Integrate Alpha Innotec LG 327 TB ventilation unit in Home-Assistant

2019-09-26 · 1328 words · 7 minute read

A while ago I built a Modbus RTU to Modbus TCP Gateway based on a Beaglebone Green and a RS485 Cape (check my blog post from back then). It worked, but stoped working from time to time and I decided to fix that issue a few weeks ago. I updated the OS on the Beaglebone and realized that so many things changed since my initial implementation that I didn’t want to invest to much time.

So I decided to use a USB to RS485 converter and plug that directly into my server and control the ventilation unit directly from Home-Assistant.

Modbus configuration 🔗

configuration.yaml

1modbus:
2  name: ventilation_unit
3  type: serial
4  method: rtu
5  port: /dev/ttyUSB0
6  baudrate: 19200
7  stopbits: 1
8  bytesize: 8
9  parity: E

Nothing special here, the port must match the USB converter and the user that runs HA must have the rights to access the port (I had to add it to the uucp group).

ventilation.yaml

 1- platform: modbus
 2  registers:
 3    - name: einlass_ventilator
 4      hub: ventilation_unit
 5      unit_of_measurement: '%'
 6      slave: 1
 7      register: 102
 8      register_type: input
 9    - name: Auslass Ventilator 
10      hub: ventilation_unit
11      unit_of_measurement: '%'
12      slave: 1
13      register: 103
14      register_type: input
15    - name: Alarm 
16      hub: ventilation_unit
17      slave: 1
18      register: 101
19      register_type: input
20    - name: CO2 
21      hub: ventilation_unit
22      unit_of_measurement: 'PPM'
23      slave: 1
24      register: 10
25      register_type: input
26    - name: Temperatur Zuluft 
27      hub: ventilation_unit
28      unit_of_measurement: '°C'
29      slave: 1
30      register: 0
31      register_type: input
32      scale: 0.1
33      offset: -30.0
34      precision: 1
35    - name: Temperatur Frischluft 
36      hub: ventilation_unit
37      unit_of_measurement: '°C'
38      slave: 1
39      register: 2
40      register_type: input
41      scale: 0.1
42      offset: -30.0
43      precision: 1
44    - name: Temperatur Fortluft 
45      hub: ventilation_unit
46      unit_of_measurement: '°C'
47      slave: 1
48      register: 3
49      register_type: input
50      scale: 0.1
51      offset: -30.0
52      precision: 1
53    - name: Temperatur Abluft 
54      hub: ventilation_unit
55      unit_of_measurement: '°C'
56      slave: 1
57      register: 6
58      register_type: input
59      scale: 0.1
60      offset: -30.0
61      precision: 1

I set up the registers that I want to read as documented in the [Modbus PDF from Alpha Innotec]({static}/blog/2019/lg327TB-hass-knx/Modbus OPT250 - 20130813.pdf) (they sent it to me years ago when I asked them). The only think that’s important is that the hub matches the name defined in configuration.yaml.

The only kind of special thing here is the alram. It gives me a binary representation of all alarms. I used template binary sensors to decode them.

 1- platform: template
 2  sensors:
 3    alarm_external_stop:
 4      friendly_name: "Alarm Externer Stop"
 5      value_template: >-
 6        {{ states('sensor.alarm')|int|bitwise_and(1) }}
 7    alarm_main_filter:
 8      friendly_name: "Hauptfilter"
 9      value_template: >-
10        {{ states('sensor.alarm')|int|bitwise_and(2) }}
11    alarm_high_preasure:
12      friendly_name: "Hochdruck"
13      value_template: >-
14        {{ states('sensor.alarm')|int|bitwise_and(4) }}
15    alarm_frost:
16      friendly_name: "Frost"
17      value_template: >-
18        {{ states('sensor.alarm')|int|bitwise_and(8) }}
19    alarm_communication_error:
20      friendly_name: "Kommunikationsfehler"
21      value_template: >-
22        {{ states('sensor.alarm')|int|bitwise_and(16) }}
23    alarm_external_filter:
24      friendly_name: "Externer Filter"
25      value_template: >-
26        {{ states('sensor.alarm')|int|bitwise_and(32) }}
27    alarm_fan_speed:
28      friendly_name: "Lüfter Geschwindigkeit"
29      value_template: >-
30        {{ states('sensor.alarm')|int|bitwise_and(64) }}

That enabled me to get the sensor data into HA:

hass ventilation UI

Snippet from the Lovelace UI config

 1- entities:
 2      - entity: sensor.einlass_ventilator
 3        icon: 'mdi:fan'
 4        name: Einlass Ventilator
 5      - entity: sensor.auslass_ventilator
 6        icon: 'mdi:fan'
 7        name: Auslass Ventilator
 8      - entity: sensor.co2
 9        icon: 'mdi:grain'
10        name: Kohlendioxyd
11      - entity: sensor.temperatur_frischluft
12        icon: 'mdi:thermometer'
13        name: Temperatur Frischluft
14      - entity: sensor.temperatur_zuluft
15        icon: 'mdi:thermometer'
16        name: Temperatur Zuluft
17      - entity: sensor.temperatur_abluft
18        icon: 'mdi:thermometer'
19        name: Temperatur Abluft
20      - entity: sensor.temperatur_fortluft
21        icon: 'mdi:thermometer'
22        name: Temperatur Fortluft
23	  - entity: binary_sensor.alarm_external_stop
24        icon: 'mdi:alert-decagram-outline'
25        name: Alarm externer Stop
26      - entity: binary_sensor.alarm_main_filter
27        icon: 'mdi:alert-decagram-outline'
28        name: Alarm Hauptfilter
29      - entity: binary_sensor.alarm_high_preasure
30        icon: 'mdi:alert-decagram-outline'
31        name: Alarm Hochdruck
32      - entity: binary_sensor.alarm_frost
33        icon: 'mdi:alert-decagram-outline'
34        name: Alarm Frost
35      - entity: binary_sensor.alarm_communication_error
36        icon: 'mdi:alert-decagram-outline'
37        name: Alarm Kommunikation
38      - entity: binary_sensor.alarm_external_filter
39        icon: 'mdi:alert-decagram-outline'
40        name: Alarm Externer Filter
41      - entity: binary_sensor.alarm_fan_speed
42        icon: 'mdi:alert-decagram-outline'
43        name: Alarm Lüftergeschwindigkeit
44    show_header_toggle: false
45    title: Lüftungsanlage
46    type: entities

Writing ventilation levels 🔗

So I was able to read but not to write. I asked in the discord channel how to achieve that and was pointed towards the entity-button card. Unfortunately that card requires a entity_id, so I decided to create kind of a dummy entity.

confguration.yaml

1input_boolean:
2  stufe:
3    name: "Lüftung Stufe"

With that I created a horizontal-stack of entity-button cards

Snippet from the Lovelace UI config

 1- cards:
 2      - entity: input_boolean.stufe
 3        hold_action:
 4          action: none
 5        icon: 'mdi:fan-off'
 6        name: Aus
 7        show_icon: true
 8        show_name: true
 9        tap_action:
10          action: call-service
11          service: modbus.write_register
12          service_data:
13            address: 100
14            hub: ventilation_unit
15            unit: 1
16            value: 0
17        type: entity-button
18      - entity: input_boolean.stufe
19        hold_action:
20          action: none
21        icon: 'mdi:numeric-1-box'
22        name: Stufe 1
23        show_icon: true
24        show_name: true
25        tap_action:
26          action: call-service
27          service: modbus.write_register
28          service_data:
29            address: 100
30            hub: ventilation_unit
31            unit: 1
32            value: 1
33        type: entity-button
34      - entity: input_boolean.stufe
35        hold_action:
36          action: none
37        icon: 'mdi:numeric-2-box'
38        name: Stufe 2
39        show_icon: true
40        show_name: true
41        tap_action:
42          action: call-service
43          service: modbus.write_register
44          service_data:
45            address: 100
46            hub: ventilation_unit
47            unit: 1
48            value: 2
49        type: entity-button
50      - entity: input_boolean.stufe
51        hold_action:
52          action: none
53        icon: 'mdi:numeric-3-box'
54        name: Stufe 3
55        show_icon: true
56        show_name: true
57        tap_action:
58          action: call-service
59          service: modbus.write_register
60          service_data:
61            address: 100
62            hub: ventilation_unit
63            unit: 1
64            value: 3
65        type: entity-button
66      - entity: input_boolean.stufe
67        hold_action:
68          action: none
69        icon: 'mdi:numeric-4-box'
70        name: Stufe 4
71        show_icon: true
72        show_name: true
73        tap_action:
74          action: call-service
75          service: modbus.write_register
76          service_data:
77            address: 100
78            hub: ventilation_unit
79            unit: 1
80            value: 4
81        type: entity-button
82    type: horizontal-stack

That results in 5 buttons that when clicked call a service provided by the Modbus integration that writes a certain value into a Modbus register and therby sets the speed of the ventilators.

hass ventilation UI

KNX integration 🔗

With my old solution I had two buttons on a KNX Glas button that allowd me to control the level without using the phone. The control was actually done by my Loxone Miniserver that has a KNX interface, but I wanted to reduce the amount of things that this device does because I need a Windows Software to make changes to it and that sucks :-)

Also I want HA to be able to react on KNX telegrams, so here is how I solved this last task.

First I need to configure that the KNX integration fires an event whenever a KNX telegram is received. For the moment I decided to not set any filters.

configuration.yaml

1knx:
2  fire_event: true
3  fire_event_filter: ["*"]

Then I created an automation that reacts on a certain KNX Group Address with a data value of 1

automation.yaml

 1- alias: 'Set ventilation level to 4 via KNX Switch'
 2  trigger:
 3    platform: event
 4    event_type: knx_event
 5    event_data:
 6      address: "6/1/162"
 7      data: 1
 8  action:
 9  - service: modbus.write_register
10    data:
11      address: 100
12      hub: ventilation_unit
13      unit: 1
14      value: 4
15
16- alias: 'Set ventilation level to 2 via KNX Switch'
17  trigger:
18    platform: event
19    event_type: knx_event
20    event_data:
21      address: "6/1/161"
22      data: 1
23  action:
24  - service: modbus.write_register
25    data:
26      address: 100
27      hub: ventilation_unit
28      unit: 1
29      value: 2

The trigger ist set to knx_event and the event_data is like a filter to only react on a given Group address and data. The action calls the modbus.write_register service and sends the right values to the Modbus registers of the ventilation unit.