Skip to content

Commit

Permalink
working scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Jul 16, 2024
1 parent 5d1e266 commit 1df5cfe
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 60 deletions.
37 changes: 17 additions & 20 deletions plugins/core/src/automation-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,38 @@ import { StorageSettingsDict } from "@scrypted/sdk/storage-settings";

interface InvokeStorage<T extends string> {
settings: StorageSettingsDict<T>;
invoke(storageSettings: StorageSettingsDict<T>): Promise<void>;
invoke(device: ScryptedDevice, storageSettings: { [key in T]: any }): Promise<void>;
}

export const automationActions = new Map<ScryptedInterface, InvokeStorage<any>>();

function addAction<T extends string>(
iface: ScryptedInterface,
settings: StorageSettingsDict<T>,
invoke: (device: ScryptedDevice, storageSettings: StorageSettingsDict<T>) => Promise<void>) {
invoke: (device: ScryptedDevice, storageSettings: { [key in T]: any }) => Promise<void>) {
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) {
Expand Down
102 changes: 67 additions & 35 deletions plugins/core/src/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}
}
Expand All @@ -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({
Expand Down
9 changes: 4 additions & 5 deletions plugins/core/src/builtins/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 1df5cfe

Please sign in to comment.