Shelly Logo Squared

Script Shelly scripts

Holiday lights that come on at a different time each night

While you're away, a light switches on and off at a random time inside the windows you set, so the house doesn't look empty at the same minute every evening.

Updated v1.1

  • Gen2
  • Gen3
  • Gen4
  • Pro
holiday-lights.js · 91 lines Download .js
// Holiday lights: switches a light on and off at a different time each evening, so// the house looks lived in while you're away. Runs on any Gen2 or newer Shelly relay or dimmer. let CONFIG = {  onFrom: "18:30",  onSpreadMin: 45,  offFrom: "22:30",  offSpreadMin: 60,  switchId: 0,  dimmer: false,  brightness: 60,  fadeSec: 0,}; // Check the clock every 20 seconds, so each change lands within the minute picked.let CHECK_EVERY_SEC = 20; // Tonight's plan: the local date it's for and the minutes past midnight to switch.let plan = { date: -1, onAt: 0, offAt: 0 };let isOn = null;let waitingForClock = false; function toMinutes(hhmm) {  let p = hhmm.split(":");  return Number(p[0]) * 60 + Number(p[1]);} function hhmm(m) {  m = m % 1440;  let h = Math.floor(m / 60);  let mm = m % 60;  return (h < 10 ? "0" : "") + h + ":" + (mm < 10 ? "0" : "") + mm;} // Local date (days since 1970) and minutes past midnight, 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 t = s.unixtime + (s.utc_offset || 0);  return { date: Math.floor(t / 86400), min: Math.floor((t % 86400) / 60) };} // An evening runs from midday to midday, so times after midnight belong to the// evening before.let MIDDAY = 720; function evening(t) {  return t < MIDDAY ? t + 1440 : t;} function newPlan(date) {  let onAt = evening(toMinutes(CONFIG.onFrom)) + Math.floor(Math.random() * (CONFIG.onSpreadMin + 1));  let offAt = evening(toMinutes(CONFIG.offFrom)) + Math.floor(Math.random() * (CONFIG.offSpreadMin + 1));  plan = { date: date, onAt: onAt, offAt: offAt };  print("Tonight: on at " + hhmm(onAt) + ", off at " + hhmm(offAt) + ".");} function setLight(on) {  if (isOn === on) return;  isOn = on;  print(on ? "Light on." : "Light off.");  if (!CONFIG.dimmer) {    Shelly.call("Switch.Set", { id: CONFIG.switchId, on: on });    return;  }  let p = { id: CONFIG.switchId, on: on };  if (on) p.brightness = CONFIG.brightness;  if (CONFIG.fadeSec > 0) p.transition_duration = CONFIG.fadeSec;  Shelly.call("Light.Set", p);} function check() {  let now = localNow();  // Without the clock it can't tell the time, so it leaves the light alone.  if (now === null) {    if (!waitingForClock) print("Waiting for the clock to sync.");    waitingForClock = true;    return;  }  waitingForClock = false;  let date = now.min < MIDDAY ? now.date - 1 : now.date;  if (plan.date !== date) newPlan(date);  // Minutes since midnight at the start of this evening.  let m = now.min + (now.date - date) * 1440;  setLight(m >= plan.onAt && m < plan.offAt);} Timer.set(CHECK_EVERY_SEC * 1000, true, check);print("Holiday lights started. Stop the script when you're home.");check();

What it does

Each day at midday the script picks two random minutes: one for the light to come on, somewhere between onFrom and the spread after it, and one for it to go off. With the defaults the light comes on between 6:30 and 7:15 pm and goes off between 10:30 and 11:30 pm, different every night. A Shelly schedule can't do that, because it fires at the same minute every day.

If you start the script during the evening, the light comes on straight away and goes off at tonight's time. It does nothing until the Shelly's clock has synced, so a blackout can't switch the light on in the middle of the day. It only sends a command when the plan changes, so if you switch the light at the wall while it's running, it waits until the next on or off time before changing it again.

On a Shelly dimmer, set dimmer to true. The light then comes on at the brightness you choose rather than full, and fadeSec lets it fade up and down the way someone would dim a room. A dimmer's night mode doesn't change it, because the script always sets the brightness itself.

Install it on your Shelly

View the full install guide

Before you install

  1. Check the device's time zone

    In the Shelly app, check the relay's time zone is your own. The script reads the device's clock, and the times follow daylight saving.

Install the script

Install it before you leave, so a blackout while you're away doesn't end it.

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 holiday-lights. 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 holiday-lights. 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. Check tonight's times

    On the device's web page, the console prints tonight's times, such as Tonight, on at 18:52, off at 23:07.

  2. Stop it when you're home

    Stop the script (Stop in the browser, the pause button in the app) and turn off Run on startup. The light and its wall switch work as normal again.

Changelog

v1.1 Runs on a Shelly dimmer too
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