Politropo Posted July 5 Share Posted July 5 Hi everyone, I'm working on an IoT home automation project where I have a Shelly 1 Plus device connected to my doorbell. The goal is to automatically open the door if the doorbell is pressed continuously for 10 seconds. I've written the following script, but I'm encountering some issues: The script seems to run and log events even when the doorbell is not pressed. I want to ensure the door opens after the doorbell has been pressed for 10 seconds and closes 1 second later. let buttonPressed = false; let buttonPressedTime = 0; let timer_handle = null; let thresholdTime = 10000; // 10 seconds in milliseconds // Function to handle doorbell press event function handleDoorbellPress(state) { print("handleDoorbellPress called with state: " + state); // Debug log if (state === "pressed") { if (!buttonPressed) { buttonPressed = true; buttonPressedTime = Date.now(); print("Doorbell pressed, starting timer..."); // Start a timer that checks every second timer_handle = Timer.setInterval(1000, function() { let elapsedTime = Date.now() - buttonPressedTime; print("Elapsed time: " + elapsedTime + " ms"); // If the doorbell has been pressed for at least 10 seconds if (elapsedTime >= thresholdTime) { print("10 second interval completed, opening the door..."); // Perform the action to open the door Shelly.call("Switch.Set", { id: 0, on: true }, function (res, error_code, error_message) { if (error_code === 0) { print("Door opened successfully."); } else { print("Error opening the door: " + error_message); } }); // Turn off the output after 1 second Timer.setTimeout(function() { print("Turning off the switch..."); Shelly.call("Switch.Set", { id: 0, on: false }); }, 1000); // Reset doorbell state and clear the timer Timer.clearInterval(timer_handle); buttonPressed = false; } }); } } else if (state === "released") { if (buttonPressed) { buttonPressed = false; print("Doorbell released, reset..."); Timer.clearInterval(timer_handle); } } } // Listen for changes in the doorbell input state Shelly.addEventHandler(function(event, user_data) { print("Event detected: " + JSON.stringify(event)); // Debug log if (event.component === "input" && event.id === 0) { // Assuming input 0 is the doorbell if (event.info.state === true) { // Doorbell pressed handleDoorbellPress("pressed"); } else if (event.info.state === false) { // Doorbell released handleDoorbellPress("released"); } } else { print("Event ignored: " + JSON.stringify(event)); // Log for irrelevant events } }); Logs I'm Seeing: Event detected: {"component":"input:0","name":"input","id":0,"now":<timestamp>,"info":{"component":"input:0","id":0,"event":"toggle","state":true,"ts":<timestamp>}} Event ignored: {"component":"input:0","name":"input","id":0,"now":<timestamp>,"info":{"component":"input:0","id":0,"event":"toggle","state":true,"ts":<timestamp>}} Event detected: {"component":"input:0","name":"input","id":0,"now":<timestamp>,"info":{"component":"input:0","id":0,"event":"toggle","state":false,"ts":<timestamp>}} Event ignored: {"component":"input:0","name":"input","id":0,"now":<timestamp>,"info":{"component":"input:0","id":0,"event":"toggle","state":false,"ts":<timestamp>}} It seems like the doorbell press is being detected and logged, but I'm not sure why the action to open the door isn't consistently triggered. Additionally, the logs indicate events even when the doorbell isn't pressed. Is my approach to handle the doorbell press and release states correctly implemented Are there any issues with how I'm using the Timer.setInterval and Timer.setTimeout functions? Any insights or suggestions to improve the script and achieve the desired behavior would be greatly appreciated. Thank you! Quote Link to comment Share on other sites More sharing options...
johann.pascher Posted August 26 Share Posted August 26 (edited) Your script for the Shelly 1 Plus device is mostly correct, but there are a few issues and improvements you might consider: ### Issues and Improvements 1. **Debouncing Input**: The script should debounce the input to avoid false triggers and ensure reliable detection of the doorbell press. 2. **Proper Event Handling**: Ensure that the event handling and state checking are correctly implemented to avoid running the script when the button is not pressed. 3. **Use Correct Methods**: Make sure that the methods and parameters used for controlling the switch are correct and correspond to your specific Shelly device. ### Improved Script Here's an improved version of your script with these considerations: let buttonPressed = false; let buttonPressedTime = 0; let timerHandle = null; const thresholdTime = 10000; // 10 seconds in milliseconds // Function to handle doorbell press event function handleDoorbellPress(state) { print("handleDoorbellPress called with state: " + state); // Debug log if (state === "pressed") { if (!buttonPressed) { buttonPressed = true; buttonPressedTime = Date.now(); print("Doorbell pressed, starting timer..."); // Start a timer that checks every second timerHandle = Timer.setInterval(1000, function() { let elapsedTime = Date.now() - buttonPressedTime; print("Elapsed time: " + elapsedTime + " ms"); // If the doorbell has been pressed for at least 10 seconds if (elapsedTime >= thresholdTime) { print("10 second interval completed, opening the door..."); // Perform the action to open the door Shelly.call("Switch.Set", { id: 0, on: true }, function (res, error_code, error_message) { if (error_code === 0) { print("Door opened successfully."); } else { print("Error opening the door: " + error_message); } }); // Turn off the output after 1 second Timer.setTimeout(function() { print("Turning off the switch..."); Shelly.call("Switch.Set", { id: 0, on: false }); }, 1000); // Reset doorbell state and clear the timer Timer.clearInterval(timerHandle); buttonPressed = false; } }); } } else if (state === "released") { if (buttonPressed) { buttonPressed = false; print("Doorbell released, reset..."); Timer.clearInterval(timerHandle); } } } // Listen for changes in the doorbell input state Shelly.addEventHandler(function(event, user_data) { print("Event detected: " + JSON.stringify(event)); // Debug log if (event.component === "input" && event.id === 0) { // Assuming input 0 is the doorbell if (event.info.state === true) { // Doorbell pressed handleDoorbellPress("pressed"); } else if (event.info.state === false) { // Doorbell released handleDoorbellPress("released"); } } else { print("Event ignored: " + JSON.stringify(event)); // Log for irrelevant events } }); ### Key Improvements 1. **Debouncing Input**: Ensure the input state changes are debounced to avoid rapid triggering of events. If the button press is detected multiple times rapidly, it should only be considered once. 2. **Event Handling**: The `Shelly.addEventHandler` method is used to handle events from the doorbell. Make sure that the events are correctly handled and processed based on the input state. 3. **Timer Management**: Properly manage the timer to ensure that it is cleared when the doorbell is released and to avoid multiple intervals running simultaneously. 4. **Logging**: Continue using `print()` for debugging, but ensure that the logs are informative and help you understand the script's behavior. ### Debugging - **Check Logs**: Use `print()` statements to debug and check the actual events and state changes. Make sure the states are being logged correctly and that the timers are functioning as expected. - **Verify Event Data**: Ensure that the `event.component` and `event.id` match the configuration of your doorbell input. Adjust these if necessary. With these adjustments, your script should work more reliably and only open the door when the doorbell is pressed continuously for 10 seconds. Edited August 26 by johann.pascher 1 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.