3 from aiohttp import ClientSession
6 from dateutil.parser import parse
7 import pymyq # type: ignore
8 from typing import Dict, Optional
10 from pyutils.datetimes import datetime_utils
12 import kiosk_constants
15 import kiosk_secrets as secrets
18 class garage_door_renderer(renderer.abstaining_renderer):
19 def __init__(self, name_to_timeout_dict: Dict[str, int]) -> None:
20 super().__init__(name_to_timeout_dict)
21 self.doors: Optional[Dict] = None
22 self.last_update: Optional[datetime.datetime] = None
24 def debug_prefix(self) -> str:
27 def periodic_render(self, key: str) -> bool:
29 self.last_update = datetime.datetime.now()
30 return asyncio.run(self.poll_myq())
31 elif key == "Update Page":
32 return self.update_page()
34 raise Exception("Unknown operaiton")
36 async def poll_myq(self) -> bool:
37 async with ClientSession() as websession:
38 myq = await pymyq.login(
39 secrets.myq_username, secrets.myq_password, websession
41 self.doors = myq.devices
42 assert(self.doors is not None)
43 return len(self.doors) > 0
45 def update_page(self) -> bool:
46 with file_writer.file_writer(kiosk_constants.myq_pagename) as f:
49 <H1>Garage Door Status</H1>
50 <!-- Last updated at {self.last_update} -->
52 <TABLE BORDER=0 WIDTH=99%>
56 html = self.do_door("Near House")
61 html = self.do_door("Middle Door")
72 def get_state_icon(self, state: str) -> str:
74 return "/kiosk/images/garage_open.png"
75 elif state == "closed":
76 return "/kiosk/images/garage_closed.png"
77 elif state == "opening":
78 return "/kiosk/images/garage_opening.png"
79 elif state == "closing":
80 return "/kiosk/images/garage_closing.png"
82 return str(state) + ", an unknown state for the door."
84 def do_door(self, name: str) -> Optional[str]:
85 if self.doors is None:
87 for key in self.doors:
88 door = self.doors[key]
90 j = self.doors[key].device_json
91 state = j["state"]["door_state"]
93 # "last_update": "2020-07-04T18:11:34.2981419Z"
94 raw = j["state"]["last_update"]
97 now = datetime.datetime.now(tz_info)
98 delta = (now - ts).total_seconds()
99 now = datetime.datetime.now()
100 is_night = now.hour <= 7 or now.hour >= 21
101 duration = datetime_utils.describe_duration_briefly(int(delta))
103 if is_night and door.state == "open":
104 color = "border-color: #ff0000;"
112 <FONT STYLE="font-size:26pt">{name}<BR>
113 <IMG SRC="{self.get_state_icon(state)}"
115 STYLE="border-style: solid; border-width: {width}px; {color}">
117 <B>{state}</B></FONT><BR>
125 #x = garage_door_renderer({"Test": 1})
126 #x.periodic_render("Poll MyQ")
127 #x.periodic_render("Update Page")