UNPKG

homebridge-hikvision-local

Version:

Homebridge plugin that connects to your HikVision DVR via a local connection and exposes your cameras in Homebridge. The plugin is heavily based on excellent [homebridge-camera-ffmpeg](https://github.com/Sunoo/homebridge-camera-ffmpeg) and the various hom

133 lines 8.45 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HikVisionNVR = void 0; const HikVisionCamera_1 = require("./HikVisionCamera"); const HikvisionApi_1 = require("./HikvisionApi"); const logger_1 = require("./lib/logger"); const _1 = require("."); class HikVisionNVR { constructor(log, config, api) { this.log = new logger_1.Log(log, config.debug); this.homebridgeApi = api; this.hikVisionApi = new HikvisionApi_1.HikvisionApi(config, this.log); this.config = config; this.cameras = []; this.log.info('Initialising accessories for HikVision...'); this.homebridgeApi.on('didFinishLaunching', this.loadAccessories.bind(this)); setInterval(this.loadAccessories.bind(this), (this.config.refresh ? this.config.refresh * 60 * 60 * 1000 : 12 * 60 * 60 * 1000)); } loadAccessories() { return __awaiter(this, void 0, void 0, function* () { this.log.info(`Connecting to NVR system @ ${this.hikVisionApi._baseURL}`); const systemInformation = yield this.hikVisionApi.getSystemInfo(); if (this.hikVisionApi.connected) { this.log.info(`Connected to NVR system: @ ${this.hikVisionApi._baseURL} -> '${systemInformation.DeviceInfo.deviceName}' ${systemInformation.DeviceInfo.model}`); this.log.info('Loading cameras...'); const apiCameras = yield this.hikVisionApi.getCameras(); this.log.debug(`Found cameras: ${JSON.stringify(apiCameras, null, 2)}`); apiCameras.map((channel) => { var _a, _b, _c; if (!channel.capabilities.StreamingChannel) { this.log.error(`Failed to connect to NVR system, incomplete config @ ${this.hikVisionApi._baseURL}`); return; } const cameraConfig = { accessory: 'camera', name: (this.config.test ? 'Test ' : '') + channel.name, channelId: channel.id, hasAudio: channel.capabilities ? String(channel.capabilities.StreamingChannel.Audio.enabled._) == 'true' : false, doorbell: (((_a = this.config) === null || _a === void 0 ? void 0 : _a.doorbells) ? (_b = this.config) === null || _b === void 0 ? void 0 : _b.doorbells.includes(channel.name) : false), model: (_c = channel.sourceInputPortDescriptor) === null || _c === void 0 ? void 0 : _c.model, }; const cameraUUID = this.homebridgeApi.hap.uuid.generate((this.config.test ? 'Test ' : '') + _1.HIKVISION_PLUGIN_NAME + systemInformation.DeviceInfo.deviceID + cameraConfig.channelId); let accessoryType = 17 /* this.homebridgeApi.hap.Accessory.Categories.CAMERA */; if (cameraConfig.doorbell) { accessoryType = 18 /* this.homebridgeApi.hap.Accessory.Categories.VIDEO_DOORBELL */; } const accessory = new this.homebridgeApi.platformAccessory(cameraConfig.name, cameraUUID, accessoryType); accessory.context = cameraConfig; // Only add new cameras that are not cached if (!this.cameras.find((x) => x.UUID === accessory.UUID)) { this.configureAccessory(accessory); // abusing the configureAccessory here this.homebridgeApi.publishExternalAccessories(_1.HIKVISION_PLUGIN_NAME, [accessory]); } return accessory; }); this.log.info('Registering cameras with homebridge'); this.startMonitoring(); } else { this.log.error(`Failed to connect to NVR system @ ${this.hikVisionApi._baseURL}`); } // var camerasToRemove: any[] = []; // // Remove cameras that were not in previous call // this.cameras.forEach((camera: any) => { // if (!newAccessories.find((x: PlatformAccessory) => x.UUID === camera.UUID)) { // this.log(`Unregistering missing camera: ${camera.UUID}`) // camerasToRemove.push(camera.accessory); // } // }); // this.homebridgeApi.unregisterPlatformAccessories(HIKVISION_PLUGIN_NAME, HIKVISION_PLATFORM_NAME, camerasToRemove); }); } configureAccessory(accessory) { return __awaiter(this, void 0, void 0, function* () { accessory.context = Object.assign(accessory.context, this.config); const camera = new HikVisionCamera_1.HikVisionCamera(this.log, this.homebridgeApi, accessory, this.config); const cameraAccessoryInfo = camera.getService(this.homebridgeApi.hap.Service.AccessoryInformation); cameraAccessoryInfo.setCharacteristic(this.homebridgeApi.hap.Characteristic.Manufacturer, 'HikVision'); cameraAccessoryInfo.setCharacteristic(this.homebridgeApi.hap.Characteristic.Model, accessory.context.model); // cameraAccessoryInfo!.setCharacteristic(this.homebridgeApi.hap.Characteristic.SerialNumber, systemInformation.DeviceInfo.serialNumber); // cameraAccessoryInfo!.setCharacteristic(this.homebridgeApi.hap.Characteristic.FirmwareRevision, systemInformation.DeviceInfo.firmwareVersion); this.cameras.push(camera); }); } processHikVisionEvent(event) { switch (event.EventNotificationAlert.eventType) { case 'videoloss': this.log.debug('videoloss, nothing to do...'); break; case 'fielddetection': case 'linedetection': case 'shelteralarm': case 'VMD': const motionDetected = event.EventNotificationAlert.eventState === 'active'; const channelId = (event.EventNotificationAlert.channelID ? event.EventNotificationAlert.channelID : event.EventNotificationAlert.dynChannelID); const camera = this.cameras.find((data) => data.accessory.context.channelId === channelId); if (!camera) { return this.log.warn(`Could not find camera for event ${event}`); } this.log.info(`Motion detected on camera, triggering motion for ${camera.displayName}`); if (motionDetected !== camera.motionDetected) { camera.motionDetected = motionDetected; const motionService = camera.getService(this.homebridgeApi.hap.Service.MotionSensor); motionService === null || motionService === void 0 ? void 0 : motionService.setCharacteristic(this.homebridgeApi.hap.Characteristic.MotionDetected, motionDetected); setTimeout(() => { var _a; this.log.debug(`Disabling motion detection on camera ${camera.displayName}`); camera.motionDetected = !motionDetected; (_a = camera .getService(this.homebridgeApi.hap.Service.MotionSensor)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.homebridgeApi.hap.Characteristic.MotionDetected, !motionDetected); }, 10000); } default: this.log.debug(`event ${event}`); } } startMonitoring() { if (this.hikVisionApi.connected) { this.hikVisionApi.startMonitoringEvents(this.processHikVisionEvent.bind(this)); } } } exports.HikVisionNVR = HikVisionNVR; //# sourceMappingURL=HikVisionNVR.js.map