UNPKG

daikin-controller

Version:

Control Daikin Air Conditioner devices using nodejs

72 lines (62 loc) 2.86 kB
import { createSocket, Socket } from 'dgram'; // Change this to true to output debugging logs to the console const debug = false; export class DaikinDiscovery { private readonly listenAddress: string = '0.0.0.0'; private readonly listenPort: number = 30000; private readonly probePort: number = 30050; private readonly probeAddress: string = '255.255.255.255'; private readonly probeAttempts: number = 10; private readonly probeInterval: number = 500; private readonly probeData: Buffer = Buffer.from('DAIKIN_UDP/common/basic_info'); private probeTimeout: NodeJS.Timeout | null = null; private discoveredDevices: { [address: string]: string } = {}; private udpSocket: Socket; private readonly callback: (devices: { [p: string]: string }) => void; public constructor(waitForCount: number, callback: (devices: { [address: string]: string }) => void) { this.callback = callback; // TODO: Which parameterrs are really needed // TODO: Also initialize DaicinAC instances? this.udpSocket = createSocket({ type: 'udp4', reuseAddr: true }); this.udpSocket.on('error', (err) => { this.log(`ERROR udpSocket: ${err}`); }); this.udpSocket.bind(this.listenPort, this.listenAddress, () => { this.udpSocket.addMembership('224.0.0.1'); this.udpSocket.setBroadcast(true); }); this.udpSocket.on('message', (message, remote) => { this.log(`${remote.address}:${remote.port} - ${message}`); // this.discoveredDevices[remote.address] = message.toString(); this.discoveredDevices[remote.address] = remote.address; if (Object.keys(this.discoveredDevices).length >= waitForCount) { this.finalizeDiscovery(); } }); this.udpSocket.on('listening', () => { this.sendProbes(this.probeAttempts); }); } private sendProbes(attemptsLeft: number) { this.probeTimeout = null; if (attemptsLeft <= 0) { this.finalizeDiscovery(); return; } this.log(`Send UDP discovery package ${attemptsLeft}`); this.udpSocket.send(this.probeData, 0, this.probeData.length, this.probePort, this.probeAddress); this.probeTimeout = setTimeout(this.sendProbes.bind(this), this.probeInterval, --attemptsLeft); } private finalizeDiscovery() { if (this.probeTimeout !== null) { clearTimeout(this.probeTimeout); this.probeTimeout = null; } this.udpSocket.close(); this.log(`Discovery finished with ${Object.keys(this.discoveredDevices).length} devices found`); this.callback(this.discoveredDevices); } private log(message: string) { if (debug) console.log(message); } }