homebridge-http-motion-sensor
Version:
Homebridge plugin for a remote motion sensor based on http
106 lines (105 loc) • 4.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpMotionSensorAccessory = void 0;
const http_1 = require("http");
const schemas_1 = require("./schemas");
class HttpMotionSensorAccessory {
constructor(log, config, api, hap) {
var _a, _b, _c;
this.log = log;
this.api = api;
this.motionDetected = false;
this.timeout = null;
const result = schemas_1.sensorConfigSchema.safeParse(config);
if (!result.success) {
this.log.error('Invalid sensor configuration:');
result.error.issues.forEach((issue) => {
this.log.error(`${issue.path.join('.')}: ${issue.message}`);
});
throw new Error('Sensor configuration validation failed');
}
this.config = result.data;
this.name = this.config.name;
this.bindIP = (_a = this.config.bind_ip) !== null && _a !== void 0 ? _a : '0.0.0.0';
this.informationService = new hap.Service.AccessoryInformation()
.setCharacteristic(hap.Characteristic.Manufacturer, 'Homebridge')
.setCharacteristic(hap.Characteristic.Model, (_b = this.config.model) !== null && _b !== void 0 ? _b : 'HTTP Motion Sensor')
.setCharacteristic(hap.Characteristic.SerialNumber, (_c = this.config.serial) !== null && _c !== void 0 ? _c : 'Default-Serial');
this.motionSensorService = new hap.Service.MotionSensor(this.config.name);
this.motionSensorService
.getCharacteristic(hap.Characteristic.MotionDetected)
.on("get" /* CharacteristicEventTypes.GET */, this.getState.bind(this));
this.setupHttpServer();
this.api.on('shutdown', this.shutdown.bind(this));
}
setupHttpServer() {
this.server = (0, http_1.createServer)((request, response) => {
this.httpHandler();
response.writeHead(200, { 'Content-Type': 'text/plain' });
response.end('Successfully requested: ' + request.url);
});
this.server.listen(this.config.port, this.bindIP, () => {
this.log.info(`HTTP Motion Sensor '${this.config.name}' is listening on http://${this.bindIP}:${this.config.port}`);
});
this.server.on('error', (error) => {
this.log.error(`HTTP Server error: ${error.message}`);
});
}
httpHandler() {
if (this.config.repeater && Array.isArray(this.config.repeater)) {
for (const repeater of this.config.repeater) {
const url = `http://${repeater.host}:${repeater.port}${repeater.path}`;
const options = {
host: repeater.host,
port: repeater.port,
path: repeater.path,
method: 'GET',
};
if (repeater.auth) {
options.headers = {
Authorization: repeater.auth,
};
}
(0, http_1.get)(url, () => {
this.log.debug(`Repeater request to ${url} successful`);
}).on('error', (error) => {
this.log.warn(`Repeater request to ${url} failed: ${error.message}`);
});
}
}
this.motionDetected = true;
this.motionSensorService
.getCharacteristic(this.api.hap.Characteristic.MotionDetected)
.updateValue(this.motionDetected);
this.log.debug('Motion detected via HTTP request');
if (this.timeout) {
clearTimeout(this.timeout);
}
this.timeout = setTimeout(() => {
this.motionDetected = false;
this.motionSensorService
.getCharacteristic(this.api.hap.Characteristic.MotionDetected)
.updateValue(this.motionDetected);
this.timeout = null;
this.log.debug('Motion detection reset');
}, 11 * 1000);
}
getState(callback) {
this.log.debug(`Motion sensor state requested: ${this.motionDetected}`);
callback(null, this.motionDetected);
}
shutdown() {
if (this.server) {
this.server.close();
this.log.info('HTTP server shutdown');
}
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
}
getServices() {
return [this.informationService, this.motionSensorService];
}
}
exports.HttpMotionSensorAccessory = HttpMotionSensorAccessory;