Skip to content

Commit

Permalink
Quick update for 2024. Will update again before the holiday starts wi…
Browse files Browse the repository at this point in the history
…th additional enhancements
  • Loading branch information
BryanSlavinBryter committed Nov 7, 2024
1 parent 320b724 commit b1e247b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 119 deletions.
Binary file modified apps/hanukkah/hanukkah.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
148 changes: 29 additions & 119 deletions apps/hanukkah/hanukkah.star
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",
),
],
)

0 comments on commit b1e247b

Please sign in to comment.