UNPKG

homebridge-sensor-cmd-polling

Version:

Fork of apexad/homebridge-sensor-cmd with automatic polling support (configurable interval) – original minimal contact sensor via shell command

96 lines 3.6 kB
"use strict"; const child_process_1 = require("child_process"); let hap; class SensorCmd { constructor(log, config) { this.log = log; this.config = config; // Determine which sensor type to create switch (this.config.type) { case "motion": this.sensorService = new hap.Service.MotionSensor(this.config.name); break; case "occupancy": this.sensorService = new hap.Service.OccupancySensor(this.config.name); break; case "contact": default: this.sensorService = new hap.Service.ContactSensor(this.config.name); } // Register the on-demand GET handler const characteristic = this.getRelevantCharacteristic(); characteristic.on("get" /* GET */, (callback) => { this.runCommand((err, value) => callback(null, err ? 0 : value)); }); // Accessory info this.infoService = new hap.Service.AccessoryInformation() .setCharacteristic(hap.Characteristic.Manufacturer, 'apexad') .setCharacteristic(hap.Characteristic.Model, 'sensor-cmd'); // Polling interval (default 60s) this.pollingInterval = this.config.pollingInterval ? this.config.pollingInterval : 60; if (this.pollingInterval > 0) { this.log(`Starting automatic polling every ${this.pollingInterval}s`); this.startPolling(); } } /** Get the correct characteristic based on sensor type */ getRelevantCharacteristic() { switch (this.config.type) { case "motion": return this.sensorService.getCharacteristic(hap.Characteristic.MotionDetected); case "occupancy": return this.sensorService.getCharacteristic(hap.Characteristic.OccupancyDetected); case "contact": default: return this.sensorService.getCharacteristic(hap.Characteristic.ContactSensorState); } } /** Run the configured command and return parsed result */ runCommand(callback) { child_process_1.exec(this.config.command, (err, stdout) => { if (err) { this.log(`Command failed: ${err.message}`); callback(true, 0); return; } let parsed = parseInt(stdout.trim(), 10); if (isNaN(parsed)) parsed = 0; callback(false, parsed); }); } /** Start polling periodically */ startPolling() { const characteristic = this.getRelevantCharacteristic(); const poll = () => { this.runCommand((err, value) => { if (!err) { this.log(`Polled value: ${value}`); characteristic.updateValue(value); } else { this.log(`Polling error, keeping previous value`); } }); }; // Initial poll poll(); // Set recurring interval this.pollingTimer = setInterval(poll, this.pollingInterval * 1000); } /** Clean up when accessory is unloaded */ shutdown() { if (this.pollingTimer) { clearInterval(this.pollingTimer); this.pollingTimer = undefined; } } getServices() { return [this.infoService, this.sensorService]; } } module.exports = (api) => { hap = api.hap; api.registerAccessory('SensorCmd', SensorCmd); }; //# sourceMappingURL=accessory.js.map