homebridge-kiwigrid
Version:
A HomeBridge plugin to connect local KiwiGrid installations (like Solarwatt EnergyManager) to HomeKit.
130 lines • 8.31 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.KiwigridHomebridgePlatform = void 0;
const settings_1 = require("./settings");
const KiwiBatteryServiceAccessory_1 = require("./KiwiBatteryServiceAccessory");
const axios_1 = __importDefault(require("axios"));
const uuid_validate_1 = __importDefault(require("uuid-validate"));
/**
* HomebridgePlatform
* This class is the main constructor for your plugin, this is where you should
* parse the user config and discover/register accessories with Homebridge.
*/
class KiwigridHomebridgePlatform {
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.Service = this.api.hap.Service;
this.Characteristic = this.api.hap.Characteristic;
// this is used to track restored cached accessories
this.accessories = [];
this.customPlatformAccessories = {};
this.log.debug('Finished initializing platform:', this.config.name);
// When this event is fired it means Homebridge has restored all cached accessories from disk.
// Dynamic Platform plugins should only register new accessories after this event was fired,
// in order to ensure they weren't added to homebridge already. This event can also be used
// to start discovery of new accessories.
this.api.on('didFinishLaunching', () => {
log.debug('Executed didFinishLaunching callback');
const devicesUrl = 'http://' + this.config.ip + '/rest/kiwigrid/wizard/devices';
// run the method to discover / register your devices as accessories
this.updateDevices(devicesUrl, true);
if (this.config.refreshIntervalMinutes > 0) {
log.debug('Refresh interval set to ' + this.config.refreshIntervalMinutes);
setInterval(() => {
this.updateDevices(devicesUrl, false);
}, this.config.refreshIntervalMinutes * 60 * 1000);
}
else {
log.debug('No refresh interval set');
}
});
}
/**
* This function is invoked when homebridge restores cached accessories from disk at startup.
* It should be used to setup event handlers for characteristics and update respective values.
*/
configureAccessory(accessory) {
this.log.debug('Loading accessory from cache:', accessory.displayName);
// add the restored accessory to the accessories cache so we can track if it has already been registered
this.accessories.push(accessory);
}
/**
* This is an example method showing how to register discovered accessories.
* Accessories must only be registered once, previously created accessories
* must not be registered again to prevent "duplicate UUID" errors.
*/
async updateDevices(url, firstRun) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
this.log.debug('Reading devices from: ' + url);
try {
const response = await axios_1.default.get(url);
const json = response.data;
// loop over the discovered devices and register each one if it has not already been registered
for (let i = 0; i < json.result.items.length; i++) {
const item = json.result.items[i];
const info = item.tagValues;
if (info.StateOfCharge) {
const battery = {
Guid: (0, uuid_validate_1.default)(item.guid) ? item.guid : this.api.hap.uuid.generate(item.guid),
StateOfCharge: (_b = (_a = info === null || info === void 0 ? void 0 : info.StateOfCharge) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 0,
IsCharging: ((_c = info === null || info === void 0 ? void 0 : info.ModeConverter) === null || _c === void 0 ? void 0 : _c.value) === 'CHARGING',
Manufacturer: (_e = (_d = info === null || info === void 0 ? void 0 : info.IdManufacturer) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : 'n/a',
Name: (_g = (_f = info === null || info === void 0 ? void 0 : info.IdName) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : item.guid,
Model: (_j = (_h = info === null || info === void 0 ? void 0 : info.IdName) === null || _h === void 0 ? void 0 : _h.value) !== null && _j !== void 0 ? _j : item.guid,
StateOfHealth: (_l = (_k = info === null || info === void 0 ? void 0 : info.StateOfHealth) === null || _k === void 0 ? void 0 : _k.value) !== null && _l !== void 0 ? _l : null,
Temperature: (_o = (_m = info === null || info === void 0 ? void 0 : info.TemperatureBattery) === null || _m === void 0 ? void 0 : _m.value) !== null && _o !== void 0 ? _o : null,
IsHealthy: ((_p = info === null || info === void 0 ? void 0 : info.StateDevice) === null || _p === void 0 ? void 0 : _p.value) === 'OK',
Firmware: (_r = (_q = info === null || info === void 0 ? void 0 : info.IdFirmware) === null || _q === void 0 ? void 0 : _q.value) !== null && _r !== void 0 ? _r : 'n/a',
ModuleCount: (_t = (_s = info === null || info === void 0 ? void 0 : info.CountBatteryModules) === null || _s === void 0 ? void 0 : _s.value) !== null && _t !== void 0 ? _t : null,
SerialNumber: (_v = (_u = info === null || info === void 0 ? void 0 : info.IdSerialNumber) === null || _u === void 0 ? void 0 : _u.value) !== null && _v !== void 0 ? _v : 'n/a',
Updated: Date.now(),
};
// at least Solarwatt seems to put the SerialNumber into the Name
battery.Name = battery.Name.replace(battery.SerialNumber, '').trim();
this.log.debug('Battery info: ' + JSON.stringify(battery));
if (firstRun) {
this.RegisterBattery(battery);
}
this.UpdateBattery(battery);
}
}
}
catch (exception) {
process.stderr.write(`ERROR received from ${url}: ${exception}\n`);
}
}
RegisterBattery(battery) {
const uuid = battery.Guid;
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (existingAccessory) {
this.log.debug('Restoring existing accessory from cache:', existingAccessory.displayName);
existingAccessory.context.device = battery;
this.api.updatePlatformAccessories([existingAccessory]);
this.customPlatformAccessories[uuid] = new KiwiBatteryServiceAccessory_1.KiwiBatteryServiceAccessory(this.log, this, existingAccessory);
}
else {
this.log.debug('Adding new accessory:', battery.Name);
const accessory = new this.api.platformAccessory(battery.Name, uuid, 10 /* this.api.hap.Categories.SENSOR */);
accessory.context.device = battery;
this.customPlatformAccessories[uuid] = new KiwiBatteryServiceAccessory_1.KiwiBatteryServiceAccessory(this.log, this, accessory);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
}
}
UpdateBattery(battery) {
const uuid = battery.Guid;
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
if (existingAccessory) {
this.log.debug('Update: Restoring existing accessory from cache:', existingAccessory.displayName);
existingAccessory.context.device = battery;
this.customPlatformAccessories[uuid].Update(existingAccessory);
this.api.updatePlatformAccessories([existingAccessory]);
}
}
}
exports.KiwigridHomebridgePlatform = KiwigridHomebridgePlatform;
//# sourceMappingURL=KiwigridHomebridgePlatform.js.map