Support KNX channels with Home Assistant owned state

I want to control non-KNX devices (or in my case actually scenes) with KNX switches. The KNX switches have LEDs that should always show the current state even if it was changed from another place (like the Home Assistant app).
The problem now: When I create an automation that is triggered by the KNX switch (entity status change), it is also triggered if I send a status update to the switch, which has nasty side effects. In OpenHab I could use Control Channel Types to achieve it. In Node-RED with knxUltimate it “just works” if you send an update to a KNX node it is not injected as a message again.
Maybe there is a workaround to trigger the automation using specific events and filters but I think there should be an easier solution.

Hi!
Maybe using a binary_sensor instead of a switch will help with your problem. Or omit the state address and use an exposed state.
The pendant to control channel as I understand from your link (I’ve never used OpenHab) is an exposed state - see https://www.home-assistant.io/integrations/knx/#exposing-entity-states-entity-attributes-or-time-to-knx-bus

Hi Matthias,

thanks for those great ideas.

So, I changed the switch to a binary_sensor and am not able to send status updates to it any more (which makes sense for a sensor). Now I could use the “sensor” for control direction and exposed state for the state direction. This currently does not work because I want to expose the state of a Scene to the LED, however Scenes seem to have no state and are only triggers. On the other hand, I cannot select the switch as part of the scene actions any more because we have converted it to a sensor.

And if I would get this to work (I can think of a workaround), don’t you think that an update to an exposed state would also have an effect on the binary_sensor trigger as it’s still the same GA or did I miss something?

Basically I want a way to send an update to KNX without triggering an action like an external update would.

You can always use a different GA for status - that’s knx.
I don’t fully get the problem. When you send something to the bus shouldn’t it always behave the same way - independent of the source?
That scenes don’t have states is a common concept in knx too…

Can you describe what you want to accomplish, maybe there is another way than switch and scene.

Hi,

yes probably I could use a separate GA for the status of all my switches. I guess this would be the cleanest solution as currently the switch assumes it knows the correct state. However, I don’t have ETS and the way it is programmed right now does work in OpenHAB and Node-RED without workarounds.

And yes, sending to the bus should always behave the same way - no matter who is sending. But for me this does not necessarily mean that every participant needs to receive and handle everything he has sent to the bus again. Or is it how KNX is designed that everyone also receives his own messages?

What I want to accomplish is basically scenes with states and that the current (read: last activated) scene is also visible on the button that activated it. States are important because the current scene has influence on other logic (e.g. in a bedroom with activated scene “Sleep” the shutters will not open on sunrise). Every room has an “Off” Scene that is activated if you use the button of the currently activated scene. Since scenes are usually mututally exclusive I know I have to do some extra work (if scene 2 is activated I have to send a state “Off” for scene 1) but that works pretty well.

So can you show the automation that is not working (working too much xD)? Im sure there is a solution for this.

Automation that should turn on a scene:

- id: '1602963435430'
  alias: Büro unten Szene Licht
  description: ''
  trigger:
  - platform: state
    entity_id: switch.c_office_taster_ul
    to: 'on'
    from: 'off'
  condition: []
  action:
  - scene: scene.c_office_licht
  mode: single

Automation that turns everything off if the current scene is switched off:

- id: '1602965814904'
  alias: Büro unten Programm Aus
  description: ''
  trigger:
  - platform: state
    entity_id: switch.c_office_taster_ul
    to: 'off'
    from: 'on'
  - platform: state
    entity_id: switch.c_office_taster_ur
    from: 'on'
    to: 'off'
  condition: []
  action:
  - scene: scene.buro_unten_aus
  mode: single

Scene that controls the light and writes the status back to KNX:

- id: '1602963474334'
  name: Büro unten Licht
  entities:
    switch.c_office_light_power:
      friendly_name: C.Office.Light.Power
      state: 'on'
    switch.c_office_taster_ul:
      friendly_name: C.Office.Taster.UL
      state: 'on'
    switch.c_office_taster_ur:
      friendly_name: C.Office.Taster.UR
      state: 'off'

Activating one scene (e.g. automation 1), will send an “off” to other scenes’s GAs which will trigger the automation 2. If I could send the “off” to the bus bypassing the triggers this would work.

My solution now is to keep scenes in Node-RED and use Home Assistant only to activate them (by sending to KNX like a physical button would).

In the meantime I solved it by sending state updates to the switches with a small delay. Not perfect, but works well enough…

How did you do that?
Did you add a HA script to the scene using knx.send to update the state? But that would probably be the same as toggling the switches directly from the scene :thinking:

Why doesn’t the scene get triggered a second time after the small delay you introduced?

Thanks for asking, I just noticed that I went away from the delay because it introduced other problems - so please forget my last comment. My current solution is a little more complicated.

First, I created a helper variable (type select) for every room that has scenes, e.g. input_select.badezimmer_programm

Then, I created boolean helper variables for every scene that can be active, e.g.
input_boolean.badezimmer_programm_hell_aktiv

Then I add expose configurations for all helper variables to the 1-n switches’ GAs that both trigger and indicate the state of the scene.

- type: 'binary'
  entity_id: 'input_boolean.badezimmer_programm_hell_aktiv'
  address: '4/0/34'

Why the string helper if the booleans update the switches? In the scene configuration I only have to update the string helper which is convenient since it is a drop-down list. And, I don’t have to change all scenes if I add a new scene. The drawback, I need a mapping from string to booleans. So I have an automation, that on every change of the string variable updates all the booleans like this:

service: |
  {% if is_state('input_select.badezimmer_programm', 'Hell') %}
    input_boolean.turn_on
  {% else %}
    input_boolean.turn_off
  {% endif %}
data: {}
entity_id: input_boolean.badezimmer_programm_hell_aktiv

Now for the following step I’m not sure but I assume that also exposed values are handled by HA again and could trigger unwanted automations. So are we now back at the start? How to filter/ignore those KNX commands we sent ourselves? That has become quite easy now with a trick, I can use the boolean helper variables to check: If I receive an “off” from a switch GA but I know the associated scene is not even active, I can just ignore it. To make it a little easier I created blueprints I use for every switch - scene - boolean combination. For example, for a switch to activate a scene:

blueprint:
  name: Activate Szene X, when switch Y is turned on
  domain: automation
  input:
    switch_entity:
      name: Switch (KNX)
      selector:
        entity:
          domain: switch
    target_scene:
      name: Target Scene
      selector:
        entity:
          domain: scene
    scene_active_flag:
      name: Helper that shows if the desired scene is (already) active
      selector:
        entity:
          domain: input_boolean

mode: single

trigger:
- platform: state
  entity_id: !input switch_entity
  to: 'on'
  from: 'off'

condition:
- condition: state
  entity_id: !input scene_active_flag
  state: 'off'

action:
- scene: !input target_scene

This is a lot of helpers and automations and basically boilerplate code in comparison to OpenHAB or Node-RED. But once the skeleton is there, it’s easy to maintain and works quite fast.

This could be solved quite easily by using HA events, the knx_event more specifically, instead of switch entities. There you can match for a direction: Incoming data attribute.

I could also imagine using knx select entities (without state_address) instead of input_select helpers. These could be set to receive scene numbers from the knx devices instead of booleans, but for this you’d need ETS again.

Thank you, I will have a look if knx_events help!