KNX contact-control Thing related to Group:Contact Item not working

This drives me crazy … I cannot get the state of a Group:Contact Item into KNX.

I have three (zigbee based) window contacts (Things), linked into openhab 3 via zigbee2mqtt, like so:

# -----------------------------------
  # Dirk's Office (BD)
  # --------------------
  - id: BDW1
    channelTypeUID: mqtt:contact
    label: Window Right Dirk
    description: null
    configuration:
      stateTopic: z2m/BDW1
      transformationPattern: JSONPATH:$.contact
      off: "true"
      on: "false"
  - id: BDW2
    channelTypeUID: mqtt:contact
    label: Window Left Dirk
    description: null
    configuration:
      stateTopic: z2m/BDW2
      transformationPattern: JSONPATH:$.contact
      off: "true"
      on: "false"
  # --------------------
  # Hervé's Office (BH)
  # --------------------
  - id: BHW1
    channelTypeUID: mqtt:contact
    label: Window Hervé
    description: null
    configuration:
      stateTopic: z2m/BHW1
      transformationPattern: JSONPATH:$.contact
      off: "true"
      on: "false"
  #

I want to channel the contact state (OPEN/CLOSED) as binary information to a KNX group address as (false/true), for example to feed into a room thermostat’s window contact. To that end, I have created two virtual KNX Things of contact-control type, along with a Thing that will hold the number of open windows, like so:

UID: knx:device:_:__W
label: KNX Windows
thingTypeUID: knx:device
configuration:
  pingInterval: 600
  readInterval: 0
  fetch: false
bridgeUID: knx:ip:_
channels:
# SECOND FLOOR
# -----------------------------------
  # Windows open
  # --------------------
  - id: _2W0_
    channelTypeUID: knx:number-control
    label: Windows 2nd floor
    description: Virtual for z2m
    configuration:
      ga: 9.001:6/2/5
  - id: BDW0_
    channelTypeUID: knx:contact-control
    label: Windows Dirk
    description: Virtual for z2m, BDW1 || BDW2
    configuration:
      ga: 1.009:6/2/15
  - id: BHW0_
    channelTypeUID: knx:contact-control
    label: Window Hervé
    description: Virtual for z2m
    configuration:
      ga: 1.009:6/2/25

If there is only window (contact) per room, I’m creating a single Item, linking the zigbee2mqtt contact Thing with the KNX contact-control Thing:

Contact OfficeHerve_Window "Window" <window> (OfficeHerve, SecondFloor_Windows, WindowContact)  ["Window"]
  {channel="mqtt:topic:_:__W:BHW1", channel="knx:device:_:__W:BHW0_"}

If there are several window (contact)s per room, I’m creating one Item per contact linked to the zigbee2mqtt sensor, plus a Windows Item per room, which is OPEN, when at least one of the contacts in the room is OPEN (i.e. logical OR) and which links to the virtual KNX contact-control channel.

Group:Contact:OR(OPEN,CLOSED) OfficeDirk_Windows "Windows" <window> (OfficeDirk)
  {channel="knx:device:_:__W:BDW0_"}
Contact OfficeDirk_WindowRight "Window Right" <window> (OfficeDirk, OfficeDirk_Windows, SecondFloor_Windows, WindowContact) ["Window"]
  {channel="mqtt:topic:_:__W:BDW1"}
Contact OfficeDirk_WindowLeft "Window Left" <window> (OfficeDirk, OfficeDirk_Windows, SecondFloor_Windows, WindowContact)  ["Window"]
  {channel="mqtt:topic:_:__W:BDW2"}

An additional Item counts the OPEN windows:

Group:Number:SUM SecondFloor_Windows "Windows Open" <window> (SecondFloor)
  {channel="knx:device:_:__W:_2W0_"}

This works well on openhab and the UI. The Items do what they should:

2022-10-04 19:44:06.491 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'OfficeDirk_WindowLeft' changed from CLOSED to OPEN
2022-10-04 19:44:06.518 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'SecondFloor_Windows' changed from 1 to 2 through OfficeDirk_WindowLeft
2022-10-04 19:44:06.528 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'OfficeDirk_Windows' changed from CLOSED to UNDEF through OfficeDirk_WindowLeft
2022-10-04 19:44:06.491 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'OfficeDirk_WindowLeft' changed from CLOSED to OPEN
2022-10-04 19:44:06.518 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'SecondFloor_Windows' changed from 1 to 2 through OfficeDirk_WindowLeft
2022-10-04 19:44:06.528 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'OfficeDirk_Windows' changed from CLOSED to OPEN through OfficeDirk_WindowLeft

The ‘simple’ contact gets relayed into the KNX bus, but the 'OR’ed multiple contact does not:

Any help on what I’m doing wrong here? I have modified the GA types between 1.009, 1.019 and 1.001 types both in the Thing definition and ETS. Somehow, the simple Item is written to the KNX bus, while the Group Item is not.

You can’t link Group type Items to channels. Architecture restriction.
Groups derive their state from member Items (not channels)
Groups route commands to member Items (not channels)

KNX xxx-control type channels reverse the usual command/state flow direction, but the Group behaviour still holds true and will not work.

Thanks for the info. So, I would have to create rules to update the ‘OR’-ed Items, instead of a ‘Group’ logic?

I’d do it the lazy way.
If you want to transmit some value to KNX, you will need to do it through an Item, yes.
But you can keep your Group, doing its its aggregation.
A very simple rule can update or command your dummy Item from Group state changes or updates.

Hi @Rossko57,
I’m lazy, too. So I did it the way you suggested. However, I cannot send send a ‘OPEN/CLOSED’ command to a contact in a rule, so I changed it to a switch (side remark: I would have liked to keep this a contact element for consistency … so any suggestions for a workaround here welcome).

Switch OfficeDirk_Windows "Windows" (OfficeDirk)
  {channel="knx:device:_:__W:BDW0_"}
Group:Contact:OR(OPEN,CLOSED) OfficeDirk_WindowGroup "Windows Group" (OfficeDirk, WindowGroup)
Contact OfficeDirk_WindowRight "Window Right" <window> (OfficeDirk, OfficeDirk_WindowGroup, SecondFloor_Windows, WindowContact) ["Window"]
  {channel="mqtt:topic:_:__W:BDW1"}
Contact OfficeDirk_WindowLeft "Window Left" <window> (OfficeDirk, OfficeDirk_WindowGroup, SecondFloor_Windows, WindowContact)  ["Window"]
  {channel="mqtt:topic:_:__W:BDW2"}

Contact OfficeHerve_Window "Window" <window> (OfficeHerve, SecondFloor_Windows, WindowContact)  ["Window"]
  {channel="mqtt:topic:_:__W:BHW1", channel="knx:device:_:__W:BHW0_"}

I added the rule which you suggested (which also now needs to replace the OPEN/CLOSED by ON/OFF)

console.log('Rule window started');
var knxItem = items.getItem(event.itemName.replace('WindowGroup','Windows'));
var knxState = items.getItem(event.itemName).state.replace('OPEN','ON').replace('CLOSED','OFF');

knxItem.sendCommand(knxState);

So on an openHAB Item level, this seems to work:

2022-10-05 17:05:29.365 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'OfficeDirk_WindowLeft' changed from OPEN to CLOSED
2022-10-05 17:05:29.381 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'WindowGroup' changed from OPEN to CLOSED through OfficeDirk_WindowGroup
2022-10-05 17:05:29.388 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'SecondFloor_Windows' changed from 1 to 0 through OfficeDirk_WindowLeft
2022-10-05 17:05:29.395 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'OfficeDirk_WindowGroup' changed from OPEN to CLOSED through OfficeDirk_WindowLeft
==> /var/log/openhab/openhab.log <==
2022-10-05 17:05:39.943 [INFO ] [nhab.automation.script.ui.0b6bebc2df] - Rule window started
2022-10-05 17:05:40.106 [INFO ] [nhab.automation.script.ui.0b6bebc2df] - Rule window started2022-10-05 17:05:29.365 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'OfficeDirk_WindowLeft' changed from OPEN to CLOSED
2022-10-05 17:05:29.381 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'WindowGroup' changed from OPEN to CLOSED through OfficeDirk_WindowGroup
2022-10-05 17:05:29.388 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'SecondFloor_Windows' changed from 1 to 0 through OfficeDirk_WindowLeft
2022-10-05 17:05:29.395 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'OfficeDirk_WindowGroup' changed from OPEN to CLOSED through OfficeDirk_WindowLeft
==> /var/log/openhab/openhab.log <==
2022-10-05 17:05:39.943 [INFO ] [nhab.automation.script.ui.0b6bebc2df] - Rule window started
2022-10-05 17:05:40.106 [INFO ] [nhab.automation.script.ui.0b6bebc2df] - Rule window started
2022-10-05 17:05:40.027 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'OfficeDirk_Windows' received command OFF
2022-10-05 17:05:40.050 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'OfficeDirk_Windows' predicted to become OFF
2022-10-05 17:05:40.073 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'OfficeDirk_Windows' changed from ON to OFF

HOWEVER: Still no trace of the command on the KNX bus. I have manipulated the ‘OfficeDirk_Windows’ directly in the UI. Also that change is not lobbed over to KNX. I have adapted the DPT for the Thing and in ETS to 1.001, restarted everything. But to no avail. :smiling_face_with_tear:

That’s right. There is a logical restriction that you cannot command (send a “do something” instruction) to a passive contact sensor, which the Contact type Item is supposed to represent.

If you want to change the state of an Item from a rule, then do so - use postUpdate.

If you want to mirror state changes of an Item to the KNX bus, you already know how to do that using the special xxx-control KNX channel types.

If channel BDW0 is still of xxx-control type, it is not going to do anything with any command on a linked Item.
If channel BDW0 is still of contact-control type, it is not going to do anything with any ON/OFF states of a linked Item, because it expects OPEN/CLOSED.

So you just need to be consistent from end to end here.

I try :upside_down_face:

That, I understand. And it’s not the case. The ‘simple’ and the ‘grouped’ contact are now of a different type, which I don’t particularly like in terms of consistency, but so be it:

  - id: BDW0_
    channelTypeUID: knx:switch-control
    label: Windows Dirk
    description: Virtual for z2m, BDW1 || BDW2
    configuration:
      ga: 1.001:6/2/15
  - id: BHW0_
    channelTypeUID: knx:contact-control
    label: Window Hervé
    description: Virtual for z2m
    configuration:
      ga: 1.009:6/2/25

That, I do not understand. I thought this was the very purpose of a xxx-control type channel, control a KNX group address, without any command being issued within KNX, but from outside (i.e. openHAB). And that’s also how it works for channel BHW0 (of contact-control type). Anyway, I changed channel BDW0 for the purpose of the argument to type switch) and still no reaction in KNX. What am I doing wrong?

imagine like this you have a nice philips hue light but that doesnt talk knx and we have a knx switch to control it so what we do is create a group adress in ets for that button to talk to when its pressed but the group only has that button so what we do we use the openhab control channel to link to that group adress and also the channel for the philips hue into an item so whenever you press the button that group adress will be transfered to openhab and openhab in turn will relay that state to the philips hue binding channel wich in turn will put the light on

That I understand as well. And i’m also using that very same procedure and set up to link in my zigbee sockets and lightbulbs into KNX, for example to include them into KNX scenes (or as you describe) simply get them switched by a KNX wall switch.

My situation here, is different, though. It’s actually the other way around:

  • A zigbee contact sensor is installed on a window. That sensor is linked via zigbee2mqtt and the mqtt topic Thing to an openHab Item. In turn, that Item, is also linked, via a KNX Thing of type contact-control to a KNX group address. Within KNX, I’m linking that group address to the ‘Window contact’ input of my room temperature controller, so it ((sort of) shuts down the radiator if the window is open. This works just fine!

  • What does not work is the following: I have two zigbee contact sensors on the two windows in a single room and I want to feed the combined ('OR’ed) window sensor information to the KNX room temperature controller, as if it were a single window contact (i.e. shut down the radiator, if any of the two windows is open). To that end, I was following the initial logic of the single-contact case (above) with the following adaptations:

  1. Created a Group:Contact:OR(OPEN,CLOSED) WindowGroup Item, which consolidates the two sensors. This works and the Item has the correct OPEN state, if I open either or both windows.

  2. Tried to link the WindowGroup Item to a contact-control type channel of a KNX Thing. I learned that this doesn’t work, as Group Items cannot send any commands to channels. Fine.

  3. Created an additional Contact Windows Item, linking it to the KNX Thing of type contact-control. Plus a Rule, supposed to send a command with the state of the WindowGroup to that Item. That didn’t work, as you cannot send commands to Contact Items (for reasons I understand).

  4. I hence replaced it by a Switch Item and changed the Rule so that it sends a OFF for a CLOSED WindowGroup (and ON for OPEN). I changed the KNX Thing to be of type switch-control and modified the DPT in both the Thing definition and in ETS. Unfortunately, still no trace of the WindowGroup changes of state within KNX.

  5. Although I still don’t understand why a xxx-control type Thing is inappropriate here (since it works with a contact-control Thing in the single sensor case), I tried to modify the Thing to be of type switch. Unfortunately also that did not yield any result (i.e. reaction within in KNX).

then its very simple you just need to update that group adress with the state of your zigbee contact

rule "send status"

when
    Item WindowGroup changed
then
    if (WindowGroup.state == OPEN) {
        sendCommand(Windows , ON)
    } else {
        sendCommand(Windows , OFF)
    }
end

Windows being the switch item linked to the group adress you want your thermostat controller to read the status of the window and WindowGroup being the openhab zigbee group Group:Contact:OR(OPEN,CLOSED) WindowGroup

Oh wait how is your knx topology only one line ? what happens when you switch on or off the item does it go to the knx bus ?

Did the test on real installation
so this is what i have

Group:Contact:OR(OPEN,CLOSED) g_main_room_top_window_heating
Switch Main_room_top_heating_window_status_input {channel="knx:device:bridge10:top_floor_heating:heating_window_status_input_big_room_top" }
Contact Main_area_Window2 "Window main are top left full [%s]" <window> (g_main_room_top_window, g_general_windows,g_general_windows_counting, g_main_room_top_window_heating) ["OpenState"] {channel="knx:device:bridge10:top_floor_windows:main_room_top_left_full_window" }
Contact Main_area_Window5 "Window main are top right full [%s]" <window> (g_main_room_top_window, g_general_windows,g_general_windows_counting, g_main_room_top_window_heating) ["OpenState"] {channel="knx:device:bridge10:top_floor_windows:main_room_top_right_full_window" } 
Type switch        : heating_window_status_input_big_room_top   "Window status input big room top floor" [ ga="3/1/3" ]
Type contact        : main_room_top_left_full_window      "main room full left window"        [ ga="1.019:<3/3/1" ]
rule "big room top floor windows heat"

when
    Item g_main_room_top_window_heating changed
then
    if (g_main_room_top_window_heating.state == OPEN) {
        sendCommand(Main_room_top_heating_window_status_input , ON)
    } else {
        sendCommand(Main_room_top_heating_window_status_input , OFF)
    }
end

it works just fine when i open one of the windows the heating shuts down from the knx thermostat keep in mind the thermostat has an window input that does all the logic inside the thermostat and that has a write flag not a read flag

The first solution

does not work, as per this explanation:

No, that’s what an ‘ordinary’ KNX channel does (and practically every other binding channel as well).

It’s vital to distinguish Item commands (“do something” instructuctions) from Item state (“this is the condition”) within openHAB,
Switches get especially confusing as we call the instruction ON and the condition report ON as well, but they are not the same. Dimmers make better examples, where the state may be 70% and we can issue command INCREASE.

Okay, so in the ordinary way Item commands are listened for by the channel, and sent to the target device.
Incoming messages from a device are processed into Item state updates.
Ordinary KNX channels like switch type worjk that way.

The KNX xxx-control type channels are special - they reverse that flow.
Incoming messages from the device are sent as commands to the Item. And the bit you’re interested in, internal Item state updates are sent out to KNX.
Why would you want that? It’s intended for something like a glass control panel - the user poking the panel ends up as a command, an instruction within openHAB. An Item changing state gets reported out to KNX, so that the panel can make its graphic green or red or whatever.

Wow, @rossko57! Thanks a lot for the detailed explanation.

Just wondering now:

So you are actually saying, I do need a xxx-control channel like the one I have been trying to use.

I aggregate the individual contacts into a Group:Contact:OR(…). Then I use the change of state of that Group to trigger a state update on a Contact Item (which follows the Group state as is).

Contact OfficeDirk_Windows "Windows" (OfficeDirk)
  {channel="knx:device:_:__W:BDW0_"}
Group:Contact:OR(OPEN,CLOSED) OfficeDirk_WindowGroup "Windows Group" (OfficeDirk, WindowGroup)
Contact OfficeDirk_WindowRight "Window Right" <window> (OfficeDirk, OfficeDirk_WindowGroup, SecondFloor_Windows, WindowContact) ["Window"]
  {channel="mqtt:topic:_:__W:BDW1"}
Contact OfficeDirk_WindowLeft "Window Left" <window> (OfficeDirk, OfficeDirk_WindowGroup, SecondFloor_Windows, WindowContact)  ["Window"]
  {channel="mqtt:topic:_:__W:BDW2"}
var knxItemName = event.itemName.replace('WindowGroup','Windows');
var knxItem = items.getItem(knxItemName);
var knxState = items.getItem(event.itemName).state;

console.log(knxItemName, knxItem, knxState);

knxItem.postUpdate(knxState);

and then this Contact Item could be linked to a contract-control channel , since

“internal Item state updates are sent out to KNX.”

as you say?

  - id: BDW0_
    channelTypeUID: knx:contact-control
    label: Windows Dirk
    description: Virtual for z2m, BDW1 || BDW2
    configuration:
      ga: 1.009:6/2/15

It’s just … it doesn’t work… absolutely nothing within KNX.

can you show a screen shot of the group adress content in ets that you want to send all this ?

sure

I still dont get it you want to send the status of your zigbee contacts to your knx input interface ?? is that what you want to do ?
or is that the input for the logic of the thermostat ?

That’s precisely what it is. Communication object 34, feeds into the “Window contact” input of the GIRA Tastsensor thermostat.

Once again, this works perfectly for some other window/thermostat combination, where I relay the zigbee2mqtt contact directly into KNX, without going through an OR-Group or a dummy switch/contact.

Just like yourself, I’m suspecting the problem lies in the communication between openHAB and KNX, but I just cannot see any difference between the two Thing/Group address links.

Make sure your rule is functional - does the given Item really get an update? You should see state changes (but not updates-to-same) in your events.log.
Thinking about it, I’m not really sure if the xxx-control channel responds to Item state updates or only to change. Either makes sense in practice, so be sure to invoke a change for testing.

You’ve been changing types, channels, etc. The KNX binding is one of the venerable ones, from before everyone expected editing config files to have an immediate effect.
If you are confident in your current sertup (looks okay to me, I don’t understand the KNX ga stuff but you have that working for other channels) - reboot for a clean slate on the binding and its links.