#!/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")