homebridge-homekit-proxy
Version:
Homebridge Homekit Proxy allows you to control HomeKit-enabled Devices directly from within HomeBridege. (Based on homebridge-homekit-controller by MartinPham)
157 lines • 5.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpWrapper = exports.Sequencer = void 0;
const hap_controller_1 = require("hap-controller");
const TIMEOUT = 5000;
const MAX_RETRY = 10;
class Sequencer {
constructor(log) {
this._queue = [];
this.timer = undefined;
this.log = log;
}
get length() {
return this._queue.length;
}
get busy() {
return this.timer !== undefined;
}
push(call, name, uuid) {
const self = this;
return new Promise((resolve, reject) => {
this._queue.push({
uuid: uuid,
name: name,
fkt: call,
timer: undefined,
resolve: resolve,
reject: reject,
finished: false,
retries: MAX_RETRY,
});
self.next();
});
}
next() {
const self = this;
this._queue = this._queue.filter((i) => i.finished === false);
if (self.timer === undefined && this._queue.length > 0) {
const qi = this._queue.shift();
self.timer = setTimeout(() => {
self.timer = setTimeout(() => {
self.timer = undefined;
qi.retries--;
if (qi.retries <= 0) {
this.log.debug(`Timeout for Task ${qi.name}/${qi.uuid} => GIVING UP`);
qi.reject(`Timeout for Task ${qi.name}/${qi.uuid}`);
}
else {
this.log.debug(`Timeout for Task ${qi.name}/${qi.uuid} => RETRY`);
this._queue.push(qi);
}
self.next();
}, 100);
}, TIMEOUT);
qi
.fkt()
.then((value) => {
if (self.timer) {
clearTimeout(self.timer);
}
self.timer = setTimeout(() => {
self.timer = undefined;
self._queue
.filter((i) => i.name === qi.name && i.uuid == qi.uuid && i.finished === false)
.forEach((i) => {
i.resolve(value);
i.finished = true;
});
qi.resolve(value);
self.next();
}, 100);
})
.catch((e) => {
if (self.timer) {
clearTimeout(self.timer);
}
self.timer = setTimeout(() => {
self.timer = undefined;
qi.reject(e);
self.next();
}, 100);
});
}
}
}
exports.Sequencer = Sequencer;
class HttpWrapper {
constructor(log, deviceId, address, port, pairingData) {
this.uct = 0;
this.listeners = [];
this.log = log;
this.list = new Sequencer(log);
this.client = new hap_controller_1.HttpClient(deviceId, address, port, pairingData);
this.client.on('event', this.onEvent.bind(this));
}
identify() {
const self = this;
return self.list.push(() => {
return self.client.identify();
}, 'identify', '-');
}
getAccessories() {
const self = this;
return self.list.push(() => {
return self.client.getAccessories();
}, 'getAccessories', '-');
}
getCharacteristics(characteristics, options) {
const self = this;
return self.list.push(() => {
if (characteristics.length === 0) {
return new Promise((resolve) => {
resolve({});
});
}
return self.client.getCharacteristics(characteristics, options);
}, 'getCharacteristics', characteristics.join(', '));
}
setCharacteristics(characteristics) {
const self = this;
return self.list.push(() => {
return self.client.setCharacteristics(characteristics);
}, 'setCharacteristics', Object.keys(characteristics)
.map((k) => `${k}=${characteristics[k]}`)
.join(', '));
}
subscribeCharacteristics(characteristics) {
const self = this;
return self.list.push(() => {
this.log.debug('Running Subscribe task', characteristics.join(', '));
return self.client.subscribeCharacteristics(characteristics);
}, 'subscribeCharacteristics', characteristics.join(', '));
}
onEvent(event) {
const self = this;
this.log.debug('Received Event', event);
event.characteristics.forEach((cc) => {
const cname = `${cc.aid}.${cc.iid}`;
self.listeners
.filter((l) => l.c.cname === cname)
.forEach((l) => {
var _a;
self.log.debug(`Notifiying listener for ${(_a = l.c.connect) === null || _a === void 0 ? void 0 : _a.displayName} (${cname})`);
l.listener(cc);
});
});
}
on(c, listener) {
this.listeners.push({
c: c,
listener: listener,
});
return this;
}
}
exports.HttpWrapper = HttpWrapper;
//# sourceMappingURL=HttpWrapper.js.map