iobroker.zendure-solarflow 1.12.3 → 1.12.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
@@ -57,6 +57,10 @@ You can still do firmware updates with the official Zendure app via bluetooth an
57
57
  Credits goes to https://github.com/reinhard-brandstaedter/solarflow which helped a lot with the knowledge about the MQTT server from Zendure! Thanks!
58
58
 
59
59
  ## Changelog
60
+ ### 1.12.4 (2025-03-19)
61
+
62
+ - Fix calculation of SOC if "local" mode is used
63
+
60
64
  ### 1.12.3 (2025-03-19)
61
65
 
62
66
  - Add 2 more devices if "local" mode is used
@@ -73,11 +73,11 @@ const setSocToZero = async (adapter, productKey, deviceKey) => {
73
73
  ));
74
74
  };
75
75
  const calculateSocAndEnergy = async (adapter, productKey, deviceKey, stateKey, value) => {
76
- var _a, _b, _c;
76
+ var _a, _b;
77
77
  adapter.log.debug(
78
78
  `[calculateSocAndEnergy] Calculating for: ${productKey}.${deviceKey} and stateKey ${stateKey}!`
79
79
  );
80
- let energyWhMax = 0;
80
+ let energyWhMax = void 0;
81
81
  const minSoc = (_a = await adapter.getStateAsync(`${productKey}.${deviceKey}.minSoc`)) == null ? void 0 : _a.val;
82
82
  const currentSoc = (_b = await adapter.getStateAsync(`${productKey}.${deviceKey}.electricLevel`)) == null ? void 0 : _b.val;
83
83
  if (currentSoc && minSoc && Number(currentSoc) < Number(minSoc)) {
@@ -86,7 +86,6 @@ const calculateSocAndEnergy = async (adapter, productKey, deviceKey, stateKey, v
86
86
  );
87
87
  return;
88
88
  }
89
- const productName = (_c = await adapter.getStateAsync(`${productKey}.${deviceKey}.productName`)) == null ? void 0 : _c.val;
90
89
  const currentEnergyState = await (adapter == null ? void 0 : adapter.getStateAsync(
91
90
  productKey + "." + deviceKey + ".calculations.energyWh"
92
91
  ));
@@ -103,23 +102,19 @@ const calculateSocAndEnergy = async (adapter, productKey, deviceKey, stateKey, v
103
102
  const batteries = adapter.pack2Devices.filter(
104
103
  (x) => x.deviceKey == deviceKey
105
104
  );
106
- let isAio = false;
107
- if (productName == null ? void 0 : productName.toString().toLowerCase().includes("aio")) {
108
- isAio = true;
109
- }
110
- if (isAio) {
105
+ if (productKey == "yWF7hV") {
111
106
  energyWhMax = 2400;
112
107
  } else {
113
108
  for (let i = 0; i < batteries.length; i++) {
114
109
  if (batteries[i].type == "AB1000") {
115
- energyWhMax = energyWhMax + 960;
110
+ energyWhMax = (energyWhMax ? energyWhMax : 0) + 960;
116
111
  } else if (batteries[i].type == "AB2000") {
117
- energyWhMax = energyWhMax + 1920;
112
+ energyWhMax = (energyWhMax ? energyWhMax : 0) + 1920;
118
113
  }
119
114
  }
120
115
  }
121
116
  let newEnergyWh = stateKey == "outputPack" ? currentEnergyWh + value : currentEnergyWh - value;
122
- if (stateKey == "outputPack" && newEnergyWh > energyWhMax) {
117
+ if (stateKey == "outputPack" && energyWhMax != void 0 && newEnergyWh > energyWhMax) {
123
118
  newEnergyWh = energyWhMax;
124
119
  adapter.log.debug(
125
120
  `[calculateSocAndEnergy] newEnergyWh (${newEnergyWh}) is greater than energyWhMax (${energyWhMax}), don't extend value!`
@@ -206,7 +201,7 @@ const calculateSocAndEnergy = async (adapter, productKey, deviceKey, stateKey, v
206
201
  true
207
202
  ));
208
203
  const newEnergyWhPositive = Math.abs(newEnergyWh);
209
- if (currentMaxValue + newEnergyWhPositive <= energyWhMax) {
204
+ if (energyWhMax && currentMaxValue + newEnergyWhPositive <= energyWhMax) {
210
205
  await (adapter == null ? void 0 : adapter.setState(
211
206
  `${productKey}.${deviceKey}.calculations.energyWhMax`,
212
207
  currentMaxValue + newEnergyWhPositive,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/services/calculationService.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\n\r\nimport { toHoursAndMinutes } from \"../helpers/timeHelper\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\n\r\nconst calculationStateKeys = [\r\n \"packInput\",\r\n \"outputHome\",\r\n \"outputPack\",\r\n \"outputPack\",\r\n \"solarInput\",\r\n \"gridInput\",\r\n \"pvPower1\",\r\n \"pvPower2\",\r\n];\r\n\r\nexport const setEnergyWhMax = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n const currentEnergyState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWh\"\r\n );\r\n\r\n if (currentEnergyState) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n currentEnergyState?.val,\r\n true\r\n );\r\n }\r\n};\r\n\r\nexport const setSocToZero = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n // Set SOC to 0\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.soc`,\r\n 0,\r\n true\r\n );\r\n\r\n // Calculate new Wh Max Value\r\n const energyWhState = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.calculations.energyWh`\r\n );\r\n const energyWhMaxState = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`\r\n );\r\n\r\n const newMax = Number(energyWhMaxState?.val) - Number(energyWhState?.val);\r\n\r\n // Set Max Energy to value minus current energy\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n newMax,\r\n true\r\n );\r\n\r\n // Set Energy in Battery to 0\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWh`,\r\n 0,\r\n true\r\n );\r\n};\r\n\r\nexport const calculateSocAndEnergy = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n stateKey: string,\r\n value: number\r\n): Promise<void> => {\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] Calculating for: ${productKey}.${deviceKey} and stateKey ${stateKey}!`\r\n );\r\n\r\n let energyWhMax = 0;\r\n\r\n const minSoc = (\r\n await adapter.getStateAsync(`${productKey}.${deviceKey}.minSoc`)\r\n )?.val;\r\n const currentSoc = (\r\n await adapter.getStateAsync(`${productKey}.${deviceKey}.electricLevel`)\r\n )?.val;\r\n\r\n if (currentSoc && minSoc && Number(currentSoc) < Number(minSoc)) {\r\n // Don't calculate if current SOC is lower then minimum\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] Don't calculate, currentSoc (${Number(currentSoc)}) is lower than minSoc (${Number(minSoc)})!`\r\n );\r\n\r\n return;\r\n }\r\n\r\n const productName = (\r\n await adapter.getStateAsync(`${productKey}.${deviceKey}.productName`)\r\n )?.val;\r\n\r\n const currentEnergyState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWh\"\r\n );\r\n\r\n const currentEnergyMaxState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWhMax\"\r\n );\r\n\r\n const lowVoltageBlock = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n\r\n const currentMaxValue = Number(\r\n currentEnergyMaxState ? currentEnergyMaxState.val : 0\r\n );\r\n\r\n const currentEnergyWh = currentEnergyState?.val\r\n ? Number(currentEnergyState?.val)\r\n : 0;\r\n\r\n const batteries = adapter.pack2Devices.filter(\r\n (x) => x.deviceKey == deviceKey\r\n );\r\n\r\n let isAio = false;\r\n // Check if device is an solarflow or hyper device. Don't use LowVoltageBlock on an ACE device?\r\n if (productName?.toString().toLowerCase().includes(\"aio\")) {\r\n isAio = true;\r\n }\r\n\r\n if (isAio) {\r\n energyWhMax = 2400;\r\n } else {\r\n for (let i = 0; i < batteries.length; i++) {\r\n if (batteries[i].type == \"AB1000\") {\r\n energyWhMax = energyWhMax + 960;\r\n } else if (batteries[i].type == \"AB2000\") {\r\n energyWhMax = energyWhMax + 1920;\r\n }\r\n }\r\n }\r\n\r\n // newValue is the current available energy in the batteries. If outputPack (charging) add value, if packInput (discharging) subtract value.\r\n let newEnergyWh =\r\n stateKey == \"outputPack\"\r\n ? currentEnergyWh + value\r\n : currentEnergyWh - value;\r\n\r\n // If greater than Max of batteries, set it to this value.\r\n if (stateKey == \"outputPack\" && newEnergyWh > energyWhMax) {\r\n newEnergyWh = energyWhMax;\r\n\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] newEnergyWh (${newEnergyWh}) is greater than energyWhMax (${energyWhMax}), don't extend value!`\r\n );\r\n }\r\n\r\n if (newEnergyWh > 0) {\r\n adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWh`,\r\n newEnergyWh,\r\n true\r\n );\r\n\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] set '${productKey}.${deviceKey}.calculations.energyWh' to ${newEnergyWh}!`\r\n );\r\n\r\n if (currentEnergyMaxState) {\r\n const soc = Number(((newEnergyWh / currentMaxValue) * 100).toFixed(1));\r\n\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.soc`,\r\n soc > 100.0 ? 100 : soc,\r\n true\r\n );\r\n\r\n if (newEnergyWh > currentMaxValue && !lowVoltageBlock?.val) {\r\n // Extend maxVal\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n newEnergyWh,\r\n true\r\n );\r\n }\r\n\r\n const currentOutputPackPower = await adapter?.getStateAsync(\r\n `${productKey}.${deviceKey}.outputPackPower`\r\n );\r\n\r\n const currentPackInputPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".packInputPower\"\r\n );\r\n\r\n if (\r\n stateKey == \"outputPack\" &&\r\n currentOutputPackPower?.val != null &&\r\n currentOutputPackPower != undefined\r\n ) {\r\n // Charging, calculate remaining charging time\r\n const toCharge = currentMaxValue - newEnergyWh;\r\n\r\n const remainHoursAsDecimal =\r\n toCharge / Number(currentOutputPackPower.val);\r\n\r\n if (remainHoursAsDecimal < 48.0) {\r\n const remainFormatted = toHoursAndMinutes(\r\n Math.round(remainHoursAsDecimal * 60)\r\n );\r\n\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n remainFormatted,\r\n true\r\n );\r\n } else {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n } else if (\r\n stateKey == \"packInput\" &&\r\n currentPackInputPower != null &&\r\n currentPackInputPower != undefined\r\n ) {\r\n // Discharging, calculate remaining discharge time\r\n const remainHoursAsDecimal =\r\n newEnergyWh / Number(currentPackInputPower.val);\r\n const remainFormatted = toHoursAndMinutes(\r\n Math.round(remainHoursAsDecimal * 60)\r\n );\r\n\r\n if (remainHoursAsDecimal < 48.0) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n remainFormatted,\r\n true\r\n );\r\n } else {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n }\r\n }\r\n } else if (newEnergyWh <= 0 && stateKey == \"outputPack\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n } else if (newEnergyWh <= 0 && stateKey == \"packInput\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n\r\n // TEST: if SOC == 0, add newValue as positive to energyWhMax\r\n const newEnergyWhPositive = Math.abs(newEnergyWh);\r\n\r\n if (currentMaxValue + newEnergyWhPositive <= energyWhMax) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n currentMaxValue + newEnergyWhPositive,\r\n true\r\n );\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Calculates the energy for all items in 'calculationStateKeys'.\r\n *\r\n * @param adapter - The core adapter object\r\n * @param productKey - The productKey of the device\r\n * @param deviceKey - The device individual key\r\n * @returns Promise<void>\r\n *\r\n * @beta\r\n */\r\nexport const calculateEnergy = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n calculationStateKeys.forEach(async (stateKey) => {\r\n let stateNameEnergyWh = \"\";\r\n let stateNameEnergykWh = \"\";\r\n let stateNamePower = \"\";\r\n\r\n if (stateKey == \"pvPower1\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.pvPower1`;\r\n } else if (stateKey == \"pvPower2\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.pvPower2`;\r\n } else {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.${stateKey}Power`;\r\n }\r\n\r\n const currentPowerState = await adapter?.getStateAsync(stateNamePower);\r\n const currentEnergyState = await adapter?.getStateAsync(stateNameEnergyWh);\r\n\r\n if (currentEnergyState?.val == 0) {\r\n // Workaround, set Val to very low value to avoid Jump in data...\r\n await adapter?.setState(stateNameEnergyWh, 0.000001, true);\r\n } else if (\r\n currentEnergyState &&\r\n currentEnergyState.lc &&\r\n currentPowerState &&\r\n currentPowerState.val != undefined &&\r\n currentPowerState.val != null\r\n ) {\r\n // Timeframe = 30000ms, Job runs every 30 seconds...\r\n const timeFrame = 30000;\r\n\r\n // Calculate Energy value (Wh) from current power in the timeframe from last run...\r\n let addEnergyValue =\r\n (Number(currentPowerState.val) * timeFrame) / 3600000; // Wh\r\n\r\n // Use efficiency factor (used the one from Youtube Channel VoltAmpereLux - thanks!)\r\n const chargingFactor = 0.96; // Efficiency 96%\r\n const dischargingFactor = 1.08 - addEnergyValue / 10000; // Efficiency 92% - 98% (92% + Energy / 10000 = 600W -> +6%)\r\n\r\n // Calculate energy from efficiency factor if value for charging or discharging\r\n addEnergyValue =\r\n stateKey == \"outputPack\" && addEnergyValue > 0\r\n ? addEnergyValue * chargingFactor\r\n : addEnergyValue;\r\n addEnergyValue =\r\n stateKey == \"packInput\" && addEnergyValue > 0\r\n ? addEnergyValue * dischargingFactor\r\n : addEnergyValue;\r\n\r\n let newEnergyValue = Number(currentEnergyState.val) + addEnergyValue;\r\n\r\n // Fix negative value\r\n if (newEnergyValue < 0) {\r\n newEnergyValue = 0;\r\n }\r\n\r\n await adapter?.setState(stateNameEnergyWh, newEnergyValue, true);\r\n await adapter?.setState(\r\n stateNameEnergykWh,\r\n Number((newEnergyValue / 1000).toFixed(2)),\r\n true\r\n );\r\n\r\n // SOC and energy in batteries\r\n if (\r\n (stateKey == \"outputPack\" || stateKey == \"packInput\") &&\r\n addEnergyValue > 0\r\n ) {\r\n await calculateSocAndEnergy(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n stateKey,\r\n addEnergyValue\r\n );\r\n } else {\r\n if (stateKey == \"outputPack\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n } else if (stateKey == \"packInput\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n }\r\n } else {\r\n await adapter?.setState(stateNameEnergyWh, 0, true);\r\n await adapter?.setState(stateNameEnergykWh, 0, true);\r\n }\r\n });\r\n};\r\n\r\nconst resetValuesForDevice = (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n) => {\r\n calculationStateKeys.forEach(async (stateKey: string) => {\r\n let stateNameEnergyWh = \"\";\r\n let stateNameEnergykWh = \"\";\r\n\r\n if (stateKey == \"pvPower1\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\r\n } else if (stateKey == \"pvPower2\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\r\n } else {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\r\n }\r\n\r\n await adapter?.setState(stateNameEnergyWh, 0, true);\r\n await adapter?.setState(stateNameEnergykWh, 0, true);\r\n });\r\n};\r\n\r\nexport const resetTodaysValues = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n if (adapter.config.server == \"local\") {\r\n if (\r\n adapter.config.localDevice1ProductKey &&\r\n adapter.config.localDevice1DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice2ProductKey &&\r\n adapter.config.localDevice2DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice3ProductKey &&\r\n adapter.config.localDevice3DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice4ProductKey &&\r\n adapter.config.localDevice4DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey\r\n );\r\n }\r\n } else {\r\n adapter.deviceList.forEach((device: ISolarFlowDeviceDetails) => {\r\n resetValuesForDevice(adapter, device.productKey, device.deviceKey);\r\n\r\n if (device.packList && device.packList.length > 0) {\r\n device.packList.forEach(async (subDevice) => {\r\n if (subDevice.productName.toLocaleLowerCase() == \"ace 1500\") {\r\n resetValuesForDevice(\r\n adapter,\r\n subDevice.productKey,\r\n subDevice.deviceKey\r\n );\r\n }\r\n });\r\n }\r\n });\r\n }\r\n};\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\n\r\nimport { toHoursAndMinutes } from \"../helpers/timeHelper\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\n\r\nconst calculationStateKeys = [\r\n \"packInput\",\r\n \"outputHome\",\r\n \"outputPack\",\r\n \"outputPack\",\r\n \"solarInput\",\r\n \"gridInput\",\r\n \"pvPower1\",\r\n \"pvPower2\",\r\n];\r\n\r\nexport const setEnergyWhMax = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n const currentEnergyState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWh\"\r\n );\r\n\r\n if (currentEnergyState) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n currentEnergyState?.val,\r\n true\r\n );\r\n }\r\n};\r\n\r\nexport const setSocToZero = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n // Set SOC to 0\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.soc`,\r\n 0,\r\n true\r\n );\r\n\r\n // Calculate new Wh Max Value\r\n const energyWhState = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.calculations.energyWh`\r\n );\r\n const energyWhMaxState = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`\r\n );\r\n\r\n const newMax = Number(energyWhMaxState?.val) - Number(energyWhState?.val);\r\n\r\n // Set Max Energy to value minus current energy\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n newMax,\r\n true\r\n );\r\n\r\n // Set Energy in Battery to 0\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWh`,\r\n 0,\r\n true\r\n );\r\n};\r\n\r\nexport const calculateSocAndEnergy = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n stateKey: string,\r\n value: number\r\n): Promise<void> => {\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] Calculating for: ${productKey}.${deviceKey} and stateKey ${stateKey}!`\r\n );\r\n\r\n let energyWhMax: number | undefined = undefined;\r\n\r\n const minSoc = (\r\n await adapter.getStateAsync(`${productKey}.${deviceKey}.minSoc`)\r\n )?.val;\r\n const currentSoc = (\r\n await adapter.getStateAsync(`${productKey}.${deviceKey}.electricLevel`)\r\n )?.val;\r\n\r\n if (currentSoc && minSoc && Number(currentSoc) < Number(minSoc)) {\r\n // Don't calculate if current SOC is lower then minimum\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] Don't calculate, currentSoc (${Number(currentSoc)}) is lower than minSoc (${Number(minSoc)})!`\r\n );\r\n\r\n return;\r\n }\r\n\r\n const currentEnergyState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWh\"\r\n );\r\n\r\n const currentEnergyMaxState = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".calculations.energyWhMax\"\r\n );\r\n\r\n const lowVoltageBlock = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n\r\n const currentMaxValue = Number(\r\n currentEnergyMaxState ? currentEnergyMaxState.val : 0\r\n );\r\n\r\n const currentEnergyWh = currentEnergyState?.val\r\n ? Number(currentEnergyState?.val)\r\n : 0;\r\n\r\n const batteries = adapter.pack2Devices.filter(\r\n (x) => x.deviceKey == deviceKey\r\n );\r\n\r\n if (productKey == \"yWF7hV\") {\r\n // The device is an AIO 2400, so set maximum Wh to 2400!\r\n energyWhMax = 2400;\r\n } else {\r\n // Iterate over all batteries!\r\n for (let i = 0; i < batteries.length; i++) {\r\n if (batteries[i].type == \"AB1000\") {\r\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 960;\r\n } else if (batteries[i].type == \"AB2000\") {\r\n energyWhMax = (energyWhMax ? energyWhMax : 0) + 1920;\r\n }\r\n }\r\n }\r\n\r\n // newValue is the current available energy in the batteries. If outputPack (charging) add value, if packInput (discharging) subtract value.\r\n let newEnergyWh =\r\n stateKey == \"outputPack\"\r\n ? currentEnergyWh + value\r\n : currentEnergyWh - value;\r\n\r\n // If greater than Max of batteries, set it to this value.\r\n if (\r\n stateKey == \"outputPack\" &&\r\n energyWhMax != undefined &&\r\n newEnergyWh > energyWhMax\r\n ) {\r\n newEnergyWh = energyWhMax;\r\n\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] newEnergyWh (${newEnergyWh}) is greater than energyWhMax (${energyWhMax}), don't extend value!`\r\n );\r\n }\r\n\r\n if (newEnergyWh > 0) {\r\n adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWh`,\r\n newEnergyWh,\r\n true\r\n );\r\n\r\n adapter.log.debug(\r\n `[calculateSocAndEnergy] set '${productKey}.${deviceKey}.calculations.energyWh' to ${newEnergyWh}!`\r\n );\r\n\r\n if (currentEnergyMaxState) {\r\n const soc = Number(((newEnergyWh / currentMaxValue) * 100).toFixed(1));\r\n\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.soc`,\r\n soc > 100.0 ? 100 : soc,\r\n true\r\n );\r\n\r\n if (newEnergyWh > currentMaxValue && !lowVoltageBlock?.val) {\r\n // Extend maxVal\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n newEnergyWh,\r\n true\r\n );\r\n }\r\n\r\n const currentOutputPackPower = await adapter?.getStateAsync(\r\n `${productKey}.${deviceKey}.outputPackPower`\r\n );\r\n\r\n const currentPackInputPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".packInputPower\"\r\n );\r\n\r\n if (\r\n stateKey == \"outputPack\" &&\r\n currentOutputPackPower?.val != null &&\r\n currentOutputPackPower != undefined\r\n ) {\r\n // Charging, calculate remaining charging time\r\n const toCharge = currentMaxValue - newEnergyWh;\r\n\r\n const remainHoursAsDecimal =\r\n toCharge / Number(currentOutputPackPower.val);\r\n\r\n if (remainHoursAsDecimal < 48.0) {\r\n const remainFormatted = toHoursAndMinutes(\r\n Math.round(remainHoursAsDecimal * 60)\r\n );\r\n\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n remainFormatted,\r\n true\r\n );\r\n } else {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n } else if (\r\n stateKey == \"packInput\" &&\r\n currentPackInputPower != null &&\r\n currentPackInputPower != undefined\r\n ) {\r\n // Discharging, calculate remaining discharge time\r\n const remainHoursAsDecimal =\r\n newEnergyWh / Number(currentPackInputPower.val);\r\n const remainFormatted = toHoursAndMinutes(\r\n Math.round(remainHoursAsDecimal * 60)\r\n );\r\n\r\n if (remainHoursAsDecimal < 48.0) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n remainFormatted,\r\n true\r\n );\r\n } else {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n }\r\n }\r\n } else if (newEnergyWh <= 0 && stateKey == \"outputPack\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n } else if (newEnergyWh <= 0 && stateKey == \"packInput\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n\r\n // TEST: if SOC == 0, add newValue as positive to energyWhMax\r\n const newEnergyWhPositive = Math.abs(newEnergyWh);\r\n\r\n if (energyWhMax && currentMaxValue + newEnergyWhPositive <= energyWhMax) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.energyWhMax`,\r\n currentMaxValue + newEnergyWhPositive,\r\n true\r\n );\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Calculates the energy for all items in 'calculationStateKeys'.\r\n *\r\n * @param adapter - The core adapter object\r\n * @param productKey - The productKey of the device\r\n * @param deviceKey - The device individual key\r\n * @returns Promise<void>\r\n *\r\n * @beta\r\n */\r\nexport const calculateEnergy = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n calculationStateKeys.forEach(async (stateKey) => {\r\n let stateNameEnergyWh = \"\";\r\n let stateNameEnergykWh = \"\";\r\n let stateNamePower = \"\";\r\n\r\n if (stateKey == \"pvPower1\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.pvPower1`;\r\n } else if (stateKey == \"pvPower2\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.pvPower2`;\r\n } else {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\r\n stateNamePower = `${productKey}.${deviceKey}.${stateKey}Power`;\r\n }\r\n\r\n const currentPowerState = await adapter?.getStateAsync(stateNamePower);\r\n const currentEnergyState = await adapter?.getStateAsync(stateNameEnergyWh);\r\n\r\n if (currentEnergyState?.val == 0) {\r\n // Workaround, set Val to very low value to avoid Jump in data...\r\n await adapter?.setState(stateNameEnergyWh, 0.000001, true);\r\n } else if (\r\n currentEnergyState &&\r\n currentEnergyState.lc &&\r\n currentPowerState &&\r\n currentPowerState.val != undefined &&\r\n currentPowerState.val != null\r\n ) {\r\n // Timeframe = 30000ms, Job runs every 30 seconds...\r\n const timeFrame = 30000;\r\n\r\n // Calculate Energy value (Wh) from current power in the timeframe from last run...\r\n let addEnergyValue =\r\n (Number(currentPowerState.val) * timeFrame) / 3600000; // Wh\r\n\r\n // Use efficiency factor (used the one from Youtube Channel VoltAmpereLux - thanks!)\r\n const chargingFactor = 0.96; // Efficiency 96%\r\n const dischargingFactor = 1.08 - addEnergyValue / 10000; // Efficiency 92% - 98% (92% + Energy / 10000 = 600W -> +6%)\r\n\r\n // Calculate energy from efficiency factor if value for charging or discharging\r\n addEnergyValue =\r\n stateKey == \"outputPack\" && addEnergyValue > 0\r\n ? addEnergyValue * chargingFactor\r\n : addEnergyValue;\r\n addEnergyValue =\r\n stateKey == \"packInput\" && addEnergyValue > 0\r\n ? addEnergyValue * dischargingFactor\r\n : addEnergyValue;\r\n\r\n let newEnergyValue = Number(currentEnergyState.val) + addEnergyValue;\r\n\r\n // Fix negative value\r\n if (newEnergyValue < 0) {\r\n newEnergyValue = 0;\r\n }\r\n\r\n await adapter?.setState(stateNameEnergyWh, newEnergyValue, true);\r\n await adapter?.setState(\r\n stateNameEnergykWh,\r\n Number((newEnergyValue / 1000).toFixed(2)),\r\n true\r\n );\r\n\r\n // SOC and energy in batteries\r\n if (\r\n (stateKey == \"outputPack\" || stateKey == \"packInput\") &&\r\n addEnergyValue > 0\r\n ) {\r\n await calculateSocAndEnergy(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n stateKey,\r\n addEnergyValue\r\n );\r\n } else {\r\n if (stateKey == \"outputPack\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainInputTime`,\r\n \"\",\r\n true\r\n );\r\n } else if (stateKey == \"packInput\") {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.calculations.remainOutTime`,\r\n \"\",\r\n true\r\n );\r\n }\r\n }\r\n } else {\r\n await adapter?.setState(stateNameEnergyWh, 0, true);\r\n await adapter?.setState(stateNameEnergykWh, 0, true);\r\n }\r\n });\r\n};\r\n\r\nconst resetValuesForDevice = (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n) => {\r\n calculationStateKeys.forEach(async (stateKey: string) => {\r\n let stateNameEnergyWh = \"\";\r\n let stateNameEnergykWh = \"\";\r\n\r\n if (stateKey == \"pvPower1\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv1EnergyTodaykWh`;\r\n } else if (stateKey == \"pvPower2\") {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.solarInputPv2EnergyTodaykWh`;\r\n } else {\r\n stateNameEnergyWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodayWh`;\r\n stateNameEnergykWh = `${productKey}.${deviceKey}.calculations.${stateKey}EnergyTodaykWh`;\r\n }\r\n\r\n await adapter?.setState(stateNameEnergyWh, 0, true);\r\n await adapter?.setState(stateNameEnergykWh, 0, true);\r\n });\r\n};\r\n\r\nexport const resetTodaysValues = async (\r\n adapter: ZendureSolarflow\r\n): Promise<void> => {\r\n if (adapter.config.server == \"local\") {\r\n if (\r\n adapter.config.localDevice1ProductKey &&\r\n adapter.config.localDevice1DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice2ProductKey &&\r\n adapter.config.localDevice2DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice3ProductKey &&\r\n adapter.config.localDevice3DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey\r\n );\r\n }\r\n\r\n if (\r\n adapter.config.localDevice4ProductKey &&\r\n adapter.config.localDevice4DeviceKey\r\n ) {\r\n resetValuesForDevice(\r\n adapter,\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey\r\n );\r\n }\r\n } else {\r\n adapter.deviceList.forEach((device: ISolarFlowDeviceDetails) => {\r\n resetValuesForDevice(adapter, device.productKey, device.deviceKey);\r\n\r\n if (device.packList && device.packList.length > 0) {\r\n device.packList.forEach(async (subDevice) => {\r\n if (subDevice.productName.toLocaleLowerCase() == \"ace 1500\") {\r\n resetValuesForDevice(\r\n adapter,\r\n subDevice.productKey,\r\n subDevice.deviceKey\r\n );\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": "1.12.3",
4
+ "version": "1.12.4",
5
5
  "news": {
6
+ "1.12.4": {
7
+ "en": "Fix calculation of SOC if \"local\" mode is used",
8
+ "de": "Fixe Berechnung von SOC, wenn \"lokal\" Modus verwendet wird",
9
+ "ru": "Исправьте расчет SOC, если используется «местный» режим",
10
+ "pt": "Corrigir o cálculo do SOC se o modo \"local\" for usado",
11
+ "nl": "Berekening van SOC repareren als de \"lokale\" modus wordt gebruikt",
12
+ "fr": "Correction du calcul de SOC si le mode \"local\" est utilisé",
13
+ "it": "Fissare il calcolo di SOC se viene utilizzata la modalità \"locale\"",
14
+ "es": "Cálculo fijo de SOC si se utiliza el modo \"local\"",
15
+ "pl": "Popraw obliczanie SOC, jeśli używany jest tryb \"lokalny\"",
16
+ "uk": "Фіксований розрахунок СОУ, якщо використовується режим «локального»",
17
+ "zh-cn": "如果使用“ 本地” 模式, 固定 SOC 的计算"
18
+ },
6
19
  "1.12.3": {
7
20
  "en": "Add 2 more devices if \"local\" mode is used\nFix mqtt subscription of 2. device in \"local\" mode",
8
21
  "de": "Fügen Sie 2 weitere Geräte hinzu, wenn \"lokal\" Modus verwendet wird\nFix mqt Abonnement von 2. Gerät im \"lokalen\" Modus",
@@ -80,19 +93,6 @@
80
93
  "pl": "Popraw wartości obliczeniowe resetu ACE, jeśli podłączone do HUB",
81
94
  "uk": "Виправлення значень розрахунку скидання ACE при підключенні до HUB",
82
95
  "zh-cn": "修复连接到 HUB 的 ACE 计算值"
83
- },
84
- "1.10.6": {
85
- "en": "Fix start of calculation if HUB is connected with Ace",
86
- "de": "Fix Beginn der Berechnung, wenn HUB mit Ace verbunden ist",
87
- "ru": "Исправить начало расчета, если HUB подключен к Ace",
88
- "pt": "Corrigir o início do cálculo se HUB estiver conectado com Ace",
89
- "nl": "Fix begin van berekening als HUB is verbonden met Ace",
90
- "fr": "Correction du début du calcul si HUB est connecté à Ace",
91
- "it": "Fissare l'inizio del calcolo se HUB è collegato con Ace",
92
- "es": "Arranque el inicio del cálculo si HUB está conectado con Ace",
93
- "pl": "Popraw początek obliczeń, jeśli HUB jest połączony z Asem",
94
- "uk": "Виправлення запуску розрахунку, якщо HUB підключено до Ace",
95
- "zh-cn": "如果 HUB 与 Ace 连接, 则固定开始计算"
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": "1.12.3",
3
+ "version": "1.12.4",
4
4
  "description": "zendure-solarflow",
5
5
  "author": {
6
6
  "name": "Peter",