-
Notifications
You must be signed in to change notification settings - Fork 715
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quick update for 2024. Will update again before the holiday starts wi…
…th additional enhancements
- Loading branch information
1 parent
320b724
commit b1e247b
Showing
2 changed files
with
29 additions
and
119 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,166 +1,76 @@ | ||
""" | ||
Applet: Hanukkah | ||
Summary: A Tidbyt Hanukkah Menorah | ||
Description: Displays a Hanukkah Menorah during the holiday with the correct number of candles. Also displays a countdown to Hanukkah before the holiday! | ||
Author: Bryan Slavin | ||
""" | ||
|
||
load("encoding/base64.star", "base64") | ||
load("encoding/json.star", "json") | ||
load("render.star", "render") | ||
load("schema.star", "schema") | ||
load("sunrise.star", "sunrise") | ||
load("time.star", "time") | ||
|
||
# Defaults | ||
DEFAULT_LOCATION = { | ||
"lat": 40.758896, | ||
"lng": -73.985130, | ||
"locality": "New York, New York USA", | ||
"timezone": "US/Eastern", | ||
} | ||
|
||
DEFAULT_FONT = "CG-pixel-4x5-mono" | ||
|
||
ALT_FLAME_IMAGE = base64.decode(""" | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAx0lEQVRoBe3RoQrCUBSA4XO36ZIKYrEMwxCjYDCbfQAfwCdQfIRFX8RqswzEsigGkQkigsFgUhiCu3OLewXvf+GEc9r/XREeAgggYLCAKtpfUTVSVvbY7GT8zXR3skgvppg466nftCvXoU5V0nHraR7uizyNAZDsLMHnYGsdi85u/dDzvIEpv190OsewNW/33iq+K9nuT6MkqbkmAZRag5k0SgcWBGS1tK18kEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBP5C4AeI8S0Wa9XInwAAAABJRU5ErkJggg== | ||
""") | ||
|
||
FLAME_IMAGE = base64.decode(""" | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVRoBe3QIRKCQBSA4bcuK90xb/IAzhDInIUbEM1eSA5AZogGgxSHajAA88bg4kHe/9/g/0QIAQQQsC4w9/t+GcLNokPW1qeDD68y/ZxaBJBtlOv37lN6StqmcxdjLCxB7B7dsVk/wc3v3Km/VKqaWwLgFQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABQwJ/E1ggSHCAkpcAAAAASUVORK5CYII= | ||
""") | ||
|
||
CANDLE_IMAGE = base64.decode(""" | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAeklEQVRoBe3UsQ2AIBRFUULopHACNnAS53QrOxoqncDoIwGXeJfkh9/eE0IIHAQQQAABBBCwFrjuWjS7I0Ia0YfuTbO6IcQR/Ope3OJ77wTI2h93AMf+/wVYxvfo+Qme2putAuEIIIAAAggggAACCCCAAAIIIICAk8AHfoQKv0cwj+IAAAAASUVORK5CYII= | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAwElEQVRoBe3TMQrCMBTG8ZemsYNO4pzJAwgOnT2LN3B09kJ6gC4uxdHBQR2kLoJghSrBoYlPCR7C9wXCl/X/gxDhQAACEJAu0JSd8rExS4kO6Wo67Gtzyn2rnEQACgdavLba+z35UI0Ka+1YEkSyKwazZ21Uc82U0/OJcy6TBPBtvdXnNd+7uHAOTmJ04O1KBuhxfCsdQGL/7wuIjP9Ep7H8yHuJbwwEIAABCEAAAhCAAAQgAAEIQAACEIDAPwu8AYNcK2rAdvQuAAAAAElFTkSuQmCC | ||
""") | ||
|
||
MAIN_MENORAH_IMAGE = base64.decode(""" | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAgCAYAAACinX6EAAAACXBIWXMAAC4jAAAuIwF4pT92AAACTUlEQVRoBe1ZvUoDQRDeeMZAjGhiEKsDxcLCQhQJgo1gpY02voCNtaWNCHkAX8AXsDH6AGlEjBYWChb+IUZUNCZiNEdEL34T70I8EW4lmwlcBiZ7l539Zua73dn7EaIpfAzkU22p1wP/Fl8EQrRyOd9eGIho/quY+ekzuGJg9Vs6E/HikWaap8IsXQ8ndV0f5QiohcMp+TxJRpfecn5f/jHgM7TlScMwAlyxsPnN5tI70Ge2AOCYbQZYSZfQtnuZgBCS//Q0AZeZgs/LBIj+aJCWAZuw3QdYGZ+jvWfLHo5ZCZha26O9/5KTAO5doA3Jj3mZgCckb3qZAM7cy77LS2BkZSNB+lc0qvudflX7q8a3i+CQMwjHuep+hzuh2l8Fn7sIOhOv+3mTgLpT3mAOmzOgwS5I3cOxdwF6Igsr9N4riS1rLwkvIhiQo0H2EkjiOIz9cZP+VCBZYJK6FVl7t7jCypEuNuUsKs/iVscs/stDH6izSuieneT9u/n1+9/+fiBRDBcOxP/i2TB/je+BQQc0cbg6P0fGFQLoxCIhhsMCnddB+uCDZqGTAFWugwDet5NX5cQ1LgjPQlkfhuwi6DroGhumgVcuRjXGdQ1nF0HXA2psGALeS40xpeB+1ACpkRLGmObTMJ+BjkP1qqFdOKZ3gmdQKrz0fiADpRp0C13HepXZPTBETpQSgMQXEU4c2m2FRR9B7qD2i9BB6/gGLc0G+jpEFZxmpgalXecYJCh7a6SaAFrfndAPqB8qI0UY04dTmiUTIGFXZrBb2y9APpyWjITdDwAAAABJRU5ErkJggg== | ||
""") | ||
|
||
MAIN_MENORAH_IMAGE_26 = base64.decode(""" | ||
iVBORw0KGgoAAAANSUhEUgAAAEAAAAAaCAYAAAAHfFpPAAAACXBIWXMAAC4jAAAuIwF4pT92AAACd0lEQVRYCeVYS0tbQRS+1zxErYqVKhKJZieujI9FN120brq0QhfSFqG/om5ExL3+A90Ktv4B1xGpqYsiuCpRS6HQhESbh9VrvxPnhHH0olecnEUOfMzrzHl8mXPn5jqOoJxsR1OnO5FNwRCcJinn35Z7ekMRL+m6zovLw5H2eDwekohFjIDEeH4JyTdHWy+6PDex5XlesqEIOP7e/qFUCDvFXMSpNL2bqFQqUQkCRH1mc0dfgUvJIMRKQCVNyZ81MgEdmWxJMn+5W0BlXR542lKQZCAs6Ry+j4CcZAyiBEwup54jeVeSAOmH4CmS7xAnYHR+vZvgF4jFdboBPNOvRX9VV7p9LoF1FcQrMxg1trXud/xt+eP0avaZgASv+LS21023tv3V7DMBN46hEZHtdcPdzbIwFB4tHumHoJFX/YcNTwCXAFEfsch/c0DbQfUDmq/m+o828Qn4g34M18ProJbuqd8KPYIpfrXsp2/uDzxWOcawkXK+egvD5Cj6q8AAsAHkAV2m1OCLPqn171p/o3Q/a3uo+xF4AqzQQBM/fVa5y5/feicMTAMZYDa98DbtskWQQKysAUnghOdVy3/ZWox5Hj50PQ4DFMMvNqTah9pjM3776a1zF5hB8j9JuUYADUACfZWh50K9PlJk4KsTwdiuebi5XfSHoINA6NW0bh8oQPhv+KvW4u3h2Z+9dgJsuUOifbA9BAwCXQDLHDp0XBcBKrsi8BegH6GAH2QPrVWxSgASf4no3wPDQD/QBlByXGLP0Cehk0BCt8KFQhntPnAAIj6htSK2CfiBqAe1yClxvcS49s8xHwLMeOiupveTMZCQRvvo8h+2raqd8MEEUAAAAABJRU5ErkJggg== | ||
""") | ||
|
||
def main(config): | ||
timezone = config.get("timezone") or "US/Eastern" | ||
if (not time.is_valid_timezone(timezone)): | ||
timezone = "US/Eastern" | ||
timezone = config.get("timezone") or "America/New_York" | ||
if not time.is_valid_timezone(timezone): | ||
timezone = "America/New_York" | ||
current_time = time.now().in_location(timezone) | ||
|
||
# Used for testing | ||
# current_time = time.time(year = 2023, month = 12, day = 15, hour = 23, minute =0, second = 0, location = timezone) | ||
# current_time = time.parse_time("2024-12-24T10:00:00Z") | ||
# TODO: Current time to midnight or 11:59:59? | ||
|
||
# First Day of Hanukkah | ||
# TODO: Look up for future years - hardcoded for 2023 | ||
hanukkah_first_day = time.time(year = 2023, month = 12, day = 7, hour = 0, minute = 0, second = 0, location = timezone) | ||
# TODO: Look up for future years | ||
# 20241107 - bas - hardcoded for 2024 | ||
hanukkah_first_day = time.parse_time("2024-12-25T00:00:00Z") | ||
hanukkah_last_day = hanukkah_first_day + time.parse_duration("192h") | ||
|
||
# Is it currently Hanukkah? | ||
# Check if it is after Hanukkah | ||
if (current_time > hanukkah_last_day): | ||
msg = render.Text( | ||
content = "Hanukkah is over for 2023. See you on December 24, 2024!", | ||
if current_time > hanukkah_last_day: | ||
# TODO: Make work with Marquee | ||
msg = render.WrappedText( | ||
content = "Hanukkah is over for 2024.\nSee you on December 14, 2025!", | ||
color = "#0000ff", | ||
font = "tb-8", | ||
) | ||
|
||
row = render.Row( | ||
children = [ | ||
render.Image(src = MAIN_MENORAH_IMAGE), | ||
render.Box(width = 15), | ||
msg, | ||
render.Box(width = 15), | ||
render.Image(src = MAIN_MENORAH_IMAGE), | ||
], | ||
main_align = "center", | ||
cross_align = "center", | ||
) | ||
|
||
main_child = render.Marquee( | ||
width = 64, | ||
child = row, | ||
font = "CG-pixel-4x5-mono", | ||
) | ||
|
||
# TODO: Animation with menorah? | ||
main_child = msg | ||
# Check if it is before Hanukkah | ||
elif (current_time < hanukkah_first_day): | ||
|
||
elif current_time < hanukkah_first_day: | ||
# How many days before Hanukkah begins? | ||
countdown_days = int((hanukkah_first_day - current_time).hours / 24) + 1 | ||
if (countdown_days == 1): | ||
msg = render.Text("Hanukkah 2023 starts tomorrow!", font = "tb-8", color = "#0000ff") | ||
if countdown_days == 1: | ||
msg = render.WrappedText("Hanukkah 2024 starts tomorrow!", font = "tb-8", color = "#0000ff") | ||
else: | ||
msg = render.WrappedText("Hanukkah 2023 starts in %d days!" % countdown_days, font = "tb-8", color = "#0000ff") | ||
|
||
row = render.Row( | ||
children = [ | ||
render.Image(src = MAIN_MENORAH_IMAGE), | ||
render.Box(width = 15), | ||
msg, | ||
render.Box(width = 15), | ||
render.Image(src = MAIN_MENORAH_IMAGE), | ||
], | ||
main_align = "center", | ||
cross_align = "center", | ||
) | ||
|
||
main_child = render.Marquee( | ||
width = 256, | ||
child = row, | ||
) | ||
msg = render.WrappedText("Hanukkah 2024 starts in %d days!" % countdown_days, font = "tb-8", color = "#0000ff") | ||
|
||
# TODO: Animation with menorah? | ||
main_child = msg | ||
# It's Hanukkah! | ||
else: | ||
location = config.get("location") | ||
loc = json.decode(location) if location else DEFAULT_LOCATION | ||
|
||
now = time.now().in_location(loc.get("timezone")) | ||
|
||
lat = float(loc.get("lat")) | ||
lng = float(loc.get("lng")) | ||
sunsetTime = sunrise.sunset(lat, lng, now).in_location(loc.get("timezone")) | ||
|
||
candles = [] | ||
if sunsetTime == None: | ||
sunsetText = "" | ||
else: | ||
sunsetText = "%s" % sunsetTime.format("3:04 PM") | ||
#candles.append(render.Text(sunsetText)) | ||
|
||
else: | ||
# TODO: Figure out whether to show the candles being lit | ||
# Figure out how many candles to show | ||
num_candles = int((current_time - hanukkah_first_day).hours / 24) + 1 | ||
candles = [] | ||
|
||
# Magical Offsets for the candle images | ||
offset_widths = [184, 168, 152, 136, 112, 96, 80, 0] | ||
offset_widths = [0, 80, 96, 112, 136, 152, 168, 184] | ||
|
||
# Lay out the candles | ||
for i in range(0, num_candles): | ||
candles.append(render.Box(width = offset_widths[i], child = render.Image(src = FLAME_IMAGE))) | ||
candles.append(render.Box(width = offset_widths[i], child = render.Image(src = CANDLE_IMAGE))) | ||
|
||
# Insert the base menorah | ||
candles.append(render.Image(src = MAIN_MENORAH_IMAGE_26)) | ||
candles.append(render.Image(src = MAIN_MENORAH_IMAGE)) | ||
|
||
# Render as a flat stack | ||
main_child = render.Stack(children = candles) | ||
|
||
if (sunsetTime != ""): | ||
sunset_row = render.Marquee(width = 64, child = render.Text(font = DEFAULT_FONT, color = "#0000ff", content = "Sunset tonight: " + sunsetText)) | ||
main_child = render.Column(main_align = "start", cross_align = "start", children = [sunset_row, main_child]) | ||
|
||
return render.Root( | ||
show_full_animation = True, | ||
delay = int(config.get("scroll", 64)), | ||
child = main_child, | ||
) | ||
|
||
def get_schema(): | ||
return schema.Schema( | ||
version = "1", | ||
fields = [ | ||
schema.Location( | ||
id = "location", | ||
name = "Location", | ||
desc = "Location for which to display the sun rise and set times.", | ||
icon = "locationDot", | ||
), | ||
], | ||
) |