homebridge-apc-ups-alert
Version:
Provide information (and alerts) for apcupsd connected Uninterruptible Power Supplies
156 lines • 9.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpsPlatformAccessory = void 0;
const hap_1 = require("./hap");
const helpers_1 = require("./helpers");
const apcaccess_1 = __importDefault(require("apcaccess"));
const dataModels_1 = require("./dataModels");
/**
* Platform Accessory
* An instance of this class is created for each accessory your platform registers
* Each accessory may expose multiple services of different service types.
*/
class UpsPlatformAccessory {
constructor(platform, accessory, config) {
var _a, _b;
this.platform = platform;
this.accessory = accessory;
this.config = config;
this.service = this.accessory.getService(hap_1.hap.Service.LeakSensor) || this.accessory.addService(hap_1.hap.Service.LeakSensor);
// set accessory information
if (this.accessory.context.dataCache !== undefined) {
this.platform.log.info(`Cached info for ${this.accessory.displayName}: ${JSON.stringify(this.accessory.context.dataCache)}`);
this.processData(this.accessory.context.dataCache);
}
else {
this.accessory.getService(hap_1.hap.Service.AccessoryInformation)
.setCharacteristic(hap_1.hap.Characteristic.Name, config.host)
.setCharacteristic(hap_1.hap.Characteristic.Manufacturer, (_a = config.manufacturer) !== null && _a !== void 0 ? _a : 'UPS')
.setCharacteristic(hap_1.hap.Characteristic.Model, 'Unknown Model')
.setCharacteristic(hap_1.hap.Characteristic.SerialNumber, 'SN0000');
}
this.isOnline = false;
setInterval(() => {
this.pollForInformation();
}, (_b = this.config.interval) !== null && _b !== void 0 ? _b : 10000);
}
async pollForInformation() {
var _a;
const client = new apcaccess_1.default();
try {
await client.connect(this.config.host, (_a = this.config.port) !== null && _a !== void 0 ? _a : 3551);
const result = await client.getStatusJson();
await client.disconnect;
this.processData(result);
}
catch (error) {
this.platform.log.warn(`Error while polling ${this.config.host}: ${(0, helpers_1.errorToString)(error)}`);
}
}
static normalizeString(value) {
return value.trim();
}
static extractNumber(value) {
if (typeof value === 'string') {
return Number(value.trim().replace(/\s.*/, ''));
}
return value;
}
static normalizeProperty(value) {
return value.replace(' ', '').trim().toUpperCase();
}
processData(data) {
var _a;
const accessoryInfo = this.accessory.getService(hap_1.hap.Service.AccessoryInformation);
const initialCache = this.accessory.context.dataCache;
if (this.accessory.context.dataCache === undefined) {
this.accessory.context.dataCache = {};
}
for (const prop in data) {
const propNormalized = UpsPlatformAccessory.normalizeProperty(prop);
switch (propNormalized) {
case dataModels_1.StandardKeys.Model:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.Model, this.accessory.context.dataCache[propNormalized]);
break;
case dataModels_1.StandardKeys.UpsName:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.Name, this.accessory.context.dataCache[propNormalized]);
break;
case dataModels_1.StandardKeys.Status:
{
const status = UpsPlatformAccessory.normalizeString(data[prop]);
if (status === dataModels_1.KnownStatus.CommunicationLost) {
this.isOnline = false;
}
else {
this.isOnline = true;
if (status === dataModels_1.KnownStatus.OnLine) {
this.service.updateCharacteristic(hap_1.hap.Characteristic.LeakDetected, hap_1.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
}
else {
// Assume on battery
this.service.updateCharacteristic(hap_1.hap.Characteristic.LeakDetected, hap_1.hap.Characteristic.LeakDetected.LEAK_DETECTED);
}
}
}
break;
case dataModels_1.OptionalKeys.ApcModel:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.Model, this.accessory.context.dataCache[propNormalized]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.Manufacturer, 'APC');
break;
case dataModels_1.OptionalKeys.SerialNumber:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.SerialNumber, this.accessory.context.dataCache[propNormalized]);
break;
case dataModels_1.OptionalKeys.FirmwareVersion:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.FirmwareRevision, this.accessory.context.dataCache[propNormalized]);
break;
case dataModels_1.OptionalKeys.ManufactureDate:
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.normalizeString(data[prop]);
accessoryInfo === null || accessoryInfo === void 0 ? void 0 : accessoryInfo.updateCharacteristic(hap_1.hap.Characteristic.HardwareRevision, this.accessory.context.dataCache[propNormalized]);
break;
case dataModels_1.OptionalKeys.BatteryLevel:
{
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.extractNumber(data[prop]);
this.service.updateCharacteristic(hap_1.hap.Characteristic.BatteryLevel, this.accessory.context.dataCache[propNormalized]);
const hasLowBattery = (this.accessory.context.dataCache[propNormalized] <= ((_a = this.config.low_battery_threshold) !== null && _a !== void 0 ? _a : 30));
this.service.updateCharacteristic(hap_1.hap.Characteristic.StatusLowBattery, hasLowBattery ?
hap_1.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : hap_1.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
}
break;
case dataModels_1.OptionalKeys.RemainingRuntime:
{
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.extractNumber(data[prop]);
// minutes to seconds
const duration = 60 * this.accessory.context.dataCache[propNormalized];
if ((this.highestTimeRemaining === undefined) || (this.highestTimeRemaining < duration)) {
(0, helpers_1.getOrAddCharacteristic)(this.service, hap_1.hap.Characteristic.RemainingDuration).setProps({
minValue: 0,
maxValue: duration,
});
this.highestTimeRemaining = duration;
}
this.service.updateCharacteristic(hap_1.hap.Characteristic.RemainingDuration, duration);
}
break;
case dataModels_1.OptionalKeys.InternalTemperature:
{
this.accessory.context.dataCache[propNormalized] = UpsPlatformAccessory.extractNumber(data[prop]);
this.service.updateCharacteristic(hap_1.hap.Characteristic.CurrentTemperature, this.accessory.context.dataCache[propNormalized]);
}
break;
}
if (!(0, helpers_1.objectsEqual)(initialCache, this.accessory.context.dataCache)) {
this.platform.log.debug(`Cache updated (${this.accessory.displayName}): ${JSON.stringify(this.accessory.context.dataCache)}`);
}
}
}
}
exports.UpsPlatformAccessory = UpsPlatformAccessory;
//# sourceMappingURL=platformAccessory.js.map