Scripts Examples

Here we will add all the scripts we made. (still under construction)

How to add a script

Here is a quick guide showing how to add scripts
How to add script

Light and Dimmers scripts

Pro Dimmer 2PM - Ch.1 "Follows" Ch.0 settings

Script summary (for Shelly Pro Dimmer 2PM with 2 channels):

  • Monitors channel 0 for changes.
  • If on/off or brightness changes, it updates channel 1 to match.

Testet with FW. 1.6.2

// This script is for Shelly Pro Dimmer 2PM with 2 channels:
// Channel 0 is the primary dimmer
// Channel 1 will follow channel 0

try {
  Shelly.addStatusHandler(function (event, user_data) {
    // Only respond to changes on channel 0
    if (event.component === "light:0" && event.delta) {
      let stateChanged = event.delta.hasOwnProperty('output');
      let brightnessChanged = event.delta.hasOwnProperty('brightness');

      if (stateChanged || brightnessChanged) {
        let newParams = { id: 1 };

        if (stateChanged) {
          newParams.on = event.delta.output;
        }

        if (brightnessChanged) {
          newParams.brightness = event.delta.brightness;
        }

        Shelly.call("light.set", newParams,
          function (res, err_code, err_msg) {
            if (err_code === 0) {
              print("Channel 1 updated to match Channel 0.");
            } else {
              print("Error updating Channel 1: " + err_msg);
            }
          }
        );
      }
    }
  });
} catch (err) {
  print("Script error: " + err.message);
}
Dimmer Gen3/Pro1PM - Sync to other dimmers

Shelly Dimmer Sync Script:

  • Monitors the state and brightness of the primary dimmer (light:0).
  • Detects changes in on/off state or brightness.
  • Sends updated state and brightness via HTTP RPC calls to a list of secondary dimmers (at configured IPs and channels).
  • Automatically keeps all secondary dimmers in sync with the primary.

To control more dimmers, simply add more IP address and channel entries to the list.
Testet with FW. 1.6.2

// Set the IP addresses and channels for the secondary dimmers (device B, C, etc.)
let secondaryDimmers = [
  { ip: "192.168.2.169", channel: 0 }, // Channel 0 on the first dimmer
  { ip: "192.168.2.169", channel: 1 }, // Channel 1 on the same dimmer
 // Add more devices as needed
  
  
];

// Function to update a secondary dimmer using RPC
function updateSecondaryDimmer(ip, channel, state, brightness) {
  try {
    let url = "http://" + ip + "/rpc/light.set?id=" + channel + "&on=" + (state === "on" ? "true" : "false") + "&brightness=" + brightness;

    print("Attempting to update secondary dimmer at: " + url);

    Shelly.call(
      "http.get",
      { url: url },
      function (response, error_code, error_message) {
        try {
          if (error_code === 0) {
            print("Successfully updated secondary dimmer at IP: " + ip + " on channel: " + channel);
          } else {
            print("Error updating secondary dimmer at IP: " + ip + " on channel: " + channel + " - " + error_message);
          }
        } catch (err) {
          print("Exception in RPC response handler: " + JSON.stringify(err));
        }
      }
    );
  } catch (err) {
    print("Exception while preparing or sending RPC call: " + JSON.stringify(err));
  }
}

// Update all secondary dimmers
function updateAllSecondaryDimmers(state, brightness) {
  try {
    for (let i = 0; i < secondaryDimmers.length; i++) {
      let dimmer = secondaryDimmers[i];
      updateSecondaryDimmer(dimmer.ip, dimmer.channel, state, brightness);
    }
  } catch (err) {
    print("Exception in updateAllSecondaryDimmers: " + JSON.stringify(err));
  }
}

// Monitor changes in the on/off status and brightness of the primary dimmer (channel 0)
try {
  Shelly.addStatusHandler(function (event, user_data) {
    try {
      print("Event received: ", JSON.stringify(event));

      if (event.component === "light:0" && event.delta) {
        let state = event.delta.output ? "on" : "off";
        let brightness = event.delta.brightness !== undefined ? event.delta.brightness : 0;

        if (event.delta.hasOwnProperty("output") || event.delta.hasOwnProperty("brightness")) {
          print("Primary dimmer state changed - State: " + state + ", Brightness: " + brightness);
          updateAllSecondaryDimmers(state, brightness);
        }
      }
    } catch (err) {
      print("Exception in status handler: " + JSON.stringify(err));
    }
  });
} catch (err) {
  print("Exception while registering status handler: " + JSON.stringify(err));
}
Plus RGBW PM - Sync to other Plus RGBW PM's

Shelly Plus RGBW PM Sync Script:

  • Monitors RGBW state of the primary device (rgbw:0)
  • Detects changes in output, brightness, RGB, and white levels
  • Forwards updates via HTTP POST (RGBW.Set) to all secondary devices
  • Keeps all RGBW devices in sync with the primary

To control more Plus RGBW, simply add more IP address and channel entries to the list.
Testet with FW. 1.6.2

// Set the IP addresses for the secondary RGBW devices
let secondaryDevices = [
  { ip: "192.168.2.220" },  // Add more devices as needed. just remove // to make line active
  // { ip: "192.168.2.221" },
  // { ip: "192.168.2.222" },
  // { ip: "192.168.2.223" },
  
];

// Function to update a secondary RGBW device using RPC
function updateSecondaryDevice(ip, state, brightness, rgb, white) {
  try {
    let payload = {
      id: 0,
      on: state === "true",
      brightness: brightness,
      white: white,
      rgb: rgb,
    };

    let url = "http://" + ip + "/rpc/RGBW.Set";

    print("Attempting to update secondary RGBW device at: " + url + " with payload: " + JSON.stringify(payload));

    Shelly.call(
      "http.post",
      {
        url: url,
        body: JSON.stringify(payload),
        headers: { "Content-Type": "application/json" },
      },
      function (response, error_code, error_message) {
        try {
          if (error_code === 0) {
            print("Successfully updated secondary RGBW device at IP: " + ip);
          } else {
            print("Error updating secondary RGBW device at IP: " + ip + " - " + error_message);
          }
        } catch (err) {
          print("Exception in RPC response handler: " + JSON.stringify(err));
        }
      }
    );
  } catch (err) {
    print("Exception in updateSecondaryDevice for IP " + ip + ": " + JSON.stringify(err));
  }
}

// Update all secondary RGBW devices
function updateAllSecondaryDevices(state, brightness, rgb, white) {
  try {
    for (let i = 0; i < secondaryDevices.length; i++) {
      let device = secondaryDevices[i];
      updateSecondaryDevice(device.ip, state, brightness, rgb, white);
    }
  } catch (err) {
    print("Exception in updateAllSecondaryDevices: " + JSON.stringify(err));
  }
}

// Monitor changes in the RGBW device status
try {
  Shelly.addStatusHandler(function (event, user_data) {
    try {
      print("Event received: ", JSON.stringify(event));

      if (event.component === "rgbw:0" && event.delta) {
        let state = event.delta.output ? "true" : "false";
        let brightness = event.delta.brightness || 0;
        let rgb = event.delta.rgb || [0, 0, 0];
        let white = event.delta.white || 0;

        if (event.delta.hasOwnProperty('output') ||
            event.delta.hasOwnProperty('brightness') ||
            event.delta.hasOwnProperty('rgb') ||
            event.delta.hasOwnProperty('white')) {

          print("Primary RGBW device state changed - State: " + state +
                ", Brightness: " + brightness +
                ", RGB: [" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "]" +
                ", White: " + white);

          updateAllSecondaryDevices(state, brightness, rgb, white);
        }
      }
    } catch (err) {
      print("Exception in status handler: " + JSON.stringify(err));
    }
  });
} catch (err) {
  print("Exception while registering status handler: " + JSON.stringify(err));
}

Misc.

Rename the SSID with Total Energy

Rename the SSID with Total Energy script:

  • Retrieves device ID (or uses custom name)
  •  Reads total energy consumption from Switch (Wh → kWh)
  •  Updates SSID every minute with name + current kWh value
  • Useful for standalone use: check consumption directly in WiFi list

Testet with FW. 1.7.1

/**
 * Shelly Script: Dynamic SSID Updater
 * 
 * Description:
 * This script automatically updates the device's WiFi SSID every minute.
 * The SSID will contain either the default Shelly device ID (without MAC suffix) 
 * or a custom name, followed by the current total energy consumption in kWh 
 * with two decimals.
 * 
 * Use case:
 * Useful when running the device in standalone mode without an app or cloud,
 * but you still want to occasionally check the total energy usage just by 
 * scanning available WiFi networks.
 * 
 * Example SSIDs:
 *   default → "shellyplugsg3-0.41kWh"
 *   custom  → "WashingMachine-0.41kWh"
 */

// ===== CONFIGURATION =====
let SWITCH_ID = 0;                 // Typically 0 on PlugS
let UPDATE_INTERVAL_MS = 60000;    // Update interval in ms (1 minute)
let BASE_NAME = "default";         // Use "default" for device ID, or set custom name string
// ==========================

function updateSSID() {
  try {
    // 1. Get device info
    Shelly.call("Shelly.GetDeviceInfo", {}, function (dev, err1) {
      try {
        if (err1) {
          print("Error getting device info:", JSON.stringify(err1));
          return;
        }

        let baseId;
        if (BASE_NAME !== "default") {
          baseId = BASE_NAME;
          print("Using custom name:", baseId);
        } else {
          let fullId = dev.id; // Example: "shellyplugsg3-543204664698"
          let dashPos = fullId.lastIndexOf("-");
          baseId = (dashPos > 0) ? fullId.substring(0, dashPos) : fullId;
          print("Using default ID:", baseId);
        }

        // 2. Get energy consumption
        Shelly.call("Switch.GetStatus", {id: SWITCH_ID}, function (sw, err2) {
          try {
            if (err2) {
              print("Error getting switch status:", JSON.stringify(err2));
              return;
            }

            let totalWh = sw.aenergy.total;       // Value in Wh
            let totalKWh = totalWh / 1000;        // Convert to kWh
            let formatted = totalKWh.toFixed(2) + "kWh"; // Two decimals + unit

            let newSSID = baseId + "-" + formatted;

            print("Changing SSID to:", newSSID);

            // 3. Update WiFi SSID
            Shelly.call(
              "WiFi.SetConfig",
              { config: { ap: { ssid: newSSID } } },
              function (resp, err3) {
                try {
                  if (err3) {
                    print("Error setting WiFi SSID:", JSON.stringify(err3));
                  } else {
                    print("WiFi SSID updated successfully!");
                  }
                } catch (e3) {
                  print("Exception in WiFi.SetConfig callback:", e3);
                }
              }
            );
          } catch (e2) {
            print("Exception in Switch.GetStatus callback:", e2);
          }
        });
      } catch (e1) {
        print("Exception in Shelly.GetDeviceInfo callback:", e1);
      }
    });
  } catch (e) {
    print("Exception in updateSSID:", e);
  }
}

try {
  // Run once at script start
  updateSSID();

  // Run again every minute
  Timer.set(UPDATE_INTERVAL_MS, true, function() {
    try {
      updateSSID();
    } catch (e) {
      print("Exception in Timer callback:", e);
    }
  });
} catch (mainErr) {
  print("Fatal exception in main script:", mainErr);
}
Dimmer Gen3/Pro1PM - Sync to other dimmers

Shelly Dimmer Sync Script:

  • Monitors the state and brightness of the primary dimmer (light:0).
  • Detects changes in on/off state or brightness.
  • Sends updated state and brightness via HTTP RPC calls to a list of secondary dimmers (at configured IPs and channels).
  • Automatically keeps all secondary dimmers in sync with the primary.

To control more dimmers, simply add more IP address and channel entries to the list.
Testet with FW. 1.6.2

// Set the IP addresses and channels for the secondary dimmers (device B, C, etc.)
let secondaryDimmers = [
  { ip: "192.168.2.169", channel: 0 }, // Channel 0 on the first dimmer
  { ip: "192.168.2.169", channel: 1 }, // Channel 1 on the same dimmer
 // Add more devices as needed
  
  
];

// Function to update a secondary dimmer using RPC
function updateSecondaryDimmer(ip, channel, state, brightness) {
  try {
    let url = "http://" + ip + "/rpc/light.set?id=" + channel + "&on=" + (state === "on" ? "true" : "false") + "&brightness=" + brightness;

    print("Attempting to update secondary dimmer at: " + url);

    Shelly.call(
      "http.get",
      { url: url },
      function (response, error_code, error_message) {
        try {
          if (error_code === 0) {
            print("Successfully updated secondary dimmer at IP: " + ip + " on channel: " + channel);
          } else {
            print("Error updating secondary dimmer at IP: " + ip + " on channel: " + channel + " - " + error_message);
          }
        } catch (err) {
          print("Exception in RPC response handler: " + JSON.stringify(err));
        }
      }
    );
  } catch (err) {
    print("Exception while preparing or sending RPC call: " + JSON.stringify(err));
  }
}

// Update all secondary dimmers
function updateAllSecondaryDimmers(state, brightness) {
  try {
    for (let i = 0; i < secondaryDimmers.length; i++) {
      let dimmer = secondaryDimmers[i];
      updateSecondaryDimmer(dimmer.ip, dimmer.channel, state, brightness);
    }
  } catch (err) {
    print("Exception in updateAllSecondaryDimmers: " + JSON.stringify(err));
  }
}

// Monitor changes in the on/off status and brightness of the primary dimmer (channel 0)
try {
  Shelly.addStatusHandler(function (event, user_data) {
    try {
      print("Event received: ", JSON.stringify(event));

      if (event.component === "light:0" && event.delta) {
        let state = event.delta.output ? "on" : "off";
        let brightness = event.delta.brightness !== undefined ? event.delta.brightness : 0;

        if (event.delta.hasOwnProperty("output") || event.delta.hasOwnProperty("brightness")) {
          print("Primary dimmer state changed - State: " + state + ", Brightness: " + brightness);
          updateAllSecondaryDimmers(state, brightness);
        }
      }
    } catch (err) {
      print("Exception in status handler: " + JSON.stringify(err));
    }
  });
} catch (err) {
  print("Exception while registering status handler: " + JSON.stringify(err));
}
Plus RGBW PM - Sync to other Plus RGBW PM's

Shelly Plus RGBW PM Sync Script:

  • Monitors RGBW state of the primary device (rgbw:0)
  • Detects changes in output, brightness, RGB, and white levels
  • Forwards updates via HTTP POST (RGBW.Set) to all secondary devices
  • Keeps all RGBW devices in sync with the primary

To control more Plus RGBW, simply add more IP address and channel entries to the list.
Testet with FW. 1.6.2

// Set the IP addresses for the secondary RGBW devices
let secondaryDevices = [
  { ip: "192.168.2.220" },  // Add more devices as needed. just remove // to make line active
  // { ip: "192.168.2.221" },
  // { ip: "192.168.2.222" },
  // { ip: "192.168.2.223" },
  
];

// Function to update a secondary RGBW device using RPC
function updateSecondaryDevice(ip, state, brightness, rgb, white) {
  try {
    let payload = {
      id: 0,
      on: state === "true",
      brightness: brightness,
      white: white,
      rgb: rgb,
    };

    let url = "http://" + ip + "/rpc/RGBW.Set";

    print("Attempting to update secondary RGBW device at: " + url + " with payload: " + JSON.stringify(payload));

    Shelly.call(
      "http.post",
      {
        url: url,
        body: JSON.stringify(payload),
        headers: { "Content-Type": "application/json" },
      },
      function (response, error_code, error_message) {
        try {
          if (error_code === 0) {
            print("Successfully updated secondary RGBW device at IP: " + ip);
          } else {
            print("Error updating secondary RGBW device at IP: " + ip + " - " + error_message);
          }
        } catch (err) {
          print("Exception in RPC response handler: " + JSON.stringify(err));
        }
      }
    );
  } catch (err) {
    print("Exception in updateSecondaryDevice for IP " + ip + ": " + JSON.stringify(err));
  }
}

// Update all secondary RGBW devices
function updateAllSecondaryDevices(state, brightness, rgb, white) {
  try {
    for (let i = 0; i < secondaryDevices.length; i++) {
      let device = secondaryDevices[i];
      updateSecondaryDevice(device.ip, state, brightness, rgb, white);
    }
  } catch (err) {
    print("Exception in updateAllSecondaryDevices: " + JSON.stringify(err));
  }
}

// Monitor changes in the RGBW device status
try {
  Shelly.addStatusHandler(function (event, user_data) {
    try {
      print("Event received: ", JSON.stringify(event));

      if (event.component === "rgbw:0" && event.delta) {
        let state = event.delta.output ? "true" : "false";
        let brightness = event.delta.brightness || 0;
        let rgb = event.delta.rgb || [0, 0, 0];
        let white = event.delta.white || 0;

        if (event.delta.hasOwnProperty('output') ||
            event.delta.hasOwnProperty('brightness') ||
            event.delta.hasOwnProperty('rgb') ||
            event.delta.hasOwnProperty('white')) {

          print("Primary RGBW device state changed - State: " + state +
                ", Brightness: " + brightness +
                ", RGB: [" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "]" +
                ", White: " + white);

          updateAllSecondaryDevices(state, brightness, rgb, white);
        }
      }
    } catch (err) {
      print("Exception in status handler: " + JSON.stringify(err));
    }
  });
} catch (err) {
  print("Exception while registering status handler: " + JSON.stringify(err));
}