Skip to content

Instantly share code, notes, and snippets.

@flxkid
Created September 5, 2020 19:48
Show Gist options
  • Save flxkid/ac1133d414c85259763269ae66cf6242 to your computer and use it in GitHub Desktop.
Save flxkid/ac1133d414c85259763269ae66cf6242 to your computer and use it in GitHub Desktop.
Script to read ring alarm state
#!/usr/bin/python
from enum import Enum
import time
import requests
import RPi.GPIO as GPIO
# For this package see gist: https://gist.github.com/flxkid/2c8af86d51dc3532b6e0a085b8727e48
from TCS34725 import TCS34725
from colormath.color_objects import sRGBColor, LabColor
from colormath.color_conversions import convert_color
from colormath.color_diff import delta_e_cie2000
class AlarmState(Enum):
UNKNOWN = 1
DISARMED = 2
ARMED = 3
BATTERYLOW = 4
class AlarmColor:
"""A class to compare the color detected on ring alarm to predefined colors"""
# These are the detected colors on a gen 1 Ring base station
armed_color_rgb = sRGBColor((245/255.0), (15/255.0), (23/255.0))
armed_color = convert_color(armed_color_rgb, LabColor)
disarmed_color_rgb = sRGBColor((18/255.0), (69/255.0), (251/255.0))
disarmed_color = convert_color(disarmed_color_rgb, LabColor)
batterylow_color_rgb = sRGBColor((250/255.0), (250/255.0), (100/255.0))
batterylow_color = convert_color(batterylow_color_rgb, LabColor)
# This is the threshold for the delta (based on cie2000) to detect a different color
change_threshold = 18
def __init__(self, notifier_func):
self.notification_function = notifier_func
self.last_state = AlarmState.UNKNOWN
self.last_color = None
self.current_state = AlarmState.UNKNOWN
self.sensor = TCS34725(0x29, debug=False)
if (self.sensor.TCS34725_init() == 1):
print("Couldn't initialize the light sensor!")
exit()
time.sleep(1) # give the sensor time to initialize
self.sensor.SetLight(0) # turn off the light because we're trying to read an LED's value
def read_current_color_data(self):
self.sensor.Get_RGBData()
self.sensor.GetRGB888()
self.current_color_rgb = sRGBColor(self.sensor.RGB888_R/255, self.sensor.RGB888_G/255, self.sensor.RGB888_B/255)
self.current_color_lab = convert_color(self.current_color_rgb, LabColor)
self.interpret_color()
def color_delta(self, color1, color2):
if color1 is None or color2 is None:
return 255
return delta_e_cie2000(color1, color2)
def color_by_name(self, color_name):
pass
def interpret_color(self):
if self.color_delta(self.last_color, self.current_color_lab) > self.change_threshold:
self.last_color = self.current_color_lab
self.last_state = self.current_state
if self.color_delta(self.current_color_lab, self.armed_color) < self.change_threshold:
self.current_state = AlarmState.ARMED
elif self.color_delta(self.current_color_lab, self.disarmed_color) < self.change_threshold:
self.current_state = AlarmState.DISARMED
elif self.color_delta(self.current_color_lab, self.batterylow_color) < self.change_threshold:
self.current_state = AlarmState.BATTERYLOW
else:
self.current_state = AlarmState.UNKNOWN
# Trigger the notification function that there has been a state change
self.notification_function(self.last_state, self.current_state, self.current_color_rgb)
def status_notify(prior_state, current_state, current_rgb):
print("The state of the alarm changed from ", str(prior_state), " to ", str(current_state))
if current_state == AlarmState.UNKNOWN:
print ("The unknown RGB is ", current_rgb)
if current_state == AlarmState.ARMED:
# put in the address for your home assistant server and webhook name
r = requests.post('http://172.16.10.12:8123/api/webhook/armed', data='')
r.close()
if current_state == AlarmState.DISARMED:
# put in the address for your home assistant server and webhook name
r = requests.post('http://172.16.10.12:8123/api/webhook/disarmed', data='')
r.close()
if __name__ == "__main__":
alarm = AlarmColor(status_notify)
while True:
alarm.read_current_color_data()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment