iobroker.zendure-solarflow 2.0.0-alpha.1 → 2.0.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/services/mqttService.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport * as mqtt from \"mqtt\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\nimport {\r\n checkVoltage,\r\n updateSolarFlowControlState,\r\n updateSolarFlowState,\r\n} from \"./adapterService\";\r\nimport { IPackData } from \"../models/IPackData\";\r\nimport { setEnergyWhMax, setSocToZero } from \"./calculationService\";\r\nimport { IMqttData } from \"../models/ISolarFlowMqttProperties\";\r\nimport {\r\n startCalculationJob,\r\n startCheckStatesAndConnectionJob,\r\n startResetValuesJob,\r\n} from \"./jobSchedule\";\r\nimport { createSolarFlowLocalStates } from \"../helpers/createSolarFlowLocalStates\";\r\nimport { ISolarflowState } from \"../models/ISolarflowState\";\r\nimport { getStateDefinition } from \"../helpers/createSolarFlowStates\";\r\nimport {\r\n getMinAndMaxInputLimitForProductKey,\r\n getMinAndMaxOutputLimitForProductKey,\r\n getProductNameFromProductKey,\r\n} from \"../helpers/helpers\";\r\nimport { IDeviceAutomationPayload } from \"../models/IDeviceAutomationPayload\";\r\n\r\nlet adapter: ZendureSolarflow | undefined = undefined;\r\n\r\nconst knownPackDataProperties = [\r\n \"sn\",\r\n \"totalVol\",\r\n \"maxVol\",\r\n \"minVol\",\r\n \"socLevel\",\r\n \"maxTemp\",\r\n \"soh\",\r\n];\r\n\r\nexport const addOrUpdatePackData = async (\r\n productKey: string,\r\n deviceKey: string,\r\n packData: IPackData[],\r\n isSolarFlow: boolean\r\n): Promise<void> => {\r\n if (adapter && productKey && deviceKey) {\r\n await packData.forEach(async (x) => {\r\n // Process data only with a serial id!\r\n if (x.sn && adapter) {\r\n // Create channel (e.g. the device specific key)\r\n // We can determine the type of the battery by the SN number.\r\n let batType = \"\";\r\n if (productKey == \"yWF7hV\") {\r\n batType = \"AIO2400\";\r\n } else if (x.sn.startsWith(\"A\")) {\r\n batType = \"AB1000\";\r\n } else if (x.sn.startsWith(\"B\")) {\r\n batType = \"AB1000S\";\r\n } else if (x.sn.startsWith(\"C\")) {\r\n if (x.sn[3] == \"F\") {\r\n batType = \"AB2000S\";\r\n } else {\r\n batType = \"AB2000\";\r\n }\r\n } else if (x.sn.startsWith(\"F\")) {\r\n batType = \"AB3000X\";\r\n }\r\n\r\n // Check if is in Pack2device list\r\n if (\r\n !adapter.pack2Devices.some(\r\n (y) => y.packSn == x.sn && y.deviceKey == deviceKey\r\n )\r\n ) {\r\n adapter.pack2Devices.push({\r\n packSn: x.sn,\r\n deviceKey: deviceKey,\r\n type: batType,\r\n });\r\n\r\n adapter.log.debug(\r\n `[addOrUpdatePackData] Added battery ${batType} with SN ${x.sn} on deviceKey ${deviceKey} to pack2Devices!`\r\n );\r\n }\r\n\r\n // create a state for the serial id\r\n const key = (\r\n productKey +\r\n \".\" +\r\n deviceKey +\r\n \".packData.\" +\r\n x.sn\r\n ).replace(adapter.FORBIDDEN_CHARS, \"\");\r\n\r\n await adapter?.extendObject(key, {\r\n type: \"channel\",\r\n common: {\r\n name: {\r\n de: batType,\r\n en: batType,\r\n },\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.extendObject(key + \".model\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Batterietyp\",\r\n en: \"Battery type\",\r\n },\r\n type: \"string\",\r\n desc: \"model\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".model\", batType, true);\r\n\r\n await adapter?.extendObject(key + \".sn\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Seriennummer\",\r\n en: \"Serial id\",\r\n },\r\n type: \"string\",\r\n desc: \"Serial ID\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".sn\", x.sn, true);\r\n\r\n if (x.socLevel) {\r\n // State f\u00FCr socLevel\r\n await adapter?.extendObject(key + \".socLevel\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"SOC der Batterie\",\r\n en: \"soc of battery\",\r\n },\r\n type: \"number\",\r\n desc: \"SOC Level\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"%\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".socLevel\", x.socLevel, true);\r\n }\r\n\r\n if (x.maxTemp) {\r\n // State f\u00FCr maxTemp\r\n await adapter?.extendObject(key + \".maxTemp\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Max. Temperatur der Batterie\",\r\n en: \"max temp. of battery\",\r\n },\r\n type: \"number\",\r\n desc: \"Max. Temp\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"\u00B0C\",\r\n },\r\n native: {},\r\n });\r\n\r\n // Convert Kelvin to Celsius\r\n await adapter?.setState(\r\n key + \".maxTemp\",\r\n x.maxTemp / 10 - 273.15,\r\n true\r\n );\r\n }\r\n\r\n if (x.minVol) {\r\n await adapter?.extendObject(key + \".minVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"minVol\",\r\n type: \"number\",\r\n desc: \"minVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".minVol\", x.minVol / 100, true);\r\n }\r\n\r\n if (x.batcur) {\r\n await adapter?.extendObject(key + \".batcur\", {\r\n type: \"state\",\r\n common: {\r\n name: \"batcur\",\r\n type: \"number\",\r\n desc: \"batcur\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"A\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".batcur\", x.batcur / 10, true);\r\n }\r\n\r\n if (x.maxVol) {\r\n await adapter?.extendObject(key + \".maxVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"maxVol\",\r\n type: \"number\",\r\n desc: \"maxVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".maxVol\", x.maxVol / 100, true);\r\n }\r\n\r\n if (x.totalVol) {\r\n await adapter?.extendObject(key + \".totalVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"totalVol\",\r\n type: \"number\",\r\n desc: \"totalVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n const totalVol = x.totalVol / 100;\r\n\r\n await adapter?.setState(key + \".totalVol\", totalVol, true);\r\n\r\n // Send Voltage to checkVoltage Method (only if is Solarflow device)\r\n if (isSolarFlow) {\r\n checkVoltage(adapter, productKey, deviceKey, totalVol);\r\n }\r\n }\r\n\r\n if (x.soh) {\r\n await adapter?.extendObject(key + \".soh\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Gesundheitszustand\",\r\n en: \"State of Health\",\r\n },\r\n type: \"number\",\r\n desc: \"State of Health\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"%\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".soh\", x.soh / 10, true);\r\n }\r\n\r\n // Debug, send message if property is unknown!\r\n let found = false;\r\n\r\n Object.entries(x).forEach(([key, value]) => {\r\n knownPackDataProperties.forEach((property: string) => {\r\n if (property == key) {\r\n found = true;\r\n }\r\n });\r\n\r\n if (found) {\r\n //console.log(\r\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\r\n //);\r\n } else {\r\n adapter?.log.debug(\r\n `[addOrUpdatePackData] ${key} with value ${value} is a UNKNOWN PackData Mqtt Property!`\r\n );\r\n }\r\n });\r\n }\r\n });\r\n }\r\n};\r\n\r\nconst onMessage = async (topic: string, message: Buffer): Promise<void> => {\r\n if (adapter) {\r\n if (topic.toLowerCase().includes(\"loginOut/force\")) {\r\n // TODO: Ausloggen???\r\n }\r\n\r\n const topicSplitted = topic.replace(\"/server/app\", \"\").split(\"/\");\r\n const productKey = topicSplitted[1];\r\n const deviceKey = topicSplitted[2];\r\n\r\n let obj: IMqttData = {};\r\n try {\r\n obj = JSON.parse(message.toString());\r\n } catch (e) {\r\n const txt = message.toString();\r\n adapter.log.error(`[onMessage] JSON Parse error!`);\r\n\r\n adapter.log.debug(`[onMessage] JSON Parse error: ${txt}!`);\r\n }\r\n\r\n let isSolarFlow = false;\r\n const productName = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.productName`\r\n );\r\n\r\n if (adapter.log.level == \"debug\") {\r\n adapter.log.debug(\r\n `[onMessage] MQTT message on topic '${topic}': ${message.toString()}`\r\n );\r\n }\r\n\r\n if (obj.timestamp) {\r\n const currentTimeStamp = new Date().getTime() / 1000;\r\n const diff = currentTimeStamp - obj.timestamp;\r\n\r\n if (diff > 600) {\r\n // Timestamp older than 5 Minutens, device is offline!\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n \"Disconnected\"\r\n );\r\n } else {\r\n // Timestamp older than 5 Minutens, device is offline!\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n \"Connected\"\r\n );\r\n }\r\n }\r\n\r\n // Check if device is an solarflow or hyper device. Don't use LowVoltageBlock on an ACE device?\r\n if (productKey != \"8bM93H\") {\r\n isSolarFlow = true;\r\n }\r\n\r\n // set lastUpdate for deviceKey\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"lastUpdate\",\r\n new Date().getTime()\r\n );\r\n\r\n if (\r\n obj.properties?.autoModel != null &&\r\n obj.properties?.autoModel != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoModel\",\r\n obj.properties.autoModel\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoModel\",\r\n obj.properties.autoModel\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.heatState != null &&\r\n obj.properties?.heatState != undefined\r\n ) {\r\n const value = obj.properties?.heatState == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"heatState\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.electricLevel != null &&\r\n obj.properties?.electricLevel != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"electricLevel\",\r\n obj.properties.electricLevel\r\n );\r\n\r\n if (\r\n adapter?.config.useCalculation &&\r\n obj.properties.electricLevel == 100 &&\r\n isSolarFlow\r\n ) {\r\n setEnergyWhMax(adapter, productKey, deviceKey);\r\n }\r\n\r\n if (obj.properties.electricLevel == 100) {\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true\r\n ) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.control.fullChargeNeeded`,\r\n false,\r\n true\r\n );\r\n }\r\n }\r\n\r\n // if minSoc is reached, set the calculated soc to 0\r\n const minSoc = await adapter?.getStateAsync(\r\n `${productKey}.${deviceKey}.minSoc`\r\n );\r\n if (\r\n adapter?.config.useCalculation &&\r\n minSoc &&\r\n minSoc.val &&\r\n obj.properties.electricLevel == Number(minSoc.val) &&\r\n isSolarFlow\r\n ) {\r\n setSocToZero(adapter, productKey, deviceKey);\r\n }\r\n }\r\n\r\n if (obj.power != null && obj.power != undefined) {\r\n const value = obj.power / 10;\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"power\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.packState != null &&\r\n obj.properties?.packState != undefined\r\n ) {\r\n const value =\r\n obj.properties?.packState == 0\r\n ? \"Idle\"\r\n : obj.properties?.packState == 1\r\n ? \"Charging\"\r\n : obj.properties?.packState == 2\r\n ? \"Discharging\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packState\", value);\r\n\r\n if (obj.properties?.packState) {\r\n // Update combined data point\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packPower\", 0);\r\n }\r\n }\r\n\r\n if (\r\n obj.properties?.passMode != null &&\r\n obj.properties?.passMode != undefined\r\n ) {\r\n const value =\r\n obj.properties?.passMode == 0\r\n ? \"Automatic\"\r\n : obj.properties?.passMode == 1\r\n ? \"Always off\"\r\n : obj.properties?.passMode == 2\r\n ? \"Always on\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"passMode\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"passMode\",\r\n obj.properties?.passMode\r\n );\r\n }\r\n\r\n if (obj.properties?.pass != null && obj.properties?.pass != undefined) {\r\n const value = obj.properties?.pass == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"pass\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.autoRecover != null &&\r\n obj.properties?.autoRecover != undefined\r\n ) {\r\n const value = obj.properties?.autoRecover == 0 ? false : true;\r\n\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoRecover\",\r\n value\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoRecover\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputHomePower != null &&\r\n obj.properties?.outputHomePower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputHomePower\",\r\n obj.properties.outputHomePower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.energyPower != null &&\r\n obj.properties?.energyPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"energyPower\",\r\n obj.properties.energyPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputLimit != null &&\r\n obj.properties?.outputLimit != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputLimit\",\r\n obj.properties.outputLimit\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"setOutputLimit\",\r\n obj.properties.outputLimit\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.smartMode != null &&\r\n obj.properties?.smartMode != undefined\r\n ) {\r\n const value = obj.properties?.smartMode == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"smartMode\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"smartMode\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.buzzerSwitch != null &&\r\n obj.properties?.buzzerSwitch != undefined\r\n ) {\r\n const value = obj.properties?.buzzerSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"buzzerSwitch\",\r\n value\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"buzzerSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputPackPower != null &&\r\n obj.properties?.outputPackPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n obj.properties.outputPackPower\r\n );\r\n\r\n if (obj.properties?.outputPackPower > 0) {\r\n // Update combined data point\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n obj.properties.outputPackPower\r\n );\r\n } else if (obj.properties?.outputPackPower == 0) {\r\n // Check if packInputPower is 0\r\n const packInputPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".packInputPower\"\r\n );\r\n\r\n if (packInputPower?.val == 0) {\r\n // Update combined data point to 0 as both are 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.outputPackPower)\r\n );\r\n }\r\n }\r\n\r\n // if outPutPackPower set packInputPower to 0\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packInputPower\", 0);\r\n }\r\n\r\n if (\r\n obj.properties?.packInputPower != null &&\r\n obj.properties?.packInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packInputPower\",\r\n obj.properties.packInputPower\r\n );\r\n\r\n if (obj.properties?.packInputPower > 0) {\r\n // Update combined data point\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.packInputPower)\r\n );\r\n } else if (obj.properties?.packInputPower == 0) {\r\n // Check if outputPackPower is 0\r\n const outputPackPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".outputPackPower\"\r\n );\r\n\r\n if (outputPackPower?.val == 0) {\r\n // Update combined data point to 0 as both are 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.packInputPower)\r\n );\r\n }\r\n }\r\n\r\n // if packInputPower set outputPackPower to 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n 0\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarInputPower != null &&\r\n obj.properties?.solarInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"solarInputPower\",\r\n obj.properties.solarInputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvPower1 != null &&\r\n obj.properties?.pvPower1 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower2\", // Reversed to adjust like offical app\r\n obj.properties.pvPower1\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvPower2 != null &&\r\n obj.properties?.pvPower2 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower1\", // Reversed to adjust like offical app\r\n obj.properties.pvPower2\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower1 != null &&\r\n obj.properties?.solarPower1 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower1\",\r\n obj.properties.solarPower1\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower2 != null &&\r\n obj.properties?.solarPower2 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower2\",\r\n obj.properties.solarPower2\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower3 != null &&\r\n obj.properties?.solarPower3 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower3\",\r\n obj.properties.solarPower3\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower4 != null &&\r\n obj.properties?.solarPower4 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower4\",\r\n obj.properties.solarPower4\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainOutTime != null &&\r\n obj.properties?.remainOutTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainOutTime\",\r\n obj.properties.remainOutTime\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainInputTime != null &&\r\n obj.properties?.remainInputTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainInputTime\",\r\n obj.properties.remainInputTime\r\n );\r\n }\r\n\r\n if (obj.properties?.socSet != null && obj.properties?.socSet != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"socSet\",\r\n Number(obj.properties.socSet) / 10\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"chargeLimit\",\r\n Number(obj.properties.socSet) / 10\r\n );\r\n }\r\n\r\n if (obj.properties?.minSoc != null && obj.properties?.minSoc != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"minSoc\",\r\n Number(obj.properties.minSoc) / 10\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dischargeLimit\",\r\n Number(obj.properties.minSoc) / 10\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.inputLimit != null &&\r\n obj.properties?.inputLimit != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"inputLimit\",\r\n obj.properties.inputLimit\r\n );\r\n\r\n if (\r\n productName?.val?.toString().toLowerCase().includes(\"solarflow\") ||\r\n productName?.val?.toString().toLowerCase().includes(\"ace\") ||\r\n productName?.val?.toString().toLowerCase().includes(\"hyper\")\r\n ) {\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"setInputLimit\",\r\n obj.properties.inputLimit\r\n );\r\n }\r\n }\r\n\r\n if (\r\n obj.properties?.gridInputPower != null &&\r\n obj.properties?.gridInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"gridInputPower\",\r\n obj.properties.gridInputPower\r\n );\r\n }\r\n\r\n if (obj.properties?.acMode != null && obj.properties?.acMode != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acMode\",\r\n obj.properties.acMode\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acMode\",\r\n obj.properties.acMode\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.hyperTmp != null &&\r\n obj.properties?.hyperTmp != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hyperTmp\",\r\n obj.properties.hyperTmp / 10 - 273.15\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.acOutputPower != null &&\r\n obj.properties?.acOutputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acOutputPower\",\r\n obj.properties.acOutputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.gridPower != null &&\r\n obj.properties?.gridPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"gridInputPower\",\r\n obj.properties.gridPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.acSwitch != null &&\r\n obj.properties?.acSwitch != undefined\r\n ) {\r\n const value = obj.properties?.acSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"acSwitch\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.dcSwitch != null &&\r\n obj.properties?.dcSwitch != undefined\r\n ) {\r\n const value = obj.properties?.dcSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"dcSwitch\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dcSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.dcOutputPower != null &&\r\n obj.properties?.dcOutputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dcOutputPower\",\r\n obj.properties.dcOutputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvBrand != null &&\r\n obj.properties?.pvBrand != undefined\r\n ) {\r\n const value =\r\n obj.properties?.pvBrand == 0\r\n ? \"Others\"\r\n : obj.properties?.pvBrand == 1\r\n ? \"Hoymiles\"\r\n : obj.properties?.pvBrand == 2\r\n ? \"Enphase\"\r\n : obj.properties?.pvBrand == 3\r\n ? \"APSystems\"\r\n : obj.properties?.pvBrand == 4\r\n ? \"Anker\"\r\n : obj.properties?.pvBrand == 5\r\n ? \"Deye\"\r\n : obj.properties?.pvBrand == 6\r\n ? \"Bosswerk\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"pvBrand\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.inverseMaxPower != null &&\r\n obj.properties?.inverseMaxPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"inverseMaxPower\",\r\n obj.properties.inverseMaxPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.wifiState != null &&\r\n obj.properties?.wifiState != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n obj.properties.wifiState == 1 ? \"Connected\" : \"Disconnected\"\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.packNum != null &&\r\n obj.properties?.packNum != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packNum\",\r\n obj.properties.packNum\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.hubState != null &&\r\n obj.properties?.hubState != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hubState\",\r\n obj.properties.hubState\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hubState\",\r\n obj.properties.hubState\r\n );\r\n }\r\n\r\n if (obj.packData) {\r\n addOrUpdatePackData(productKey, deviceKey, obj.packData, isSolarFlow);\r\n }\r\n\r\n if (obj.properties && adapter.log.level == \"debug\") {\r\n const _productName = productName?.val?.toString();\r\n\r\n if (_productName) {\r\n const states = getStateDefinition(_productName);\r\n let found = false;\r\n\r\n Object.entries(obj.properties).forEach(([key, value]) => {\r\n states.forEach((state: ISolarflowState) => {\r\n if (state.title == key) {\r\n found = true;\r\n }\r\n });\r\n\r\n if (found) {\r\n //console.log(\r\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\r\n //);\r\n } else {\r\n adapter?.log.debug(\r\n `[onMessage] ${productName?.val}: ${key} with value ${JSON.stringify(value)} is a UNKNOWN Mqtt Property!`\r\n );\r\n }\r\n });\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const setAcMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n acMode: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (acMode >= 0 && acMode <= 2) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAcMode = { properties: { acMode: acMode } };\r\n adapter.log.debug(`[setAcMode] Set AC mode to ${acMode}!`);\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAcMode));\r\n } else {\r\n adapter.log.error(`[setAcMode] AC mode must be a value between 0 and 2!`);\r\n }\r\n }\r\n};\r\n\r\nexport const setChargeLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n socSet: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (socSet >= 40 && socSet <= 100) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { socSet: socSet * 10 } };\r\n adapter.log.debug(\r\n `[setChargeLimit] Setting ChargeLimit for device key ${deviceKey} to ${socSet}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(\r\n `[setChargeLimit] Charge limit is not in range 40<>100!`\r\n );\r\n }\r\n }\r\n};\r\n\r\nexport const setDischargeLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n minSoc: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (minSoc >= 0 && minSoc <= 50) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { minSoc: minSoc * 10 } };\r\n adapter.log.debug(\r\n `[setDischargeLimit] Setting Discharge Limit for device key ${deviceKey} to ${minSoc}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(\r\n `[setDischargeLimit] Discharge limit is not in range 0<>50!`\r\n );\r\n }\r\n }\r\n};\r\n\r\nexport const setHubState = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n hubState: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (hubState == 0 || hubState == 1) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { hubState: hubState } };\r\n adapter.log.debug(\r\n `[setHubState] Setting Hub State for device key ${deviceKey} to ${hubState}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(`[setHubState] Hub state is not 0 or 1!`);\r\n }\r\n }\r\n};\r\n\r\nexport const setDeviceAutomationInOutLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number // can be negative, negative will trigger charging mode\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Set device Automation limit to ${limit}!`\r\n );\r\n\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n if (adapter.config.useLowVoltageBlock) {\r\n const lowVoltageBlockState = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n if (\r\n lowVoltageBlockState &&\r\n lowVoltageBlockState.val &&\r\n lowVoltageBlockState.val == true &&\r\n limit > 0\r\n ) {\r\n limit = 0;\r\n }\r\n\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true &&\r\n limit > 0\r\n ) {\r\n limit = 0;\r\n }\r\n }\r\n\r\n if (limit < 0) {\r\n // Get input limit, make number positive and the new value negative\r\n limit = -getMinAndMaxInputLimitForProductKey(productKey, -limit);\r\n } else {\r\n limit = getMinAndMaxOutputLimitForProductKey(productKey, limit);\r\n }\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/function/invoke`;\r\n\r\n adapter.msgCounter += 1;\r\n\r\n const timestamp = new Date();\r\n timestamp.setMilliseconds(0);\r\n\r\n // HUB1200 & HUB 2000\r\n let _arguments: IDeviceAutomationPayload[] = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: limit,\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n\r\n const productName = getProductNameFromProductKey(productKey);\r\n\r\n // Wenn kein Hub1200 oder Hub2000 \u00FCberschreiben wir die Werte.\r\n if (\r\n productName.toLowerCase().includes(\"2400 ac\") ||\r\n productName.toLowerCase().includes(\"solarflow 800\")\r\n ) {\r\n // HEMS Variante\r\n const outputlimit = {\r\n arguments: {\r\n outputPower: limit,\r\n chargeState: limit > 0 ? 0 : 1,\r\n chargePower: limit > 0 ? 0 : -limit,\r\n mode: 9,\r\n },\r\n function: \"deviceAutomation\",\r\n messageId: adapter.msgCounter,\r\n deviceKey: deviceKey,\r\n timestamp: timestamp.getTime() / 1000,\r\n };\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n } else if (productName.toLowerCase().includes(\"ace\")) {\r\n _arguments = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: {\r\n chargingType: limit > 0 ? 0 : 1,\r\n chargingPower: limit > 0 ? 0 : -limit,\r\n freq: 0,\r\n outPower: limit,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n } else {\r\n if (productName.toLowerCase().includes(\"hyper\")) {\r\n if (limit < 0) {\r\n _arguments = [\r\n {\r\n autoModelProgram: 1,\r\n autoModelValue: {\r\n upTime: 0,\r\n chargingType: 1,\r\n pullTime: 1800,\r\n price: 2,\r\n chargingPower: -limit,\r\n prices: [\r\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r\n 1, 1, 1,\r\n ],\r\n outPower: 0,\r\n freq: 0,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n } else {\r\n _arguments = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: {\r\n chargingType: 0,\r\n chargingPower: 0,\r\n freq: 0,\r\n outPower: limit,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n }\r\n }\r\n\r\n const outputlimit = {\r\n arguments: _arguments,\r\n function: \"deviceAutomation\",\r\n messageId: adapter.msgCounter,\r\n deviceKey: deviceKey,\r\n timestamp: timestamp.getTime() / 1000,\r\n };\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n }\r\n }\r\n};\r\n\r\nexport const setOutputLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n // Check if autoModel is set to 0 (Nothing) or 8 (Smart Matching)\r\n const autoModel = (\r\n await adapter.getStateAsync(productKey + \".\" + deviceKey + \".autoModel\")\r\n )?.val;\r\n\r\n if (autoModel != 0) {\r\n adapter.log.warn(\r\n \"Operation mode (autoModel) is not set to '0', we can't set the output limit!\"\r\n );\r\n return;\r\n }\r\n\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n if (adapter.config.useLowVoltageBlock) {\r\n const lowVoltageBlockState = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n if (\r\n lowVoltageBlockState &&\r\n lowVoltageBlockState.val &&\r\n lowVoltageBlockState.val == true\r\n ) {\r\n limit = 0;\r\n }\r\n\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true\r\n ) {\r\n limit = 0;\r\n }\r\n }\r\n\r\n const currentLimit = (\r\n await adapter.getStateAsync(productKey + \".\" + deviceKey + \".outputLimit\")\r\n )?.val;\r\n\r\n if (currentLimit != null && currentLimit != undefined) {\r\n if (currentLimit != limit) {\r\n limit = getMinAndMaxOutputLimitForProductKey(productKey, limit);\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const outputlimit = { properties: { outputLimit: limit } };\r\n\r\n adapter.msgCounter += 1;\r\n\r\n const timestamp = new Date();\r\n timestamp.setMilliseconds(0);\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const setInputLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n limit = getMinAndMaxInputLimitForProductKey(productKey, limit);\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const inputLimitContent = { properties: { inputLimit: limit } };\r\n adapter.mqttClient?.publish(topic, JSON.stringify(inputLimitContent));\r\n }\r\n};\r\n\r\nexport const setSmartMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n smartModeOn: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setSmartModeContent = {\r\n properties: { smartMode: smartModeOn ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setBuzzer] Setting Smart Mode for device key ${deviceKey} to ${smartModeOn}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setSmartModeContent));\r\n }\r\n};\r\n\r\nexport const setBuzzerSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n buzzerOn: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setBuzzerSwitchContent = {\r\n properties: { buzzerSwitch: buzzerOn ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setBuzzer] Setting Buzzer for device key ${deviceKey} to ${buzzerOn}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setBuzzerSwitchContent));\r\n }\r\n};\r\n\r\nexport const setAutoModel = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n autoModel: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n let setAutoModelContent: any = { properties: { autoModel: autoModel } };\r\n\r\n switch (autoModel) {\r\n case 8: // Smart Matching Modus\r\n setAutoModelContent = {\r\n properties: {\r\n autoModelProgram: 1,\r\n autoModelValue: { chargingType: 0, chargingPower: 0, outPower: 0 },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n };\r\n break;\r\n case 9: // Smart CT Modus\r\n setAutoModelContent = {\r\n properties: {\r\n autoModelProgram: 2,\r\n autoModelValue: { chargingType: 3, chargingPower: 0, outPower: 0 },\r\n msgType: 1,\r\n autoModel: 9,\r\n },\r\n };\r\n break;\r\n }\r\n\r\n adapter.log.debug(\r\n `[setAutoModel] Setting autoModel for device key ${deviceKey} to ${autoModel}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAutoModelContent));\r\n }\r\n};\r\n\r\nexport const triggerFullTelemetryUpdate = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/read`;\r\n\r\n const getAllContent = { properties: [\"getAll\"] };\r\n adapter.log.debug(\r\n `[triggerFullTelemetryUpdate] Triggering full telemetry update for device key ${deviceKey}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(getAllContent));\r\n }\r\n};\r\n\r\nexport const setPassMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n passMode: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setPassModeContent = { properties: { passMode: passMode } };\r\n adapter.log.debug(\r\n `[setPassMode] Set passMode for device ${deviceKey} to ${passMode}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setPassModeContent));\r\n }\r\n};\r\n\r\nexport const setAutoRecover = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n autoRecover: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAutoRecoverContent = {\r\n properties: { autoRecover: autoRecover ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setAutoRecover] Set autoRecover for device ${deviceKey} to ${autoRecover}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAutoRecoverContent));\r\n }\r\n};\r\n\r\nexport const setDcSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n dcSwitch: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setDcSwitchContent = {\r\n properties: { dcSwitch: dcSwitch ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setDcSwitch] Set DC Switch for device ${deviceKey} to ${dcSwitch}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setDcSwitchContent));\r\n }\r\n};\r\n\r\nexport const setAcSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n acSwitch: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAcSwitchContent = {\r\n properties: { acSwitch: acSwitch ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setAcSwitch] Set AC Switch for device ${deviceKey} to ${acSwitch}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAcSwitchContent));\r\n }\r\n};\r\n\r\nconst onConnected = (): void => {\r\n adapter?.log.info(\"[onConnected] Connected with MQTT!\");\r\n};\r\n\r\nconst onError = (error: any): void => {\r\n adapter?.log.error(\"Connection to MQTT failed! Error: \" + error);\r\n};\r\n\r\nconst onSubscribeReportTopic: any = (error: Error | null) => {\r\n if (error) {\r\n adapter?.log.error(\"Subscription to MQTT failed! Error: \" + error);\r\n } else {\r\n adapter?.log.debug(\"Subscription of Report Topic successful!\");\r\n }\r\n};\r\n\r\nconst onSubscribeIotTopic: any = (\r\n error: Error | null,\r\n productKey: string,\r\n deviceKey: string\r\n) => {\r\n if (error) {\r\n adapter?.log.error(\"Subscription to MQTT failed! Error: \" + error);\r\n } else if (adapter) {\r\n adapter?.log.debug(\"Subscription of IOT Topic successful!\");\r\n triggerFullTelemetryUpdate(adapter, productKey, deviceKey);\r\n }\r\n};\r\n\r\nexport const subscribeReportTopic = (\r\n productKey: string,\r\n deviceKey: string,\r\n timeout: number\r\n): void => {\r\n const reportTopic = `/${productKey}/${deviceKey}/#`;\r\n\r\n setTimeout(() => {\r\n if (adapter) {\r\n adapter.log.debug(\r\n `[subscribeReportTopic] Subscribing to MQTT Topic: ${reportTopic}`\r\n );\r\n adapter.mqttClient?.subscribe(reportTopic, onSubscribeReportTopic);\r\n }\r\n }, timeout);\r\n};\r\n\r\nexport const subscribeIotTopic = (\r\n productKey: string,\r\n deviceKey: string,\r\n timeout: number\r\n): void => {\r\n const iotTopic = `iot/${productKey}/${deviceKey}/#`;\r\n\r\n setTimeout(() => {\r\n adapter?.log.debug(\r\n `[subscribeIotTopic] Subscribing to MQTT Topic: ${iotTopic}`\r\n );\r\n adapter?.mqttClient?.subscribe(iotTopic, (error) => {\r\n onSubscribeIotTopic(error, productKey, deviceKey);\r\n });\r\n }, timeout);\r\n};\r\n\r\nexport const connectCloudMqttClient = (_adapter: ZendureSolarflow): void => {\r\n adapter = _adapter;\r\n\r\n if (!adapter.paths?.mqttPassword) {\r\n adapter.log.error(`[connectCloudMqttClient] MQTT Password is missing!`);\r\n return;\r\n }\r\n\r\n const mqttPassword = atob(adapter.paths?.mqttPassword);\r\n\r\n const options: mqtt.IClientOptions = {\r\n clientId: adapter.accessToken,\r\n username: \"zenApp\",\r\n password: mqttPassword,\r\n clean: true,\r\n protocolVersion: 5,\r\n };\r\n\r\n if (mqtt && adapter && adapter.paths && adapter.deviceList) {\r\n adapter.log.debug(\r\n `[connectCloudMqttClient] Connecting to MQTT broker ${\r\n adapter.paths.mqttUrl + \":\" + adapter.paths.mqttPort\r\n }...`\r\n );\r\n adapter.mqttClient = mqtt.connect(\r\n \"mqtt://\" + adapter.paths.mqttUrl + \":\" + adapter.paths.mqttPort,\r\n options\r\n ); // create a client\r\n\r\n if (adapter && adapter.mqttClient) {\r\n adapter.mqttClient.on(\"connect\", onConnected);\r\n adapter.mqttClient.on(\"error\", onError);\r\n\r\n // Subscribe to Topic (appkey von Zendure)\r\n adapter.deviceList.forEach(\r\n (device: ISolarFlowDeviceDetails, index: number) => {\r\n if (adapter) {\r\n let connectIot = true;\r\n\r\n if (device.productKey == \"s3Xk4x\") {\r\n const smartPlugReportTopic = `/server/app/${adapter.userId}/${device.id}/smart/power`;\r\n\r\n adapter.mqttClient?.subscribe(\r\n smartPlugReportTopic,\r\n onSubscribeReportTopic\r\n );\r\n\r\n connectIot = false;\r\n }\r\n\r\n subscribeReportTopic(\r\n device.productKey,\r\n device.deviceKey,\r\n 1000 * index\r\n );\r\n\r\n if (connectIot) {\r\n subscribeIotTopic(\r\n device.productKey,\r\n device.deviceKey,\r\n 1000 * index\r\n );\r\n }\r\n\r\n // Check if has subdevice e.g. ACE and connect to this also?\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 subscribeReportTopic(\r\n subDevice.productKey,\r\n subDevice.deviceKey,\r\n 1000 * index\r\n );\r\n\r\n subscribeIotTopic(\r\n subDevice.productKey,\r\n subDevice.deviceKey,\r\n 2000 * index\r\n );\r\n }\r\n });\r\n }\r\n }\r\n }\r\n );\r\n\r\n adapter.mqttClient.on(\"message\", onMessage);\r\n\r\n // Job starten die states in der Nacht zu resetten\r\n startResetValuesJob(adapter);\r\n\r\n // Job starten die States zu checken\r\n startCheckStatesAndConnectionJob(adapter);\r\n\r\n // Calculation Job starten sofern aktiviert\r\n if (adapter.config.useCalculation) {\r\n startCalculationJob(adapter);\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const connectLocalMqttClient = (_adapter: ZendureSolarflow): void => {\r\n adapter = _adapter;\r\n\r\n const options: mqtt.IClientOptions = {\r\n clientId: \"ioBroker.zendure-solarflow.\" + adapter.instance,\r\n };\r\n\r\n if (mqtt && adapter && adapter.config && adapter.config.localMqttUrl) {\r\n adapter.log.debug(\r\n `[connectLocalMqttClient] Connecting to MQTT broker ${\r\n adapter.config.localMqttUrl + \":\" + 1883\r\n }...`\r\n );\r\n adapter.mqttClient = mqtt.connect(\r\n \"mqtt://\" + adapter.config.localMqttUrl + \":\" + 1883,\r\n options\r\n ); // create a client\r\n\r\n if (adapter && adapter.mqttClient) {\r\n adapter.mqttClient.on(\"connect\", onConnected);\r\n adapter.mqttClient.on(\"error\", onError);\r\n\r\n adapter.setState(\"info.connection\", true, true);\r\n\r\n // Subscribe to 1. device from local settings\r\n if (\r\n adapter.config.localDevice1ProductKey &&\r\n adapter.config.localDevice1DeviceKey\r\n ) {\r\n // Create states and subscribe device 1\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey,\r\n 1000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey,\r\n 1000\r\n );\r\n }\r\n\r\n // Subscribe to 2. device from local settings\r\n if (\r\n adapter.config.localDevice2ProductKey &&\r\n adapter.config.localDevice2DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n // Subscribe to 3. device from local settings\r\n if (\r\n adapter.config.localDevice3ProductKey &&\r\n adapter.config.localDevice3DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n // Subscribe to 3. device from local settings\r\n if (\r\n adapter.config.localDevice4ProductKey &&\r\n adapter.config.localDevice4DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n adapter.mqttClient.on(\"message\", onMessage);\r\n\r\n // Job starten die states in der Nacht zu resetten\r\n startResetValuesJob(adapter);\r\n\r\n // Job starten die States zu checken\r\n startCheckStatesAndConnectionJob(adapter);\r\n\r\n // Calculation Job starten sofern aktiviert\r\n if (adapter.config.useCalculation) {\r\n startCalculationJob(adapter);\r\n }\r\n }\r\n }\r\n};\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport * as mqtt from \"mqtt\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\nimport {\r\n checkVoltage,\r\n updateSolarFlowControlState,\r\n updateSolarFlowState,\r\n} from \"./adapterService\";\r\nimport { IPackData } from \"../models/IPackData\";\r\nimport { setEnergyWhMax, setSocToZero } from \"./calculationService\";\r\nimport { IMqttData } from \"../models/ISolarFlowMqttProperties\";\r\nimport {\r\n startCalculationJob,\r\n startCheckStatesAndConnectionJob,\r\n startResetValuesJob,\r\n} from \"./jobSchedule\";\r\nimport { createSolarFlowLocalStates } from \"../helpers/createSolarFlowLocalStates\";\r\nimport { ISolarflowState } from \"../models/ISolarflowState\";\r\nimport { getStateDefinition } from \"../helpers/createSolarFlowStates\";\r\nimport {\r\n getMinAndMaxInputLimitForProductKey,\r\n getMinAndMaxOutputLimitForProductKey,\r\n getProductNameFromProductKey,\r\n} from \"../helpers/helpers\";\r\nimport { IDeviceAutomationPayload } from \"../models/IDeviceAutomationPayload\";\r\n\r\nlet adapter: ZendureSolarflow | undefined = undefined;\r\n\r\nconst knownPackDataProperties = [\r\n \"sn\",\r\n \"totalVol\",\r\n \"maxVol\",\r\n \"minVol\",\r\n \"socLevel\",\r\n \"maxTemp\",\r\n \"soh\",\r\n];\r\n\r\nexport const addOrUpdatePackData = async (\r\n productKey: string,\r\n deviceKey: string,\r\n packData: IPackData[],\r\n isSolarFlow: boolean\r\n): Promise<void> => {\r\n if (adapter && productKey && deviceKey) {\r\n await packData.forEach(async (x) => {\r\n // Process data only with a serial id!\r\n if (x.sn && adapter) {\r\n // Create channel (e.g. the device specific key)\r\n // We can determine the type of the battery by the SN number.\r\n let batType = \"\";\r\n if (productKey == \"yWF7hV\") {\r\n batType = \"AIO2400\";\r\n } else if (x.sn.startsWith(\"A\")) {\r\n batType = \"AB1000\";\r\n } else if (x.sn.startsWith(\"B\")) {\r\n batType = \"AB1000S\";\r\n } else if (x.sn.startsWith(\"C\")) {\r\n if (x.sn[3] == \"F\") {\r\n batType = \"AB2000S\";\r\n } else {\r\n batType = \"AB2000\";\r\n }\r\n } else if (x.sn.startsWith(\"F\")) {\r\n batType = \"AB3000X\";\r\n }\r\n\r\n // Check if is in Pack2device list\r\n if (\r\n !adapter.pack2Devices.some(\r\n (y) => y.packSn == x.sn && y.deviceKey == deviceKey\r\n )\r\n ) {\r\n adapter.pack2Devices.push({\r\n packSn: x.sn,\r\n deviceKey: deviceKey,\r\n type: batType,\r\n });\r\n\r\n adapter.log.debug(\r\n `[addOrUpdatePackData] Added battery ${batType} with SN ${x.sn} on deviceKey ${deviceKey} to pack2Devices!`\r\n );\r\n }\r\n\r\n // create a state for the serial id\r\n const key = (\r\n productKey +\r\n \".\" +\r\n deviceKey +\r\n \".packData.\" +\r\n x.sn\r\n ).replace(adapter.FORBIDDEN_CHARS, \"\");\r\n\r\n await adapter?.extendObject(key, {\r\n type: \"channel\",\r\n common: {\r\n name: {\r\n de: batType,\r\n en: batType,\r\n },\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.extendObject(key + \".model\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Batterietyp\",\r\n en: \"Battery type\",\r\n },\r\n type: \"string\",\r\n desc: \"model\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".model\", batType, true);\r\n\r\n await adapter?.extendObject(key + \".sn\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Seriennummer\",\r\n en: \"Serial id\",\r\n },\r\n type: \"string\",\r\n desc: \"Serial ID\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".sn\", x.sn, true);\r\n\r\n if (x.socLevel) {\r\n // State f\u00FCr socLevel\r\n await adapter?.extendObject(key + \".socLevel\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"SOC der Batterie\",\r\n en: \"soc of battery\",\r\n },\r\n type: \"number\",\r\n desc: \"SOC Level\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"%\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".socLevel\", x.socLevel, true);\r\n }\r\n\r\n if (x.maxTemp) {\r\n // State f\u00FCr maxTemp\r\n await adapter?.extendObject(key + \".maxTemp\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Max. Temperatur der Batterie\",\r\n en: \"max temp. of battery\",\r\n },\r\n type: \"number\",\r\n desc: \"Max. Temp\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"\u00B0C\",\r\n },\r\n native: {},\r\n });\r\n\r\n // Convert Kelvin to Celsius\r\n await adapter?.setState(\r\n key + \".maxTemp\",\r\n x.maxTemp / 10 - 273.15,\r\n true\r\n );\r\n }\r\n\r\n if (x.minVol) {\r\n await adapter?.extendObject(key + \".minVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"minVol\",\r\n type: \"number\",\r\n desc: \"minVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".minVol\", x.minVol / 100, true);\r\n }\r\n\r\n if (x.batcur) {\r\n await adapter?.extendObject(key + \".batcur\", {\r\n type: \"state\",\r\n common: {\r\n name: \"batcur\",\r\n type: \"number\",\r\n desc: \"batcur\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"A\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".batcur\", x.batcur / 10, true);\r\n }\r\n\r\n if (x.maxVol) {\r\n await adapter?.extendObject(key + \".maxVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"maxVol\",\r\n type: \"number\",\r\n desc: \"maxVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".maxVol\", x.maxVol / 100, true);\r\n }\r\n\r\n if (x.totalVol) {\r\n await adapter?.extendObject(key + \".totalVol\", {\r\n type: \"state\",\r\n common: {\r\n name: \"totalVol\",\r\n type: \"number\",\r\n desc: \"totalVol\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"V\",\r\n },\r\n native: {},\r\n });\r\n\r\n const totalVol = x.totalVol / 100;\r\n\r\n await adapter?.setState(key + \".totalVol\", totalVol, true);\r\n\r\n // Send Voltage to checkVoltage Method (only if is Solarflow device)\r\n if (isSolarFlow) {\r\n checkVoltage(adapter, productKey, deviceKey, totalVol);\r\n }\r\n }\r\n\r\n if (x.soh) {\r\n await adapter?.extendObject(key + \".soh\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Gesundheitszustand\",\r\n en: \"State of Health\",\r\n },\r\n type: \"number\",\r\n desc: \"State of Health\",\r\n role: \"value\",\r\n read: true,\r\n write: false,\r\n unit: \"%\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".soh\", x.soh / 10, true);\r\n }\r\n\r\n if (x.power) {\r\n await adapter?.extendObject(key + \".power\", {\r\n type: \"state\",\r\n common: {\r\n name: {\r\n de: \"Energie\",\r\n en: \"Power\",\r\n },\r\n type: \"number\",\r\n desc: \"Power\",\r\n read: true,\r\n write: false,\r\n role: \"value.power\",\r\n unit: \"W\",\r\n },\r\n native: {},\r\n });\r\n\r\n await adapter?.setState(key + \".power\", x.power, true);\r\n }\r\n\r\n // Debug, send message if property is unknown!\r\n let found = false;\r\n\r\n Object.entries(x).forEach(([key, value]) => {\r\n knownPackDataProperties.forEach((property: string) => {\r\n if (property == key) {\r\n found = true;\r\n }\r\n });\r\n\r\n if (found) {\r\n //console.log(\r\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\r\n //);\r\n } else {\r\n adapter?.log.debug(\r\n `[addOrUpdatePackData] ${key} with value ${value} is a UNKNOWN PackData Mqtt Property!`\r\n );\r\n }\r\n });\r\n }\r\n });\r\n }\r\n};\r\n\r\nconst onMessage = async (topic: string, message: Buffer): Promise<void> => {\r\n if (adapter) {\r\n if (topic.toLowerCase().includes(\"loginOut/force\")) {\r\n // TODO: Ausloggen???\r\n }\r\n\r\n const topicSplitted = topic.replace(\"/server/app\", \"\").split(\"/\");\r\n const productKey = topicSplitted[1];\r\n const deviceKey = topicSplitted[2];\r\n\r\n let obj: IMqttData = {};\r\n try {\r\n obj = JSON.parse(message.toString());\r\n } catch (e) {\r\n const txt = message.toString();\r\n adapter.log.error(`[onMessage] JSON Parse error!`);\r\n\r\n adapter.log.debug(`[onMessage] JSON Parse error: ${txt}!`);\r\n }\r\n\r\n let isSolarFlow = false;\r\n const productName = await adapter.getStateAsync(\r\n `${productKey}.${deviceKey}.productName`\r\n );\r\n\r\n if (adapter.log.level == \"debug\") {\r\n adapter.log.debug(\r\n `[onMessage] MQTT message on topic '${topic}': ${message.toString()}`\r\n );\r\n }\r\n\r\n if (obj.timestamp) {\r\n const currentTimeStamp = new Date().getTime() / 1000;\r\n const diff = currentTimeStamp - obj.timestamp;\r\n\r\n if (diff > 600) {\r\n // Timestamp older than 5 Minutens, device is offline!\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n \"Disconnected\"\r\n );\r\n } else {\r\n // Timestamp older than 5 Minutens, device is offline!\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n \"Connected\"\r\n );\r\n }\r\n }\r\n\r\n // Check if device is an solarflow or hyper device. Don't use LowVoltageBlock on an ACE device?\r\n if (productKey != \"8bM93H\") {\r\n isSolarFlow = true;\r\n }\r\n\r\n // set lastUpdate for deviceKey\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"lastUpdate\",\r\n new Date().getTime()\r\n );\r\n\r\n //\r\n if (obj.function == \"deviceAutomation\" && obj.success == 1) {\r\n // setDeviceAutomationInOutLimit ack = true setzen;\r\n const currentValue = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.setDeviceAutomationInOutLimit\"\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"setDeviceAutomationInOutLimit\",\r\n currentValue?.val ? currentValue.val : 0\r\n );\r\n } else if (obj.function == \"deviceAutomation\" && obj.success == 0) {\r\n adapter?.log.warn(\r\n `[onMessage] device automation failed for ${productName?.val}: ${productKey}/${deviceKey}!`\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.autoModel != null &&\r\n obj.properties?.autoModel != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoModel\",\r\n obj.properties.autoModel\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoModel\",\r\n obj.properties.autoModel\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.heatState != null &&\r\n obj.properties?.heatState != undefined\r\n ) {\r\n const value = obj.properties?.heatState == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"heatState\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.electricLevel != null &&\r\n obj.properties?.electricLevel != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"electricLevel\",\r\n obj.properties.electricLevel\r\n );\r\n\r\n if (\r\n adapter?.config.useCalculation &&\r\n obj.properties.electricLevel == 100 &&\r\n isSolarFlow\r\n ) {\r\n setEnergyWhMax(adapter, productKey, deviceKey);\r\n }\r\n\r\n if (obj.properties.electricLevel == 100) {\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true\r\n ) {\r\n await adapter?.setState(\r\n `${productKey}.${deviceKey}.control.fullChargeNeeded`,\r\n false,\r\n true\r\n );\r\n }\r\n }\r\n\r\n // if minSoc is reached, set the calculated soc to 0\r\n const minSoc = await adapter?.getStateAsync(\r\n `${productKey}.${deviceKey}.minSoc`\r\n );\r\n if (\r\n adapter?.config.useCalculation &&\r\n minSoc &&\r\n minSoc.val &&\r\n obj.properties.electricLevel == Number(minSoc.val) &&\r\n isSolarFlow\r\n ) {\r\n setSocToZero(adapter, productKey, deviceKey);\r\n }\r\n }\r\n\r\n if (obj.power != null && obj.power != undefined) {\r\n const value = obj.power / 10;\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"power\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.packState != null &&\r\n obj.properties?.packState != undefined\r\n ) {\r\n const value =\r\n obj.properties?.packState == 0\r\n ? \"Idle\"\r\n : obj.properties?.packState == 1\r\n ? \"Charging\"\r\n : obj.properties?.packState == 2\r\n ? \"Discharging\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packState\", value);\r\n\r\n if (obj.properties?.packState) {\r\n // Update combined data point\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packPower\", 0);\r\n }\r\n }\r\n\r\n if (\r\n obj.properties?.passMode != null &&\r\n obj.properties?.passMode != undefined\r\n ) {\r\n const value =\r\n obj.properties?.passMode == 0\r\n ? \"Automatic\"\r\n : obj.properties?.passMode == 1\r\n ? \"Always off\"\r\n : obj.properties?.passMode == 2\r\n ? \"Always on\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"passMode\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"passMode\",\r\n obj.properties?.passMode\r\n );\r\n }\r\n\r\n if (obj.properties?.pass != null && obj.properties?.pass != undefined) {\r\n const value = obj.properties?.pass == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"pass\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.autoRecover != null &&\r\n obj.properties?.autoRecover != undefined\r\n ) {\r\n const value = obj.properties?.autoRecover == 0 ? false : true;\r\n\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoRecover\",\r\n value\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"autoRecover\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputHomePower != null &&\r\n obj.properties?.outputHomePower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputHomePower\",\r\n obj.properties.outputHomePower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.energyPower != null &&\r\n obj.properties?.energyPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"energyPower\",\r\n obj.properties.energyPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputLimit != null &&\r\n obj.properties?.outputLimit != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputLimit\",\r\n obj.properties.outputLimit\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"setOutputLimit\",\r\n obj.properties.outputLimit\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.smartMode != null &&\r\n obj.properties?.smartMode != undefined\r\n ) {\r\n const value = obj.properties?.smartMode == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"smartMode\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"smartMode\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.buzzerSwitch != null &&\r\n obj.properties?.buzzerSwitch != undefined\r\n ) {\r\n const value = obj.properties?.buzzerSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"buzzerSwitch\",\r\n value\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"buzzerSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputPackPower != null &&\r\n obj.properties?.outputPackPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n obj.properties.outputPackPower\r\n );\r\n\r\n if (obj.properties?.outputPackPower > 0) {\r\n // Update combined data point\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n obj.properties.outputPackPower\r\n );\r\n } else if (obj.properties?.outputPackPower == 0) {\r\n // Check if packInputPower is 0\r\n const packInputPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".packInputPower\"\r\n );\r\n\r\n if (packInputPower?.val == 0) {\r\n // Update combined data point to 0 as both are 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.outputPackPower)\r\n );\r\n }\r\n }\r\n\r\n // if outPutPackPower set packInputPower to 0\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packInputPower\", 0);\r\n }\r\n\r\n if (\r\n obj.properties?.packInputPower != null &&\r\n obj.properties?.packInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packInputPower\",\r\n obj.properties.packInputPower\r\n );\r\n\r\n if (obj.properties?.packInputPower > 0) {\r\n // Update combined data point\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.packInputPower)\r\n );\r\n } else if (obj.properties?.packInputPower == 0) {\r\n // Check if outputPackPower is 0\r\n const outputPackPower = await adapter?.getStateAsync(\r\n productKey + \".\" + deviceKey + \".outputPackPower\"\r\n );\r\n\r\n if (outputPackPower?.val == 0) {\r\n // Update combined data point to 0 as both are 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packPower\",\r\n -Math.abs(obj.properties.packInputPower)\r\n );\r\n }\r\n }\r\n\r\n // if packInputPower set outputPackPower to 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n 0\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarInputPower != null &&\r\n obj.properties?.solarInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"solarInputPower\",\r\n obj.properties.solarInputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvPower1 != null &&\r\n obj.properties?.pvPower1 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower2\", // Reversed to adjust like offical app\r\n obj.properties.pvPower1\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvPower2 != null &&\r\n obj.properties?.pvPower2 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower1\", // Reversed to adjust like offical app\r\n obj.properties.pvPower2\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower1 != null &&\r\n obj.properties?.solarPower1 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower1\",\r\n obj.properties.solarPower1\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower2 != null &&\r\n obj.properties?.solarPower2 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower2\",\r\n obj.properties.solarPower2\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower3 != null &&\r\n obj.properties?.solarPower3 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower3\",\r\n obj.properties.solarPower3\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarPower4 != null &&\r\n obj.properties?.solarPower4 != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"pvPower4\",\r\n obj.properties.solarPower4\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainOutTime != null &&\r\n obj.properties?.remainOutTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainOutTime\",\r\n obj.properties.remainOutTime\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainInputTime != null &&\r\n obj.properties?.remainInputTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainInputTime\",\r\n obj.properties.remainInputTime\r\n );\r\n }\r\n\r\n if (obj.properties?.socSet != null && obj.properties?.socSet != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"socSet\",\r\n Number(obj.properties.socSet) / 10\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"chargeLimit\",\r\n Number(obj.properties.socSet) / 10\r\n );\r\n }\r\n\r\n if (obj.properties?.minSoc != null && obj.properties?.minSoc != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"minSoc\",\r\n Number(obj.properties.minSoc) / 10\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dischargeLimit\",\r\n Number(obj.properties.minSoc) / 10\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.inputLimit != null &&\r\n obj.properties?.inputLimit != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"inputLimit\",\r\n obj.properties.inputLimit\r\n );\r\n\r\n if (\r\n productName?.val?.toString().toLowerCase().includes(\"solarflow\") ||\r\n productName?.val?.toString().toLowerCase().includes(\"ace\") ||\r\n productName?.val?.toString().toLowerCase().includes(\"hyper\")\r\n ) {\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"setInputLimit\",\r\n obj.properties.inputLimit\r\n );\r\n }\r\n }\r\n\r\n if (\r\n obj.properties?.gridInputPower != null &&\r\n obj.properties?.gridInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"gridInputPower\",\r\n obj.properties.gridInputPower\r\n );\r\n }\r\n\r\n if (obj.properties?.acMode != null && obj.properties?.acMode != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acMode\",\r\n obj.properties.acMode\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acMode\",\r\n obj.properties.acMode\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.hyperTmp != null &&\r\n obj.properties?.hyperTmp != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hyperTmp\",\r\n obj.properties.hyperTmp / 10 - 273.15\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.acOutputPower != null &&\r\n obj.properties?.acOutputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acOutputPower\",\r\n obj.properties.acOutputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.gridPower != null &&\r\n obj.properties?.gridPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"gridInputPower\",\r\n obj.properties.gridPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.acSwitch != null &&\r\n obj.properties?.acSwitch != undefined\r\n ) {\r\n const value = obj.properties?.acSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"acSwitch\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"acSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.dcSwitch != null &&\r\n obj.properties?.dcSwitch != undefined\r\n ) {\r\n const value = obj.properties?.dcSwitch == 0 ? false : true;\r\n\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"dcSwitch\", value);\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dcSwitch\",\r\n value\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.dcOutputPower != null &&\r\n obj.properties?.dcOutputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"dcOutputPower\",\r\n obj.properties.dcOutputPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.pvBrand != null &&\r\n obj.properties?.pvBrand != undefined\r\n ) {\r\n const value =\r\n obj.properties?.pvBrand == 0\r\n ? \"Others\"\r\n : obj.properties?.pvBrand == 1\r\n ? \"Hoymiles\"\r\n : obj.properties?.pvBrand == 2\r\n ? \"Enphase\"\r\n : obj.properties?.pvBrand == 3\r\n ? \"APSystems\"\r\n : obj.properties?.pvBrand == 4\r\n ? \"Anker\"\r\n : obj.properties?.pvBrand == 5\r\n ? \"Deye\"\r\n : obj.properties?.pvBrand == 6\r\n ? \"Bosswerk\"\r\n : \"Unknown\";\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"pvBrand\", value);\r\n }\r\n\r\n if (\r\n obj.properties?.inverseMaxPower != null &&\r\n obj.properties?.inverseMaxPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"inverseMaxPower\",\r\n obj.properties.inverseMaxPower\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.wifiState != null &&\r\n obj.properties?.wifiState != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"wifiState\",\r\n obj.properties.wifiState == 1 ? \"Connected\" : \"Disconnected\"\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.packNum != null &&\r\n obj.properties?.packNum != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packNum\",\r\n obj.properties.packNum\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.hubState != null &&\r\n obj.properties?.hubState != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hubState\",\r\n obj.properties.hubState\r\n );\r\n\r\n updateSolarFlowControlState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"hubState\",\r\n obj.properties.hubState\r\n );\r\n }\r\n\r\n if (obj.packData) {\r\n addOrUpdatePackData(productKey, deviceKey, obj.packData, isSolarFlow);\r\n }\r\n\r\n if (obj.properties && adapter.log.level == \"debug\") {\r\n const _productName = productName?.val?.toString();\r\n\r\n if (_productName) {\r\n const states = getStateDefinition(_productName);\r\n let found = false;\r\n\r\n Object.entries(obj.properties).forEach(([key, value]) => {\r\n states.forEach((state: ISolarflowState) => {\r\n if (state.title == key) {\r\n found = true;\r\n }\r\n });\r\n\r\n if (found) {\r\n //console.log(\r\n // `${productName?.val}: ${key} with value ${value} is a KNOWN Mqtt Prop!`\r\n //);\r\n } else {\r\n adapter?.log.debug(\r\n `[onMessage] ${productName?.val}: ${key} with value ${JSON.stringify(value)} is a UNKNOWN Mqtt Property!`\r\n );\r\n }\r\n });\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const setAcMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n acMode: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (acMode >= 0 && acMode <= 3) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAcMode = { properties: { acMode: acMode } };\r\n adapter.log.debug(`[setAcMode] Set AC mode to ${acMode}!`);\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAcMode));\r\n\r\n // Check if device is HUB, then check if smartMode is false - if so send a warning to log!\r\n const smartMode = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.smartMode\"\r\n );\r\n\r\n if (smartMode && !smartMode.val) {\r\n adapter.log.warn(\r\n `[setAcMode] AC mode was switched and smartMode is false - changes will be written to flash memory. In the worst case, the device may break or changes may no longer be saved!`\r\n );\r\n }\r\n } else {\r\n adapter.log.error(`[setAcMode] AC mode must be a value between 0 and 3!`);\r\n }\r\n }\r\n};\r\n\r\nexport const setChargeLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n socSet: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (socSet >= 40 && socSet <= 100) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { socSet: socSet * 10 } };\r\n adapter.log.debug(\r\n `[setChargeLimit] Setting ChargeLimit for device key ${deviceKey} to ${socSet}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(\r\n `[setChargeLimit] Charge limit is not in range 40<>100!`\r\n );\r\n }\r\n }\r\n};\r\n\r\nexport const setDischargeLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n minSoc: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (minSoc >= 0 && minSoc <= 50) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { minSoc: minSoc * 10 } };\r\n adapter.log.debug(\r\n `[setDischargeLimit] Setting Discharge Limit for device key ${deviceKey} to ${minSoc}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(\r\n `[setDischargeLimit] Discharge limit is not in range 0<>50!`\r\n );\r\n }\r\n }\r\n};\r\n\r\nexport const setHubState = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n hubState: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (hubState == 0 || hubState == 1) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const socSetLimit = { properties: { hubState: hubState } };\r\n adapter.log.debug(\r\n `[setHubState] Setting Hub State for device key ${deviceKey} to ${hubState}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(socSetLimit));\r\n } else {\r\n adapter.log.debug(`[setHubState] Hub state is not 0 or 1!`);\r\n }\r\n }\r\n};\r\n\r\nexport const setDeviceAutomationInOutLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number // can be negative, negative will trigger charging mode\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Set device Automation limit to ${limit}!`\r\n );\r\n\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n if (adapter.config.useLowVoltageBlock) {\r\n const lowVoltageBlockState = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n if (\r\n lowVoltageBlockState &&\r\n lowVoltageBlockState.val &&\r\n lowVoltageBlockState.val == true &&\r\n limit > 0\r\n ) {\r\n limit = 0;\r\n }\r\n\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true &&\r\n limit > 0\r\n ) {\r\n limit = 0;\r\n }\r\n }\r\n\r\n if (limit < 0) {\r\n // Get input limit, make number positive and the new value negative\r\n limit = -getMinAndMaxInputLimitForProductKey(productKey, -limit);\r\n } else {\r\n limit = getMinAndMaxOutputLimitForProductKey(productKey, limit);\r\n }\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/function/invoke`;\r\n\r\n adapter.msgCounter += 1;\r\n\r\n const timestamp = new Date();\r\n timestamp.setMilliseconds(0);\r\n\r\n // HUB1200 & HUB 2000\r\n let _arguments: IDeviceAutomationPayload[] = [];\r\n\r\n const productName = getProductNameFromProductKey(productKey);\r\n\r\n if (\r\n productName.toLowerCase().includes(\"2400 ac\") ||\r\n productName.toLowerCase().includes(\"solarflow 800\")\r\n ) {\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Using HEMS Variant of device automation, as device '${productName}' detected!`\r\n );\r\n // HEMS Variante\r\n const outputlimit = {\r\n arguments: {\r\n outputPower: limit > 0 ? limit : 0,\r\n chargeState: limit > 0 ? 0 : 1,\r\n chargePower: limit > 0 ? 0 : -limit,\r\n mode: 9,\r\n },\r\n function: \"hemsEP\",\r\n messageId: adapter.msgCounter,\r\n deviceKey: deviceKey,\r\n timestamp: timestamp.getTime() / 1000,\r\n };\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n return;\r\n } else if (productName.toLowerCase().includes(\"hyper\")) {\r\n if (limit < 0) {\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Using CHARGE variant of HYPER device automation, as device '${productName}' detected and limit is negative!`\r\n );\r\n // Input / Charge\r\n _arguments = [\r\n {\r\n autoModelProgram: 1,\r\n autoModelValue: {\r\n upTime: 0,\r\n chargingType: 1,\r\n pullTime: 1800,\r\n price: 2,\r\n chargingPower: -limit,\r\n prices: [\r\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r\n 1, 1, 1,\r\n ],\r\n outPower: 0,\r\n freq: 0,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n } else {\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Using FEED IN variant of HYPER device automation, as device '${productName}' detected and limit is positive!`\r\n );\r\n // Output\r\n _arguments = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: {\r\n chargingType: 0,\r\n chargingPower: 0,\r\n freq: 0,\r\n outPower: limit,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n }\r\n } else {\r\n if (limit < 0) {\r\n adapter.log.warn(\r\n `[setDeviceAutomationInOutLimit] Using CHARGE variant of Hub device automation is currently not working! You have to manualy switch acMode and inputLimit!`\r\n );\r\n /* // Input / Charge\r\n _arguments = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: {\r\n upTime: 0,\r\n chargingType: 1,\r\n pullTime: 1800,\r\n price: 2,\r\n chargingPower: -limit,\r\n prices: [\r\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r\n 1, 1, 1,\r\n ],\r\n outPower: 0,\r\n freq: 0,\r\n },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ]; */\r\n } else {\r\n // Output\r\n adapter.log.debug(\r\n `[setDeviceAutomationInOutLimit] Using FEED IN variant of Hub device automation, as device '${productName}' detected and limit is positive!`\r\n );\r\n _arguments = [\r\n {\r\n autoModelProgram: 2,\r\n autoModelValue: limit,\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n ];\r\n }\r\n\r\n const outputlimit = {\r\n arguments: _arguments,\r\n function: \"deviceAutomation\",\r\n messageId: adapter.msgCounter,\r\n deviceKey: deviceKey,\r\n timestamp: timestamp.getTime() / 1000,\r\n };\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n }\r\n }\r\n};\r\n\r\nexport const setOutputLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n // Check if autoModel is set to 0 (Nothing) or 8 (Smart Matching)\r\n const autoModel = (\r\n await adapter.getStateAsync(productKey + \".\" + deviceKey + \".autoModel\")\r\n )?.val;\r\n\r\n if (autoModel != 0) {\r\n adapter.log.warn(\r\n \"Operation mode (autoModel) is not set to '0', we can't set the output limit!\"\r\n );\r\n return;\r\n }\r\n\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n if (adapter.config.useLowVoltageBlock) {\r\n const lowVoltageBlockState = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.lowVoltageBlock\"\r\n );\r\n if (\r\n lowVoltageBlockState &&\r\n lowVoltageBlockState.val &&\r\n lowVoltageBlockState.val == true\r\n ) {\r\n limit = 0;\r\n }\r\n\r\n const fullChargeNeeded = await adapter.getStateAsync(\r\n productKey + \".\" + deviceKey + \".control.fullChargeNeeded\"\r\n );\r\n\r\n if (\r\n fullChargeNeeded &&\r\n fullChargeNeeded.val &&\r\n fullChargeNeeded.val == true\r\n ) {\r\n limit = 0;\r\n }\r\n }\r\n\r\n const currentLimit = (\r\n await adapter.getStateAsync(productKey + \".\" + deviceKey + \".outputLimit\")\r\n )?.val;\r\n\r\n if (currentLimit != null && currentLimit != undefined) {\r\n if (currentLimit != limit) {\r\n limit = getMinAndMaxOutputLimitForProductKey(productKey, limit);\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const outputlimit = { properties: { outputLimit: limit } };\r\n\r\n adapter.msgCounter += 1;\r\n\r\n const timestamp = new Date();\r\n timestamp.setMilliseconds(0);\r\n\r\n adapter.mqttClient?.publish(topic, JSON.stringify(outputlimit));\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const setInputLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n if (limit) {\r\n limit = Math.round(limit);\r\n } else {\r\n limit = 0;\r\n }\r\n\r\n limit = getMinAndMaxInputLimitForProductKey(productKey, limit);\r\n\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const inputLimitContent = { properties: { inputLimit: limit } };\r\n adapter.mqttClient?.publish(topic, JSON.stringify(inputLimitContent));\r\n }\r\n};\r\n\r\nexport const setSmartMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n smartModeOn: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setSmartModeContent = {\r\n properties: { smartMode: smartModeOn ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setBuzzer] Setting Smart Mode for device key ${deviceKey} to ${smartModeOn}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setSmartModeContent));\r\n }\r\n};\r\n\r\nexport const setBuzzerSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n buzzerOn: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setBuzzerSwitchContent = {\r\n properties: { buzzerSwitch: buzzerOn ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setBuzzer] Setting Buzzer for device key ${deviceKey} to ${buzzerOn}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setBuzzerSwitchContent));\r\n }\r\n};\r\n\r\nexport const setAutoModel = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n autoModel: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n let setAutoModelContent: any = { properties: { autoModel: autoModel } };\r\n\r\n switch (autoModel) {\r\n case 8: // Smart Matching Modus\r\n setAutoModelContent = {\r\n properties: {\r\n autoModelProgram: 1,\r\n autoModelValue: { chargingType: 0, chargingPower: 0, outPower: 0 },\r\n msgType: 1,\r\n autoModel: 8,\r\n },\r\n };\r\n break;\r\n case 9: // Smart CT Modus\r\n setAutoModelContent = {\r\n properties: {\r\n autoModelProgram: 2,\r\n autoModelValue: { chargingType: 3, chargingPower: 0, outPower: 0 },\r\n msgType: 1,\r\n autoModel: 9,\r\n },\r\n };\r\n break;\r\n }\r\n\r\n adapter.log.debug(\r\n `[setAutoModel] Setting autoModel for device key ${deviceKey} to ${autoModel}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAutoModelContent));\r\n }\r\n};\r\n\r\nexport const triggerFullTelemetryUpdate = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/read`;\r\n\r\n const getAllContent = { properties: [\"getAll\"] };\r\n adapter.log.debug(\r\n `[triggerFullTelemetryUpdate] Triggering full telemetry update for device key ${deviceKey}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(getAllContent));\r\n }\r\n};\r\n\r\nexport const setPassMode = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n passMode: number\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setPassModeContent = { properties: { passMode: passMode } };\r\n adapter.log.debug(\r\n `[setPassMode] Set passMode for device ${deviceKey} to ${passMode}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setPassModeContent));\r\n }\r\n};\r\n\r\nexport const setAutoRecover = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n autoRecover: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAutoRecoverContent = {\r\n properties: { autoRecover: autoRecover ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setAutoRecover] Set autoRecover for device ${deviceKey} to ${autoRecover}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAutoRecoverContent));\r\n }\r\n};\r\n\r\nexport const setDcSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n dcSwitch: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setDcSwitchContent = {\r\n properties: { dcSwitch: dcSwitch ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setDcSwitch] Set DC Switch for device ${deviceKey} to ${dcSwitch}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setDcSwitchContent));\r\n }\r\n};\r\n\r\nexport const setAcSwitch = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n acSwitch: boolean\r\n): Promise<void> => {\r\n if (adapter.mqttClient && productKey && deviceKey) {\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const setAcSwitchContent = {\r\n properties: { acSwitch: acSwitch ? 1 : 0 },\r\n };\r\n adapter.log.debug(\r\n `[setAcSwitch] Set AC Switch for device ${deviceKey} to ${acSwitch}!`\r\n );\r\n adapter.mqttClient?.publish(topic, JSON.stringify(setAcSwitchContent));\r\n }\r\n};\r\n\r\nconst onConnected = (): void => {\r\n adapter?.log.info(\"[onConnected] Connected with MQTT!\");\r\n};\r\n\r\nconst onError = (error: any): void => {\r\n adapter?.log.error(\"Connection to MQTT failed! Error: \" + error);\r\n};\r\n\r\nconst onSubscribeReportTopic: any = (error: Error | null) => {\r\n if (error) {\r\n adapter?.log.error(\"Subscription to MQTT failed! Error: \" + error);\r\n } else {\r\n adapter?.log.debug(\"Subscription of Report Topic successful!\");\r\n }\r\n};\r\n\r\nconst onSubscribeIotTopic: any = (\r\n error: Error | null,\r\n productKey: string,\r\n deviceKey: string\r\n) => {\r\n if (error) {\r\n adapter?.log.error(\"Subscription to MQTT failed! Error: \" + error);\r\n } else if (adapter) {\r\n adapter?.log.debug(\"Subscription of IOT Topic successful!\");\r\n triggerFullTelemetryUpdate(adapter, productKey, deviceKey);\r\n }\r\n};\r\n\r\nexport const subscribeReportTopic = (\r\n productKey: string,\r\n deviceKey: string,\r\n timeout: number\r\n): void => {\r\n const reportTopic = `/${productKey}/${deviceKey}/#`;\r\n\r\n setTimeout(() => {\r\n if (adapter) {\r\n adapter.log.debug(\r\n `[subscribeReportTopic] Subscribing to MQTT Topic: ${reportTopic}`\r\n );\r\n adapter.mqttClient?.subscribe(reportTopic, onSubscribeReportTopic);\r\n }\r\n }, timeout);\r\n};\r\n\r\nexport const subscribeIotTopic = (\r\n productKey: string,\r\n deviceKey: string,\r\n timeout: number\r\n): void => {\r\n const iotTopic = `iot/${productKey}/${deviceKey}/#`;\r\n\r\n setTimeout(() => {\r\n adapter?.log.debug(\r\n `[subscribeIotTopic] Subscribing to MQTT Topic: ${iotTopic}`\r\n );\r\n adapter?.mqttClient?.subscribe(iotTopic, (error) => {\r\n onSubscribeIotTopic(error, productKey, deviceKey);\r\n });\r\n }, timeout);\r\n};\r\n\r\nexport const connectCloudMqttClient = (_adapter: ZendureSolarflow): void => {\r\n adapter = _adapter;\r\n\r\n if (!adapter.paths?.mqttPassword) {\r\n adapter.log.error(`[connectCloudMqttClient] MQTT Password is missing!`);\r\n return;\r\n }\r\n\r\n const mqttPassword = atob(adapter.paths?.mqttPassword);\r\n\r\n const options: mqtt.IClientOptions = {\r\n clientId: adapter.accessToken,\r\n username: \"zenApp\",\r\n password: mqttPassword,\r\n clean: true,\r\n protocolVersion: 5,\r\n };\r\n\r\n if (mqtt && adapter && adapter.paths && adapter.deviceList) {\r\n adapter.log.debug(\r\n `[connectCloudMqttClient] Connecting to MQTT broker ${\r\n adapter.paths.mqttUrl + \":\" + adapter.paths.mqttPort\r\n }...`\r\n );\r\n adapter.mqttClient = mqtt.connect(\r\n \"mqtt://\" + adapter.paths.mqttUrl + \":\" + adapter.paths.mqttPort,\r\n options\r\n ); // create a client\r\n\r\n if (adapter && adapter.mqttClient) {\r\n adapter.mqttClient.on(\"connect\", onConnected);\r\n adapter.mqttClient.on(\"error\", onError);\r\n\r\n // Subscribe to Topic (appkey von Zendure)\r\n adapter.deviceList.forEach(\r\n (device: ISolarFlowDeviceDetails, index: number) => {\r\n if (adapter) {\r\n let connectIot = true;\r\n\r\n if (device.productKey == \"s3Xk4x\") {\r\n const smartPlugReportTopic = `/server/app/${adapter.userId}/${device.id}/smart/power`;\r\n\r\n adapter.mqttClient?.subscribe(\r\n smartPlugReportTopic,\r\n onSubscribeReportTopic\r\n );\r\n\r\n connectIot = false;\r\n }\r\n\r\n subscribeReportTopic(\r\n device.productKey,\r\n device.deviceKey,\r\n 1000 * index\r\n );\r\n\r\n if (connectIot) {\r\n subscribeIotTopic(\r\n device.productKey,\r\n device.deviceKey,\r\n 1000 * index\r\n );\r\n }\r\n\r\n // Check if has subdevice e.g. ACE and connect to this also?\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 subscribeReportTopic(\r\n subDevice.productKey,\r\n subDevice.deviceKey,\r\n 1000 * index\r\n );\r\n\r\n subscribeIotTopic(\r\n subDevice.productKey,\r\n subDevice.deviceKey,\r\n 2000 * index\r\n );\r\n }\r\n });\r\n }\r\n }\r\n }\r\n );\r\n\r\n adapter.mqttClient.on(\"message\", onMessage);\r\n\r\n // Job starten die states in der Nacht zu resetten\r\n startResetValuesJob(adapter);\r\n\r\n // Job starten die States zu checken\r\n startCheckStatesAndConnectionJob(adapter);\r\n\r\n // Calculation Job starten sofern aktiviert\r\n if (adapter.config.useCalculation) {\r\n startCalculationJob(adapter);\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const connectLocalMqttClient = (_adapter: ZendureSolarflow): void => {\r\n adapter = _adapter;\r\n\r\n const options: mqtt.IClientOptions = {\r\n clientId: \"ioBroker.zendure-solarflow.\" + adapter.instance,\r\n };\r\n\r\n if (mqtt && adapter && adapter.config && adapter.config.localMqttUrl) {\r\n adapter.log.debug(\r\n `[connectLocalMqttClient] Connecting to MQTT broker ${\r\n adapter.config.localMqttUrl + \":\" + 1883\r\n }...`\r\n );\r\n adapter.mqttClient = mqtt.connect(\r\n \"mqtt://\" + adapter.config.localMqttUrl + \":\" + 1883,\r\n options\r\n ); // create a client\r\n\r\n if (adapter && adapter.mqttClient) {\r\n adapter.mqttClient.on(\"connect\", onConnected);\r\n adapter.mqttClient.on(\"error\", onError);\r\n\r\n adapter.setState(\"info.connection\", true, true);\r\n\r\n // Subscribe to 1. device from local settings\r\n if (\r\n adapter.config.localDevice1ProductKey &&\r\n adapter.config.localDevice1DeviceKey\r\n ) {\r\n // Create states and subscribe device 1\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey,\r\n 1000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice1ProductKey,\r\n adapter.config.localDevice1DeviceKey,\r\n 1000\r\n );\r\n }\r\n\r\n // Subscribe to 2. device from local settings\r\n if (\r\n adapter.config.localDevice2ProductKey &&\r\n adapter.config.localDevice2DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice2ProductKey,\r\n adapter.config.localDevice2DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n // Subscribe to 3. device from local settings\r\n if (\r\n adapter.config.localDevice3ProductKey &&\r\n adapter.config.localDevice3DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice3ProductKey,\r\n adapter.config.localDevice3DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n // Subscribe to 3. device from local settings\r\n if (\r\n adapter.config.localDevice4ProductKey &&\r\n adapter.config.localDevice4DeviceKey\r\n ) {\r\n // Create states and subscribe device 2\r\n createSolarFlowLocalStates(\r\n adapter,\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey\r\n );\r\n\r\n subscribeReportTopic(\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey,\r\n 2000\r\n );\r\n\r\n subscribeIotTopic(\r\n adapter.config.localDevice4ProductKey,\r\n adapter.config.localDevice4DeviceKey,\r\n 2000\r\n );\r\n }\r\n\r\n adapter.mqttClient.on(\"message\", onMessage);\r\n\r\n // Job starten die states in der Nacht zu resetten\r\n startResetValuesJob(adapter);\r\n\r\n // Job starten die States zu checken\r\n startCheckStatesAndConnectionJob(adapter);\r\n\r\n // Calculation Job starten sofern aktiviert\r\n if (adapter.config.useCalculation) {\r\n startCalculationJob(adapter);\r\n }\r\n }\r\n }\r\n};\r\n"],
5
+ "mappings": "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",
6
6
  "names": ["key", "adapter", "setAcMode", "_a"]
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zendure-solarflow",
4
- "version": "2.0.0-alpha.1",
4
+ "version": "2.0.0",
5
5
  "news": {
6
+ "2.0.0": {
7
+ "en": "Breaking Change: Add control parameter 'setDeviceAutomationInOutLimit' which emulates Zendure's Smart Matching mode. I recommend using this device automation instead of 'setInputLimit'/'setOutputLimit' from now on, as there were concerns that setting limits/modes would be stored in the flash memory. You can use negative values for charging and positive for feed in. On HUB 1200/2000 with ACE 1500 you can use \"smartMode\" to prevent switching AC mode trigger writing to the flash memory. Check you the readme for more details or participate in the ioBroker forum.",
8
+ "de": "Veränderung: Fügen Sie den Steuerparameter 'setDeviceAutomationInOutLimit' hinzu, der den Smart Matching-Modus von Zendure emuliert. Ich empfehle, diese Geräteautomatisierung anstelle von 'setInputLimit'/'setOutputLimit' von jetzt an zu verwenden, da es Bedenken gab, dass Einstelllimits/Mode im Flash-Speicher gespeichert würden. Sie können negative Werte für das Laden und positiv für das Einspeisen verwenden. Auf HUB 1200/2000 mit ACE 1500 können Sie \"smartMode\" verwenden, um zu verhindern, dass Wechselstrommodus das Schreiben an den Flash-Speicher auslöst. Überprüfen Sie das Readme für weitere Details oder nehmen Sie am ioBroker Forum teil.",
9
+ "ru": "Переломные изменения: Добавьте параметр управления «setDeviceAutomationInOutLimit», который эмулирует режим Smart Matching от Zendure. Отныне я рекомендую использовать автоматизацию этого устройства вместо «setInputLimit» / «setOutputLimit», поскольку были опасения, что установка ограничений / режимов будет храниться во флэш-памяти. Вы можете использовать отрицательные значения для зарядки и положительные для подачи. На HUB 1200/2000 с ACE 1500 можно использовать «smartMode», чтобы предотвратить переключение записи в режиме переменного тока на флэш-память. Проверьте Readme для получения более подробной информации или участвуйте в форуме ioBroker.",
10
+ "pt": "Quebrar a Mudança: Adicionar parâmetro de controle 'setDeviceAutomationInOutLimit' que emula o modo Smart Matching da Zendure. Eu recomendo usar esta automação de dispositivo em vez de 'setInputLimit'/'setOutputLimit' a partir de agora, como havia preocupações de que definir limites/modos seria armazenado na memória flash. Você pode usar valores negativos para carregar e positivos para alimentação. Em HUB 1200/2000 com ACE 1500 você pode usar \"smartMode\" para evitar a ativação do modo AC de comutação de gravação para a memória flash. Confira o readme para mais detalhes ou participe no fórum ioBroker.",
11
+ "nl": "Verandering doorbreken: Voeg controleparameter 'setDeviceAutomationInOutLimit' toe die Zendure's Smart Matching-modus emuleert. Ik adviseer deze apparaatautomatisering vanaf nu te gebruiken in plaats van 'setInputLimit'/'setOutputLimit', omdat er bezorgdheid bestond dat het instellen van limieten/modi in het flitsgeheugen zou worden opgeslagen. U kunt negatieve waarden gebruiken voor het opladen en positief voor voer in. Op HUB 1200/2000 met ACE 1500 kunt u \"smartMode\" gebruiken om te voorkomen dat het schakelen van de AC-modus trigger schrijven naar het flitsgeheugen. Bekijk de readme voor meer details of neem deel aan het ioBroker forum.",
12
+ "fr": "Briser le changement : Ajouter le paramètre de contrôle 'setDeviceAutomationInOutLimit' qui émule le mode Smart Matching de Zendure. Je recommande d'utiliser cette automatisation de périphérique au lieu de 'setInputLimit'/'setOutputLimit' à partir de maintenant, car il y avait des préoccupations que le réglage des limites/modes serait stocké dans la mémoire flash. Vous pouvez utiliser des valeurs négatives pour la charge et positives pour l'alimentation. Sur HUB 1200/2000 avec ACE 1500, vous pouvez utiliser \"smartMode\" pour empêcher le passage de l'écriture du déclencheur en mode AC à la mémoire flash. Vérifiez la lecture pour plus de détails ou participez au forum ioBroker.",
13
+ "it": "Cambiamento di rottura: Aggiungi il parametro di controllo 'setDeviceAutomationInOutLimit' che emula la modalità Smart Matching di Zendure. Raccomando di utilizzare questo dispositivo di automazione invece di 'setInputLimit'/'setOutputLimit' da ora in poi, in quanto vi erano preoccupazioni che la regolazione dei limiti/modi sarebbe memorizzata nella memoria flash. È possibile utilizzare valori negativi per la ricarica e positivo per il feed in. Su HUB 1200/2000 con ACE 1500 è possibile utilizzare \"smartMode\" per evitare di commutare la modalità AC di attivare la scrittura alla memoria flash. Controlla il readme per maggiori dettagli o partecipa al forum ioBroker.",
14
+ "es": "Cambio de ruptura: Añadir parámetro de control 'setDeviceAutomationInOutLimit' que emula el modo Smart Matching de Zendure. Recomiendo usar esta automatización de dispositivos en lugar de 'setInputLimit'/'setOutputLimit' a partir de ahora, ya que había preocupaciones de que fijar límites/modes se almacenarían en la memoria flash. Puede utilizar valores negativos para cargar y positivos para alimentarse. En HUB 1200/2000 con ACE 1500 se puede utilizar \"smartMode\" para evitar cambiar el modo AC activando la escritura a la memoria flash. Comprueba la lectura para más detalles o participa en el foro ioBroker.",
15
+ "pl": "Łamanie zmian: Dodaj parametr sterowania 'setDeviceAutomationInOutLimit', który emuluje tryb inteligentnego dopasowywania Zhamb. Zalecam stosowanie automatyzacji tego urządzenia zamiast 'setInputLimit' / 'setOutputLimit' od teraz, ponieważ istniały obawy, że ustawianie limitów / trybów będzie przechowywane w pamięci flash. Możesz użyć wartości ujemnych do ładowania i dodatnich do podawania. W HUB 1200 / 2000 z ACE 1500 można użyć \"smartMode\", aby zapobiec przełączaniu zapisu trybu AC do pamięci flash. Sprawdź czytaj więcej szczegółów lub uczestnicz w forum jOBroker.",
16
+ "uk": "Зміна несправностей: Додавання параметра керування «setDeviceAutomationInOutLimit», який визначає режим Smart Matching Zendure. Я рекомендую використовувати цей пристрій автоматизації замість 'setInputLimit'/'setOutputLimit' відтепер, оскільки є побоювання, що налаштування лімітів/модів буде зберігатися в флеш-пам'яті. Ви можете використовувати негативні значення для зарядки та позитиву для живлення. На HUB 1200/2000 з ACE 1500 ви можете використовувати \"smartMode\" для запобігання перемикання режиму змінного струму, що тривають на флеш-пам'ять. Перевірити читання для отримання більш детальної інформації або участі в форумі ioBroker.",
17
+ "zh-cn": "中断更改 : 添加模拟 Zendure 智能匹配模式的控制参数“ set DeviceAutomation InOutLimit ” 。 我建议从现在开始使用这个设备自动化, 而不是“ setInputLimit ” /“ setOutputLimit ” , 因为有人担心设定限制/ modes会存储在闪存中 。 可以使用负值充电,正值用于饲料输入. 在 HUB 1200/2000 与 ACE 1500 可以使用\"smartMode\"来防止将 AC 模式触发写入到闪存中. 请检查access-date=中的日期值 (帮助) 更多细节或参加ioBroker论坛."
18
+ },
6
19
  "2.0.0-alpha.1": {
7
20
  "en": "Breaking Change: Add control parameter 'setDeviceAutomationInOutLimit' which emulates Zendure's Smart Matching mode. Since there were concerns that setting limits would be stored in the flash memory, I recommend using this device automation instead of 'setInputLimit'/'setOutputLimit' from now on. You can use negative values for charging and positive for feed in.",
8
21
  "de": "Veränderung: Fügen Sie den Steuerparameter 'setDeviceAutomationInOutLimit' hinzu, der den Smart Matching-Modus von Zendure emuliert. Da Bedenken bestehen, dass Einstellgrenzen im Flash-Speicher gespeichert werden würden, empfehle ich die Verwendung dieser Geräteautomatisierung anstelle von 'setInputLimit'/'setOutputLimit' von jetzt an. Sie können negative Werte für das Laden und positiv für das Einspeisen verwenden.",
@@ -80,19 +93,6 @@
80
93
  "pl": "Naprawianie brakujących SF 800 & 2400 AC w lokalnych ustawieniach trybu",
81
94
  "uk": "Виправлення відсутніх SF 800 & 2400 AC в налаштуваннях локального режиму",
82
95
  "zh-cn": "在本地模式设置中修复缺失的 SF 800 & 2400 AC"
83
- },
84
- "1.15.1": {
85
- "en": "Fix missing Solar Input 3 & 4 on Solarflow 800 Pro\nFix 'packPower' state did not set to 0 if no input/output",
86
- "de": "Fix fehlende Solar Input 3 & 4 auf Solarflow 800 Pro\n'packPower' Zustand wurde nicht auf 0 gesetzt, wenn keine Eingabe/Ausgabe",
87
- "ru": "Недостающий Solar Input 3 и 4 на Solarflow 800 Pro\nСостояние «packPower» не устанавливается на 0, если нет ввода/вывода",
88
- "pt": "Corrigir falta de entrada solar 3 & 4 no Solarflow 800 Pro\nCorrigir o estado de 'packPower' não definido para 0 se não houver entrada/saída",
89
- "nl": "Fix ontbrekende Solar Input 3 & 4 op Solarflow 800 Pro\nFix 'packPower' status is niet ingesteld op 0 als geen invoer/uitvoer",
90
- "fr": "Correction de l'entrée solaire 3 & 4 manquante sur Solarflow 800 Pro\nCorrection de l'état 'packPower' n'a pas été réglé à 0 si aucune entrée/sortie",
91
- "it": "Fissare l'ingresso solare mancante 3 & 4 su Solarflow 800 Pro\nFissare lo stato 'packPower' non è stato impostato a 0 se nessun input/output",
92
- "es": "Fijar la entrada solar faltante 3 \" 4 en el flujo solar 800 Pro\nFijar 'paquetePower' estado no se estableció a 0 si no entrada / salida",
93
- "pl": "Popraw brakujące wejście Solar 3 i 4 na Solarflow 800 Pro\nStan 'packPower' nie ustawił się na 0, jeśli nie ma wejścia / wyjścia",
94
- "uk": "Виправлення відсутніх сонячних входів 3 & 4 на Solarflow 800 Pro\nВиправлення 'packPower' стану не встановлено до 0, якщо немає входу/виходу",
95
- "zh-cn": "在太阳流800 Pro 上修复缺失的太阳输入 3 & 4\n将“ packPower” 状态固定为 0 如果没有输入/输出"
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": "2.0.0-alpha.1",
3
+ "version": "2.0.0",
4
4
  "description": "zendure-solarflow",
5
5
  "author": {
6
6
  "name": "Peter",