homebridge-loxone-proxy
Version:
Homebridge Dynamic Platform Plugin which exposes a Loxone System to Homekit.
168 lines • 6.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("uuid");
const LxCommunicator = __importStar(require("lxcommunicator"));
const WebSocketConfig = LxCommunicator.WebSocketConfig;
class LoxoneHandler {
constructor(platform) {
this.socket = undefined;
this.loxdata = undefined;
this.log = platform.log;
this.host = platform.config.host;
this.port = platform.config.port;
this.tls = platform.config.TLS;
this.username = platform.config.username;
this.password = platform.config.password;
this.uuidCallbacks = {};
this.uuidCache = {};
this.startListener();
}
startListener() {
if (typeof this.socket === 'undefined') {
const uuid = (0, uuid_1.v4)();
const webSocketConfig = new WebSocketConfig(WebSocketConfig.protocol.WS, uuid, 'homebridge', WebSocketConfig.permission.APP, false);
const handleAnyEvent = (uuid, message) => {
if (Object.prototype.hasOwnProperty.call(this.uuidCallbacks, uuid)) {
if (typeof message === 'string') {
if (message.includes('->')) {
const parts = message.split('->');
if (parts.length === 2) {
message = parts[1].trim();
}
}
message = { uuid: uuid, value: message };
}
this.uuidCallbacks[uuid].forEach(callback => callback(message));
}
this.uuidCache[uuid] = message;
};
webSocketConfig.delegate = {
socketOnDataProgress: (socket, progress) => {
this.log.debug('data progress ' + progress);
},
socketOnTokenConfirmed: (socket, response) => {
this.log.debug('token confirmed');
},
socketOnTokenReceived: (socket, result) => {
this.log.debug('token received');
},
socketOnConnectionClosed: (socket, code) => {
this.log.info('Socket closed ' + code);
if (code !== LxCommunicator.SupportCode.WEBSOCKET_MANUAL_CLOSE) {
this.reconnect();
}
},
socketOnEventReceived: (socket, events, type) => {
for (const evt of events) {
switch (type) {
case LxCommunicator.BinaryEvent.Type.EVENT:
handleAnyEvent(evt.uuid, evt.value);
handleAnyEvent(evt.uuid, evt);
break;
case LxCommunicator.BinaryEvent.Type.EVENTTEXT:
handleAnyEvent(evt.uuid, evt.text);
break;
case LxCommunicator.BinaryEvent.Type.WEATHER:
handleAnyEvent(evt.uuid, evt);
break;
default:
break;
}
}
},
};
this.socket = new LxCommunicator.WebSocket(webSocketConfig);
this.connect()
.catch(error => {
this.log.error('Couldn\'t open socket: ' + error);
this.reconnect();
});
}
}
connect() {
this.log.info('Trying to connect to Miniserver');
const protocol = this.tls ? 'https://' : 'http://';
return this.socket.open(protocol + this.host + ':' + this.port, this.username, this.password)
.then(() => this.socket.send('data/LoxAPP3.json'))
.then((file) => {
this.loxdata = JSON.parse(file);
return this.socket.send('jdev/sps/enablebinstatusupdate');
})
.then(() => {
this.log.info('Connected to Miniserver');
return true;
})
.catch(error => {
this.log.error('Connection failed: ' + error);
this.socket.close();
return false;
});
}
reconnect() {
this.log.info('Reconnecting in 10 seconds...');
const delay = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
};
const runTimer = async () => {
await delay(10000);
const success = await this.connect();
if (!success) {
this.reconnect();
}
};
runTimer();
}
registerListenerForUUID(uuid, callback) {
if (Object.prototype.hasOwnProperty.call(this.uuidCallbacks, uuid)) {
this.uuidCallbacks[uuid].push(callback);
}
else {
this.uuidCallbacks[uuid] = [callback];
}
if (uuid in this.uuidCache) {
this.uuidCallbacks[uuid].forEach(callback => callback(this.uuidCache[uuid]));
}
}
sendCommand(uuid, action) {
this.socket.send(`jdev/sps/io/${uuid}/${action}`, 2);
}
getsecuredDetails(uuid) {
return new Promise((resolve, reject) => {
this.socket.send(`jdev/sps/io/${uuid}/securedDetails`)
.then((file) => {
resolve(file);
})
.catch((error) => {
reject(error);
});
});
}
getLastCachedValue(uuid) {
return this.uuidCache[uuid];
}
}
exports.default = LoxoneHandler;
//# sourceMappingURL=LoxoneHandler.js.map