From 1df5cfefd07b9e40136e2f0af81eb7a49ea8d46b Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Mon, 15 Jul 2024 20:57:09 -0700 Subject: [PATCH] working scheduler --- plugins/core/src/automation-actions.ts | 37 +++++---- plugins/core/src/automation.ts | 102 ++++++++++++++++--------- plugins/core/src/builtins/scheduler.ts | 9 +-- 3 files changed, 88 insertions(+), 60 deletions(-) diff --git a/plugins/core/src/automation-actions.ts b/plugins/core/src/automation-actions.ts index 03e0c68d99..bc22656ed2 100644 --- a/plugins/core/src/automation-actions.ts +++ b/plugins/core/src/automation-actions.ts @@ -3,7 +3,7 @@ import { StorageSettingsDict } from "@scrypted/sdk/storage-settings"; interface InvokeStorage { settings: StorageSettingsDict; - invoke(storageSettings: StorageSettingsDict): Promise; + invoke(device: ScryptedDevice, storageSettings: { [key in T]: any }): Promise; } export const automationActions = new Map>(); @@ -11,33 +11,30 @@ export const automationActions = new Map>( function addAction( iface: ScryptedInterface, settings: StorageSettingsDict, - invoke: (device: ScryptedDevice, storageSettings: StorageSettingsDict) => Promise) { + invoke: (device: ScryptedDevice, storageSettings: { [key in T]: any }) => Promise) { automationActions.set(iface, { settings, - invoke: async (storageSettings) => { - const device = this as ScryptedDevice; - return invoke(device, storageSettings); - } + invoke }); } addAction(ScryptedInterface.OnOff, { - on: { - title: 'Turn On/Off', - type: 'boolean', - } - }, async function invoke(device: ScryptedDevice & OnOff, storageSettings) { - return storageSettings.on ? device.turnOn() : device.turnOff(); - }); + on: { + title: 'Turn On/Off', + type: 'boolean', + } +}, async function invoke(device: ScryptedDevice & OnOff, storageSettings) { + return storageSettings.on ? device.turnOn() : device.turnOff(); +}); addAction(ScryptedInterface.Brightness, { - brightness: { - title: 'Brightness', - type: 'number', - } - }, async function invoke(device: ScryptedDevice & Brightness, storageSettings) { - return device.setBrightness(storageSettings.brightness as number); - }); + brightness: { + title: 'Brightness', + type: 'number', + } +}, async function invoke(device: ScryptedDevice & Brightness, storageSettings) { + return device.setBrightness(storageSettings.brightness as number); +}); addAction(ScryptedInterface.Program, {}, async function invoke(device: ScryptedDevice & Program, storageSettings) { diff --git a/plugins/core/src/automation.ts b/plugins/core/src/automation.ts index 12af1e55cb..d3c449c252 100644 --- a/plugins/core/src/automation.ts +++ b/plugins/core/src/automation.ts @@ -217,33 +217,63 @@ export class Automation extends ScryptedDeviceBase implements OnOff, Settings { if (id === 'scheduler') { stepTriggers.push(createTriggerTypeStorageSettings(index, 'Scheduler')); - // stepTriggers.push(new StorageSettings(this, { - // [`trigger-day-${index}`]: { - // title: 'Day', - // type: 'day', - // mapGet() { - // return trigger.model.day; - // }, - // mapPut: (ov: any, value: any) => { - // trigger.model.day = value; - // this.storageSettings.values.data = this.data; - // }, - // } - // })); - - // stepTriggers.push(new StorageSettings(this, { - // [`trigger-time-${index}`]: { - // title: 'Time', - // type: 'time', - // mapGet() { - // return trigger.model.time; - // }, - // mapPut: (ov: any, value: any) => { - // trigger.model.time = value; - // this.storageSettings.values.data = this.data; - // }, - // } - // })); + stepTriggers.push(new StorageSettings(this, { + [`trigger-day-${index}`]: { + title: 'Day', + type: 'day', + multiple: true, + mapGet() { + + const days: number[] = []; + if (trigger?.model.sunday) + days.push(0); + if (trigger?.model.monday) + days.push(1); + if (trigger?.model.tuesday) + days.push(2); + if (trigger?.model.wednesday) + days.push(3); + if (trigger?.model.thursday) + days.push(4); + if (trigger?.model.friday) + days.push(5); + if (trigger?.model.saturday) + days.push(6); + + return days; + }, + mapPut: (ov: any, value: any) => { + trigger.model.sunday = value.includes(0); + trigger.model.monday = value.includes(1); + trigger.model.tuesday = value.includes(2); + trigger.model.wednesday = value.includes(3); + trigger.model.thursday = value.includes(4); + trigger.model.friday = value.includes(5); + trigger.model.saturday = value.includes(6); + + this.storageSettings.values.data = this.data; + }, + } + })); + + stepTriggers.push(new StorageSettings(this, { + [`trigger-time-${index}`]: { + title: 'Time', + type: 'time', + mapGet() { + const date = new Date(); + date.setHours(trigger.model.hour); + date.setMinutes(trigger.model.minute); + return date.getTime(); + }, + mapPut: (ov: any, value: any) => { + const date = new Date(value); + trigger.model.hour = date.getHours(); + trigger.model.minute = date.getMinutes(); + this.storageSettings.values.data = this.data; + }, + } + })); } else { stepTriggers.push(createTriggerTypeStorageSettings(index, 'Device Event')); @@ -470,7 +500,7 @@ export class Automation extends ScryptedDeviceBase implements OnOff, Settings { } const parts = action.id.split('#'); - const id = parts[0]; + const [id, iface] = parts; if (id === 'scriptable') { const script = new AutomationJavascript(this, eventSource, eventDetails, eventData); @@ -490,10 +520,13 @@ export class Automation extends ScryptedDeviceBase implements OnOff, Settings { else { const device = systemManager.getDeviceById(id); if (!device) - throw new Error(`unknown action ${action.id}`); + throw new Error(`unknown device ${id}`); + + const runner = automationActions.get(iface as ScryptedInterface); + if (!runner) + throw new Error(`unknown action ${iface}`); - const { rpc } = action.model; - device[rpc.method](...rpc.parameters || []); + runner.invoke(device, action.model); } } } @@ -517,16 +550,15 @@ export class Automation extends ScryptedDeviceBase implements OnOff, Settings { listen = device; } else { - let device: any; + let scheduler: Scheduler; if (id === 'scheduler') { - device = new Scheduler(); + scheduler = new Scheduler(); } else { throw new Error(`unknown action ${trigger.id}`); } - const { rpc } = trigger.model; - listen = device[rpc.method](...rpc.parameters || []); + listen = scheduler.schedule(trigger.model); } register = listen.listen({ diff --git a/plugins/core/src/builtins/scheduler.ts b/plugins/core/src/builtins/scheduler.ts index f94f60ed6a..856379a4be 100644 --- a/plugins/core/src/builtins/scheduler.ts +++ b/plugins/core/src/builtins/scheduler.ts @@ -2,16 +2,15 @@ import { ScryptedDevice, EventListenerOptions, ScryptedDeviceBase } from "@scryp import { Listen } from "./listen"; export interface Schedule { - clockType: "AM" | "PM" | "24HourClock" | "BeforeSunrise" | "BeforeSunset" | "AfterSunrise" | "AfterSunset"; - friday: boolean; hour: number; minute: number; - monday: boolean - saturday: boolean sunday: boolean - thursday: boolean; + monday: boolean tuesday: boolean wednesday: boolean + thursday: boolean; + friday: boolean; + saturday: boolean } export class Scheduler {