SunEvent: Sunrise & Sunset Countdown
Simple automation for displaying time to sunset and sunrise
| System | AWTRIX NG Scripts |
|---|---|
| Firmware | AWTRIX NG |
| Topic | Smarthome |
| Built by | strusic |
| File | Nz45xrESE6xC.ax · 3.6 KB |
| Icons | 2 |
| Published | 26 Aug 2026 |
| Downloads | 2 |
🌅 SunEvent: Sunrise & Sunset Countdown
A native Berry script for AWTRIX NG that acts as a smart countdown timer for upcoming sun events. It runs completely independently on the device and fetches data via the free Open-Meteo API, meaning no Home Assistant and no API keys are required.
✨ Features
-
Smart App Loop (Auto-Hide): The app stays hidden (skipped in the background) for most of the day. It only injects itself into your AWTRIX app rotation when a sunrise or sunset is imminent (e.g., exactly 30 minutes before it happens).
-
Live Countdown: Displays a dynamic countdown in minutes (e.g.,
15M) perfectly centered next to your chosen icon. -
Zero Registration: Uses the open-meteo.com API, which works out of the box using just your GPS coordinates.
-
Built-in Test Mode: Includes a toggle to force the app to appear immediately on your screen, making it easy to test your icons and settings without waiting for the actual sunset.
⚙️ Configuration
Navigate to Apps -> Settings (next to the script name) in your AWTRIX WebUI to configure the following parameters:
-
lat&lon(number): Your exact Latitude and Longitude for accurate sun event calculations. -
minutes(number): The alert threshold. This dictates how many minutes before the sunrise/sunset the app should start appearing in your rotation (Default:30, Range: 5–120). -
duration(number): How long the app stays on the screen per cycle, in milliseconds (Default:10000/ 10 seconds). -
icon_rise(text): The AWTRIX Icon ID to display during a sunrise (Default:2893). -
icon_set(text): The AWTRIX Icon ID to display during a sunset (Default:53384). -
test_mode(bool): Toggle this totrueto bypass the timer and force the app to display immediately. Remember to set it back tofalsefor normal operation!
💡 How it works
The script fetches the daily sunrise and sunset UNIX timestamps once an hour to keep the API load extremely low. Every second, it checks the local device time against these timestamps. Once the remaining time drops below your configured minutes threshold, the app automatically activates and starts counting down.
Nz45xrESE6xC.ax
# @name SunEvent
# @desc Odliczanie do wschodu i zachodu słońca
# @author strusic
# @version 1.5
# @config lat number "Latitude" default=50.2584 min=-90 max=90 step=0.0001
# @config lon number "Longitude" default=19.0275 min=-180 max=180 step=0.0001
# @config minutes number "Alert przed (min)" default=30 min=5 max=120
# @config duration number "Czas wyświetlania (ms)" default=10000 min=1000 max=60000
# @config icon_rise text "Ikona - Wschód" default="2893"
# @config icon_set text "Ikona - Zachód" default="53384"
# @config test_mode bool "Tryb testowy (pokaż teraz)" default=false
class SunEvent
var sunrise_ts, sunset_ts, active, label, current_icon, ticks, check_ticks, alert_mins, dur, icon_rise, icon_set, test_mode
def init()
self.sunrise_ts = store.get("sunrise_ts", 0)
self.sunset_ts = store.get("sunset_ts", 0)
self.active = false
self.label = ""
self.current_icon = ""
self.ticks = 0
self.check_ticks = 0
self.alert_mins = int(store.get("minutes"))
self.dur = int(store.get("duration"))
self.icon_rise = store.get("icon_rise")
self.icon_set = store.get("icon_set")
self.test_mode = store.get("test_mode")
end
def duration()
return self.dur
end
def on_body(body, status)
if body == nil return end
# Naprawiony regex - wyłapuje pierwszą liczbę po znaku nawiasu kwadratowego "["
var sr = re.search("\"sunrise\":\\s*\\[\\s*([0-9]+)", body)
var ss = re.search("\"sunset\":\\s*\\[\\s*([0-9]+)", body)
if sr != nil && ss != nil
self.sunrise_ts = int(sr[1])
self.sunset_ts = int(ss[1])
store.set("sunrise_ts", self.sunrise_ts)
store.set("sunset_ts", self.sunset_ts)
end
end
def loop()
self.test_mode = store.get("test_mode")
if self.test_mode
self.label = "15M"
self.current_icon = self.icon_set
self.active = true
return
end
if self.ticks <= 0
self.ticks = 3600
# Dodany parametr &forecast_days=1 odchudza JSON-a do dzisiejszego dnia
var url = "http://api.open-meteo.com/v1/forecast?latitude=" + str(store.get("lat")) +
"&longitude=" + str(store.get("lon")) +
"&daily=sunrise,sunset&timeformat=unixtime&timezone=auto&forecast_days=1"
http.get(url, / b, st -> self.on_body(b, st), {'find': "\"daily\":", 'keep': 256})
end
self.ticks -= 1
if self.check_ticks <= 0
self.check_ticks = 60
var now = epoch_ms() / 1000
if now >= 0 && self.sunrise_ts > 0
var threshold = self.alert_mins * 60
var diff_sr = self.sunrise_ts - now
if diff_sr >= 0 && diff_sr <= threshold
var m = int(diff_sr / 60)
self.label = str(m) + "M"
self.current_icon = self.icon_rise
self.active = true
return
end
var diff_ss = self.sunset_ts - now
if diff_ss >= 0 && diff_ss <= threshold
var m = int(diff_ss / 60)
self.label = str(m) + "M"
self.current_icon = self.icon_set
self.active = true
return
end
end
self.active = false
end
self.check_ticks -= 1
end
def should_show()
return self.active
end
def draw()
clear()
if !icon(self.current_icon, 0, 0)
circle_fill(4, 4, 3, 0xFF8800)
end
var text_w = text_ink_width(self.label)
var x = 8 + int((24 - text_w) / 2)
text(x, 6, self.label, 0xFFFFFF)
end
end
return SunEvent()
Install it on your AWTRIX NG
Your browser writes the script straight to the device on your network. It joins the app rotation right away.
Some browsers refuse to talk to a device on your network from a public page. Download the flow and paste it into the Scripts tab of your device, or install it from a terminal:
These icons belong on the device, in /ICONS. Each one is at
most 32×8
pixels — shown here magnified, at their real proportions.
8×8 px
8×8 px
More flows for AWTRIX NG Scripts or Smarthome
Something wrong with this flow? Report it.