diff --git a/packages/homebridge-plugin/homebridge-ui/public/index.html b/packages/homebridge-plugin/homebridge-ui/public/index.html
index 71be028..c0a5207 100644
--- a/packages/homebridge-plugin/homebridge-ui/public/index.html
+++ b/packages/homebridge-plugin/homebridge-ui/public/index.html
@@ -398,6 +398,13 @@
+
+
+
+
diff --git a/packages/homebridge-plugin/homebridge-ui/public/index.js b/packages/homebridge-plugin/homebridge-ui/public/index.js
index 9fa8517..42c1407 100644
--- a/packages/homebridge-plugin/homebridge-ui/public/index.js
+++ b/packages/homebridge-plugin/homebridge-ui/public/index.js
@@ -195,8 +195,9 @@ function dwmRuleSummary(r) {
return `⚡ If ${src} → ${when}, then ${action} (${targets})`;
}
if (r.type === 'Countdown') {
- const mins = r.countdownTime ? Math.round(r.countdownTime / 60) : null;
- return mins ? `⏱ ${mins} min auto-off` : '—';
+ const mins = r.countdownTime ? Math.round(r.countdownTime / 60) : null;
+ const action = r.countdownAction === 0 ? 'OFF → auto-ON' : 'ON → auto-OFF';
+ return mins ? `⏱ ${mins} min · ${action}` : '—';
}
const days = dayLabel(r.days);
const devs = (r.targetDevices ?? []).map((td) => esc(td.name ?? td.host)).join(', ') || 'no targets';
@@ -442,6 +443,7 @@ function openDwmEdit(id) {
document.getElementById('dwm-end-action').value = String(r.endAction ?? -1);
document.getElementById('dwm-countdown-mins').value =
r.countdownTime ? String(Math.round(r.countdownTime / 60)) : '';
+ document.getElementById('dwm-countdown-action').value = String(r.countdownAction ?? 1);
_selectedDwmDays = new Set((r.days ?? []).map(Number));
@@ -474,8 +476,9 @@ function openDwmEdit(id) {
document.getElementById('dwm-end-time').value = '';
document.getElementById('dwm-start-action').value = '1';
document.getElementById('dwm-end-action').value = '-1';
- document.getElementById('dwm-countdown-mins').value = '';
- document.getElementById('dwm-trigger-src').value = '';
+ document.getElementById('dwm-countdown-mins').value = '';
+ document.getElementById('dwm-countdown-action').value = '1';
+ document.getElementById('dwm-trigger-src').value = '';
document.getElementById('dwm-trigger-event').value = 'any';
document.getElementById('dwm-trigger-action').value = 'on';
Array.from(document.getElementById('dwm-target-devices').options).forEach((opt) => { opt.selected = false; });
@@ -604,7 +607,8 @@ document.getElementById('dwm-form-save-btn').addEventListener('click', async ()
if (type === 'Countdown') {
const mins = Number(document.getElementById('dwm-countdown-mins').value);
if (!mins || mins < 1) { showModalError('Enter countdown duration in minutes'); return; }
- rule.countdownTime = mins * 60;
+ rule.countdownTime = mins * 60;
+ rule.countdownAction = Number(document.getElementById('dwm-countdown-action').value);
} else {
const startType = document.getElementById('dwm-start-type').value;
const startOffset = parseInt(document.getElementById('dwm-start-offset').value ?? '0', 10) || 0;
diff --git a/packages/homebridge-plugin/lib/scheduler.js b/packages/homebridge-plugin/lib/scheduler.js
index 9148a84..29bafac 100644
--- a/packages/homebridge-plugin/lib/scheduler.js
+++ b/packages/homebridge-plugin/lib/scheduler.js
@@ -186,9 +186,11 @@ class DwmScheduler {
// Away Mode
if (rule.type === 'Away') {
- const startSecs = resolveSecs(Number(rule.startTime ?? -1), rule.startType, rule.startOffset, todaySun);
- const endSecs = resolveSecs(Number(rule.endTime ?? -1), rule.endType, rule.endOffset, todaySun);
+ const startSecs = resolveSecs(Number(rule.startTime ?? -1), rule.startType, rule.startOffset, todaySun);
+ const endSecs = resolveSecs(Number(rule.endTime ?? -1), rule.endType, rule.endOffset, todaySun);
if (startSecs === null) continue;
+ const awayStartAction = Number(rule.startAction ?? 1);
+ const awayEndAction = Number(rule.endAction ?? 0);
for (const dayId of (rule.days ?? [])) {
const td0 = rule.targetDevices?.[0];
@@ -196,14 +198,14 @@ class DwmScheduler {
ruleId: rule.id, ruleName: rule.name,
targetHost: td0?.host ?? '', targetPort: td0?.port ?? 0,
dayId: Number(dayId), targetSecs: startSecs,
- action: 1, isAwayStart: true,
+ action: awayStartAction, isAwayStart: true,
});
if (endSecs !== null && endSecs >= 0) {
schedule.push({
ruleId: rule.id + '-away-end', ruleName: rule.name,
targetHost: td0?.host ?? '', targetPort: td0?.port ?? 0,
dayId: Number(dayId), targetSecs: endSecs,
- action: 0, isAwayEnd: true, awayRuleId: rule.id,
+ action: awayEndAction, isAwayEnd: true, awayRuleId: rule.id,
});
}
}
@@ -212,22 +214,24 @@ class DwmScheduler {
// Countdown with active window
if (rule.type === 'Countdown') {
- const windowStart = Number(rule.windowStart ?? -1);
- const windowEnd = Number(rule.windowEnd ?? -1);
+ const windowStart = Number(rule.windowStart ?? -1);
+ const windowEnd = Number(rule.windowEnd ?? -1);
if (windowStart < 0 || !(rule.windowDays?.length)) continue;
+ const countdownAction = Number(rule.countdownAction ?? 1);
+ const countdownEnd = countdownAction === 1 ? 0 : 1; // opposite of start
const crossesMidnight = windowEnd >= 0 && windowEnd < windowStart;
for (const dayId of rule.windowDays) {
for (const td of (rule.targetDevices ?? [])) {
if (!td.host || !td.port) continue;
schedule.push({ ruleId: rule.id, ruleName: rule.name,
targetHost: td.host, targetPort: td.port,
- dayId: Number(dayId), targetSecs: windowStart, action: 1 });
+ dayId: Number(dayId), targetSecs: windowStart, action: countdownAction });
if (windowEnd >= 0) {
const offDayId = crossesMidnight ? (Number(dayId) % 7) + 1 : Number(dayId);
schedule.push({ ruleId: rule.id + '-wend', ruleName: rule.name,
targetHost: td.host, targetPort: td.port,
- dayId: offDayId, targetSecs: windowEnd, action: 0 });
+ dayId: offDayId, targetSecs: windowEnd, action: countdownEnd });
}
}
}
@@ -344,12 +348,14 @@ class DwmScheduler {
if (loop.timer) clearTimeout(loop.timer);
this._awayLoops.delete(ruleId);
if (forceOff) {
+ const endAction = Number(loop.rule.endAction ?? 0);
+ const turnOn = endAction === 1;
for (const td of loop.devices) {
- this._wemo.setBinaryState(td.host, td.port, false).catch(() => {});
+ this._wemo.setBinaryState(td.host, td.port, turnOn).catch(() => {});
}
this._emit({ success: true,
- msg: `"${loop.rule.name}" Away Mode window ended — all devices OFF`,
- entry: { action: 0 } });
+ msg: `"${loop.rule.name}" Away Mode window ended — all devices ${turnOn ? 'ON' : 'OFF'}`,
+ entry: { action: endAction } });
}
}