homebridge-smarthomeng/src/SmartHomeNG.ts
2022-02-11 09:07:51 +01:00

118 lines
3.6 KiB
TypeScript

import WebSocket from 'ws';
import { SmartHomeNGPlatform } from './platform';
export class SmartHomeNG {
private ws: WebSocket;
private tomonitor = {};
public connected = false;
constructor(private readonly platform: SmartHomeNGPlatform, private url: string, private autoReconnectInterval = 10) {
this.platform.log.debug('SHNG constructor');
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.on('open', () => {
this.platform.log.info('Connected to SmartHomeNG on', this.url);
this.connected = true;
this.identifyMyself();
this.startMonitoring();
});
this.ws.on('message', (data: string) => {
this.receive(data);
});
this.ws.on('error', (error) => {
this.platform.log.error('WebSocket error: ' + error.toString());
});
this.ws.on('close', (code: number) => {
this.platform.log.warn('Lost connection (Code: ' + code + '). Reconnecting in', this.autoReconnectInterval, 'seconds.');
this.connected = false;
if (this.autoReconnectInterval > 0) {
this.reconnect();
}
});
}
reconnect() {
this.ws.removeAllListeners();
setTimeout(() => {
this.platform.log.info('WebSocketClient: reconnecting...');
this.connect();
}, this.autoReconnectInterval * 1000);
}
identifyMyself(): void {
const protocol = { 'cmd': 'proto', 'ver': 4 };
const identify = { 'cmd': 'identity', 'sw': 'homebridge-smarthomeng', 'ver': '2.0' };
this.send(protocol);
this.send(identify);
}
addMonitor(item: string, callback: (value: unknown) => void): void {
if (item !== null && item !== 'undefined') {
this.tomonitor[item] = callback;
}
}
startMonitoring(): void {
const itemlist: string[] = [];
for (const item in this.tomonitor) {
itemlist.push(item);
}
if (itemlist.length > 0) {
this.platform.log.info('Start monitoring ' + itemlist);
const buffer = {
'cmd': 'monitor',
'items': itemlist,
};
this.send(buffer);
} else {
this.platform.log.warn('No need to start monitoring because no items are defined !');
}
}
setItem(item: string, value: unknown): void {
this.platform.log.info('Sending value', value, 'for', item);
const command = { 'cmd': 'item', 'id': item, 'val': value };
this.send(command);
}
send(buffer: unknown): boolean {
const command = JSON.stringify(buffer);
if (this.connected) {
this.platform.log.debug('WS: sending:', command);
this.ws.send(command);
return true;
} else {
this.platform.log.warn('Error sending command !');
return false;
}
}
receive(data: string): void {
const msg = JSON.parse(data);
this.platform.log.debug('WS: received: %s', data);
if (msg.cmd === 'item' && msg.items) {
for (const item of msg.items) {
const name = item[0];
const value = item[1];
if (name in this.tomonitor) {
const callback = this.tomonitor[name];
this.platform.log.info('Received value', value, 'for', name, 'callback', callback);
callback(value);
} else {
this.platform.log.debug('Ignoring unmonitored item', name);
}
}
}
}
}