Shelly Relais - Automatisch Aus wenn Gerät im Leerlauf

Wollt ihr Stromsparen mit Hilfe von Shelly Devices um automatisch ein Gerät im IDLE / Standby komplett auszuschalten, dann nutzt dieses shelly Script hier. Dies lässt sich gut anwenden, falls ihr zum Beispiel einen Fernseher im Standby Modus samt angeschlossener Peripherie, wie DVD Player, Soundbar, etc, komplett Stromlos machen möchtet. Oder aber nach einem Ladevorgang, zum Beispiel eines eBikes mittels Shelly Relais oder einem Shelly Plug S automatisch die Stromzufuhr kappen möchtet.
Shelly IDLE Timer Script
Dieses Script, welches ihr direkt auf einem Shelly Relais, bzw. einem Shelly Plug S installieren könnt, bietet die Möglichkeit den Ausgang (SWITCH_ID
), wenn eine Wattzahl X (POWER_THRESHOLD
) mindestens einer Zeit X lang (IDLE_TIMEOUT
) unterschritten wird, auszuschalten.
Hierfür müsst ihr nur die folgenden Parameter im Script konfigurieren:
// Power threshold, in watts
POWER_THRESHOLD: 3,
// Duration of low power before turning off, in minutes
IDLE_TIMEOUT: 5,
// Which of the device switches to monitor
SWITCH_ID: 0,
// When set to true, debug messages will be logged to the console if console is enabled
DEBUG_LOG: false,
// Enable periodic polling as fallback if no power_update is received
ENABLE_POLLING: false,
// Polling interval in seconds
POLL_INTERVAL: 60
Die Switch ID ist bei den 1 Ausgang Shelly Devices immer 0.... bei Devices mit mehren schaltbaren Ausgängen, bitte schauen, welche ID ihr schalten möchtet.
ENABLE_POLLING
ist dann wichtig wenn ihr Geräte ausschalten möchtet die einen sehr geringen Unterschied im AN und IDLE Zustand haben. Wie es aussieht wir das Event, das benötigt wird vom Shelly erst ab einem Differenz-Wert größer 1 Watt ausgelöst. Wenn ihr das Polling aktiviert, fragt das Skript aktiv die aktuellen Werte, die es benötigt alle POLL_INTERVALL
Sekunden ab.
Das script könnt ihr dann einfach entweder über das Shelly Webinterface, oder der Mobile App hochladen, installieren, Starten und dann noch den Autostart aktivieren:
- GitHub Link zum Script: https://github.com/alaub81/shelly/blob/main/shelly-idle-timer.js
shelly-idle-timer.js
/**
* Shelly Idle Timer Script
* ------------------------
* This script monitors the active power (`apower`) of a Shelly device and
* automatically turns off the configured switch if power consumption stays
* below a defined threshold for a specified duration.
*
* Functionality:
* - Starts a timer when the switch is ON and `apower < POWER_THRESHOLD`.
* - If the condition persists for more than `IDLE_TIMEOUT` minutes,
* the switch will be turned OFF.
* - Reacts to `power_update`, `toggle`, and `input` events.
*
* Extension: Polling Fallback
* ---------------------------
* Some Shelly devices (e.g. Plug S Gen2) only emit `power_update` events
* when power changes significantly. Small or slowly changing values
* may not trigger any event.
*
* To ensure reliable behavior in such cases, the script includes
* an optional polling mechanism that regularly fetches the current
* device state and applies the same idle logic.
*
* Configurable options:
* - `ENABLE_POLLING`: true / false (default: false)
* - `POLL_INTERVAL`: polling interval in seconds
*
* Recommendation:
* Enable `ENABLE_POLLING` if your device does not emit frequent
* `power_update` events, or if you want to catch subtle idle conditions.
*/
/******************* START CHANGE HERE *******************/
const CONFIG = {
// Power threshold, in watts
POWER_THRESHOLD: 3,
// Duration of low power before turning off, in minutes
IDLE_TIMEOUT: 5,
// Which of the device switches to monitor
SWITCH_ID: 0,
// When set to true, debug messages will be logged to the console if console is enabled
DEBUG_LOG: false,
// Enable periodic polling as fallback if no power_update is received
ENABLE_POLLING: false,
// Polling interval in seconds
POLL_INTERVAL: 60
};
/******************* STOP CHANGE HERE *******************/
let timerHandle = undefined;
// Logs the provided message with an optional prefix to the console
function logger(message, prefix) {
if (!CONFIG.DEBUG_LOG) return;
let finalText = '';
if (Array.isArray(message)) {
for (let i = 0; i < message.length; i++) {
finalText += ' ' + JSON.stringify(message[i]);
}
} else {
finalText = JSON.stringify(message);
}
if (typeof prefix !== 'string') prefix = '';
else prefix = prefix + ':';
console.log(prefix, finalText);
}
function startTimer() {
if (timerHandle !== undefined) {
logger('Timer was already started.', 'startTimer');
return;
}
timerHandle = Timer.set(CONFIG.IDLE_TIMEOUT * 60 * 1000, false, function () {
clearTimer();
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (result) {
if (result.output === true && result.apower < CONFIG.POWER_THRESHOLD) {
Shelly.call('Switch.set', { id: CONFIG.SWITCH_ID, on: false }, function () {
logger(
'Switched off due to active power of ' + result.apower + ' < ' + CONFIG.POWER_THRESHOLD + ' Watts.',
'startTimer'
);
logger('Switch turned OFF by idle timer.', 'action');
});
} else {
logger('No action taken. Power: ' + result.apower + ' W, Switch ON: ' + result.output, 'startTimer');
}
});
});
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (status) {
logger('Timer was started. Current power: ' + status.apower + ' W', 'startTimer');
});
}
function clearTimer() {
if (timerHandle === undefined) return;
Timer.clear(timerHandle);
timerHandle = undefined;
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (status) {
logger('Timer was reset. Current power: ' + status.apower + ' W', 'clearTimer');
});
}
Shelly.addEventHandler(function (event) {
logger(event, 'raw-event');
if (!event || !event.info || event.info.event === undefined) return;
if (event.info.event === 'power_update') {
logger('Power was updated.', 'Event');
if (event.info.apower < CONFIG.POWER_THRESHOLD) {
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (status) {
if (status.output === true) {
logger('Switch is ON. Power is low, current power: ' + status.apower + ' W – starting timer.', 'power_update');
startTimer();
} else {
logger('Power is low, but switch is OFF – not starting timer.', 'power_update');
clearTimer();
}
});
} else {
clearTimer();
}
return;
}
if (
event.name === 'switch' &&
event.id === CONFIG.SWITCH_ID &&
typeof event.info.state !== 'undefined' &&
(event.info.event === 'toggle' || event.name === 'input')
) {
logger('Switch state changed (toggle or input).', 'Event');
if (event.info.state === true) {
clearTimer();
} else if (event.info.state === false) {
clearTimer();
}
return;
}
});
// Check initial state once at startup
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (status) {
if (status.output === true && status.apower < CONFIG.POWER_THRESHOLD) {
logger('Initial state: switch is ON and power is low, current power: ' + status.apower + ' W – starting timer.', 'init');
startTimer();
} else {
logger('Initial state: no need to start timer.', 'init');
}
});
// Start polling fallback if enabled
if (CONFIG.ENABLE_POLLING) {
Timer.set(CONFIG.POLL_INTERVAL * 1000, true, function () {
Shelly.call('Switch.GetStatus', { id: CONFIG.SWITCH_ID }, function (status) {
if (status.output === true && status.apower < CONFIG.POWER_THRESHOLD) {
logger('Polling: Power is low, switch ON – starting timer.', 'polling');
startTimer();
} else {
logger('Polling: Power OK or switch OFF – no action.', 'polling');
clearTimer();
}
});
});
}