homebridge-connector-hub
Version:
A Homebridge plugin to expose Connector+ compatible blinds, curtains, awnings etc to Homekit
95 lines • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectorHubClient = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-len */
/* eslint-disable indent */
const dgram_as_promised_1 = require("dgram-as-promised");
const log_1 = require("../util/log");
const connector_hub_api_1 = require("./connector-hub-api");
const connector_hub_constants_1 = require("./connector-hub-constants");
const connector_hub_helpers_1 = require("./connector-hub-helpers");
// Function to send a request to the hub and receive a sequence of responses.
async function sendCommandMultiResponse(cmdObj, ip, expectSingleResponse = false) {
// Array of responses received from the hub(s).
const responses = [];
// Extract the retry settings specified in the plugin configuration.
const [maxRetries, socketTimeoutMs] = [connector_hub_constants_1.kNetworkSettings.maxRetries, connector_hub_constants_1.kNetworkSettings.retryDelayMs];
// Retry up to kMaxRetries times to overcome any transient network issues.
for (let attempt = 0; attempt <= maxRetries && !responses.length; ++attempt) {
try {
// Create a socket to service this request.
const socket = dgram_as_promised_1.DgramAsPromised.createSocket('udp4');
// Convert the command to a string representation.
const sendMsg = JSON.stringify(cmdObj);
// Send the message. We'll wait for confirmation that it was sent later.
const sendResult = socket.send(sendMsg, connector_hub_constants_1.kSendPort, ip);
// Holds the message parsed from the hub response.
let response;
do {
// Set a maximum timeout for the request. If we get a response within
// the timeout, clear the timeout for the next iteration.
const timer = setTimeout(() => socket.close(), socketTimeoutMs);
const recvMsg = await sendResult && await socket.recv();
// Try to parse the response and add it to the list of responses.
if ((response = recvMsg && (0, connector_hub_helpers_1.tryParse)(recvMsg.msg.toString()))) {
responses.push(response);
}
// Clear the timeout if we still need to read from the socket.
if (response && !expectSingleResponse) {
clearTimeout(timer);
}
} while (response && !expectSingleResponse);
}
catch (ex) {
log_1.Log.error('Network error:', ex.message);
}
}
// Return a series of responses, or an empty array if the op was unsuccessful.
return responses;
}
// Function to send a request to the hub and receive a single response.
async function sendCommand(cmdObj, ip) {
// Delegate to the generic function with the expectation of a single response.
const response = await sendCommandMultiResponse(cmdObj, ip, true);
return response ? response[0] : response;
}
class ConnectorHubClient {
constructor(config, deviceInfo, hubIp, hubToken) {
this.config = config;
this.deviceInfo = deviceInfo;
this.hubIp = hubIp;
this.hubToken = hubToken;
this.accessToken =
(0, connector_hub_helpers_1.computeAccessToken)(this.config.connectorKey, this.hubToken);
}
static getDeviceList(hubIp) {
return sendCommandMultiResponse((0, connector_hub_helpers_1.makeGetDeviceListRequest)(), hubIp);
}
static readDeviceState(deviceInfo, hubIp, hubToken, connectorKey) {
const accessToken = (0, connector_hub_helpers_1.computeAccessToken)(connectorKey, hubToken);
return sendCommand((0, connector_hub_helpers_1.makeReadDeviceRequest)(deviceInfo, accessToken), hubIp);
}
getDeviceState(readType) {
if (readType === connector_hub_constants_1.ReadDeviceType.kActive) {
const activeReq = (0, connector_hub_helpers_1.makeWriteDeviceRequest)(this.deviceInfo, this.accessToken, { operation: connector_hub_api_1.DeviceOpCode.kStatusQuery });
return sendCommand(activeReq, this.hubIp);
}
return sendCommand((0, connector_hub_helpers_1.makeReadDeviceRequest)(this.deviceInfo, this.accessToken), this.hubIp);
}
setOpenCloseState(op) {
return this.setDeviceState({ operation: op });
}
setTargetPosition(position) {
return this.setDeviceState({ targetPosition: position });
}
setTargetAngle(angle) {
return this.setDeviceState({ targetAngle: angle });
}
setDeviceState(command) {
const request = (0, connector_hub_helpers_1.makeWriteDeviceRequest)(this.deviceInfo, this.accessToken, command);
return sendCommand(request, this.hubIp);
}
}
exports.ConnectorHubClient = ConnectorHubClient;
//# sourceMappingURL=connectorHubClient.js.map