Hi everybody,
I recently got myself a bunch of Shelly Button1 to control wallplugs without the need to use an app for that. The device itself is lovely but the integration in OH2 could be better. I’m integrating them (like most of my devices these days) using MQTT which is a fairly straight forward setup and the same as for other existing Shelly devices (power on, connect to WLAN, configure MQTT broker, done). Once set up, the Button1 knows four different input signals (event_cnt will increase if the same signal is being sent multiple times).
- Single short click: MQTT message {“event”:“S”,“event_cnt”:1})
- Double short click: MQTT message {“event”:“SS”,“event_cnt”:1})
- Triple short click: MQTT message {“event”:“SSS”,“event_cnt”:1})
- Long click: MQTT message {“event”:“L”,“event_cnt”:1})
To got the buttons working in my OH instance, I first set them up the following way (replacing the MAC with XXXXXXXXXXXX here):
// ===== mqtt.things =====
Bridge mqtt:broker:mqtt-broker [ host="10.0.0.1", secure=false, username="myUser", password="myPassword" , clientID="openhab-client" ]
Thing topic shellybutton1-XXXXXXXXXXXX "ShellyButton1 XXXXXXXXXXXX" {
Channels:
Type switch : switch "Switch" [ stateTopic="shellies/shellybutton1-XXXXXXXXXXXX/input_event/0", transformationPattern="JSONPATH:$.event", postCommand="true", on="S", off="SS"]
Type number : battery "Battery" [ stateTopic="shellies/shellybutton1-XXXXXXXXXXXX/sensor/battery" ]
}
}
// ===== button.items =====
Switch ShellyButton1_XXXXXXXXXXXX_Switch "Shelly Button1 XXXXXXXXXXXX [%s]" { channel="mqtt:topic:twilight-mqtt:shellybutton1-XXXXXXXXXXXX:switch" }
Number ShellyButton1_XXXXXXXXXXXX_Battery "Shelly Button1 XXXXXXXXXXXX [%d]" { channel="mqtt:topic:twilight-mqtt:shellybutton1-XXXXXXXXXXXX:battery" }
// ===== default.sitemap ======
Frame label="Buttons" {
Default item=ShellyButton1_XXXXXXXXXXXX_Switch
Default item=ShellyButton1_XXXXXXXXXXXX_Battery
}
// ===== button.rules =====
rule "ShellyButton1_XXXXXXXXXXXX_Switch"
when
Item ShellyButton1_XXXXXXXXXXXX_Switch received command
then
Lighting_Switch.sendCommand(receivedCommand)
sendTelegram("openHAB", "Automatic wallplugs changed to" + receivedCommand)
end
With that setup, I was able to trigger something like one or more wallplugs (single click = ON, double click = OFF) or send me a telegram when battery of one of the Button1’s was getting low. While this was neat, I was not able to use this approach to implement the other input signals (“SSS” and “L”). On “human error”, I’m seeing something like this in the log:
2020-08-13 13:05:00.329 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Command 'SSS' not supported by type 'OnOffValue': No enum constant org.eclipse.smarthome.core.library.types.OnOffType.SSS
It is clear that for a binary switch something besides On or Off does not make much sense so I worked around this by changing the channel type for Switch to string and updated the items accordingly. Next I changed the rules to react on different input signals. I could’ve done this in multiple rules that each react on a different input but did not want to scatter logic too much:
// ===== mqtt.things =====
Bridge mqtt:broker:mqtt-broker [ host="10.0.0.1", secure=false, username="myUser", password="myPassword" , clientID="openhab-client" ]
Thing topic shellybutton1-XXXXXXXXXXXX "Shellybutton1 XXXXXXXXXXXX" {
Channels:
Type string: switch "Switch" [ stateTopic="shellies/shellybutton1-XXXXXXXXXXXX/input_event/0", transformationPattern="JSONPATH:$.event", postCommand="true"]
Type number : battery "Battery" [ stateTopic="shellies/shellybutton1-XXXXXXXXXXXX/sensor/battery" ]
}
}
// ===== button.items =====
String ShellyButton1_XXXXXXXXXXXX_Switch "Shelly Button1 XXXXXXXXXXXX" { channel="mqtt:topic:twilight-mqtt:shellybutton1-XXXXXXXXXXXX:switch" }
Number ShellyButton1_XXXXXXXXXXXX_Battery "Shelly Button1 XXXXXXXXXXXX [%d]" { channel="mqtt:topic:twilight-mqtt:shellybutton1-XXXXXXXXXXXX:battery" }
// ===== default.sitemap =====
Frame label="Buttons" {
Switch item=ShellyButton1_XXXXXXXXXXXX_Switch mappings=["S"="S","SS"="2*S","SSS"="3*S","L"="L"]
Default item=ShellyButton1_XXXXXXXXXXXX_Battery
}
// ===== button.rules =====
rule "ShellyButton1_XXXXXXXXXXXX_Switch"
when
Item ShellyButton1_XXXXXXXXXXXX_Switch received command
then
if(receivedCommand == "S") {
Lighting_Switch.sendCommand(ON)
sendTelegram("openHAB", "Automatic wallplugs changed to ON")
} else if(receivedCommand == "SS") {
Lighting_Switch.sendCommand(OFF)
sendTelegram("openHAB", "Automatic wallplugs changed to OFF")
} else {
sendTelegram("openHAB", "Unbound input signal: " + receivedCommand)
}
end
This now works for all possible inputs and also shows the state in the sitemap but I would consider it a little hacky and I really dislike the if in my rules files. Adding additional states to the switch channel would’ve been great (e.g. ‘on=“S”, off=“SS”, custom1=“SSS”, custom2=“L”’) but this seems to be unsupported. So my question is: Is the above setup the right way to go or is there a better solution that I did not find so far?
BR Tilman