Rollershutter Group with mixed item types — is this configuration correct?

openHAB version: 5.2.0.M4
Binding: MQTT Binding with Zigbee2MQTT

Problem

I have rollershutter groups that also contain other item types (Switch, Number, Dimmer). Because of this, I cannot use Group:Rollershutter for the sub-groups, since that would prevent UP/DOWN/STOP commands from being accepted when other item types are members.

To work around this, I use two separate groups: one plain Group for the sitemap structure, and one Group:Rollershutter purely for the command forwarding.

My current configuration

groups.items:

// Plain group for sitemap structure (Switch, Slider, sub-groups)
Group Group_GF_Livingroom_Rollershutter "Wohnzimmer Rollos" <rollershutter>
  (Group_GF_Livingroom) ["Control"]

// Typed group for UP/DOWN/STOP command forwarding
Group:Rollershutter Group_GF_Livingroom_Rollershutter_Function "Wohnzimmer Rollos" <rollershutter>
  (Group_GF_Livingroom)

// AVG position group for the position slider
Group:Number:AVG Group_GF_Livingroom_RollershutterPosition "Wohnzimmer Position [%.0f %%]" <rollershutter>
  (Group_GF_Livingroom)

zigbee.items — sub-groups (plain Group, contain mixed item types):

Group Group_GF_Livingroom_RollershutterOne (Group_GF_Livingroom_Rollershutter) ["Control"]
Group Group_GF_Livingroom_RollershutterTwo (Group_GF_Livingroom_Rollershutter) ["Control"]

zigbee.items — Rollershutter items (member of BOTH sub-group AND function group):

Rollershutter Rollershutter_GF_Livingroom_DoorCoveringOne "..." 
  (Group_GF_Livingroom_RollershutterOne, Group_GF_Livingroom_Rollershutter_Function) ["OpenLevel"] {
    channel="mqtt:topic:zigbee:rollershutterLivingRoomDoor1Rollershutter" 
      [profile="transform:JS", toItemScript="| 100 - Number(input)", commandFromItemScript="| 100 - Number(input)"]
}

Rollershutter Rollershutter_GF_Livingroom_DoorCoveringTwo "..."
  (Group_GF_Livingroom_RollershutterTwo, Group_GF_Livingroom_Rollershutter_Function) ["OpenLevel"] {
    channel="mqtt:topic:zigbee:rollershutterLivingRoomDoor2Rollershutter"
      [profile="transform:JS", toItemScript="| 100 - Number(input)", commandFromItemScript="| 100 - Number(input)"]
}

// Position as separate Dimmer item with inverted value
Dimmer Position_GF_Livingroom_DoorCoveringOnePosition "..." <rollershutter>
  (Group_GF_Livingroom_RollershutterOne, Group_GF_Livingroom_RollershutterPosition, ...) ["Control"] {
    channel="mqtt:topic:zigbee:numberLivingRoomDoor1RollershutterPosition"
      [profile="transform:JS", toItemScript="| 100 - Number(input)", commandFromItemScript="| 100 - Number(input)"]
}

mqtt.things — Rollershutter channel:

Type rollershutter : rollershutterLivingRoomDoor1Rollershutter "..." [
    stateTopic="zigbee2mqtt/0xAABBCCDDEEFF0001",
    transformationPattern="JSONPATH:$.position",
    commandTopic="zigbee2mqtt/0xAABBCCDDEEFF0001/set",
    stop="{\"state\": \"STOP\"}",
    formatBeforePublish="{\"state\":%s}",
    off="{\"state\": \"CLOSE\"}",
    on="{\"state\": \"OPEN\"}"
]

sitemap:

Group item=Group_GF_Livingroom_Rollershutter label="Wohnzimmer Rollos" icon="rollershutter"
{
    Switch item=Group_GF_Livingroom_Rollershutter_Function label="Alle Rollos" mappings=[UP="▲", STOP="■", DOWN="▼"]
    Slider item=Group_GF_Livingroom_RollershutterPosition  label="Alle Position [%.0f %%]" icon="rollershutter" minValue=0 maxValue=100 step=1

    Group item=Group_GF_Livingroom_RollershutterOne label="Rollo 1" icon="rollershutter"
    {
        Default item=Rollershutter_GF_Livingroom_DoorCoveringOne    label="Rollo"
        Slider  item=Position_GF_Livingroom_DoorCoveringOnePosition  label="Position [%.0f %%]" icon="rollershutter" minValue=0 maxValue=100 step=1
        Switch  item=Switch_GF_Livingroom_DoorCoveringOneBacklight   label="Hintergrundbeleuchtung"
        Switch  item=Switch_GF_Livingroom_DoorCoveringOneCalibration label="Kalibrierung"
        Text    item=Sensor_GF_Livingroom_DoorCoveringOneLinkQuality label="Verbindungsqualität"
    }
    Group item=Group_GF_Livingroom_RollershutterTwo label="Rollo 2" icon="rollershutter"
    {
        Default item=Rollershutter_GF_Livingroom_DoorCoveringTwo    label="Rollo"
        Slider  item=Position_GF_Livingroom_DoorCoveringTwoPosition  label="Position [%.0f %%]" icon="rollershutter" minValue=0 maxValue=100 step=1
        Switch  item=Switch_GF_Livingroom_DoorCoveringTwoBacklight   label="Hintergrundbeleuchtung"
        Switch  item=Switch_GF_Livingroom_DoorCoveringTwoCalibration label="Kalibrierung"
        Text    item=Sensor_GF_Livingroom_DoorCoveringTwoLinkQuality label="Verbindungsqualität"
    }
}

Background / Reason for inversion

Zigbee2MQTT reports position: 0 = fully closed and position: 100 = fully open, which is the opposite of openHAB’s convention (0% = open, 100% = closed). I use inline JS transformation to invert the value in both directions:

[profile="transform:JS", toItemScript="| 100 - Number(input)", commandFromItemScript="| 100 - Number(input)"]

Questions

  1. Is the two-group approach (Group for structure + Group:Rollershutter for command forwarding) the correct/recommended way to handle groups with mixed item types?
    Thanks in advance!

Groups: You can use as many groups as you want. :slight_smile: there is no right or wrong.
Shutter position: I doubt that Zigbee2mqtt is the culprit, instead My guess is the used hardware.

The shutter position is built like it is in knx (one of the first bindings in openHAB) and the knx engineers used 0 and 100 on purpose, as a shutter is almost the exact opposite of a dimmer.
You can use a dimmer to brighten up the light, but you can’t use it to make it darker as it already is. For a shutter it’s the opposite way, you can make it darker, but not brighter (e.g. when it’s dark outside to open the shutter won’t give light). So, when the shutter is most active, it’s 100 %.

Some systems use it the other way (for other reasons, of course) and as there is sometimes no way to change the behavior, the only solution is to rewrite the command and the status like you did. That’s absolutely ok.