homebridge-enphase-envoy
Version:
Homebridge plugin for Photovoltaic Energy System manufactured by Enphase.
938 lines (861 loc) • 461 kB
JavaScript
import { promises as fsPromises } from 'fs';
import axios from 'axios';
import { Agent } from 'https';
import { XMLParser, XMLBuilder, XMLValidator } from 'fast-xml-parser';
import EventEmitter from 'events';
import RestFul from './restful.js';
import Mqtt from './mqtt.js';
import EnvoyToken from './envoytoken.js';
import DigestAuth from './digestauth.js';
import PasswdCalc from './passwdcalc.js';
import ImpulseGenerator from './impulsegenerator.js';
import { ApiUrls, PartNumbers, Authorization, ApiCodes, LedStatus } from './constants.js';
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
class EnvoyDevice extends EventEmitter {
constructor(api, deviceName, host, displayType, envoyFirmware7xxTokenGenerationMode, envoyPasswd, envoyToken, envoyTokenInstaller, enlightenUser, enlightenPasswd, envoyIdFile, envoyTokenFile, device) {
super();
Accessory = api.platformAccessory;
Characteristic = api.hap.Characteristic;
Service = api.hap.Service;
Categories = api.hap.Categories;
AccessoryUUID = api.hap.uuid;
//device configuration
this.name = deviceName;
this.host = host;
this.displayType = displayType;
this.envoyFirmware7xxTokenGenerationMode = envoyFirmware7xxTokenGenerationMode;
this.envoyPasswd = envoyPasswd;
this.enlightenUser = enlightenUser;
this.enlightenPassword = enlightenPasswd;
this.envoyToken = envoyToken;
this.envoyTokenInstaller = envoyTokenInstaller;
this.productionStateControl = device.productionStateControl || {};
this.productionStateSensor = device.productionStateSensor || {};
this.plcLevelControl = device.plcLevelControl || {};
this.powerProductionSummary = device.powerProductionSummary || 1;
this.powerProductionStateSensor = device.powerProductionStateSensor || {};
this.powerProductionLevelSensors = device.powerProductionLevelSensors || [];
this.energyProductionStateSensor = device.energyProductionStateSensor || {};
this.energyProductionLevelSensors = device.energyProductionLevelSensors || [];
this.energyProductionLifetimeOffset = device.energyProductionLifetimeOffset || 0;
this.powerConsumptionTotalStateSensor = device.powerConsumptionTotalStateSensor || {};
this.powerConsumptionTotalLevelSensors = device.powerConsumptionTotalLevelSensors || [];
this.energyConsumptionTotalStateSensor = device.energyConsumptionTotalStateSensor || {};
this.energyConsumptionTotalLevelSensors = device.energyConsumptionTotalLevelSensors || [];
this.energyConsumptionTotalLifetimeOffset = device.energyConsumptionTotalLifetimeOffset || 0;
this.powerConsumptionNetStateSensor = device.powerConsumptionNetStateSensor || {};
this.powerConsumptionNetLevelSensors = device.powerConsumptionNetLevelSensors || [];
this.energyConsumptionNetStateSensor = device.energyConsumptionNetStateSensor || {};
this.energyConsumptionNetLevelSensors = device.energyConsumptionNetLevelSensors || [];
this.energyConsumptionNetLifetimeOffset = device.energyConsumptionNetLifetimeOffset || 0;
//qRelay
this.qRelayStateSensor = device.qRelayStateSensor || {};
//ac battery
this.acBatterieName = device.acBatterieName || 'AC Batterie';
this.acBatterieBackupLevelSummaryAccessory = device.acBatterieBackupLevelSummaryAccessory || {};
this.acBatterieBackupLevelAccessory = device.acBatterieBackupLevelAccessory || {};
//enpower
this.enpowerDryContactsControl = envoyFirmware7xxTokenGenerationMode > 0 ? device.enpowerDryContactsControl || false : false;
this.enpowerDryContactsSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.enpowerDryContactsSensor || false : false;
this.enpowerGridStateControl = envoyFirmware7xxTokenGenerationMode > 0 ? device.enpowerGridStateControl || {} : {};
this.enpowerGridStateSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.enpowerGridStateSensor || {} : {};
this.enpowerGridModeSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.enpowerGridModeSensors || [] : [];
//encharge
this.enchargeName = device.enchargeName || 'Encharge';
this.enchargeBackupLevelSummaryAccessory = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeBackupLevelSummaryAccessory || {} : {};
this.enchargeBackupLevelAccessory = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeBackupLevelAccessory || {} : {};
this.enchargeStateSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeStateSensor || {} : {};
this.enchargeProfileControls = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeProfileControls || [] : [];
this.enchargeProfileSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeProfileSensors || [] : [];
this.enchargeGridStateSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeGridStateSensor || {} : {};
this.enchargeGridModeSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeGridModeSensors || [] : [];
this.enchargeBackupLevelSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.enchargeBackupLevelSensors || [] : [];
//solar
this.solarGridStateSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.solarGridStateSensor || {} : {};
this.solarGridModeSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.solarGridModeSensors || [] : [];
//generator
this.generatorStateControl = envoyFirmware7xxTokenGenerationMode > 0 ? device.generatorStateControl || {} : {};
this.generatorStateSensor = envoyFirmware7xxTokenGenerationMode > 0 ? device.generatorStateSensor || {} : {};
this.generatorModeContols = envoyFirmware7xxTokenGenerationMode > 0 ? device.generatorModeControls || [] : [];
this.generatorModeSensors = envoyFirmware7xxTokenGenerationMode > 0 ? device.generatorModeSensors || [] : [];
//data refresh
this.dataRefreshControl = device.dataRefreshControl || {};
this.dataRefreshSensor = device.dataRefreshSensor || {};
this.metersDataRefreshTime = device.metersDataRefreshTime * 1000 || 5000;
this.productionDataRefreshTime = device.productionDataRefreshTime * 1000 || 10000;
this.liveDataRefreshTime = device.liveDataRefreshTime * 1000 || 3000;
this.ensembleDataRefreshTime = device.ensembleDataRefreshTime * 1000 || 15000;
//log
this.enableDebugMode = device.enableDebugMode || false;
this.disableLogInfo = device.disableLogInfo || false;
this.disableLogDeviceInfo = device.disableLogDeviceInfo || false;
//external integrations
this.restFul = device.restFul ?? {};
this.restFulConnected = false;
this.mqtt = device.mqtt ?? {};
this.mqttConnected = false;
//system
const systemAccessoryDisplayType = this.displayType ?? 0;
if (systemAccessoryDisplayType > 0) {
const tile = {};
tile.serviceType = ['', Service.Lightbulb, Service.Fan, Service.HumiditySensor, Service.CarbonMonoxideSensor][systemAccessoryDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.StatusActive, Characteristic.CarbonMonoxideDetected][systemAccessoryDisplayType];
tile.characteristicType1 = ['', Characteristic.Brightness, Characteristic.RotationSpeed, Characteristic.CurrentRelativeHumidity, Characteristic.CarbonMonoxideLevel][systemAccessoryDisplayType];
tile.state = false;
tile.level = 0;
this.systemAccessoryActive = tile;
};
//production state control
const productionStateControlDisplayType = this.productionStateControl.displayType ?? 0;
if (productionStateControlDisplayType > 0) {
const tile = {};
tile.name = this.productionStateControl.name || 'Production State Control';
tile.namePrefix = this.productionStateControl.namePrefix || false;
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][productionStateControlDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][productionStateControlDisplayType];
tile.state = false;
this.productionStateActiveControl = tile;
};
//production state sensor
const productionStateSensorDisplayType = this.productionStateSensor.displayType ?? 0;
if (productionStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.productionStateSensor.name || 'Production State Sensor';
sensor.namePrefix = this.productionStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][productionStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][productionStateSensorDisplayType];
sensor.state = false;
this.productionStateActiveSensor = sensor;
};
//plc level control
const plcLevelControlDisplayType = this.plcLevelControl.displayType ?? 0;
if (plcLevelControlDisplayType > 0) {
const tile = {};
tile.name = this.plcLevelControl.name || 'PLC Level Refresh Control';
tile.namePrefix = this.plcLevelControl.namePrefix || false;
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][plcLevelControlDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][plcLevelControlDisplayType];
tile.state = false;
this.plcLevelActiveControl = tile;
}
//data refresh control
const dataRefreshControlDisplayType = this.dataRefreshControl.displayType ?? 0;
if (dataRefreshControlDisplayType > 0) {
const tile = {};
tile.name = this.dataRefreshControl.name || 'Data Refresh Control';
tile.namePrefix = this.dataRefreshControl.namePrefix || false;
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][dataRefreshControlDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][dataRefreshControlDisplayType];
tile.state = false;
this.dataRefreshActiveControl = tile;
};
//data refresh sensor
const dataRefreshSensorDisplayType = this.dataRefreshSensor.displayType ?? 0;
if (dataRefreshSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.dataRefreshSensor.name || 'Data Refresh Sensor';
sensor.namePrefix = this.dataRefreshSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][dataRefreshSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][dataRefreshSensorDisplayType];
sensor.state = false;
this.dataRefreshActiveSensor = sensor;
};
//power production level sensors
this.powerProductionLevelActiveSensors = [];
for (const sensor of this.powerProductionLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Power Production Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.powerLevel = sensor.powerLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.powerProductionLevelActiveSensors.push(sensor);
}
this.powerProductionLevelActiveSensorsCount = this.powerProductionLevelActiveSensors.length || 0;
//power production state sensor
const powerProductionStateSensorDisplayType = this.powerProductionStateSensor.displayType ?? 0;
if (powerProductionStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.powerProductionStateSensor.name || 'Power Production State Sensor';
sensor.namePrefix = this.powerProductionStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][powerProductionStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][powerProductionStateSensorDisplayType];
sensor.state = false;
this.powerProductionStateActiveSensor = sensor;
};
//energy production state sensor
const energyProductionStateSensorDisplayType = this.energyProductionStateSensor.displayType ?? 0;
if (energyProductionStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.energyProductionStateSensor.name || 'Energy Production State Sensor';
sensor.namePrefix = this.energyProductionStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][energyProductionStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][energyProductionStateSensorDisplayType];
sensor.state = false;
this.energyProductionStateActiveSensor = sensor;
};
this.energyProductionLevelActiveSensors = [];
for (const sensor of this.energyProductionLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Energy Production Levele Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.energyLevel = sensor.energyLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.energyProductionLevelActiveSensors.push(sensor);
}
this.energyProductionLevelActiveSensorsCount = this.energyProductionLevelActiveSensors.length || 0;
//power consumption total state sensor
const powerConsumptionTotalStateSensorDisplayType = this.powerConsumptionTotalStateSensor.displayType ?? 0;
if (powerConsumptionTotalStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.powerConsumptionTotalStateSensor.name || 'Power Consumption Total State Sensor';
sensor.namePrefix = this.powerConsumptionTotalStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][powerConsumptionTotalStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][powerConsumptionTotalStateSensorDisplayType];
sensor.state = false;
this.powerConsumptionTotalStateActiveSensor = sensor;
};
this.powerConsumptionTotalLevelActiveSensors = [];
for (const sensor of this.powerConsumptionTotalLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Power Consumption Total Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.powerLevel = sensor.powerLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.powerConsumptionTotalLevelActiveSensors.push(sensor);
}
this.powerConsumptionTotalLevelActiveSensorsCount = this.powerConsumptionTotalLevelActiveSensors.length || 0;
//energy consumption total state sensor
const energyConsumptionTotalStateSensorDisplayType = this.energyConsumptionTotalStateSensor.displayType ?? 0;
if (energyConsumptionTotalStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.energyConsumptionTotalStateSensor.name || 'Energy Consumption Total State Sensor';
sensor.namePrefix = this.energyConsumptionTotalStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][energyConsumptionTotalStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][energyConsumptionTotalStateSensorDisplayType];
sensor.state = false;
this.energyConsumptionTotalStateActiveSensor = sensor;
};
this.energyConsumptionTotalLevelActiveSensors = [];
for (const sensor of this.energyConsumptionTotalLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Energy Consumption Total Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.energyLevel = sensor.energyLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.energyConsumptionTotalLevelActiveSensors.push(sensor);
}
this.energyConsumptionTotalLevelActiveSensorsCount = this.energyConsumptionTotalLevelActiveSensors.length || 0;
//power consumption net state sensor
const powerConsumptionNetStateSensorDisplayType = this.powerConsumptionNetStateSensor.displayType ?? 0;
if (powerConsumptionNetStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.powerConsumptionNetStateSensor.name || 'Power Consumption Net State Sensor';
sensor.namePrefix = this.powerConsumptionNetStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][powerConsumptionNetStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][powerConsumptionNetStateSensorDisplayType];
sensor.state = false;
this.powerConsumptionNetStateActiveSensor = sensor;
};
this.powerConsumptionNetLevelActiveSensors = [];
for (const sensor of this.powerConsumptionNetLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Power Consumption Net Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.powerLevel = sensor.powerLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.powerConsumptionNetLevelActiveSensors.push(sensor);
}
this.powerConsumptionNetLevelActiveSensorsCount = this.powerConsumptionNetLevelActiveSensors.length || 0;
//energy consumption net state sensor
const energyConsumptionNetStateSensorDisplayType = this.energyConsumptionNetStateSensor.displayType ?? 0;
if (energyConsumptionNetStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.energyConsumptionNetStateSensor.name || 'Energy Consumption Net State Sensor';
sensor.namePrefix = this.energyConsumptionNetStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][energyConsumptionNetStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][energyConsumptionNetStateSensorDisplayType];
sensor.state = false;
this.energyConsumptionNetStateActiveSensor = sensor;
};
this.energyConsumptionNetLevelActiveSensors = [];
for (const sensor of this.energyConsumptionNetLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
}
sensor.name = sensor.name || 'Energy Consumption Net Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.energyLevel = sensor.energyLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.energyConsumptionNetLevelActiveSensors.push(sensor);
}
this.energyConsumptionNetLevelActiveSensorsCount = this.energyConsumptionNetLevelActiveSensors.length || 0;
//qRelay
const qRelayStateSensorDisplayType = this.qRelayStateSensor.displayType ?? 0;
if (qRelayStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.qRelayStateSensor.name || 'State Sensor';
sensor.namePrefix = this.qRelayStateSensor.namePrefix || false;
sensor.multiphase = this.qRelayStateSensor.multiphase || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][qRelayStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][qRelayStateSensorDisplayType];
sensor.state0 = false;
sensor.state1 = false;
sensor.state2 = false;
sensor.state3 = false;
this.qRelayStateActiveSensor = sensor;
};
//ac battery
const acBatterieBackupLevelSummaryAccessoryDisplayType = this.acBatterieBackupLevelSummaryAccessory.displayType ?? 0;
if (acBatterieBackupLevelSummaryAccessoryDisplayType > 0) {
const tile = {};
tile.namePrefix = this.acBatterieBackupLevelSummaryAccessory.namePrefix || false;
tile.serviceType = ['', Service.Lightbulb, Service.Fan, Service.HumiditySensor, Service.CarbonMonoxideSensor, Service.Battery][acBatterieBackupLevelSummaryAccessoryDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.StatusActive, Characteristic.CarbonMonoxideDetected, Characteristic.StatusLowBattery][acBatterieBackupLevelSummaryAccessoryDisplayType];
tile.characteristicType1 = ['', Characteristic.Brightness, Characteristic.RotationSpeed, Characteristic.CurrentRelativeHumidity, Characteristic.CarbonMonoxideLevel, Characteristic.BatteryLevel][acBatterieBackupLevelSummaryAccessoryDisplayType];
tile.displayType = this.acBatterieBackupLevelSummaryAccessory.displayType;
tile.minSoc = this.acBatterieBackupLevelSummaryAccessory.minSoc ?? 0;
tile.state = false;
tile.backupLevel = 0;
this.acBatterieBackupLevelSummaryActiveAccessory = tile;
};
const acBatterieBackupLevelAccessoryDisplayType = this.acBatterieBackupLevelAccessory.displayType ?? 0;
if (acBatterieBackupLevelAccessoryDisplayType > 0) {
const tile = {};
tile.namePrefix = this.acBatterieBackupLevelAccessory.namePrefix || false;
tile.serviceType = ['', Service.Battery][acBatterieBackupLevelAccessoryDisplayType];
tile.characteristicType = ['', Characteristic.StatusLowBattery][acBatterieBackupLevelAccessoryDisplayType];
tile.characteristicType1 = ['', Characteristic.BatteryLevel][acBatterieBackupLevelAccessoryDisplayType];
tile.characteristicType2 = ['', Characteristic.ChargingState][acBatterieBackupLevelAccessoryDisplayType];
tile.displayType = this.acBatterieBackupLevelAccessory.displayType;
tile.minSoc = this.acBatterieBackupLevelAccessory.minSoc ?? 0;
this.acBatterieBackupLevelActiveAccessory = tile;
};
//enpower
const enpowerGridStateControlDisplaqyType = this.enpowerGridStateControl.displayType ?? 0;
if (enpowerGridStateControlDisplaqyType > 0) {
const tile = {};
tile.name = this.enpowerGridStateControl.name || 'Enpower Grid State Control';
tile.namePrefix = this.enpowerGridStateControl.namePrefix || false;
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][enpowerGridStateControlDisplaqyType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][enpowerGridStateControlDisplaqyType];
tile.state = false;
this.enpowerGridStateActiveControl = tile;
};
const enpowerGridStateSensorDisplayType = this.enpowerGridStateSensor.displayType ?? 0;
if (enpowerGridStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.enpowerGridStateSensor.name || 'Enpower Grid State Sensor';
sensor.namePrefix = this.enpowerGridStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][enpowerGridStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][enpowerGridStateSensorDisplayType];
sensor.state = false;
this.enpowerGridStateActiveSensor = sensor;
};
this.enpowerGridModeActiveSensors = [];
for (const sensor of this.enpowerGridModeSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Enpower Grid Mode Sensor';
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.enpowerGridModeActiveSensors.push(sensor);
}
this.enpowerGridModeActiveSensorsCount = this.enpowerGridModeActiveSensors.length || 0;
//encharge
const enchargeBackupLevelSummaryAccessoryDisplayType = this.enchargeBackupLevelSummaryAccessory.displayType ?? 0;
if (enchargeBackupLevelSummaryAccessoryDisplayType > 0) {
const tile = {};
tile.namePrefix = this.enchargeBackupLevelSummaryAccessory.namePrefix || false;
tile.serviceType = ['', Service.Lightbulb, Service.Fan, Service.HumiditySensor, Service.CarbonMonoxideSensor, Service.Battery][enchargeBackupLevelSummaryAccessoryDisplayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.StatusActive, Characteristic.CarbonMonoxideDetected, Characteristic.StatusLowBattery][enchargeBackupLevelSummaryAccessoryDisplayType];
tile.characteristicType1 = ['', Characteristic.Brightness, Characteristic.RotationSpeed, Characteristic.CurrentRelativeHumidity, Characteristic.CarbonMonoxideLevel, Characteristic.BatteryLevel][enchargeBackupLevelSummaryAccessoryDisplayType];
tile.displayType = this.enchargeBackupLevelSummaryAccessory.displayType;
tile.minSoc = this.enchargeBackupLevelSummaryAccessory.minSoc ?? 0;
tile.state = false;
tile.backupLevel = 0;
this.enchargeBackupLevelSummaryActiveAccessory = tile;
};
const enchargeBackupLevelAccessoryDisplayType = this.enchargeBackupLevelAccessory.displayType ?? 0;
if (enchargeBackupLevelAccessoryDisplayType > 0) {
const tile = {};
tile.namePrefix = this.enchargeBackupLevelAccessory.namePrefix || false;
tile.serviceType = ['', Service.Battery][enchargeBackupLevelAccessoryDisplayType];
tile.characteristicType1 = ['', Characteristic.StatusLowBattery][enchargeBackupLevelAccessoryDisplayType];
tile.characteristicType = ['', Characteristic.BatteryLevel][enchargeBackupLevelAccessoryDisplayType];
tile.characteristicType2 = ['', Characteristic.ChargingState][enchargeBackupLevelAccessoryDisplayType];
tile.displayType = this.enchargeBackupLevelAccessory.displayType;
tile.minSoc = this.enchargeBackupLevelAccessory.minSoc ?? 0;
this.enchargeBackupLevelActiveAccessory = tile;
};
const enchargeStateSensorDisplayType = this.enchargeStateSensor.displayType ?? 0;
if (enchargeStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.enchargeStateSensor.name || 'State Sensor';
sensor.namePrefix = this.enchargeStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][enchargeStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][enchargeStateSensorDisplayType];
sensor.state = false;
this.enchargeStateActiveSensor = sensor;
};
this.enchargeProfileActiveControls = [];
for (const tile of this.enchargeProfileControls) {
const displayType = tile.displayType ?? 0;
if (displayType === 0) {
continue;
}
tile.name = tile.name || 'Echarge profile Control';
tile.serviceType = ['', Service.Lightbulb][displayType];
tile.characteristicType = ['', Characteristic.On][displayType];
tile.state = false;
tile.previousState = null;
this.enchargeProfileActiveControls.push(tile);
}
this.enchargeProfileActiveControlsCount = this.enchargeProfileActiveControls.length || 0;
this.enchargeProfileActiveSensors = [];
for (const sensor of this.enchargeProfileSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Profile Sensor';
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.enchargeProfileActiveSensors.push(sensor);
}
this.enchargeProfileActiveSensorsCount = this.enchargeProfileActiveSensors.length || 0;
const enchargeGridStateSensorDisplayType = this.enchargeGridStateSensor.displayType ?? 0;
if (enchargeGridStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.enchargeGridStateSensor.name || 'Grid State Sensor';
sensor.namePrefix = this.enchargeGridStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][enchargeGridStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][enchargeGridStateSensorDisplayType];
sensor.state = false;
this.enchargeGridStateActiveSensor = sensor;
};
this.enchargeGridModeActiveSensors = [];
for (const sensor of this.enchargeGridModeSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Grid Mode Sensor';
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.enchargeGridModeActiveSensors.push(sensor);
}
this.enchargeGridModeActiveSensorsCount = this.enchargeGridModeActiveSensors.length || 0;
this.enchargeBackupLevelActiveSensors = [];
for (const sensor of this.enchargeBackupLevelSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
}
sensor.name = sensor.name || 'Backup Level Sensor';
sensor.compareMode = sensor.compareMode ?? 0;
sensor.backupLevel = sensor.backupLevel ?? 0;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.enchargeBackupLevelActiveSensors.push(sensor);
}
this.enchargeBackupLevelActiveSensorsCount = this.enchargeBackupLevelActiveSensors.length || 0;
//solar
const solarGridStateSensorDisplayType = this.solarGridStateSensor.displayType ?? 0;
if (solarGridStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.solarGridStateSensor.name || 'Solar Grid State Sensor';
sensor.namePrefix = this.solarGridStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][solarGridStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][solarGridStateSensorDisplayType];
sensor.state = false;
this.solarGridStateActiveSensor = sensor;
};
this.solarGridModeActiveSensors = [];
for (const sensor of this.solarGridModeSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Solar Grid Mode Sensor';
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.solarGridModeActiveSensors.push(sensor);
}
this.solarGridModeActiveSensorsCount = this.solarGridModeActiveSensors.length || 0;
//generator
const generatorStateControlDisplaqyType = this.generatorStateControl.displayType ?? 0;
if (generatorStateControlDisplaqyType > 0) {
const tile = {};
tile.name = this.generatorStateControl.name || 'Generator State Control';
tile.namePrefix = this.generatorStateControl.namePrefix || false;
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][generatorStateControlDisplaqyType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][generatorStateControlDisplaqyType];
tile.state = false;
this.generatorStateActiveControl = tile;
};
const generatorStateSensorDisplayType = this.generatorStateSensor.displayType ?? 0;
if (generatorStateSensorDisplayType > 0) {
const sensor = {};
sensor.name = this.generatorStateSensor.name || 'Generator State Sensor';
sensor.namePrefix = this.generatorStateSensor.namePrefix || false;
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][generatorStateSensorDisplayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][generatorStateSensorDisplayType];
sensor.state = false;
this.generatorStateActiveSensor = sensor;
};
this.generatorModeActiveControls = [];
for (const tile of this.generatorModeContols) {
const displayType = tile.displayType ?? 0;
if (displayType === 0) {
continue;
};
tile.name = tile.name || 'Generator Mode Control';
tile.serviceType = ['', Service.Switch, Service.Outlet, Service.Lightbulb][displayType];
tile.characteristicType = ['', Characteristic.On, Characteristic.On, Characteristic.On][displayType];
tile.state = false;
tile.previousState = null;
this.generatorModeActiveControls.push(tile);
}
this.generatorModeActiveControlsCount = this.generatorModeActiveControls.length || 0;
this.generatorModeActiveSensors = [];
for (const sensor of this.generatorModeSensors) {
const displayType = sensor.displayType ?? 0;
if (displayType === 0) {
continue;
};
sensor.name = sensor.name || 'Generator Mode Sensor';
sensor.serviceType = ['', Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][displayType];
sensor.characteristicType = ['', Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][displayType];
sensor.state = false;
this.generatorModeActiveSensors.push(sensor);
}
this.generatorModeActiveSensorsCount = this.generatorModeActiveSensors.length || 0;
//setup variables
this.envoyIdFile = envoyIdFile;
this.envoyTokenFile = envoyTokenFile;
this.startPrepareAccessory = true;
//url
this.url = envoyFirmware7xxTokenGenerationMode > 0 ? `https://${this.host}` : `http://${this.host}`;
//create axios instance
this.axiosInstance = axios.create({
method: 'GET',
baseURL: this.url,
withCredentials: true,
headers: {
Accept: 'application/json'
},
httpsAgent: new Agent({
keepAlive: false,
rejectUnauthorized: false
}),
timeout: 25000
});
//supported functions
this.feature = {
info: {
devId: '',
envoyPasswd: '',
installerPasswd: '',
firmware: 500,
firmware7xx: envoyFirmware7xxTokenGenerationMode > 0,
jwtToken: {
generation_time: 0,
token: envoyToken,
expires_at: 0,
installer: this.envoyFirmware7xxTokenGenerationMode === 2 ? this.envoyTokenInstaller : false
}
},
home: {
supported: false,
networkInterfaces: {
supported: false,
installed: false,
count: 0
},
wirelessConnections: {
supported: false,
installed: false,
count: 0
},
},
inventory: {
supported: false,
pcus: {
supported: false,
installed: false,
count: 0
},
qRelays: {
supported: false,
installed: false,
count: 0
},
acBatteries: {
supported: false,
installed: false,
count: 0
},
ensembles: {
supported: false,
installed: false,
count: 0
}
},
pcuStatus: {
supported: false
},
meters: {
supported: false,
installed: false,
count: 0,
production: {
supported: false,
enabled: false,
voltageDivide: 1
},
consumption: {
supported: false,
enabled: false,
voltageDivide: 1
},
acBatterie: {
supported: false,
enabled: false,
voltageDivide: 1
}
},
metersReading: {
supported: false,
installed: false,
count: 0,
channels: {
supported: false,
installed: false,
count: 0
}
},
production: {
supported: false
},
energy: {
supported: false,
production: {
supported: false
},
consumption: {
supported: false
}
},
productionPdm: {
supported: false
},
energyPdm: {
supported: false,
production: {
supported: false
},
consumption: {
supported: false
}
},
productionCt: {
supported: false,
production: {
supported: false,
pcu: {
supported: false
},
eim: {
supported: false
}
},
consumption: {
supported: false
},
acBatterie: {
supported: false
}
},
ensemble: {
supported: false,
installed: false,
status: {
supported: false
}
},
enpowers: {
supported: false,
installed: false,
count: 0
},
encharges: {
supported: false,
installed: false,
count: 0,
settings: {
supported: false,
installed: false,
}
},
tariff: {
supported: false
},
dryContacts: {
supported: false,
installed: false,
count: 0,
settings: {
supported: false,
installed: false,
count: 0
}
},
generators: {
supported: false,
installed: false,
count: 0,
settings: {
supported: false
}
},
liveData: {
supported: false
},
gridProfile: {
supported: false
},
plcLevel: {
supported: false
},
productionState: {
supported: false
},
backboneApp: {
supported: false
},
dataSampling: false,
checkJwtTokenRunning: false,
cookie: false,
};
//pv object
this.pv = {
info: {},
home: {},
inventory: {
pcus: [],
qRelays: [],
acBatteries: {
devices: []
},
ensembles: [],
},
meters: [],
production: {},
energy: {},
productionPdm: {},
energyPdm: {
production: {},
consumption: {}
},
productionCt: {
pcu: {},
production: {},
consumption: [],
acBatterie: {}
},
ensemble: {
enpowers: {
devices: []
},
encharges: {
devices: []
},
counters: {},
secctrl: {},
relay: {},
tariff: {},
dryContacts: [],
generator: {}
},
liveData: {},
gridProfile: {},
productionState: false,
plcLevelState: false,
powerState: false,
powerLevel: 0,
productionPowerPeak: 0,
consumptionTotalPowerPeak: 0,
consumptionNetPowerPeak: 0
};
//create impulse generator
this.impulseGenerator = new ImpulseGenerator();
this.impulseGenerator.on('updateHomeInventoryAndPcuStatus', async () => {
try {
const tokenValid = await this.checkJwtToken();
const updateHome = tokenValid && this.feature.home.supported ? await this.updateHome() : false;
const updateInventory = tokenValid && this.feature.inventory.supported ? await this.updateInventory() : false;
const updatePcuStatus = tokenValid && this.feature.pcuStatus.supported ? await this.updatePcuStatus() : false;
} catch (error) {
this.handleError(error);
};
}).on('updateMeters', async () => {
try {
const tokenValid = await this.checkJwtToken();
const updateMeters = tokenValid && this.feature.meters.supported ? await this.updateMeters() : false;
const updateMetersReading = tokenValid && this.feature.meters.installed && this.feature.metersReading.supported ? await this.updateMetersReading() : false;
} catch (error) {
this.handleError(error);
};
}).on('updateProduction', async () => {
try {
const tokenValid = await this.checkJwtToken();
const updateProduction = tokenValid && this.feature.production.supported ? await this.updateProduction() : false;
const updateProductionPdm = tokenValid && this.feature.productionPdm.supported ? await this.updateProductionPdm() : false;
const updateEnergyPdm = tokenValid && this.feature.energyPdm.supported ? await this.updateEnergyPdm() : false;
const updateProductionCt = (updateProduction || updateProductionPdm) && this.feature.productionCt.supported ? await this.updateProductionCt() : false;
} catch (error) {
this.handleError(error);
};
}).on('updateEnsemble', async () => {
try {
const tokenValid = await this.checkJwtToken();
const updateEnsemble = tokenValid && this.feature.ensemble.supported ? await this.updateEnsembleInventory() : false;
const updateEnsembleStatus = tokenValid && this.feature.ensemble.status.supported ? await this.updateEnsembleStatus() : false;
const updateEnchargeSettings = tokenValid && this.feature.encharges.settings.supported ? await this.updateEnchargesSettings() : false;
const updateTariffSettings = tokenValid && this.feature.tariff.supported ? await this.updateTariff() : false;
const updateDryContacts = tokenValid && this.feature.dryContacts.supported ? await this.updateDryContacts() : false;