Scott,
I like your approach, i.e., not being spoonfed, you learn more and it sticks that way. Let me share one of the basic things I learned working with a veteran. When you display code in this forum, start it and end it with three âticâ marks, see keyboard.
![image|690x232]
(upload://ndOykg7bZ5MjBeAxcyCTVyTc9Rn.jpg)
To illustrate, I will repeat your code here:
#!/usr/bin/env python
import appdaemon.plugins.hass.hassapi as hass
import base64
import string
class pavey(hass.Hass):
def initialize(self):
email_body = âAlarm event: MotionDetectStart (1)â
y = email_body.find(âDetectStartâ)
z = email_body.split(â(â)
camera_index = z[1]
if y == -1:
self.log(âDetectStart not foundâ)
self.set_state(âsensor.motionâ, state = âclearâ, attributes = {âfriendly_nameâ: âMotionâ})
else:
camera_where_motion_detected = camera_index[0]
self.log(camera_where_motion_detected)
self.set_state(âsensor.motionâ, state = (camera_where_motion_detected), attributes = {âfriendly_nameâ: âMotion Detectedâ}
This approach makes your code more readable.
I realise I can run the required actions (light/turn_on) directly within the code, but I had ideas of using the sensor to run automations.
When you code the state change of your imap sensor, the automation takes place. In my NVR system, I am able to change the subject of the email, so I make the âsubjectâ âAlertâ. In the IMAP sensor, the âsubjectâ is the state value, so in the following line of code:
self.listen_state(self.motion_detected,"sensor.backyard_motion", new="Alert")
the âlisten_stateâ is looking at the subject line to see if it says âAlertâ. If so, it triggers the motion detect routine. In the motion detect routine, the email body is parsed to determine what camera detected the motion. I donât think you need the following code:
self.set_state(âsensor.motionâ, state = (camera_where_motion_detected), attributes = {âfriendly_nameâ: âMotion Detectedâ}
What do you want to happen when motion is detected? In my application I turn on a light near the motion and keep it on for 5 minutes as shown in this code where I have 3 possible lights to turn on, depending on where the motion occurs:
if detected_by_camera == "3":
self.set_state("sensor.backyard_motion", new = "off")
self.turn_on("light.linear_lb60z1_dimmable_led_light_bulb_level", brightness = "120")
self.cancel_timer(self.camera_3_handle)
self.camera_3_handle = self.run_in(self.timer_handler, 300, myentity = "light.linear_lb60z1_dimmable_led_light_bulb_level")
self.log(self.get_state("light.linear_lb60z1_dimmable_led_light_bulb_level", attribute='friendly_name') + ", turned on due to motion - line 30")
# courtyard light
elif detected_by_camera == "2":
if self.now_is_between("sunset + 02:00:00", "sunrise"):
#if self.now_is_between("sunrise", "sunset"):
self.set_state("sensor.backyard_motion", new = "off")
self.turn_on("light.linear_lb60z1_dimmable_led_light_bulb_level_4", brightness = "120")
self.cancel_timer(self.camera_2_handle)
self.camera_2_handle = self.run_in(self.timer_handler, 300, myentity = "llight.linear_lb60z1_dimmable_led_light_bulb_level_4")
self.log(self.get_state("light.linear_lb60z1_dimmable_led_light_bulb_level_4", attribute='friendly_name') + ", turned on due to motion - line 39")
# middle garage
elif detected_by_camera == "1":
self.set_state("sensor.backyard_motion", new = "off")
self.turn_on("light.unknown_node_21_level", brightness = "120")
self.cancel_timer(self.camera_1_handle)
self.camera_1_handle = self.run_in(self.timer_handler, 300, myentity = "light.unknown_node_21_level")
self.log(self.get_state("light.unknown_node_21_level", attribute='friendly_name') + ", turned on due to motion - line 48")
else: self.log("Old email dated "+email_date+" ignored")
self.set_state("sensor.backyard_motion", new = "off")
#self.notify("Motion detected from camera " + detected_by_camera)
detected_by_camera = ''
# else: self.log("Sun is not down")
def timer_handler(self, kwargs):
self.turn_off(kwargs['myentity'])
self.log(self.get_state(kwargs['myentity'], attribute='friendly_name') + ", turned on due to motion, is now off")
self.notify(self.get_state(kwargs['myentity'], attribute='friendly_name') + ", turned on due to motion, is now off")
One other subtle point, when Home Assistant is restarted, the IMAP sensor rereads all the emails from the beginning of your inbox, at 30 second intervals, and will go through your detection routine and can send false information to you. There is reference to a routine on this forum that will delete all old emails if Home Assistant is restarted (I thought I had it bookmarked, but I donât). In my case, I decided to manually delete the emails each day as I scan through to see what happened the night before, and in the interim I installed this code to ignore old email messages:
now = datetime.now()
now_string = str(now.hour)+':'+str(now.minute) +':'+str(now.second)
message_string = email_date[17:25] #Mon, 18 Jun 2018 15:21:43
FMT = '%H:%M:%S'
tdelta = datetime.strptime(now_string, FMT) - datetime.strptime(message_string, FMT)
self.log(str(tdelta.total_seconds()))
if tdelta.total_seconds() > 600:
detected_by_camera = "" #reading old email messages, bypass motion processing
elif tdelta.total_seconds() < -300: #There is a difference in time between NVR and Home Assistant
detected_by_camera = "" #reading old email messages, bypass motion processing
I hope this helps!