KNX-HomeKit-CarPlay-Garage Door Opener

Thank you eugen for your code. As I see (and you also wrote) you have one switch but I have now Up and Down. The behaviour is like this: If you press UP the door opens and if you press any switch again the door stops.
I will try to implement your code but I am not sure doing this for UP/DOWN-Switches.
The Alexa stuff can be deleted, can it?

alexa="ModeController.mode" [category="EXTERIOR_BLIND", supportedModes="Closed=@Value.Close, Open=@Value.Open",actionMappings="Close=Closed,Open=Open", friendlyNames="Garage", language="de"]

Oh you have language=“de”. Are you speaking German? I am from Austria. :wink:

i have only one switch for garage opener which react on event like this “Open-Stop-Close-Stop”

alexa stuff can be removed.

do you have a sensor or other way to derive the current status of the door, e.g. close/open?
at the end you need to provide the current and target states.

e.g. if “UP” switch is activated you would set the target state to “OPEN”, if “DOWN” is activated then to “CLOSED”.

I have now implemented this in my items file but the garagedooropener is not shown in my HomeKit app.

Group gGarage           "Garage"             {homekit="GarageDoorOpener"}
Switch  garageObstruction "Garage Obstruction"       (gGarage)       {homekit="ObstructionStatus"}
String  garageCurrentState "Garage Current State [%s]"  (gGarage)       {homekit="CurrentDoorState"}
String  garageTargetState "Garage Target State [%s]"    (gGarage)  {homekit="TargetDoorState"}

hm. if you just added these lines you should already see garage door in home app. if it does not appear:

  • try to restart openHAB and home app
  • try to update homekit integration in openHAB (not sure in which version garage door opener was added)

I did a restart already and also reset the HomeKit bindings (sin openhab console)
I have Homekit 2.5.3 integration, I think this is an actual one.

ok. 2.5.3 is a pretty old one. the latest one is 2.5.7
check this post for update instructions

Can u tell me, what I have to provide for “id of homekit binding” in the update command?

Edit Ok I got it by using “list” command

Ok, now I see the garage door opener in the homekit app. I have to check now if my modified rule is working.

It seems I have a logic issue in my rules.

rule "garage door state update"
when
     Item garageDoorStatus received update
then
     if (garageDoorStatus.state == "OPEN" ) {
        garageCurrentState.sendCommand("OPEN")
        garageTargetState.postUpdate("OPEN")
        garagentorZu.postUpdate(OFF)
        garagentorAuf.postUpdate(OFF)
     } else {
        garageCurrentState.sendCommand("CLOSED")
        garageTargetState.postUpdate("CLOSED")
        garagentorZu.postUpdate(OFF)
        garagentorAuf.postUpdate(OFF)
     }
end

rule "garage door target state"
when
     Item garageTargetState received command
then
        if (garageTargetState.state == "OPEN") {
                garageCurrentState.sendCommand("OPEN")
                garagentorAuf.sendCommand(ON)
                garagentorZu.postUpdate(OFF)
        } else if (garageTargetState.state == "CLOSED") {
                garageCurrentState.sendCommand("CLOSED")
                garagentorZu.sendCommand(ON)
                garagentorAuf.postUpdate(OFF)
        }
end

lets first focus on garageTargetState rule. this rule gets triggered when you change garage door target state in home app, e.g. click on “close door”

important is to know the difference between sendCommand and postUpdate.

  • sendCommand sends update to the actual device (via binding)
  • postUpdate change the status in openHAB (e.g. in paperUI) without sending the command to the actually device.

means, in your case you should use sendCommand for garagentorAuf/garagentorZu.
e.g.
garagentorAuf.sendCommand(ON)
garagentorZu.sendCommand(OFF)

the next is to check whether garagentorAuf/garagentorZu are working independent of homekit. what happens if you change the values via paper UI?

I am not at home now. When i am back i am going to check the rules again.
I guess i have to rethink my rules. Also i am using a real contact sensor for the state of the door. This i a knx contact which sends contact close when door is completely closed and open when door is not in closed state.

Do you also have a real contact on your door?

garagentorAuf / garagentorZu Items are working. I have them visible in Homekit and Openhab Ui.

In garageTargetState rule i am sending the command to the items. The postUpdate command is to set the visible state in the Ui (Homekit ui and openhab ui).
This is because openhab does not have push buttons.

yes, i have physical contact sensor (based on homematic) that reports open/close state for the door

I am a little confused on the DPT for my contact sensor.

In the documentation they write Default DPT for a contact is 1.009

But in the attached example near the end of the page they use 1.019 as DPT.

Type contact       : demoContact       "Door"        [ ga="1.019:<5/1/2" ]

What is right now and what do I use if I have more contacts (like window contacts)?
Also State is not read from contact. Is your physical contact thing also from type contact?

I am also getting warnings in the log file after restarting openhab:

2020-08-09 19:31:36.449 [WARN ] [essories.HomekitGarageDoorOpenerImpl] - Current door state not available. Relaying value of CLOSED to HomeKit

2020-08-09 19:31:36.450 [WARN ] [essories.HomekitGarageDoorOpenerImpl] - Unsupported value NULL for garageTargetState. Only CLOSED and OPEN supported. Check HomeKit settings if you want to change the mapping

If found out now that using “String” does not work for me.

String    garageDoorStatus     "Garage door Status [%s]"  <door>  (gGarageDoor)      {homekit="ContactSensor",.......}

I have to use a Contact

Contact         garageDoorStatus        "Garagentor [%s]"                       <door>          (KG_Garage)     {homekit="ContactSensor",.......}

So now after a while restarting contact sensor for the door is read correct using

knx.things

Type contact        : garagentorSensor      "Garangentor Status"    [ga="1.019:<2/0/1"]

knx.items

Contact         garageDoorStatus        "Garagentor [%s]"                       <door>          (KG_Garage)     {homekit="ContactSensor", channel="knx:device:bridge:Garagentor_Sensor:garagentorSensor" }

The syntax on the rules file is so bad. I am trying this rule:

rule "garage door state update"
when
     Item garageDoorStatus received update 
then
        logDebug("GarageDoor", "garageDoorStatus.state --> " + garageDoorStatus.state )
        var curState = garageDoorStatus.state
        logDebug("GarageDoor", "curState --> " + curState )
        switch(curState) {
                case "OPEN": {
                logDebug("GarageDoor", "case OPEN done" )
                garageCurrentState.sendCommand("OPEN")
                garageTargetState.postUpdate("OPEN")
                }
                case "CLOSED": {
                logDebug("GarageDoor", "case CLOSED done" )
                garageCurrentState.sendCommand("CLOSED")
                garageTargetState.postUpdate("CLOSED")
                }
        }
end

But the switch statement is not working and I don’t know why.
Log is outputting everything until switch(curState)…

Oh really?! It must case the command and not the string of the command.

rule "garage door state update"
when
     Item garageDoorStatus received update 
then
        logDebug("GarageDoor", "garageDoorStatus.state --> " + garageDoorStatus.state )
        var curState = garageDoorStatus.state
        logDebug("GarageDoor", "curState --> " + curState )
        switch(curState) {
                case OPEN: {
                logDebug("GarageDoor", "case OPEN done" )
                garageCurrentState.sendCommand("OPEN")
                garageTargetState.postUpdate("OPEN")
                }
                case CLOSED: {
                logDebug("GarageDoor", "case CLOSED done" )
                garageCurrentState.sendCommand("CLOSED")
                garageTargetState.postUpdate("CLOSED")
                }
        }
end

So now it works with this rules. I think it is totally confusing. Receiving an update is posted as Command (no string e.g OPEN) but receiving a command is posted as string (e.g “OPEN”)

Here is the solution for using an UP and DOWN button for a garageDoorOpener with KNX:

knx.things

/*Garagentor*/
    Thing device Schaltaktor_Garagentor [
        address="1.1.6",
        fetch=true,
        pingInterval=300,
        readInterval=3600
    ] {
    Type switch         : garagentorAuf    "Garagentor Auf"            [ga="2/0/2"]
    Type switch         : garagentorZu     "Garagentor Zu"             [ga="2/0/3"]
    }

    Thing device Garagentor_Sensor [
        address="1.1.15",
        fetch=true,
        pingInterval=300,
        readInterval=3600
    ] {
    Type contact        : garagentorSensor      "Garangentor Status"    [ga="1.019:<2/0/1"]
    }

knx.items

Group   gGarage                 "Garage HomeKit"                                        {homekit="GarageDoorOpener"}

/*Garage*/
Switch          garagentorAuf      "Garagentor Auf"                                             (KG_Garage)     { channel="knx:device:bridge:Schaltaktor_Garagentor:garagentorAuf" }
Switch          garagentorZu      "Garagentor Zu"                                               (KG_Garage)     { channel="knx:device:bridge:Schaltaktor_Garagentor:garagentorZu" }
Contact         garageDoorStatus        "Garagentor [%s]"                       <door>          (KG_Garage)     {homekit="ContactSensor", channel="knx:device:bridge:Garagentor_Sensor:garagentorSensor" }

knx.rules (logDebug can be ignored)

rule "garage door state update"
when
     Item garageDoorStatus received update 
then
        logDebug("GarageDoor", "garageDoorStatus.state --> " + garageDoorStatus.state )
        var curState = garageDoorStatus.state
        logDebug("GarageDoor", "curState --> " + curState )
        switch(curState) {
                case OPEN: {
                logDebug("GarageDoor", "case OPEN done" )
                garageCurrentState.sendCommand("OPEN")
                garageTargetState.sendCommand("OPEN")
                garageTargetState.postUpdate("OPEN")
                }
                case CLOSED: {
                logDebug("GarageDoor", "case CLOSED done" )
                garageCurrentState.sendCommand("CLOSED")
                garageTargetState.sendCommand("CLOSED")
                garageTargetState.postUpdate("CLOSED")
                }
        }
end


rule "garage door target state"
when
     Item garageTargetState received command
then
        logDebug("GarageDoor", "garageTargetState.state --> " + garageTargetState.state )
        var curTargetState = garageTargetState.state
        logDebug("GarageDoor", "curTargetState --> " + curTargetState )
        switch(curTargetState) {
                case "OPEN": {
                logDebug("GarageDoor", "Garage Door will be open")
                garageCurrentState.sendCommand("OPEN")
                garagentorAuf.sendCommand(ON)
                //garagentorAuf.postUpdate(OFF)
                }
                case "CLOSED": {
                logDebug("GarageDoor", "Garage Door will be closed")
                garageCurrentState.sendCommand("CLOSED")
                garagentorZu.sendCommand(ON)
                //garagentorZu.postUpdate(OFF)
                }
        }
end

Only one thing is still to solve: What if the door is opening or closing and you change the state in den garageOpener item in homekit. In my case the door stops in current position. I think another rule is needed. Maybe also a second physical contact too.

1 Like

cool. you found the solution.
im also thinking about the second contact sensor. currently i can only see whether the garage is closed or not, but not whether it is completely open or stopped somewhere in the middle… maybe even something with movement sensor…

1 Like

I will think about it next days. I have an unused channel on my knx device. Maybe i will get another physical magnetic contact and test it then.

Thank you very much eugen for your help and your sample code!

An idea could be to run a timer on open or closing the garage door. If a „stop command“‘is send, then the timer is stoppt and you know, that the door is neither open nor closed if timer is not run to zero. And before starting the timer store the current state of the door into a variable.
Could be getting complex, but maybe will work.