Script Shelly scripts
Frost alert on your phone the evening before a cold night
Checks tonight's forecast low each evening and sends a notification through ntfy when it's cold enough for frost. Uses the free Open-Meteo forecast, with no account.
- Gen2
- Gen3
- Gen4
- Pro
// Frost alert: checks the overnight forecast each evening and tells your phone// through ntfy when it's going to be cold enough for frost. Uses the free Open-Meteo forecast. let CONFIG = { latitude: -37.81, longitude: 144.96, checkAt: "17:00", frostTemp: 2, ntfyTopic: "",}; // Check the clock every 20 seconds, so the check runs within the minute set.let CHECK_EVERY_SEC = 20;// If the forecast doesn't come back, ask once more ten minutes later.let RETRY_SEC = 600; let lastCheckDate = -1;let retried = false; // Local date (days since 1970) and "HH:MM", or null before the clock has synced.function localNow() { let s = Shelly.getComponentStatus("sys"); if (s === null || typeof s.unixtime !== "number" || s.time === null) return null; return { date: Math.floor((s.unixtime + (s.utc_offset || 0)) / 86400), time: s.time };} // Today's and tomorrow's lows. The coldest part of tonight is early tomorrow// morning, so the second day's low is the one that matters.function forecastUrl() { return "https://api.open-meteo.com/v1/forecast?latitude=" + CONFIG.latitude + "&longitude=" + CONFIG.longitude + "&daily=temperature_2m_min&timezone=auto&forecast_days=2";} function onSent(res, err) { if (err !== 0 || res.code !== 200) print("Couldn't send the alert to ntfy.");} function alert(msg) { print(msg); if (CONFIG.ntfyTopic === "") return; Shelly.call("HTTP.Request", { method: "POST", url: "https://ntfy.sh/" + CONFIG.ntfyTopic, body: msg, headers: { "Content-Type": "text/plain" }, timeout: 15, }, onSent);} function noForecast(why) { if (!retried) { retried = true; print("Couldn't get the forecast (" + why + "). Trying again in 10 min."); Timer.set(RETRY_SEC * 1000, false, fetchForecast); return; } print("Still no forecast (" + why + "). No frost check tonight.");} function onForecast(res, err) { if (err !== 0 || res.code !== 200) return noForecast("error " + (err !== 0 ? err : res.code)); let low = null; try { low = JSON.parse(res.body).daily.temperature_2m_min[1]; } catch (e) { return noForecast("unreadable reply"); } if (typeof low !== "number") return noForecast("no temperature in the reply"); if (low <= CONFIG.frostTemp) { alert("Frost likely tonight: the forecast low is " + low + " C. Cover or bring in anything tender."); } else { print("Forecast low of " + low + " C tonight. No frost alert."); }} function fetchForecast() { Shelly.call("HTTP.GET", { url: forecastUrl(), timeout: 15 }, onForecast);} function check() { let now = localNow(); // Without the clock it can't tell the time, so it does nothing. if (now === null) return; if (now.time !== CONFIG.checkAt || now.date === lastCheckDate) return; lastCheckDate = now.date; retried = false; fetchForecast();} Timer.set(CHECK_EVERY_SEC * 1000, true, check);print("Frost alert started. Checks the forecast at " + CONFIG.checkAt + " each day, alerts at " + CONFIG.frostTemp + " C or below."); What it does
At the time you set, 5 pm by default, the script asks Open-Meteo for tomorrow's low at your garden. The coldest part of the night is just before sunrise, so tomorrow's low is the one that decides a frost. At 2 °C or below you get a message with the figure, in time to cover seedlings or bring pots in. Above that, the console notes the low and nothing is sent. The forecast is for the air above the ground, and the ground gets colder on a clear, still night, so the default warns a little above zero.
If the forecast doesn't come back, the script asks again ten minutes later, then gives up for the night and says so in the console. It does nothing until the Shelly's clock has synced, so it can't check at the wrong time.
Install it on your Shelly
Before you install
- Find your garden's location
In Google Maps, right-click your garden and click the numbers at the top of the menu to copy them. The first is the latitude, the second the longitude.
- Subscribe in ntfy
Install the ntfy app and subscribe to a topic name nobody would guess, such as smith-garden-4821.
Install the script
Shelly Smart Control
- Open the device and tap Scripts
In Shelly Smart Control, open the room, then the device. Tap Scripts, the { } icon in the menu down the left.
- Tap Create new script
If the device has no scripts yet, the screen says No scripts created.
- Name it, paste the code, then tap Save
Name it frost-alert. Tap in the code area, paste the script you copied above, then tap Save (the disk icon at the top right).
- Tap the play button
The play button lights up once the script is saved. Tap it and a message says the script has been started.
- Close the editor and turn on Run on startup
Back on the Scripts screen, turn on Run on startup next to your script, so it starts again after a power cut or a firmware update.
Direct access via IP
- Open the device's web page and click Scripts
Find the IP address in the Shelly app under Device settings, then Device information, and type it into a browser on the same Wi-Fi. Click Scripts in the menu on the left.
- Click Create script
If the device has no scripts yet, the list says so.
- Name it, paste the code, then click Save
Name it frost-alert. Click in the code area, paste the script you copied above, then click Save (the disk icon above the code).
- Click Run and check the console
Run appears once the script is saved. The console under the code then prints what the script is doing.
- Turn on Run on startup
Click Scripts again and turn on Run on startup next to your script, so it starts again after a power cut or a firmware update.
After you install
- Test it
Stop the script, set checkAt two minutes ahead and frostTemp to 30, save it and run it again. Your phone gets a frost alert with tonight's low. Set both back afterwards.
Changelog
v1.0 First release. Still need a hand?
We answer most messages within one business day. If your question is about an existing order, have your order number ready. It speeds things up.
Contact us