iobroker.zendure-solarflow 3.0.3 → 3.0.4

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,6 +59,11 @@ 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.0.4 (2025-10-09)
63
+
64
+ - Fix inputLimit issue
65
+ - Fix Wifi status not updating when packData changes
66
+
62
67
  ### 3.0.3 (2025-10-07)
63
68
 
64
69
  - Optimize setting of wifiMode in local mode
@@ -137,6 +137,12 @@ class ZenHaDevice {
137
137
  (/* @__PURE__ */ new Date()).getTime(),
138
138
  true
139
139
  ));
140
+ const currentWifiState = await this.adapter.getStateAsync(
141
+ `${this.productKey}.${this.deviceKey}.wifiState`
142
+ );
143
+ if (currentWifiState && currentWifiState.val == "Disconnected") {
144
+ this.updateSolarFlowState("wifiState", "Connected");
145
+ }
140
146
  }
141
147
  await ((_j = this.adapter) == null ? void 0 : _j.extendObject(key + ".maxTemp", {
142
148
  type: "state",
@@ -171,6 +177,12 @@ class ZenHaDevice {
171
177
  (/* @__PURE__ */ new Date()).getTime(),
172
178
  true
173
179
  ));
180
+ const currentWifiState = await this.adapter.getStateAsync(
181
+ `${this.productKey}.${this.deviceKey}.wifiState`
182
+ );
183
+ if (currentWifiState && currentWifiState.val == "Disconnected") {
184
+ this.updateSolarFlowState("wifiState", "Connected");
185
+ }
174
186
  }
175
187
  await ((_n = this.adapter) == null ? void 0 : _n.extendObject(key + ".minVol", {
176
188
  type: "state",
@@ -214,6 +226,12 @@ class ZenHaDevice {
214
226
  (/* @__PURE__ */ new Date()).getTime(),
215
227
  true
216
228
  ));
229
+ const currentWifiState = await this.adapter.getStateAsync(
230
+ `${this.productKey}.${this.deviceKey}.wifiState`
231
+ );
232
+ if (currentWifiState && currentWifiState.val == "Disconnected") {
233
+ this.updateSolarFlowState("wifiState", "Connected");
234
+ }
217
235
  }
218
236
  await ((_t = this.adapter) == null ? void 0 : _t.extendObject(key + ".maxVol", {
219
237
  type: "state",
@@ -241,6 +259,12 @@ class ZenHaDevice {
241
259
  (/* @__PURE__ */ new Date()).getTime(),
242
260
  true
243
261
  ));
262
+ const currentWifiState = await this.adapter.getStateAsync(
263
+ `${this.productKey}.${this.deviceKey}.wifiState`
264
+ );
265
+ if (currentWifiState && currentWifiState.val == "Disconnected") {
266
+ this.updateSolarFlowState("wifiState", "Connected");
267
+ }
244
268
  }
245
269
  await ((_x = this.adapter) == null ? void 0 : _x.extendObject(key + ".totalVol", {
246
270
  type: "state",
@@ -855,8 +879,8 @@ class ZenHaDevice {
855
879
  limit = 0;
856
880
  } else if (limit > 0 && limit <= 30) {
857
881
  limit = 30;
858
- } else if (limit > -this.maxInputLimit) {
859
- limit = -this.maxInputLimit;
882
+ } else if (limit > this.maxInputLimit) {
883
+ limit = this.maxInputLimit;
860
884
  }
861
885
  if (this.productKey.includes("8bm93h")) {
862
886
  limit = Math.ceil(limit / 100) * 100;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/models/deviceModels/ZenHaDevice.ts"],
4
- "sourcesContent": ["import { 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 batteries: IDevicePack[] = [];\n\n public iotTopic: string = \"\";\n public functionTopic = \"\";\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 // 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.adapter.msgCounter += 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 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\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\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\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\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 if (stateKey == \"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 } else if (stateKey == \"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 } else {\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 }\n\n const currentPowerState =\n await this.adapter?.getStateAsync(stateNamePower);\n const currentEnergyState =\n await this.adapter?.getStateAsync(stateNameEnergyWh);\n\n if (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 {\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\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 const currentEnergyWh = currentEnergyState?.val\n ? Number(currentEnergyState?.val)\n : 0;\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 if (stateKey == \"pvPower1\") {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n } else if (stateKey == \"pvPower2\") {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n } else {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\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 { 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 batteries: IDevicePack[] = [];\n\n public iotTopic: string = \"\";\n public functionTopic = \"\";\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 // 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.adapter.msgCounter += 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 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 if (stateKey == \"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 } else if (stateKey == \"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 } else {\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 }\n\n const currentPowerState =\n await this.adapter?.getStateAsync(stateNamePower);\n const currentEnergyState =\n await this.adapter?.getStateAsync(stateNameEnergyWh);\n\n if (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 {\n await this.adapter?.setState(stateNameEnergyWh, 0, true);\n await this.adapter?.setState(stateNameEnergykWh, 0, true);\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 const currentEnergyWh = currentEnergyState?.val\n ? Number(currentEnergyState?.val)\n : 0;\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 if (stateKey == \"pvPower1\") {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\n } else if (stateKey == \"pvPower2\") {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\n } else {\n stateNameEnergyWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodayWh`;\n stateNameEnergykWh = `${this.productKey}.${this.deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\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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",
6
6
  "names": ["key", "_a", "_b"]
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zendure-solarflow",
4
- "version": "3.0.3",
4
+ "version": "3.0.4",
5
5
  "news": {
6
+ "3.0.4": {
7
+ "en": "Fix inputLimit issue\nFix Wifi status not updating when packData changes",
8
+ "de": "InputLimit Problem beheben\nWifi-Status nicht aktualisieren, wenn packData Änderungen",
9
+ "ru": "Исправить ошибку inputLimit issue\nСтатус Wi-Fi не обновляется при изменении пакетных данных",
10
+ "pt": "Corrigir a entradaLimit issue\nCorrigir o estado do Wifi não actualizado quando o pacote de dados mudar",
11
+ "nl": "Fix inputLimit probleem\nFix Wifi-status niet bijwerken wanneer packData wijzigingen",
12
+ "fr": "Correction du problème d'entréeLimit\nCorrection de l'état Wifi non mis à jour lorsque le paquetLes données changent",
13
+ "it": "Risolvere il numero di inputLimit\nFissare lo stato Wifi non aggiornando quando PackData cambia",
14
+ "es": "Corrección de entrada\nFijar el estado de Wifi no actualizar cuando el paqueteLos cambios de datos",
15
+ "pl": "Fix inputLimit wydania\nNaprawianie stanu Wifi nie aktualizuje się przy zmianie PackData",
16
+ "uk": "Виправлення вхідного номера\nВиправлення стану Wifi не оновлення при зміні пакетаData",
17
+ "zh-cn": "修正输入范围\nBackData 更改时不更新 Wifi 状态"
18
+ },
6
19
  "3.0.3": {
7
20
  "en": "Optimize setting of wifiMode in local mode\nOptimize Debug option",
8
21
  "de": "Optimieren Sie die Einstellung von wifiMode im lokalen Modus\nOptimierung der Debug-Option",
@@ -80,19 +93,6 @@
80
93
  "pl": "Dodano \"B3Dxda\" jako nowy klucz urządzenia Hyper 2000. Usunięto parametr 'upTime' i 'pullTime' z 'setDeviceAutomationInOutLimit'. TEST: Użyj 'setDeviceAutomationInOutLimit', aby umożliwić ładowanie HUB1200/HUB2000 z podłączonym ACE 1500.",
81
94
  "uk": "Додано 'B3Dxda' як новий Hyper 2000 productKey. Видалено параметри 'upTime' та 'pullTime' з 'setDeviceAutomationInOutLimit'. ТЕСТ: Використовуйте 'setDeviceAutomationInOutLimit', щоб дозволити HUB1200/HUB2000 заряджатися з підключеним ACE 1500",
82
95
  "zh-cn": "Added 'B3Dxda' as new Hyper 2000 productKey. Removed parameter 'upTime' and 'pullTime' from 'setDeviceAutomationInOutLimit'. TEST: Use 'setDeviceAutomationInOutLimit' to let HUB1200/HUB2000 charge with connected ACE 1500"
83
- },
84
- "2.0.1": {
85
- "en": "Small fix MQTT service",
86
- "de": "Kleiner MQTT-Service",
87
- "ru": "Небольшой ремонт MQTT",
88
- "pt": "Pequeno serviço de correção MQTT",
89
- "nl": "Kleine reparatie MQTT service",
90
- "fr": "Petit service MQTT fixe",
91
- "it": "Servizio MQTT piccolo fix",
92
- "es": "Servicio de fijación pequeña MQTT",
93
- "pl": "Usługa małej naprawy MQTT",
94
- "uk": "Невелика фіксація MQTT сервіс",
95
- "zh-cn": "小修补 MQTT 服务"
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.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "zendure-solarflow",
5
5
  "author": {
6
6
  "name": "Peter",