From df1c6fdad9a669ccc6bc5df2ee723978bea81267 Mon Sep 17 00:00:00 2001 From: faanskit Date: Wed, 14 Dec 2022 09:50:19 +0100 Subject: [PATCH] Added TypedDef and protective code. Multiple Home Assistant checks passed. black....................................................................Passed codespell................................................................Passed flake8...................................................................Passed bandit...................................................................Passed isort....................................................................Passed Check JSON...............................................................Passed yamllint.............................................(no files to check)Skipped prettier.................................................................Passed mypy.....................................................................Passed pylint...................................................................Passed gen_requirements_all.....................................................Passed hassfest.................................................................Passed hassfest-metadata....................................(no files to check)Skipped hassfest-mypy-config.................................(no files to check)Skipped --- custom_components/saj_esolar_air/__init__.py | 381 +++++++- custom_components/saj_esolar_air/esolar.py | 104 +- .../saj_esolar_air/manifest.json | 2 +- custom_components/saj_esolar_air/sensor.py | 912 +++++++++--------- 4 files changed, 875 insertions(+), 524 deletions(-) diff --git a/custom_components/saj_esolar_air/__init__.py b/custom_components/saj_esolar_air/__init__.py index 2091771..df094a3 100644 --- a/custom_components/saj_esolar_air/__init__.py +++ b/custom_components/saj_esolar_air/__init__.py @@ -22,11 +22,388 @@ PLATFORMS: list[Platform] = [Platform.SENSOR] +class ESolarStoreFindRawdataPageList(TypedDict): + """API response for findRawdataPageList.""" + + nowPrower: float + rOutPowerWattStr: str + batPower: float + rBackupPowerWatt: float + pV3StrCurr1Str: str + timeStart: str + pV4Curr: float + currSelfConsumePowerStr: str + rOutVolt: float + totalPVEnergy: float + tOutVolt: float + createTimeStr: str + deviceType: int + pV4StrCurr2Str: str + pv3SeriesCurrent: str + rGridFreqStr: str + totalBatDisEnergy: float + tOutFreqStr: str + sGridPowerWattStr: str + totalBatChgEnergy: float + isAdmin: str + pV1StrCurr4: float + pV1StrCurr3: float + pV1StrCurr2: float + pV1StrCurr1: float + pv2SeriesCurrent: str + POP: float + RST: int + pvInputMode: str + rGridFreq: float + sGridFreqStr: str + sGridVoltStr: str + tOutPowerVAStr: str + pV4VoltStr: str + batEnergyPercent: float + backupTotalLoadPowerWatt: float + tableStoreTimeEnd: str + tOutVoltStr: str + rGridVoltStr: str + batVoltStr: str + tGridCurrStr: str + rGridCurr: float + rOutFreqStr: str + userId: str + partitionName: str + sGridVolt: float + pV3PowerStr: str + tOnGridOutVolt: float + tGridPowerWattStr: str + pV2StrCurr4Str: str + ctPVPowerWattStr: str + pV4StrCurr3Str: str + tOutPowerWatt: float + pV3Power: float + pV1CurrStr: str + pV2CurrStr: str + pV4CurrStr: str + onLineStr: str + pV2Power: float + todayBatDisEnergy: float + pac: float + officeId: str + rOutPowerWatt: float + pacStr: str + powernow: float + ctPvCurr: float + tGridVoltStr: str + powerNower: str + pvChannelList: list[Any] + pv1SeriesCurrent: str + pV1Power: float + pV4Volt: float + pV3StrCurr2Str: str + deviceTempStr: str + rOutCurr: float + tOutCurr: float + todayFeedInEnergyStr: str + totalPVEnergyStr: str + pV3Curr: float + sOnGridOutPowerWatt: float + tGridFreqStr: str + todayBatChgEnergy: float + pV1StrCurr1Str: str + tGridFreq: float + totalFeedInEnergy: float + sOutPowerVAStr: str + gridDirection: int + batCurrStr: str + powerNow: float + rOutPowerVA: float + kitType: str + pV1VoltStr: str + todayLoadEnergy: float + sOutPowerWattStr: str + pV4StrCurr1: float + sGridPowerVA: float + pV4StrCurr2: float + pV4StrCurr3: float + pV4StrCurr4: float + sOutPowerVA: float + batType: str + pV3Volt: float + rGridPowerVAStr: str + tGridPowerVAStr: str + tGridCurr: float + rOnGridOutFreq: float + pV4StrCurr4Str: str + tOutFreq: float + todayPVEnergy: float + tGridPowerWatt: float + sGridPowerVAStr: str + tOutCurrStr: str + ctPvCurrStr: str + pV2Curr: float + totalLoadEnergy: float + pV2PowerStr: str + datetimeStr: str + powernower: str + PVP: float + rGridCurrStr: str + totalLoadPowerWattStr: str + pV1StrCurr2Str: str + nowProwerStr: str + totalLoadEnergyStr: str + sOutVolt: float + ctGridPowerWattStr: str + rGridPowerVA: float + index: int + tGridVolt: float + todayFeedInEnergy: float + totalBatChgEnergyStr: str + tOnGridOutPowerWatt: float + pV3VoltStr: str + batPowerStr: str + pV2Volt: float + deviceSn: str + todayPVEnergyStr: str + pV3StrCurr3Str: str + rGridPowerWattStr: str + batCapicity: str + sGridCurrStr: str + sOutCurrStr: str + pV2StrCurr2: float + timeEnd: str + pV2StrCurr1: float + pV2StrCurr3Str: str + tOutPowerWattStr: str + tOutPowerVA: float + pV2StrCurr4: float + pV2StrCurr3: float + rOutFreq: float + plantuid: str + endUser: str + totalSellEnergy: float + sGridPowerWatt: float + pV1StrCurr3Str: str + rOnGridOutVolt: float + totalSellEnergyStr: str + deviceModel: str + batVolt: float + todaySellEnergy: float + totalFeedInEnergyStr: str + sOutVoltStr: str + timeStr: str + pV3CurrStr: str + pV1Curr: float + sOutPowerWatt: float + pV3StrCurr1: float + pV3StrCurr2: float + rOnGridOutPowerWatt: float + pV3StrCurr3: float + pV3StrCurr4: float + pv4SeriesCurrent: str + kitSN: str + pV2StrCurr1Str: str + pV4Power: float + todaySellEnergyStr: str + sOutFreq: float + sGridCurr: float + typeStr: str + rGridVolt: float + rOutPowerVAStr: str + rOutCurrStr: str + pV4PowerStr: str + userUid: str + pV2StrCurr2Str: str + pV4StrCurr1Str: str + ctGridPowerWatt: float + deviceTemp: float + pV2VoltStr: str + sOutFreqStr: str + batCurr: float + totalBatDisEnergyStr: str + pV1PowerStr: str + batEnergyPercentStr: str + pV1StrCurr4Str: str + ctPVPowerWatt: float + totalLoadPowerWatt: float + todaySelfConsumpEnergy: float + rOutVoltStr: str + todayLoadEnergyStr: str + rGridPowerWatt: float + sOutCurr: float + pV3StrCurr4Str: str + sGridFreq: float + tGridPowerVA: float + meterAStatus: int + pV1Volt: float + sOnGridOutVolt: float + todaySelfConsumpEnergyStr: str + plantName: str + + +class ESolarStoreDevicePower(TypedDict): + """API response for storeDevicePower.""" + + pvPower: float + gridPower: float + inputOutputPower: float + batteryPower: float + totalLoadPower: float + homeLoadPower: float + backupLoadPower: float + solarPower: float + batCurr: float + batEnergyPercent: float + runningState: int + isOnline: int + isAlarm: int + mark: int + batCapcity: float + batCapcityStr: str + hasMeter: bool + hasBattery: bool + pvDirection: int + gridDirection: int + batteryDirection: int + outPutDirection: int + dataTime: int + updateDate: int + + +class ESolarKitList(TypedDict): + """API response for kitList.""" + + invType: str + kitType: str + monthSellEnergyStr: str + todaySellEnergy: float + kitSn: str + updateDateStr: str + ifShowAFCI: int + powernower: str + mastermcufw: str + type: int + devicetype: str + onLineStr: str + displayfw: str + devicepc: str + powernow: float + isShowBattery: int + owner: str + todaySellEnergyStr: str + index: int + monthSellEnergy: float + devicesn: str + userId: str + onLine: int + slavemcufw: str + isModuleExpire: int + totalSellEnergy: float + totalSellEnergyStr: str + isShowHighVoltBat: int + isHistory: int + mark: int + plantName: str + dataTimeStr: str + findRawdataPageList: ESolarStoreFindRawdataPageList + storeDevicePower: ESolarStoreDevicePower + status: str + + +class ESolarBeanList(TypedDict): + """API response for beanList.""" + + pvElec: float + useElec: float + buyElec: float + sellElec: float + chargeElec: float + dischargeElec: float + buyRate: str + sellRate: str + selfConsumedRate1: str + selfConsumedRate2: str + selfConsumedEnergy1: float + selfConsumedEnergy2: float + plantTreeNum: float + reduceCo2: float + dataTime: None | int + devicesn: str + + +class ESolarPlantDetail(TypedDict): + """API response for platDetail.""" + + type: int + runningState: int + nowPower: float + todayElectricity: float + monthElectricity: float + yearElectricity: float + totalElectricity: float + totalConsumpElec: None | float + totalBuyElec: None | float + totalSellElec: None | float + selfUseRate: None | str + income: None | float + todayGridIncome: None | float + devOnlineNum: int + devTotalNum: int + totalPlantTreeNum: float + totalReduceCo2: float + todayAlarmNum: None | int + lastUploadTime: str + userType: int + snList: list[str] + energyCompareYearList: list[str] + + +class ESolarPeakList(TypedDict): + """API response for peakList.""" + + devicesn: str + peakPower: float + + +class ESolarPlantList(TypedDict): + """API response for plantList.""" + + plantuid: str + plantname: str + systempower: float + currency: str + type: int + installername: str + countryCode: str + country: str + province: str + city: str + county: str + foreignRemark: str + address: str + latitude: float + longitude: float + createDateStr: str + isOnline: str + runningState: int + nowPower: float + todayElectricity: float + totalElectricity: float + enableEdit: str + enableDelete: str + enableVisitor: str + isFavorite: str + isRename: int + isMulBind: int + isTimeError: int + plantDetail: ESolarPlantDetail + status: str + peakList: None | list[ESolarPeakList] + kitList: None | list[ESolarKitList] + beanList: None | list[ESolarBeanList] + + class ESolarResponse(TypedDict): """API response.""" - status: str - plantList: dict[str, Any] + plantList: list[ESolarPlantList] async def update_listener(hass, entry): diff --git a/custom_components/saj_esolar_air/esolar.py b/custom_components/saj_esolar_air/esolar.py index 8184da8..2842242 100644 --- a/custom_components/saj_esolar_air/esolar.py +++ b/custom_components/saj_esolar_air/esolar.py @@ -294,65 +294,63 @@ def web_get_device_page_list(session, plant_info, use_pv_grid_attributes): kit = [] for device in device_list: - if device["devicesn"] in plant["plantDetail"]["snList"]: - _LOGGER.debug("Device SN: %s", device["devicesn"]) - if use_pv_grid_attributes: - url = f"{BASE_URL_WEB}/cloudMonitor/deviceInfo/findRawdataPageList" - payload = f"deviceSn={device['devicesn']}&deviceType={device['type']}&timeStr={datetime.date.today().strftime('%Y-%m-%d')}" - _LOGGER.debug("Fetching URL : %s", url) - _LOGGER.debug("Fetching Payload: %s", payload) - response = session.post( - url, headers=headers, data=payload, timeout=WEB_TIMEOUT + if not device["devicesn"] in plant["plantDetail"]["snList"]: + continue + _LOGGER.debug("Device SN: %s", device["devicesn"]) + if use_pv_grid_attributes: + url = f"{BASE_URL_WEB}/cloudMonitor/deviceInfo/findRawdataPageList" + payload = f"deviceSn={device['devicesn']}&deviceType={device['type']}&timeStr={datetime.date.today().strftime('%Y-%m-%d')}" + _LOGGER.debug("Fetching URL : %s", url) + _LOGGER.debug("Fetching Payload: %s", payload) + response = session.post( + url, headers=headers, data=payload, timeout=WEB_TIMEOUT + ) + response.raise_for_status() + find_rawdata_page_list = response.json() + _LOGGER.debug( + "Result length : %s", len(find_rawdata_page_list["list"]) + ) + + if len(find_rawdata_page_list["list"]) > 0: + device.update( + {"findRawdataPageList": find_rawdata_page_list["list"][0]} ) - response.raise_for_status() - find_rawdata_page_list = response.json() + else: + device.update({"findRawdataPageList": None}) + + if VERBOSE_DEBUG and len(find_rawdata_page_list["list"]) > 0: _LOGGER.debug( - "Result length : %s", len(find_rawdata_page_list["list"]) + "\n.../findRawdataPageList\n-----------------------\n%s", + find_rawdata_page_list["list"][0], ) - if len(find_rawdata_page_list["list"]) > 0: - device.update( - { - "findRawdataPageList": find_rawdata_page_list[ - "list" - ][0] - } - ) - if VERBOSE_DEBUG: - _LOGGER.debug( - "\n.../findRawdataPageList\n-----------------------\n%s", - find_rawdata_page_list["list"][0], - ) - else: - device.update({"findRawdataPageList": None}) - - # Fetch battery for H1 system (UNTESTED CODE) - if plant["type"] == 3: - _LOGGER.debug("Fetching storage information") - epochmilliseconds = round( - int( - ( - datetime.datetime.utcnow() - - datetime.datetime(1970, 1, 1) - ).total_seconds() - * 1000 - ) + # Fetch battery for H1 system (UNTESTED CODE) + if plant["type"] == 3: + _LOGGER.debug("Fetching storage information") + epochmilliseconds = round( + int( + ( + datetime.datetime.utcnow() + - datetime.datetime(1970, 1, 1) + ).total_seconds() + * 1000 ) - url = f"{BASE_URL_WEB}/monitor/site/getStoreOrAcDevicePowerInfo" - payload = f"plantuid={plant['plantuid']}&devicesn={device['devicesn']}&_={epochmilliseconds}" - _LOGGER.debug("Fetching URL : %s", url) - _LOGGER.debug("Fetching Payload: %s", payload) - response = session.post( - url, headers=headers, data=payload, timeout=WEB_TIMEOUT + ) + url = f"{BASE_URL_WEB}/monitor/site/getStoreOrAcDevicePowerInfo" + payload = f"plantuid={plant['plantuid']}&devicesn={device['devicesn']}&_={epochmilliseconds}" + _LOGGER.debug("Fetching URL : %s", url) + _LOGGER.debug("Fetching Payload: %s", payload) + response = session.post( + url, headers=headers, data=payload, timeout=WEB_TIMEOUT + ) + response.raise_for_status() + store_device_power = response.json() + device.update(store_device_power) + if VERBOSE_DEBUG: + _LOGGER.debug( + "getStoreOrAcDevicePowerInfo\n-------------------------------\n%s", + store_device_power, ) - response.raise_for_status() - store_device_power = response.json() - device.update(store_device_power) - if VERBOSE_DEBUG: - _LOGGER.debug( - "getStoreOrAcDevicePowerInfo\n-------------------------------\n%s", - store_device_power, - ) kit.append(device) diff --git a/custom_components/saj_esolar_air/manifest.json b/custom_components/saj_esolar_air/manifest.json index e505aee..d2ea22c 100644 --- a/custom_components/saj_esolar_air/manifest.json +++ b/custom_components/saj_esolar_air/manifest.json @@ -1,7 +1,7 @@ { "domain": "saj_esolar_air", "name": "eSolar", - "version": "0.0.7", + "version": "0.0.8", "config_flow": true, "issue_tracker": "https://github.com/faanskit/ha-esolar/issues", "documentation": "https://github.com/faanskit/ha-esolar#readme", diff --git a/custom_components/saj_esolar_air/sensor.py b/custom_components/saj_esolar_air/sensor.py index 44b7747..b418c58 100644 --- a/custom_components/saj_esolar_air/sensor.py +++ b/custom_components/saj_esolar_air/sensor.py @@ -17,7 +17,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import ESolarCoordinator +from . import ESolarCoordinator, ESolarResponse from .const import ( B_B_LOAD, B_BACKUP_POWER_W, @@ -120,122 +120,125 @@ async def async_setup_entry( """Set up the eSolar sensor.""" coordinator: ESolarCoordinator = hass.data[DOMAIN][entry.entry_id] entities: list[ESolarSensor] = [] + esolar_data: ESolarResponse = coordinator.data my_plants = entry.options.get(CONF_MONITORED_SITES) use_inverter_sensors = entry.options.get(CONF_INVERTER_SENSORS) use_pv_grid_attributes = entry.options.get(CONF_PV_GRID_DATA) - if my_plants is not None: - for enabled_plant in my_plants: - for plant in coordinator.data["plantList"]: - if plant["plantname"] == enabled_plant: + if my_plants is None: + return + + for enabled_plant in my_plants: + for plant in esolar_data["plantList"]: + if plant["plantname"] != enabled_plant: + continue + + _LOGGER.debug( + "Setting up ESolarSensorPlant sensor for %s", plant["plantname"] + ) + entities.append( + ESolarSensorPlant(coordinator, plant["plantname"], plant["plantuid"]) + ) + if plant["type"] == 0: + _LOGGER.debug( + "Setting up ESolarSensorPlantTotalEnergy sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantTotalEnergy( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + elif plant["type"] == 3: + _LOGGER.debug( + "Setting up ESolarSensorPlantBatterySellEnergy sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantBatterySellEnergy( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + _LOGGER.debug( + "Setting up ESolarSensorPlantBatteryBuyEnergy sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantBatteryBuyEnergy( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + _LOGGER.debug( + "Setting up ESolarSensorPlantBatteryChargeEnergy sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantBatteryChargeEnergy( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + _LOGGER.debug( + "Setting up ESolarSensorPlantBatteryDischargeEnergy sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantBatteryDischargeEnergy( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + _LOGGER.debug( + "Setting up ESolarSensorPlantBatterySoC sensor for %s", + plant["plantname"], + ) + entities.append( + ESolarSensorPlantBatterySoC( + coordinator, plant["plantname"], plant["plantuid"] + ) + ) + + if use_inverter_sensors: + for inverter in plant["plantDetail"]["snList"]: _LOGGER.debug( - "Setting up ESolarSensorPlant sensor for %s", plant["plantname"] + "Setting up ESolarInverterEnergyTotal sensor for %s and inverter %s", + plant["plantname"], + inverter, ) entities.append( - ESolarSensorPlant( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - if plant["type"] == 0: - _LOGGER.debug( - "Setting up ESolarSensorPlantTotalEnergy sensor for %s", + ESolarInverterEnergyTotal( + coordinator, plant["plantname"], + plant["plantuid"], + inverter, ) - entities.append( - ESolarSensorPlantTotalEnergy( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - elif plant["type"] == 3: - _LOGGER.debug( - "Setting up ESolarSensorPlantBatterySellEnergy sensor for %s", - plant["plantname"], - ) - entities.append( - ESolarSensorPlantBatterySellEnergy( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - _LOGGER.debug( - "Setting up ESolarSensorPlantBatteryBuyEnergy sensor for %s", - plant["plantname"], - ) - entities.append( - ESolarSensorPlantBatteryBuyEnergy( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - _LOGGER.debug( - "Setting up ESolarSensorPlantBatteryChargeEnergy sensor for %s", - plant["plantname"], - ) - entities.append( - ESolarSensorPlantBatteryChargeEnergy( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - _LOGGER.debug( - "Setting up ESolarSensorPlantBatteryDischargeEnergy sensor for %s", + ) + _LOGGER.debug( + "Setting up ESolarInverterPower sensor for %s and inverter %s", + plant["plantname"], + inverter, + ) + entities.append( + ESolarInverterPower( + coordinator, plant["plantname"], + plant["plantuid"], + inverter, + use_pv_grid_attributes, ) - entities.append( - ESolarSensorPlantBatteryDischargeEnergy( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) + ) + if plant["type"] == 3: _LOGGER.debug( - "Setting up ESolarSensorPlantBatterySoC sensor for %s", + "Setting up ESolarInverterBatterySoC sensor for %s and inverter %s", plant["plantname"], + inverter, ) entities.append( - ESolarSensorPlantBatterySoC( - coordinator, plant["plantname"], plant["plantuid"] - ) - ) - - if use_inverter_sensors: - for inverter in plant["plantDetail"]["snList"]: - _LOGGER.debug( - "Setting up ESolarInverterEnergyTotal sensor for %s and inverter %s", - plant["plantname"], - inverter, - ) - entities.append( - ESolarInverterEnergyTotal( - coordinator, - plant["plantname"], - plant["plantuid"], - inverter, - ) - ) - _LOGGER.debug( - "Setting up ESolarInverterPower sensor for %s and inverter %s", + ESolarInverterBatterySoC( + coordinator, plant["plantname"], + plant["plantuid"], inverter, ) - entities.append( - ESolarInverterPower( - coordinator, - plant["plantname"], - plant["plantuid"], - inverter, - use_pv_grid_attributes, - ) - ) - if plant["type"] == 3: - _LOGGER.debug( - "Setting up ESolarInverterBatterySoC sensor for %s and inverter %s", - plant["plantname"], - inverter, - ) - entities.append( - ESolarInverterBatterySoC( - coordinator, - plant["plantname"], - plant["plantuid"], - inverter, - ) - ) + ) async_add_entities(entities, True) @@ -405,7 +408,7 @@ async def async_update(self) -> None: self._attr_native_value = float(plant["totalElectricity"]) @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" for plant in self._coordinator.data["plantList"]: if plant["plantname"] == self._plant_name: @@ -417,9 +420,10 @@ def native_value(self) -> str | None: plant["nowPower"] ) if plant["type"] == 0: - peak_power = 0 - for inverter in plant["peakList"]: - peak_power += inverter["peakPower"] + peak_power = float(0.0) + if plant["peakList"] is not None: + for inverter in plant["peakList"]: + peak_power += inverter["peakPower"] self._attr_extra_state_attributes[P_PEAK_POWER] = float(peak_power) else: self._attr_extra_state_attributes[P_PEAK_POWER] = None @@ -467,15 +471,19 @@ async def async_update(self) -> None: self._attr_extra_state_attributes[P_UID] = plant["plantuid"] # Setup state - self._attr_native_value = float(plant["plantDetail"]["totalBuyElec"]) + if plant["plantDetail"]["totalBuyElec"] is not None: + self._attr_native_value = float( + plant["plantDetail"]["totalBuyElec"] + ) @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" for plant in self._coordinator.data["plantList"]: if plant["plantname"] == self._plant_name: # Setup state - value = float(plant["plantDetail"]["totalBuyElec"]) + if plant["plantDetail"]["totalBuyElec"] is not None: + value = float(plant["plantDetail"]["totalBuyElec"]) return value @@ -517,15 +525,19 @@ async def async_update(self) -> None: self._attr_extra_state_attributes[P_UID] = plant["plantuid"] # Setup state - self._attr_native_value = float(plant["plantDetail"]["totalSellElec"]) + if plant["plantDetail"]["totalSellElec"] is not None: + self._attr_native_value = float( + plant["plantDetail"]["totalSellElec"] + ) @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" for plant in self._coordinator.data["plantList"]: if plant["plantname"] == self._plant_name: # Setup state - value = float(plant["plantDetail"]["totalSellElec"]) + if plant["plantDetail"]["totalSellElec"] is not None: + value = float(plant["plantDetail"]["totalSellElec"]) return value @@ -568,19 +580,19 @@ async def async_update(self) -> None: # Setup state charge = float(0) - if "beanList" in plant: + if "beanList" in plant and plant["beanList"] is not None: for bean in plant["beanList"]: charge += float(bean["chargeElec"]) self._attr_native_value = charge @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" for plant in self._coordinator.data["plantList"]: if plant["plantname"] == self._plant_name: # Setup state charge = float(0) - if "beanList" in plant: + if "beanList" in plant and plant["beanList"] is not None: for bean in plant["beanList"]: charge += float(bean["chargeElec"]) value = charge @@ -626,19 +638,19 @@ async def async_update(self) -> None: # Setup state discharge = float(0) - if "beanList" in plant: + if "beanList" in plant and plant["beanList"] is not None: for bean in plant["beanList"]: discharge += float(bean["dischargeElec"]) self._attr_native_value = discharge @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" for plant in self._coordinator.data["plantList"]: if plant["plantname"] == self._plant_name: # Setup state discharge = float(0) - if "beanList" in plant: + if "beanList" in plant and plant["beanList"] is not None: for bean in plant["beanList"]: discharge += float(bean["dischargeElec"]) value = discharge @@ -674,50 +686,54 @@ def __init__(self, coordinator: ESolarCoordinator, plant_name, plant_uid) -> Non async def async_update(self) -> None: """Get the latest data and updates the states.""" - installed_power = 0 - available_power = 0 + installed_power = float(0) + available_power = float(0) for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: - # Setup static attributes - self._attr_available = True - self._attr_extra_state_attributes[P_NAME] = plant["plantname"] - self._attr_extra_state_attributes[P_UID] = plant["plantuid"] - - # Setup state - for inverter in plant["plantDetail"]["snList"]: - for kit in plant["kitList"]: - if inverter == kit["devicesn"]: - if kit["onLineStr"] == "1": - installed_power += kit["storeDevicePower"]["batCapcity"] - available_power += ( - kit["storeDevicePower"]["batCapcity"] - * kit["storeDevicePower"]["batEnergyPercent"] - ) + if plant["plantname"] != self._plant_name: + continue + # Setup static attributes + self._attr_available = True + self._attr_extra_state_attributes[P_NAME] = plant["plantname"] + self._attr_extra_state_attributes[P_UID] = plant["plantuid"] + + # Setup state + for inverter in plant["plantDetail"]["snList"]: + if "kitList" not in plant or plant["kitList"] is None: + continue + for kit in plant["kitList"]: + if inverter == kit["devicesn"] and kit["onLineStr"] == "1": + installed_power += kit["storeDevicePower"]["batCapcity"] + available_power += ( + kit["storeDevicePower"]["batCapcity"] + * kit["storeDevicePower"]["batEnergyPercent"] + ) - if installed_power > 0: - self._attr_native_value = float(available_power / installed_power) + if installed_power > 0: + self._attr_native_value = float(available_power / installed_power) @property - def native_value(self) -> str | None: + def native_value(self) -> float | None: """Return sensor state.""" - installed_power = 0 - available_power = 0 + installed_power = float(0) + available_power = float(0) for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: - # Setup state - for inverter in plant["plantDetail"]["snList"]: - for kit in plant["kitList"]: - if inverter == kit["devicesn"]: - if kit["onLineStr"] == "1": - installed_power += kit["storeDevicePower"]["batCapcity"] - available_power += ( - kit["storeDevicePower"]["batCapcity"] - * kit["storeDevicePower"]["batEnergyPercent"] - ) - if installed_power > 0: - value = float(available_power / installed_power) - else: - value = None + if plant["plantname"] != self._plant_name: + continue + # Setup state + for inverter in plant["plantDetail"]["snList"]: + if "kitList" not in plant or plant["kitList"] is None: + continue + for kit in plant["kitList"]: + if inverter == kit["devicesn"] and kit["onLineStr"] == "1": + installed_power += kit["storeDevicePower"]["batCapcity"] + available_power += ( + kit["storeDevicePower"]["batCapcity"] + * kit["storeDevicePower"]["batEnergyPercent"] + ) + if installed_power > 0: + value = float(available_power / installed_power) + else: + value = None return value @@ -772,6 +788,8 @@ async def async_update(self) -> None: self._attr_available = True self._attr_extra_state_attributes[P_NAME] = plant["plantname"] self._attr_extra_state_attributes[P_UID] = plant["plantuid"] + if "kitList" not in plant or plant["kitList"] is None: + continue for kit in plant["kitList"]: if kit["devicesn"] == self.inverter_sn: self._attr_extra_state_attributes[I_MODEL] = kit["devicetype"] @@ -801,76 +819,61 @@ def native_value(self) -> float | None: """Return sensor state.""" value = None for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: + if plant["plantname"] != self._plant_name: + continue + if "kitList" in plant and plant["kitList"] is not None: for kit in plant["kitList"]: - if kit["devicesn"] == self.inverter_sn: - # Setup state - value = float(kit["totalSellEnergy"]) - - # Setup dynamic attributes - self._attr_extra_state_attributes[I_TODAY_E] = float( - kit["todaySellEnergy"] - ) - self._attr_extra_state_attributes[I_MONTH_E] = float( - kit["monthSellEnergy"] - ) - self._attr_extra_state_attributes[I_TOTAL_E] = float( - kit["totalSellEnergy"] - ) - if kit["onLineStr"] == "1": - self._attr_extra_state_attributes[I_STATUS] = I_NORMAL - elif kit["onLineStr"] == "2": - self._attr_extra_state_attributes[I_STATUS] = I_ALARM - elif kit["onLineStr"] == "3": - self._attr_extra_state_attributes[I_STATUS] = I_OFFLINE - elif kit["onLineStr"] == "4": - self._attr_extra_state_attributes[I_STATUS] = I_STOCK - elif kit["onLineStr"] == "4": - self._attr_extra_state_attributes[I_STATUS] = I_HISTORY + if kit["devicesn"] != self.inverter_sn: + continue + # Setup state + value = float(kit["totalSellEnergy"]) + + # Setup dynamic attributes + self._attr_extra_state_attributes[I_TODAY_E] = float( + kit["todaySellEnergy"] + ) + self._attr_extra_state_attributes[I_MONTH_E] = float( + kit["monthSellEnergy"] + ) + self._attr_extra_state_attributes[I_TOTAL_E] = float( + kit["totalSellEnergy"] + ) + if kit["onLineStr"] == "1": + self._attr_extra_state_attributes[I_STATUS] = I_NORMAL + elif kit["onLineStr"] == "2": + self._attr_extra_state_attributes[I_STATUS] = I_ALARM + elif kit["onLineStr"] == "3": + self._attr_extra_state_attributes[I_STATUS] = I_OFFLINE + elif kit["onLineStr"] == "4": + self._attr_extra_state_attributes[I_STATUS] = I_STOCK + elif kit["onLineStr"] == "4": + self._attr_extra_state_attributes[I_STATUS] = I_HISTORY + else: + self._attr_extra_state_attributes[I_STATUS] = P_UNKNOWN + + self._attr_extra_state_attributes[I_CURRENT_POWER] = kit["powernow"] + + if kit["type"] == 2: + if kit["storeDevicePower"]["batteryDirection"] == 0: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_STB + elif kit["storeDevicePower"]["batteryDirection"] == 1: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_DIS + elif kit["storeDevicePower"]["batteryDirection"] == -1: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_CH else: - self._attr_extra_state_attributes[I_STATUS] = P_UNKNOWN - - self._attr_extra_state_attributes[I_CURRENT_POWER] = kit[ - "powernow" + self._attr_extra_state_attributes[B_DIRECTION] = P_UNKNOWN + if "beanList" in plant and plant["beanList"] is not None: + for bean in plant["beanList"]: + if bean["devicesn"] == self.inverter_sn: + self._attr_extra_state_attributes[B_PVELEC] = bean["pvElec"] + self._attr_extra_state_attributes[B_USELEC] = bean["useElec"] + self._attr_extra_state_attributes[B_BUYELEC] = bean["buyElec"] + self._attr_extra_state_attributes[B_SELLELEC] = bean["sellElec"] + self._attr_extra_state_attributes[B_BUY_RATE] = bean["buyRate"] + self._attr_extra_state_attributes[B_SELL_RATE] = bean[ + "sellRate" ] - if kit["type"] == 2: - if kit["storeDevicePower"]["batteryDirection"] == 0: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_STB - elif kit["storeDevicePower"]["batteryDirection"] == 1: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_DIS - elif kit["storeDevicePower"]["batteryDirection"] == -1: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_CH - else: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = P_UNKNOWN - if "beanList" in plant: - for bean in plant["beanList"]: - if bean["devicesn"] == self.inverter_sn: - self._attr_extra_state_attributes[B_PVELEC] = bean["pvElec"] - self._attr_extra_state_attributes[B_USELEC] = bean[ - "useElec" - ] - self._attr_extra_state_attributes[B_BUYELEC] = bean[ - "buyElec" - ] - self._attr_extra_state_attributes[B_SELLELEC] = bean[ - "sellElec" - ] - self._attr_extra_state_attributes[B_BUY_RATE] = bean[ - "buyRate" - ] - self._attr_extra_state_attributes[B_SELL_RATE] = bean[ - "sellRate" - ] - return value @@ -932,151 +935,145 @@ async def async_update(self) -> None: self._attr_available = True self._attr_extra_state_attributes[P_NAME] = plant["plantname"] self._attr_extra_state_attributes[P_UID] = plant["plantuid"] - for kit in plant["kitList"]: - if kit["devicesn"] == self.inverter_sn: - self._attr_extra_state_attributes[I_MODEL] = kit["devicetype"] - self._attr_extra_state_attributes[I_SN] = kit["devicesn"] + if "kitList" in plant and plant["kitList"] is not None: + for kit in plant["kitList"]: + if kit["devicesn"] == self.inverter_sn: + self._attr_extra_state_attributes[I_MODEL] = kit[ + "devicetype" + ] + self._attr_extra_state_attributes[I_SN] = kit["devicesn"] - # Setup state - self._attr_native_value = float(kit["powernow"]) + # Setup state + self._attr_native_value = float(kit["powernow"]) @property def native_value(self) -> float | None: """Return sensor state.""" value = None for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: - # Setup dynamic attributes - for kit in plant["kitList"]: - if kit["devicesn"] == self.inverter_sn: - if self.use_pv_grid_attributes: - if kit["onLineStr"] == "1": - self._attr_extra_state_attributes[I_PV_VOL_PV] = [ - kit["findRawdataPageList"]["pV1Volt"], - kit["findRawdataPageList"]["pV2Volt"], - kit["findRawdataPageList"]["pV3Volt"], - ] - self._attr_extra_state_attributes[I_PV_CURR_PV] = [ - kit["findRawdataPageList"]["pV1Curr"], - kit["findRawdataPageList"]["pV2Curr"], - kit["findRawdataPageList"]["pV3Curr"], - ] - self._attr_extra_state_attributes[I_G_VOL_L] = [ - kit["findRawdataPageList"]["rGridVolt"], - kit["findRawdataPageList"]["sGridVolt"], - kit["findRawdataPageList"]["tGridVolt"], - ] - self._attr_extra_state_attributes[I_G_CURR_L] = [ - kit["findRawdataPageList"]["rGridCurr"], - kit["findRawdataPageList"]["sGridCurr"], - kit["findRawdataPageList"]["tGridCurr"], - ] - self._attr_extra_state_attributes[I_G_FREQ_L] = [ - kit["findRawdataPageList"]["rGridFreq"], - kit["findRawdataPageList"]["sGridFreq"], - kit["findRawdataPageList"]["tGridFreq"], - ] - if (kit["findRawdataPageList"]["deviceType"]) == 2: - - self._attr_extra_state_attributes[ - B_GRID_POWER_W - ] = [ - kit["findRawdataPageList"]["rGridPowerWatt"], - kit["findRawdataPageList"]["sGridPowerWatt"], - kit["findRawdataPageList"]["tGridPowerWatt"], - ] - self._attr_extra_state_attributes[ - B_GRID_POWER_VA - ] = [ - kit["findRawdataPageList"]["rGridPowerVA"], - kit["findRawdataPageList"]["sGridPowerVA"], - kit["findRawdataPageList"]["tGridPowerVA"], - ] - self._attr_extra_state_attributes[B_OUT_VOLT] = [ - kit["findRawdataPageList"]["rOutVolt"], - kit["findRawdataPageList"]["sOutVolt"], - kit["findRawdataPageList"]["tOutVolt"], - ] - self._attr_extra_state_attributes[B_OUT_CURR] = [ - kit["findRawdataPageList"]["rOutCurr"], - kit["findRawdataPageList"]["sOutCurr"], - kit["findRawdataPageList"]["tOutCurr"], - ] - self._attr_extra_state_attributes[ - B_OUT_POWER_WATT - ] = [ - kit["findRawdataPageList"]["rOutPowerWatt"], - kit["findRawdataPageList"]["sOutPowerWatt"], - kit["findRawdataPageList"]["tOutPowerWatt"], - ] - self._attr_extra_state_attributes[ - B_OUT_POWER_VA - ] = [ - kit["findRawdataPageList"]["rOutPowerVA"], - kit["findRawdataPageList"]["sOutPowerVA"], - kit["findRawdataPageList"]["tOutPowerVA"], - ] - self._attr_extra_state_attributes[B_OUT_FREQ] = [ - kit["findRawdataPageList"]["rOutFreq"], - kit["findRawdataPageList"]["sOutFreq"], - kit["findRawdataPageList"]["tOutFreq"], - ] - self._attr_extra_state_attributes[B_ON_G_VOLT] = [ - kit["findRawdataPageList"]["rOnGridOutVolt"], - kit["findRawdataPageList"]["sOnGridOutVolt"], - kit["findRawdataPageList"]["tOnGridOutVolt"], - ] - self._attr_extra_state_attributes[B_ON_G_FREQ] = [ - kit["findRawdataPageList"]["rOnGridOutFreq"] - ] - self._attr_extra_state_attributes[ - B_ON_G_POWER_W - ] = [ - kit["findRawdataPageList"][ - "rOnGridOutPowerWatt" - ], - kit["findRawdataPageList"][ - "sOnGridOutPowerWatt" - ], - kit["findRawdataPageList"][ - "tOnGridOutPowerWatt" - ], - ] - self._attr_extra_state_attributes[B_ON_G_FREQ] = [ - kit["findRawdataPageList"]["rOnGridOutFreq"] - ] - self._attr_extra_state_attributes[ - B_BACKUP_POWER_W - ] = [kit["findRawdataPageList"]["rBackupPowerWatt"]] - else: - self._attr_extra_state_attributes[I_PV_VOL_PV] = [ - None, - None, - None, - ] - self._attr_extra_state_attributes[I_PV_CURR_PV] = [ - None, - None, - None, - ] - self._attr_extra_state_attributes[I_G_VOL_L] = [ - None, - None, - None, - ] - self._attr_extra_state_attributes[I_G_CURR_L] = [ - None, - None, - None, - ] - self._attr_extra_state_attributes[I_G_FREQ_L] = [ - None, - None, - None, - ] + if plant["plantname"] != self._plant_name: + continue + # Setup dynamic attributes + if "kitList" not in plant or plant["kitList"] is None: + continue + for kit in plant["kitList"]: + if kit["devicesn"] != self.inverter_sn: + continue - # Setup state - value = float(kit["powernow"]) + # Setup state + value = float(kit["powernow"]) + + if not self.use_pv_grid_attributes: + continue + + if kit["onLineStr"] == "1": + self._attr_extra_state_attributes[I_PV_VOL_PV] = [ + kit["findRawdataPageList"]["pV1Volt"], + kit["findRawdataPageList"]["pV2Volt"], + kit["findRawdataPageList"]["pV3Volt"], + ] + self._attr_extra_state_attributes[I_PV_CURR_PV] = [ + kit["findRawdataPageList"]["pV1Curr"], + kit["findRawdataPageList"]["pV2Curr"], + kit["findRawdataPageList"]["pV3Curr"], + ] + self._attr_extra_state_attributes[I_G_VOL_L] = [ + kit["findRawdataPageList"]["rGridVolt"], + kit["findRawdataPageList"]["sGridVolt"], + kit["findRawdataPageList"]["tGridVolt"], + ] + self._attr_extra_state_attributes[I_G_CURR_L] = [ + kit["findRawdataPageList"]["rGridCurr"], + kit["findRawdataPageList"]["sGridCurr"], + kit["findRawdataPageList"]["tGridCurr"], + ] + self._attr_extra_state_attributes[I_G_FREQ_L] = [ + kit["findRawdataPageList"]["rGridFreq"], + kit["findRawdataPageList"]["sGridFreq"], + kit["findRawdataPageList"]["tGridFreq"], + ] + if (kit["findRawdataPageList"]["deviceType"]) == 2: + + self._attr_extra_state_attributes[B_GRID_POWER_W] = [ + kit["findRawdataPageList"]["rGridPowerWatt"], + kit["findRawdataPageList"]["sGridPowerWatt"], + kit["findRawdataPageList"]["tGridPowerWatt"], + ] + self._attr_extra_state_attributes[B_GRID_POWER_VA] = [ + kit["findRawdataPageList"]["rGridPowerVA"], + kit["findRawdataPageList"]["sGridPowerVA"], + kit["findRawdataPageList"]["tGridPowerVA"], + ] + self._attr_extra_state_attributes[B_OUT_VOLT] = [ + kit["findRawdataPageList"]["rOutVolt"], + kit["findRawdataPageList"]["sOutVolt"], + kit["findRawdataPageList"]["tOutVolt"], + ] + self._attr_extra_state_attributes[B_OUT_CURR] = [ + kit["findRawdataPageList"]["rOutCurr"], + kit["findRawdataPageList"]["sOutCurr"], + kit["findRawdataPageList"]["tOutCurr"], + ] + self._attr_extra_state_attributes[B_OUT_POWER_WATT] = [ + kit["findRawdataPageList"]["rOutPowerWatt"], + kit["findRawdataPageList"]["sOutPowerWatt"], + kit["findRawdataPageList"]["tOutPowerWatt"], + ] + self._attr_extra_state_attributes[B_OUT_POWER_VA] = [ + kit["findRawdataPageList"]["rOutPowerVA"], + kit["findRawdataPageList"]["sOutPowerVA"], + kit["findRawdataPageList"]["tOutPowerVA"], + ] + self._attr_extra_state_attributes[B_OUT_FREQ] = [ + kit["findRawdataPageList"]["rOutFreq"], + kit["findRawdataPageList"]["sOutFreq"], + kit["findRawdataPageList"]["tOutFreq"], + ] + self._attr_extra_state_attributes[B_ON_G_VOLT] = [ + kit["findRawdataPageList"]["rOnGridOutVolt"], + kit["findRawdataPageList"]["sOnGridOutVolt"], + kit["findRawdataPageList"]["tOnGridOutVolt"], + ] + self._attr_extra_state_attributes[B_ON_G_FREQ] = [ + kit["findRawdataPageList"]["rOnGridOutFreq"] + ] + self._attr_extra_state_attributes[B_ON_G_POWER_W] = [ + kit["findRawdataPageList"]["rOnGridOutPowerWatt"], + kit["findRawdataPageList"]["sOnGridOutPowerWatt"], + kit["findRawdataPageList"]["tOnGridOutPowerWatt"], + ] + self._attr_extra_state_attributes[B_ON_G_FREQ] = [ + kit["findRawdataPageList"]["rOnGridOutFreq"] + ] + self._attr_extra_state_attributes[B_BACKUP_POWER_W] = [ + kit["findRawdataPageList"]["rBackupPowerWatt"] + ] + else: + self._attr_extra_state_attributes[I_PV_VOL_PV] = [ + None, + None, + None, + ] + self._attr_extra_state_attributes[I_PV_CURR_PV] = [ + None, + None, + None, + ] + self._attr_extra_state_attributes[I_G_VOL_L] = [ + None, + None, + None, + ] + self._attr_extra_state_attributes[I_G_CURR_L] = [ + None, + None, + None, + ] + self._attr_extra_state_attributes[I_G_FREQ_L] = [ + None, + None, + None, + ] return value @@ -1133,24 +1130,27 @@ def __init__( async def async_update(self) -> None: """Get the latest data and updates the states.""" for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: - # Setup static attributes - self._attr_available = True - self._attr_extra_state_attributes[P_NAME] = plant["plantname"] - self._attr_extra_state_attributes[P_UID] = plant["plantuid"] - for kit in plant["kitList"]: - if kit["devicesn"] == self.inverter_sn: - self._attr_extra_state_attributes[I_MODEL] = kit["devicetype"] - self._attr_extra_state_attributes[I_SN] = kit["devicesn"] - self._attr_extra_state_attributes[B_CAPACITY] = kit[ - "storeDevicePower" - ]["batCapcityStr"] - - # Setup state - if kit["onLineStr"] == "1": - self._attr_native_value = kit["storeDevicePower"][ - "batEnergyPercent" - ] + if plant["plantname"] != self._plant_name: + continue + # Setup static attributes + self._attr_available = True + self._attr_extra_state_attributes[P_NAME] = plant["plantname"] + self._attr_extra_state_attributes[P_UID] = plant["plantuid"] + if "kitList" not in plant or plant["kitList"] is None: + continue + for kit in plant["kitList"]: + if kit["devicesn"] == self.inverter_sn: + self._attr_extra_state_attributes[I_MODEL] = kit["devicetype"] + self._attr_extra_state_attributes[I_SN] = kit["devicesn"] + self._attr_extra_state_attributes[B_CAPACITY] = kit[ + "storeDevicePower" + ]["batCapcityStr"] + + # Setup state + if kit["onLineStr"] == "1": + self._attr_native_value = kit["storeDevicePower"][ + "batEnergyPercent" + ] @property def native_value(self) -> float | None: @@ -1158,99 +1158,75 @@ def native_value(self) -> float | None: # Setup state value = None for plant in self._coordinator.data["plantList"]: - if plant["plantname"] == self._plant_name: - for kit in plant["kitList"]: - if self.inverter_sn == kit["devicesn"]: - if kit["onLineStr"] == "1": - value = float(kit["storeDevicePower"]["batEnergyPercent"]) - - # Setup dynamic attributes - self._attr_extra_state_attributes[B_CURRENT] = kit[ - "storeDevicePower" - ]["batCurr"] - self._attr_extra_state_attributes[B_POWER] = kit[ - "storeDevicePower" - ]["batteryPower"] - - if kit["storeDevicePower"]["batteryDirection"] == 0: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_STB - elif kit["storeDevicePower"]["batteryDirection"] == 1: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_DIS - elif kit["storeDevicePower"]["batteryDirection"] == -1: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = B_DIR_CH - else: - self._attr_extra_state_attributes[ - B_DIRECTION - ] = P_UNKNOWN - - self._attr_extra_state_attributes[G_POWER] = kit[ - "storeDevicePower" - ]["gridPower"] - - if kit["storeDevicePower"]["gridDirection"] == 1: - self._attr_extra_state_attributes[ - B_GRID_DIRECT - ] = B_EXPORT - elif kit["storeDevicePower"]["gridDirection"] == -1: - self._attr_extra_state_attributes[ - B_GRID_DIRECT - ] = B_IMPORT - else: - self._attr_extra_state_attributes[ - B_GRID_DIRECT - ] = P_UNKNOWN - - self._attr_extra_state_attributes[IO_POWER] = kit[ - "storeDevicePower" - ]["inputOutputPower"] - - if kit["storeDevicePower"]["outPutDirection"] == 1: - self._attr_extra_state_attributes[ - IO_DIRECTION - ] = B_EXPORT - elif kit["storeDevicePower"]["outPutDirection"] == -1: - self._attr_extra_state_attributes[ - IO_DIRECTION - ] = B_IMPORT - else: - self._attr_extra_state_attributes[ - IO_DIRECTION - ] = P_UNKNOWN - - self._attr_extra_state_attributes[PV_POWER] = kit[ - "storeDevicePower" - ]["pvPower"] - - if kit["storeDevicePower"]["pvDirection"] == 1: - self._attr_extra_state_attributes[ - PV_DIRECTION - ] = B_EXPORT - elif kit["storeDevicePower"]["pvDirection"] == -1: - self._attr_extra_state_attributes[ - PV_DIRECTION - ] = B_IMPORT - else: - self._attr_extra_state_attributes[ - PV_DIRECTION - ] = P_UNKNOWN - - self._attr_extra_state_attributes[B_T_LOAD] = kit[ - "storeDevicePower" - ]["totalLoadPower"] - self._attr_extra_state_attributes[B_H_LOAD] = kit[ - "storeDevicePower" - ]["homeLoadPower"] - self._attr_extra_state_attributes[B_B_LOAD] = kit[ - "storeDevicePower" - ]["backupLoadPower"] - self._attr_extra_state_attributes[S_POWER] = kit[ - "storeDevicePower" - ]["solarPower"] + if plant["plantname"] != self._plant_name: + continue + if "kitList" not in plant or plant["kitList"] is None: + continue + for kit in plant["kitList"]: + if self.inverter_sn == kit["devicesn"] and kit["onLineStr"] == "1": + value = float(kit["storeDevicePower"]["batEnergyPercent"]) + + # Setup dynamic attributes + self._attr_extra_state_attributes[B_CURRENT] = kit[ + "storeDevicePower" + ]["batCurr"] + self._attr_extra_state_attributes[B_POWER] = kit[ + "storeDevicePower" + ]["batteryPower"] + + if kit["storeDevicePower"]["batteryDirection"] == 0: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_STB + elif kit["storeDevicePower"]["batteryDirection"] == 1: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_DIS + elif kit["storeDevicePower"]["batteryDirection"] == -1: + self._attr_extra_state_attributes[B_DIRECTION] = B_DIR_CH + else: + self._attr_extra_state_attributes[B_DIRECTION] = P_UNKNOWN + + self._attr_extra_state_attributes[G_POWER] = kit[ + "storeDevicePower" + ]["gridPower"] + + if kit["storeDevicePower"]["gridDirection"] == 1: + self._attr_extra_state_attributes[B_GRID_DIRECT] = B_EXPORT + elif kit["storeDevicePower"]["gridDirection"] == -1: + self._attr_extra_state_attributes[B_GRID_DIRECT] = B_IMPORT + else: + self._attr_extra_state_attributes[B_GRID_DIRECT] = P_UNKNOWN + + self._attr_extra_state_attributes[IO_POWER] = kit[ + "storeDevicePower" + ]["inputOutputPower"] + + if kit["storeDevicePower"]["outPutDirection"] == 1: + self._attr_extra_state_attributes[IO_DIRECTION] = B_EXPORT + elif kit["storeDevicePower"]["outPutDirection"] == -1: + self._attr_extra_state_attributes[IO_DIRECTION] = B_IMPORT + else: + self._attr_extra_state_attributes[IO_DIRECTION] = P_UNKNOWN + + self._attr_extra_state_attributes[PV_POWER] = kit[ + "storeDevicePower" + ]["pvPower"] + + if kit["storeDevicePower"]["pvDirection"] == 1: + self._attr_extra_state_attributes[PV_DIRECTION] = B_EXPORT + elif kit["storeDevicePower"]["pvDirection"] == -1: + self._attr_extra_state_attributes[PV_DIRECTION] = B_IMPORT + else: + self._attr_extra_state_attributes[PV_DIRECTION] = P_UNKNOWN + + self._attr_extra_state_attributes[B_T_LOAD] = kit[ + "storeDevicePower" + ]["totalLoadPower"] + self._attr_extra_state_attributes[B_H_LOAD] = kit[ + "storeDevicePower" + ]["homeLoadPower"] + self._attr_extra_state_attributes[B_B_LOAD] = kit[ + "storeDevicePower" + ]["backupLoadPower"] + self._attr_extra_state_attributes[S_POWER] = kit[ + "storeDevicePower" + ]["solarPower"] return value