/shelly2pm-cover-control.js Secret
Created
February 25, 2024 20:31
Open/close cover completely on a long switch press
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print("script start"); | |
// how long to press the switch to consider a "long press" | |
// and start the "open/close cover completely" action | |
const longPressThreshold = 1500; // miliseconds | |
// how much miliseconds the converControlTimer waits | |
// after each check - lower value means quicker reaction | |
// of the "open/close cover completely" action after the | |
// switch is being released | |
const coverControlTimerCheckThreshold = 100; // miliseconds | |
let switchId; | |
let delayTimer; | |
let coverControlTimer; | |
Shelly.addStatusHandler(function (e) { | |
print(JSON.stringify(e)); | |
// note down which switch was pressed (up or down) | |
if (e.name === "input") { | |
// if a different switch was pressed before, clear delay timer | |
if (switchId != null && e.id != switchId) { | |
print("Different switch was pressed, clearing timer"); | |
if (delayTimer != null) { | |
Timer.clear(delayTimer); | |
} | |
} | |
switchId = e.id; | |
print("Using switch with ID: ", switchId); | |
} | |
if (e.component === "cover:0") { | |
if (e.delta.state != null && e.delta.source != null) { | |
print("Cover state: ", e.delta.state); | |
print("Triggered source: ", e.delta.source); | |
if (e.delta.source == "switch") { | |
if (e.delta.state == "closing" || e.delta.state == "opening") { | |
delayTimer = Timer.set(longPressThreshold, false, function (user_data) { | |
print("2 seconds passed - checking if switch is still pressed"); | |
let switchStatus = Shelly.getComponentStatus("input:" + switchId); | |
print("switch: ", switchStatus); | |
if (switchStatus.state == true) { | |
print("Switch pressed more than 2 seconds"); | |
// Now create a Timer that checks the state of the Cover every few miliseconds | |
// The timer will still being executed when the switch is not being pressed | |
// anymore, so we can use that to re-trigger the Cover open/close event so | |
// that the cover opens/closes completely (rather than stopping at the time) | |
// when the switch is being released. | |
coverControlTimer = Timer.set(coverControlTimerCheckThreshold, true, MoveCoverWhenNeeded, null); | |
} | |
}, null); | |
} | |
} | |
} | |
} | |
}); | |
function MoveCoverWhenNeeded() { | |
componentStatus = Shelly.getComponentStatus("cover:0"); | |
if (componentStatus.state == "opening" || componentStatus.state == "closing") { | |
print("Cover still opening/closing, no need to send Open/Close signal"); | |
} else { | |
// now sending the Open/Close signal and clearing Timer (to stop its execution) | |
if (componentStatus.last_direction == "open") { | |
print("Cover not opening anymore, sending Open signal (and clearing Timer)"); | |
Shelly.call("Cover.Open", { "id": "0" }); | |
} else { | |
print("Cover not opening anymore, sending Close signal (and clearing Timer)"); | |
Shelly.call("Cover.Close", { "id": "0" }); | |
} | |
Timer.clear(coverControlTimer); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment