Skip to content

Commit d0e3e3b

Browse files
Merge branch 'main' into config-flow-reconfigure
2 parents 70bd3d1 + a58568c commit d0e3e3b

File tree

6 files changed

+56
-20
lines changed

6 files changed

+56
-20
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ body:
3333
id: diagnostic-file
3434
attributes:
3535
label: Diagnostic File
36-
description: Drag and drop to attach your diagnostic file. The diagnostic file is a snapshot. Make sure it's taken at the exact time the issue is happening.
36+
description: REQUIRED. Drag and drop to attach your diagnostic file. The diagnostic file is a snapshot. Make sure it's taken at the exact time the issue is happening. Diagnostic file is not required when reporting an issue that prevents the integration from starting.
3737
validations:
3838
required: true
3939
- type: textarea
4040
id: log-file
4141
attributes:
4242
label: Debug logs
43-
description: Debug logs are not always necessary, but may be required for more complex issues. You can enable debug logs in Home Assistant. Debug logging will generate a large amount of data. Turn on debug only to observe the isseue then turn off debug during normal operation.
43+
description: Optional. Debug logs are not always necessary, but may be required for more complex issues. You can enable debug logs in Home Assistant. Debug logging will generate a large amount of data. Turn on debug only to observe the isseue then turn off debug during normal operation. Debug logs are required when reporting an issue that prevents the integration from starting.
4444
render: shell
4545
- type: input
4646
id: ha-version

.github/workflows/python-quality.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v4
15-
- uses: WillCodeForCats/[email protected].4
15+
- uses: WillCodeForCats/[email protected].6
1616
with:
1717
python-root-list: "custom_components/solaredge_modbus_multi"
1818
use-flake8: true

custom_components/solaredge_modbus_multi/config_flow.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class SolaredgeModbusMultiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
2929
"""Handle a config flow for SolarEdge Modbus Multi."""
3030

3131
VERSION = 1
32+
MINOR_VERSION = 1
3233

3334
@staticmethod
3435
@callback

custom_components/solaredge_modbus_multi/hub.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,14 @@ async def _async_init_solaredge(self) -> None:
241241
inverter_unit_id = inverter_index + self._start_device_id
242242

243243
try:
244+
_LOGGER.debug(
245+
f"Looking for inverter at {self.hub_host} ID {inverter_unit_id}"
246+
)
244247
new_inverter = SolarEdgeInverter(inverter_unit_id, self)
245248
await new_inverter.init_device()
246249
self.inverters.append(new_inverter)
247250

248-
except ModbusReadError as e:
251+
except (ModbusReadError, TimeoutError) as e:
249252
self.disconnect()
250253
raise HubInitFailed(f"{e}")
251254

@@ -257,6 +260,9 @@ async def _async_init_solaredge(self) -> None:
257260
if self._detect_meters:
258261
for meter_id in METER_REG_BASE:
259262
try:
263+
_LOGGER.debug(
264+
f"Looking for meter I{inverter_unit_id}M{meter_id}"
265+
)
260266
new_meter = SolarEdgeMeter(inverter_unit_id, meter_id, self)
261267
await new_meter.init_device()
262268

@@ -274,7 +280,7 @@ async def _async_init_solaredge(self) -> None:
274280
self.meters.append(new_meter)
275281
_LOGGER.debug(f"Found I{inverter_unit_id}M{meter_id}")
276282

277-
except ModbusReadError as e:
283+
except (ModbusReadError, TimeoutError) as e:
278284
self.disconnect()
279285
raise HubInitFailed(f"{e}")
280286

@@ -285,6 +291,9 @@ async def _async_init_solaredge(self) -> None:
285291
if self._detect_batteries:
286292
for battery_id in BATTERY_REG_BASE:
287293
try:
294+
_LOGGER.debug(
295+
f"Looking for battery I{inverter_unit_id}B{battery_id}"
296+
)
288297
new_battery = SolarEdgeBattery(
289298
inverter_unit_id, battery_id, self
290299
)
@@ -307,7 +316,7 @@ async def _async_init_solaredge(self) -> None:
307316
self.batteries.append(new_battery)
308317
_LOGGER.debug(f"Found I{inverter_unit_id}B{battery_id}")
309318

310-
except ModbusReadError as e:
319+
except (ModbusReadError, TimeoutError) as e:
311320
self.disconnect()
312321
raise HubInitFailed(f"{e}")
313322

@@ -341,6 +350,10 @@ async def _async_init_solaredge(self) -> None:
341350
self.disconnect()
342351
raise HubInitFailed(f"Modbus error: {e}")
343352

353+
except TimeoutError as e:
354+
self.disconnect()
355+
raise HubInitFailed(f"Timeout error: {e}")
356+
344357
self.initalized = True
345358

346359
async def async_refresh_modbus_data(self) -> bool:
@@ -739,6 +752,8 @@ def __init__(self, device_id: int, hub: SolarEdgeModbusMultiHub) -> None:
739752
self.site_limit_control = None
740753

741754
async def init_device(self) -> None:
755+
"""Set up data about the device from modbus."""
756+
742757
try:
743758
inverter_data = await self.hub.modbus_read_holding_registers(
744759
unit=self.inverter_unit_id, address=40000, rcount=69
@@ -856,14 +871,27 @@ async def init_device(self) -> None:
856871
self.manufacturer = self.decoded_common["C_Manufacturer"]
857872
self.model = self.decoded_common["C_Model"]
858873
self.option = self.decoded_common["C_Option"]
859-
self.fw_version = self.decoded_common["C_Version"]
860874
self.serial = self.decoded_common["C_SerialNumber"]
861875
self.device_address = self.decoded_common["C_Device_address"]
862876
self.name = f"{self.hub.hub_id.capitalize()} I{self.inverter_unit_id}"
863877
self.uid_base = f"{self.model}_{self.serial}"
864878

865879
async def read_modbus_data(self) -> None:
880+
"""Read and update dynamic modbus registers."""
881+
866882
try:
883+
inverter_data = await self.hub.modbus_read_holding_registers(
884+
unit=self.inverter_unit_id, address=40044, rcount=16
885+
)
886+
887+
decoder = BinaryPayloadDecoder.fromRegisters(
888+
inverter_data.registers, byteorder=Endian.BIG
889+
)
890+
891+
self.decoded_common["C_Version"] = parse_modbus_string(
892+
decoder.decode_string(16)
893+
)
894+
867895
inverter_data = await self.hub.modbus_read_holding_registers(
868896
unit=self.inverter_unit_id, address=40069, rcount=40
869897
)
@@ -1362,6 +1390,13 @@ def online(self) -> bool:
13621390
"""Device is online."""
13631391
return self.hub.online
13641392

1393+
@property
1394+
def fw_version(self) -> str | None:
1395+
if "C_Version" in self.decoded_common:
1396+
return self.decoded_common["C_Version"]
1397+
1398+
return None
1399+
13651400
@property
13661401
def device_info(self) -> DeviceInfo:
13671402
"""Return the device info."""

custom_components/solaredge_modbus_multi/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"issue_tracker": "https://github.com/WillCodeForCats/solaredge-modbus-multi/issues",
1111
"loggers": ["custom_components.solaredge_modbus_multi"],
1212
"requirements": ["pymodbus>=3.6.6"],
13-
"version": "2.4.13"
13+
"version": "2.4.14-pre.2"
1414
}

custom_components/solaredge_modbus_multi/sensor.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,7 +1740,8 @@ def native_value(self):
17401740
class SolarEdgeBatteryEnergyExport(SolarEdgeSensorBase):
17411741
device_class = SensorDeviceClass.ENERGY
17421742
state_class = SensorStateClass.TOTAL_INCREASING
1743-
native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
1743+
native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
1744+
suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
17441745
suggested_display_precision = 3
17451746
icon = "mdi:battery-charging-20"
17461747

@@ -1780,9 +1781,7 @@ def native_value(self):
17801781
if self._platform.allow_battery_energy_reset:
17811782
self._count = 0
17821783

1783-
return (
1784-
self._platform.decoded_model["B_Export_Energy_WH"] * 0.001
1785-
)
1784+
return self._platform.decoded_model["B_Export_Energy_WH"]
17861785

17871786
else:
17881787
if self._platform.allow_battery_energy_reset:
@@ -1815,7 +1814,8 @@ def native_value(self):
18151814
class SolarEdgeBatteryEnergyImport(SolarEdgeSensorBase):
18161815
device_class = SensorDeviceClass.ENERGY
18171816
state_class = SensorStateClass.TOTAL_INCREASING
1818-
native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
1817+
native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
1818+
suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
18191819
suggested_display_precision = 3
18201820
icon = "mdi:battery-charging-100"
18211821

@@ -1855,9 +1855,7 @@ def native_value(self):
18551855
if self._platform.allow_battery_energy_reset:
18561856
self._count = 0
18571857

1858-
return (
1859-
self._platform.decoded_model["B_Import_Energy_WH"] * 0.001
1860-
)
1858+
return self._platform.decoded_model["B_Import_Energy_WH"]
18611859

18621860
else:
18631861
if self._platform.allow_battery_energy_reset:
@@ -1890,7 +1888,8 @@ def native_value(self):
18901888
class SolarEdgeBatteryMaxEnergy(SolarEdgeSensorBase):
18911889
device_class = SensorDeviceClass.ENERGY_STORAGE
18921890
state_class = SensorStateClass.MEASUREMENT
1893-
native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
1891+
native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
1892+
suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
18941893
suggested_display_precision = 3
18951894

18961895
@property
@@ -1913,7 +1912,7 @@ def native_value(self):
19131912
return None
19141913

19151914
else:
1916-
return self._platform.decoded_model["B_Energy_Max"] * 0.001
1915+
return self._platform.decoded_model["B_Energy_Max"]
19171916

19181917

19191918
class SolarEdgeBatteryPowerBase(SolarEdgeSensorBase):
@@ -2027,7 +2026,8 @@ def native_value(self):
20272026
class SolarEdgeBatteryAvailableEnergy(SolarEdgeSensorBase):
20282027
device_class = SensorDeviceClass.ENERGY_STORAGE
20292028
state_class = SensorStateClass.MEASUREMENT
2030-
native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
2029+
native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
2030+
suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
20312031
suggested_display_precision = 3
20322032

20332033
@property
@@ -2053,7 +2053,7 @@ def native_value(self):
20532053
return None
20542054

20552055
else:
2056-
return self._platform.decoded_model["B_Energy_Available"] * 0.001
2056+
return self._platform.decoded_model["B_Energy_Available"]
20572057

20582058

20592059
class SolarEdgeBatterySOH(SolarEdgeSensorBase):

0 commit comments

Comments
 (0)