3939from homeassistant .helpers .event import async_track_time_interval
4040from homeassistant .exceptions import HomeAssistantError
4141from homeassistant .helpers .device_registry import DeviceInfo
42+ from homeassistant .helpers import entity_registry as er
4243
43- RETRIES = 0 # was 6
44+ RETRIES = 1 # was 6 then 0, which worked also, but 1 is probably the safe choice
4445INVALID_START = 99999
4546
4647
@@ -260,16 +261,29 @@ def Gen4Timestring(numb):
260261 m = numb >> 8
261262 return f"{ h :02d} :{ m :02d} "
262263
263- def is_entity_enabled (hass , hubname , key ): # Check if the entity is enabled in Home Assistant
264- """
265- for platform in ("sensor", "number", "select", "switch",):
266- state = hass.states.get(f"{platform}.{hubname}_{key}")
267- if state is not None:
268- return True
269- _LOGGER.debug(f"Entity sensor.{hubname}_{key} not found in state manager, assuming disabled - skipping unless declared internal")
270- return False
271- """
272- return True # temporary solution for issue #1490
264+
265+ def is_entity_enabled (hass , hubname , descriptor ): # Check if the entity is enabled in Home Assistant
266+ unique_id = f"{ hubname } _{ descriptor .key } "
267+ platform = "sensor"
268+ #Check if an entity is enabled in the entity registry
269+ registry = er .async_get (hass )
270+ entity_id = registry .async_get_entity_id (platform , DOMAIN , unique_id )
271+ entity_entry = registry .async_get (entity_id )
272+
273+ # If an entity is not in the registry, it is probably a new one.
274+ # return True #Apply the default specified in the descriptor
275+ if entity_entry is None :
276+ _LOGGER .debug (f"Entity { unique_id } not found in entity registry, "
277+ f"applying default { descriptor .entity_registry_enabled_default } "
278+ )
279+ return descriptor .entity_registry_enabled_default
280+
281+ # Otherwise, return the inverse of the 'disabled' attribute
282+ if entity_entry .disabled :
283+ _LOGGER .debug (f"Entity { entity_id } is disabled, not adding to read block." )
284+ return False
285+ return True
286+
273287
274288@dataclass
275289class block ():
@@ -489,9 +503,11 @@ def device_group_key(self, device_info: DeviceInfo):
489503
490504 return key
491505
506+ # following function is the added_to_hass callback for sensors, numbers and selects
492507 @callback
493508 async def async_add_solax_modbus_sensor (self , sensor : SolaXModbusSensor ):
494509 """Listen for data updates."""
510+ # attention, this function is not only called for sensors also for number, select
495511 # This is the first sensor, set up interval.
496512 interval = self .scan_group (sensor )
497513 interval_group = self .groups .setdefault (interval , empty_hub_interval_group_lambda ())
@@ -508,10 +524,11 @@ async def _refresh(_now: Optional[int] = None) -> None:
508524
509525 device_key = self .device_group_key (sensor .device_info )
510526 grp = interval_group .device_groups .setdefault (device_key , empty_hub_device_group_lambda ())
511- _LOGGER .debug (f"adding sensor { sensor .entity_description .key } " )
527+ _LOGGER .debug (f"adding sensor { sensor .entity_description .key } available: { sensor . _attr_available } " )
512528 grp .sensors .append (sensor )
513529 self .blocks_changed = True # will force rebuild_blocks to be called
514530
531+
515532 @callback
516533 async def async_remove_solax_modbus_sensor (self , sensor ):
517534 """Remove data update."""
@@ -552,7 +569,7 @@ async def async_refresh_modbus_data(self, interval_group, _now: Optional[int] =
552569 if self .blocks_changed :
553570 self .rebuild_blocks (self .initial_groups )
554571 if (self .cyclecount % self .slowdown ) == 0 : # only execute once every slowdown count
555- for group in interval_group .device_groups .values ():
572+ for group in list ( interval_group .device_groups .values ()): # not sure if this does not break things or affects performance
556573 update_result = await self .async_read_modbus_data (group )
557574 if update_result :
558575 if self .slowdown > 1 : _LOGGER .info (f"communication restored, resuming normal speed after slowdown" )
@@ -842,6 +859,7 @@ def treat_address(self, data, decoder, descr, initval=0):
842859 """
843860
844861 if val == None : # E.g. if errors have occurred during readout
862+ #_LOGGER.warning(f"****tmp*** treating {descr.key} failed")
845863 return_value = None
846864 elif type (descr .scale ) is dict : # translate int to string
847865 return_value = descr .scale .get (val , "Unknown" )
@@ -881,6 +899,7 @@ def treat_address(self, data, decoder, descr, initval=0):
881899 # if (descr.sleepmode != SLEEPMODE_LASTAWAKE) or self.awakeplugin(self.data): self.data[descr.key] = return_value
882900 if ((self .tmpdata_expiry .get (descr .key , 0 ) == 0 )
883901 and ( (descr .sleepmode != SLEEPMODE_LASTAWAKE ) or self .plugin .isAwake (self .data ) )):
902+ #_LOGGER.info(f"****tmp*** returning data for {descr.key}: {return_value}")
884903 data [descr .key ] = return_value # case prevent_update number
885904
886905 async def async_read_modbus_block (self , data , block , typ ):
@@ -956,8 +975,8 @@ async def async_read_modbus_block(self, data, block, typ):
956975 for reg in block .regs :
957976 descr = block .descriptions [reg ]
958977 if type (descr ) is dict : l = descr .items () # special case: mutliple U8x entities
959- else : l = { descr .key : descr , } # normal case, one entity
960- for k , d in l . items () :
978+ else : l = { descr .key : descr , }. items () # normal case, one entity
979+ for k , d in l :
961980 d_ignore = descr .ignore_readerror
962981 d_key = descr .key
963982 if (d_ignore is not True ) and (d_ignore is not False ):
@@ -1074,15 +1093,15 @@ def splitInBlocks( self, descriptions):
10741093 d_newblock = False
10751094 d_enabled = False
10761095 for sub , d in descr .items ():
1077- d_enabled = d_enabled or d .internal or is_entity_enabled (self ._hass , self ._name , d . key )
1096+ d_enabled = d_enabled or d .internal or is_entity_enabled (self ._hass , self ._name , d )
10781097 d_newblock = d_newblock or d .newblock
10791098 d_unit = d .unit
10801099 d_wordcount = 1 # not used here
10811100 d_key = d .key # does not matter which key we use here
10821101 d_regtype = d .register_type
10831102 else : # normal entity
10841103 entity_id = f"sensor.{ self ._name } _{ descr .key } "
1085- d_enabled = descr .internal or is_entity_enabled (self ._hass , self ._name , descr . key )
1104+ d_enabled = descr .internal or is_entity_enabled (self ._hass , self ._name , descr )
10861105 d_newblock = descr .newblock
10871106 d_unit = descr .unit
10881107 d_wordcount = descr .wordcount
0 commit comments