Contact KNX Items don't seem to be sent with OH 4.1.0

Hi all,
I seem to be facing a weird issue with OH 4.1.0. I’m pretty sure that the issue wasn’t present with 4.0.4, but I only had that running for a day or so before upgrading to 4.1.0.

I have a pretty extensive KNX installation and one function that I am using OH rules for is to aggregate some contacts into a summary state.

Let me give you an example: Here are some window and door contacts for my garage, and I am pushing a summary state for “is there any door left unlocked in the garage” back to the KNX bus using this rule:

rule Garage_Contacts
	Item TuerNord changed or
	Item TuerSued changed or
	Item Fenster_EG2_Kipp changed or
	Time cron "0 0/10 * ? * * *"
	if ((TuerNord.state == OPEN) || (TuerSued.state == OPEN) || (Fenster_EG2_Kipp.state == OPEN)) {
		logInfo("RULE Garage_Contacts open:","Nord: " + TuerNord.state.toString +", Sued: " + TuerSued.state.toString +", EG2: "+Fenster_EG2_Kipp.state.toString )
	} else {
		logInfo("RULE Garagecontacts closed:","Nord: " + TuerNord.state.toString +", Sued: " + TuerSued.state.toString +", EG2: "+Fenster_EG2_Kipp.state.toString )

All items here are type “contact” items and they all link to KNX channels.

Contact Garage_Tuerkontakt "Garage Tuerkontakt" {channel="knx:device:bridge:OH2-contacts:Garage_Tuerkontakt"}

Here’s the things definition:

Type “contact” for the channels that get fed from the actual KNX binary input sensors:

Type contact    : gGarage_TuerNord      "Garage Tuer Nord unverriegelt"         [ ga="5/5/12"]
Type contact    : gGarage_TuerSued      "Garage Tuer Sued unverriegelt"         [ ga="5/5/13"]
Type contact    : Fenster_EG2_Kipp      "Fenster Garage gekippt"                [ ga="5/5/101"]

Type “contact-control” for the item that I am using OH to generate

Type contact-control : Garage_Tuerkontakt   "Ein Fenster oder Tuer in Garage offen"                 [ ga="5/5/100"]

The rule runs whenever the state of one of the items changes, or every 10 minutes. I have an LED display that visually tells me if everything is closed (green) or if there is a door open (red). It also monitors the knx address and if there isn’t any update within 30 minutes, it assumes communication is lost and it begins to flash red. This is exactly what is happening.

In my log, I can see the rule firing:

2023-12-25 09:40:00.939 [INFO ] [l.script.RULE Garagecontacts closed:] - Nord: CLOSED, Sued: CLOSED, EG2: CLOSED

Since I have two different log messages programmed in the rule, I can tell that it evaluated the contacts correctly and everything is closed, so I would expect it to send an update to the “Garage_Tuerkontakt” items with state “closed”.
I switched on event log debugging and can see that this actually happened as well:

2023-12-25 09:40:00.941 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'Garage_Tuerkontakt' received command CLOSED
>2023-12-25 09:40:00.942 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'Garage_Tuerkontakt' predicted to become CLOSED
>2023-12-25 09:40:00.942 [INFO ] [openhab.event.ItemStateEvent        ] - Item 'Garage_Tuerkontakt' shall update to CLOSED

Yet, I can see no update actually being sent to the KNX bus and also KNX binding debug logging doesn’t show an update being triggered.

Any idea what might be going on? I have a ton of these rules basically collecting contact status of all the windows and doors and putting out group items for every room and so on. None of these seem to work right now. All are set up with a similar logic (update the status if an individual contact status changes or refresh every 10 minutes). A rule where I count the number of open windows and put out a number item to a knx channel works without a problem, so this seems to be isolated to contact type channels.



It could be related to this issue / discussion:

It seems strange however, that this worked up to 4.0.4 and silently fails now. I also wonder why there is infrastructure in place for “contact-control” if as @Udo_Hartmann puts it:

As a contact Item is to refer to Contacts (at least by meaning), there is simply no command, a contact is not to be controlled from openHAB by definition.

There is no (and in fact there never was) such a thing as a OPEN / CLOSED command, instead you always had to postUpdate() that Item.

So simply change the rule slightly to be correct:

rule Garage_Contacts
	Item TuerNord changed or
	Item TuerSued changed or
	Item Fenster_EG2_Kipp changed or
	Time cron "0 0/10 * ? * * *"
	if ((TuerNord.state == OPEN) || (TuerSued.state == OPEN) || (Fenster_EG2_Kipp.state == OPEN)) {
		logInfo("RULE Garage_Contacts open:","Nord: " + TuerNord.state.toString +", Sued: " + TuerSued.state.toString +", EG2: "+Fenster_EG2_Kipp.state.toString )
	} else {
		logInfo("RULE Garagecontacts closed:","Nord: " + TuerNord.state.toString +", Sued: " + TuerSued.state.toString +", EG2: "+Fenster_EG2_Kipp.state.toString )

However, a more simple solution would be to use a Group:

Group:Contact:OR(OPEN|CLOSED) gGarageC "Garage offen [%d]"
Contact Garage_Tuerkontakt "Meldung nach knx"
Contact TuerNord "Tür Nord" (gGarageC)
Contact TuerSued "Tür Süd" (gGarageC)
Contact Fenster_EG2_Kipp "Fenster Kipp" (gGarageC)

Now the rule is much more simple:

rule "Garage Contacts"
    Time cron "0 0/10 * * * ?" or
    Member of gGarageC changed
    logInfo("garageContacts","Nord: {}, Süd: {}, EG2: {}", TuerNord.state, TuerSued.state, Fenster_EG2_Kipp.state)
    if(gGarageC.members.filter[c|c.state != CLOSED].size > 0) 

Whenever a state of a member of the Group gGarageC changes, the rule is triggered. (and also, although not needed, every ten minutes)
The logger logs all three states.
Now all Items of the Group gGarageC are filtered for a state different to “CLOSED”. The list then is counted, and if the size is greater than 0, it will set the state of Garage_Tuerkontakt to OPEN, otherwise the state is set to CLOSED.

Please be aware that the first given string to logInfo(string,string) is the logger name. It should not contain spaces nor special characters. The full logger name starts with org.openhab.core.module.script. for each logger in rules, so you don’t need to name it “rule” at all. The logger name is used to control if the logger will write or not (from karaf console log:set WARN org.openhab.core.module.script.garageContacts will stop the output for the line above)
The logger will substitute every pair of curly brackets {} with the next given parameter. It will automatically change that to string.

Another thing: Maybe you don’t need the Item Garage_Tuerkontakt nor the rule at all, simply check whether the Group Item can be linked to the Channel (I’m not sure about this detail). The Group Item gGarageC will always show state OPEN as long as there is at least one Member Item of state OPEN

Fun fact: The Item gGarageC will show the count of OPEN Members in the label, but the state will be OPEN or CLOSED. This is a nice feature (available since OH0.x)

1 Like

Hello Udo,

postUpdate doesn’t work either. Events.log doesn’t register the update (if the rule was just triggered by the timer and not leading to an actual state change of the output item). Consequently, no update is sent to the KNX Bus. I’m guesssing the other examples you posted would behave the same. Any idea short of converting all the items to switches and sending ON/OFF instead of OPEN/CLOSED?

Edit: I also tried to set the channel of the output item with the follow profile:

Contact Garage_Tuerkontakt "Garage Tuerkontakt" {channel="knx:device:bridge:OH2-contacts:Garage_Tuerkontakt"[profile="follow"]}

I guess this only works if you actually link two channels, so this didn’t help either.



Also, channel linking doesn’t seem to work for contacts any longer. Some of my contacts are on a building alarm system from Telenot. I use the Telenot community binding to access the status of those contacts, The relevant items are also channel-linked to KNX channels to replicate the contact status on the bus:

Contact Fenster_OG9_Offen (gOG_AZ,Fenster_Detail) {channel="telenot:mp:c400:Fenster_OG9_Offen:contact", channel="knx:device:bridge:C400:Fenster_OG9_Offen"}

In the event log I can see the items getting updated and chaning their status, however nothing gets sent to the KNX bus. Even if I set the KNX channel to the follow profile, no KNX telegrams get sent.

Contact Fenster_OG9_Offen (gOG_AZ,Fenster_Detail) {channel="telenot:mp:c400:Fenster_OG9_Offen:contact", channel="knx:device:bridge:C400:Fenster_OG9_Offen"[profile="follow"]}

Am I doing this right? Once again, I am 100% sure that this worked with OH3.4 (even without the follow profile). By now this smells even more of a bug than a feature, really. I can’t help but wonder about the reasoning to introduce such a breaking change in a minor release.



I group them and then use a rule to send whatever value I need to the bus. For example a knx thermostat has an input for windows I use openhab to agregate because it’s easier.

Group:Contact:OR(OPEN,CLOSED) g_kitchen_ground_floor_window_heating

Contact  Kitchen_door1 "Kitchen left side left [%s]" <door> (g_kitchen_ground_floor_doors, g_general_door,g_general_door_counting,g_kitchen_ground_floor_window_heating,g_kitchen_ground_floor_window_airco,g_general_door_important) ["OpenState"] {channel="knx:device:bridge1:ground_floor_windows_doors:kitchen_left_side_left" }

Contact  Kitchen_door2 "Kitchen left side right [%s]" <door> (g_kitchen_ground_floor_doors, g_general_door,g_general_door_counting,g_kitchen_ground_floor_window_heating,g_kitchen_ground_floor_window_airco,g_general_door_important) ["OpenState"] {channel="knx:device:bridge1:ground_floor_windows_doors:kitchen_left_side_right" }
Contact  Kitchen_door3 "Kitchen right side left [%s]" <door> (g_kitchen_ground_floor_doors, g_general_door,g_general_door_counting,g_kitchen_ground_floor_window_heating,g_kitchen_ground_floor_window_airco,g_general_door_important) ["OpenState"] {channel="knx:device:bridge1:ground_floor_windows_doors:kitchen_right_side_left" }
Contact  Kitchen_door4 "Kitchen right side right [%s]" <door> (g_kitchen_ground_floor_doors, g_general_door,g_general_door_counting,g_kitchen_ground_floor_window_heating,g_kitchen_ground_floor_window_airco,g_general_door_important) ["OpenState"] {channel="knx:device:bridge1:ground_floor_windows_doors:kitchen_right_side_right" }

Switch Kitchen_heating_window_status_input {channel="knx:device:bridge1:ground_floor_heating:heating_window_status_input_kitchen" }
Number Kitchen_Temperature "Temperature average kitchen[%.1f %unit%]" <temperature> (g_kitchen_ground_floor_heating, g_general_heat_sensor) ["Measurement"] {channel="knx:device:bridge1:ground_floor_heating:effective_temperature_kitchen" }
Number Kitchen_Temperature_floor "Temperature floor kitchen [%.1f %unit%]" <temperature> (g_kitchen_ground_floor_heating, g_general_heat_sensor) ["Measurement"] {channel="knx:device:bridge1:ground_floor_heating:floor_temperature_kitchen" }
Number Kitchen_Temperature_ambient "Temperature ambient kitchen[%.1f %unit%]" <temperature> (g_kitchen_ground_floor_heating, g_general_heat_sensor) ["Measurement"] {channel="knx:device:bridge1:ground_floor_heating:touch_screen_temperature_kitchen" }
Number Kitchen_Temperature_SETPOINT "Set temperature kitchen [%.1f %unit%]" <heating> (g_kitchen_ground_floor_heating, g_general_heat_setpoint) ["Setpoint", "Temperature"] {channel="knx:device:bridge1:ground_floor_heating:setpoint_temperature_kitchen", stateDescription="" [pattern="%.1f °C"], listWidget="oh-stepper-item" [step=0.5, min=0, max=30, enableInput=true], widget="oh-stepper-card" [step=0.5, min=0, max=30, enableInput=true]}
Number Kitchen_Heatstatus "Underfloor heating status kitchen [MAP(]" <flow>  (g_kitchen_ground_floor_heating, g_general_heat_status)  ["Status"] {channel="knx:device:bridge1:ground_floor_heating:floor_heating_status_kitchen" }
Number Kitchen_electrovan_alarm "Electrovan alarm status kitchen [MAP(]" <error>  (g_kitchen_ground_floor_heating, g_general_alarm_electrovan_status)  ["Status"] {channel="knx:device:bridge1:ground_floor_heating:floor_heating_status_alarm_electrovan_kitchen" }
Switch Kitchen_electrovan "Electrovan manual control kitchen" <faucet> (g_kitchen_ground_floor_heating) ["Control"] {channel="knx:device:bridge1:ground_floor_heating:electrovan_control_kitchen"}

rule "kitchen windows  heat"

    Item g_kitchen_ground_floor_window_heating changed
    if (g_kitchen_ground_floor_window_heating.state == OPEN) {
        sendCommand(Kitchen_heating_window_status_input , ON)
    } else {
        sendCommand(Kitchen_heating_window_status_input , OFF)


I can confirm this after upgrade of OH4.0.4 to OH4.1 all my window contacts are not sent anymore to the KNX-Bus. I havent changed anything in the things or items.

item example:

Contact Fensterkontakt_Kuechentuer       "Fenster Küche [%s]"             <window_2w> (gFenster, gFenster_Rotini, gFenster_CV, gFenster_KNX, gFenster_Wohnzimmer, gFensterkontakt_Kuechentuer)                      { ga="Window", alexa="ContactSensor", channel="mqtt:topic:mosquitto:Xiaomi_Fensterkontakt_Kuechentuer:contact,      knx:device:bridge:Raumcontroller_Kueche:KNX_Kueche_Fensterkontakt" }

KNX Thing example

Type contact-control       : KNX_Kueche_Fensterkontakt   "Küche Fensterkontakt"      [ ga="1.019:5/1/2" ]

best regards René

Remove the -control.
Control is when for example knx needs to control your mqtt stuff


I believe control is required as the contact sensor is not an KNX device, it is an zigbee contact sensor.

Description from the manual:
“Control channel types (suffix -control) are used for cases where the KNX bus does not own the physical state of a device.”

best regards René

Control means openhab becomes a knx input so it will respond for example on a knx read from the bus with status from your ZigBee device.
I stand to be corrected otherwise.

To my understanding, you are both correct. The thing definition needs -control to be added since the KNX bus is not owning the status of the device, but rather OH is, so indeed, it should be able to respond to query from or send status updates to the KNX bus.



btw, I solved my issue for the moment by converting all my contact-control things to switch-control things and sending “on/off” rather than “open/closed”. It’s a bit tedious since it also meant removing all the channel links between my source binding and the knx targets.
@Rene, a shot might be to add [profile:“follow”] to you KNX channel in the item definition. It didn’t help for me, but who knows?

The only thing I have to add here is that an input is an input not an output so it cannot be both.


So is this an known bug and will be fixed?

Best regards Rene

That is indeed still unknown. I opened an issue at Github for it but so far no feedback.

I just stumbled upon this issue as i was configuring my first contact-control in order to get the status to KNX. The binding only is responding to reads, when the value got written over the bus. Even when the state changes in OpenHAB the old value from the write gets returned on read. No state change is sent automatically.


// Channel MQTT
Type contact : contact [ stateTopic = "zigbee2mqtt/Contact_Test", transformationPattern="JSONPATH:$.contact", on="false", off="true" ]

// Channel KNX
Type contact-control : cont_test   "Test" [ ga="6/3/0" ]

// Item
Contact cont_test "Test" { channel="knx:device:bridge:openhab:cont_test", channel="mqtt:topic:contact_test:contact" }

Logs on write from bus:

Item 'cont_test' received command ON
Item 'cont_test' predicted to become OPEN
Item 'cont_test' changed from CLOSED to OPEN

On read:

Item 'cont_test' received command REFRESH

→ OPEN telegram is sent over the KNX bus.

Item changes over MQTT:

Item 'cont_test' changed from OPEN to CLOSED
Item 'cont_test' received command REFRESH

On read:

Item 'cont_test' received command REFRESH

→ Still a OPEN telegram is sent over the KNX bus.

The same configuration, but with switch-control instead of contact-control, works as expected.

1 Like

It seems that the initial investigation of the KNX binding indeed might point to an issue with contact-control channels.

[knx] OH 4.1.0 KNX binding fails to send updates to contact-control items #16115


I have updated Today to the latest release 4.1.1 but still the same error.

best regards René

Hi 2 All,

I’ve updated to 4.1.3. The issue exists. What version should have these changes?

I’m pretty sure there is no issue at all.

  1. There is no such command as OPEN/CLOSED (really!).
  2. You simply can’t command a contact Item. (for sure!) *)
  3. *-control channels are indeed meant to control non-knx actuators from within knx.
  4. But *-control channels have another implication, too. A *-control channel will act reverse to a non-control channel:
Type    | received GA results in | postUpdate results in | sendCommand results in
normal  | received update Event  | update only the Item  | send command to knx
control | received command Event | send update to knx    | --

So in fact for a linked contact-control channel a myContactItem.postUpdate(OPEN|CLOSED) should result in a GA telegram!
The point is: if there is, let’s say a mqtt channel which receives OPEN/CLOSED messages from some contacts it should suffice to link both channels (mqtt and knx-control) to the same contact Item without any additiontal profile:

// Channel in Thing mqttThing
Type contact : chan27 "Window 14" [stateTopic="window/contacts/channel12"]
// Channel in Thing knxThing
Type contact-control : ch1 "Window 1" [ ga="1/1/1" ]


Contact windowContact "my Window" {channel="mqtt:topic:broker:mqttThing:chan27", channel="knx:brdge:knxThing:ch1"}

Of course UIDs are completely random :slight_smile:

*) In fact, a Contact Item can receive a command: MyContact.sendCommand(REFRESH) This will result in a forced state update, if the addon does support this command.

Hmm, i‘m guessing the bugfix has only been applied to the code that will go into OH4.2. A workaraound to solve the problem for now would be to convert all contact-control items to switch-control so that it works with 4.1.3…

@Udo_Hartmann you can see from the testing I did above that neither postUpdate nor channel linking works for contact-control at the moment.