Dimitar Posted December 3, 2023 Share Posted December 3, 2023 This script show how to use components to control 3th party device. Also show how dynamically to change label and icon of the virtual components. let CONFIG = { token: "My token", // Replace with your actual token ip: "192.168.3.111:8443", // Replace with the IP of your TaHoma Hub hub: "io://1218-1660-0674/", // hubID encodedhub: "io%3A%2F%2F1218-1660-0674%2F" }; let devices = [ { url: "15077540", label: "Livingroom central", virtualComponentId: 200 }, { url: "11848943", label: "Livingroom left", virtualComponentId: 201 }, { url: "13858948", label: "Kitchen balcony", virtualComponentId: 202 }, { url: "11743604", label: "Lower room left", virtualComponentId: 203 }, { url: "14407349", label: "Lower room right", virtualComponentId: 204 }, { url: "7827441", label: "Bassement left", virtualComponentId: 205 }, { url: "13430515", label: "Bassement right", virtualComponentId: 206 } // Add more devices as needed ]; let checkInterval = 1000; // Adjust as needed for processing time let currentDeviceIndex = 0; let initializationDone = false; function getDevices(device, isInitialization) { if (isInitialization === undefined) { isInitialization = false; } let url = "https://" + CONFIG.ip + "/enduser-mobile-web/1/enduserAPI/setup/devices/" + CONFIG.encodedhub + device.url + "/states"; let payload = { method: "GET", ssl_ca: "*", headers: { "Authorization": "Bearer " + CONFIG.token }, url: url }; Shelly.call("HTTP.REQUEST", payload, function(res, err_code, err_msg) { if (err_code) { console.log("Error getting device state: ", err_msg); return; } try { let deviceData = JSON.parse(res.body); let openClosedState, closureState, nameState, movingState; for (let i = 0; i < deviceData.length; i++) { if (deviceData[i].name === "core:OpenClosedState") { openClosedState = deviceData[i].value; } else if (deviceData[i].name === "core:ClosureState") { closureState = deviceData[i].value; } else if (deviceData[i].name === "core:NameState") { nameState = deviceData[i].value; } else if (deviceData[i].name === "core:MovingState") { movingState = deviceData[i].value; } } console.log(device.virtualComponentId, " Device Name: ", nameState, " ", openClosedState, " ", closureState , " ", movingState ); if (movingState === false) { Shelly.call("number.set", { id: device.virtualComponentId, value: closureState }); // icon(closureState, device.virtualComponentId); } if (isInitialization) { device.lastScriptPosition = closureState; // Set initial script position Shelly.call("number.set", { id: device.virtualComponentId, value: closureState }); icon(closureState, device.virtualComponentId); } else { if (movingState === false && device.wasMoving) { // Shelly.call("number.setconfig", { id: device.virtualComponentId, config: { name: device.label } }); icon(closureState, device.virtualComponentId); device.wasMoving = false; device.lastScriptPosition = closureState; // Update last position set by the script } else if (movingState === true) { device.wasMoving = true; // Shelly.call("number.setconfig", { id: device.virtualComponentId, config: { name: device.label + " MOVING" } }); } device.wasMoving = true; // } } } catch (e) { console.log("Error parsing response: ", e.message); } }); } function sendSetPositionCommand(position, device) { let commandUrl = "https://" + CONFIG.ip + "/enduser-mobile-web/1/enduserAPI/exec/apply"; let payload = { method: "POST", ssl_ca: "*", headers: { "Authorization": "Bearer " + CONFIG.token, "Content-Type": "application/json" }, url: commandUrl, body: JSON.stringify({ actions: [{ deviceURL: CONFIG.hub + device.url, commands: [{ name: "setClosure", parameters: [position] }] }] }) }; Shelly.call("HTTP.REQUEST", payload, function(res, err_code, err_msg) { if (err_code) { console.log("Error sending set position command: ", err_msg); return; } console.log("Set position command sent successfully: ", res.body); device.lastScriptPosition = position; // Update the last position set by the script }); } function icon(state, device) { if (state == 100) { iconurl = "http://minhome.net:8080/close.png" } else if (state == 0) { iconurl = "http://minhome.net:8080/open.png" } else { iconurl = "http://minhome.net:8080/halfopen.png" } const currentConfig = Shelly.getComponentConfig("number:" + device); currentConfig.ui.icon = iconurl; Shelly.call("Number.setconfig",{ id: device, config: currentConfig}); } function processNextDevice() { if (currentDeviceIndex >= devices.length) { currentDeviceIndex = 0; // Reset index for regular monitoring if (!initializationDone) { // Initialization completed, now start regular checks initializationDone = true; Timer.set(checkInterval, true, processNextDevice); // Set regular interval } return; // Exit function to avoid further execution in this cycle } let device = devices[currentDeviceIndex++]; getDevices(device, !initializationDone); // Pass true for initialization on first run if (!initializationDone) { // Use a shorter delay during initialization Timer.set(1000, false, processNextDevice); } } function initializeDevices() { currentDeviceIndex = 0; initializationDone = false; processNextDevice(); // Start the initialization process } Shelly.addStatusHandler(function(event) { if (event.component.indexOf("number:") === 0) { const componentId = parseInt(event.component.split(":")[1]); // Manually searching for the device in the array let device = null; for (let i = 0; i < devices.length; i++) { if (devices[i].virtualComponentId === componentId) { device = devices[i]; break; } } if (device) { const newPosition = event.delta.value; sendSetPositionCommand(newPosition, device); } } }); // Remove any additional Timer.set calls that are outside of your functions initializeDevices(); // Only call this once to start the process Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.