Help with MQTT Rollershutter item

Hi there, grateful for any help. I have an MQTT garage door controller that works as follows:

“OPEN” on “garage/door/1/action” opens the door
"CLOSE" on “garage/door/1/action” closes the door
"open" is published to “garage/door/1/status” when the door opens
"closed" is published to “garage/door/1/status” when the door closes

I have created a Rollershutter item as follows:

Rollershutter GarageDoor "Garage Door" <garagedoor> (gOutdoor) {mqtt=">[mosquitto:garage/door/1/action:command:UP:OPEN],>[mosquitto:garage/door/1/action:command:DOWN:CLOSE],>[mosquitto:garage/door/1/action:command:STOP:default],<[mosquitto:garage/door/1/status:state:default]", autoupdate="false"}

And added it to my sitemap as follows:

Switch item=GarageDoor

Commanding the garage door works fine - clicking the up arrow makes the door go up, clicking the down arrow makes the garage door go down.

But how is the state captured in the UI? The icon doesn’t change when the door is open or closed, even though I’m using the dynamic icon and there are icon files for garagedoor-open and garagedoor-closed.

Can someone give me some pointers to integrating a garage door? Is a Rollershutter item the best way to do it?

Rollershutter doesn’t store its state as OPEN/CLOSED, it uses PercentType (i.e. a number between 0 and 100).

Frankly, I’m surprised this is working at all as Rollershutter can only take UP/DOWN, STOP/MOVE, or an integer between 0 and 100. It shouldn’t accept OPEN/CLOSED at all so I’m pretty sure if you looked in the logs you will see errors every time it receives a message on the status topic. So to answer your question about how it is capturing the status…it isn’t capturing the state. You are using the wrong states to drive this Item type.

Furthermore, case matters so if you are posting “open” and “closed” instead of “OPEN” and “CLOSED” it would fail anyway, assuming that Rollershutter could take OPEN/CLOSED in the first place. Contact is the correct Item Type to receive OPEN/CLOSED and to use with the default garagedoor icons.

Are you sure you are using a Switch to put the Item on your sitemap? That would not give you up and down arrows. It would give you a toggle. A Setpoint will give you the up/down arrows, not a switch.

I’ve no experience with Rollershutter so I don’t know what sort of changes to the Item’s state occurs when it receives UP and DOWN commands. But I’m pretty sure this is not a good way to do this. The only way I would use RollerShutter is if your opener reported a percent number showing how far up or down the opener is rather than just OPEN and CLOSED.

Here is how I’ve implemented it (note, I have a lot of things I want to happen when the opener is commanded to open so I use a proxy Item and rule (NOTE: I’ve simplified these to just include one of my openers, these rules are a bit more generic in my setup and handle all of my entry points):

Theory of Operation:

  • Use a proxy item to control the garage door so we can intercept the command and check the status of things and and an alert
  • Use a Contact to represent the state of the opener
  • Additional requirements, generate an alert if the opener changes state and noone is home or it is night time, generate an alert if the door is left open more than an hour

Items: (note there are some Items in the Rules below that are not listed here, more on those later)

// Controls the opener
Switch aGarageOpener1 "Garage Door Opener 1" 

// Status of the opener
Contact vGarageOpener1 "Garage Door Opener 1 is [MAP(en.map):%s]"
  <door> (gDoorSensors)
  { mqtt="<[mosquitto:entry_sensors/main/garage/door1:state:default]" }

String GarageOpener1_Cmd
  { mqtt=">[mosquitto:entry_sensors/main/garage/door1/cmd:state:*:default]" }

Switch vGarageOpener1_Timer
  (gDoorsTimers)
  { expire="1h,command=OFF" }

DateTime vGarageOpener1_LastUpdate "Garage Door Opener 1 [%1$tm/%1$td %1$tH:%1$tM]"
  <clock> (gDoorsLast)

Rules:

rule "Garage Opener 1 Triggered"
when
    Item aGarageOpener1 received command
then
    GarageOpener1_Cmd.sendCommand("TRIGGER") // Any message will cause the opener to trigger on my system

    // Send an alert if the controller is offline
    if(vNetwork_Cerberos.state == OFF) {
        aAlert.sendCommand("Attempting to trigger the garage opener but the controller is offline!")
    }
end

rule "Keep track of when the Garage Door was opened"
when
    Item vGarageOpener1 changed from CLOSED to OPEN or
    Item vGarageOpener1 changed from OPEN to CLOSED
then
    // Update the last time the door was opened
    vGarageOpener1_LastUpdate.postUpdate(new DateTimeType)

    // Set/cancel a timer
    if(vGarageOpener1.state == OPEN) vGarageOpener1_Timer.sendCommand(ON)
    else vGarageOpener1_Timer.sendCommand(OFF)

    // Log the change and alert if no one is home and/or it is night time
    val StringBuilder msg = new StringBuilder
    
    msg.append("Garage door opener was")
    msg.append(if(vGarageOpener1.state == OPEN) " opened" else " closed")

    var alert = false
    if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
        alert = true
        msg.append(" and it is night")
    }

    if(vPresent.state == OFF){
        alert = true
        msg.append(" and no one is home")
    }

    if(alert){
        msg.append("!")
        aAlert.sendCommand(msg.toString)
    }
    logInfo("Entry", msg.toString)
end

rule "Timer expired for Garage Door 1"
when
    Item vGarageOpener1_Timer received command OFF
then
    aAlert.sendCommand("Garage door has been open for over an hour!"

    // reschedule the timer if it is night time
    if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state == "BED") {
        vGarageOpener1_Timer.sendCommand(ON)
    }
end

Sitemap:

                Switch item=aGarageOpener1 icon="garagedoorclosed" mappings=[ON=Open]  visibility=[vGarageOpener1 == CLOSED]
                Switch item=aGarageOpener1 icon="garagedooropen"   mappings=[ON=Close] visibility=[vGarageOpener1 == OPEN]

In your case since you can actually command the opener to OPEN or CLOSE instead of the opener acting like a pushbutton like mine, you might use a String Item instead of a Switch and continue to use the Rollershutter/Setpoint to command the opener.

The key takeaway from the above sitemap though is that you will notice that I use the visibility tag based on the door sensos’s state and use a special icon and mappings based on that state. To do this you will need to make a copy of the garage door icons and change their name like I did above.

Hey @rlkoshak, just wanted to say thanks for the detailed writeup… this was very helpful! I hadn’t wrapped my head around which states correspond to which item types which was making things difficult to understand.

I think I understand your approach, but I’m just wondering if there is a particular reason you’ve separated the opening and state functions of the door into a switch and a contact… isn’t it possible to have a single switch item that both commands the opener and shows its state? I’ve currently set up a single switch item this way (I think) - it shows as “on” when the door is open and “off” when it’s closed (I’ve used the Map transformation to map the “open” and “closed” MQTT messages I get from my opener on the status topic to “ON” and “OFF” and the switch seems to react appropriately - e.g. if I open the door manually, the switch responds by turning on if it was off).

I’m a newbie to OpenHAB so I’m just probing a bit to see if I can understand your approach. Thanks for any further insights!

I prefer to keep sensors and actuators separate. To me, the actuator (i.e. button) is completely separate from the sensor and should be modeled in OH separately. This also gives me opportunities elsewhere in OH. For example, the rest of my doors also have reed sensors on them. If I were to combine the actuator and sensor for my garage door openers into a single Switch I would have to treat them as a special case. But by keeping the sensor separate and as a Contact I can include them and process them just like my other door sensors.

It can also be a major pain to combine incoming and outgoing MQTT into one Item, particularly when they are fundamentally different types.

If you got it working using one Item and it works there is nothing wrong with combining them. Whether to do so has as much to do with the wider context of the home automation overall and personal preference.

Here are my entry sensor rules to illustrate what I mean about being able to treat all my entry doors separate.

rule "Keep track of the last time a door was opened or closed"
when
  Item vGarageOpener1 changed from CLOSED to OPEN or
  Item vGarageOpener1 changed from OPEN to CLOSED or
  Item vGarageOpener2 changed from CLOSED to OPEN or
  Item vGarageOpener2 changed from OPEN to CLOSED or
  Item vFrontDoor changed from CLOSED to OPEN or
  Item vFrontDoor changed from OPEN to CLOSED or
  Item vBackDoor changed from CLOSED to OPEN or
  Item vBackDoor changed from OPEN to CLOSED or
  Item vGarageDoor changed from CLOSED to OPEN or
  Item vGarageDoor changed from OPEN to CLOSED
then
  // Get the sensor that triggered the rule
  Thread::sleep(100)
  val door = gDoorSensors.members.filter[s|s.lastUpdate("mapdb") != null].sortBy[lastUpdate("mapdb")].last as ContactItem

  // Update LastUpdate
  val last = gDoorsLast.members.findFirst[dt | dt.name == door.name+"_LastUpdate"] as DateTimeItem
  last.postUpdate(new DateTimeType)

  // Set/cancel the Timer
  sendCommand(door.name+"_Timer", if(door.state == OPEN) "ON" else "OFF")

  // Log and alert
  val StringBuilder msg = new StringBuilder
  val doorName = transform("MAP", "en.map", door.name)

  msg.append(doorName)
  msg.append(" was")
  msg.append(if(door.state == OPEN) " opened" else " closed")

  var alert = false
  if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED"){
        alert = true
        msg.append(" and it is night")
  }

  if(vPresent.state == OFF) {
        alert = true
        msg.append(" and no one is home")
  }

  if(alert){
        msg.append("!")
        aAlert.sendCommand(msg.toString)
  }

  logInfo(logName, msg.toString)

end

rule "Timer expired for a door"
when
  Item vGarageOpener1_Timer received command OFF or
  Item vGarageOpener2_Timer received command OFF or
  Item vFrontDoor_Timer received command OFF or
  Item vBackDoor_Timer received command OFF or
  Item vGarageDoor_Timer received command OFF
then
  // Get the timer that triggered the rule
  Thread::sleep(100)
  val timer = gDoorsTimers.members.sortBy[lastUpdate("mapdb")].last as SwitchItem

  val doorName = transform("MAP", "en.map", timer.name)
  aAlert.sendCommand(doorName + " has been open for over an hour")

  // reschedule the timer if it is night time
  if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
        timer.sendCommand(ON) // reschedule the timer
  }
end

Thanks! This makes sense. Is there any issue with creating a switch item that combines the command/state functions and also a contact item that displays the state for rules and such?

Also: I notice you preface certain items with “v” and others with “a” - what’s the reason for that?

It adds some duplication of the state since it ends up located in both the Switch and the Contact which I’m generally against. It forces you to add a good deal of extra complexity to support, violates DRY (Don’t Repeat Yourself) and makes your overall system model a little inconsistent. To me, I’d rather have a more consistent model and apply DRY than avoid a couple extra lines in my sitemap.

But none of that may matter to you which is perfectly fine and valid as well. This is your home automation so how you design and model it is up to you. There is not just one correct answer.

It is a naming convention I use. Items that start with an “a” are Actuators (i.e. Items I sendCommand to). Items that start with a “v” are values and represent a sensor or overall system state (e.g. vTimeOfDay). Items that start with a “g” are Groups.

So aGarageOpener1 is the actuator Item used to trigger the garage door opener and vGarageOpener1 is the sensor indicating the OPEN/CLOSED state of the same door. There are lots of conventions people use and there is an issue open to provide some general advice about naming conventions as part of the official docs. The generic advice differs slightly from the convention I use (e.g. use plural nouns to represent Groups rather than a leading character or word).