Shelly Logo Squared

Script Shelly scripts

Phone alert when your mains voltage goes too high or too low

Reads the supply voltage on a Shelly energy meter and sends a notification to your phone through ntfy when it stays outside the Australian range, then again when it's back.

Updated v1.0

  • Gen3
  • Gen4
  • Pro
mains-voltage-alert.js · 111 lines Download .js
// Mains voltage alert: tells your phone through ntfy when the supply voltage stays// outside the Australian range, and again when it's back. Needs a Shelly energy meter. let CONFIG = {  highVolts: 253,  lowVolts: 216,  holdSec: 60,  ntfyTopic: "",  meterId: 0,}; // Read the meter every 5 seconds, so a short spike is seen without filling the log.let READ_EVERY_SEC = 5;// The voltage has to come this far back inside the range before the all-clear,// so a reading that sits right on the limit can't send alert after alert.let RECOVER_VOLTS = 2;// Unsent messages are kept and retried after each reading, up to this many.let MAX_QUEUED = 10; let outSince = 0;let alerted = false;let worst = 0;let queue = [];let sending = false;let warnedNoMeter = false; function readVolts() {  let s = Shelly.getComponentStatus("em1", CONFIG.meterId);  if (s === null || typeof s.voltage !== "number") return null;  return s.voltage;} function onSent(res, err) {  sending = false;  if (err === 0 && res.code === 200) {    queue.splice(0, 1);    sendNext();  } else {    print("Couldn't reach ntfy. Will try again shortly.");  }} function sendNext() {  if (sending || queue.length === 0 || CONFIG.ntfyTopic === "") return;  sending = true;  Shelly.call("HTTP.Request", {    method: "POST",    url: "https://ntfy.sh/" + CONFIG.ntfyTopic,    body: queue[0],    headers: { "Content-Type": "text/plain" },    timeout: 15,  }, onSent);} function alert(msg) {  print(msg);  if (queue.length >= MAX_QUEUED) queue.splice(0, 1);  queue.push(msg);} function isWorse(v) {  if (worst === 0) return true;  if (v > CONFIG.highVolts) return v > worst;  return v < worst;} function check() {  let v = readVolts();  if (v === null) {    if (!warnedNoMeter) print("No voltage reading. Check meterId.");    warnedNoMeter = true;    return;  }  warnedNoMeter = false;  let now = Shelly.getComponentStatus("sys").uptime;  let out = v > CONFIG.highVolts || v < CONFIG.lowVolts;  let recovered = v <= CONFIG.highVolts - RECOVER_VOLTS && v >= CONFIG.lowVolts + RECOVER_VOLTS;   if (out) {    if (outSince === 0) {      outSince = now;      worst = 0;      print("Voltage " + v.toFixed(1) + " V is outside " + CONFIG.lowVolts + "-" +        CONFIG.highVolts + " V. Watching.");    }    if (isWorse(v)) worst = v;    if (!alerted && now - outSince >= CONFIG.holdSec) {      alerted = true;      alert("Mains voltage is " + (v > CONFIG.highVolts ? "high" : "low") + ": " +        v.toFixed(1) + " V for over " + CONFIG.holdSec + " s (range " +        CONFIG.lowVolts + "-" + CONFIG.highVolts + " V).");    }  } else if (outSince !== 0 && (recovered || !alerted)) {    if (alerted) {      let secs = now - outSince;      let took = secs < 60 ? "under a minute" : "about " + Math.round(secs / 60) + " min";      alert("Mains voltage is back to " + v.toFixed(1) + " V after " + took +        ". It reached " + worst.toFixed(1) + " V.");    } else {      print("Voltage back to " + v.toFixed(1) + " V before the hold time. No alert.");    }    outSince = 0;    alerted = false;  }  sendNext();} Timer.set(READ_EVERY_SEC * 1000, true, check);print("Voltage alert started. Range " + CONFIG.lowVolts + "-" + CONFIG.highVolts +  " V, alert after " + CONFIG.holdSec + " s outside it.");check();

What it does

Every 5 seconds the script reads the voltage from your meter. If it stays above 253 V or below 216 V for a minute, your phone gets an alert with the reading. When the voltage comes back inside the range, a second message says how long it lasted and how far it went. A reading that crosses the line and comes straight back is printed in the console but doesn't alert you.

High voltage is common on streets with a lot of rooftop solar, and it can make a solar inverter switch itself off. A record of when it happens is useful if you report it to your electricity distributor. The meter reads to within 1%, so a reading of 255 V could be anywhere from about 252 V to 258 V. If ntfy can't be reached, the alert waits on the Shelly and goes out once it can.

Install it on your Shelly

View the full install guide

Before you install

  1. Subscribe in ntfy

    Install the ntfy app and subscribe to a topic name nobody would guess, such as smith-volts-4821.

Install the script

Install it on the meter.

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 mains-voltage-alert. 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 mains-voltage-alert. 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

    On the meter's web page, the console prints Voltage alert started with your range. To see an alert, stop the script, set highVolts a few volts under the voltage the meter shows, save it and run it again, then wait out the hold time. Set it 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