### Example Changelog Entry Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Provides a concrete example of how to format entries in the CHANGELOG.md file for a specific month. ```markdown ## 2026-02 - Add precipitation-based irrigation control script - Fix BLE scanner timeout issue ``` -------------------------------- ### Start a Script Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Use this command to start a script. Replace DEVICE with the device's IP address or hostname and N with the script ID. ```bash curl -s -X POST http://DEVICE/rpc/Script.Start -H "Content-Type: application/json" -d '{"id":N}' ``` -------------------------------- ### Start Script Manually Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md If the script did not auto-start after deployment, use this command to start it manually. Replace `1` with the correct script ID if it differs. ```bash curl -s -X POST "http://${DEVICE}/rpc/Script.Start" \ -H "Content-Type: application/json" \ -d '{"id":1}' ``` -------------------------------- ### Example Log Output - Deye Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This is an example of expected log output when the Deye SG02LP1 script is running correctly. It shows the script initialization and current readings. ```text Deye SG02LP1 - MODBUS-RTU Reader + Virtual Components ====================================================== [DEYE] VC handle for Total Power -> number:200 ... --- Deye SG02LP1 --- Total Power: 1250 [W] Battery Power: -300 [W] ... ``` -------------------------------- ### Setup Roomba Status Virtual Components Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Creates the necessary virtual components on the Shelly device to display Roomba status and battery percentage. This setup is run once. ```javascript // text:200 - Roomba status display // number:200 - Battery percentage ``` -------------------------------- ### IR Learn Mode Output Example Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/ys_irtm/README.md Example of the output format when capturing IR codes in learn mode, showing Hex, Array, and copy-pasteable addCode format. ```text --- NEW CODE #1 --- Hex: 00 BF 0D Array: [0x00, 0xBF, 0x0D] Copy: addCode('BTN_1', 0x00, 0xBF, 0x0D); ``` -------------------------------- ### Start Script Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Starts the execution of a script identified by its ID. ```APIDOC ## POST /rpc/Script.Start ### Description Starts the execution of a script. ### Method POST ### Endpoint http://DEVICE/rpc/Script.Start ### Parameters #### Request Body - **id** (integer) - Required - The ID of the script to start. ### Request Example ```json { "id": N } ``` ### Response #### Success Response (200) - **result** (object) - An empty object indicating success. #### Response Example ```json { "result": {} } ``` ``` -------------------------------- ### Script Header Documentation Example Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Use this JSDoc format to document script purpose, firmware requirements, device compatibility, and configuration parameters. ```javascript /** * Script name and purpose * * Firmware requirements: X.X+ * Device compatibility: Gen2/Gen3, Plus/Pro series * External hardware: (if applicable) * * Configuration: * - PARAM_1: Description of what it does * - PARAM_2: Description of what it does */ ``` -------------------------------- ### Start Shelly Script Execution Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Initiate the execution of a script on the Shelly device using its assigned ID. ```bash curl -s -X POST http:///rpc/Script.Start \ -H "Content-Type: application/json" -d '{"id": N}' ``` -------------------------------- ### MFRC522 Basic Read Example Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/RFID-RC522/README.md A simple example script for initializing the MFRC522 module, detecting MIFARE cards, and printing their UID. It includes callback-based card detection and read debouncing. ```APIDOC ## MFRC522 Basic Read Example ### Description This script provides a basic example for initializing the MFRC522 RFID module via UART, detecting MIFARE cards, and printing their serial number (UID). It supports callback-based card detection and includes a debounce mechanism to prevent repeated reads of the same card. ### API Methods - **MFRC522.init()** - Description: Initializes the UART connection for the MFRC522 module. - Returns: void - **MFRC522.wait()** - Description: Starts listening for RFID card detections. - Returns: void - **MFRC522.onCard(callback)** - Description: Registers a callback function to be executed when a card is detected. - Parameters: - `callback` (function) - The function to call upon card detection. It receives card details as an argument. - Returns: string - An identifier for the registered callback, which can be used with `offCard`. - **MFRC522.offCard(id)** - Description: Removes a previously registered card detection callback. - Parameters: - `id` (string) - The identifier returned by `onCard` for the callback to remove. - Returns: void ### Example Output ``` ======================================== CARD DETECTED ======================================== Serial (hex): A1 B2 C3 D4 UID: A1B2C3D4 Bytes: [161, 178, 195, 212] ======================================== ``` ``` -------------------------------- ### MFRC522 Basic Read Example API Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/RFID-RC522/README.md API methods for the basic MFRC522 read example. These are used to initialize the module, start listening for cards, and register a callback for card detection. ```javascript MFRC522.init() MFRC522.wait() MFRC522.onCard(callback) MFRC522.offCard(id) ``` -------------------------------- ### Example Log Output - JK200 BMS Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This log output demonstrates successful execution of the JK200 BMS script, including VC handling and device status. ```text JK200 BMS - MODBUS-RTU Reader + Virtual Components =================================================== [JK200] VC handle for MOSFET Temperature -> number:200 ... --- JK200 BMS --- Cells (16): ... Pack: 48.123 V | -12.456 A | -598.765 W SOC: 87 % ... ``` -------------------------------- ### Example Log Output - ST802 Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This log output indicates that the LinkedGo ST802 script is running correctly, showing VC handling and current thermostat readings. ```text LinkedGo ST802 - BMS Modbus RTU Client + Virtual Components [ST802] VC handle for Room Temperature -> number:200 ... [ST802] Room: 21.5degC Humidity: 55% Floor: 19.0degC [ST802] Mode: Heating [ST802] Fan: Auto ``` -------------------------------- ### Deye - Virtual Channel Deployment Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md Examples for adding virtual channels for Deye solar inverter data. ```APIDOC ## POST /rpc/Virtual.Add ### Description Adds a virtual channel to the device to represent a specific sensor or control. ### Method POST ### Endpoint http://${DEVICE}/rpc/Virtual.Add ### Parameters #### Request Body - **type** (string) - Required - The type of the virtual channel (e.g., "number"). - **id** (number) - Required - A unique identifier for the virtual channel. - **config** (object) - Required - Configuration for the virtual channel. - **name** (string) - Required - The display name of the virtual channel. - **persisted** (boolean) - Required - Whether the channel's value should be persisted across reboots. - **unit** (string) - Optional - The unit of measurement for the channel's value. - **min** (number) - Optional - The minimum allowed value for the channel. - **max** (number) - Optional - The maximum allowed value for the channel. ### Request Example ```json { "type": "number", "id": 200, "config": { "name": "Total Power", "persisted": false, "unit": "W", "min": -100000, "max": 100000 } } ``` ### Response #### Success Response (200) - **Result** (boolean) - Indicates if the operation was successful. ``` -------------------------------- ### Create Feature Branch Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/git-commit-merge-cleanup.md Start a new feature branch from the 'dev' branch. Use a descriptive name for the feature branch. ```bash git checkout dev git checkout -b feature/ ``` -------------------------------- ### Example Log Output - CWT-MB308V Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This log shows the expected output for the CWT-MB308V script, detailing VC mappings for buttons and numbers, and current input/output states. ```text CWT-MB308V MODBUS IO Module + Virtual Components ================================================= button:200/201 -> relay toggle (DO 0/1) number:200/201 -> DI 0/1 display number:202/203 -> AO 0/1 sliders number:204/205 -> AI 0/1 progress bars group:200 -> MB308V Demo [MB308V] VC out: DI 0 -> number:200 [MB308V] VC out: DI 1 -> number:201 [MB308V] VC out: AI 0 -> number:204 [MB308V] VC out: AI 1 -> number:205 [MB308V] VC in: Relay 0 toggle -> button:200 [MB308V] VC in: Relay 1 toggle -> button:201 [MB308V] VC in: AO 0 slider -> number:202 [MB308V] VC in: AO 1 slider -> number:203 Polling every 5s... [DI] DI0:0 DI1:1 [AI] AI0:4.12mA AI1:8.35mA ``` -------------------------------- ### Project Structure Overview Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Illustrates the directory layout of the Shelly Script Examples repository, highlighting key subdirectories for different functionalities like BLE, LoRa, MQTT, and utilities. ```text shelly-script-examples/ |-- ble/ # BLE/BLU sensor and button examples |-- lora/ # LoRa communication and device control |-- mqtt/ # MQTT and Home Assistant integrations |-- power-energy/ # Power monitoring and load management |-- switch-input/ # Input, switch, and cover control scripts |-- weather-env/ # Weather and environmental integrations |-- http-integrations/ # HTTP endpoints and external services |-- networking/ # Provisioning and watchdog scripts |-- scheduling/ # Scheduling, scenes, and orchestration |-- blu-assistant/ # Shelly BLU Assistant device management |-- examples-manifest.json # Central registry of all examples (IMPORTANT) |-- howto/ # Basic tutorials and minimal examples |-- snippets/ # Reusable code snippets (JSON format) |-- tools/ # Upload utilities (Python/Bash) `-- .github/ # CI/CD workflows and issue templates ``` -------------------------------- ### Verify Component Creation Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This command lists all components on the device and filters for keys, helping to verify that virtual components were created successfully. The output should include entries like `"key": "number:200"`. ```bash curl -s "http://${DEVICE}/rpc/Shelly.GetComponents" | python3 -m json.tool | grep '"key"' ``` -------------------------------- ### Read via GET Request Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/MODBUS/HTTP-Bridge/README.md Perform a MODBUS read operation using a GET request. URL-encode the descriptor JSON and pass it as the 'register' query parameter. ```bash # URL-encode the JSON first, then: curl 'http:///script//modbus?slave=1®ister=' ``` ```python import json, urllib.parse, requests reg = { "name": "W", "units": "W", "scale": 1, "rights": "R", "reg": {"addr": 0, "rtype": "holding", "itype": "u16", "bo": "BE", "wo": "BE"}, "value": None, "human_readable": None } url = f"http:///script//modbus?register={urllib.parse.quote(json.dumps(reg))}" print(requests.get(url).json()) ``` -------------------------------- ### Create and Configure a Group VC for Deye SG02LP1 Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This section demonstrates how to create a group virtual channel and then set its members. Ensure all desired VCs are created before running the `Group.Set` command. All VCs listed in the `value` array will be visible within the group. ```bash curl -s -X POST "http://${DEVICE}/rpc/Virtual.Add" -H "Content-Type: application/json" \ -d '{"type":"group","id":200,"config":{"name":"Deye SG02LP1"}}' ``` ```bash curl -s -X POST "http://${DEVICE}/rpc/Group.Set" -H "Content-Type: application/json" \ -d '{"id":200,"value":["number:200","number:201","number:202","number:203","number:204","number:205","number:206","number:207","number:208"]}' ``` -------------------------------- ### Shelly HTTP GET Request Pattern Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Perform an HTTP GET request to a specified URL and process the response. Handles successful responses and checks for HTTP status codes. ```javascript Shelly.call('HTTP.GET', { url: 'http://example.com/api' }, function(result, error_code) { if (error_code === 0 && result && result.code === 200) { let data = JSON.parse(result.body); // Process data } }); ``` -------------------------------- ### Configure WiFi Provisioning Script Source: https://github.com/allterco/shelly-script-examples/blob/main/blu-assistant/README.md Sets up target device model IDs, WiFi credentials, and the maximum number of provisioning attempts. Ensure TARGET_MODEL_IDS includes the correct hex ID for your Shelly device. ```javascript var PROV_CONFIG = { TARGET_MODEL_IDS: [0x1829], // add more IDs as needed WIFI_SSID: "your-ssid", WIFI_PASS: "your-password", MAX_ATTEMPTS: 3 }; ``` -------------------------------- ### Read via GET request Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/MODBUS/HTTP-Bridge/README.md It is also possible to read Modbus data using a GET request. In this case, the register descriptor JSON must be URL-encoded and passed as the `register` query parameter. An optional `slave` parameter can also be included. ```APIDOC ## GET /script//modbus ### Description Reads Modbus data using a GET request. The register descriptor must be URL-encoded. ### Method GET ### Endpoint `/script//modbus` ### Parameters #### Query Parameters - **slave** (number) - Optional - The Modbus slave ID to use. - **register** (string) - Required - The URL-encoded JSON string describing the register or coil to read. ### Request Example (using curl) ```bash # URL-encode the JSON descriptor first curl 'http:///script//modbus?slave=1®ister=' ``` ### Request Example (using Python) ```python import json, urllib.parse, requests reg = { "name": "W", "units": "W", "scale": 1, "rights": "R", "reg": {"addr": 0, "rtype": "holding", "itype": "u16", "bo": "BE", "wo": "BE"}, "value": None, "human_readable": None } url = f"http:///script//modbus?register={urllib.parse.quote(json.dumps(reg))}" print(requests.get(url).json()) ``` ### Response #### Success Response (200) Returns a JSON object with the register details and the read value, similar to the POST request response. ``` -------------------------------- ### Get Script Status Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Retrieves the current status of a script identified by its ID. ```APIDOC ## GET /rpc/Script.GetStatus ### Description Retrieves the status of a script. ### Method GET ### Endpoint http://DEVICE/rpc/Script.GetStatus?id=N ### Parameters #### Query Parameters - **id** (integer) - Required - The ID of the script to get the status for. ### Response #### Success Response (200) - **id** (integer) - The ID of the script. - **running** (boolean) - Indicates if the script is currently running. - **error_code** (integer) - The error code if the script encountered an error (0 for no error). #### Response Example ```json { "id": N, "running": true, "error_code": 0 } ``` ``` -------------------------------- ### Synchronize Manifest with Production Scripts Source: https://github.com/allterco/shelly-script-examples/blob/main/tools/README.md Synchronizes the examples-manifest.json file with .shelly.js files in the repository. Only includes files with '@status production' in their JSDoc header. Options include dry-run, removing missing files, and extracting metadata. ```python python tools/sync-manifest-md.py ``` ```python python tools/sync-manifest-md.py --dry-run ``` ```python python tools/sync-manifest-md.py --remove-missing ``` -------------------------------- ### CWT-MB308V - Virtual Channel Deployment Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md Examples for adding virtual channels for CWT-MB308V device. ```APIDOC ## POST /rpc/Virtual.Add ### Description Adds a virtual channel to the device for the CWT-MB308V, supporting relays, digital inputs, and analog signals. ### Method POST ### Endpoint http://${DEVICE}/rpc/Virtual.Add ### Parameters #### Request Body - **type** (string) - Required - The type of the virtual channel (e.g., "button", "number"). - **id** (number) - Required - A unique identifier for the virtual channel. - **config** (object) - Required - Configuration for the virtual channel. - **name** (string) - Required - The display name of the virtual channel. - **persisted** (boolean) - Required - Whether the channel's value should be persisted across reboots. - **unit** (string) - Optional - The unit of measurement for the channel's value. - **min** (number) - Optional - The minimum allowed value for the channel. - **max** (number) - Optional - The maximum allowed value for the channel. ### Request Example ```json { "type": "button", "id": 200, "config": { "name": "Relay 0", "persisted": false } } ``` ### Response #### Success Response (200) - **Result** (boolean) - Indicates if the operation was successful. ``` -------------------------------- ### Power Management Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/SDS018/README.md Methods and examples for managing the SDS018 sensor's power consumption to extend its lifespan. ```APIDOC ## SDS018 Power Management ### Description Strategies for managing the SDS018 sensor's power to prolong its operational life, given its limited lifespan. ### Methods - **SDS018.setWorkPeriod(minutes)** - **Description**: Configures the sensor to take readings at a specified interval, reducing continuous operation. - **Parameters**: - **minutes** (`number`) - The interval in minutes. Set to `0` for continuous operation, or `1-30` for periodic measurements. - **Example**: ```javascript // Measure every 5 minutes SDS018.setWorkPeriod(5); ``` - **SDS018.sleep()** - **Description**: Manually puts the sensor into a low-power sleep state, turning off the fan. - **SDS018.wake()** - **Description**: Wakes the sensor from sleep mode, reactivating the fan. A warm-up period of approximately 30 seconds is recommended after waking before taking readings. ### Example Usage ```javascript // To manually control sleep and wake cycles: SDS018.sleep(); // Fan stops, laser off // ... perform other tasks or wait ... SDS018.wake(); // Fan starts, laser on. Allow ~30s warm-up. ``` ``` -------------------------------- ### Full Deploy and Monitor Workflow with Python Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Automates the deployment of a Shelly script, monitors its startup output, and reports its final status. Handles script sanitization and chunked uploads. ```python #!/usr/bin/env python3 """ Deploy a Shelly script and monitor its startup output. Usage: python deploy.py """ import json, sys, time, threading, urllib.request DEVICE = "http://" + sys.argv[1] SLOT = int(sys.argv[2]) SCRIPT = sys.argv[3] CHUNK = 4000 LOG_SEC = 15 # -- load & sanitise -- with open(SCRIPT) as f: code = f.read() for src, dst in [('\u00b0','deg'),('\u2013','-'),('\u2014','--'),('\u2192','->')]: code = code.replace(src, dst) bad = [c for c in code if ord(c) > 127] if bad: sys.exit(f"Non-ASCII chars remaining: {set(bad)}") # -- helpers -- def rpc(method, params): payload = json.dumps(params).encode() req = urllib.request.Request( DEVICE + "/rpc/" + method, data=payload, headers={"Content-Type": "application/json"} ) try: with urllib.request.urlopen(req, timeout=10) as r: return json.loads(r.read().decode()) except urllib.error.HTTPError as e: sys.exit(f"HTTP {e.code} on {method}: {e.read().decode()}") # -- log stream -- log_lines = [] log_done = threading.Event() def _stream(): try: with urllib.request.urlopen(DEVICE + "/debug/log", timeout=LOG_SEC+5) as r: while not log_done.is_set(): l = r.readline() if not l: break log_lines.append(l.decode("utf-8", errors="replace").rstrip()) except Exception: pass log_thread = threading.Thread(target=_stream, daemon=True) log_thread.start() time.sleep(0.4) # -- stop existing -- try: rpc("Script.Stop", {"id": SLOT}) except SystemExit: pass time.sleep(0.3) # -- upload -- total, offset, last_resp = len(code), 0, {} print(f"Uploading {total} chars to slot {SLOT}...") while offset < total: chunk = code[offset:offset+CHUNK] last_resp = rpc("Script.PutCode", {"id": SLOT, "code": chunk, "append": offset > 0}) print(f" {offset+len(chunk)}/{total}", end="\r") offset += CHUNK print() stored = last_resp.get("len", -1) if stored != total: sys.exit(f"Upload mismatch: source={total} stored={stored}") print(f"Upload verified: {stored} chars stored.") # -- start -- rpc("Script.Start", {"id": SLOT}) print(f"Script started. Collecting log for {LOG_SEC}s...\n") time.sleep(LOG_SEC) log_done.set() # -- print log -- print("---" + " Log output ---") for l in log_lines: print(l) # -- final status -- status = rpc("Script.GetStatus", {"id": SLOT}) print(f"\n---" + " Script status ---") print(f" running : {status.get('running')}") print(f" errors : {status.get('errors')}") print(f" error_msg: {status.get('error_msg')}") print(f" mem_used : {status.get('mem_used')} B") print(f" mem_free : {status.get('mem_free')} B") ``` -------------------------------- ### JK200 BMS - Virtual Channel Deployment Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md Examples for adding virtual channels for JK200 BMS data. ```APIDOC ## POST /rpc/Virtual.Add ### Description Adds a virtual channel to the device to represent a specific sensor or control for the JK200 BMS. ### Method POST ### Endpoint http://${DEVICE}/rpc/Virtual.Add ### Parameters #### Request Body - **type** (string) - Required - The type of the virtual channel (e.g., "number"). - **id** (number) - Required - A unique identifier for the virtual channel. - **config** (object) - Required - Configuration for the virtual channel. - **name** (string) - Required - The display name of the virtual channel. - **persisted** (boolean) - Required - Whether the channel's value should be persisted across reboots. - **unit** (string) - Optional - The unit of measurement for the channel's value. - **min** (number) - Optional - The minimum allowed value for the channel. - **max** (number) - Optional - The maximum allowed value for the channel. ### Request Example ```json { "type": "number", "id": 200, "config": { "name": "MOSFET Temperature", "persisted": false, "unit": "degC", "min": -50, "max": 150 } } ``` ### Response #### Success Response (200) - **Result** (boolean) - Indicates if the operation was successful. ``` -------------------------------- ### Ad Unit Initialization and GPT Setup Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/MODBUS/V-TAC/VT6607103/datasheets/VT-66036103_manualslib_download.html Initializes ad units and configures Google Publisher Tag (GPT) services upon DOMContentLoaded. It sets up ad IDs, defines ad units with their properties, and configures size mappings for different ad units. ```javascript var adUnits = {}, lazyUnits = {}, adUnitIds = {}; let interstitialSlot; var testBannerSizes = []; document.addEventListener("DOMContentLoaded", function () { googletag.cmd.push(function () { googletag.pubads().disableInitialLoad(); }); adUnitIds = { downloadBottom: 'banner_downloadBottomAd', downloadSide: 'banner_downloadSideAd', }; adUnits = { banner_downloadBottomAd: new AdUnit(adUnitIds.downloadBottom, '/134767771/manualslib_dwn_gpt_btm', [728, 90], true, null), banner_downloadSideAd: new AdUnit(adUnitIds.downloadSide, '/134767771/manualslib_dwn_gpt_left_new', [336, 280], true, null), }; lazyUnits = {}; adUnits.banner_downloadBottomAd.slotSizeMap = [[[1370,100], [[980, 120], [970, 250], [930, 180], [336, 280], [580, 400], [250, 360], [300, 250], [250, 250], [200, 200], [728, 90], [300, 50], [480, 320], [320, 480], [320, 50], [120, 600], [300, 1050], [970, 90], [320, 100], [160, 600], [468, 60], [300, 100], [750, 300], [300, 600], [240, 400], [750, 200]]],[[1140,100], [[336, 280], [580, 400], [250, 360], [300, 250], [250, 250], [200, 200], [728, 90], [300, 50], [480, 320], [320, 480], [320, 50], [120, 600], [300, 1050], [320, 100], [160, 600], [468, 60], [300, 100], [750, 300], [300, 600], [240, 400], [750, 200]]],[[1111,100], [[250, 360], [250, 250], [200, 200], [120, 600], [160, 600], [240, 400]]],[[980,100], [[980, 120], [970, 250], [930, 180], [336, 280], [580, 400], [250, 360], [300, 250], [250, 250], [200, 200], [728, 90], [300, 50], [480, 320], [320, 480], [320, 50], [120, 600], [300, 1050], [970, 90], [320, 100], [160, 600], [468, 60], [300, 100], [750, 300], [300, 600], [240, 400], [750, 200]]],[[768,100], [[728, 90], [468, 60], [300, 250], [336, 280], [320, 100], [320, 50]]],[[468,100], [[468, 60], [300, 250], [336, 280], [320, 100], [320, 50]]],[[320,100], [[300, 250], [250, 250], [200, 200], [180, 150], [250, 360]]],[[0,0], [[300, 250], [300, 50]]]]; adUnits.banner_downloadSideAd.slotSizeMap = [[[1111,100], [[336, 280], [320, 100], [234, 60], [300, 50], [300, 100], [300, 250], [320, 50], [250, 250], [250, 250], [200, 200]]],[[768,100], [[728, 90], [468, 60], [300, 250], [336, 280], [320, 100], [320, 50]]],[[468,100], [[468, 60], [300, 250], [336, 280], [320, 100], [320, 50]]],[[320,100], [[300, 250], [250, 250], [200, 200], [180, 150], [250, 360]]],[[0,0], [[300, 250], [300, 50]]]]; ``` -------------------------------- ### Setup Roomba Controller Virtual Components Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Creates all virtual components required for the Roomba button controller, including status displays and control buttons. Run this once before the controller script. ```javascript // text:200 - Roomba status display // number:200 - Battery percentage // button:200 - Main control (Clean/Stop/Dock) // button:201 - Spot clean button ``` -------------------------------- ### Get Device Info with Curl Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Retrieve general information about the Shelly device using a simple curl command. ```bash # Device info curl -s http://DEVICE/rpc/Shelly.GetDeviceInfo ``` -------------------------------- ### Script Categories Table Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Summarizes the different categories of scripts available in the repository, along with examples and brief descriptions of their purpose. ```text | Category | Examples | Description | |----------|----------|-------------| | **BLE/Bluetooth** | aranet4, ruuvi, bparasite, shelly-blu-* | BTHome protocol, sensor reading | | **MQTT** | mqtt-discovery, mqtt-announce | Home Assistant integration | | **Home Automation** | hue-lights, load-shedding | Scene control, power management | | **LoRa** | lora/* | Long-range communication | | **Utilities** | power-*, scheduler-*, weather-* | Monitoring, scheduling | | **Blu Assistant** | blu-assistant/*.shelly.js | Virtual component management | ``` -------------------------------- ### Automated Python Helper for VC Deployment Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/modbus-vc-deploy.md This Python script automates the discovery of VC IDs from a JavaScript file, creates VCs on the device, and uploads/starts a Shelly script. It requires the device IP and the path to the script as arguments. ```python #!/usr/bin/env python3 """ modbus_vc_setup.py -- auto-provision VCs and deploy a *_vc.shelly.js script. Usage: python3 modbus_vc_setup.py Example: python3 modbus_vc_setup.py 192.168.1.100 \ the_pill/MODBUS/Deye/the_pill_mbsa_deye_vc.shelly.js """ import sys, re, json, urllib.request, subprocess def rpc(ip, method, params=None): url = f"http://{ip}/rpc/{method}" data = json.dumps(params or {}).encode() req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"}) with urllib.request.urlopen(req, timeout=10) as r: return json.loads(r.read()) def parse_vc_ids(path): """Extract unique non-null vcId strings from the JS file.""" text = open(path).read() return sorted(set(re.findall(r'vcId:\s*"([^"]+)"', text))) def vc_type_id(vc_str): t, i = vc_str.split(":") return t, int(i) def vc_name_from_file(path, vc_str): """Find the 'name' field of the ENTITY whose vcId matches vc_str.""" pattern = r'name:\s*"([^"]+)"[^}]*vcId:\s*"' + re.escape(vc_str) + '"' m = re.search(pattern, open(path).read(), re.DOTALL) return m.group(1) if m else vc_str def main(): if len(sys.argv) < 3: print(__doc__) sys.exit(1) ip, script = sys.argv[1], sys.argv[2] vc_ids = parse_vc_ids(script) if not vc_ids: print("No vcId values found in", script) sys.exit(0) print(f"Found {len(vc_ids)} VCs to create: {vc_ids}") # Step 1: create each VC group_members = [] for vc in vc_ids: t, i = vc_type_id(vc) if t == "group": continue # create group last name = vc_name_from_file(script, vc) print(f" Virtual.Add {vc} '{name}'") try: rpc(ip, "Virtual.Add", { "type": t, "id": i, "config": {"name": name, "persisted": False, "min": -1000000, "max": 1000000} }) except Exception as e: print(f" WARNING: {e}") group_members.append(vc) # Step 2: create group if present group_ids = [vc for vc in vc_ids if vc.startswith("group:")] for g in group_ids: _, gid = vc_type_id(g) print(f" Virtual.Add {g} (group)") try: rpc(ip, "Virtual.Add", { "type": "group", "id": gid, "config": {"name": "Modbus Device"} }) rpc(ip, "Group.Set", {"id": gid, "value": group_members}) except Exception as e: print(f" WARNING: {e}") # Step 3: upload script print(f"\nUploading {script} ...") subprocess.run(["python3", "tools/put_script.py", ip, script], check=True) print("Done. Stream log with:") print(f" curl -s -N http://{ip}/debug/log") if __name__ == "__main__": main() ``` -------------------------------- ### Get Last Received IR Code Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/ys_irtm/README.md Retrieves the most recently received IR code. Useful for debugging or immediate re-use. ```javascript YSIRTM.getLastCode() ``` -------------------------------- ### Generate SHELLY_MJS.md from Manifest Source: https://github.com/allterco/shelly-script-examples/blob/main/tools/README.md Generates the SHELLY_MJS.md file from a provided examples-manifest.json file. The output file is created next to the manifest. ```python python tools/sync-manifest-json.py ./examples-manifest.json ``` -------------------------------- ### Set Roomba Mode to Passive Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Puts the Roomba into Passive mode, allowing basic control. This is a fundamental mode for starting interactions. ```javascript ROOMBA.start() ``` -------------------------------- ### Sync Manifest JSON with File Headers Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Use `sync-manifest-md.py` to extract metadata from script headers and update the `examples-manifest.json` file. This is crucial for keeping the script registry accurate. ```bash python tools/sync-manifest-md.py --extract-metadata ``` -------------------------------- ### Delete Local Feature Branches Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/git-commit-merge-cleanup.md Remove all local branches that start with 'feature/'. This is part of the cleanup process after a successful merge and push. ```bash for b in $(git branch --format='%(refname:short)' | rg '^feature/'); do git branch -D "$b"; done ``` -------------------------------- ### List existing VCs Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-vc-manage.md Retrieves a list of all existing Virtual Components on the device and filters for keys. ```APIDOC ## List existing VCs ### Description Retrieves a list of all existing Virtual Components on the device and filters for keys. ### Method GET ### Endpoint `/rpc/Shelly.GetComponents` ### Request Example ```bash export DEVICE= curl -s "http://${DEVICE}/rpc/Shelly.GetComponents" \ | python3 -m json.tool | grep '"key"' ``` ### Response Example ```json { "result": { "components": [ { "key": "number:200", "type": "number", "id": 200, "name": "Solar Irradiance", "unit": "W/m2", "min": 0, "max": 2000, "persisted": false }, { "key": "group:200", "type": "group", "id": 200, "name": "Davis Pyranometer" } ] } } ``` ``` -------------------------------- ### Manifest Entry Format Source: https://github.com/allterco/shelly-script-examples/blob/main/AGENTS.md Defines the structure for entries in the examples-manifest.json file, which registers production scripts. ```json { "fname": "script-name.shelly.js", "title": "Human-Readable Title", "description": "What the script does and its requirements", "doc": "subdirectory/README.md" // Optional: path to additional docs } ``` -------------------------------- ### Get Roomba Battery Status Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Reads the Roomba's battery status. A callback function is required to receive the battery information. ```javascript ROOMBA.getBattery(cb) ``` -------------------------------- ### Create a Script Slot Source: https://github.com/allterco/shelly-script-examples/blob/main/skills/shelly-script-deploy.md Use this command to create a new script slot on the device. Replace DEVICE with the device's IP address or hostname. ```bash curl -s -X POST http://DEVICE/rpc/Script.Create \ -H "Content-Type: application/json" -d '{"name":"my_script"}' ``` -------------------------------- ### Start Roomba Spot Cleaning Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Initiates a spot cleaning cycle, where the Roomba cleans a small, concentrated area. Useful for targeted cleaning. ```javascript ROOMBA.spot() ``` -------------------------------- ### Start Roomba Cleaning Cycle Source: https://github.com/allterco/shelly-script-examples/blob/main/the_pill/iRobotRoomba/README.md Initiates the standard cleaning cycle for the Roomba. Ensure the Roomba is in an appropriate mode (Safe or Full) before calling. ```javascript ROOMBA.clean() ```