Skip to content

Instantly share code, notes, and snippets.

@spinpwr
Last active December 31, 2022 16:04
Show Gist options
  • Save spinpwr/1fb29f7c05686af7af4832c2ab666eee to your computer and use it in GitHub Desktop.
Save spinpwr/1fb29f7c05686af7af4832c2ab666eee to your computer and use it in GitHub Desktop.
Python class for appdaemon using Sonoff motion sensor
import hassapi as hass
#
# App to turn lights on when motion detected then off again after a delay
#
# Use with constraints to activate only for the hours of darkness
#
# Args:
#
# sensor: binary sensor to use as trigger
# entity_on : entity to turn on when detecting motion, can be a light, script, scene or anything else that can be turned on
# entity_off : entity to turn off when detecting motion, can be a light, script or anything else that can be turned off.
# Can also be a scene which will be turned on.
# delay: amount of time after turning on to turn off again. If not specified defaults to 60 seconds.
class MotionLights(hass.Hass):
def initialize(self):
self.handle = None
# Check some Params
if "delay" in self.args:
self.delay_off = self.args["delay"]
else:
self.delay_off = 60
# Subscribe to sensors
if "sensor" in self.args:
self.listen_state(self.motion, self.args["sensor"])
self.log("Sensor: {} Timeout: {}".format(self.args["sensor"], self.args["delay"]))
else:
self.log("No sensor specified, doing nothing")
def motion(self, entity, attribute, old, new, kwargs):
if new == "on":
if "entity_on" in self.args:
self.log("Motion detected: switching {} on".format(self.args["entity_on"]))
self.turn_on(self.args["entity_on"])
if self.handle:
self.cancel_timer(self.handle)
elif new == "off":
self.log("Motion sensor went off: switch off in {} sec".format(self.delay_off))
self.handle = self.run_in(self.light_off, self.delay_off)
def light_off(self, kwargs):
if "entity_off" in self.args:
self.log("Turning {} off".format(self.args["entity_off"]))
self.handle = None
self.turn_off(self.args["entity_off"])
def cancel(self):
self.cancel_timer(self.handle)
@spinpwr
Copy link
Author

spinpwr commented Dec 31, 2022

Based on AppDaemon example app:
https://github.com/AppDaemon/appdaemon/blob/dev/conf/example_apps/motion_lights.py

The original version doesn't work well with sensors which won't re-trigger (e.g. Sonoff SNZB-03 with ~60 sec timeout). The lamp will be turned off even with continuous motion and will only be re-triggered when motion state changes to off and on again.
So I have changed the code to only start the timer when the motion sensor state changes to off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment