#!/usr/bin/env python3 import datetime import logging import json from dateutil.parser import parse from typing import Any, Dict, Optional import requests from pyutils.datetimes import datetime_utils import file_writer import globals import kiosk_constants import kiosk_secrets as secrets import renderer logger = logging.getLogger(__name__) class ratago_renderer(renderer.abstaining_renderer): def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None: super().__init__(name_to_timeout_dict) self.last_update: Optional[datetime.datetime] = None self.doors: Dict[str, Dict[str, Any]] = { "cover.ratgdo_middle_door_door": {"state": "unknown"}, "cover.ratgdo_near_house_door": {"state": "unknown"}, "cover.ratgdo_shop_door": {"state": "unknown"}, } def debug_prefix(self) -> str: return "ratago" def periodic_render(self, key: str) -> bool: if key == "Poll Home Assistant": return self.poll_home_assistant() elif key == "Update Page": return self.update_page() else: raise Exception("Unknown operaiton") def poll_home_assistant(self) -> bool: key = secrets.homeassistant_api_key headers = { "Authorization": f"Bearer {key}", "Content-Type": "application/json", } for door in self.doors.keys(): try: r = requests.get( f"https://home.acknak.org/api/states/{door}", headers=headers, timeout=3.0, ) if r.ok: j = json.loads(r.content.decode()) self.doors[door] = j else: logger.warning("Unable to get state of garage door {door}, using 'unknown'") except Exception: logger.exception("Unable to get state of garage door {door}, using 'unknown'") self.last_update = datetime_utils.now_pacific() return True def update_page(self) -> bool: with file_writer.file_writer(kiosk_constants.ratago_pagename) as f: f.write( f"""

Garage Door Status


""" ) html = self.do_door('cover.ratgdo_near_house_door') if html is None: return False f.write(html) html = self.do_door('cover.ratgdo_middle_door_door') if html is None: return False f.write(html) html = self.do_door('cover.ratgdo_shop_door') if html is None: return False f.write(html) f.write( """
""" ) return True def get_state_icon(self, state: str) -> str: if state == "open": return "/kiosk/images/garage_open.png" elif state == "closed": return "/kiosk/images/garage_closed.png" elif state == "opening": return "/kiosk/images/garage_opening.png" elif state == "closing": return "/kiosk/images/garage_closing.png" else: return str(state) + ", an unknown state for the door." def do_door(self, name: str) -> Optional[str]: friendly_door_names = { "cover.ratgdo_middle_door_door": "Middle Door", "cover.ratgdo_near_house_door": "Near House Door", "cover.ratgdo_shop_door": "Workshop Door", } friendly_name = friendly_door_names.get(name, "unknown") attributes = self.doors[name] #.get(name) #, {"state": "unknown"}) state = attributes.get("state", "unknown").lower() since = attributes.get("last_changed", "unknown").lower() # "last_update": "2020-07-04T18:11:34.2981419Z" if since != "unknown": ts = parse(since) tz_info = ts.tzinfo now = datetime.datetime.now(tz_info) delta = (now - ts).total_seconds() duration = datetime_utils.describe_duration_briefly(int(delta)) else: duration = "unknown" now = datetime.datetime.now() is_night = now.hour <= 7 or now.hour >= 21 width = 0 if is_night and state == "open": color = "border-color: #ff0000;" width = 15 globals.put("ratago_triggered", True) else: color = "" width = 0 globals.put("ratago_triggered", False) return f"""
{friendly_name}

{state}

for {duration}
""" # Test #x = ratago_renderer({"Test": 1}) #x.periodic_render("Poll Home Assistant") #x.periodic_render("Update Page")