Files
HomebridgeDomotica/platform.ts
T
2023-03-16 14:09:20 +01:00

220 lines
8.3 KiB
TypeScript

import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service, Characteristic } from 'homebridge'
import { PLATFORM_NAME, PLUGIN_NAME } from './settings'
import { accessory } from './accessory'
import { device } from './device'
import { klikAanKlikUitAccessory } from './klikAanKlikUitAccessory'
import { powerSocketAccessory } from './powerSocketAccessory'
import { powerSwitchAccessory } from './powerSwitchAccessory'
import { environmentSensorAccessory } from './environmentSensorAccessory'
import { doorWindowSensorAccessory } from './doorWindowSensorAccessory'
import { motionSensorAccessory } from './motionSensorAccessory'
import { cameraAccessory } from './cameraAccessory'
import { activityAccessory } from './activityAccessory'
import { httpServer } from './httpServer'
export class domoticaPlatform implements DynamicPlatformPlugin {
public readonly Service: typeof Service = this.api.hap.Service
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic
public readonly accessories: accessory[] = []
public readonly cachedAccessories: PlatformAccessory[] = []
public readonly presentAccessories: PlatformAccessory[] = []
private readonly discoveries: String[] = []
private readonly completedDiscoveries: String[] = []
private httpServer: httpServer = new httpServer(this, this.config)
constructor(
public readonly log: Logger,
public readonly config: PlatformConfig,
public readonly api: API
) {
this.api.on('didFinishLaunching', () => {
this.discoverDevices()
this.httpServer.start()
})
}
configureAccessory(accessory: PlatformAccessory) {
this.cachedAccessories.push(accessory)
}
discoverDevices() {
this.discoveryStarted('klikAanKlikUitAccessory')
klikAanKlikUitAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('klikAanKlikUitAccessory')
})
.catch((error) => {
this.log.debug('klikAanKlikUitAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('powerSocketAccessory')
powerSocketAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('powerSocketAccessory')
})
.catch((error) => {
this.log.debug('powerSocketAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('powerSwitchAccessory')
powerSwitchAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('powerSwitchAccessory')
})
.catch((error) => {
this.log.debug('powerSwitchAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('environmentSensorAccessory')
environmentSensorAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('environmentSensorAccessory')
})
.catch((error) => {
this.log.debug('environmentSensorAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('doorWindowSensorAccessory')
doorWindowSensorAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('doorWindowSensorAccessory')
})
.catch((error) => {
this.log.debug('doorWindowSensorAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('motionSensorAccessory')
motionSensorAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('motionSensorAccessory')
})
.catch((error) => {
this.log.debug('motionSensorAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('cameraAccessory')
cameraAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('cameraAccessory')
})
.catch((error) => {
this.log.debug('cameraAccessory.discoverDevices Error ->' + error)
})
this.discoveryStarted('activityAccessory')
activityAccessory.discoverDevices(this)
.then((devices) => {
this.processDiscoveredDevices(devices)
this.discoveryCompleted('activityAccessory')
})
.catch((error) => {
this.log.debug('activityAccessory.discoverDevices Error ->' + error)
})
}
processDiscoveredDevices(domoticaDevices: device[]) {
for (const device of domoticaDevices) {
const uuid = this.api.hap.uuid.generate(device.uniqueId)
const existingAccessory = this.cachedAccessories.find(accessory => accessory.UUID === uuid)
if (existingAccessory) {
this.log.info('| ' + existingAccessory.context.device.type + ': ' + existingAccessory.displayName)
this.presentAccessories.push(existingAccessory)
if (existingAccessory.displayName != device.deviceName) {
this.log.info('! ' + existingAccessory.displayName + ' => ' + device.deviceName)
existingAccessory.context.device = device
this.api.updatePlatformAccessories([existingAccessory])
}
if (existingAccessory.context.device.type == 'KlikAanKlikUit') {
this.accessories.push(new klikAanKlikUitAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'PowerSocket') {
this.accessories.push(new powerSocketAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'PowerSwitch') {
this.accessories.push(new powerSwitchAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'EnvironmentSensor') {
this.accessories.push(new environmentSensorAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'DoorWindowSensor') {
this.accessories.push(new doorWindowSensorAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'MotionSensor') {
this.accessories.push(new motionSensorAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'Camera') {
this.accessories.push(new cameraAccessory(this, existingAccessory))
} else if (existingAccessory.context.device.type == 'Activity') {
this.accessories.push(new activityAccessory(this, existingAccessory))
}
} else {
this.log.info('+ ' + device.type + ': ' + device.deviceName)
const accessory = new this.api.platformAccessory(device.deviceName, uuid)
accessory.context.device = device
if (accessory.context.device.type == 'KlikAanKlikUit') {
this.accessories.push(new klikAanKlikUitAccessory(this, accessory))
} else if (accessory.context.device.type == 'PowerSocket') {
this.accessories.push(new powerSocketAccessory(this, accessory))
} else if (accessory.context.device.type == 'PowerSwitch') {
this.accessories.push(new powerSwitchAccessory(this, accessory))
} else if (accessory.context.device.type == 'EnvironmentSensor') {
this.accessories.push(new environmentSensorAccessory(this, accessory))
} else if (accessory.context.device.type == 'DoorWindowSensor') {
this.accessories.push(new doorWindowSensorAccessory(this, accessory))
} else if (accessory.context.device.type == 'MotionSensor') {
this.accessories.push(new motionSensorAccessory(this, accessory))
} else if (accessory.context.device.type == 'Camera') {
this.accessories.push(new cameraAccessory(this, accessory))
} else if (accessory.context.device.type == 'Activity') {
this.accessories.push(new activityAccessory(this, accessory))
}
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory])
}
}
}
discoveryStarted(deviceType) {
this.discoveries.push(deviceType)
}
discoveryCompleted(deviceType) {
this.completedDiscoveries.push(deviceType)
if (this.completedDiscoveries.length == this.discoveries.length) {
this.cleanupRemovedDevices()
}
//setInterval(this.updateAccessories.bind(this), 60 * 1000); // Poll every minute
}
updateAccessories() {
for (const accessory of this.accessories) {
accessory.update()
}
}
cleanupRemovedDevices() {
for (const existingAccessory of this.cachedAccessories) {
const presentAccessory = this.presentAccessories.find(accessory => accessory.UUID === existingAccessory.UUID)
if (!presentAccessory) {
this.log.info('- ' + existingAccessory.context.device.type + ': ' + existingAccessory.displayName)
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory])
}
}
}
}