Script Shelly scripts
Blinds that close before a hot day, from the weather forecast
Checks the morning forecast and lowers your blinds or shutters before the heat arrives when the day will be hot, then raises them in the evening. Uses the free Open-Meteo forecast, with no account.
- Gen2
- Gen3
- Gen4
- Pro
// Blinds on a hot day: checks the forecast each morning and closes the blinds before the// heat arrives when the day will be hot, then opens them in the evening.// Uses the free Open-Meteo forecast, with no account. Needs a Shelly in cover mode. let CONFIG = { latitude: -37.81, longitude: 144.96, hotTemp: 30, closeAt: "09:00", openAt: "18:30", coverId: 0,}; // Check the clock every 20 seconds, so a move starts within the minute set.let CHECK_EVERY_SEC = 20;// If the forecast doesn't come back, ask once more two minutes later.let RETRY_SEC = 120;let TAG = "hot-day-blinds"; let lastCheckDate = -1;let lastOpenDate = -1;let closedToday = false;let retried = false; function onForecast(res, err) { if (err !== 0 || res.code !== 200) return retryWithDelay("error " + (err !== 0 ? err : res.code)); let temp = null; try { temp = JSON.parse(res.body).daily.temperature_2m_max[0]; } catch (e) { return retryWithDelay("unreadable reply"); } if (typeof temp !== "number") return retryWithDelay("no temperature in the reply"); if (temp < CONFIG.hotTemp) { print("Forecast top of " + temp + " C today, under " + CONFIG.hotTemp + " C. Blind left open."); return; } print("Forecast top of " + temp + " C today. Closing the blind."); closedToday = close();} function forecastLink() { return "https://api.open-meteo.com/v1/forecast?latitude=" + CONFIG.latitude + "&longitude=" + CONFIG.longitude + "&daily=temperature_2m_max&timezone=auto&forecast_days=1";} function moveOutcome(res, err, msg) { if (err !== 0) print("The Shelly refused the move: " + msg);} function retryWithDelay(why) { if (!retried) { retried = true; print("Couldn't get the forecast (" + why + "). Trying again in 2 min."); Timer.set(RETRY_SEC * 1000, false, fetchForecast_ed4c); return; } print("No forecast today, so the blind stays where it is.");} // 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 };} function readCover() { return Shelly.getComponentStatus("cover", CONFIG.coverId);} function close() { let c = readCover(); if (c.state === "closed") { print("The blind is already closed. Leaving it."); return false; } Shelly.call("Cover.Close", { id: CONFIG.coverId, tag: TAG }, moveOutcome); return true;} // Opens only if the blind is still where the script left it. If someone has moved it// since, they wanted it that way.function open() { let c = readCover(); if (c.state !== "closed") { print("Someone has moved the blind since this morning. Leaving it."); return; } print("Opening the blind for the evening."); Shelly.call("Cover.Open", { id: CONFIG.coverId, tag: TAG }, moveOutcome);} function fetchForecast_ed4c() { Shelly.call("HTTP.GET", { url: forecastLink(), 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.closeAt && now.date !== lastCheckDate) { lastCheckDate = now.date; closedToday = false; retried = false; fetchForecast_ed4c(); } if (CONFIG.openAt !== "" && now.time === CONFIG.openAt && now.date !== lastOpenDate) { lastOpenDate = now.date; if (closedToday) open(); closedToday = false; }} function init() { let c = readCover(); if (c === null) { print("There's no blind " + CONFIG.coverId + " on this Shelly. Set it to cover mode, or check coverId."); return; } Timer.set(CHECK_EVERY_SEC * 1000, true, check); print("Hot day blinds started. Checks the forecast at " + CONFIG.closeAt + " and closes at " + CONFIG.hotTemp + " C or more.");} init(); What it does
Each morning at the time you set, the script asks Open-Meteo for today's top temperature at your home. If it's at or above your limit, it lowers the blind, before the sun has had a chance to heat the room. In the evening it raises it again. On a mild day it leaves the blind alone.
The script only reopens a blind it closed itself, and only if it's still closed, so a blind you've moved during the day stays where you put it. If the forecast doesn't come back, it asks again two minutes later, then leaves the blind as it is. It does nothing until the Shelly's clock has synced. Shelly's Premium plan can close blinds from a forecast in the app; this does it on the device for free. Give each blind its own copy of the script, with a closeAt that suits when the sun reaches that side of the house.
Install it on your Shelly
Before you install
- Find your home's location
In Google Maps, right-click your home and click the numbers at the top of the menu to copy them. The first is the latitude, the second the longitude.
Install the script
Install it on the Shelly that drives the blind, one copy per Shelly.
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 blinds-hot-day-forecast. 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 blinds-hot-day-forecast. 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 hotTemp to 5 and closeAt two minutes ahead, save it and run it again. The console prints the forecast and the blind closes. Set them back afterwards.
Changelog
v1.1 Tidied the internal function names. It works exactly as before. 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