import pymyq
from aiohttp import ClientSession
import asyncio
import constants
import datetime
from dateutil.parser import parse
import file_writer
import renderer
import secrets
class garage_door_renderer(renderer.debuggable_abstaining_renderer):
def __init__(self, name_to_timeout_dict):
super(garage_door_renderer, self).__init__(name_to_timeout_dict, False)
self.doors = None
self.last_update = None
def debug_prefix(self):
return "myq"
def periodic_render(self, key):
if key == "Poll MyQ":
self.last_update = datetime.datetime.now()
return asyncio.run(self.poll_myq())
elif key == "Update Page":
return self.update_page()
else:
raise error("Unknown operaiton")
async def poll_myq(self):
async with ClientSession() as websession:
myq = await pymyq.login(
secrets.myq_username, secrets.myq_password, websession
)
self.doors = myq.devices
return len(self.doors) > 0
def update_page(self):
f = file_writer.file_writer(constants.myq_pagename)
f.write(
"""
Garage Door Status
"""
% self.last_update
)
html = self.do_door("Near House")
if html == None:
return False
f.write(html)
html = self.do_door("Middle Door")
if html == None:
return False
f.write(html)
f.write(
"""
"""
)
f.close()
return True
def get_state_icon(self, state):
if state == "open":
return "/icons/garage_open.png"
elif state == "closed":
return "/icons/garage_closed.png"
elif state == "opening":
return "/icons/garage_opening.png"
elif state == "closing":
return "/icons/garage_closing.png"
else:
return str(state) + ", an unknown state for the door."
def do_door(self, name):
for key in self.doors:
door = self.doors[key]
if door.name == name:
j = self.doors[key].json
state = j["state"]["door_state"]
# "last_update": "2020-07-04T18:11:34.2981419Z"
raw = j["state"]["last_update"]
ts = parse(raw)
tz_info = ts.tzinfo
now = datetime.datetime.now(tz_info)
delta = (now - ts).total_seconds()
now = datetime.datetime.now()
is_night = now.hour <= 7 or now.hour >= 21
days = divmod(delta, constants.seconds_per_day)
hours = divmod(days[1], constants.seconds_per_hour)
minutes = divmod(hours[1], constants.seconds_per_minute)
width = 0
if is_night and door.state == "open":
color = "border-color: #ff0000;"
width = 15
else:
color = ""
width = 0
return """
%s
%s
for %d day(s), %02d:%02d.
| """ % (
name,
self.get_state_icon(state),
width,
color,
state,
days[0],
hours[0],
minutes[0],
)
return None
# Test
x = garage_door_renderer({"Test": 1})
x.periodic_render("Poll MyQ")
x.periodic_render("Update Page")