import sys import time import settings from support.hue import COMMAND_FULL_ON, COMMAND_OFF from support.lock import is_locked, lock, unlock from support.logger import get_logger ''' Handle 'Arriving home' action. Turn on stairwell for 30m, then turn off ''' logger = get_logger("arrive") ON_TIME_S = 60 * 20 # 30m PROCESS_NAME = 'arrive' # For use with lockfile to prevent multiple simultaneous operations def perform_arrival(): stairway = settings.ROOMS[4] stairway.update(COMMAND_FULL_ON) time.sleep(ON_TIME_S) stairway.update(COMMAND_OFF)
import time from support.color import get_next_circadian_color from support.hue import command_all_lights, hue from support.logger import get_logger from support.room import LightsOnDuringDayRoom from support.time_utils import get_local_time from settings import ROOMS # Logging logger = get_logger("circadian") while 1: now = get_local_time() next_color_date, next_color = get_next_circadian_color(date=now) sleep_time_s = (next_color_date - now).seconds logger.info("Sleeping until %s at %s", next_color.name, next_color_date.strftime('%Y/%m/%d %I:%M:%S %p')) time.sleep(sleep_time_s + 30) # Add padding to compensate for sleep inaccuracy logger.info("Adjusting hue for %s", next_color.name) command = next_color.apply_to_command({'transitiontime': 60 * 10}) # 60 s transition if next_color.name == 'Day': lights = [] for room in ROOMS: if not isinstance(room, LightsOnDuringDayRoom): lights += room.lights hue.set_light(lights, command) else: command_all_lights(command)
import datetime import copy from astral import SUN_RISING from support.hue import COMMAND_OFF from support.logger import get_logger from support.time_utils import get_local_sunrise, get_local_sunset, LOCAL_TIMEZONE, get_time_at_elevation from support.weather_utils import is_cloudy LIGHT_DAYTIME_XY = [0.4506, 0.4081] LIGHT_EVENING_XY = [0.4904, 0.4075] LIGHT_NIGHT_XY = [0.5304, 0.4068] LIGHT_LATENIGHT_XY = [0.6185, 0.363] logger = get_logger("color") class CircadianColor: def __init__(self, name: str, color_xy: list, brightness: int, trigger_date_function: callable): """ A light setting that depends only on the circadian cycle. :param name: human-readable name :param color_xy: the hue accompanying this circadian event. See http://www.developers.meethue.com/documentation/hue-xy-values :param brightness: the brightness from 0 to 255. If zero, will be treated as switch-off command :param trigger_date_function: a function returning the start time for the day the function is called. :return: """ self.name = name self.color_xy = color_xy
from support.logger import get_logger FRAME_TIME_S = 10 COLORS = [ [0.1772, 0.0592], # Blue [0.4882, 0.2286], # Pink [0.6043, 0.3728], # Sun Amber [0.6736, 0.3221], # Red [0.6043, 0.3728], # Sun Amber [0.4882, 0.2286], # Pink ] PROCESS_NAME = 'animate' logger = get_logger("animate") command = {'on': True, 'bri': 254, 'transitiontime': 10 * FRAME_TIME_S} LIGHT_TO_COLOR_IDX = {} counter = 0 def assign_colors(offset: int = 0): colors_idx = offset for light in hue.get_light_objects(mode='id'): LIGHT_TO_COLOR_IDX[light] = colors_idx #logger.info("Light %d will have color %d : %s" % (light, colors_idx, COLORS[colors_idx]))
import copy import flask import re from SECRETS import HTTPS_API_KEY, SSL_CERT_PEM, SSL_KEY_PEM from arrive import unlock from settings import ROOMS from support import env from support.color import get_current_circadian_color from support.hue import command_all_lights, COMMAND_FULL_ON from support.logger import get_logger from support.time_utils import get_local_time app = flask.Flask(__name__) logger = get_logger("web_server") party_process = None # Party mode process def is_local_request(request): request_remote_addr = request.environ["REMOTE_ADDR"] return request_remote_addr.startswith("192.168.1.") def get_home_status(template_friendly_dict: bool) -> dict: """ :param template_friendly_dict: whether to create a template friendly cict. This involves representing booleans as "true"/"false" strings and stripping spaces from keys. For template dicts, we need to use string values, for json return we can use bool """
import time import settings from support.color import LIGHT_DAYTIME_XY, LIGHT_EVENING_XY # Start at evening hue, min brightness. Fade to daytime hue, full brightness # over 30m from support.logger import get_logger logger = get_logger('wakeup') living_room = settings.ROOMS[0] hall = settings.ROOMS[1] kitchen = settings.ROOMS[2] bedroom = settings.ROOMS[3] if bedroom.is_lit() or living_room.is_lit() or kitchen.is_lit() or hall.is_lit(): logger.info('Aborting wakeup, room is already lit. Bed %r, Living %r, Kitchen %r, Hall %r' % (bedroom.is_lit(), living_room.is_lit(), kitchen.is_lit(), hall.is_lit())) quit() command = {'xy': LIGHT_EVENING_XY, 'bri': 1, 'on': True} bedroom.update(command) time.sleep(5) command['bri'] = 254 command['xy'] = LIGHT_DAYTIME_XY command['transitiontime'] = 10 * 60 * 30 bedroom.update(command)
import time import RPi.GPIO as GPIO import settings from support.logger import get_logger from support.room import PIN_NO_PIN from support.time_utils import get_local_time # Logging logger = get_logger("motion") # Motion sensor pin -> Room PIN_TO_ROOM = {} for room in settings.ROOMS: pin = room.motion_pin if pin != PIN_NO_PIN: PIN_TO_ROOM[room.motion_pin] = room def on_motion(triggered_pin: int): now = get_local_time() is_motion_start = GPIO.input(triggered_pin) room = PIN_TO_ROOM[triggered_pin] logger.info("Motion %s in %s" % (("started" if is_motion_start else "stopped"), room.name)) # Ignore repeat motion stop events