Forráskód Böngészése

Add CameraAccessory

JDierkse 3 éve
szülő
commit
16cf72954f
2 módosított fájl, 132 hozzáadás és 4 törlés
  1. 113 0
      cameraAccessory.ts
  2. 19 4
      platform.ts

+ 113 - 0
cameraAccessory.ts

@@ -0,0 +1,113 @@
+import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge'
+
+import { accessory } from './accessory'
+import { device } from './device'
+import { httpRequest, response } from './httpPromise'
+import { domoticaPlatform } from './platform'
+
+export class cameraAccessory extends accessory {
+	private service: Service
+
+	private state = {
+		Motion: false
+	}
+
+	static async discoverDevices(platform: domoticaPlatform): Promise<device[]> {
+		return new Promise((resolve, reject) => {
+			let cameraDevices: device[] = []
+
+			httpRequest("http://" + platform.config.hostname + ':' + platform.config.port + '/API/inventory/camera')
+				.then((response) => {
+					let devices = JSON.parse(response.body)
+
+					for (const device of devices) {
+						if (device.enabled == "true" &&
+							device.brand == "RTSP" &&
+							device.motiondetect == "true") {
+							let object: device = {
+								type: "Camera",
+								typeId: device.id,
+								uniqueId: "Camera." + device.id,
+								deviceName: device.name,
+								switchable: "false",
+								dimmable: "false",
+								detailedType: device.brand
+							}
+							cameraDevices.push(object)
+						}
+					}
+
+					resolve(cameraDevices)
+				})
+				.catch((error) => {
+					reject('cameraAccessory::discoverDevices Error ->' + error)
+				})
+		})
+	}
+
+	constructor(
+		private readonly platform: domoticaPlatform,
+		private readonly accessory: PlatformAccessory,
+	) {
+		super("Camera", accessory.context.device.typeId)
+		this.accessory.getService(this.platform.Service.AccessoryInformation)!
+			.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Camera')
+			.setCharacteristic(this.platform.Characteristic.Model, 'ONVIF')
+			.setCharacteristic(this.platform.Characteristic.SerialNumber, '07000' + accessory.context.device.typeId)
+
+		this.service = this.accessory.getService(this.platform.Service.MotionSensor) || this.accessory.addService(this.platform.Service.MotionSensor)
+
+		this.service.getCharacteristic(this.platform.Characteristic.MotionDetected)
+			.onGet(this.getState.bind(this));
+
+		this.setName(accessory.context.device.deviceName)
+		this.update()
+	}
+
+	setName(name) {
+		this.service.setCharacteristic(this.platform.Characteristic.Name, name)
+	}
+
+	setValue(key, value) {
+		if (key == "state" && value != "") {
+			if (value == "On") {
+				this.state.Motion = true
+			} else {
+				this.state.Motion = false
+			}
+			this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.state.Motion)
+		}
+	}
+
+	update() {
+		const data = JSON.stringify([{
+			type: 'camera',
+			query: 'state'
+		}])
+
+		httpRequest("http://" + this.platform.config.hostname + ':' + this.platform.config.port + '/API/Status', data)
+			.then((response) => {
+				const devices = JSON.parse(response.body)
+
+				for (const device of devices.camera) {
+					if (device.id == this.accessory.context.device.typeId) {
+						if (device.motionstate == 'absent') {
+							this.state.Motion = false
+						} else { // present
+							this.state.Motion = true
+						}
+						return this.state.Motion
+						this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.state.Motion)
+						break
+					}
+				}
+			})
+			.catch((error) => {
+				this.platform.log.debug('cameraAccessory::update Error ->' + error)
+			})
+	}
+
+	getState(): CharacteristicValue {
+		return this.state.Motion
+	}
+}

+ 19 - 4
platform.ts

@@ -10,6 +10,7 @@ import { powerSwitchAccessory } from './powerSwitchAccessory'
 import { environmentSensorAccessory } from './environmentSensorAccessory'
 import { doorWindowSensorAccessory } from './doorWindowSensorAccessory'
 import { motionSensorAccessory } from './motionSensorAccessory'
+import { cameraAccessory } from './cameraAccessory'
 import { httpServer } from './httpServer'
 
 export class domoticaPlatform implements DynamicPlatformPlugin {
@@ -19,7 +20,7 @@ export class domoticaPlatform implements DynamicPlatformPlugin {
 	public readonly accessories: accessory[] = []
 	public readonly cachedAccessories: PlatformAccessory[] = []
 	public readonly presentAccessories: PlatformAccessory[] = []
-	
+
 	private readonly discoveries: String[] = []
 	private readonly completedDiscoveries: String[] = []
 
@@ -100,6 +101,16 @@ export class domoticaPlatform implements DynamicPlatformPlugin {
 			.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)
+			})
 	}
 
 	processDiscoveredDevices(domoticaDevices: device[]) {
@@ -130,6 +141,8 @@ export class domoticaPlatform implements DynamicPlatformPlugin {
 					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 {
 				this.log.info('+ ' + device.type + ': ' + device.deviceName)
@@ -149,6 +162,8 @@ export class domoticaPlatform implements DynamicPlatformPlugin {
 					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))
 				}
 
 				this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory])
@@ -162,14 +177,14 @@ export class domoticaPlatform implements DynamicPlatformPlugin {
 
 	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()