UNPKG

homebridge-unifi-protect

Version:

Homebridge UniFi Protect plugin providing complete HomeKit integration for the entire UniFi Protect ecosystem with full support for most features including HomeKit Secure Video, multiple controllers, blazing fast performance, and much more.

98 lines 4.4 kB
import { FeatureOptions, FfmpegCodecs, RtpPortAllocator } from "homebridge-plugin-utils"; import { featureOptionCategories, featureOptions } from "./protect-options.js"; import { PROTECT_MQTT_TOPIC } from "./settings.js"; import { ProtectNvr } from "./protect-nvr.js"; import ffmpegPath from "ffmpeg-for-homebridge"; import util from "node:util"; export class ProtectPlatform { accessories; api; codecSupport; config; controllers; featureOptions; log; rtpPorts; verboseFfmpeg; constructor(log, config, api) { this.accessories = []; this.api = api; this.controllers = []; this.featureOptions = new FeatureOptions(featureOptionCategories, featureOptions, config?.options ?? []); this.log = log; this.rtpPorts = new RtpPortAllocator(); this.verboseFfmpeg = false; // We can't start without being configured. if (!config) { return; } // Plugin options into our config variables. this.config = { controllers: config.controllers, debugAll: config.debug === true, options: config.options, ringDelay: config.ringDelay ?? 0, verboseFfmpeg: config.verboseFfmpeg === true, videoProcessor: config.videoProcessor ?? ffmpegPath ?? "ffmpeg" }; // We need a UniFi Protect controller configured to do anything. if (!this.config.controllers) { this.log.info("No UniFi Protect controllers have been configured."); return; } // Debugging - most people shouldn't enable this. this.debug("Debug logging on. Expect a lot of data."); // Debug FFmpeg. if (this.config.verboseFfmpeg) { this.verboseFfmpeg = true; this.log.info("Verbose logging of video streaming sessions enabled. Expect a lot of data."); } // Loop through each configured NVR and instantiate it. for (const controllerConfig of this.config.controllers) { // We need an address, or there's nothing to do. if (!controllerConfig.address) { this.log.info("No host or IP address has been configured."); continue; } // We need login credentials or we're skipping this one. if (!controllerConfig.username || !controllerConfig.password) { this.log.info("No UniFi Protect login credentials have been configured."); continue; } // MQTT topic to use. if (!controllerConfig.mqttTopic) { controllerConfig.mqttTopic = PROTECT_MQTT_TOPIC; } this.controllers.push(new ProtectNvr(this, controllerConfig)); } // Probe our FFmpeg capabilities. this.codecSupport = new FfmpegCodecs({ ffmpegExec: this.config.videoProcessor, log: this.log, verbose: this.verboseFfmpeg }); // Avoid a prospective race condition by waiting to configure our controllers until Homebridge is done loading all the cached accessories it knows about, and calling // configureAccessory() on each. api.on("didFinishLaunching" /* APIEvent.DID_FINISH_LAUNCHING */, this.launchControllers.bind(this)); } // This gets called when homebridge restores cached accessories at startup. We intentionally avoid doing anything significant here, and save it for device discovery. configureAccessory(accessory) { // Add this to the accessory array so we can track it. this.accessories.push(accessory); } // Launch our configured controllers once all accessories have been loaded. Once we do, they will sustain themselves. async launchControllers() { // First things first - ensure we've got a working video processor before we do anything else. if (!(await this.codecSupport.probe())) { return; } // Iterate through all our controllers and startup. for (const controller of this.controllers) { // Login to the Protect controller. void controller.login(); } } // Utility for debug logging. debug(message, ...parameters) { if (this.config.debugAll) { this.log.warn(util.format(message, ...parameters)); } } } //# sourceMappingURL=protect-platform.js.map