Shelly 1 + Tasmota + Momentary Switches

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.

3 Likes

Great tutorial.
It would help a bit if you explained the Tasmota configuration setoptions.
What they do and why you chose that.
(I know but others will find it useful as they can be confusing)

Well done.
Thanks

1 Like

:+1:

For me, it gets even more confusing when trying to explain it. :laughing:

I’ll write something up in the coming days.

I also want to see if I can disable GPIO4 / Relay to make it only publish a MQTT command on single press.

UPDATE: As promised I added some explanation. I hope this is clear enough for everybody.

I also played around with disabling the relay. This is as easy as disabling GPIO4. Only issue I have is that I can’t get the button to turn OFF after 1 second, just like the double and hold.

I would say it shoud be something like

on button1#state=1 do RuleTimer3 1 endon
on Rules#Timer=3 do publish cmnd/shelly_bar/POWER OFF endon

But for some reason button1#state=1 doesn’t get triggered when GPIO4 is disabled. I could solve this in openHAB, but I rather do it all in the same place.

UPDATE2: PulseTime is the solution. I’ll update the tutorial later this week.