Shelly Scripts Overview
Shelly devices run JavaScript directly on-device for local automation and integrations—no cloud or external servers required. Scripts execute on a modified version of Espruino, providing a JavaScript environment that's close to the standard while optimized for embedded systems.
What Can Scripts Do?
Scripts on Shelly devices can:
- Automate device behavior - Create complex logic that responds to device events
- Create HTTP endpoints - Turn your Shelly into a mini web server
- Integrate with external services - Send HTTP requests, publish MQTT messages
- Control virtual components - Create and manage virtual switches, sensors, and more
- Process sensor data - Read from Bluetooth devices, parse data, trigger actions
- Schedule actions - Use timers for delayed or periodic tasks
Quick Start: Your First Script
Prerequisites
- A Shelly Gen2+ device (Plus or Pro series)
- Device connected to your network
- Device IP address (find it in your router or device's local web interface)
Step 1: Create a Script Slot
- Script.Create HTTP GET Request
- Script.Create Curl Request
- Script.Create Mos Request
http://192.168.33.1/rpc/Script.Create?name="my_first_script"
curl -X POST -d '{"id":1,"method":"Script.Create","params":{"name":"my_first_script"}}' http://${SHELLY}/rpc
mos --port ${PORT} call Script.Create '{"name":"my_first_script"}'
Response
- Script.Create HTTP GET Response
- Script.Create Curl Response
- Script.Create Mos Response
{
"id": 1
}
{
"id": 1,
"params": {
"id": 1
}
}
{
"id": 1
}
Step 2: Upload Your Code
- Script.PutCode HTTP GET Request
- Script.PutCode Curl Request
- Script.PutCode Mos Request
http://192.168.33.1/rpc/Script.PutCode?id=1&code="console.log('Hello Shelly!');\nlet temp = Shelly.getComponentStatus('temperature', 0);\nif (temp && temp.tC > 25) {\n console.log('Temperature is', temp.tC, '°C - Too hot!');\n}"
curl -X POST -d '{"id":1,"method":"Script.PutCode","params":{"id":1,"code":"console.log('Hello Shelly!');\nlet temp = Shelly.getComponentStatus('temperature', 0);\nif (temp && temp.tC > 25) {\n console.log('Temperature is', temp.tC, '°C - Too hot!');\n}"}}' http://${SHELLY}/rpc
mos --port ${PORT} call Script.PutCode '{"id":1,"code":"console.log('Hello Shelly!');\nlet temp = Shelly.getComponentStatus('temperature', 0);\nif (temp && temp.tC > 25) {\n console.log('Temperature is', temp.tC, '°C - Too hot!');\n}"}'
Step 3: Start the Script
- Script.Start HTTP GET Request
- Script.Start Curl Request
- Script.Start Mos Request
http://192.168.33.1/rpc/Script.Start?id=1
curl -X POST -d '{"id":1,"method":"Script.Start","params":{"id":1}}' http://${SHELLY}/rpc
mos --port ${PORT} call Script.Start '{"id":1}'
Step 4: Enable Auto-Start (Optional)
To make the script run automatically when the device boots:
- Script.SetConfig HTTP GET Request
- Script.SetConfig Curl Request
- Script.SetConfig Mos Request
http://192.168.33.1/rpc/Script.SetConfig?id=1&config={"enable":true}
curl -X POST -d '{"id":1,"method":"Script.SetConfig","params":{"id":1,"config":{"enable":true}}}' http://${SHELLY}/rpc
mos --port ${PORT} call Script.SetConfig '{"id":1,"config":{"enable":true}}'
Script Management
For complete script management operations including:
- Listing all scripts
- Checking script status and errors
- Downloading script code
- Stopping and deleting scripts
See the Script Component documentation for all available RPC methods.
Common Script Patterns
Respond to Button Press
Shelly.addEventHandler(function(event) {
if (event.component === "input:0" && event.info.event === "single_push") {
Shelly.call("Switch.Toggle", {id: 0});
console.log("Button pressed - toggling switch");
}
});
Temperature-Based Automation
// Check temperature every minute
Timer.set(60000, true, function() {
let status = Shelly.getComponentStatus("temperature", 0);
if (status && status.tC > 28) {
// Turn on cooling fan
Shelly.call("Switch.Set", {id: 0, on: true});
} else if (status && status.tC < 25) {
// Turn off cooling fan
Shelly.call("Switch.Set", {id: 0, on: false});
}
});
Send HTTP Notifications
function sendAlert(message) {
Shelly.call("HTTP.Request", {
method: "POST",
url: "https://your-webhook.com/alert",
body: JSON.stringify({
device: Shelly.getDeviceInfo().id,
message: message,
timestamp: Date.now()
}),
headers: {"Content-Type": "application/json"}
});
}
// Use it in event handlers
Shelly.addEventHandler(function(event) {
if (event.component === "input:0" && event.info.state === true) {
sendAlert("Motion detected!");
}
});
Debugging
Enable debug logs to see script output:
- Sys.SetConfig HTTP GET Request
- Sys.SetConfig Curl Request
- Sys.SetConfig Mos Request
http://192.168.33.1/rpc/Sys.SetConfig?config={"debug":{"websocket":{"enable":true}}}
curl -X POST -d '{"id":1,"method":"Sys.SetConfig","params":{"config":{"debug":{"websocket":{"enable":true}}}}}' http://${SHELLY}/rpc
mos --port ${PORT} call Sys.SetConfig '{"config":{"debug":{"websocket":{"enable":true}}}}'
Then connect to see logs:
wscat --connect ws://YOUR_SHELLY_IP/debug/log
Community Script Examples
The shelly-script-examples repository contains example scripts for common use cases. Here are some highlights:
BLE and Shelly BLU Integration
| Script | Description |
|---|---|
| ble-shelly-blu.js | Universal BLU device scanner that decodes BTHome data and emits events for other scripts to handle |
| ble-events-handler.js | Companion script that handles BLU events with configurable automations |
| ble-shelly-btn-gateway.js | Use Gen2 device as gateway between BLU Button and other Shelly devices |
Power and Energy Management
| Script | Description |
|---|---|
| load-shedding.js | Automatic load shedding based on power thresholds with Pro4PM/Pro3EM |
| consume-limited-power.js | Stop output after consuming a set amount of energy |
| failure-monitor.js | Alert when load power drops to zero while switch is on |
MQTT and Home Assistant
| Script | Description |
|---|---|
| mqtt-discovery.js | MQTT Auto Discovery for Home Assistant integration |
| mqtt-announce.js | Gen1 MQTT format compatibility for mixed device networks |
Advanced Patterns
| Script | Description |
|---|---|
| scene.js | Scene player with sequential actions, delays, and conditions |
| remoterpc.js | Remote Shelly abstraction for calling RPC methods on other devices |
| telegram-interaction.js | Telegram bot framework with command parsing and parameter validation |
| router-watchdog.js | Monitor connectivity and auto-restart router on failure |
LoRa Communication (Gen3+)
| Script | Description |
|---|---|
| lora-send-encrypted-msg.js | Send AES-encrypted messages over LoRa with checksum verification |
| lora-covercontrol-sender.js | Remote cover control over LoRa for long-range automation |
Many scripts in the repository are designed to work together. For example, ble-shelly-blu.js emits events that ble-events-handler.js can process, allowing you to separate BLE scanning from automation logic.
Getting Help
- Check
Script.GetStatusfor error information - Enable debug logs to see script output and errors
- Scripts causing crashes are automatically disabled on reboot
- Browse the full community examples repository for more scripts