iobroker.zendure-solarflow 3.3.1 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -59,9 +59,15 @@ On a HUB 1200 / HUB 2000 / ACE 1500 combination you have to use '**setDeviceAuto
59
59
  This adapter will now use the Cloud Authorization Code for authentication on the official mqtt servers, which you can generate in the Zendure app!
60
60
 
61
61
  ## Changelog
62
+ ### 3.3.2 (2026-02-02)
63
+
64
+ - Fix another 'has no existing object' message bug on pvPower3 + 4
65
+ - Fix Battery identification of AB2000X and calculation of 'energyWhMax'
66
+ - Fix Battery identification of AB3000 and calculation of 'energyWhMax'
67
+
62
68
  ### 3.3.1 (2026-01-30)
63
69
 
64
- - Fix caluclation issue
70
+ - Fix calculation issue
65
71
 
66
72
  ### 3.3.0 (2026-01-30)
67
73
 
@@ -52,6 +52,8 @@ class ZenHaDevice {
52
52
  } else if (x.sn.startsWith("C")) {
53
53
  if (x.sn[3] == "F") {
54
54
  batType = "AB2000S";
55
+ } else if (x.sn[3] == "E") {
56
+ batType = "AB2000X";
55
57
  } else {
56
58
  batType = "AB2000";
57
59
  }
@@ -382,10 +384,12 @@ class ZenHaDevice {
382
384
  energyWhMax = 2400;
383
385
  } else {
384
386
  for (let i = 0; i < this.batteries.length; i++) {
385
- if (this.batteries[i].type == "AB1000") {
387
+ if (this.batteries[i].type.includes("AB1000")) {
386
388
  energyWhMax = (energyWhMax ? energyWhMax : 0) + 960;
387
- } else if (this.batteries[i].type == "AB2000") {
389
+ } else if (this.batteries[i].type.includes("AB2000")) {
388
390
  energyWhMax = (energyWhMax ? energyWhMax : 0) + 1920;
391
+ } else if (this.batteries[i].type.includes("AB3000")) {
392
+ energyWhMax = (energyWhMax ? energyWhMax : 0) + 2880;
389
393
  }
390
394
  }
391
395
  }
@@ -1199,12 +1203,16 @@ class ZenHaDevice {
1199
1203
  if (this.states.find((x) => x.title == "pvPower3")) {
1200
1204
  stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodayWh`;
1201
1205
  stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodaykWh`;
1206
+ } else {
1207
+ return;
1202
1208
  }
1203
1209
  break;
1204
1210
  case "pvPower4":
1205
1211
  if (this.states.find((x) => x.title == "pvPower4")) {
1206
1212
  stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodayWh`;
1207
1213
  stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodaykWh`;
1214
+ } else {
1215
+ return;
1208
1216
  }
1209
1217
  break;
1210
1218
  default:
@@ -1212,8 +1220,10 @@ class ZenHaDevice {
1212
1220
  stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;
1213
1221
  break;
1214
1222
  }
1215
- await ((_a = this.adapter) == null ? void 0 : _a.setState(stateNameEnergyWh, 0, true));
1216
- await ((_b = this.adapter) == null ? void 0 : _b.setState(stateNameEnergykWh, 0, true));
1223
+ if (stateNameEnergyWh != "" && stateNameEnergykWh != "") {
1224
+ await ((_a = this.adapter) == null ? void 0 : _a.setState(stateNameEnergyWh, 0, true));
1225
+ await ((_b = this.adapter) == null ? void 0 : _b.setState(stateNameEnergykWh, 0, true));
1226
+ }
1217
1227
  });
1218
1228
  }
1219
1229
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/models/deviceModels/ZenHaDevice.ts"],
4
- "sourcesContent": ["import { createHash } from \"crypto\";\nimport { calculationStateKeys } from \"../../constants/constants\";\nimport { createCalculationStates } from \"../../helpers/createCalculationStates\";\nimport { toHoursAndMinutes } from \"../../helpers/timeHelper\";\nimport { ZendureSolarflow } from \"../../main\";\nimport {\n knownPackDataProperties,\n onSubscribeIotTopic,\n onSubscribeReportTopic,\n} from \"../../services/mqttSharedService\";\nimport { IDevicePack } from \"../IDevicePack\";\nimport { IPackData } from \"../IPackData\";\nimport { ISolarflowState } from \"../ISolarflowState\";\nimport { IZenHaDeviceDetails } from \"../IZenHaDeviceDetails\";\n\nexport class ZenHaDevice {\n public zenHaDeviceDetails?: IZenHaDeviceDetails;\n public adapter: ZendureSolarflow;\n\n public productKey: string;\n public deviceKey: string;\n public productName: string;\n public deviceName: string;\n public messageId: number = 0;\n public batteries: IDevicePack[] = [];\n\n public iotTopic: string = \"\";\n public functionTopic = \"\";\n public password: string = \"\";\n\n public maxInputLimit: number = 0;\n public maxOutputLimit: number = 0;\n\n public states: ISolarflowState[] = [];\n public controlStates: ISolarflowState[] = [];\n\n public constructor(\n _adapter: ZendureSolarflow,\n _productKey: string,\n _deviceKey: string,\n _productName: string,\n _deviceName: string,\n _zenHaDeviceDetails?: IZenHaDeviceDetails,\n ) {\n this.zenHaDeviceDetails = _zenHaDeviceDetails;\n this.adapter = _adapter;\n this.productKey = _productKey;\n this.deviceKey = _deviceKey;\n\n this.deviceName = _deviceName;\n this.productName = _productName;\n\n this.iotTopic = `iot/${_productKey}/${_deviceKey}/properties/write`;\n this.functionTopic = `iot/${_productKey}/${_deviceKey}/function/invoke`;\n\n // Calculate device password\n this.password = createHash(\"md5\")\n .update(_deviceKey, \"utf8\")\n .digest(\"hex\")\n .toUpperCase()\n .substring(8, 24);\n\n // Create or update states\n this.createSolarFlowStates();\n\n // Subscribe to report topic (get telemetry)\n this.subscribeReportTopic();\n\n // Subscribe to Iot topic (push control values)\n this.subscribeIotTopic();\n\n // Get complete data from device after a timeout\n this.adapter.setTimeout(() => {\n this.triggerFullTelemetryUpdate();\n }, 5000);\n\n if (this.zenHaDeviceDetails?.online) {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n } else if (this.zenHaDeviceDetails?.online == false) {\n this.updateSolarFlowState(\"wifiState\", \"Disconnected\");\n }\n }\n\n private async createSolarFlowStates(): Promise<void> {\n const productKey = this.productKey.replace(\n this.adapter.FORBIDDEN_CHARS,\n \"\",\n );\n const deviceKey = this.deviceKey.replace(this.adapter.FORBIDDEN_CHARS, \"\");\n\n this.adapter.log.debug(\n `[createSolarFlowStates] Creating or updating SolarFlow states for ${this.productName} (${productKey}/${deviceKey}) and name '${this.deviceName}'.`,\n );\n\n // Create device (e.g. the product type -> SolarFlow)\n await this.adapter?.extendObject(productKey, {\n type: \"device\",\n common: {\n name: {\n de: `${this.productName} (${productKey})`,\n en: `${this.productName} (${productKey})`,\n },\n },\n native: {},\n });\n\n // Create channel (e.g. the device specific key)\n await this.adapter?.extendObject(productKey + \".\" + deviceKey, {\n type: \"channel\",\n common: {\n name: {\n de: `${this.deviceName} (${deviceKey})`,\n en: `${this.deviceName} (${deviceKey})`,\n },\n },\n native: {},\n });\n\n // Create pack data folder\n await this.adapter?.extendObject(`${productKey}.${deviceKey}.packData`, {\n type: \"channel\",\n common: {\n name: {\n de: \"Batterie Packs\",\n en: \"Battery packs\",\n },\n },\n native: {},\n });\n\n // Create report states\n this.states.forEach(async (state: ISolarflowState) => {\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.${state.title}`,\n {\n type: \"state\",\n common: {\n name: {\n de: state.nameDe,\n en: state.nameEn,\n },\n type: state.type,\n desc: state.title,\n role: state.role,\n read: true,\n write: false,\n unit: state.unit,\n states: state.states,\n },\n native: {},\n },\n );\n });\n\n // Create control folder\n await this.adapter?.extendObject(`${productKey}.${deviceKey}.control`, {\n type: \"channel\",\n common: {\n name: {\n de: \"Steuerung f\u00FCr Ger\u00E4t \" + deviceKey,\n en: \"Control for device \" + deviceKey,\n },\n },\n native: {},\n });\n\n this.controlStates.forEach(async (state: ISolarflowState) => {\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.control.${state.title}`,\n {\n type: \"state\",\n common: {\n name: {\n de: state.nameDe,\n en: state.nameEn,\n },\n type: state.type,\n desc: state.title,\n role: state.role,\n read: true,\n write: true,\n unit: state.unit,\n states: state.states,\n },\n native: {},\n },\n );\n\n // Subscribe to states to respond to changes\n this.adapter?.subscribeStates(\n `${productKey}.${deviceKey}.control.${state.title}`,\n );\n });\n\n if (this.adapter.config.useCalculation) {\n // Create calculations folder\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.calculations`,\n {\n type: \"channel\",\n common: {\n name: {\n de: \"Berechnungen f\u00FCr Ger\u00E4t \" + deviceKey,\n en: \"Calculations for Device \" + deviceKey,\n },\n },\n native: {},\n },\n );\n\n await createCalculationStates(this.adapter, productKey, deviceKey);\n }\n }\n\n public subscribeReportTopic(): void {\n const reportTopic = `/${this.productKey}/${this.deviceKey}/#`;\n\n if (this.adapter) {\n this.adapter.log.debug(\n `[subscribeReportTopic] Subscribing to MQTT Topic: ${reportTopic}`,\n );\n this.adapter.mqttClient?.subscribe(reportTopic, onSubscribeReportTopic);\n }\n }\n\n private subscribeIotTopic(): void {\n const iotTopic = `iot/${this.productKey}/${this.deviceKey}/#`;\n\n this.adapter?.log.debug(\n `[subscribeIotTopic] Subscribing to MQTT Topic: ${iotTopic}`,\n );\n this.adapter?.mqttClient?.subscribe(iotTopic, (error) => {\n onSubscribeIotTopic(error, this.productKey, this.deviceKey);\n });\n }\n\n public setDeviceAutomationInOutLimit(limit: number): void {\n this.adapter?.log.error(\n `[setAcMode] Method setDeviceAutomationInOutLimit (set to ${limit}) not defined in base class!`,\n );\n return;\n }\n\n public setAcMode(acMode: number): void {\n this.adapter?.log.error(\n `[setAcMode] Method setAcMode (set to ${acMode}) not defined in base class!`,\n );\n return;\n }\n\n public setDcSwitch(dcSwitch: boolean): void {\n this.adapter?.log.error(\n `[setAcMode] Method setDcSwitch (set to ${dcSwitch}) not defined in base class!`,\n );\n return;\n }\n\n public setAcSwitch(acSwitch: boolean): void {\n this.adapter?.log.error(\n `[setAcMode] Method setAcSwitch (set to ${acSwitch}) not defined in base class!`,\n );\n return;\n }\n\n public setHubState(hubState: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (hubState == 0 || hubState == 1) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const socSetLimit = { properties: { hubState: hubState } };\n this.adapter.log.debug(\n `[setHubState] Setting Hub State for deviceKey ${this.deviceKey} to ${hubState}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\n } else {\n this.adapter.log.debug(`[setHubState] Hub state is not 0 or 1!`);\n }\n }\n }\n\n public setPassMode(passMode: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const setPassModeContent = { properties: { passMode: passMode } };\n this.adapter.log.debug(\n `[setPassMode] Set passMode for deviceKey ${this.deviceKey} to ${passMode}!`,\n );\n this.adapter.mqttClient?.publish(\n topic,\n JSON.stringify(setPassModeContent),\n );\n }\n }\n\n public setAutoRecover(autoRecover: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const setAutoRecoverContent = {\n properties: { autoRecover: autoRecover ? 1 : 0 },\n };\n this.adapter.log.debug(\n `[setAutoRecover] Set autoRecover for deviceKey ${this.deviceKey} to ${autoRecover}!`,\n );\n this.adapter.mqttClient?.publish(\n topic,\n JSON.stringify(setAutoRecoverContent),\n );\n }\n }\n\n /**\n * Will set the discharge limit (minSoc)\n * @param socSet the desired minimum soc\n * @returns void\n */\n public setDischargeLimit(minSoc: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (minSoc >= 0 && minSoc <= 50) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const socSetLimit = { properties: { minSoc: minSoc * 10 } };\n this.adapter.log.debug(\n `[setDischargeLimit] Setting Discharge Limit for device key ${this.deviceKey} to ${minSoc}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\n } else {\n this.adapter.log.debug(\n `[setDischargeLimit] Discharge limit is not in range 0<>50!`,\n );\n }\n }\n }\n\n /**\n * Will set the maximum charge limit\n * @param socSet the desired max SOC\n * @returns void\n */\n public setChargeLimit(socSet: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (socSet >= 40 && socSet <= 100) {\n const socSetLimit = { properties: { socSet: socSet * 10 } };\n this.adapter.log.debug(\n `[setChargeLimit] Setting ChargeLimit for device key ${this.deviceKey} to ${socSet}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(socSetLimit),\n );\n } else {\n this.adapter.log.debug(\n `[setChargeLimit] Charge limit is not in range 40<>100!`,\n );\n }\n }\n }\n\n /**\n * Will set the 'energy plan'\n * @param autoModel autoModel value, like 8 for smart matching\n * @returns void\n */\n public setAutoModel(autoModel: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n let setAutoModelContent: any = { properties: { autoModel: autoModel } };\n\n switch (autoModel) {\n case 8: {\n // Smart Matching Modus\n setAutoModelContent = {\n properties: {\n autoModelProgram: 1,\n autoModelValue: {\n chargingType: 0,\n chargingPower: 0,\n outPower: 0,\n },\n msgType: 1,\n autoModel: 8,\n },\n };\n break;\n }\n case 9: // Smart CT Modus\n setAutoModelContent = {\n properties: {\n autoModelProgram: 2,\n autoModelValue: {\n chargingType: 3,\n chargingPower: 0,\n outPower: 0,\n },\n msgType: 1,\n autoModel: 9,\n },\n };\n break;\n }\n\n this.adapter.log.debug(\n `[setAutoModel] Setting autoModel for device key ${this.deviceKey} to ${autoModel}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setAutoModelContent),\n );\n }\n }\n\n public async setOutputLimit(limit: number): Promise<void> {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n // Check if autoModel is set to 0 (Nothing) or 8 (Smart Matching)\n const autoModel = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".autoModel\",\n )\n )?.val;\n\n if (autoModel != 0) {\n this.adapter.log.warn(\n \"Operation mode (autoModel) is not set to '0', we can't set the output limit!\",\n );\n return;\n }\n\n if (limit) {\n limit = Math.round(limit);\n } else {\n limit = 0;\n }\n\n // Limit to the device max limit\n if (limit > this.maxOutputLimit) {\n limit = this.maxOutputLimit;\n }\n\n if (\n limit < 100 &&\n limit != 90 &&\n limit != 60 &&\n limit != 30 &&\n limit != 0 &&\n (this.productKey == \"73bktv\" || this.productKey == \"a8yh63\")\n ) {\n // NUR Solarflow HUB: Das Limit kann unter 100 nur in 30er Schritten gesetzt werden, dH. 30/60/90/100, wir rechnen das also um\n if (limit < 100 && limit > 90) {\n limit = 90;\n } else if (limit > 60 && limit < 90) {\n limit = 60;\n } else if (limit > 30 && limit < 60) {\n limit = 30;\n } else if (limit < 30) {\n limit = 30;\n }\n }\n\n if (this.adapter.config.useLowVoltageBlock) {\n const lowVoltageBlockState = await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.lowVoltageBlock\",\n );\n if (\n lowVoltageBlockState &&\n lowVoltageBlockState.val &&\n lowVoltageBlockState.val == true\n ) {\n limit = 0;\n }\n\n const fullChargeNeeded = await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.fullChargeNeeded\",\n );\n\n if (\n fullChargeNeeded &&\n fullChargeNeeded.val &&\n fullChargeNeeded.val == true\n ) {\n limit = 0;\n }\n }\n\n const currentLimit = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".outputLimit\",\n )\n )?.val;\n\n if (currentLimit != null && currentLimit != undefined) {\n if (currentLimit != limit) {\n const outputlimit = { properties: { outputLimit: limit } };\n\n this.messageId += 1;\n\n const timestamp = new Date();\n timestamp.setMilliseconds(0);\n\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(outputlimit),\n );\n }\n }\n }\n }\n\n public setInputLimit(limit: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n // Limit has always to be positive!\n if (limit < 0) {\n this.adapter.log.debug(\n `[setInputLimit] limit ${limit} is negative, converting to positive!`,\n );\n limit = Math.abs(limit);\n }\n\n if (limit) {\n limit = Math.round(limit);\n } else {\n limit = 0;\n }\n\n if (limit < 0) {\n limit = 0;\n } else if (limit > 0 && limit <= 30) {\n limit = 30;\n } else if (limit > this.maxInputLimit) {\n limit = this.maxInputLimit;\n }\n\n if (this.productKey.includes(\"8bm93h\")) {\n // Das Limit kann beim ACE nur in 100er Schritten gesetzt werden\n limit = Math.ceil(limit / 100) * 100;\n }\n\n const inputLimitContent = { properties: { inputLimit: limit } };\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(inputLimitContent),\n );\n }\n }\n\n public setSmartMode(smartModeOn: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const setSmartModeContent = {\n properties: { smartMode: smartModeOn ? 1 : 0 },\n };\n\n this.adapter.log.debug(\n `[setBuzzer] Setting Smart Mode for device key ${this.deviceKey} to ${smartModeOn}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setSmartModeContent),\n );\n }\n }\n\n public setBuzzerSwitch(buzzerOn: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const setBuzzerSwitchContent = {\n properties: { buzzerSwitch: buzzerOn ? 1 : 0 },\n };\n this.adapter.log.debug(\n `[setBuzzer] Setting Buzzer for device key ${this.deviceKey} to ${buzzerOn}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setBuzzerSwitchContent),\n );\n }\n }\n\n public triggerFullTelemetryUpdate(): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/read`;\n\n const getAllContent = { properties: [\"getAll\"] };\n this.adapter.log.debug(\n `[triggerFullTelemetryUpdate] Triggering full telemetry update for device key ${this.deviceKey}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(getAllContent));\n }\n }\n\n public async updateSolarFlowState(\n state: string,\n val: number | string | boolean,\n ): Promise<void> {\n const currentValue = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.${state}`,\n );\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.${state}`,\n val,\n true,\n );\n\n if (currentValue?.val != val && state != \"wifiState\") {\n // Set lastUpdate for deviceKey if a value was changed!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n }\n\n public async updateSolarFlowControlState(\n state: string,\n val: number | string | boolean,\n ): Promise<void> {\n // First check if state exist\n const stateExist = await this.adapter?.objectExists(\n `${this.productKey}.${this.deviceKey}.control.${state}`,\n );\n\n // Update the control state\n if (stateExist) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.${state}`,\n val,\n true,\n );\n }\n }\n\n addOrUpdatePackData = async (\n packData: IPackData[],\n isSolarFlow: boolean,\n ): Promise<void> => {\n if (this.adapter && this.productKey && this.deviceKey) {\n await packData.forEach(async (x) => {\n // Process data only with a serial id!\n if (x.sn && this.adapter) {\n // Create channel (e.g. the device specific key)\n // We can determine the type of the battery by the SN number.\n let batType = \"\";\n if (this.productKey == \"yWF7hV\") {\n batType = \"AIO2400\";\n } else if (x.sn.startsWith(\"A\")) {\n batType = \"AB1000\";\n } else if (x.sn.startsWith(\"B\")) {\n batType = \"AB1000S\";\n } else if (x.sn.startsWith(\"C\")) {\n if (x.sn[3] == \"F\") {\n batType = \"AB2000S\";\n } else {\n batType = \"AB2000\";\n }\n } else if (x.sn.startsWith(\"F\")) {\n batType = \"AB3000X\";\n }\n\n // Check if is in Pack2device list\n if (!this.batteries.some((y) => y.packSn == x.sn)) {\n this.batteries.push({\n packSn: x.sn,\n type: batType,\n });\n\n this.adapter.log.debug(\n `[addOrUpdatePackData] Added battery ${batType} with SN ${x.sn} on deviceKey ${this.deviceKey} to batteries array!`,\n );\n }\n\n // create a state for the serial id\n const key = (\n this.productKey +\n \".\" +\n this.deviceKey +\n \".packData.\" +\n x.sn\n ).replace(this.adapter.FORBIDDEN_CHARS, \"\");\n\n await this.adapter?.extendObject(key, {\n type: \"channel\",\n common: {\n name: {\n de: batType,\n en: batType,\n },\n },\n native: {},\n });\n\n await this.adapter?.extendObject(key + \".model\", {\n type: \"state\",\n common: {\n name: {\n de: \"Batterietyp\",\n en: \"Battery type\",\n },\n type: \"string\",\n desc: \"model\",\n role: \"value\",\n read: true,\n write: false,\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".model\", batType, true);\n\n await this.adapter?.extendObject(key + \".sn\", {\n type: \"state\",\n common: {\n name: {\n de: \"Seriennummer\",\n en: \"Serial id\",\n },\n type: \"string\",\n desc: \"Serial ID\",\n role: \"value\",\n read: true,\n write: false,\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".sn\", x.sn, true);\n\n if (x.socLevel) {\n // State f\u00FCr socLevel\n await this.adapter?.extendObject(key + \".socLevel\", {\n type: \"state\",\n common: {\n name: {\n de: \"SOC der Batterie\",\n en: \"soc of battery\",\n },\n type: \"number\",\n desc: \"SOC Level\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"%\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".socLevel\", x.socLevel, true);\n }\n\n if (x.maxTemp) {\n const maxTempCelsius = x.maxTemp / 10 - 273.15;\n const maxTempState = await this.adapter?.getStateAsync(\n key + \".maxTemp\",\n );\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (\n maxTempState &&\n maxTempState.val &&\n maxTempCelsius != maxTempState.val\n ) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n // State f\u00FCr maxTemp\n await this.adapter?.extendObject(key + \".maxTemp\", {\n type: \"state\",\n common: {\n name: {\n de: \"Max. Temperatur der Batterie\",\n en: \"max temp. of battery\",\n },\n type: \"number\",\n desc: \"Max. Temp\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"\u00B0C\",\n },\n native: {},\n });\n\n // Convert Kelvin to Celsius\n await this.adapter?.setState(\n key + \".maxTemp\",\n maxTempCelsius,\n true,\n );\n }\n\n if (x.minVol) {\n const minVol = x.minVol / 100;\n const minVolState = await this.adapter?.getStateAsync(\n key + \".minVol\",\n );\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (minVolState && minVolState.val && minVol != minVolState.val) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".minVol\", {\n type: \"state\",\n common: {\n name: \"minVol\",\n type: \"number\",\n desc: \"minVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".minVol\", minVol, true);\n }\n\n if (x.batcur) {\n await this.adapter?.extendObject(key + \".batcur\", {\n type: \"state\",\n common: {\n name: \"batcur\",\n type: \"number\",\n desc: \"batcur\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"A\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".batcur\", x.batcur / 10, true);\n }\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (x.maxVol) {\n const maxVol = x.maxVol / 100;\n const maxVolState = await this.adapter?.getStateAsync(\n key + \".maxVol\",\n );\n\n if (maxVolState && maxVolState.val && maxVol != maxVolState.val) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".maxVol\", {\n type: \"state\",\n common: {\n name: \"maxVol\",\n type: \"number\",\n desc: \"maxVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".maxVol\", maxVol, true);\n }\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (x.totalVol) {\n const totalVol = x.totalVol / 100;\n\n const totalVolState = await this.adapter?.getStateAsync(\n key + \".totalVol\",\n );\n\n if (\n totalVolState &&\n totalVolState.val &&\n totalVol != totalVolState.val\n ) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".totalVol\", {\n type: \"state\",\n common: {\n name: \"totalVol\",\n type: \"number\",\n desc: \"totalVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".totalVol\", totalVol, true);\n\n // Send Voltage to checkVoltage Method (only if is Solarflow device)\n if (isSolarFlow) {\n this.checkVoltage(totalVol);\n }\n }\n\n if (x.soh) {\n await this.adapter?.extendObject(key + \".soh\", {\n type: \"state\",\n common: {\n name: {\n de: \"Gesundheitszustand\",\n en: \"State of Health\",\n },\n type: \"number\",\n desc: \"State of Health\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"%\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".soh\", x.soh / 10, true);\n }\n\n if (x.power) {\n await this.adapter?.extendObject(key + \".power\", {\n type: \"state\",\n common: {\n name: {\n de: \"Energie\",\n en: \"Power\",\n },\n type: \"number\",\n desc: \"Power\",\n read: true,\n write: false,\n role: \"value.power\",\n unit: \"W\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".power\", x.power, true);\n }\n\n // Debug, send message if property is unknown!\n let found = false;\n\n Object.entries(x).forEach(([key, value]) => {\n knownPackDataProperties.forEach((property: string) => {\n if (property == key) {\n found = true;\n }\n });\n\n if (found) {\n //console.log(\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\n //);\n } else {\n this.adapter?.log.debug(\n `[addOrUpdatePackData] ${key} with value ${value} is a UNKNOWN PackData Mqtt Property!`,\n );\n }\n });\n }\n });\n }\n };\n\n public async checkVoltage(voltage: number): Promise<void> {\n if (voltage < 46.1) {\n if (this.adapter.config.useCalculation) {\n this.setSocToZero();\n }\n\n if (this.adapter.config.useLowVoltageBlock) {\n // Activate Low Voltage Block\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n true,\n true,\n );\n\n // Low Voltage Block activated, stop power input immediately\n const autoModel = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".autoModel\",\n )\n )?.val;\n if (autoModel == 8) {\n this.setDeviceAutomationInOutLimit(0);\n } else {\n this.setOutputLimit(0);\n }\n\n if (this.adapter.config.forceShutdownOnLowVoltage) {\n const currentSoc = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.electricLevel`,\n );\n\n if (currentSoc && Number(currentSoc.val) > 50) {\n // We can't shut down the device. Full charge needed!\n if (this.adapter.config.fullChargeIfNeeded) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.fullChargeNeeded`,\n true,\n true,\n );\n }\n } else {\n if (currentSoc && currentSoc.val) {\n this.setDischargeLimit(Number(currentSoc.val));\n }\n\n // Check if device setting is correct\n const hubState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.hubState`,\n );\n\n if (!hubState || Number(hubState.val) != 1) {\n this.adapter.log.warn(\n `[checkVoltage] hubState is not set to 'Stop output and shut down', device will NOT go offline!`,\n );\n }\n }\n }\n }\n } else if (voltage >= 47.5) {\n // Deactivate Low Voltage Block\n const lowVoltageBlock = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n );\n\n if (lowVoltageBlock && lowVoltageBlock.val == true) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n false,\n true,\n );\n\n if (\n this.adapter.config.useLowVoltageBlock &&\n this.adapter.config.forceShutdownOnLowVoltage\n ) {\n this.setDischargeLimit(\n this.adapter.config.dischargeLimit\n ? this.adapter.config.dischargeLimit\n : 5,\n );\n }\n }\n }\n }\n\n /**\n * Calculates the energy for all items in 'calculationStateKeys'.\n *\n * @returns Promise<void>\n *\n * @beta\n */\n public calculateEnergy(): void {\n calculationStateKeys.forEach(async (stateKey) => {\n let stateNameEnergyWh = \"\";\n let stateNameEnergykWh = \"\";\n let stateNamePower = \"\";\n\n switch (stateKey) {\n case \"pvPower1\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower1`;\n break;\n case \"pvPower2\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower2`;\n break;\n case \"pvPower3\":\n const pvPower3StateDef = this.states.find(\n (x) => x.title == \"pvPower3\",\n );\n if (pvPower3StateDef) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower3`;\n }\n break;\n case \"pvPower4\":\n const pvPower4StateDef = this.states.find(\n (x) => x.title == \"pvPower4\",\n );\n if (pvPower4StateDef) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower4`;\n }\n break;\n default:\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.${stateKey}Power`;\n break;\n }\n\n if (stateNamePower != \"\") {\n // If stateNamePower found, proceed with calculation, otherwise skip this stateKey\n this.adapter.log.debug(\n `[calculateEnergy] No stateNamePower found for ${stateKey}!`,\n );\n const currentPowerState =\n await this.adapter?.getStateAsync(stateNamePower);\n\n const currentEnergyState =\n await this.adapter?.getStateAsync(stateNameEnergyWh);\n\n if (!currentEnergyState?.val || currentEnergyState?.val == 0) {\n // Workaround, set Val to very low value to avoid Jump in data...\n await this.adapter?.setState(stateNameEnergyWh, 0.000001, true);\n } else if (\n currentEnergyState &&\n currentEnergyState.lc &&\n currentPowerState &&\n currentPowerState.val != undefined &&\n currentPowerState.val != null\n ) {\n // Timeframe = 30000ms, Job runs every 30 seconds...\n const timeFrame = 30000;\n\n // Calculate Energy value (Wh) from current power in the timeframe from last run...\n const addEnergyValue =\n (Number(currentPowerState.val) * timeFrame) / 3600000; // Wh\n\n /* // Use efficiency factor (used the one from Youtube Channel VoltAmpereLux - thanks!)\n const chargingFactor = 0.96; // Efficiency 96%\n const dischargingFactor = 1.08 - addEnergyValue / 10000; // Efficiency 92% - 98% (92% + Energy / 10000 = 600W -> +6%)\n\n // Calculate energy from efficiency factor if value for charging or discharging\n addEnergyValue =\n stateKey == \"outputPack\" && addEnergyValue > 0\n ? addEnergyValue * chargingFactor\n : addEnergyValue;\n addEnergyValue =\n stateKey == \"packInput\" && addEnergyValue > 0\n ? addEnergyValue * dischargingFactor\n : addEnergyValue; */\n\n let newEnergyValue = Number(currentEnergyState.val) + addEnergyValue;\n\n // Fix negative value\n if (newEnergyValue < 0) {\n newEnergyValue = 0;\n }\n\n await this.adapter?.setState(stateNameEnergyWh, newEnergyValue, true);\n await this.adapter?.setState(\n stateNameEnergykWh,\n Number((newEnergyValue / 1000).toFixed(2)),\n true,\n );\n\n // SOC and energy in batteries\n if (\n (stateKey == \"outputPack\" || stateKey == \"packInput\") &&\n addEnergyValue > 0\n ) {\n await this.calculateSocAndEnergy(stateKey, addEnergyValue);\n } else {\n if (stateKey == \"outputPack\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n } else if (stateKey == \"packInput\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n }\n }\n } else if (currentPowerState && currentEnergyState) {\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\n }\n }\n });\n }\n\n public calculateSocAndEnergy = async (\n stateKey: string,\n value: number,\n ): Promise<void> => {\n this.adapter.log.debug(\n `[calculateSocAndEnergy] Calculating for: ${this.productKey}.${this.deviceKey} and stateKey ${stateKey}!`,\n );\n\n let energyWhMax: number | undefined = undefined;\n\n const minSoc = (\n await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.minSoc`,\n )\n )?.val;\n const currentSoc = (\n await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.electricLevel`,\n )\n )?.val;\n\n if (currentSoc && minSoc && Number(currentSoc) < Number(minSoc)) {\n // Don't calculate if current SOC is lower then minimum\n this.adapter.log.debug(\n `[calculateSocAndEnergy] Don't calculate, currentSoc (${Number(currentSoc)}) is lower than minSoc (${Number(minSoc)})!`,\n );\n\n return;\n }\n\n const currentEnergyState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWh\",\n );\n\n const currentEnergyMaxState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWhMax\",\n );\n\n const lowVoltageBlock = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.lowVoltageBlock\",\n );\n\n const currentMaxValue = Number(\n currentEnergyMaxState ? currentEnergyMaxState.val : 0,\n );\n\n let currentEnergyWh = currentEnergyState?.val\n ? Number(currentEnergyState?.val)\n : 0;\n\n if (\n currentEnergyWh == null ||\n currentEnergyWh == undefined ||\n currentEnergyWh <= 0\n ) {\n currentEnergyWh = 0;\n }\n\n if (this.productKey == \"yWF7hV\") {\n // The device is an AIO 2400, so set maximum Wh to 2400!\n energyWhMax = 2400;\n } else {\n // Iterate over all batteries!\n for (let i = 0; i < this.batteries.length; i++) {\n if (this.batteries[i].type == \"AB1000\") {\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 960;\n } else if (this.batteries[i].type == \"AB2000\") {\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 1920;\n }\n }\n }\n\n // newValue is the current available energy in the batteries. If outputPack (charging) add value, if packInput (discharging) subtract value.\n let newEnergyWh =\n stateKey == \"outputPack\"\n ? currentEnergyWh + value\n : currentEnergyWh - value;\n\n // If greater than Max of batteries, set it to this value.\n if (\n stateKey == \"outputPack\" &&\n energyWhMax != undefined &&\n newEnergyWh > energyWhMax\n ) {\n newEnergyWh = energyWhMax;\n\n this.adapter.log.debug(\n `[calculateSocAndEnergy] newEnergyWh (${newEnergyWh}) is greater than energyWhMax (${energyWhMax}), don't extend value!`,\n );\n }\n\n if (newEnergyWh > 0) {\n this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n newEnergyWh,\n true,\n );\n\n this.adapter.log.debug(\n `[calculateSocAndEnergy] set '${this.productKey}.${this.deviceKey}.calculations.energyWh' to ${newEnergyWh}!`,\n );\n\n if (currentEnergyMaxState) {\n const soc = Number(((newEnergyWh / currentMaxValue) * 100).toFixed(1));\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.soc`,\n soc > 100.0 ? 100 : soc,\n true,\n );\n\n if (newEnergyWh > currentMaxValue && !lowVoltageBlock?.val) {\n // Extend maxVal\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n newEnergyWh,\n true,\n );\n }\n\n const currentOutputPackPower = await this.adapter?.getStateAsync(\n `${this.productKey}.${this.deviceKey}.outputPackPower`,\n );\n\n const currentPackInputPower = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".packInputPower\",\n );\n\n if (\n stateKey == \"outputPack\" &&\n currentOutputPackPower?.val != null &&\n currentOutputPackPower != undefined\n ) {\n // Charging, calculate remaining charging time\n const toCharge = currentMaxValue - newEnergyWh;\n\n const remainHoursAsDecimal =\n toCharge / Number(currentOutputPackPower.val);\n\n if (remainHoursAsDecimal < 48.0) {\n const remainFormatted = toHoursAndMinutes(\n Math.round(remainHoursAsDecimal * 60),\n );\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n remainFormatted,\n true,\n );\n } else {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n }\n } else if (\n stateKey == \"packInput\" &&\n currentPackInputPower != null &&\n currentPackInputPower != undefined\n ) {\n // Discharging, calculate remaining discharge time\n const remainHoursAsDecimal =\n newEnergyWh / Number(currentPackInputPower.val);\n const remainFormatted = toHoursAndMinutes(\n Math.round(remainHoursAsDecimal * 60),\n );\n\n if (remainHoursAsDecimal < 48.0) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n remainFormatted,\n true,\n );\n } else {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n }\n }\n }\n } else if (newEnergyWh <= 0 && stateKey == \"outputPack\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n } else if (newEnergyWh <= 0 && stateKey == \"packInput\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n\n // TEST: if SOC == 0, add newValue as positive to energyWhMax\n const newEnergyWhPositive = Math.abs(newEnergyWh);\n\n if (energyWhMax && currentMaxValue + newEnergyWhPositive <= energyWhMax) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n currentMaxValue + newEnergyWhPositive,\n true,\n );\n }\n }\n };\n\n public async setSocToZero(): Promise<void> {\n // Set SOC to 0\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.soc`,\n 0,\n true,\n );\n\n // Calculate new Wh Max Value\n const energyWhState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n );\n const energyWhMaxState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n );\n\n const newMax = Number(energyWhMaxState?.val) - Number(energyWhState?.val);\n\n // Set Max Energy to value minus current energy\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n newMax,\n true,\n );\n\n // Set Energy in Battery to 0\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n 0,\n true,\n );\n }\n\n public async setEnergyWhMax(): Promise<void> {\n const currentEnergyState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWh\",\n );\n\n if (currentEnergyState) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n currentEnergyState?.val,\n true,\n );\n }\n }\n\n public resetValuesForDevice(): void {\n calculationStateKeys.forEach(async (stateKey: string) => {\n let stateNameEnergyWh = \"\";\n let stateNameEnergykWh = \"\";\n\n switch (stateKey) {\n case \"pvPower1\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n break;\n case \"pvPower2\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n break;\n case \"pvPower3\":\n if (this.states.find((x) => x.title == \"pvPower3\")) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodaykWh`;\n }\n break;\n case \"pvPower4\":\n if (this.states.find((x) => x.title == \"pvPower4\")) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodaykWh`;\n }\n break;\n default:\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\n break;\n }\n\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createHash } from \"crypto\";\nimport { calculationStateKeys } from \"../../constants/constants\";\nimport { createCalculationStates } from \"../../helpers/createCalculationStates\";\nimport { toHoursAndMinutes } from \"../../helpers/timeHelper\";\nimport { ZendureSolarflow } from \"../../main\";\nimport {\n knownPackDataProperties,\n onSubscribeIotTopic,\n onSubscribeReportTopic,\n} from \"../../services/mqttSharedService\";\nimport { IDevicePack } from \"../IDevicePack\";\nimport { IPackData } from \"../IPackData\";\nimport { ISolarflowState } from \"../ISolarflowState\";\nimport { IZenHaDeviceDetails } from \"../IZenHaDeviceDetails\";\n\nexport class ZenHaDevice {\n public zenHaDeviceDetails?: IZenHaDeviceDetails;\n public adapter: ZendureSolarflow;\n\n public productKey: string;\n public deviceKey: string;\n public productName: string;\n public deviceName: string;\n public messageId: number = 0;\n public batteries: IDevicePack[] = [];\n\n public iotTopic: string = \"\";\n public functionTopic = \"\";\n public password: string = \"\";\n\n public maxInputLimit: number = 0;\n public maxOutputLimit: number = 0;\n\n public states: ISolarflowState[] = [];\n public controlStates: ISolarflowState[] = [];\n\n public constructor(\n _adapter: ZendureSolarflow,\n _productKey: string,\n _deviceKey: string,\n _productName: string,\n _deviceName: string,\n _zenHaDeviceDetails?: IZenHaDeviceDetails,\n ) {\n this.zenHaDeviceDetails = _zenHaDeviceDetails;\n this.adapter = _adapter;\n this.productKey = _productKey;\n this.deviceKey = _deviceKey;\n\n this.deviceName = _deviceName;\n this.productName = _productName;\n\n this.iotTopic = `iot/${_productKey}/${_deviceKey}/properties/write`;\n this.functionTopic = `iot/${_productKey}/${_deviceKey}/function/invoke`;\n\n // Calculate device password\n this.password = createHash(\"md5\")\n .update(_deviceKey, \"utf8\")\n .digest(\"hex\")\n .toUpperCase()\n .substring(8, 24);\n\n // Create or update states\n this.createSolarFlowStates();\n\n // Subscribe to report topic (get telemetry)\n this.subscribeReportTopic();\n\n // Subscribe to Iot topic (push control values)\n this.subscribeIotTopic();\n\n // Get complete data from device after a timeout\n this.adapter.setTimeout(() => {\n this.triggerFullTelemetryUpdate();\n }, 5000);\n\n if (this.zenHaDeviceDetails?.online) {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n } else if (this.zenHaDeviceDetails?.online == false) {\n this.updateSolarFlowState(\"wifiState\", \"Disconnected\");\n }\n }\n\n private async createSolarFlowStates(): Promise<void> {\n const productKey = this.productKey.replace(\n this.adapter.FORBIDDEN_CHARS,\n \"\",\n );\n const deviceKey = this.deviceKey.replace(this.adapter.FORBIDDEN_CHARS, \"\");\n\n this.adapter.log.debug(\n `[createSolarFlowStates] Creating or updating SolarFlow states for ${this.productName} (${productKey}/${deviceKey}) and name '${this.deviceName}'.`,\n );\n\n // Create device (e.g. the product type -> SolarFlow)\n await this.adapter?.extendObject(productKey, {\n type: \"device\",\n common: {\n name: {\n de: `${this.productName} (${productKey})`,\n en: `${this.productName} (${productKey})`,\n },\n },\n native: {},\n });\n\n // Create channel (e.g. the device specific key)\n await this.adapter?.extendObject(productKey + \".\" + deviceKey, {\n type: \"channel\",\n common: {\n name: {\n de: `${this.deviceName} (${deviceKey})`,\n en: `${this.deviceName} (${deviceKey})`,\n },\n },\n native: {},\n });\n\n // Create pack data folder\n await this.adapter?.extendObject(`${productKey}.${deviceKey}.packData`, {\n type: \"channel\",\n common: {\n name: {\n de: \"Batterie Packs\",\n en: \"Battery packs\",\n },\n },\n native: {},\n });\n\n // Create report states\n this.states.forEach(async (state: ISolarflowState) => {\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.${state.title}`,\n {\n type: \"state\",\n common: {\n name: {\n de: state.nameDe,\n en: state.nameEn,\n },\n type: state.type,\n desc: state.title,\n role: state.role,\n read: true,\n write: false,\n unit: state.unit,\n states: state.states,\n },\n native: {},\n },\n );\n });\n\n // Create control folder\n await this.adapter?.extendObject(`${productKey}.${deviceKey}.control`, {\n type: \"channel\",\n common: {\n name: {\n de: \"Steuerung f\u00FCr Ger\u00E4t \" + deviceKey,\n en: \"Control for device \" + deviceKey,\n },\n },\n native: {},\n });\n\n this.controlStates.forEach(async (state: ISolarflowState) => {\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.control.${state.title}`,\n {\n type: \"state\",\n common: {\n name: {\n de: state.nameDe,\n en: state.nameEn,\n },\n type: state.type,\n desc: state.title,\n role: state.role,\n read: true,\n write: true,\n unit: state.unit,\n states: state.states,\n },\n native: {},\n },\n );\n\n // Subscribe to states to respond to changes\n this.adapter?.subscribeStates(\n `${productKey}.${deviceKey}.control.${state.title}`,\n );\n });\n\n if (this.adapter.config.useCalculation) {\n // Create calculations folder\n await this.adapter?.extendObject(\n `${productKey}.${deviceKey}.calculations`,\n {\n type: \"channel\",\n common: {\n name: {\n de: \"Berechnungen f\u00FCr Ger\u00E4t \" + deviceKey,\n en: \"Calculations for Device \" + deviceKey,\n },\n },\n native: {},\n },\n );\n\n await createCalculationStates(this.adapter, productKey, deviceKey);\n }\n }\n\n public subscribeReportTopic(): void {\n const reportTopic = `/${this.productKey}/${this.deviceKey}/#`;\n\n if (this.adapter) {\n this.adapter.log.debug(\n `[subscribeReportTopic] Subscribing to MQTT Topic: ${reportTopic}`,\n );\n this.adapter.mqttClient?.subscribe(reportTopic, onSubscribeReportTopic);\n }\n }\n\n private subscribeIotTopic(): void {\n const iotTopic = `iot/${this.productKey}/${this.deviceKey}/#`;\n\n this.adapter?.log.debug(\n `[subscribeIotTopic] Subscribing to MQTT Topic: ${iotTopic}`,\n );\n this.adapter?.mqttClient?.subscribe(iotTopic, (error) => {\n onSubscribeIotTopic(error, this.productKey, this.deviceKey);\n });\n }\n\n public setDeviceAutomationInOutLimit(limit: number): void {\n this.adapter?.log.error(\n `[setAcMode] Method setDeviceAutomationInOutLimit (set to ${limit}) not defined in base class!`,\n );\n return;\n }\n\n public setAcMode(acMode: number): void {\n this.adapter?.log.error(\n `[setAcMode] Method setAcMode (set to ${acMode}) not defined in base class!`,\n );\n return;\n }\n\n public setDcSwitch(dcSwitch: boolean): void {\n this.adapter?.log.error(\n `[setAcMode] Method setDcSwitch (set to ${dcSwitch}) not defined in base class!`,\n );\n return;\n }\n\n public setAcSwitch(acSwitch: boolean): void {\n this.adapter?.log.error(\n `[setAcMode] Method setAcSwitch (set to ${acSwitch}) not defined in base class!`,\n );\n return;\n }\n\n public setHubState(hubState: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (hubState == 0 || hubState == 1) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const socSetLimit = { properties: { hubState: hubState } };\n this.adapter.log.debug(\n `[setHubState] Setting Hub State for deviceKey ${this.deviceKey} to ${hubState}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\n } else {\n this.adapter.log.debug(`[setHubState] Hub state is not 0 or 1!`);\n }\n }\n }\n\n public setPassMode(passMode: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const setPassModeContent = { properties: { passMode: passMode } };\n this.adapter.log.debug(\n `[setPassMode] Set passMode for deviceKey ${this.deviceKey} to ${passMode}!`,\n );\n this.adapter.mqttClient?.publish(\n topic,\n JSON.stringify(setPassModeContent),\n );\n }\n }\n\n public setAutoRecover(autoRecover: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const setAutoRecoverContent = {\n properties: { autoRecover: autoRecover ? 1 : 0 },\n };\n this.adapter.log.debug(\n `[setAutoRecover] Set autoRecover for deviceKey ${this.deviceKey} to ${autoRecover}!`,\n );\n this.adapter.mqttClient?.publish(\n topic,\n JSON.stringify(setAutoRecoverContent),\n );\n }\n }\n\n /**\n * Will set the discharge limit (minSoc)\n * @param socSet the desired minimum soc\n * @returns void\n */\n public setDischargeLimit(minSoc: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (minSoc >= 0 && minSoc <= 50) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/write`;\n\n const socSetLimit = { properties: { minSoc: minSoc * 10 } };\n this.adapter.log.debug(\n `[setDischargeLimit] Setting Discharge Limit for device key ${this.deviceKey} to ${minSoc}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\n } else {\n this.adapter.log.debug(\n `[setDischargeLimit] Discharge limit is not in range 0<>50!`,\n );\n }\n }\n }\n\n /**\n * Will set the maximum charge limit\n * @param socSet the desired max SOC\n * @returns void\n */\n public setChargeLimit(socSet: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n if (socSet >= 40 && socSet <= 100) {\n const socSetLimit = { properties: { socSet: socSet * 10 } };\n this.adapter.log.debug(\n `[setChargeLimit] Setting ChargeLimit for device key ${this.deviceKey} to ${socSet}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(socSetLimit),\n );\n } else {\n this.adapter.log.debug(\n `[setChargeLimit] Charge limit is not in range 40<>100!`,\n );\n }\n }\n }\n\n /**\n * Will set the 'energy plan'\n * @param autoModel autoModel value, like 8 for smart matching\n * @returns void\n */\n public setAutoModel(autoModel: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n let setAutoModelContent: any = { properties: { autoModel: autoModel } };\n\n switch (autoModel) {\n case 8: {\n // Smart Matching Modus\n setAutoModelContent = {\n properties: {\n autoModelProgram: 1,\n autoModelValue: {\n chargingType: 0,\n chargingPower: 0,\n outPower: 0,\n },\n msgType: 1,\n autoModel: 8,\n },\n };\n break;\n }\n case 9: // Smart CT Modus\n setAutoModelContent = {\n properties: {\n autoModelProgram: 2,\n autoModelValue: {\n chargingType: 3,\n chargingPower: 0,\n outPower: 0,\n },\n msgType: 1,\n autoModel: 9,\n },\n };\n break;\n }\n\n this.adapter.log.debug(\n `[setAutoModel] Setting autoModel for device key ${this.deviceKey} to ${autoModel}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setAutoModelContent),\n );\n }\n }\n\n public async setOutputLimit(limit: number): Promise<void> {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n // Check if autoModel is set to 0 (Nothing) or 8 (Smart Matching)\n const autoModel = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".autoModel\",\n )\n )?.val;\n\n if (autoModel != 0) {\n this.adapter.log.warn(\n \"Operation mode (autoModel) is not set to '0', we can't set the output limit!\",\n );\n return;\n }\n\n if (limit) {\n limit = Math.round(limit);\n } else {\n limit = 0;\n }\n\n // Limit to the device max limit\n if (limit > this.maxOutputLimit) {\n limit = this.maxOutputLimit;\n }\n\n if (\n limit < 100 &&\n limit != 90 &&\n limit != 60 &&\n limit != 30 &&\n limit != 0 &&\n (this.productKey == \"73bktv\" || this.productKey == \"a8yh63\")\n ) {\n // NUR Solarflow HUB: Das Limit kann unter 100 nur in 30er Schritten gesetzt werden, dH. 30/60/90/100, wir rechnen das also um\n if (limit < 100 && limit > 90) {\n limit = 90;\n } else if (limit > 60 && limit < 90) {\n limit = 60;\n } else if (limit > 30 && limit < 60) {\n limit = 30;\n } else if (limit < 30) {\n limit = 30;\n }\n }\n\n if (this.adapter.config.useLowVoltageBlock) {\n const lowVoltageBlockState = await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.lowVoltageBlock\",\n );\n if (\n lowVoltageBlockState &&\n lowVoltageBlockState.val &&\n lowVoltageBlockState.val == true\n ) {\n limit = 0;\n }\n\n const fullChargeNeeded = await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.fullChargeNeeded\",\n );\n\n if (\n fullChargeNeeded &&\n fullChargeNeeded.val &&\n fullChargeNeeded.val == true\n ) {\n limit = 0;\n }\n }\n\n const currentLimit = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".outputLimit\",\n )\n )?.val;\n\n if (currentLimit != null && currentLimit != undefined) {\n if (currentLimit != limit) {\n const outputlimit = { properties: { outputLimit: limit } };\n\n this.messageId += 1;\n\n const timestamp = new Date();\n timestamp.setMilliseconds(0);\n\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(outputlimit),\n );\n }\n }\n }\n }\n\n public setInputLimit(limit: number): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n // Limit has always to be positive!\n if (limit < 0) {\n this.adapter.log.debug(\n `[setInputLimit] limit ${limit} is negative, converting to positive!`,\n );\n limit = Math.abs(limit);\n }\n\n if (limit) {\n limit = Math.round(limit);\n } else {\n limit = 0;\n }\n\n if (limit < 0) {\n limit = 0;\n } else if (limit > 0 && limit <= 30) {\n limit = 30;\n } else if (limit > this.maxInputLimit) {\n limit = this.maxInputLimit;\n }\n\n if (this.productKey.includes(\"8bm93h\")) {\n // Das Limit kann beim ACE nur in 100er Schritten gesetzt werden\n limit = Math.ceil(limit / 100) * 100;\n }\n\n const inputLimitContent = { properties: { inputLimit: limit } };\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(inputLimitContent),\n );\n }\n }\n\n public setSmartMode(smartModeOn: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const setSmartModeContent = {\n properties: { smartMode: smartModeOn ? 1 : 0 },\n };\n\n this.adapter.log.debug(\n `[setBuzzer] Setting Smart Mode for device key ${this.deviceKey} to ${smartModeOn}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setSmartModeContent),\n );\n }\n }\n\n public setBuzzerSwitch(buzzerOn: boolean): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const setBuzzerSwitchContent = {\n properties: { buzzerSwitch: buzzerOn ? 1 : 0 },\n };\n this.adapter.log.debug(\n `[setBuzzer] Setting Buzzer for device key ${this.deviceKey} to ${buzzerOn}!`,\n );\n this.adapter.mqttClient?.publish(\n this.iotTopic,\n JSON.stringify(setBuzzerSwitchContent),\n );\n }\n }\n\n public triggerFullTelemetryUpdate(): void {\n if (this.adapter.mqttClient && this.productKey && this.deviceKey) {\n const topic = `iot/${this.productKey}/${this.deviceKey}/properties/read`;\n\n const getAllContent = { properties: [\"getAll\"] };\n this.adapter.log.debug(\n `[triggerFullTelemetryUpdate] Triggering full telemetry update for device key ${this.deviceKey}!`,\n );\n this.adapter.mqttClient?.publish(topic, JSON.stringify(getAllContent));\n }\n }\n\n public async updateSolarFlowState(\n state: string,\n val: number | string | boolean,\n ): Promise<void> {\n const currentValue = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.${state}`,\n );\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.${state}`,\n val,\n true,\n );\n\n if (currentValue?.val != val && state != \"wifiState\") {\n // Set lastUpdate for deviceKey if a value was changed!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n }\n\n public async updateSolarFlowControlState(\n state: string,\n val: number | string | boolean,\n ): Promise<void> {\n // First check if state exist\n const stateExist = await this.adapter?.objectExists(\n `${this.productKey}.${this.deviceKey}.control.${state}`,\n );\n\n // Update the control state\n if (stateExist) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.${state}`,\n val,\n true,\n );\n }\n }\n\n addOrUpdatePackData = async (\n packData: IPackData[],\n isSolarFlow: boolean,\n ): Promise<void> => {\n if (this.adapter && this.productKey && this.deviceKey) {\n await packData.forEach(async (x) => {\n // Process data only with a serial id!\n if (x.sn && this.adapter) {\n // Create channel (e.g. the device specific key)\n // We can determine the type of the battery by the SN number.\n let batType = \"\";\n if (this.productKey == \"yWF7hV\") {\n batType = \"AIO2400\";\n } else if (x.sn.startsWith(\"A\")) {\n batType = \"AB1000\";\n } else if (x.sn.startsWith(\"B\")) {\n batType = \"AB1000S\";\n } else if (x.sn.startsWith(\"C\")) {\n if (x.sn[3] == \"F\") {\n batType = \"AB2000S\";\n } else if (x.sn[3] == \"E\") {\n batType = \"AB2000X\";\n } else {\n batType = \"AB2000\";\n }\n } else if (x.sn.startsWith(\"F\")) {\n batType = \"AB3000X\";\n }\n\n // Check if is in Pack2device list\n if (!this.batteries.some((y) => y.packSn == x.sn)) {\n this.batteries.push({\n packSn: x.sn,\n type: batType,\n });\n\n this.adapter.log.debug(\n `[addOrUpdatePackData] Added battery ${batType} with SN ${x.sn} on deviceKey ${this.deviceKey} to batteries array!`,\n );\n }\n\n // create a state for the serial id\n const key = (\n this.productKey +\n \".\" +\n this.deviceKey +\n \".packData.\" +\n x.sn\n ).replace(this.adapter.FORBIDDEN_CHARS, \"\");\n\n await this.adapter?.extendObject(key, {\n type: \"channel\",\n common: {\n name: {\n de: batType,\n en: batType,\n },\n },\n native: {},\n });\n\n await this.adapter?.extendObject(key + \".model\", {\n type: \"state\",\n common: {\n name: {\n de: \"Batterietyp\",\n en: \"Battery type\",\n },\n type: \"string\",\n desc: \"model\",\n role: \"value\",\n read: true,\n write: false,\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".model\", batType, true);\n\n await this.adapter?.extendObject(key + \".sn\", {\n type: \"state\",\n common: {\n name: {\n de: \"Seriennummer\",\n en: \"Serial id\",\n },\n type: \"string\",\n desc: \"Serial ID\",\n role: \"value\",\n read: true,\n write: false,\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".sn\", x.sn, true);\n\n if (x.socLevel) {\n // State f\u00FCr socLevel\n await this.adapter?.extendObject(key + \".socLevel\", {\n type: \"state\",\n common: {\n name: {\n de: \"SOC der Batterie\",\n en: \"soc of battery\",\n },\n type: \"number\",\n desc: \"SOC Level\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"%\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".socLevel\", x.socLevel, true);\n }\n\n if (x.maxTemp) {\n const maxTempCelsius = x.maxTemp / 10 - 273.15;\n const maxTempState = await this.adapter?.getStateAsync(\n key + \".maxTemp\",\n );\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (\n maxTempState &&\n maxTempState.val &&\n maxTempCelsius != maxTempState.val\n ) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n // State f\u00FCr maxTemp\n await this.adapter?.extendObject(key + \".maxTemp\", {\n type: \"state\",\n common: {\n name: {\n de: \"Max. Temperatur der Batterie\",\n en: \"max temp. of battery\",\n },\n type: \"number\",\n desc: \"Max. Temp\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"\u00B0C\",\n },\n native: {},\n });\n\n // Convert Kelvin to Celsius\n await this.adapter?.setState(\n key + \".maxTemp\",\n maxTempCelsius,\n true,\n );\n }\n\n if (x.minVol) {\n const minVol = x.minVol / 100;\n const minVolState = await this.adapter?.getStateAsync(\n key + \".minVol\",\n );\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (minVolState && minVolState.val && minVol != minVolState.val) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".minVol\", {\n type: \"state\",\n common: {\n name: \"minVol\",\n type: \"number\",\n desc: \"minVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".minVol\", minVol, true);\n }\n\n if (x.batcur) {\n await this.adapter?.extendObject(key + \".batcur\", {\n type: \"state\",\n common: {\n name: \"batcur\",\n type: \"number\",\n desc: \"batcur\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"A\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".batcur\", x.batcur / 10, true);\n }\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (x.maxVol) {\n const maxVol = x.maxVol / 100;\n const maxVolState = await this.adapter?.getStateAsync(\n key + \".maxVol\",\n );\n\n if (maxVolState && maxVolState.val && maxVol != maxVolState.val) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".maxVol\", {\n type: \"state\",\n common: {\n name: \"maxVol\",\n type: \"number\",\n desc: \"maxVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".maxVol\", maxVol, true);\n }\n\n // Check if Value exist and changed, if so update lastUpdate!\n if (x.totalVol) {\n const totalVol = x.totalVol / 100;\n\n const totalVolState = await this.adapter?.getStateAsync(\n key + \".totalVol\",\n );\n\n if (\n totalVolState &&\n totalVolState.val &&\n totalVol != totalVolState.val\n ) {\n // Value exist and value changed, update last update!\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.lastUpdate`,\n new Date().getTime(),\n true,\n );\n\n // Check current wifiState, if Disconnected set it to Connected!\n const currentWifiState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.wifiState`,\n );\n\n if (currentWifiState && currentWifiState.val == \"Disconnected\") {\n this.updateSolarFlowState(\"wifiState\", \"Connected\");\n }\n }\n\n await this.adapter?.extendObject(key + \".totalVol\", {\n type: \"state\",\n common: {\n name: \"totalVol\",\n type: \"number\",\n desc: \"totalVol\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"V\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".totalVol\", totalVol, true);\n\n // Send Voltage to checkVoltage Method (only if is Solarflow device)\n if (isSolarFlow) {\n this.checkVoltage(totalVol);\n }\n }\n\n if (x.soh) {\n await this.adapter?.extendObject(key + \".soh\", {\n type: \"state\",\n common: {\n name: {\n de: \"Gesundheitszustand\",\n en: \"State of Health\",\n },\n type: \"number\",\n desc: \"State of Health\",\n role: \"value\",\n read: true,\n write: false,\n unit: \"%\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".soh\", x.soh / 10, true);\n }\n\n if (x.power) {\n await this.adapter?.extendObject(key + \".power\", {\n type: \"state\",\n common: {\n name: {\n de: \"Energie\",\n en: \"Power\",\n },\n type: \"number\",\n desc: \"Power\",\n read: true,\n write: false,\n role: \"value.power\",\n unit: \"W\",\n },\n native: {},\n });\n\n await this.adapter?.setState(key + \".power\", x.power, true);\n }\n\n // Debug, send message if property is unknown!\n let found = false;\n\n Object.entries(x).forEach(([key, value]) => {\n knownPackDataProperties.forEach((property: string) => {\n if (property == key) {\n found = true;\n }\n });\n\n if (found) {\n //console.log(\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\n //);\n } else {\n this.adapter?.log.debug(\n `[addOrUpdatePackData] ${key} with value ${value} is a UNKNOWN PackData Mqtt Property!`,\n );\n }\n });\n }\n });\n }\n };\n\n public async checkVoltage(voltage: number): Promise<void> {\n if (voltage < 46.1) {\n if (this.adapter.config.useCalculation) {\n this.setSocToZero();\n }\n\n if (this.adapter.config.useLowVoltageBlock) {\n // Activate Low Voltage Block\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n true,\n true,\n );\n\n // Low Voltage Block activated, stop power input immediately\n const autoModel = (\n await this.adapter.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".autoModel\",\n )\n )?.val;\n if (autoModel == 8) {\n this.setDeviceAutomationInOutLimit(0);\n } else {\n this.setOutputLimit(0);\n }\n\n if (this.adapter.config.forceShutdownOnLowVoltage) {\n const currentSoc = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.electricLevel`,\n );\n\n if (currentSoc && Number(currentSoc.val) > 50) {\n // We can't shut down the device. Full charge needed!\n if (this.adapter.config.fullChargeIfNeeded) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.fullChargeNeeded`,\n true,\n true,\n );\n }\n } else {\n if (currentSoc && currentSoc.val) {\n this.setDischargeLimit(Number(currentSoc.val));\n }\n\n // Check if device setting is correct\n const hubState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.hubState`,\n );\n\n if (!hubState || Number(hubState.val) != 1) {\n this.adapter.log.warn(\n `[checkVoltage] hubState is not set to 'Stop output and shut down', device will NOT go offline!`,\n );\n }\n }\n }\n }\n } else if (voltage >= 47.5) {\n // Deactivate Low Voltage Block\n const lowVoltageBlock = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n );\n\n if (lowVoltageBlock && lowVoltageBlock.val == true) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.control.lowVoltageBlock`,\n false,\n true,\n );\n\n if (\n this.adapter.config.useLowVoltageBlock &&\n this.adapter.config.forceShutdownOnLowVoltage\n ) {\n this.setDischargeLimit(\n this.adapter.config.dischargeLimit\n ? this.adapter.config.dischargeLimit\n : 5,\n );\n }\n }\n }\n }\n\n /**\n * Calculates the energy for all items in 'calculationStateKeys'.\n *\n * @returns Promise<void>\n *\n * @beta\n */\n public calculateEnergy(): void {\n calculationStateKeys.forEach(async (stateKey) => {\n let stateNameEnergyWh = \"\";\n let stateNameEnergykWh = \"\";\n let stateNamePower = \"\";\n\n switch (stateKey) {\n case \"pvPower1\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower1`;\n break;\n case \"pvPower2\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower2`;\n break;\n case \"pvPower3\":\n const pvPower3StateDef = this.states.find(\n (x) => x.title == \"pvPower3\",\n );\n if (pvPower3StateDef) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower3`;\n }\n break;\n case \"pvPower4\":\n const pvPower4StateDef = this.states.find(\n (x) => x.title == \"pvPower4\",\n );\n if (pvPower4StateDef) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.pvPower4`;\n }\n break;\n default:\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\n stateNamePower = `${this.productKey}.${this.deviceKey}.${stateKey}Power`;\n break;\n }\n\n if (stateNamePower != \"\") {\n // If stateNamePower found, proceed with calculation, otherwise skip this stateKey\n this.adapter.log.debug(\n `[calculateEnergy] No stateNamePower found for ${stateKey}!`,\n );\n const currentPowerState =\n await this.adapter?.getStateAsync(stateNamePower);\n\n const currentEnergyState =\n await this.adapter?.getStateAsync(stateNameEnergyWh);\n\n if (!currentEnergyState?.val || currentEnergyState?.val == 0) {\n // Workaround, set Val to very low value to avoid Jump in data...\n await this.adapter?.setState(stateNameEnergyWh, 0.000001, true);\n } else if (\n currentEnergyState &&\n currentEnergyState.lc &&\n currentPowerState &&\n currentPowerState.val != undefined &&\n currentPowerState.val != null\n ) {\n // Timeframe = 30000ms, Job runs every 30 seconds...\n const timeFrame = 30000;\n\n // Calculate Energy value (Wh) from current power in the timeframe from last run...\n const addEnergyValue =\n (Number(currentPowerState.val) * timeFrame) / 3600000; // Wh\n\n /* // Use efficiency factor (used the one from Youtube Channel VoltAmpereLux - thanks!)\n const chargingFactor = 0.96; // Efficiency 96%\n const dischargingFactor = 1.08 - addEnergyValue / 10000; // Efficiency 92% - 98% (92% + Energy / 10000 = 600W -> +6%)\n\n // Calculate energy from efficiency factor if value for charging or discharging\n addEnergyValue =\n stateKey == \"outputPack\" && addEnergyValue > 0\n ? addEnergyValue * chargingFactor\n : addEnergyValue;\n addEnergyValue =\n stateKey == \"packInput\" && addEnergyValue > 0\n ? addEnergyValue * dischargingFactor\n : addEnergyValue; */\n\n let newEnergyValue = Number(currentEnergyState.val) + addEnergyValue;\n\n // Fix negative value\n if (newEnergyValue < 0) {\n newEnergyValue = 0;\n }\n\n await this.adapter?.setState(stateNameEnergyWh, newEnergyValue, true);\n await this.adapter?.setState(\n stateNameEnergykWh,\n Number((newEnergyValue / 1000).toFixed(2)),\n true,\n );\n\n // SOC and energy in batteries\n if (\n (stateKey == \"outputPack\" || stateKey == \"packInput\") &&\n addEnergyValue > 0\n ) {\n await this.calculateSocAndEnergy(stateKey, addEnergyValue);\n } else {\n if (stateKey == \"outputPack\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n } else if (stateKey == \"packInput\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n }\n }\n } else if (currentPowerState && currentEnergyState) {\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\n }\n }\n });\n }\n\n public calculateSocAndEnergy = async (\n stateKey: string,\n value: number,\n ): Promise<void> => {\n this.adapter.log.debug(\n `[calculateSocAndEnergy] Calculating for: ${this.productKey}.${this.deviceKey} and stateKey ${stateKey}!`,\n );\n\n let energyWhMax: number | undefined = undefined;\n\n const minSoc = (\n await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.minSoc`,\n )\n )?.val;\n const currentSoc = (\n await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.electricLevel`,\n )\n )?.val;\n\n if (currentSoc && minSoc && Number(currentSoc) < Number(minSoc)) {\n // Don't calculate if current SOC is lower then minimum\n this.adapter.log.debug(\n `[calculateSocAndEnergy] Don't calculate, currentSoc (${Number(currentSoc)}) is lower than minSoc (${Number(minSoc)})!`,\n );\n\n return;\n }\n\n const currentEnergyState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWh\",\n );\n\n const currentEnergyMaxState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWhMax\",\n );\n\n const lowVoltageBlock = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".control.lowVoltageBlock\",\n );\n\n const currentMaxValue = Number(\n currentEnergyMaxState ? currentEnergyMaxState.val : 0,\n );\n\n let currentEnergyWh = currentEnergyState?.val\n ? Number(currentEnergyState?.val)\n : 0;\n\n if (\n currentEnergyWh == null ||\n currentEnergyWh == undefined ||\n currentEnergyWh <= 0\n ) {\n currentEnergyWh = 0;\n }\n\n if (this.productKey == \"yWF7hV\") {\n // The device is an AIO 2400, so set maximum Wh to 2400!\n energyWhMax = 2400;\n } else {\n // Iterate over all batteries!\n for (let i = 0; i < this.batteries.length; i++) {\n if (this.batteries[i].type.includes(\"AB1000\")) {\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 960;\n } else if (this.batteries[i].type.includes(\"AB2000\")) {\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 1920;\n } else if (this.batteries[i].type.includes(\"AB3000\")) {\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 2880;\n }\n }\n }\n\n // newValue is the current available energy in the batteries. If outputPack (charging) add value, if packInput (discharging) subtract value.\n let newEnergyWh =\n stateKey == \"outputPack\"\n ? currentEnergyWh + value\n : currentEnergyWh - value;\n\n // If greater than Max of batteries, set it to this value.\n if (\n stateKey == \"outputPack\" &&\n energyWhMax != undefined &&\n newEnergyWh > energyWhMax\n ) {\n newEnergyWh = energyWhMax;\n\n this.adapter.log.debug(\n `[calculateSocAndEnergy] newEnergyWh (${newEnergyWh}) is greater than energyWhMax (${energyWhMax}), don't extend value!`,\n );\n }\n\n if (newEnergyWh > 0) {\n this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n newEnergyWh,\n true,\n );\n\n this.adapter.log.debug(\n `[calculateSocAndEnergy] set '${this.productKey}.${this.deviceKey}.calculations.energyWh' to ${newEnergyWh}!`,\n );\n\n if (currentEnergyMaxState) {\n const soc = Number(((newEnergyWh / currentMaxValue) * 100).toFixed(1));\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.soc`,\n soc > 100.0 ? 100 : soc,\n true,\n );\n\n if (newEnergyWh > currentMaxValue && !lowVoltageBlock?.val) {\n // Extend maxVal\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n newEnergyWh,\n true,\n );\n }\n\n const currentOutputPackPower = await this.adapter?.getStateAsync(\n `${this.productKey}.${this.deviceKey}.outputPackPower`,\n );\n\n const currentPackInputPower = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".packInputPower\",\n );\n\n if (\n stateKey == \"outputPack\" &&\n currentOutputPackPower?.val != null &&\n currentOutputPackPower != undefined\n ) {\n // Charging, calculate remaining charging time\n const toCharge = currentMaxValue - newEnergyWh;\n\n const remainHoursAsDecimal =\n toCharge / Number(currentOutputPackPower.val);\n\n if (remainHoursAsDecimal < 48.0) {\n const remainFormatted = toHoursAndMinutes(\n Math.round(remainHoursAsDecimal * 60),\n );\n\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n remainFormatted,\n true,\n );\n } else {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n }\n } else if (\n stateKey == \"packInput\" &&\n currentPackInputPower != null &&\n currentPackInputPower != undefined\n ) {\n // Discharging, calculate remaining discharge time\n const remainHoursAsDecimal =\n newEnergyWh / Number(currentPackInputPower.val);\n const remainFormatted = toHoursAndMinutes(\n Math.round(remainHoursAsDecimal * 60),\n );\n\n if (remainHoursAsDecimal < 48.0) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n remainFormatted,\n true,\n );\n } else {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n }\n }\n }\n } else if (newEnergyWh <= 0 && stateKey == \"outputPack\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainInputTime`,\n \"\",\n true,\n );\n } else if (newEnergyWh <= 0 && stateKey == \"packInput\") {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.remainOutTime`,\n \"\",\n true,\n );\n\n // TEST: if SOC == 0, add newValue as positive to energyWhMax\n const newEnergyWhPositive = Math.abs(newEnergyWh);\n\n if (energyWhMax && currentMaxValue + newEnergyWhPositive <= energyWhMax) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n currentMaxValue + newEnergyWhPositive,\n true,\n );\n }\n }\n };\n\n public async setSocToZero(): Promise<void> {\n // Set SOC to 0\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.soc`,\n 0,\n true,\n );\n\n // Calculate new Wh Max Value\n const energyWhState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n );\n const energyWhMaxState = await this.adapter.getStateAsync(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n );\n\n const newMax = Number(energyWhMaxState?.val) - Number(energyWhState?.val);\n\n // Set Max Energy to value minus current energy\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n newMax,\n true,\n );\n\n // Set Energy in Battery to 0\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWh`,\n 0,\n true,\n );\n }\n\n public async setEnergyWhMax(): Promise<void> {\n const currentEnergyState = await this.adapter?.getStateAsync(\n this.productKey + \".\" + this.deviceKey + \".calculations.energyWh\",\n );\n\n if (currentEnergyState) {\n await this.adapter?.setState(\n `${this.productKey}.${this.deviceKey}.calculations.energyWhMax`,\n currentEnergyState?.val,\n true,\n );\n }\n }\n\n public resetValuesForDevice(): void {\n calculationStateKeys.forEach(async (stateKey: string) => {\n let stateNameEnergyWh = \"\";\n let stateNameEnergykWh = \"\";\n\n switch (stateKey) {\n case \"pvPower1\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n break;\n case \"pvPower2\":\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n break;\n case \"pvPower3\":\n if (this.states.find((x) => x.title == \"pvPower3\")) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv3EnergyTodaykWh`;\n } else {\n return;\n }\n break;\n case \"pvPower4\":\n if (this.states.find((x) => x.title == \"pvPower4\")) {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv4EnergyTodaykWh`;\n } else {\n return;\n }\n break;\n default:\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\n break;\n }\n\n if (stateNameEnergyWh != \"\" && stateNameEnergykWh != \"\") {\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\n }\n });\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2B;AAC3B,uBAAqC;AACrC,qCAAwC;AACxC,wBAAkC;AAElC,+BAIO;AAMA,MAAM,YAAY;AAAA,EAqBhB,YACL,UACA,aACA,YACA,cACA,aACA,qBACA;AApBF,SAAO,YAAoB;AAC3B,SAAO,YAA2B,CAAC;AAEnC,SAAO,WAAmB;AAC1B,SAAO,gBAAgB;AACvB,SAAO,WAAmB;AAE1B,SAAO,gBAAwB;AAC/B,SAAO,iBAAyB;AAEhC,SAAO,SAA4B,CAAC;AACpC,SAAO,gBAAmC,CAAC;AA6lB3C,+BAAsB,OACpB,UACA,gBACkB;AAClB,UAAI,KAAK,WAAW,KAAK,cAAc,KAAK,WAAW;AACrD,cAAM,SAAS,QAAQ,OAAO,MAAM;AApoB1C;AAsoBQ,cAAI,EAAE,MAAM,KAAK,SAAS;AAGxB,gBAAI,UAAU;AACd,gBAAI,KAAK,cAAc,UAAU;AAC/B,wBAAU;AAAA,YACZ,WAAW,EAAE,GAAG,WAAW,GAAG,GAAG;AAC/B,wBAAU;AAAA,YACZ,WAAW,EAAE,GAAG,WAAW,GAAG,GAAG;AAC/B,wBAAU;AAAA,YACZ,WAAW,EAAE,GAAG,WAAW,GAAG,GAAG;AAC/B,kBAAI,EAAE,GAAG,CAAC,KAAK,KAAK;AAClB,0BAAU;AAAA,cACZ,WAAW,EAAE,GAAG,CAAC,KAAK,KAAK;AACzB,0BAAU;AAAA,cACZ,OAAO;AACL,0BAAU;AAAA,cACZ;AAAA,YACF,WAAW,EAAE,GAAG,WAAW,GAAG,GAAG;AAC/B,wBAAU;AAAA,YACZ;AAGA,gBAAI,CAAC,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG;AACjD,mBAAK,UAAU,KAAK;AAAA,gBAClB,QAAQ,EAAE;AAAA,gBACV,MAAM;AAAA,cACR,CAAC;AAED,mBAAK,QAAQ,IAAI;AAAA,gBACf,uCAAuC,OAAO,YAAY,EAAE,EAAE,iBAAiB,KAAK,SAAS;AAAA,cAC/F;AAAA,YACF;AAGA,kBAAM,OACJ,KAAK,aACL,MACA,KAAK,YACL,eACA,EAAE,IACF,QAAQ,KAAK,QAAQ,iBAAiB,EAAE;AAE1C,oBAAM,UAAK,YAAL,mBAAc,aAAa,KAAK;AAAA,cACpC,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,kBACJ,IAAI;AAAA,kBACJ,IAAI;AAAA,gBACN;AAAA,cACF;AAAA,cACA,QAAQ,CAAC;AAAA,YACX;AAEA,oBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,UAAU;AAAA,cAC/C,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,kBACJ,IAAI;AAAA,kBACJ,IAAI;AAAA,gBACN;AAAA,gBACA,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,OAAO;AAAA,cACT;AAAA,cACA,QAAQ,CAAC;AAAA,YACX;AAEA,oBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,UAAU,SAAS;AAEtD,oBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,OAAO;AAAA,cAC5C,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,kBACJ,IAAI;AAAA,kBACJ,IAAI;AAAA,gBACN;AAAA,gBACA,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,OAAO;AAAA,cACT;AAAA,cACA,QAAQ,CAAC;AAAA,YACX;AAEA,oBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,OAAO,EAAE,IAAI;AAEhD,gBAAI,EAAE,UAAU;AAEd,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,aAAa;AAAA,gBAClD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,oBACJ,IAAI;AAAA,oBACJ,IAAI;AAAA,kBACN;AAAA,kBACA,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,aAAa,EAAE,UAAU;AAAA,YAC9D;AAEA,gBAAI,EAAE,SAAS;AACb,oBAAM,iBAAiB,EAAE,UAAU,KAAK;AACxC,oBAAM,eAAe,QAAM,UAAK,YAAL,mBAAc;AAAA,gBACvC,MAAM;AAAA;AAIR,kBACE,gBACA,aAAa,OACb,kBAAkB,aAAa,KAC/B;AAEA,wBAAM,UAAK,YAAL,mBAAc;AAAA,kBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,mBACpC,oBAAI,KAAK,GAAE,QAAQ;AAAA,kBACnB;AAAA;AAIF,sBAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,kBAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACtC;AAEA,oBAAI,oBAAoB,iBAAiB,OAAO,gBAAgB;AAC9D,uBAAK,qBAAqB,aAAa,WAAW;AAAA,gBACpD;AAAA,cACF;AAGA,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,YAAY;AAAA,gBACjD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,oBACJ,IAAI;AAAA,oBACJ,IAAI;AAAA,kBACN;AAAA,kBACA,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAGA,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA;AAAA,YAEJ;AAEA,gBAAI,EAAE,QAAQ;AACZ,oBAAM,SAAS,EAAE,SAAS;AAC1B,oBAAM,cAAc,QAAM,UAAK,YAAL,mBAAc;AAAA,gBACtC,MAAM;AAAA;AAIR,kBAAI,eAAe,YAAY,OAAO,UAAU,YAAY,KAAK;AAE/D,wBAAM,UAAK,YAAL,mBAAc;AAAA,kBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,mBACpC,oBAAI,KAAK,GAAE,QAAQ;AAAA,kBACnB;AAAA;AAIF,sBAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,kBAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACtC;AAEA,oBAAI,oBAAoB,iBAAiB,OAAO,gBAAgB;AAC9D,uBAAK,qBAAqB,aAAa,WAAW;AAAA,gBACpD;AAAA,cACF;AAEA,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,WAAW;AAAA,gBAChD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,WAAW,QAAQ;AAAA,YACxD;AAEA,gBAAI,EAAE,QAAQ;AACZ,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,WAAW;AAAA,gBAChD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,WAAW,EAAE,SAAS,IAAI;AAAA,YAC/D;AAGA,gBAAI,EAAE,QAAQ;AACZ,oBAAM,SAAS,EAAE,SAAS;AAC1B,oBAAM,cAAc,QAAM,UAAK,YAAL,mBAAc;AAAA,gBACtC,MAAM;AAAA;AAGR,kBAAI,eAAe,YAAY,OAAO,UAAU,YAAY,KAAK;AAE/D,wBAAM,UAAK,YAAL,mBAAc;AAAA,kBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,mBACpC,oBAAI,KAAK,GAAE,QAAQ;AAAA,kBACnB;AAAA;AAIF,sBAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,kBAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACtC;AAEA,oBAAI,oBAAoB,iBAAiB,OAAO,gBAAgB;AAC9D,uBAAK,qBAAqB,aAAa,WAAW;AAAA,gBACpD;AAAA,cACF;AAEA,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,WAAW;AAAA,gBAChD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,WAAW,QAAQ;AAAA,YACxD;AAGA,gBAAI,EAAE,UAAU;AACd,oBAAM,WAAW,EAAE,WAAW;AAE9B,oBAAM,gBAAgB,QAAM,UAAK,YAAL,mBAAc;AAAA,gBACxC,MAAM;AAAA;AAGR,kBACE,iBACA,cAAc,OACd,YAAY,cAAc,KAC1B;AAEA,wBAAM,UAAK,YAAL,mBAAc;AAAA,kBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,mBACpC,oBAAI,KAAK,GAAE,QAAQ;AAAA,kBACnB;AAAA;AAIF,sBAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,kBAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACtC;AAEA,oBAAI,oBAAoB,iBAAiB,OAAO,gBAAgB;AAC9D,uBAAK,qBAAqB,aAAa,WAAW;AAAA,gBACpD;AAAA,cACF;AAEA,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,aAAa;AAAA,gBAClD,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,aAAa,UAAU;AAG1D,kBAAI,aAAa;AACf,qBAAK,aAAa,QAAQ;AAAA,cAC5B;AAAA,YACF;AAEA,gBAAI,EAAE,KAAK;AACT,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,QAAQ;AAAA,gBAC7C,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,oBACJ,IAAI;AAAA,oBACJ,IAAI;AAAA,kBACN;AAAA,kBACA,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,QAAQ,EAAE,MAAM,IAAI;AAAA,YACzD;AAEA,gBAAI,EAAE,OAAO;AACX,sBAAM,UAAK,YAAL,mBAAc,aAAa,MAAM,UAAU;AAAA,gBAC/C,MAAM;AAAA,gBACN,QAAQ;AAAA,kBACN,MAAM;AAAA,oBACJ,IAAI;AAAA,oBACJ,IAAI;AAAA,kBACN;AAAA,kBACA,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,MAAM;AAAA,kBACN,MAAM;AAAA,gBACR;AAAA,gBACA,QAAQ,CAAC;AAAA,cACX;AAEA,sBAAM,UAAK,YAAL,mBAAc,SAAS,MAAM,UAAU,EAAE,OAAO;AAAA,YACxD;AAGA,gBAAI,QAAQ;AAEZ,mBAAO,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAACA,MAAK,KAAK,MAAM;AAp/BtD,kBAAAC;AAq/BY,+DAAwB,QAAQ,CAAC,aAAqB;AACpD,oBAAI,YAAYD,MAAK;AACnB,0BAAQ;AAAA,gBACV;AAAA,cACF,CAAC;AAED,kBAAI,OAAO;AAAA,cAIX,OAAO;AACL,iBAAAC,MAAA,KAAK,YAAL,gBAAAA,IAAc,IAAI;AAAA,kBAChB,yBAAyBD,IAAG,eAAe,KAAK;AAAA;AAAA,cAEpD;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AA+NA,SAAO,wBAAwB,OAC7B,UACA,UACkB;AA1uCtB;AA2uCI,WAAK,QAAQ,IAAI;AAAA,QACf,4CAA4C,KAAK,UAAU,IAAI,KAAK,SAAS,iBAAiB,QAAQ;AAAA,MACxG;AAEA,UAAI,cAAkC;AAEtC,YAAM,UACJ,WAAM,KAAK,QAAQ;AAAA,QACjB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACtC,MAFA,mBAGC;AACH,YAAM,cACJ,WAAM,KAAK,QAAQ;AAAA,QACjB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACtC,MAFA,mBAGC;AAEH,UAAI,cAAc,UAAU,OAAO,UAAU,IAAI,OAAO,MAAM,GAAG;AAE/D,aAAK,QAAQ,IAAI;AAAA,UACf,wDAAwD,OAAO,UAAU,CAAC,2BAA2B,OAAO,MAAM,CAAC;AAAA,QACrH;AAEA;AAAA,MACF;AAEA,YAAM,qBAAqB,QAAM,UAAK,YAAL,mBAAc;AAAA,QAC7C,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA;AAG3C,YAAM,wBAAwB,QAAM,UAAK,YAAL,mBAAc;AAAA,QAChD,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA;AAG3C,YAAM,kBAAkB,QAAM,UAAK,YAAL,mBAAc;AAAA,QAC1C,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA;AAG3C,YAAM,kBAAkB;AAAA,QACtB,wBAAwB,sBAAsB,MAAM;AAAA,MACtD;AAEA,UAAI,mBAAkB,yDAAoB,OACtC,OAAO,yDAAoB,GAAG,IAC9B;AAEJ,UACE,mBAAmB,QACnB,mBAAmB,UACnB,mBAAmB,GACnB;AACA,0BAAkB;AAAA,MACpB;AAEA,UAAI,KAAK,cAAc,UAAU;AAE/B,sBAAc;AAAA,MAChB,OAAO;AAEL,iBAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC9C,cAAI,KAAK,UAAU,CAAC,EAAE,KAAK,SAAS,QAAQ,GAAG;AAC7C,2BAAe,cAAc,cAAc,KAAK;AAAA,UAClD,WAAW,KAAK,UAAU,CAAC,EAAE,KAAK,SAAS,QAAQ,GAAG;AACpD,2BAAe,cAAc,cAAc,KAAK;AAAA,UAClD,WAAW,KAAK,UAAU,CAAC,EAAE,KAAK,SAAS,QAAQ,GAAG;AACpD,2BAAe,cAAc,cAAc,KAAK;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AAGA,UAAI,cACF,YAAY,eACR,kBAAkB,QAClB,kBAAkB;AAGxB,UACE,YAAY,gBACZ,eAAe,UACf,cAAc,aACd;AACA,sBAAc;AAEd,aAAK,QAAQ,IAAI;AAAA,UACf,wCAAwC,WAAW,kCAAkC,WAAW;AAAA,QAClG;AAAA,MACF;AAEA,UAAI,cAAc,GAAG;AACnB,mBAAK,YAAL,mBAAc;AAAA,UACZ,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACpC;AAAA,UACA;AAAA;AAGF,aAAK,QAAQ,IAAI;AAAA,UACf,gCAAgC,KAAK,UAAU,IAAI,KAAK,SAAS,8BAA8B,WAAW;AAAA,QAC5G;AAEA,YAAI,uBAAuB;AACzB,gBAAM,MAAM,QAAS,cAAc,kBAAmB,KAAK,QAAQ,CAAC,CAAC;AAErE,kBAAM,UAAK,YAAL,mBAAc;AAAA,YAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,YACpC,MAAM,MAAQ,MAAM;AAAA,YACpB;AAAA;AAGF,cAAI,cAAc,mBAAmB,EAAC,mDAAiB,MAAK;AAE1D,oBAAM,UAAK,YAAL,mBAAc;AAAA,cAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,cACpC;AAAA,cACA;AAAA;AAAA,UAEJ;AAEA,gBAAM,yBAAyB,QAAM,UAAK,YAAL,mBAAc;AAAA,YACjD,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA;AAGtC,gBAAM,wBAAwB,QAAM,UAAK,YAAL,mBAAc;AAAA,YAChD,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA;AAG3C,cACE,YAAY,iBACZ,iEAAwB,QAAO,QAC/B,0BAA0B,QAC1B;AAEA,kBAAM,WAAW,kBAAkB;AAEnC,kBAAM,uBACJ,WAAW,OAAO,uBAAuB,GAAG;AAE9C,gBAAI,uBAAuB,IAAM;AAC/B,oBAAM,sBAAkB;AAAA,gBACtB,KAAK,MAAM,uBAAuB,EAAE;AAAA,cACtC;AAEA,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ,OAAO;AACL,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ;AAAA,UACF,WACE,YAAY,eACZ,yBAAyB,QACzB,yBAAyB,QACzB;AAEA,kBAAM,uBACJ,cAAc,OAAO,sBAAsB,GAAG;AAChD,kBAAM,sBAAkB;AAAA,cACtB,KAAK,MAAM,uBAAuB,EAAE;AAAA,YACtC;AAEA,gBAAI,uBAAuB,IAAM;AAC/B,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ,OAAO;AACL,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAW,eAAe,KAAK,YAAY,cAAc;AACvD,gBAAM,UAAK,YAAL,mBAAc;AAAA,UAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACpC;AAAA,UACA;AAAA;AAAA,MAEJ,WAAW,eAAe,KAAK,YAAY,aAAa;AACtD,gBAAM,UAAK,YAAL,mBAAc;AAAA,UAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACpC;AAAA,UACA;AAAA;AAIF,cAAM,sBAAsB,KAAK,IAAI,WAAW;AAEhD,YAAI,eAAe,kBAAkB,uBAAuB,aAAa;AACvE,kBAAM,UAAK,YAAL,mBAAc;AAAA,YAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,YACpC,kBAAkB;AAAA,YAClB;AAAA;AAAA,QAEJ;AAAA,MACF;AAAA,IACF;AAx7CF;AA4CI,SAAK,qBAAqB;AAC1B,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,YAAY;AAEjB,SAAK,aAAa;AAClB,SAAK,cAAc;AAEnB,SAAK,WAAW,OAAO,WAAW,IAAI,UAAU;AAChD,SAAK,gBAAgB,OAAO,WAAW,IAAI,UAAU;AAGrD,SAAK,eAAW,0BAAW,KAAK,EAC7B,OAAO,YAAY,MAAM,EACzB,OAAO,KAAK,EACZ,YAAY,EACZ,UAAU,GAAG,EAAE;AAGlB,SAAK,sBAAsB;AAG3B,SAAK,qBAAqB;AAG1B,SAAK,kBAAkB;AAGvB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,2BAA2B;AAAA,IAClC,GAAG,GAAI;AAEP,SAAI,UAAK,uBAAL,mBAAyB,QAAQ;AACnC,WAAK,qBAAqB,aAAa,WAAW;AAAA,IACpD,aAAW,UAAK,uBAAL,mBAAyB,WAAU,OAAO;AACnD,WAAK,qBAAqB,aAAa,cAAc;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAc,wBAAuC;AAnFvD;AAoFI,UAAM,aAAa,KAAK,WAAW;AAAA,MACjC,KAAK,QAAQ;AAAA,MACb;AAAA,IACF;AACA,UAAM,YAAY,KAAK,UAAU,QAAQ,KAAK,QAAQ,iBAAiB,EAAE;AAEzE,SAAK,QAAQ,IAAI;AAAA,MACf,qEAAqE,KAAK,WAAW,KAAK,UAAU,IAAI,SAAS,eAAe,KAAK,UAAU;AAAA,IACjJ;AAGA,YAAM,UAAK,YAAL,mBAAc,aAAa,YAAY;AAAA,MAC3C,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,IAAI,GAAG,KAAK,WAAW,KAAK,UAAU;AAAA,UACtC,IAAI,GAAG,KAAK,WAAW,KAAK,UAAU;AAAA,QACxC;AAAA,MACF;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAGA,YAAM,UAAK,YAAL,mBAAc,aAAa,aAAa,MAAM,WAAW;AAAA,MAC7D,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,IAAI,GAAG,KAAK,UAAU,KAAK,SAAS;AAAA,UACpC,IAAI,GAAG,KAAK,UAAU,KAAK,SAAS;AAAA,QACtC;AAAA,MACF;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAGA,YAAM,UAAK,YAAL,mBAAc,aAAa,GAAG,UAAU,IAAI,SAAS,aAAa;AAAA,MACtE,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AAAA,MACF;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAGA,SAAK,OAAO,QAAQ,OAAO,UAA2B;AAnI1D,UAAAC;AAoIM,cAAMA,MAAA,KAAK,YAAL,gBAAAA,IAAc;AAAA,QAClB,GAAG,UAAU,IAAI,SAAS,IAAI,MAAM,KAAK;AAAA,QACzC;AAAA,UACE,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,cACJ,IAAI,MAAM;AAAA,cACV,IAAI,MAAM;AAAA,YACZ;AAAA,YACA,MAAM,MAAM;AAAA,YACZ,MAAM,MAAM;AAAA,YACZ,MAAM,MAAM;AAAA,YACZ,MAAM;AAAA,YACN,OAAO;AAAA,YACP,MAAM,MAAM;AAAA,YACZ,QAAQ,MAAM;AAAA,UAChB;AAAA,UACA,QAAQ,CAAC;AAAA,QACX;AAAA;AAAA,IAEJ,CAAC;AAGD,YAAM,UAAK,YAAL,mBAAc,aAAa,GAAG,UAAU,IAAI,SAAS,YAAY;AAAA,MACrE,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,IAAI,+BAAyB;AAAA,UAC7B,IAAI,wBAAwB;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAEA,SAAK,cAAc,QAAQ,OAAO,UAA2B;AAtKjE,UAAAA,KAAAC;AAuKM,cAAMD,MAAA,KAAK,YAAL,gBAAAA,IAAc;AAAA,QAClB,GAAG,UAAU,IAAI,SAAS,YAAY,MAAM,KAAK;AAAA,QACjD;AAAA,UACE,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,cACJ,IAAI,MAAM;AAAA,cACV,IAAI,MAAM;AAAA,YACZ;AAAA,YACA,MAAM,MAAM;AAAA,YACZ,MAAM,MAAM;AAAA,YACZ,MAAM,MAAM;AAAA,YACZ,MAAM;AAAA,YACN,OAAO;AAAA,YACP,MAAM,MAAM;AAAA,YACZ,QAAQ,MAAM;AAAA,UAChB;AAAA,UACA,QAAQ,CAAC;AAAA,QACX;AAAA;AAIF,OAAAC,MAAA,KAAK,YAAL,gBAAAA,IAAc;AAAA,QACZ,GAAG,UAAU,IAAI,SAAS,YAAY,MAAM,KAAK;AAAA;AAAA,IAErD,CAAC;AAED,QAAI,KAAK,QAAQ,OAAO,gBAAgB;AAEtC,cAAM,UAAK,YAAL,mBAAc;AAAA,QAClB,GAAG,UAAU,IAAI,SAAS;AAAA,QAC1B;AAAA,UACE,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,cACJ,IAAI,kCAA4B;AAAA,cAChC,IAAI,6BAA6B;AAAA,YACnC;AAAA,UACF;AAAA,UACA,QAAQ,CAAC;AAAA,QACX;AAAA;AAGF,gBAAM,wDAAwB,KAAK,SAAS,YAAY,SAAS;AAAA,IACnE;AAAA,EACF;AAAA,EAEO,uBAA6B;AAtNtC;AAuNI,UAAM,cAAc,IAAI,KAAK,UAAU,IAAI,KAAK,SAAS;AAEzD,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,IAAI;AAAA,QACf,qDAAqD,WAAW;AAAA,MAClE;AACA,iBAAK,QAAQ,eAAb,mBAAyB,UAAU,aAAa;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAjOpC;AAkOI,UAAM,WAAW,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEzD,eAAK,YAAL,mBAAc,IAAI;AAAA,MAChB,kDAAkD,QAAQ;AAAA;AAE5D,qBAAK,YAAL,mBAAc,eAAd,mBAA0B,UAAU,UAAU,CAAC,UAAU;AACvD,wDAAoB,OAAO,KAAK,YAAY,KAAK,SAAS;AAAA,IAC5D;AAAA,EACF;AAAA,EAEO,8BAA8B,OAAqB;AA5O5D;AA6OI,eAAK,YAAL,mBAAc,IAAI;AAAA,MAChB,4DAA4D,KAAK;AAAA;AAEnE;AAAA,EACF;AAAA,EAEO,UAAU,QAAsB;AAnPzC;AAoPI,eAAK,YAAL,mBAAc,IAAI;AAAA,MAChB,wCAAwC,MAAM;AAAA;AAEhD;AAAA,EACF;AAAA,EAEO,YAAY,UAAyB;AA1P9C;AA2PI,eAAK,YAAL,mBAAc,IAAI;AAAA,MAChB,0CAA0C,QAAQ;AAAA;AAEpD;AAAA,EACF;AAAA,EAEO,YAAY,UAAyB;AAjQ9C;AAkQI,eAAK,YAAL,mBAAc,IAAI;AAAA,MAChB,0CAA0C,QAAQ;AAAA;AAEpD;AAAA,EACF;AAAA,EAEO,YAAY,UAAwB;AAxQ7C;AAyQI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,UAAI,YAAY,KAAK,YAAY,GAAG;AAClC,cAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEtD,cAAM,cAAc,EAAE,YAAY,EAAE,SAAmB,EAAE;AACzD,aAAK,QAAQ,IAAI;AAAA,UACf,iDAAiD,KAAK,SAAS,OAAO,QAAQ;AAAA,QAChF;AACA,mBAAK,QAAQ,eAAb,mBAAyB,QAAQ,OAAO,KAAK,UAAU,WAAW;AAAA,MACpE,OAAO;AACL,aAAK,QAAQ,IAAI,MAAM,wCAAwC;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA,EAEO,YAAY,UAAwB;AAxR7C;AAyRI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,YAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEtD,YAAM,qBAAqB,EAAE,YAAY,EAAE,SAAmB,EAAE;AAChE,WAAK,QAAQ,IAAI;AAAA,QACf,4CAA4C,KAAK,SAAS,OAAO,QAAQ;AAAA,MAC3E;AACA,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB;AAAA,QACA,KAAK,UAAU,kBAAkB;AAAA;AAAA,IAErC;AAAA,EACF;AAAA,EAEO,eAAe,aAA4B;AAvSpD;AAwSI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,YAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEtD,YAAM,wBAAwB;AAAA,QAC5B,YAAY,EAAE,aAAa,cAAc,IAAI,EAAE;AAAA,MACjD;AACA,WAAK,QAAQ,IAAI;AAAA,QACf,kDAAkD,KAAK,SAAS,OAAO,WAAW;AAAA,MACpF;AACA,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB;AAAA,QACA,KAAK,UAAU,qBAAqB;AAAA;AAAA,IAExC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,kBAAkB,QAAsB;AA7TjD;AA8TI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,UAAI,UAAU,KAAK,UAAU,IAAI;AAC/B,cAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEtD,cAAM,cAAc,EAAE,YAAY,EAAE,QAAQ,SAAS,GAAG,EAAE;AAC1D,aAAK,QAAQ,IAAI;AAAA,UACf,8DAA8D,KAAK,SAAS,OAAO,MAAM;AAAA,QAC3F;AACA,mBAAK,QAAQ,eAAb,mBAAyB,QAAQ,OAAO,KAAK,UAAU,WAAW;AAAA,MACpE,OAAO;AACL,aAAK,QAAQ,IAAI;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,eAAe,QAAsB;AApV9C;AAqVI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,UAAI,UAAU,MAAM,UAAU,KAAK;AACjC,cAAM,cAAc,EAAE,YAAY,EAAE,QAAQ,SAAS,GAAG,EAAE;AAC1D,aAAK,QAAQ,IAAI;AAAA,UACf,uDAAuD,KAAK,SAAS,OAAO,MAAM;AAAA,QACpF;AACA,mBAAK,QAAQ,eAAb,mBAAyB;AAAA,UACvB,KAAK;AAAA,UACL,KAAK,UAAU,WAAW;AAAA;AAAA,MAE9B,OAAO;AACL,aAAK,QAAQ,IAAI;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAa,WAAyB;AA5W/C;AA6WI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,UAAI,sBAA2B,EAAE,YAAY,EAAE,UAAqB,EAAE;AAEtE,cAAQ,WAAW;AAAA,QACjB,KAAK,GAAG;AAEN,gCAAsB;AAAA,YACpB,YAAY;AAAA,cACV,kBAAkB;AAAA,cAClB,gBAAgB;AAAA,gBACd,cAAc;AAAA,gBACd,eAAe;AAAA,gBACf,UAAU;AAAA,cACZ;AAAA,cACA,SAAS;AAAA,cACT,WAAW;AAAA,YACb;AAAA,UACF;AACA;AAAA,QACF;AAAA,QACA,KAAK;AACH,gCAAsB;AAAA,YACpB,YAAY;AAAA,cACV,kBAAkB;AAAA,cAClB,gBAAgB;AAAA,gBACd,cAAc;AAAA,gBACd,eAAe;AAAA,gBACf,UAAU;AAAA,cACZ;AAAA,cACA,SAAS;AAAA,cACT,WAAW;AAAA,YACb;AAAA,UACF;AACA;AAAA,MACJ;AAEA,WAAK,QAAQ,IAAI;AAAA,QACf,mDAAmD,KAAK,SAAS,OAAO,SAAS;AAAA,MACnF;AACA,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB,KAAK;AAAA,QACL,KAAK,UAAU,mBAAmB;AAAA;AAAA,IAEtC;AAAA,EACF;AAAA,EAEA,MAAa,eAAe,OAA8B;AA3Z5D;AA4ZI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAEhE,YAAM,aACJ,WAAM,KAAK,QAAQ;AAAA,QACjB,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA,MAC3C,MAFA,mBAGC;AAEH,UAAI,aAAa,GAAG;AAClB,aAAK,QAAQ,IAAI;AAAA,UACf;AAAA,QACF;AACA;AAAA,MACF;AAEA,UAAI,OAAO;AACT,gBAAQ,KAAK,MAAM,KAAK;AAAA,MAC1B,OAAO;AACL,gBAAQ;AAAA,MACV;AAGA,UAAI,QAAQ,KAAK,gBAAgB;AAC/B,gBAAQ,KAAK;AAAA,MACf;AAEA,UACE,QAAQ,OACR,SAAS,MACT,SAAS,MACT,SAAS,MACT,SAAS,MACR,KAAK,cAAc,YAAY,KAAK,cAAc,WACnD;AAEA,YAAI,QAAQ,OAAO,QAAQ,IAAI;AAC7B,kBAAQ;AAAA,QACV,WAAW,QAAQ,MAAM,QAAQ,IAAI;AACnC,kBAAQ;AAAA,QACV,WAAW,QAAQ,MAAM,QAAQ,IAAI;AACnC,kBAAQ;AAAA,QACV,WAAW,QAAQ,IAAI;AACrB,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI,KAAK,QAAQ,OAAO,oBAAoB;AAC1C,cAAM,uBAAuB,MAAM,KAAK,QAAQ;AAAA,UAC9C,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA,QAC3C;AACA,YACE,wBACA,qBAAqB,OACrB,qBAAqB,OAAO,MAC5B;AACA,kBAAQ;AAAA,QACV;AAEA,cAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,UAC1C,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA,QAC3C;AAEA,YACE,oBACA,iBAAiB,OACjB,iBAAiB,OAAO,MACxB;AACA,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,gBACJ,WAAM,KAAK,QAAQ;AAAA,QACjB,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA,MAC3C,MAFA,mBAGC;AAEH,UAAI,gBAAgB,QAAQ,gBAAgB,QAAW;AACrD,YAAI,gBAAgB,OAAO;AACzB,gBAAM,cAAc,EAAE,YAAY,EAAE,aAAa,MAAM,EAAE;AAEzD,eAAK,aAAa;AAElB,gBAAM,YAAY,oBAAI,KAAK;AAC3B,oBAAU,gBAAgB,CAAC;AAE3B,qBAAK,QAAQ,eAAb,mBAAyB;AAAA,YACvB,KAAK;AAAA,YACL,KAAK,UAAU,WAAW;AAAA;AAAA,QAE9B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,cAAc,OAAqB;AA3f5C;AA4fI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAEhE,UAAI,QAAQ,GAAG;AACb,aAAK,QAAQ,IAAI;AAAA,UACf,yBAAyB,KAAK;AAAA,QAChC;AACA,gBAAQ,KAAK,IAAI,KAAK;AAAA,MACxB;AAEA,UAAI,OAAO;AACT,gBAAQ,KAAK,MAAM,KAAK;AAAA,MAC1B,OAAO;AACL,gBAAQ;AAAA,MACV;AAEA,UAAI,QAAQ,GAAG;AACb,gBAAQ;AAAA,MACV,WAAW,QAAQ,KAAK,SAAS,IAAI;AACnC,gBAAQ;AAAA,MACV,WAAW,QAAQ,KAAK,eAAe;AACrC,gBAAQ,KAAK;AAAA,MACf;AAEA,UAAI,KAAK,WAAW,SAAS,QAAQ,GAAG;AAEtC,gBAAQ,KAAK,KAAK,QAAQ,GAAG,IAAI;AAAA,MACnC;AAEA,YAAM,oBAAoB,EAAE,YAAY,EAAE,YAAY,MAAM,EAAE;AAC9D,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB,KAAK;AAAA,QACL,KAAK,UAAU,iBAAiB;AAAA;AAAA,IAEpC;AAAA,EACF;AAAA,EAEO,aAAa,aAA4B;AAhiBlD;AAiiBI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,YAAM,sBAAsB;AAAA,QAC1B,YAAY,EAAE,WAAW,cAAc,IAAI,EAAE;AAAA,MAC/C;AAEA,WAAK,QAAQ,IAAI;AAAA,QACf,iDAAiD,KAAK,SAAS,OAAO,WAAW;AAAA,MACnF;AACA,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB,KAAK;AAAA,QACL,KAAK,UAAU,mBAAmB;AAAA;AAAA,IAEtC;AAAA,EACF;AAAA,EAEO,gBAAgB,UAAyB;AAhjBlD;AAijBI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,YAAM,yBAAyB;AAAA,QAC7B,YAAY,EAAE,cAAc,WAAW,IAAI,EAAE;AAAA,MAC/C;AACA,WAAK,QAAQ,IAAI;AAAA,QACf,6CAA6C,KAAK,SAAS,OAAO,QAAQ;AAAA,MAC5E;AACA,iBAAK,QAAQ,eAAb,mBAAyB;AAAA,QACvB,KAAK;AAAA,QACL,KAAK,UAAU,sBAAsB;AAAA;AAAA,IAEzC;AAAA,EACF;AAAA,EAEO,6BAAmC;AA/jB5C;AAgkBI,QAAI,KAAK,QAAQ,cAAc,KAAK,cAAc,KAAK,WAAW;AAChE,YAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,KAAK,SAAS;AAEtD,YAAM,gBAAgB,EAAE,YAAY,CAAC,QAAQ,EAAE;AAC/C,WAAK,QAAQ,IAAI;AAAA,QACf,gFAAgF,KAAK,SAAS;AAAA,MAChG;AACA,iBAAK,QAAQ,eAAb,mBAAyB,QAAQ,OAAO,KAAK,UAAU,aAAa;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAa,qBACX,OACA,KACe;AA9kBnB;AA+kBI,UAAM,eAAe,MAAM,KAAK,QAAQ;AAAA,MACtC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK;AAAA,IAC/C;AAEA,YAAM,UAAK,YAAL,mBAAc;AAAA,MAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK;AAAA,MAC7C;AAAA,MACA;AAAA;AAGF,SAAI,6CAAc,QAAO,OAAO,SAAS,aAAa;AAEpD,cAAM,UAAK,YAAL,mBAAc;AAAA,QAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,SACpC,oBAAI,KAAK,GAAE,QAAQ;AAAA,QACnB;AAAA;AAIF,YAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,QAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACtC;AAEA,UAAI,oBAAoB,iBAAiB,OAAO,gBAAgB;AAC9D,aAAK,qBAAqB,aAAa,WAAW;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,4BACX,OACA,KACe;AA/mBnB;AAinBI,UAAM,aAAa,QAAM,UAAK,YAAL,mBAAc;AAAA,MACrC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,YAAY,KAAK;AAAA;AAIvD,QAAI,YAAY;AACd,cAAM,UAAK,YAAL,mBAAc;AAAA,QAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,YAAY,KAAK;AAAA,QACrD;AAAA,QACA;AAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EA6YA,MAAa,aAAa,SAAgC;AA1gC5D;AA2gCI,QAAI,UAAU,MAAM;AAClB,UAAI,KAAK,QAAQ,OAAO,gBAAgB;AACtC,aAAK,aAAa;AAAA,MACpB;AAEA,UAAI,KAAK,QAAQ,OAAO,oBAAoB;AAE1C,gBAAM,UAAK,YAAL,mBAAc;AAAA,UAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACpC;AAAA,UACA;AAAA;AAIF,cAAM,aACJ,WAAM,KAAK,QAAQ;AAAA,UACjB,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA,QAC3C,MAFA,mBAGC;AACH,YAAI,aAAa,GAAG;AAClB,eAAK,8BAA8B,CAAC;AAAA,QACtC,OAAO;AACL,eAAK,eAAe,CAAC;AAAA,QACvB;AAEA,YAAI,KAAK,QAAQ,OAAO,2BAA2B;AACjD,gBAAM,aAAa,MAAM,KAAK,QAAQ;AAAA,YACpC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACtC;AAEA,cAAI,cAAc,OAAO,WAAW,GAAG,IAAI,IAAI;AAE7C,gBAAI,KAAK,QAAQ,OAAO,oBAAoB;AAC1C,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ;AAAA,UACF,OAAO;AACL,gBAAI,cAAc,WAAW,KAAK;AAChC,mBAAK,kBAAkB,OAAO,WAAW,GAAG,CAAC;AAAA,YAC/C;AAGA,kBAAM,WAAW,MAAM,KAAK,QAAQ;AAAA,cAClC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,YACtC;AAEA,gBAAI,CAAC,YAAY,OAAO,SAAS,GAAG,KAAK,GAAG;AAC1C,mBAAK,QAAQ,IAAI;AAAA,gBACf;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,WAAW,MAAM;AAE1B,YAAM,kBAAkB,MAAM,KAAK,QAAQ;AAAA,QACzC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACtC;AAEA,UAAI,mBAAmB,gBAAgB,OAAO,MAAM;AAClD,gBAAM,UAAK,YAAL,mBAAc;AAAA,UAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACpC;AAAA,UACA;AAAA;AAGF,YACE,KAAK,QAAQ,OAAO,sBACpB,KAAK,QAAQ,OAAO,2BACpB;AACA,eAAK;AAAA,YACH,KAAK,QAAQ,OAAO,iBAChB,KAAK,QAAQ,OAAO,iBACpB;AAAA,UACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,kBAAwB;AAC7B,0CAAqB,QAAQ,OAAO,aAAa;AAvmCrD;AAwmCM,UAAI,oBAAoB;AACxB,UAAI,qBAAqB;AACzB,UAAI,iBAAiB;AAErB,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD,2BAAiB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACrD;AAAA,QACF,KAAK;AACH,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD,2BAAiB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACrD;AAAA,QACF,KAAK;AACH,gBAAM,mBAAmB,KAAK,OAAO;AAAA,YACnC,CAAC,MAAM,EAAE,SAAS;AAAA,UACpB;AACA,cAAI,kBAAkB;AACpB,gCAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,iCAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD,6BAAiB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACvD;AACA;AAAA,QACF,KAAK;AACH,gBAAM,mBAAmB,KAAK,OAAO;AAAA,YACnC,CAAC,MAAM,EAAE,SAAS;AAAA,UACpB;AACA,cAAI,kBAAkB;AACpB,gCAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,iCAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD,6BAAiB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UACvD;AACA;AAAA,QACF;AACE,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,iBAAiB,QAAQ;AACjF,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,iBAAiB,QAAQ;AAClF,2BAAiB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,IAAI,QAAQ;AACjE;AAAA,MACJ;AAEA,UAAI,kBAAkB,IAAI;AAExB,aAAK,QAAQ,IAAI;AAAA,UACf,iDAAiD,QAAQ;AAAA,QAC3D;AACA,cAAM,oBACJ,QAAM,UAAK,YAAL,mBAAc,cAAc;AAEpC,cAAM,qBACJ,QAAM,UAAK,YAAL,mBAAc,cAAc;AAEpC,YAAI,EAAC,yDAAoB,SAAO,yDAAoB,QAAO,GAAG;AAE5D,kBAAM,UAAK,YAAL,mBAAc,SAAS,mBAAmB,MAAU;AAAA,QAC5D,WACE,sBACA,mBAAmB,MACnB,qBACA,kBAAkB,OAAO,UACzB,kBAAkB,OAAO,MACzB;AAEA,gBAAM,YAAY;AAGlB,gBAAM,iBACH,OAAO,kBAAkB,GAAG,IAAI,YAAa;AAgBhD,cAAI,iBAAiB,OAAO,mBAAmB,GAAG,IAAI;AAGtD,cAAI,iBAAiB,GAAG;AACtB,6BAAiB;AAAA,UACnB;AAEA,kBAAM,UAAK,YAAL,mBAAc,SAAS,mBAAmB,gBAAgB;AAChE,kBAAM,UAAK,YAAL,mBAAc;AAAA,YAClB;AAAA,YACA,QAAQ,iBAAiB,KAAM,QAAQ,CAAC,CAAC;AAAA,YACzC;AAAA;AAIF,eACG,YAAY,gBAAgB,YAAY,gBACzC,iBAAiB,GACjB;AACA,kBAAM,KAAK,sBAAsB,UAAU,cAAc;AAAA,UAC3D,OAAO;AACL,gBAAI,YAAY,cAAc;AAC5B,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ,WAAW,YAAY,aAAa;AAClC,sBAAM,UAAK,YAAL,mBAAc;AAAA,gBAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,gBACpC;AAAA,gBACA;AAAA;AAAA,YAEJ;AAAA,UACF;AAAA,QACF,WAAW,qBAAqB,oBAAoB;AAClD,kBAAM,UAAK,YAAL,mBAAc,SAAS,mBAAmB,GAAG;AACnD,kBAAM,UAAK,YAAL,mBAAc,SAAS,oBAAoB,GAAG;AAAA,QACtD;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAqNA,MAAa,eAA8B;AA17C7C;AA47CI,YAAM,UAAK,YAAL,mBAAc;AAAA,MAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACpC;AAAA,MACA;AAAA;AAIF,UAAM,gBAAgB,MAAM,KAAK,QAAQ;AAAA,MACvC,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,IACtC;AACA,UAAM,mBAAmB,MAAM,KAAK,QAAQ;AAAA,MAC1C,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,IACtC;AAEA,UAAM,SAAS,OAAO,qDAAkB,GAAG,IAAI,OAAO,+CAAe,GAAG;AAGxE,YAAM,UAAK,YAAL,mBAAc;AAAA,MAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACpC;AAAA,MACA;AAAA;AAIF,YAAM,UAAK,YAAL,mBAAc;AAAA,MAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,MACpC;AAAA,MACA;AAAA;AAAA,EAEJ;AAAA,EAEA,MAAa,iBAAgC;AA39C/C;AA49CI,UAAM,qBAAqB,QAAM,UAAK,YAAL,mBAAc;AAAA,MAC7C,KAAK,aAAa,MAAM,KAAK,YAAY;AAAA;AAG3C,QAAI,oBAAoB;AACtB,cAAM,UAAK,YAAL,mBAAc;AAAA,QAClB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,QACpC,yDAAoB;AAAA,QACpB;AAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEO,uBAA6B;AAClC,0CAAqB,QAAQ,OAAO,aAAqB;AA1+C7D;AA2+CM,UAAI,oBAAoB;AACxB,UAAI,qBAAqB;AAEzB,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD;AAAA,QACF,KAAK;AACH,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACzD;AAAA,QACF,KAAK;AACH,cAAI,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,GAAG;AAClD,gCAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,iCAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UAC3D,OAAO;AACL;AAAA,UACF;AACA;AAAA,QACF,KAAK;AACH,cAAI,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,GAAG;AAClD,gCAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AACxD,iCAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS;AAAA,UAC3D,OAAO;AACL;AAAA,UACF;AACA;AAAA,QACF;AACE,8BAAoB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,iBAAiB,QAAQ;AACjF,+BAAqB,GAAG,KAAK,UAAU,IAAI,KAAK,SAAS,iBAAiB,QAAQ;AAClF;AAAA,MACJ;AAEA,UAAI,qBAAqB,MAAM,sBAAsB,IAAI;AACvD,gBAAM,UAAK,YAAL,mBAAc,SAAS,mBAAmB,GAAG;AACnD,gBAAM,UAAK,YAAL,mBAAc,SAAS,oBAAoB,GAAG;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
6
6
  "names": ["key", "_a", "_b"]
7
7
  }
@@ -105,6 +105,13 @@ const startCheckStatesAndConnectionJob = async (adapter) => {
105
105
  )}, checking for pseudo power values!`
106
106
  );
107
107
  await statesToReset.forEach(async (stateName) => {
108
+ const exist = device.states.find((x) => x.title === stateName);
109
+ if (!exist) {
110
+ adapter.log.debug(
111
+ `[checkStatesJob] State ${stateName} does not exist for deviceKey ${device.deviceKey}!`
112
+ );
113
+ return;
114
+ }
108
115
  await (adapter == null ? void 0 : adapter.setState(
109
116
  device.productKey + "." + device.deviceKey + "." + stateName,
110
117
  0,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/services/jobSchedule.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport { scheduleJob } from \"node-schedule\";\r\nimport { ZendureSolarflow } from \"../main\";\r\n\r\nexport const startRefreshAccessTokenTimerJob = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n // Restart adapter every 3 hours\r\n adapter.refreshAccessTokenInterval = adapter.setInterval(\r\n async () => {\r\n adapter.log.info(\r\n `Refresh Access Token - Adapter will restart in 20 seconds!`\r\n );\r\n\r\n await adapter.delay(20 * 1000);\r\n adapter.restart();\r\n },\r\n 3 * 60 * 60 * 1000\r\n );\r\n};\r\n\r\nexport const startResetValuesJob = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n adapter.resetValuesJob = scheduleJob(\"5 0 0 * * *\", () => {\r\n // Reset Values\r\n adapter.zenHaDeviceList.forEach((device) => {\r\n device.resetValuesForDevice();\r\n });\r\n });\r\n};\r\n\r\nexport const startCalculationJob = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n adapter.calculationJob = scheduleJob(\"*/30 * * * * *\", () => {\r\n adapter.zenHaDeviceList.forEach((device) => {\r\n if (device.productKey != \"s3Xk4x\") {\r\n device.calculateEnergy();\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport const startCheckStatesAndConnectionJob = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n // Check for states that has no updates in the last 5 minutes and set them to 0\r\n const statesToReset: string[] = [\r\n \"outputHomePower\",\r\n \"outputPackPower\",\r\n \"gridInputPower\",\r\n \"packInputPower\",\r\n \"solarInputPower\",\r\n \"pvPower1\",\r\n \"pvPower2\",\r\n \"pvPower3\",\r\n \"pvPower4\",\r\n \"packPower\",\r\n ];\r\n\r\n let refreshAccessTokenNeeded = false;\r\n\r\n adapter.log.debug(\r\n `[checkStatesJob] Starting check of states and connection!`\r\n );\r\n\r\n adapter.checkStatesJob = scheduleJob(\"*/5 * * * *\", async () => {\r\n adapter.zenHaDeviceList.forEach(async (device) => {\r\n if (refreshAccessTokenNeeded) {\r\n return;\r\n }\r\n\r\n const lastUpdate = await adapter?.getStateAsync(\r\n device.productKey + \".\" + device.deviceKey + \".lastUpdate\"\r\n );\r\n\r\n const wifiState = await adapter?.getStateAsync(\r\n device.productKey + \".\" + device.deviceKey + \".wifiState\"\r\n );\r\n\r\n const fiveMinutesAgo = (Date.now() / 1000 - 5 * 60) * 1000; // Five minutes ago\r\n const tenMinutesAgo = (Date.now() / 1000 - 10 * 60) * 1000; // Thirty minutes ago\r\n\r\n if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < tenMinutesAgo &&\r\n wifiState?.val == \"Connected\" &&\r\n adapter.config.connectionMode == \"authKey\"\r\n ) {\r\n adapter.log.debug(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val)\r\n )}, device seems to be online - so maybe connection is broken!`\r\n );\r\n\r\n //await adapter.delay(20 * 1000);\r\n //adapter.restart();\r\n\r\n // set marker, so we discontinue the forEach Loop because of reconnect!\r\n refreshAccessTokenNeeded = true;\r\n } else if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < tenMinutesAgo &&\r\n wifiState?.val == \"Connected\" &&\r\n adapter.config.connectionMode == \"local\"\r\n ) {\r\n adapter.log.warn(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val)\r\n )}, set Wifi state to Disconnected!`\r\n );\r\n\r\n device?.updateSolarFlowState(\"wifiState\", \"Disconnected\");\r\n }\r\n\r\n if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < fiveMinutesAgo &&\r\n !refreshAccessTokenNeeded\r\n ) {\r\n adapter.log.debug(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val)\r\n )}, checking for pseudo power values!`\r\n );\r\n // State was not updated in the last 5 minutes... set states to 0\r\n await statesToReset.forEach(async (stateName: string) => {\r\n await adapter?.setState(\r\n device.productKey + \".\" + device.deviceKey + \".\" + stateName,\r\n 0,\r\n true\r\n );\r\n });\r\n }\r\n });\r\n });\r\n};\r\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,2BAA4B;AAGrB,MAAM,kCAAkC,OAC7C,YACkB;AAElB,UAAQ,6BAA6B,QAAQ;AAAA,IAC3C,YAAY;AACV,cAAQ,IAAI;AAAA,QACV;AAAA,MACF;AAEA,YAAM,QAAQ,MAAM,KAAK,GAAI;AAC7B,cAAQ,QAAQ;AAAA,IAClB;AAAA,IACA,IAAI,KAAK,KAAK;AAAA,EAChB;AACF;AAEO,MAAM,sBAAsB,OACjC,YACkB;AAClB,UAAQ,qBAAiB,kCAAY,eAAe,MAAM;AAExD,YAAQ,gBAAgB,QAAQ,CAAC,WAAW;AAC1C,aAAO,qBAAqB;AAAA,IAC9B,CAAC;AAAA,EACH,CAAC;AACH;AAEO,MAAM,sBAAsB,OACjC,YACkB;AAClB,UAAQ,qBAAiB,kCAAY,kBAAkB,MAAM;AAC3D,YAAQ,gBAAgB,QAAQ,CAAC,WAAW;AAC1C,UAAI,OAAO,cAAc,UAAU;AACjC,eAAO,gBAAgB;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEO,MAAM,mCAAmC,OAC9C,YACkB;AAElB,QAAM,gBAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,2BAA2B;AAE/B,UAAQ,IAAI;AAAA,IACV;AAAA,EACF;AAEA,UAAQ,qBAAiB,kCAAY,eAAe,YAAY;AAC9D,YAAQ,gBAAgB,QAAQ,OAAO,WAAW;AAChD,UAAI,0BAA0B;AAC5B;AAAA,MACF;AAEA,YAAM,aAAa,OAAM,mCAAS;AAAA,QAChC,OAAO,aAAa,MAAM,OAAO,YAAY;AAAA;AAG/C,YAAM,YAAY,OAAM,mCAAS;AAAA,QAC/B,OAAO,aAAa,MAAM,OAAO,YAAY;AAAA;AAG/C,YAAM,kBAAkB,KAAK,IAAI,IAAI,MAAO,IAAI,MAAM;AACtD,YAAM,iBAAiB,KAAK,IAAI,IAAI,MAAO,KAAK,MAAM;AAEtD,UACE,cACA,WAAW,OACX,OAAO,WAAW,GAAG,IAAI,kBACzB,uCAAW,QAAO,eAClB,QAAQ,OAAO,kBAAkB,WACjC;AACA,gBAAQ,IAAI;AAAA,UACV,8CACE,OAAO,SACT,WAAW,IAAI;AAAA,YACb,OAAO,WAAW,GAAG;AAAA,UACvB,CAAC;AAAA,QACH;AAMA,mCAA2B;AAAA,MAC7B,WACE,cACA,WAAW,OACX,OAAO,WAAW,GAAG,IAAI,kBACzB,uCAAW,QAAO,eAClB,QAAQ,OAAO,kBAAkB,SACjC;AACA,gBAAQ,IAAI;AAAA,UACV,8CACE,OAAO,SACT,WAAW,IAAI;AAAA,YACb,OAAO,WAAW,GAAG;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,yCAAQ,qBAAqB,aAAa;AAAA,MAC5C;AAEA,UACE,cACA,WAAW,OACX,OAAO,WAAW,GAAG,IAAI,kBACzB,CAAC,0BACD;AACA,gBAAQ,IAAI;AAAA,UACV,8CACE,OAAO,SACT,WAAW,IAAI;AAAA,YACb,OAAO,WAAW,GAAG;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,cAAM,cAAc,QAAQ,OAAO,cAAsB;AACvD,iBAAM,mCAAS;AAAA,YACb,OAAO,aAAa,MAAM,OAAO,YAAY,MAAM;AAAA,YACnD;AAAA,YACA;AAAA;AAAA,QAEJ,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport { scheduleJob } from \"node-schedule\";\r\nimport { ZendureSolarflow } from \"../main\";\r\n\r\nexport const startRefreshAccessTokenTimerJob = async (\r\n adapter: ZendureSolarflow,\r\n): Promise<void> => {\r\n // Restart adapter every 3 hours\r\n adapter.refreshAccessTokenInterval = adapter.setInterval(\r\n async () => {\r\n adapter.log.info(\r\n `Refresh Access Token - Adapter will restart in 20 seconds!`,\r\n );\r\n\r\n await adapter.delay(20 * 1000);\r\n adapter.restart();\r\n },\r\n 3 * 60 * 60 * 1000,\r\n );\r\n};\r\n\r\nexport const startResetValuesJob = async (\r\n adapter: ZendureSolarflow,\r\n): Promise<void> => {\r\n adapter.resetValuesJob = scheduleJob(\"5 0 0 * * *\", () => {\r\n // Reset Values on midnight\r\n adapter.zenHaDeviceList.forEach((device) => {\r\n device.resetValuesForDevice();\r\n });\r\n });\r\n};\r\n\r\nexport const startCalculationJob = async (\r\n adapter: ZendureSolarflow,\r\n): Promise<void> => {\r\n adapter.calculationJob = scheduleJob(\"*/30 * * * * *\", () => {\r\n adapter.zenHaDeviceList.forEach((device) => {\r\n if (device.productKey != \"s3Xk4x\") {\r\n device.calculateEnergy();\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport const startCheckStatesAndConnectionJob = async (\r\n adapter: ZendureSolarflow,\r\n): Promise<void> => {\r\n // Check for states that has no updates in the last 5 minutes and set them to 0\r\n const statesToReset: string[] = [\r\n \"outputHomePower\",\r\n \"outputPackPower\",\r\n \"gridInputPower\",\r\n \"packInputPower\",\r\n \"solarInputPower\",\r\n \"pvPower1\",\r\n \"pvPower2\",\r\n \"pvPower3\",\r\n \"pvPower4\",\r\n \"packPower\",\r\n ];\r\n\r\n let refreshAccessTokenNeeded = false;\r\n\r\n adapter.log.debug(\r\n `[checkStatesJob] Starting check of states and connection!`,\r\n );\r\n\r\n adapter.checkStatesJob = scheduleJob(\"*/5 * * * *\", async () => {\r\n adapter.zenHaDeviceList.forEach(async (device) => {\r\n if (refreshAccessTokenNeeded) {\r\n return;\r\n }\r\n\r\n const lastUpdate = await adapter?.getStateAsync(\r\n device.productKey + \".\" + device.deviceKey + \".lastUpdate\",\r\n );\r\n\r\n const wifiState = await adapter?.getStateAsync(\r\n device.productKey + \".\" + device.deviceKey + \".wifiState\",\r\n );\r\n\r\n const fiveMinutesAgo = (Date.now() / 1000 - 5 * 60) * 1000; // Five minutes ago\r\n const tenMinutesAgo = (Date.now() / 1000 - 10 * 60) * 1000; // Thirty minutes ago\r\n\r\n if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < tenMinutesAgo &&\r\n wifiState?.val == \"Connected\" &&\r\n adapter.config.connectionMode == \"authKey\"\r\n ) {\r\n adapter.log.debug(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val),\r\n )}, device seems to be online - so maybe connection is broken!`,\r\n );\r\n\r\n //await adapter.delay(20 * 1000);\r\n //adapter.restart();\r\n\r\n // set marker, so we discontinue the forEach Loop because of reconnect!\r\n refreshAccessTokenNeeded = true;\r\n } else if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < tenMinutesAgo &&\r\n wifiState?.val == \"Connected\" &&\r\n adapter.config.connectionMode == \"local\"\r\n ) {\r\n adapter.log.warn(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val),\r\n )}, set Wifi state to Disconnected!`,\r\n );\r\n\r\n device?.updateSolarFlowState(\"wifiState\", \"Disconnected\");\r\n }\r\n\r\n if (\r\n lastUpdate &&\r\n lastUpdate.val &&\r\n Number(lastUpdate.val) < fiveMinutesAgo &&\r\n !refreshAccessTokenNeeded\r\n ) {\r\n adapter.log.debug(\r\n `[checkStatesJob] Last update for deviceKey ${\r\n device.deviceKey\r\n } was at ${new Date(\r\n Number(lastUpdate.val),\r\n )}, checking for pseudo power values!`,\r\n );\r\n // State was not updated in the last 5 minutes... set states to 0\r\n await statesToReset.forEach(async (stateName: string) => {\r\n // First check if state exist\r\n const exist = device.states.find((x) => x.title === stateName);\r\n\r\n if (!exist) {\r\n adapter.log.debug(\r\n `[checkStatesJob] State ${stateName} does not exist for deviceKey ${device.deviceKey}!`,\r\n );\r\n return;\r\n }\r\n\r\n await adapter?.setState(\r\n device.productKey + \".\" + device.deviceKey + \".\" + stateName,\r\n 0,\r\n true,\r\n );\r\n });\r\n }\r\n });\r\n });\r\n};\r\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zendure-solarflow",
4
- "version": "3.3.1",
4
+ "version": "3.3.2",
5
5
  "news": {
6
+ "3.3.2": {
7
+ "en": "Fix another 'has no existing object' message bug on pvPower3 + 4\nFix Battery identification of AB2000X and calculation of 'energyWhMax'\nFix Battery identification of AB3000 and calculation of 'energyWhMax'",
8
+ "de": "Behebt einen anderen 'hat no existing object' Nachrichtenfehler auf pvPower3 + 4\nBatteriekennung von AB2000X und Berechnung von 'energyWhMax'\nBatteriekennung von AB3000 und Berechnung von 'energyWhMax'",
9
+ "ru": "Исправьте ошибку сообщения «нет существующего объекта» на pvPower3 + 4\nИдентификация батареи AB2000X и расчет «энергетического WhMax»\nИдентификация батареи AB3000 и расчет «энергетического WhMax»",
10
+ "pt": "Corrigir outro erro de mensagem 'não tem objeto existente' no pvPower3 + 4\nCorrigir a identificação da bateria de AB2000X e o cálculo de 'energyWhMax'\nCorrigir a identificação da bateria de AB3000 e o cálculo de 'energyWhMax'",
11
+ "nl": "Fix another 'has no existing object' message bug on pvPower3 + 4\nFix Batterij identificatie van AB2000X en berekening van 'energyWhMax'\nFix Batterij identificatie van AB3000 en berekening van 'energyWhMax'",
12
+ "fr": "Correction d'un autre bug de message 'n'a aucun objet existant' sur pvPower3 + 4\nCorrection de l'identification de la batterie AB2000X et calcul de 'energyWhMax'\nCorrection de l'identification de la batterie AB3000 et calcul de 'energyWhMax'",
13
+ "it": "Fissare un altro 'ha nessun oggetto esistente' messaggio bug su pvPower3 + 4\nFissa l'identificazione della batteria di AB2000X e il calcolo di 'energyWhMax'\nFissa l'identificazione della batteria di AB3000 e il calcolo di 'energyWhMax'",
14
+ "es": "Fijar otro 'no tiene ningún objeto existente' error de mensaje en pvPower3 + 4\nIdentificación de batería de AB2000X y cálculo de 'energíaWhMax'\nIdentificación de batería de AB3000 y cálculo de 'energíaWhMax'",
15
+ "pl": "Napraw kolejny błąd 'nie ma istniejącego obiektu' na pvPower3 + 4\nFix Identyfikacja baterii AB2000X i obliczenia 'energyWhMax'\nNapraw identyfikację baterii AB3000 i obliczanie 'energyWhMax'",
16
+ "uk": "Виправлено інший \"не існуючий об'єкт\" повідомлення про помилку на pvPower3 + 4\nФіксація акумулятора AB2000X та розрахунок \"енергетикиWhMax\"\nФіксація акумулятора AB3000 та розрахунок \"енергетикиWhMax\"",
17
+ "zh-cn": "在 pvPower3 + 4 上修正另一个“ 没有存在对象” 消息错误\n修复电池对AB2000X的识别和“能量WhMax”的计算\n修复电池对AB3000的识别和“能量WhMax”的计算"
18
+ },
6
19
  "3.3.1": {
7
20
  "en": "Fix caluclation issue",
8
21
  "de": "Problem der Calucation behoben",
@@ -80,19 +93,6 @@
80
93
  "pl": "Fix inputLimit na niektórych urządzeniach\nPopraw obliczenia PV3 & 4 ponownie (miejmy nadzieję, że teraz 100%)\nDodaj kilka bardziej szczegółowych wiadomości debugowania\nUsuń mylący komunikat błędu przy uruchomieniu adaptera\nZastąp ponowne uruchomienie podczas kontroli States Job z komunikatem o debugowaniu (myślę, że chmura Zabb jest teraz stabilna)\nAktualizuj adapter do adaptacji- react- v5 (MUI v5)\nNapraw pasek poleceń w ustawieniach",
81
94
  "uk": "Фіксувати вхідОблік на певних пристроях\nФіксований розрахунок ПВ3 та 4 знову (повно зараз 100%)\nДодати більше специфічних повідомлень\nВидаліть повідомлення про помилку в оману на адаптері\nЗамініть перезапуск на перевірку USAJob з повідомленням debug (Я думаю, що хмара Zendure стабільний зараз)\nОновлення адаптера до адаптера-реакт-v5 (MUI v5)\nВиправлення командного рядка в налаштуваннях",
82
95
  "zh-cn": "在某些设备上固定输入范围\n再次修复光电3 & 4 的计算( 希望现在100%)\n添加一些更具体的调试消息\n删除适配器启动时的错误消息\n检查时替换重新启动 有调试消息的国家Job(我认为Zendure云已经稳定了)\n更新适配器到适配器-反应-v5(MUI v5)\n在设置中修正命令栏"
83
- },
84
- "3.1.1": {
85
- "en": "Fix Uppercase 'a4ss5p' in helpers.ts",
86
- "de": "Großbuchstaben 'a4ss5p' in helpers.ts",
87
- "ru": "Исправьте Uppercase 'a4ss5p' в helpers.ts",
88
- "pt": "Corrigir 'a4ss5p' em helpers.ts",
89
- "nl": "Fix Uppercase 'a4ss5p' in helpers.ts",
90
- "fr": "Correction de la case supérieure 'a4ss5p' dans aideurs.ts",
91
- "it": "Fissare Uppercase 'a4ss5p' in helpers.ts",
92
- "es": "Fijar maleta superior 'a4s5p' en helpers.ts",
93
- "pl": "Fix Uppercase 'a4ss5p' in helpers.ts",
94
- "uk": "Фіксація Верхній регістр 'a4ss5p' в помічниках.ts",
95
- "zh-cn": "在助手.ts中修正大写“ a4ss5p ”"
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zendure-solarflow",
3
- "version": "3.3.1",
3
+ "version": "3.3.2",
4
4
  "description": "zendure-solarflow",
5
5
  "author": {
6
6
  "name": "Peter",