Shelly Logo Squared

Script Shelly scripts

Garden watering that skips the run when it rains

Runs your irrigation valve on the days and at the time you choose, and skips the run when it has rained or rain is forecast. Uses the free Open-Meteo forecast, with no account.

Updated v1.0

  • Gen2
  • Gen3
  • Gen4
  • Pro
rain-skip-watering.js · 104 lines Download .js
// Rain-aware watering: runs the garden valve on your days, and skips the run// when it has rained or rain is on the way. Uses the free Open-Meteo forecast. let CONFIG = {  latitude: -37.81,  longitude: 144.96,  waterAt: "06:00",  waterDays: "Mon,Wed,Fri",  runMin: 20,  skipIfRainedMm: 5,  skipIfForecastMm: 3,  skipIfChancePct: 70,  waterIfNoForecast: true,  switchId: 0,}; // Check the clock every 20 seconds, so the run 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 DAY_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; let lastRunDate = -1;let retried = false; // Local date (days since 1970), weekday 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;  let date = Math.floor((s.unixtime + (s.utc_offset || 0)) / 86400);  // 1 January 1970 was a Thursday.  return { date: date, weekday: DAY_NAMES[(date + 4) % 7], time: s.time };} function forecastUrl() {  // past_days=1 adds yesterday's rain as the first value, today's is second.  return "https://api.open-meteo.com/v1/forecast?latitude=" + CONFIG.latitude +    "&longitude=" + CONFIG.longitude +    "&daily=precipitation_sum,precipitation_probability_max" +    "&timezone=auto&past_days=1&forecast_days=1";} function water(reason) {  print("Watering for " + CONFIG.runMin + " min. " + reason);  // The relay switches itself off after runMin, so the valve can't be left  // open if the script stops or the Shelly loses Wi-Fi mid-run.  Shelly.call("Switch.Set", {    id: CONFIG.switchId,    on: true,    toggle_after: CONFIG.runMin * 60,  });} function noForecast(why) {  if (!retried) {    retried = true;    print("Couldn't get the forecast (" + why + "). Trying again in 2 min.");    Timer.set(RETRY_SEC * 1000, false, fetchForecast);    return;  }  if (CONFIG.waterIfNoForecast) water("No forecast, so watering as scheduled.");  else print("No forecast, so skipping today's watering.");} function onForecast(res, err) {  if (err !== 0 || res.code !== 200) return noForecast("error " + (err !== 0 ? err : res.code));  let d = null;  try {    d = JSON.parse(res.body).daily;  } catch (e) {    return noForecast("unreadable reply");  }  let rained = d.precipitation_sum[0] || 0;  let coming = d.precipitation_sum[1] || 0;  let chance = d.precipitation_probability_max[1] || 0;  let weather = "Rain yesterday " + rained + " mm, today " + coming + " mm forecast (" +    chance + "% chance).";  if (rained >= CONFIG.skipIfRainedMm || coming >= CONFIG.skipIfForecastMm ||      chance >= CONFIG.skipIfChancePct) {    print("Skipping today's watering. " + weather);    return;  }  water(weather);} function fetchForecast() {  Shelly.call("HTTP.GET", { url: forecastUrl(), timeout: 15 }, onForecast);} function check() {  let now = localNow();  // Without the clock it can't tell the day or the time, so it does nothing.  if (now === null) return;  if (now.time !== CONFIG.waterAt || now.date === lastRunDate) return;  if (CONFIG.waterDays.indexOf(now.weekday) === -1) return;  lastRunDate = now.date;  retried = false;  fetchForecast();} Timer.set(CHECK_EVERY_SEC * 1000, true, check);print("Rain-aware watering started. Next run at " + CONFIG.waterAt + " on " +  CONFIG.waterDays + ".");

What it does

On each watering day, at the time you set, the script asks Open-Meteo for yesterday's rainfall and today's forecast at your garden. If yesterday had 5 mm or more, today's forecast is 3 mm or more, or the chance of rain is 70% or higher, it skips the run and prints why. Otherwise it switches the relay on, which opens the valve.

The relay is told to switch itself off after the run time, so the valve closes even if the script stops or the Wi-Fi drops mid-run. If the forecast doesn't come back, the script asks again two minutes later, then waters as scheduled (or skips, if you've set it to). It does nothing until the Shelly's clock has synced, so a power cut can't make it water at the wrong time.

Install it on your Shelly

View the full install guide

Before you install

  1. Set the relay to stay off after a blackout

    In the Shelly app, open the relay's settings and set its power-on default to Off, so a power cut mid-run can't leave the valve open.

  2. 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.

Install the script

Shelly Smart Control

  1. 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.

  2. Tap Create new script

    If the device has no scripts yet, the screen says No scripts created.

  3. Name it, paste the code, then tap Save

    Name it rain-skip-watering. Tap in the code area, paste the script you copied above, then tap Save (the disk icon at the top right).

  4. 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.

  5. 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

  1. 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.

  2. Click Create script

    If the device has no scripts yet, the list says so.

  3. Name it, paste the code, then click Save

    Name it rain-skip-watering. Click in the code area, paste the script you copied above, then click Save (the disk icon above the code).

  4. 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.

  5. 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

  1. Test it

    Stop the script, set waterAt two minutes ahead, save it and run it again. On the device's web page, the console prints the rain figures and whether it's watering or skipping. Set the time 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