Da ich es gerade als angenehme Herausforderung empfand, hab ich ein Beispiel Script geschrieben.
Der Anwendungsfall ist nicht so trivial umzusetzen, wie er auf den ersten Blick scheint.
Einrichtung
Da ich ein Freund der Virtuellen Komponenten bin, habe ich mich direkt für diese entschieden. Diese müssen erst eingerichtet und Konfiguriert werden:
Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.
Zusätzlich habe ich noch eine Gruppe zur Ansicht auf dem Dashboard angelegt, so ist es möglich die Zeit für 'an' und 'aus' zu setzen.
Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.
Trigger
Das Script unterstützt sowohl 'button' als auch 'switch', wichtig ist nur, dass du input und switch im 'detatched' Modus betreibst. Denn das übernimmt das Script für dich.
Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.
Als zusätzlichen Trigger habe ich einen virtuellen Button vorgesehen. Diesen kannst du bequem in der Oberfläche zum Testen verwenden, oder auch von extern aufrufen:
http://192.168.xxx.xxx/rpc/Button.Trigger?id=200&event="single_push"
Script
Im Config Objekt müssen ggf. die IDs der Komponenten angepasst werden. Momentan unterstützt das Script Sekunden statt Millisekunden. Und es handelt sich immer um einen Mindestwert und niemals um einen exakten Zeitwert. Das kann die Shelly Firmware ohnehin nicht.
Für Interessierte:
Um nicht in Konflikt mit anderen Events zu geraten, habe ich mich für ein eigenes Event und einen Timer entschieden. Somit lässt sich das Script leicht auf verschiedene Trigger anpassen.
const CONFIG = {
switchId: 0,
inputComponent: 'input:0',
timerOnVHandle: Virtual.getHandle('number:200'),
timerOffVHandle: Virtual.getHandle('number:201'),
vButtonComponent: 'button:200', // optional
timerHandle: null
}
function resetLoop(config){
// break loop
Timer.clear(config.timerHandle);
config.timerHandle = null;
// set default: switch off
Shelly.call('Switch.Set', {id:config.switchId, on: false}, function(result, error_code, error_message, config){
if(error_code){
print(error_code, error_message);
}
}, config);
}
// callback for error handling only
function toggleSwitchCallback(result, error_code, error_message, config) {
if(error_code){
print(error_code, error_message);
resetLoop(config);
}
};
Shelly.addEventHandler(function(event_data, config){
if(event_data && event_data.info && event_data.component){
// Trigger for input type 'switch'
if(event_data.component === config.inputComponent && event_data.info.event === 'toggle') {
if(event_data.info.state === false){
// stop endless loop
resetLoop(config);
} else {
if(config.timerHandle === null){
// start endless loop
Shelly.emitEvent('SwitchToggleLoop', true);
}
}
}
// Trigger for input type 'button' with 'single_push' (or virtual component button)
if((event_data.component === config.inputComponent || event_data.component === config.vButtonComponent) && event_data.info.event === 'single_push') {
if(config.timerHandle){
// stop endless loop
resetLoop(config);
} else {
// start endless loop
Shelly.emitEvent('SwitchToggleLoop', true);
}
}
// Endless loop via own 'SwitchToggleLoop' event
if(event_data.info.event === 'SwitchToggleLoop'){
// toogle switch
Shelly.call('Switch.Set', {id:config.switchId, on: event_data.info.data}, toggleSwitchCallback, config);
var period = event_data.info.data ? config.timerOnVHandle.getValue() : config.timerOffVHandle.getValue();
//print('wait: ', period);
// keep endless timer loop running
// break: resetLoop(CONFIG);
config.timerHandle = Timer.set(period * 1000, false, function(setOn){
Shelly.emitEvent('SwitchToggleLoop', setOn);
}, !event_data.info.data)
}
}
}, CONFIG);
Alles anzeigen