One of the first things I made smart in my home was the lighting. I placed MiLights everywhere. In the beginning it was ok, all was controlled with PIR sensors and some rules. But over time I began to miss the option to control my lights with the standard wall switches.
Recently I bought a momentary switch from the same series as my wall switches, connected with a Shelly 1 (flashed Tasmota 8.1.0) and started experimenting.
My original goal was to add double, triple, quadruple-press functionality. It turns out Tasmota can’t go beyond double- and long-press functionality, so that it is!
Shelly 1 configuration
Module parameters
Module type: Generic 18
GPIO 4: Relay1 (21)
GPIO 5: Button1in (126)
Tasmota configuration
Backlog SetOption1 1; SetOption11 1; Setoption13 0; SetOption32 10
SetOption1
Set button multipress mode to
0
= allow all button actions (default)
1
= restrict to single, double and hold actions (i.e., disable inadvertent reset due to long press)
For usability I restrict this, so you accidentally for example triple click the button and Start Wi-Fi smart config allowing for SSID and password configuration. See here for all multi press functions.
SetOption11
Swap button single and double press functionality
0
= disabled (default)
1
= enabled
If you don’t enable this, single and double press are swaped.
Setoption13
SetOption13 Allow immediate action on single button press
0
= single, multi-press and hold button actions (default)
1
= only single press action for immediate response (i.e., disable multipress detection). Disable by holding for 4 x button hold time (see SetOption32
).
No explanation needed.
SetOption32
Number of 0.1 seconds to hold button before sending HOLD
action message.
1..100
to set button hold time (default = 40
) . This option also affects the time required to perform a firmware defaults reset (10x HOLD
action time)
I want to hold the button 1 second to register it as a long press. Adjust as wanted, for a maximum of 10 seconds. Beware of the unit of measurement.
rule
on button1#state=3 do backlog publish stat/shelly_keuken_hold/POWER1 ON; RuleTimer1 1 endon
on Rules#Timer=1 do publish stat/shelly_keuken_hold/POWER1 OFF endon
on button1#state=2 do backlog publish stat/shelly_keuken_doubleclick/POWER1 ON; RuleTimer2 1 endon
on Rules#Timer=2 do publish stat/shelly_keuken_doubleclick/POWER1 OFF endon
rule 1
Backlog
List of commands to be executed in sequence separated by ;
See Using Backlog for examples.
Button1#State
when a button changes state:
0
= OFF
1
= ON
2
= TOGGLE
3
= HOLD
A single click is ON, a double click is TOGGLE and hold is HOLD.
When you single click the button, the relay is turned on and the MQTT status is automatically updated.
When you doucble click the button we publish stat/shelly_keuken_doubleclick/POWER1 ON, since there is no relay that turns on and no automatic MQTT status update. So openHAB will never now you double clicked the button. This way we manually send a command to MQTT. Since this is a momentary switch, I also want it to automatically turn off, to do this I create a timer which sends the OFF comand to MQTT after 1 second.
When you hold the button for 1+ second we publish stat/shelly_keuken_hold/POWER1 ON, since there is no relay that turns on and no automatic MQTT status update. So openHAB will never now you hold the button. This way we manually send a command to MQTT. Since this is a momentary switch, I also want it to automatically turn off, to do this I create a timer which sends the OFF comand to MQTT after 1 second.
Openhab configuration
Thing:
Thing mqtt:topic:shelly_keuken "Shelly Keuken" (mqtt:broker:MosquittoMqttBroker) @ "Keuken" {
Channels:
Type switch : PowerSwitch1 "Power Switch 1" [ stateTopic="stat/shelly_keuken/POWER", commandTopic="cmnd/shelly_keuken/POWER", on="ON", off="OFF" ]
Type switch : PowerSwitchRes "Switch State 1" [ stateTopic="stat/shelly_keuken/RESULT", transformationPattern="JSONPATH:$.POWER",on="ON",off="OFF"]
Type switch : PowerSwitch2 "Power Switch 2" [ stateTopic="stat/shelly_keuken_doubleclick/POWER1", commandTopic="cmnd/shelly_keuken_doubleclick/POWER1", on="ON", off="OFF" ]
Type switch : PowerSwitchRes "Switch State 2" [ stateTopic="stat/shelly_keuken_doubleclick/RESULT", transformationPattern="JSONPATH:$.POWER",on="ON",off="OFF"]
Type switch : PowerSwitch3 "Power Switch 3" [ stateTopic="stat/shelly_keuken_hold/POWER1", commandTopic="cmnd/shelly_keuken_hold/POWER1", on="ON", off="OFF" ]
Type switch : PowerSwitchRes "Switch State 3" [ stateTopic="stat/shelly_keuken_hold/RESULT", transformationPattern="JSONPATH:$.POWER",on="ON",off="OFF"]
Type string : Version "Version" [ stateTopic="stat/shelly_keuken/STATUS2", transformationPattern="JSONPATH:$.StatusFWR.Version"]
Type string : fallback "fallback topic" [ stateTopic="tele/shelly_keuken/INFO1", transformationPattern="JSONPATH:$.FallbackTopic"]
Type string : hostname "hostname" [ stateTopic="tele/shelly_keuken/INFO2", transformationPattern="JSONPATH:$.Hostname"]
Type string : IP "IP" [ stateTopic="tele/shelly_keuken/INFO2", transformationPattern="JSONPATH:$.IPAddress"]
Type string : time "Time" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Time" ]
Type string : uptime "Uptime" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Uptime" ]
Type string : wifi-ap "Wifi AP" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Wifi.AP" ]
Type string : wifi-ssid "Wifi SSID" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Wifi.SSId" ]
Type string : wifi-channel "Wifi Channel" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Wifi.Channel" ]
Type number : wifi-rssi "Wifi RSSI" [ stateTopic="tele/shelly_keuken/STATE", transformationPattern="JSONPATH:$.Wifi.RSSI" ]
Type string : devicestate "Device State" [ stateTopic="tele/shelly_keuken/LWT", transformationPattern="MAP:reachable.map" ]
}
Items:
Switch Shelly_Keuken1 "Shelly Keuken 1" <light> (gKeuken, gSwitches) { channel="mqtt:topic:shelly_keuken:PowerSwitch1" }
Switch Shelly_Keuken2 "Shelly Keuken 2" <light> (gKeuken, gSwitches) { channel="mqtt:topic:shelly_keuken:PowerSwitch2" }
Switch Shelly_Keuken3 "Shelly Keuken 3" <light> (gKeuken, gSwitches) { channel="mqtt:topic:shelly_keuken:PowerSwitch3" }
String Shelly_Keuken_Reachable "Shelly Keuken:[]" <qualityofservice> (gVirtueel, gReachable) { channel="mqtt:topic:shelly_keuken:devicestate" }
Number Shelly_Keuken_RSSI "Shelly Keuken: RSSI [%d %%]" <qualityofservice> (gVirtueel, gRSSI) { channel="mqtt:topic:shelly_keuken:wifi-rssi" }
String Shelly_Keuken_FW "Firmware Shelly Keuken [v%s]" <settings> (gVirtueel) { channel="mqtt:topic:shelly_keuken:Version" }
This gives the following results:
Single press: Switches ON/OFF the relay. I will change this to another MQTT command, since I have no need to turn off my wifi lights by cutting the power.
Double press: Switches ON/OFF a virtual switch in openHAB.
Long press (1s): Switches ON/OFF a virtual switch in openHAB.
With those virtual switches you can trigger rules to do whatever you want.
Any feedback is welcome. I’m no Tasmota rule or MQTT expert so I think I can optimize it a bit.