Using KNX Wall Switch to Control Homeassistant

I never used blueprints, need to understand them first. Anyhow you are right my issue was around the new “destination” naming.
Thank you!!

You can just copy&paste the Forum link from above to import it.

Hi, I am new to HA and KNX, so please bear with me.

I want to connect a KNX wall switch with a Shelly Plug S to which I attached a light. The KNX wall switch is configured in ETS to “toggle”. It sends GA “3/0/0” and also reads GA “0/1/0” and “0/1/3” to sync its state with “global” actions like “All lights off” and “All lights in room (Wohnzimmer) off”. The connection between the KNX wall switch and the Shelly Plug S needs to be bidirectional: If I toggle the wall switch, the Shelly/light should toggle. If I toggle the Shelly/light via HA, the wall switch state should be synchronized to that the next toggle of the wall switch is correct.

In addition to this thread, I also read the following related topics several times.

Below you find my current solution. It works exactly as described above. So basically all good. However, I have a few questions:

  • Is this really the best, cleanest, minimal way to achieve this? I doubt that so many lines of “code” are required for such a “common” scenario.
  • If yes, how can I make this reusable? I have like 5+ same scenarios? Is this possible with scripts or templates? As said, I am new to HA and don’t know them yet.

My current solution:

Shelly integration provides:

light.wohnzimmer_stehlampe

KNX wall switch → Shelly/light:

knx:
  binary_sensor:
    - name: "Wohnzimmer Schalter Stehlampe"
      state_address:
        - "3/0/0"
        - "0/1/0"
        - "0/1/3"

automation:
  - alias: "Wohnzimmer Stehlampe anschalten via KNX Schalter"
    trigger:
      - platform: state
        entity_id: binary_sensor.wohnzimmer_schalter_stehlampe
        to: "on"
    action:
      - service: light.turn_on
        entity_id: light.wohnzimmer_stehlampe
  - alias: "Wohnzimmer Stehlampe ausschalten via KNX Schalter"
    trigger:
      - platform: state
        entity_id: binary_sensor.wohnzimmer_schalter_stehlampe
        to: "off"
    action:
      - service: light.turn_off
        entity_id: light.wohnzimmer_stehlampe

Shelly/light → KNX wall switch:

knx:
  expose:
    - type: binary
      entity_id: light.wohnzimmer_stehlampe
      address: "3/0/0"

Thanks upfront and also for making this HA and KNX things happen. Cool stuff.

Be aware that a binary sensor sends GroupValueRead requests to its first state_address periodically by default. An expose on the other hand answers such - so HA is (maybe - depending on which telegram is faster) answering itself if you use the same addresses for these.

If 3/0/0 is exclusively used for this light I wouldn’t use a binary_sensor - it already has its HA entity from the shelly integration anyway. Just use a knx_event as trigger in an automation matching the 3 GAs and the payload (1 or 0) directly.

Enter the world of blueprints! About blueprints - Home Assistant
See also Topics tagged knx there are already 2 which could fit your needs (one of them is mine :wink:). You can also just use them as examples on how to use knx_event.
Just be aware that reloading the KNX integration breaks register_event and register_expose services - so maybe better configure them in yaml.

Thanks @farmio for your answer. I think I got your point with “HA may answering itself”.

I updated my solution. This would be your preferred way, right?

Shelly integration provides (as before):

light.wohnzimmer_stehlampe

KNX wall switch → Shelly/light (now with events):

knx:
  event_filter:
    - "3/0/0"
    - "0/1/0"
    - "0/1/3"

automation:
  - alias: "Wohnzimmer Stehlampe anschalten via KNX Schalter"
    trigger:
      - platform: event
        event_type: knx_event
        event_data:
          destination: "3/0/0"
          direction: "Incoming"
          data: 1
      - platform: event
        event_type: knx_event
        event_data:
          destination: "0/1/0"
          direction: "Incoming"
          data: 1
      - platform: event
        event_type: knx_event
        event_data:
          destination: "0/1/3"
          direction: "Incoming"
          data: 1
    action:
      - service: light.turn_on
        entity_id: light.wohnzimmer_stehlampe
  - alias: "Wohnzimmer Stehlampe ausschalten via KNX Schalter"
    trigger:
      - platform: event
        event_type: knx_event
        event_data:
          destination: "3/0/0"
          direction: "Incoming"
          data: 0
      - platform: event
        event_type: knx_event
        event_data:
          destination: "0/1/0"
          direction: "Incoming"
          data: 0
      - platform: event
        event_type: knx_event
        event_data:
          destination: "0/1/3"
          direction: "Incoming"
          data: 0
    action:
      - service: light.turn_off
        entity_id: light.wohnzimmer_stehlampe

Shelly/light → KNX wall switch (same as before):

knx:
  expose:
    - type: binary
      entity_id: light.wohnzimmer_stehlampe
      address: "3/0/0"

I would have some last questions in case you ever find the time. Any feedback would be highly appreciated.

  1. This is even more code than before. Do you see any options to minimize it?
  2. On state change I see 2 knx_events, “Incoming” and “Outgoing”. The outgoing I actually do not need but I guess it’s because of the expose, right? BTW: I wonder why “Incoming” uses 0/1 while “Outgoing” uses false/true as data.
  3. Is the knx_event solution better than binary_sensor with sync_state: init? binary_sensor would allow me to group the addresses (3 per wall switch) while event_filter seems to be just a long list containing addresses of all switches (5 * 3 = 15 in my case). I should at least separate them with a comment. On the other hand you are of course right, I don’t need the binary_sensor entity since I already have the Shelly entity.
  4. In the current docs about KNX I could not find anything about event_filter, only about events which seems to be not valid anymore: KNX - Home Assistant
  5. If I am not mistaken, blueprints are “only” for automations and work with the UI instead of YAML. Furthermore, you mentioned that the “KNX integration” breaks on reload if not specified in YAML. And last but not least my scenario needs not only automations but also knx: event_filter and knx: expose. So I don’t see any benefit of using blueprints for this. Did I miss something?

Thank you.

Maybe the destination matches can be templated with some kind of in([0/1/2, 0/1/4]) or something.
Or use a trigger_id.

  1. event_filter was just deprecated in favor of event in 2021.12

  2. you can use blueprints for the automation part, the event-GAs should be enabled in yaml. So should the expose be done in yaml. But in the end some copy&paste will do as well.
    Only register_event and register_expose service doesn’t survive a reload.

Thanks again, @farmio.

  1. I understood the “in(…)” idea but did not find a solution so far. I did not understand the “trigger_id” idea but will try to figure it out.
  2. I assume no answer to question 2 means: This is expected.
  3. I assume no answer to question 3 means: binary_sensor with sync_state: init is not a good solution.
  4. I just updated to HA 2021.12.1. On startup it says “The ‘event_filter’ option is deprecated, please remove it from your configuration”. If I change it to ‘event’, it says ‘Invalid config’. So I assume I have to keep ‘event_filter’ for now.
  5. Understood. Thanks. I won’t use blueprints in this case.

What I also don’t yet understand is how HA syncs the current state between my wall toggle switch and the Shelly/light on HA startup. I assume this is done implicitly by using expose.

You can essentially define a trigger_id for some condition and match against this in the action.

You can also use template trigger.

Untested draft example:

automation:
  trigger:
    - platform: template
      value_template: >- 
        {{ trigger is defined and trigger.platform == "event" 
          and trigger.event.event_type == "knx_event"
          and trigger.event.data.direction == "Incoming"
          and trigger.event.data.destination in ["3/0/0", "0/1/0", "0/1/3"] }}
        id: '{{ "on" if trigger.event.data.data else "off" }}'
    action:
      - service: light.turn_{{ trigger.id }}
        entity_id: light.wohnzimmer_stehlampe

Its your call if shorter equals better readable…

Right. Well never checked that, but in python 0 == False and 1 == True so :man_shrugging:

No, it will be removed in some versions. Have a look at the docs or the PR that was linked in the changelog

In fact, I read the docs multiple times. When I tried event, the Studio Code Server Add-On said “Property event is not allowed.” and config verification failed with an error. Strangely enough, after reloading the KNX integration, the config verification succeeds. Studio Code Server still shows the same error even after restarting the whole OS. Anyways, it works.

I will stick with event instead of binary_sensor, will use no blueprints but check how to minimize my YAML code based on your suggestions.

Thanks for all your time and support. It wasn’t my intention to cause so much trouble.

Maybe the addon is not up to date.
If the actual config verification - the one ran by HA core on restart - fails with event then you are not on 2021.12 yet.

As said, I could not restart (via UI) because the config verification failed. So I assumed I am missing something or the docs are outdated. After reloading the KNX integration the verification worked and I could restart. Since then it works but VS Code still marks “event” as error. Never mind. All good. I am definitely on 2021.12.

Hello everyone.

My name is Dave and i’m an absolute HA beginner. Sorry for bumping this old topic. I was reading a lot the last days and tried even more but the more i read and try the more i get confused.
I’m trying to control a Zigbee thermostat via MDT Glastaster II. The thermostat is integrated to HA via zigbee2mqqt.

To start somewhere and to get an idea how things work i disabled the GT II 's internal temperature sensor and tried to send the thermostats target temperature to the bus using this code but i guess “attribute” is complete nonsense in this case?!

expose:
    - type: temperature
      entity_id:  climate.heizung_buro
      attribute:  current_heating_setpoint/get
      address:  "1/3/1"

In the thermostat’s documentation i read

To read send a message to zigbee2mqtt/FRIENDLY_NAME/get with payload {"current_heating_setpoint": ""}

How do i send a message to zigbee2mqtt/climate.heizung_buro/get and ho do i use payload?

I hope someone can give me a hint to the right direction. :sweat_smile:

Thanks
Dave

Yes. This requires the name of a HA entities attribute. You can inspect these here: Open your Home Assistant instance and show your state developer tools.

Can’t help you with mqtt or zigbee.

Hi all,
I am currently trying to control the Media.Player.
For this I use KNX with a GVS50.
This is configured as follows.

I simply solved the start/stop via a switch.

Now, however, I am also trying to make it louder/quieter. This I would solve via an automation, as already described above. Unfortunately, I can not control the volume. Do I have to create the individual KNX addresses in the Configuration.yaml?

- id: '1677413365306'
  alias: Media Leiser
  description: ''
  trigger:
  - platform: event
    event_type: knx_event
    event_data:
      destination: 6/0/3
#  - platform: event
#    event_type: knx_event
#    event_data:
#      destination: 6/0/1
  condition: []
  action:
  - choose:
#    - conditions:
#      - condition: template
#        value_template: '{{ trigger.event.data.destination==''6/0/1'' and trigger.event.data.data
#          == 1 }}'
#      sequence:
#      - service: media_player.media_play
#        entity_id: media_player.vlc_telnet
#    - conditions:
#      - condition: template
#        value_template: '{{ trigger.event.data.destination==''6/0/1'' and trigger.event.data.data
#          == 0 }}'
#      sequence:
#      - service: media_player.media_play_pause
#        entity_id: media_player.vlc_telnet
    - conditions:
      - condition: template
        value_template: '{{ trigger.event.data.destination==''6/0/3'' and trigger.event.data.data
          == 1 }}'
      sequence:
      - repeat:
          count: '25'
          sequence:
          - service: media_player.volume_up
            entity_id: media_player.vlc_telnet
          - delay: '00:00:00.25'
    - conditions:
      - condition: template
        value_template: '{{ trigger.event.data.destination==''6/0/3'' and trigger.event.data.data
          == 0 }}'
      sequence:
      - repeat:
          count: '25'
          sequence:
          - service: media_player.volume_down
            entity_id: media_player.vlc_telnet
          - delay: '00:00:00.25'
    default: []
  mode: restart

another small side question.
Is there a way to make mass comments?
e.g. /* *\

thank you in advance for your input!

You need to add all addresses you want to fire knx_event for in the yaml knx: event: key.

Can you elaborate what exactly you mean by this?

Hi,
thanks for your quick help! It works

With the commenting I meant if there is a way not to comment every single line with a #.
Above in my code I have some lines which follow together always have to comment with a #.

in C & C+ there is for example the possibility to make a mass comment with /* = start and */= end.

/*
Here starts
a long comment
and here
it ends
*/

Ah, now I get it. Was confused by the C syntax :rofl:
Yaml doesn’t support block comments.
Most editors support “commenting out selected lines” - on VSCode in macOS that would be Shift Cmd 7.

yes that’s right, I should have mentioned that it is done that way in C :joy:

thanks again for your quick help!

Hello all,
I am trying to switch radio stations with my KNX Touch.
Unfortunately, it does not switch between the desired stations. Does anyone of you see my mistake?

config.yaml: ( i am not sure if i need this in the config)

#Radio Sender wechseln KNX
input_select:
  radio_station:
    name: "Radiosender"
    options:
      - "Sender 1"
      - "Sender 2"
      - "Sender 3"
    initial: "Sender 1"
    icon: "mdi:radio"

automations.yaml:

- alias: Radiosender wechseln
  trigger:
  - platform: event
    event_type: knx_event
    event_data:
      destination: '6/0/2'
  action:
  - choose:
    # Bei einem Wert von 1: zum nächsten Radiosender wechseln
    - conditions:
      - condition: template
        value_template: '{{ trigger.event.data.destination == ''6/0/2'' and trigger.event.data.data == 1 }}'
      sequence:
      - choose:
        # Hier wird zwischen drei Radiosendern gewechselt
        - conditions:
          - condition: state
            entity_id: input_boolean.swr1
            state: 'Sender 1'
            sequence:
            - service: media_player.play_media
              data:
                entity_id: media_player.vlc_telnet
                media_content_id: media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56
                media_content_type: audio/mpeg
        - conditions:
          - condition: state
            entity_id: input_boolean.rockantenne
            state: 'Sender 2'
            sequence:
            - service: media_player.play_media
              data:
                entity_id: media_player.vlc_telnet
                media_content_id: media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81
                media_content_type: audio/mpeg
        - conditions:
          - condition: state
            entity_id: input_boolean.radiobob
            state: 'Sender 3'
            sequence:
            - service: media_player.play_media
              data:
                entity_id: media_player.vlc_telnet
                media_content_id: media-source://radio_browser/ca43455f-f027-11e8-a471-52543be04c81
                media_content_type: audio/mpeg
                # Wenn kein Sender ausgewählt ist, wird der erste Sender abgespielt
        - conditions: []
          sequence:
          - service: media_player.play_media
            data:
              entity_id: media_player.vlc_telnet
              media_content_id: media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56
              media_content_type: audio/mpeg
            # Auswahl des nächsten Radiosenders
          - service: input_select.select_next
            entity_id: input_select.radio_station
        # Bei einem Wert von 0: zum vorherigen Radiosender wechseln
        - conditions:
          - condition: template
            value_template: '{{ trigger.event.data.destination == ''6/0/2'' and trigger.event.data.data == 0 }}'
          sequence:
          - service: input_select.select_previous
            entity_id: input_select.radio_station

in general i can already start/stop and turn volume up/down the player with knx

thanks!

Hi again,
I have tried further but unfortunately do not come to the solution.

The following code works in the automations.yaml:

- alias: Radio Sender 1 starten
  trigger:
    platform: event
    event_type: knx_event
    event_data:
      destination: '6/0/2'
      data: 1
  condition:
    - condition: template
      value_template: '{{ trigger.event.data.destination == "6/0/2" and trigger.event.data.data == 1 }}'
  action:
    - service: media_player.play_media
      data:
        entity_id: media_player.vlc_telnet
        media_content_id: media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56
        media_content_type: audio/mpeg

However, as soon as I want to switch between several channels via choose, it no longer works:

- alias: Radiosender wechseln
  input_select:
    radio_station:
      name: Radio Station
      options:
        - Sender 1
        - Sender 2
        - Sender 3
      initial: Sender 1
  trigger:
    platform: event
    event_type: knx_event
    event_data:
      destination: '6/0/2'
  action:
    - choose:
      # Bei einem Wert von 1: zum nächsten Radiosender wechseln
      - conditions:
          - condition: template
            value_template: '{{ trigger.event.data.destination == "6/0/2" and trigger.event.data.data == 1 }}'
        sequence:
          - choose:
              # Hier wird zwischen drei Radiosendern gewechselt
              - conditions:
                  - condition: state
                    entity_id: input_select.radio_station
                    state: 'Sender 1'
                sequence:
                  - service: media_player.play_media
                    data:
                      entity_id: media_player.vlc_telnet
                      media_content_id: media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56
                      media_content_type: audio/mpeg
              - conditions:
                  - condition: state
                    entity_id: input_select.radio_station
                    state: 'Sender 2'
                sequence:
                  - service: media_player.play_media
                    data:
                      entity_id: media_player.vlc_telnet
                      media_content_id: media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81
                      media_content_type: audio/mpeg
              - conditions:
                  - condition: state
                    entity_id: input_select.radio_station
                    state: 'Sender 3'
                sequence:
                  - service: media_player.play_media
                    data:
                      entity_id: media_player.vlc_telnet
                      media_content_id: media-source://radio_browser/ca43455f-f027-11e8-a471-52543be04c81
                      media_content_type: audio/mpeg
              # Wenn kein Sender ausgewählt ist, wird der erste Sender abgespielt
              - conditions: []
                sequence:
                  - service: media_player.play_media
                    data:
                      entity_id: media_player.vlc_telnet
                      media_content_id: media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56
                      media_content_type: audio/mpeg
              # Auswahl des nächsten Radiosenders
              - service: input_select.select_next
                entity_id: input_select.radio_station
      # Bei einem Wert von 0: zum vorherigen Radiosender wechseln
      - conditions:
          - condition: template
            value_template: '{{ trigger.event.data.destination == "6/0/2" and trigger.event.data.data == 0 }}'
        sequence:
          - service: input_select.select_previous
            entity_id: input_select.radio_station
  mode: restart

has no one an idea, or has anyone ever switched between radio stations via KNX in any other way?

EDIT:
I have now written a new code. Unfortunately, I have no success again. Am I doing something fundamentally wrong, or am I forgetting something?

I have only written the following things and changed nothing else on HA etc.

configuration.yaml:

input_select:
  radio_stations:
    name: Radiosender
    options:
      - 'media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81,Sender 1,mdi:radio'
      - 'media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56,Sender 2,mdi:radio'
      - 'media-source://radio_browser/2c2d37a6-92ea-47d9-9f99-13b8c24b76f5,Sender 3,mdi:radio'
    initial: 'media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81,Sender 1,mdi:radio'

automations.yaml:

- alias: Radiosender wechseln
  trigger:
    platform: event
    event_type: knx_event
    event_data:
      destination: '6/0/2'
  action:
    choose:
      # Wenn der Wert "1" empfangen wird, schalte zur nächsten Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' and trigger.event.data.data == 1 }}"
        sequence:
          - service: input_select.select_next
            target:
              entity_id: input_select.radio_stations
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = state_attr('input_select.radio_stations', 'options') %}
                {{ options[states('input_select.radio_stations')] }}
              media_content_type: "audio/mpeg"
      # Wenn der Wert "0" empfangen wird, schalte zur vorherigen Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' and trigger.event.data.data == 0 }}"
        sequence:
          - service: input_select.select_previous
            target:
              entity_id: input_select.radio_stations
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = state_attr('input_select.radio_stations', 'options') %}
                {{ options[states('input_select.radio_stations')] }}
              media_content_type: "audio/mpeg"
      # Speichere die aktuelle Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' }}"
        sequence:
          - service: input_select.select_option
            data:
              entity_id: input_select.radio_stations
              option: "{{ states('input_select.radio_stations') }}"
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = state_attr('input_select.radio_stations', 'options') %}
                {{ options[states('input_select.radio_stations')] }}
              media_content_type: "audio/mpeg"
      # Wenn noch keine Option ausgewählt wurde, wähle Sender 1 aus
      - conditions: "{{ states('input_select.radio_stations') == 'Radiosender' }}"
        sequence:
          - service: input_select.select_option
            data:
              entity_id: input_select.radio_stations
              option: 'Sender 1'
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = state_attr('input_select.radio_stations', 'options') %}
                {{ options[states('input_select.radio_stations')] }}
              media_content_type: "audio/mpeg"

As soon as I want to play multiple radio stations, the code does not work.

My goal is the following:

  • With a KNX switch which sends the values 1 or 0, I want to select a list of radio stations back and forth.

  • The whole thing should be done with the variables “Sender 1-3”, which I can switch back and forth as I said and the current “Sender” always plays on VLC.

EDIT2:
I made it!

Here is the final version:
configuration.yaml:

input_select:
  radio_stations:
    name: Radio Stations
    options:
      - Sender 1
      - Sender 2
      - Sender 3
      - Sender 4
    initial: Sender 1

automations.yaml:

- alias: Radiosender wechseln
  trigger:
    platform: event
    event_type: knx_event
    event_data:
      destination: '6/0/2'
  action:
    choose:
      # Wenn der Wert "1" empfangen wird, schalte zur nächsten Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' and trigger.event.data.data == 1 }}"
        sequence:
          - service: input_select.select_next
            target:
              entity_id: input_select.radio_stations
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = {
                  'Sender 1': 'media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56',
                  'Sender 2': 'media-source://radio_browser/ca43455f-f027-11e8-a471-52543be04c81',
                  'Sender 3': 'media-source://radio_browser/c73c63c4-1c84-41f4-bd03-1eb025fb7afe',
                  'Sender 4': 'media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81',
                } %}
                {{ options[states('input_select.radio_stations')] }}
            data:
              media_content_type: "audio/mpeg"
      # Wenn der Wert "0" empfangen wird, schalte zur vorherigen Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' and trigger.event.data.data == 0 }}"
        sequence:
          - service: input_select.select_previous
            target:
              entity_id: input_select.radio_stations
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
            data_template:
              media_content_id: >
                {% set options = {
                  'Sender 1': 'media-source://radio_browser/36a6d57a-4d8a-45e3-aad9-7931c6e43c56',
                  'Sender 2': 'media-source://radio_browser/ca43455f-f027-11e8-a471-52543be04c81',
                  'Sender 3': 'media-source://radio_browser/c73c63c4-1c84-41f4-bd03-1eb025fb7afe',
                  'Sender 4': 'media-source://radio_browser/960594a6-0601-11e8-ae97-52543be04c81',
                } %}
                {{ options[states('input_select.radio_stations')] }}
            data:
              media_content_type: "audio/mpeg"
      # Speichere die aktuelle Variable
      - conditions: "{{ trigger.event.data.destination == '6/0/2' }}"
        sequence:
          - service: input_select.select_option
            data:
              entity_id: input_select.radio_stations
              option: "{{ states('input_select.radio_stations') }}"
          - service: media_player.play_media
            target:
              entity_id: media_player.vlc_telnet
1 Like