6 from dateutil.parser import parse
7 from typing import Dict, Optional
10 from pyutils.datetimes import datetime_utils
14 import kiosk_constants
15 import kiosk_secrets as secrets
19 logger = logging.getLogger(__name__)
22 class garage_door_renderer(renderer.abstaining_renderer):
23 def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
24 super().__init__(name_to_timeout_dict)
25 self.last_update: Optional[datetime.datetime] = None
27 "cover.ratgdo_middle_door_door": {"state": "unknown"},
28 "cover.ratgdo_near_house_door": {"state": "unknown"},
29 "cover.ratgdo_shop_door": {"state": "unknown"},
32 def debug_prefix(self) -> str:
35 def periodic_render(self, key: str) -> bool:
36 if key == "Poll Home Assistant":
37 return self.poll_home_assistant()
38 elif key == "Update Page":
39 return self.update_page()
41 raise Exception("Unknown operaiton")
43 def poll_home_assistant(self) -> bool:
44 key = secrets.HOMEASSISTANT_API_KEY
46 "Authorization": f"Bearer {key}",
47 "Content-Type": "application/json",
49 for door in self.doors.keys():
52 f"https://home.acknak.org/api/states/{door}",
57 j = json.loads(r.content.decode())
61 logger.warning("Unable to get state of garage door {door}, using 'unknown'")
63 logger.exception("Unable to get state of garage door {door}, using 'unknown'")
64 self.last_update = datetime_utils.now_pacific()
67 def update_page(self) -> bool:
68 with file_writer.file_writer(kiosk_constants.ratago_pagename) as f:
71 <H1>Garage Door Status</H1>
72 <!-- Last updated at {self.last_update} -->
74 <TABLE BORDER=0 WIDTH=99%>
79 html = self.do_door("cover.ratago_near_house_door")
84 html = self.do_door("cover.ratago_middle_door_door")
89 html = self.do_door("cover.ratago_shop_door")
100 def get_state_icon(self, state: str) -> str:
102 return "/kiosk/images/garage_open.png"
103 elif state == "closed":
104 return "/kiosk/images/garage_closed.png"
105 elif state == "opening":
106 return "/kiosk/images/garage_opening.png"
107 elif state == "closing":
108 return "/kiosk/images/garage_closing.png"
110 return str(state) + ", an unknown state for the door."
112 def do_door(self, name: str) -> Optional[str]:
113 friendly_door_names = {
114 "cover.ratgdo_middle_door_door": "Middle Door",
115 "cover.ratgdo_near_house_door": "Near House Door",
116 "cover.ratgdo_shop_door": "Workshop Door",
118 if self.doors is None:
121 friendly_name = friendly_door_names.get(name, "unknown")
122 attributes = self.doors.get(name, {"state": "unknown"})
123 state = attributes.get("state", "unknown").lower()
124 since = attributes.get("last_changed", "unknown").lower()
126 # "last_update": "2020-07-04T18:11:34.2981419Z"
129 now = datetime.datetime.now(tz_info)
130 delta = (now - ts).total_seconds()
131 duration = datetime_utils.describe_duration_briefly(int(delta))
133 now = datetime.datetime.now()
134 is_night = now.hour <= 7 or now.hour >= 21
136 if is_night and state == "open":
137 color = "border-color: #ff0000;"
139 globals.put("ratago_triggered", True)
143 globals.put("ratago_triggered", False)
147 <FONT STYLE="font-size:26pt">{friendly_name}<BR>
148 <IMG SRC="{self.get_state_icon(state)}"
150 STYLE="border-style: solid; border-width: {width}px; {color}">
152 <B>{state}</B></FONT><BR>
159 #x = garage_door_renderer({"Test": 1})
160 #x.periodic_render("Poll MyQ")
161 #x.periodic_render("Update Page")