neramirez-broadlink-ts
Version:
A TypeScript-enhanced Node.JS fork of broadlinkjs, designed for interacting with RM devices in homebridge-broadlink-rm. Now includes a feature for handling multiple requests to the same device, with a specific focus on supporting homebridge-broadlink-wind
142 lines • 6.83 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Device = void 0;
const logger_1 = require("../logger");
const device_types_1 = require("../device.types");
const payload_handler_1 = require("../types/payload.handler");
const packet_handler_1 = require("../packet.handler");
const socket_handler_1 = require("../socket.handler");
class Device {
constructor(host, macAddress, deviceType, port) {
this.deviceReady = (message) => {
this.logger.debug(`(${this.macAddress.toString("hex")}) Device Ready: Message: ${message}`);
};
// Create a UDP socket to receive messages from the broadlink device.
this.authenticate = async () => {
const payload = Buffer.alloc(0x50, 0);
//This device id
payload[0x04] = 0x31;
payload[0x05] = 0x31;
payload[0x06] = 0x31;
payload[0x07] = 0x31;
payload[0x08] = 0x31;
payload[0x09] = 0x31;
payload[0x0a] = 0x31;
payload[0x0b] = 0x31;
payload[0x0c] = 0x31;
payload[0x0d] = 0x31;
payload[0x0e] = 0x31;
payload[0x0f] = 0x31;
payload[0x10] = 0x31;
payload[0x11] = 0x31;
payload[0x12] = 0x31;
payload[0x1e] = 0x01;
payload[0x2d] = 0x01;
payload[0x30] = "T".charCodeAt(0);
payload[0x31] = "e".charCodeAt(0);
payload[0x32] = "s".charCodeAt(0);
payload[0x33] = "t".charCodeAt(0);
payload[0x34] = " ".charCodeAt(0);
payload[0x35] = " ".charCodeAt(0);
payload[0x36] = "1".charCodeAt(0);
return this.dispatchCommandAndIncrementCounter(0x65, payload);
};
this.onPayloadReceived = (_err, payload) => {
this.logger.debug(`(${this.macAddress.toString("hex")}) Payload received:${payload.toString("hex")}`);
const param = payload[0];
const PayloadHandlerClass = payload_handler_1.payloadHandlers[param];
if (PayloadHandlerClass) {
const handlerInstance = new PayloadHandlerClass(this.rm4Type);
handlerInstance.handle(payload);
}
};
this.checkData = () => {
let packet = Buffer.from([0x04]);
packet = Buffer.concat([this.request_header, packet]);
return this.dispatchCommandAndIncrementCounter(0x65, packet);
};
// Externally Accessed Methods
this.sendData = (data) => {
let packet = Buffer.from([0x02, 0x00, 0x00, 0x00]);
packet = Buffer.concat([this.code_sending_header, packet, data]);
return this.dispatchCommandAndIncrementCounter(0x6a, packet);
};
this.enterLearning = () => {
let packet = Buffer.from([0x03]);
packet = Buffer.concat([this.request_header, packet]);
return this.dispatchCommandAndIncrementCounter(0x6a, packet);
};
this.checkTemperature = () => {
let packet = (device_types_1.rm4DeviceTypes[(this.deviceType)] || device_types_1.rm4PlusDeviceTypes[(this.deviceType)]) ? Buffer.from([0x24]) : Buffer.from([0x1]);
packet = Buffer.concat([this.request_header, packet]);
return this.dispatchCommandAndIncrementCounter(0x6a, packet);
};
this.checkHumidity = () => {
let packet = (device_types_1.rm4DeviceTypes[(this.deviceType)] || device_types_1.rm4PlusDeviceTypes[(this.deviceType)]) ? Buffer.from([0x24]) : Buffer.from([0x1]);
packet = Buffer.concat([this.request_header, packet]);
return this.dispatchCommandAndIncrementCounter(0x6a, packet);
};
this.cancelLearn = () => {
let packet = Buffer.from([0x1e]);
packet = Buffer.concat([this.request_header, packet]);
return this.dispatchCommandAndIncrementCounter(0x6a, packet);
};
this.isProcessing = false;
this.queue = [];
this.logger = logger_1.logger;
this.promises = {};
this.isSending = false;
this.logger.info(`${host.address} ${host.port} Device: ${macAddress.toString("hex")} - ${deviceType}`);
this.host = host;
this.macAddress = macAddress;
this.deviceType = deviceType;
this.port = port;
this.requestCounter = 4444;
this.model = device_types_1.rmDeviceTypes[(deviceType)] || device_types_1.rmPlusDeviceTypes[(deviceType)] || device_types_1.rm4DeviceTypes[(deviceType)] || device_types_1.rm4PlusDeviceTypes[(deviceType)];
//Use different headers for rm4 devices
this.rm4Type = (device_types_1.rm4DeviceTypes[(deviceType)] || device_types_1.rm4PlusDeviceTypes[deviceType]);
this.request_header = this.rm4Type ? Buffer.from([0x04, 0x00]) : Buffer.from([]);
this.code_sending_header = this.rm4Type ? Buffer.from([0xda, 0x00]) : Buffer.from([]);
//except 5f36 and 6508 ¯\_(ツ)_/¯
if (deviceType === parseInt(`0x5f36`) || deviceType === parseInt(`0x6508`)) {
this.code_sending_header = Buffer.from([0xd0, 0x00]);
this.request_header = Buffer.from([0x04, 0x00]);
}
this.key = Buffer.from([0x09, 0x76, 0x28, 0x34, 0x3f, 0xe9, 0x9e, 0x23, 0x76, 0x5c, 0x15, 0x13, 0xac, 0xcf, 0x8b, 0x02]);
this.iv = Buffer.from([0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58]);
this.id = Buffer.from([0, 0, 0, 0]);
this.packetHandler = new packet_handler_1.PacketHandler(this.logger);
this.socketHandler = new socket_handler_1.SocketHandler(this.logger, this.host, this.macAddress, this.deviceType, this.packetHandler);
}
enqueue(command) {
this.queue.push(command);
if (!this.isProcessing) {
this.processQueue();
}
}
async processQueue() {
if (this.queue.length === 0) {
this.isProcessing = false;
return;
}
this.isProcessing = true;
const command = this.queue.shift();
if (command) {
try {
await this.sendData(command);
}
catch (err) {
console.error(`Error processing command: ${err}`);
}
this.processQueue();
}
}
dispatchCommandAndIncrementCounter(command, payload) {
const packet = this.packetHandler.createPacket(command, payload, this.macAddress, this.requestCounter, this.deviceType);
const responsePromise = this.socketHandler.sendPacket(command, packet, this.requestCounter);
this.requestCounter++;
return responsePromise;
}
}
exports.Device = Device;
//# sourceMappingURL=device.js.map