Scripts Examples
- Home
- 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));
}