Repository navigation
AppDaemon automation examples
Aephir edited this page Jan 10, 2023
·
3 revisions
This will run at set intervals (in this form, every Sunday at 10:00), as well as every time the ugeplan attribute changes.
It will notify the kid (or you, if you add your device instead) about checking the schedule for next week, as well as about anything they should take special note of, e.g. if the need to present (fremlægge), remember something (husk), or prepare something (forbered). Additional keywords can easily be added as needed.
This has been only superficially tested, but seems to work well with the parameters I have been able to test.
import hassapi as hass
import globals
import datetime
class Notify(hass.Hass, globals.Entities):
"""
Reminder of important things in "ugeplan" of the "aula" integration.
It runs every Sunday morning, to remind kids to look over their weekly schedule.
It also runs upon changes to the "ugeplan" attribute, where it specifically notifies about anything noteworthy.
"Noteworthy" is defined in the "self.keywords" dictionary,
To do:
Run daily to check/remind about "noteworthy" for upcoming day.
"""
def initialize(self) -> None:
"""
Adding "noteworthy" keywords and corresponding message.
Setting up schedule and listeners.
"""
self.keywords = {
"fremlægge": "i skal fremlægge",
"husk": "du skal huske noget",
"syg": "der er sygdom",
"forbered": "der er noget du skal have forberedt",
}
start = datetime.datetime(2023, 1, 8, 10, 0, 0)
self.run_every(self.run_every_week_wrapper, start, 7 * 24 * 60 * 60)
self.listen_state(self.main, self.aula_sensors["child"], attributes="ugeplan")
def main(self, entity, attribute, old, new, kwargs) -> None:
"""
Main function.
"""
title, message = self.get_message(entity)
self.notify(title, message)
def run_every_week_wrapper(self, kwargs) -> None:
"""
Wrapper to be able to call "main" with the "run_every", as this does not provide the arguments required.
"""
entity: str = "run_every_week_wrapper"
self.main(entity, None, None, None, None)
def get_message(self, entity) -> tuple[str, str]:
"""
Create a message about what to do. If updates in ugeplan outside of weekly schedule:
A message detailing whether they are "noteworthy", and which day they occur on (if only one occurrence).
If run on weekly schedule:
A message about the "ugeplan" being available, and a note about what to remember.
"""
if entity == self.aula_sensors["child"]:
title, message, days_with_notice = self.parse_notifications()
elif entity == "run_every_week_wrapper":
title, message, days_with_notice = self.parse_notifications()
if title == "Hej child!":
message: str = "Klik på denne besked for at se ugeplan.\nHer kan du læse hvad du skal, så du husker det hele :)"
else:
added_info: str = ""
for val in days_with_notice.values():
if self.keywords[val[1]] not in added_info:
added_info += self.keywords[val[1]] + ", "
added_info: str = added_info[:-2]
if len(days_with_notice) > 1:
added_info: str = self.reverse_replace(added_info)
message: str = (
"Klik på denne besked for at se ugeplan.\nHusk at "
+ added_info
+ "."
)
title: str = "Hej child, her er din ugeplan!"
return title, message
def parse_notifications(self) -> tuple[str, str, dict[str, list[str, str]]]:
"""
Parser for getting "noteworthy" information out. "Noteworthy" is in the "self.keywords" dictionary.
Any number of keywords and values can be added here.
"""
ugeplan_text: str = self.get_entity(self.aula_sensors["child"]).get_state(
attribute="ugeplan"
)
ugeplan_text_by_day: list[str] = ugeplan_text.split("<h3>")[1:]
ugeplan_text_by_subject: list[list[str]] = [day.split("<b>") for day in ugeplan_text_by_day]
days_with_notice: dict = dict()
for day in range(len(ugeplan_text_by_subject)):
for text in ugeplan_text_by_subject[day]:
for key in self.keywords.keys():
if key in text:
date: str = ugeplan_text_by_subject[day][0][:-5]
subject: str = text.split("</b>")[0]
days_with_notice[date] = [subject, key]
if len(days_with_notice) > 1:
title: str = (
"Der er "
+ str(len(days_with_notice))
+ " ting du skal være opmærksom på!"
)
information: str = ""
for val in days_with_notice.values():
information += self.keywords[val[1]] + ", "
information: str = information[:-3]
information: str = self.reverse_replace(information)
message: str = (
"Der er beskeder om at "
+ information
+ ". Klik på beskeden for at se ugeplanen."
)
elif len(days_with_notice) == 1:
title: str = (
"Hej child, husk at "
+ list(days_with_notice.values())[0][1]
+ " på "
+ list(days_with_notice.keys())[0]
+ "!"
)
message: str = (
"Der er en besked om at du skal huske at "
+ list(days_with_notice.values())[0][1]
+ " på "
+ list(days_with_notice.keys())[0]
+ ". Klik på beskeden for at se ugeplanen."
)
elif len(days_with_notice) == 0:
title: str = "Hej child!"
message: str = (
"Der er nye beskeder om ugen. Klik på beskeden for at se ugeplanen."
)
return title, message, days_with_notice
def reverse_replace(self, text: str) -> str:
"""
Helper function to remove the last ", " and replace with " og ". E.g.
"fremlægge, huske, forberede" becomes "fremlægge, huske og forberede".
"""
old: str = ", "
new: str = " og "
return (text[::-1].replace(old[::-1], new[::-1], 1))[::-1]
def notify(self, title: str, message: str) -> None:
"""
Notifies the defined device/service with the title and message passed.
"url": "/lovelace-child/school" and "clickAction": "/lovelace-child/school" are the android and iOS (respectively)
tags to open the home assistant app at the corresponding dashboard/tab where the "ugeplan" is stored.
"""
data: dict[str, str] = {
"tag": "child_school_week",
"url": "/lovelace-child/school",
"clickAction": "/lovelace-child/school",
}
self.call_service(
self.notify_phones["child"], title=title, message=message, data=data
)Notes: This is specific for my entities and Lovelace. You need to make the following changes:
- For
"/lovelace-child/school"you should navigate in a browser to the Home Assistant dashboard/tab/view you want the message to open, and copy the last part. E.g. if the full URL is https://my.ha.com/lovelace-child/school, it would be"/lovelace-child/school". - Every instance of
self.aula_sensors["child"]should be replaced with your aula sensor entity_id. - Every instance of
self.notify_phones["child"]should be replaced with the service/device you want notified (e.g."notify/mobile_app_child_iphone" - You can omit the
import globalsand passingglobals.Entitiesto theclass Notify, I do so because all my entity_ids are stored in aglobals.pyfile so I only have to change it one place if they change. - You might want to keep an eye on which keywords your teachers use, and update them in the
self.keywordsdictionary. - The
self.run_every(self.run_every_week_wrapper, start, 7 * 24 * 60 * 60)means it will run every week (7 days * 24 hours * 60 minutes * 60 seconds between each run) starting on thestart = datetime.datetime(2023, 1, 8, 10, 0, 0), which is Sunday, January 8th at 10:00 (am, if you use this). Change as you like.