raxa-plugin-trigger
Version:
87 lines (79 loc) • 2.73 kB
text/typescript
import {Action, Call, Device, Plugin, defaultInterfaces} from 'raxa-common'
import plugin from './plugin'
export interface Trigger extends Device {
config: {
pluginId: string
triggerId: string
action: Action
}
}
export default class TriggerPlugin extends Plugin {
activeTriggers = new Set<string>()
activeLearners = new Map<
Trigger,
{timer: NodeJS.Timer; resolve: () => void; reject: () => void}
>()
start() {
this.listenOn(
defaultInterfaces.Trigger.id,
defaultInterfaces.Trigger.events.triggered.id,
({pluginId, triggerId}) => {
const uniqueId = `${pluginId}:/${triggerId}`
if (this.activeTriggers.has(uniqueId)) return
this.activeTriggers.add(uniqueId)
setTimeout(() => this.activeTriggers.delete(uniqueId), 500)
const device = Object.values(this.state.getState().devices)
.map((device) => device as Trigger)
.find(
(device) =>
device.pluginId === plugin.id &&
device.deviceClassId === plugin.deviceClasses.Trigger.id &&
device.config.pluginId === pluginId &&
device.config.triggerId === triggerId,
)
this.log.debug({pluginId, triggerId, device}, 'Trigger activated')
if (device) {
if (device.config.action.type === 'call') {
this.callDevice(device.config.action)
} else {
this.setDeviceStatus(device.config.action)
}
}
for (const [trigger, learner] of this.activeLearners.entries()) {
clearTimeout(learner.timer)
this.log.debug({pluginId, triggerId}, `Learned ${trigger.name} to`)
this.upsertDevice({
...trigger,
config: {...trigger.config, pluginId, triggerId},
})
learner.resolve()
}
this.activeLearners.clear()
},
)
}
onDeviceCalled(call: Call, device: Trigger) {
if (
call.interfaceId === defaultInterfaces.SelfLearning.id &&
call.method === defaultInterfaces.SelfLearning.methods.learn.id
) {
let oldLearner = this.activeLearners.get(device)
this.log.debug(`Learning ${device.name}`)
if (oldLearner !== undefined) {
this.log.debug(`Clearing old timer for ${device.name}`)
clearTimeout(oldLearner.timer)
oldLearner.reject()
}
return new Promise<void>((resolve, reject) => {
this.activeLearners.set(device, {
timer: setTimeout(() => {
this.log.debug(`Timed out learning ${device.name}`)
this.activeLearners.delete(device)
}, 10000),
resolve,
reject,
})
})
}
}
}