NOTE: Updated 2021-03-27 for Template and switchmode.
I posted this article on the Home Assistant community Forum about a year ago. i decided to pull it back here to my website now that I have one.
I recently bought a couple of Sonoff Slamphers and Sonoff PIR’s. I have a couple of dark areas that already had the old style PIR built into the inline socket in a dumb switch version. One was failing giving random on/off results and driving us nuts, so replacement was in order. Of course I needed to run it all thru Home Assistant.
My first try got rather complicated. The Home Assistant after version .80 had the binary sensor MQTT set-up modifies so that there can only be 2 codes per entity. Using the 433mhz switching thru the Sonoff RF bridge worked differently. You get 1 topic and it sends the multitude of codes from 433 sensors thru this same topic. If you have an RF bridge you may notice a lot of warnings popping up when a code comes thru. If you have say 6 binary sensors set-up in your system coding thru the RF-Bridge and one code is sent into it, you will get the response of the 1 sensor in Home Assistant, but in the HA system log you will see warning messages from the other 5 sensors stating that this code does not match on or off for this topic. To stop this I have built several things to code around that, and this is one of them.
You see the Sonoff Slampher has the ability to read an RF signal directly as sent from a 433 device. I thought I could load the code and go. Ha ha, no such luck…
I flashed Tasmota onto the Slampher and plugged it all in, fired up the PIR. I followed the Sonoff instructions to pair the devices and it worked! The PIR sensor saw me and the light came on. 10 seconds later the PIR sensor saw me again and the light turned off. It was toggling the light on and off every time the code came in. Well, that’s no good. At that point I felt inspired by Digiblur’s (Thanks Travis!) mastery of Tasmota rules and decided I should be able to do this with rules. Here is my solution.
First, as I said, I flashed Tasmota onto the Slamphers. I got my information on how to do that from the Tasmota site. Once I got the device running and the web interface up, I added all my network information into the configuration, and I pulled in the template for #9 Slampher from the Tasmota website. So far so good.
After playing for a while, I came up with this new Template: (NOTE: Template is for Tasmota 9.1+ release)
{"NAME":"SlampherSpltRF","GPIO":[32,1,0,1,0,0,0,0,225,320,0,0,224,0],"FLAG":0,"BASE":9}
It turns out that the device has an RF radio internally that is tied to Button1/GPIO0/POWER1 internally. What I did was move GPIO12 (connected to the main relay) onto POWER2, and change POWER1 on another unused GPIO pin. Then I can ‘interrupt’ the input from the RF swirtch and trigger it whenever I want to instead of on every toggle of the RF.
First you need to set ‘PulseTime1 5’ so that relay 1 turns off after a half second. Then PulseTime2 300 so that the actual light stays on 5 minutes. This second one you can adjust the time, but 5 minutes works in this situation for me. Also to insure that the decide is triggered on, but not off from the internal switching, you should set [switchmode 13](https://tasmota.github.io/docs/Buttons-and-Switches/#switchmode). Here are the rules that make this happen:
rule1 on POWER1#state=1 do POWER2 1 endon
What rule1 does is waits for the RF signal to fire power1 and when it does, that fires power2 which is the light bulb turning on. Because of PulseTimer1 5 power1 shuts off very quickly.
rule2 on System#Boot do event#DARK endon on event#DAY do Backlog rule1 0; POWER2 0 endon on event#DARK do Backlog rule1 1; POWER2 0 endon
What rule 2 does is looks for an MQTT topic to decide if it is DAY or DARK outside. If it is DARK, it enables the light to work by turning rule1 on. If it is DAY it turns rule1 off and the light will not fire. Of course, if you want the light to always function you simply turn on rule1 and skip rule 2 completely. Then, to make things easier, I set ‘GroupTopic2 outside’ on these devices so that I can send the DARK or DAY topic only once instead of to each device separately.
In effect the light now will only respond to the RF switch turning the light on, and will always turn the light off after 5 minutes.
Here is a debug log of the device running thru a cycle where you can see everything happening:
==============================(RF Trigger of Light)
[02:38:37] StairTopLight/stat/RESULT {"POWER1":"ON"}
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/stat/RESULT = {"POWER1":"ON"}
[02:38:37] StairTopLight/stat/POWER1 ON
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/stat/POWER1 = ON
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 RUL: POWER1#STATE=1 performs "POWER2 1"
[02:38:37] StairTopLight/tele/STATE {"Time":"2020-11-18T02:38:36","Uptime":"9T10:46:59","UptimeSec":816419,"Heap":24,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":832,"POWER1":"ON","POWER2":"ON","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":4,"RSSI":100,"Signal":-37,"LinkCount":740,"Downtime":"0T02:04:39"}}
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/tele/STATE = {"Time":"2020-11-18T02:38:36","Uptime":"9T10:46:59","UptimeSec":816419,"Heap":24,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":832,"POWER1":"ON","POWER2":"ON","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":4,"RSSI":100,"Signal":-37,"LinkCount":740,"Downtime":"0T02:04:39"}}
[02:38:37] StairTopLight/stat/RESULT {"POWER2":"ON"}
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/stat/RESULT = {"POWER2":"ON"}
[02:38:37] StairTopLight/stat/POWER2 ON
[02:38:37] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/stat/POWER2 = ON
[02:38:38] StairTopLight/tele/STATE {"Time":"2020-11-18T02:38:36","Uptime":"9T10:46:59","UptimeSec":816419,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":30,"MqttCount":832,"POWER1":"OFF","POWER2":"ON","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":4,"RSSI":100,"Signal":-40,"LinkCount":740,"Downtime":"0T02:04:39"}}
[02:38:38] StairTopLight/stat/LOGGING 02:38:36 MQT: StairTopLight/tele/STATE = {"Time":"2020-11-18T02:38:36","Uptime":"9T10:46:59","UptimeSec":816419,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":30,"MqttCount":832,"POWER1":"OFF","POWER2":"ON","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":4,"RSSI":100,"Signal":-40,"LinkCount":740,"Downtime":"0T02:04:39"}}
[02:38:38] StairTopLight/stat/RESULT {"POWER1":"OFF"}
[02:43:08] StairTopLight/stat/RESULT {"POWER2":"OFF"}
[02:43:08] StairTopLight/stat/LOGGING 02:43:06 MQT: StairTopLight/stat/RESULT = {"POWER2":"OFF"}
[02:43:08] StairTopLight/stat/POWER2 OFF
[02:43:08] StairTopLight/stat/LOGGING 02:43:06 MQT: StairTopLight/stat/POWER2 = OFF
[02:43:22] StairTopLight/tele/STATE {"Time":"2020-11-18T02:43:21","Uptime":"9T10:51:44","UptimeSec":816704,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-38,"LinkCount":741,"Downtime":"0T02:04:40"}}
[02:43:22] StairTopLight/stat/LOGGING 02:43:21 MQT: StairTopLight/tele/STATE = {"Time":"2020-11-18T02:43:21","Uptime":"9T10:51:44","UptimeSec":816704,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-38,"LinkCount":741,"Downtime":"0T02:04:40"}}
==============================(DAY Event)
[02:44:34] StairTopLight/stat/RESULT {"Event":"Done"}
[02:44:34] StairTopLight/stat/LOGGING 02:44:34 MQT: StairTopLight/stat/RESULT = {"Event":"Done"}
[02:44:34] StairTopLight/stat/LOGGING 02:44:34 RUL: EVENT#DAY performs "Backlog rule1 0; POWER2 0"
[02:44:34] StairTopLight/stat/RESULT {"Rule1":"OFF","Once":"OFF","StopOnError":"OFF","Length":35,"Free":476,"Rules":"on POWER1#state=1 do POWER2 1 endon"}
[02:44:34] StairTopLight/stat/LOGGING 02:44:34 MQT: StairTopLight/stat/RESULT = {"Rule1":"OFF","Once":"OFF","StopOnError":"OFF","Length":35,"Free":476,"Rules":"on POWER1#state=1 do POWER2 1 endon"}
[02:44:35] StairTopLight/tele/STATE {"Time":"2020-11-18T02:44:35","Uptime":"9T10:52:58","UptimeSec":816778,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-39,"LinkCount":741,"Downtime":"0T02:04:40"}}
[02:44:35] StairTopLight/stat/LOGGING 02:44:35 MQT: StairTopLight/tele/STATE = {"Time":"2020-11-18T02:44:35","Uptime":"9T10:52:58","UptimeSec":816778,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-39,"LinkCount":741,"Downtime":"0T02:04:40"}}
[02:44:35] StairTopLight/stat/RESULT {"POWER2":"OFF"}
[02:44:35] StairTopLight/stat/LOGGING 02:44:35 MQT: StairTopLight/stat/RESULT = {"POWER2":"OFF"}
[02:44:35] StairTopLight/stat/POWER2 OFF
[02:44:35] StairTopLight/stat/LOGGING 02:44:35 MQT: StairTopLight/stat/POWER2 = OFF
==============================(DARK Event)
[02:45:50] StairTopLight/stat/RESULT {"Event":"Done"}
[02:45:50] StairTopLight/stat/LOGGING 02:45:50 MQT: StairTopLight/stat/RESULT = {"Event":"Done"}
[02:45:50] StairTopLight/stat/LOGGING 02:45:50 RUL: EVENT#DARK performs "Backlog rule1 1; POWER2 0"
[02:45:50] StairTopLight/stat/RESULT {"Rule1":"ON","Once":"OFF","StopOnError":"OFF","Length":35,"Free":476,"Rules":"on POWER1#state=1 do POWER2 1 endon"}
[02:45:50] StairTopLight/stat/LOGGING 02:45:50 MQT: StairTopLight/stat/RESULT = {"Rule1":"ON","Once":"OFF","StopOnError":"OFF","Length":35,"Free":476,"Rules":"on POWER1#state=1 do POWER2 1 endon"}
[02:45:51] StairTopLight/tele/STATE {"Time":"2020-11-18T02:45:50","Uptime":"9T10:54:13","UptimeSec":816853,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-39,"LinkCount":741,"Downtime":"0T02:04:40"}}
[02:45:51] StairTopLight/stat/LOGGING 02:45:50 MQT: StairTopLight/tele/STATE = {"Time":"2020-11-18T02:45:50","Uptime":"9T10:54:13","UptimeSec":816853,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-39,"LinkCount":741,"Downtime":"0T02:04:40"}}
[02:45:51] StairTopLight/stat/RESULT {"POWER2":"OFF"}
[02:45:51] StairTopLight/stat/LOGGING 02:45:50 MQT: StairTopLight/stat/RESULT = {"POWER2":"OFF"}
[02:45:51] StairTopLight/stat/POWER2 OFF
[02:45:51] StairTopLight/stat/LOGGING 02:45:50 MQT: StairTopLight/stat/POWER2 = OFF
[02:48:22] StairTopLight/tele/STATE {"Time":"2020-11-18T02:48:22","Uptime":"9T10:56:45","UptimeSec":817005,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":833,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SSID","BSSId":"74:D0:2B:65:2D:D9","Channel":1,"RSSI":100,"Signal":-39,"LinkCount":741,"Downtime":"0T02:04:40"}}
My HA already has a sensor for dark that I like taking into account cloud cover and time of day. I got this from another user a while ago, so thank you if you originally wrote this, but I am putting it to use here. ‘Dark_Sky may no longer be available, so you may need to find another way to determine cloud cover. As of now, my Dary_Sky is still working.
Here is the binary sensor I use for dark:
NOTE: I have updated this sensor since writing this… See: https://whatarewefixing.today/636/home-assistant-outside-light-control-using-met-no-weather-integration/
#####################################################
# Weather #
#####################################################
- platform: template
sensors:
dark_outside:
friendly_name: 'Is it Dark outside'
value_template: >-
{% if is_state('input_boolean.sunset_offset.state', 'on') %}
true
{% elif (states.sun.sun.attributes.elevation | int < 2) %}
true
{% elif ( (states.sun.sun.attributes.elevation | int < 3.5) and (states.sensor.dark_sky_cloud_coverage.state | int > 85)) %}
true
{% elif ( (states.sun.sun.attributes.elevation | int < 5.5) and (states.sensor.dark_sky_cloud_coverage.state | int > 90)) %}
true
{% elif (states.sensor.dark_sky_cloud_coverage.state | int > 95) %}
true
{% else %}
false
{% endif %}
Here is the automation I use to push that binary sensor out thru MQTT to my Slampher:
####################################################
# Dark out? #
####################################################
- id: mqtt_dark_switch
initial_state: 'on'
alias: MQTT Dark Switch
trigger:
- platform: state
entity_id: binary_sensor.dark_outside
action:
- service: mqtt.publish
data_template:
topic: "outside/cmnd/EVENT"
payload: >-
{% if trigger.to_state.state == 'on' %}
'DARK'
{% else %}
'DAY'
{% endif %}
To go along with this, I added another service to my HA reset automation that makes sure my Tasmota stuff reports back with it’s current state on HA boot. I added this to default the dark sensor to dark to default the light to work if it doesn’t know the state. Seemed like the way to go here:
####################################################
# MQTT Restart Tasmota #
####################################################
#### Use this automation to get all your devices in sync, including
#### power state, immediately after Home Assistant is (re)started.
#### Also taking this opportunity to start other things up for a clean restart.
- id: tasmota_restart
alias: Power state on HA start-up
initial_state: 'on'
trigger:
platform: homeassistant
event: start
action:
- service: mqtt.publish
data:
topic: tasmotas/cmnd/state
payload: ''
- service: mqtt.publish
data:
topic: outside/cmnd/EVENT
payload: 'DARK'
Notice in all this that I prefer my Tasmota MQTT Topics flipped as this way it makes more sense to me. You may need to adjust that if you run yours differently.
Thanks for reading.
If you have any suggestions for improvements let us all know!
What are we Fixing Today Homepage / Website:
https://www.WhatAreWeFixing.Today/
Channel Link URL: (WhatAreWeFixingToday)
https://bit.ly/WhatAreWeFixingTodaysYT
What are we Fixing Today Facebook page (Sir GoodEnough):
https://bit.ly/WhatAreWeFixingTodaybFB
What are we Fixing Today Twitter Account (Sir GoodEnough):
https://bit.ly/WhatAreWeFixingTodayTW
Discord Account: (Sir_Goodenough#9683)
https://discord.gg/Uhmhu3B
Patreon: https://www.patreon.com/WhatAreWeFixingToday
Buy me Coffee: https://www.buymeacoffee.com/SirGoodenough
PayPal one-off donation link: https://www.paypal.me/SirGoodenough
Cash App $CASHTAG: https://cash.me/$SirGoodenough
Venmo cash link: https://venmo.com/SirGoodenough
If you would like to donate anything to this channel, please use this address:
C/O: Sirius GoodEnough
322 Buena Vista Ave.
Department: DYT
Waukesha, Wisconsin, 53188-3602