Skip to content

Commit

Permalink
Merge pull request #316 from WillCodeForCats/coordinator-timeout
Browse files Browse the repository at this point in the history
Coordinator timeout based on number of devices
  • Loading branch information
WillCodeForCats authored Jul 16, 2023
2 parents 900aa5c + e19a563 commit 5c4a172
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 13 deletions.
16 changes: 8 additions & 8 deletions custom_components/solaredge_modbus_multi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,12 @@ def __init__(

async def _async_update_data(self):
try:
async with async_timeout.timeout(self._hub.coordinator_timeout):
return await self._refresh_modbus_data_with_retry(
ex_type=DataUpdateFailed,
limit=RetrySettings.Limit,
wait_ms=RetrySettings.Time,
wait_ratio=RetrySettings.Ratio,
)
return await self._refresh_modbus_data_with_retry(
ex_type=DataUpdateFailed,
limit=RetrySettings.Limit,
wait_ms=RetrySettings.Time,
wait_ratio=RetrySettings.Ratio,
)

except HubInitFailed as e:
raise UpdateFailed(f"{e}")
Expand Down Expand Up @@ -220,7 +219,8 @@ async def _refresh_modbus_data_with_retry(
attempt = 1
while True:
try:
return await self._hub.async_refresh_modbus_data()
async with async_timeout.timeout(self._hub.coordinator_timeout):
return await self._hub.async_refresh_modbus_data()
except Exception as ex:
if not isinstance(ex, ex_type):
raise ex
Expand Down
10 changes: 9 additions & 1 deletion custom_components/solaredge_modbus_multi/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,19 @@ class StrEnum(str, Enum):
)


class SolarEdgeTimeouts(IntEnum):
"""Timeouts in milliseconds."""

Inverter = 8400
Device = 1200
Init = 1200


class RetrySettings(IntEnum):
"""Retry settings when opening a connection to the inverter fails."""

Time = 800 # first attempt in milliseconds
Ratio = 2 # time multiplier between each attempt
Ratio = 3 # time multiplier between each attempt
Limit = 4 # number of attempts before failing


Expand Down
41 changes: 37 additions & 4 deletions custom_components/solaredge_modbus_multi/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
except ImportError:
raise ImportError("pymodbus is not installed, or pymodbus version is not supported")

from .const import DOMAIN, SunSpecNotImpl
from .const import DOMAIN, SolarEdgeTimeouts, SunSpecNotImpl
from .helpers import float_to_hex, parse_modbus_string

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -125,7 +125,6 @@ def __init__(
self._allow_battery_energy_reset = allow_battery_energy_reset
self._battery_rating_adjust = battery_rating_adjust
self._battery_energy_reset_cycles = battery_energy_reset_cycles
self._coordinator_timeout = 30
self._id = name.lower()
self._lock = asyncio.Lock()
self.inverters = []
Expand Down Expand Up @@ -497,10 +496,44 @@ def battery_rating_adjust(self) -> int:
def battery_energy_reset_cycles(self) -> int:
return self._battery_energy_reset_cycles

@property
def number_of_meters(self) -> int:
return len(self.meters)

@property
def number_of_batteries(self) -> int:
return len(self.batteries)

@property
def number_of_inverters(self) -> int:
return self._number_of_inverters

@keep_modbus_open.setter
def keep_modbus_open(self, value: bool) -> None:
if value is True:
self._keep_modbus_open = True
else:
self._keep_modbus_open = False

_LOGGER.debug(f"keep_modbus_open={self._keep_modbus_open}")

@property
def coordinator_timeout(self) -> int:
_LOGGER.debug(f"coordinator timeout is {self._coordinator_timeout}")
return self._coordinator_timeout
if not self.initalized:
this_timeout = SolarEdgeTimeouts.Inverter * self.number_of_inverters
this_timeout += SolarEdgeTimeouts.Init * self.number_of_inverters
this_timeout += (SolarEdgeTimeouts.Device * 2) * 3 # max 3 per inverter
this_timeout += (SolarEdgeTimeouts.Device * 2) * 2 # max 2 per inverter

else:
this_timeout = SolarEdgeTimeouts.Inverter * self.number_of_inverters
this_timeout += SolarEdgeTimeouts.Device * self.number_of_meters
this_timeout += SolarEdgeTimeouts.Device * self.number_of_batteries

this_timeout = this_timeout / 1000

_LOGGER.debug(f"coordinator timeout is {this_timeout}")
return this_timeout

@property
def is_connected(self) -> bool:
Expand Down

0 comments on commit 5c4a172

Please sign in to comment.