How to use AppDaemon to create motion sensor automation in home assistant

How to use AppDaemon to create motion sensor automation in home assistant
Photo by Danist Soh / Unsplash

I need to make a Home Automation with AppDaemon because the conventional automations and node red were both too slow with turning on the lights. So I investigated various approaches for developing a quick automation that dependably switches on my lights with motion. So I came upon AppDaemon and thought it could be useful.

It took some trial and error to get it completely right and working. To include numerous sensors in the template, I had to create a new template sensor.


So you start by developing a Python application.

kitchen_motion.py

import hassapi as hass


class KitchenMotion(hass.Hass):
	def initialize(self):
            self.listen_state(
                self.motion_sensor_state_changed_cb,
                entity_id="binary_sensor.kitchen_motion",
            )
            self.log("Listening for motion events in kitchen")

In this case, we import hass api and then build a class and an initialize function to listen for an event, or in this case, a binary_sensor. self.motion_sensor_state_changed_cb is the method to call when the state of the binary sensor changes. self. allows you access to the class's methods.

def motion_sensor_state_changed_cb(self, light, attribute, old, new, kwargs):
    motion_sensor_state = new
    is_got_illuminance = self.get_state('sensor.kitchen_motion_illuminance')
    is_daytime = self.now_is_between("05:00:00", "01:00:00")

    if motion_sensor_state == 'on' and is_daytime:
      # Check if kitchen has sun light over 55%
      if (float(is_got_illuminance) > 55.0):
        self.log('To much light in guest bathroom: %s', float(is_got_illuminance))
      else:
        self.log("Kitchen Motion detected")
        self.turn_on("script.turn_on_kitchen_lights")
    elif motion_sensor_state == 'off':
        self.log("Kitchen Motion ended")
        self.turn_on("script.turn_off_kitchen_lights")

As a result, this procedure is listed under initialize. It is daytime if the time is between 05:00:00 and 01:00:00. I also have an illuminance sensor and check to see whether the sunshine is above 55%. If the if condition is true, you can proceed to switch on the kitchen lights. Turn off the kitchen lights once the motion has stopped.

Now, simply adding a conventional motion sensor binary sensor to this will not work; instead, you must add a custom template binary sensor to keep up with the motion calls and reset the timer.

Create a templates.yaml

- binary_sensor:
    - name: "Kitchen Motion Sensor [TEMPLATE]"
      unique_id: "kitchen_motion"
      state: >
        {{ is_state("binary_sensor.kitchen_motion_home_security_motion_detection", "on") }}
      availability: >
        {{ is_state('input_boolean.reset_all_motion_sensors', 'off') }}
      delay_off:
        minutes: 10

So start with binary sensor and then give the template sensor a name.

  • unique_id: This is the identifier used in the Python script.
  • state: The is state variable represents your genuine binary sensor from the motion sensor, which is checked to see if it is turned on.
  • availability: I included an input boolean to allow for a quick reset of the motion sensors if the input boolean is off and the availability is on. If you enable this boolean, the availability is disabled.
  • delay_off: We discussed how, if you use the normal sensor, you must create a template sensor to keep track of the on and off times. If the state does not change within 10 minutes, the template sensor will be turned off. If the status changes in any way between 0 and 10 minutes, the timer will reset.

kitchen_motion.py

import hassapi as hass


class KitchenMotion(hass.Hass):
	def initialize(self):
            self.listen_state(
                self.motion_sensor_state_changed_cb,
                entity_id="binary_sensor.kitchen_motion",
            )
            self.log("Listening for motion events in kitchen")
            
    def motion_sensor_state_changed_cb(self, light, attribute, old, new, kwargs):
        motion_sensor_state = new
        is_got_illuminance = self.get_state('sensor.kitchen_motion_illuminance')
        is_daytime = self.now_is_between("05:00:00", "01:00:00")

        if motion_sensor_state == 'on' and is_daytime:
          # Check if kitchen has sun light over 55%
          if (float(is_got_illuminance) > 55.0):
            self.log('To much light in guest bathroom: %s', float(is_got_illuminance))
          else:
            self.log("Kitchen Motion detected")
            self.turn_on("script.turn_on_kitchen_lights")
        elif motion_sensor_state == 'off':
            self.log("Kitchen Motion ended")
            self.turn_on("script.turn_off_kitchen_lights")

Now that we've set up the Python motion script, we need to add it to apps.yaml.

kitchen_motion:
  module: kitchen_motion
  class: KitchenMotion

Following that, you may need to restart AppDaemon in the add-ons.

This should give you a working motion sensor that turns the lights on and off and resets the timer.