@@ -275,9 +275,9 @@ async def readFollowUpBattery(
275275 readFollowUpBattery ,
276276 )
277277
278+ hub .computedSensors = computedRegs
278279 async_add_entities (entities )
279280 # now the groups are available
280- hub .computedSensors = computedRegs
281281 hub .rebuild_blocks (initial_groups ) # , computedRegs) # first time call
282282 _LOGGER .info (f"{ hub .name } : computedRegs: { hub .computedSensors } " )
283283
@@ -416,17 +416,6 @@ async def readFollowUpBattery(
416416 readFollowUp ,
417417 )
418418
419- # Ensure existing Energy Dashboard entities are enabled before adding them.
420- entity_registry = er .async_get (hass )
421- for sensor_description in energy_dashboard_sensors :
422- unique_id = f"{ energy_dashboard_platform_name } _{ sensor_description .key } "
423- entity_id = entity_registry .async_get_entity_id ("sensor" , DOMAIN , unique_id )
424- if entity_id :
425- maybe_entry = entity_registry .async_get (entity_id )
426- if maybe_entry is not None and maybe_entry .disabled_by :
427- _LOGGER .debug (f"{ hub_name } : Enabling previously disabled Energy Dashboard entity: { entity_id } " )
428- entity_registry .async_update_entity (entity_id , disabled_by = None )
429-
430419 # Add Energy Dashboard entities to main entities list and register them
431420 if energy_dashboard_entities :
432421 _LOGGER .info (f"{ hub_name } : Registering { len (energy_dashboard_entities )} Energy Dashboard entities" )
@@ -465,6 +454,7 @@ async def async_refresh_energy_dashboard_entities() -> None:
465454 for newdescr in energy_dashboard_sensors :
466455 existing_sensor = hub .sensorEntities .get (newdescr .key )
467456 if existing_sensor and getattr (existing_sensor , "hass" , None ) is not None :
457+ hub .sensorDescriptions [newdescr .key ] = newdescr
468458 existing_sensor .entity_description = newdescr
469459 if hasattr (existing_sensor , "_riemann_mapping" ) and getattr (newdescr , "_riemann_mapping" , None ):
470460 existing_sensor ._riemann_mapping = newdescr ._riemann_mapping
@@ -476,6 +466,7 @@ async def async_refresh_energy_dashboard_entities() -> None:
476466 continue
477467 if existing_sensor :
478468 hub .sensorEntities .pop (newdescr .key , None )
469+ hub .sensorDescriptions .pop (newdescr .key , None )
479470 hub .computedSensors .pop (newdescr .key , None )
480471
481472 entityToListSingle (
@@ -511,7 +502,8 @@ async def async_refresh_energy_dashboard_entities() -> None:
511502
512503 if allow_remove_pv or allow_remove_home or allow_remove_grid :
513504 entity_registry = er .async_get (hass )
514- for key in list (hub .sensorEntities .keys ()):
505+ existing_keys = set (hub .sensorEntities .keys ()) | set (hub .sensorDescriptions .keys ())
506+ for key in list (existing_keys ):
515507 if key in desired_keys :
516508 continue
517509 is_pv_variant = "_pv_power_" in key or "_pv_energy_" in key
@@ -523,17 +515,20 @@ async def async_refresh_energy_dashboard_entities() -> None:
523515 if entity_id :
524516 entity_registry .async_remove (entity_id )
525517 hub .sensorEntities .pop (key , None )
518+ hub .sensorDescriptions .pop (key , None )
526519 hub .computedSensors .pop (key , None )
527520
528521 # Recompute ED values immediately to relink unavailable entities.
529522 for newdescr in energy_dashboard_sensors :
530523 if newdescr .register < 0 and newdescr .value_function :
524+ sens = hub .sensorEntities .get (newdescr .key )
525+ if sens is None and not getattr (newdescr , "internal" , False ):
526+ continue
531527 try :
532528 hub .data [newdescr .key ] = newdescr .value_function (0 , newdescr , hub .data )
533529 except Exception as e :
534530 _LOGGER .debug (f"{ hub_name } : ED refresh value_function failed for { newdescr .key } : { e } " )
535531 continue
536- sens = hub .sensorEntities .get (newdescr .key )
537532 if sens and not getattr (newdescr , "internal" , False ):
538533 sens .modbus_data_updated ()
539534
@@ -567,8 +562,18 @@ def __init__(
567562 self .entity_description : BaseModbusSensorEntityDescription = description
568563 self ._attr_extra_state_attributes = _energy_dashboard_mapping_attrs (self .entity_description , self ._hub )
569564
565+ def _register_hub_sensor_entity (self ) -> None :
566+ # Only called from async_added_to_hass so disabled entities never enter sensorEntities.
567+ self ._hub .sensorEntities [self .entity_description .key ] = self
568+ self ._hub .sensorDescriptions [self .entity_description .key ] = self .entity_description
569+
570+ def _unregister_hub_sensor_entity (self ) -> None :
571+ if self ._hub .sensorEntities .get (self .entity_description .key ) is self :
572+ self ._hub .sensorEntities .pop (self .entity_description .key , None )
573+
570574 async def async_added_to_hass (self ) -> None :
571575 """Register callbacks."""
576+ self ._register_hub_sensor_entity ()
572577 # Skip hub registration for computed/internal sensors (those without modbus registers)
573578 # These sensors don't participate in the polling cycle
574579 if self .entity_description .register < 0 :
@@ -587,7 +592,11 @@ async def async_added_to_hass(self) -> None:
587592 await self ._hub .async_add_solax_modbus_sensor (self )
588593
589594 async def async_will_remove_from_hass (self ) -> None :
590- await self ._hub .async_remove_solax_modbus_sensor (self )
595+ if self .entity_description .register >= 0 or getattr (self .entity_description , "_is_riemann_sum_sensor" , False ):
596+ await self ._hub .async_remove_solax_modbus_sensor (self )
597+ if self .entity_description .register < 0 and not getattr (self .entity_description , "_is_riemann_sum_sensor" , False ):
598+ self ._hub .computedSensors .pop (self .entity_description .key , None )
599+ self ._unregister_hub_sensor_entity ()
591600
592601 @callback
593602 def modbus_data_updated (self ) -> None :
@@ -707,6 +716,7 @@ async def async_added_to_hass(self) -> None:
707716 self .async_write_ha_state ()
708717
709718 # Register with hub
719+ self ._register_hub_sensor_entity ()
710720 await self ._hub .async_add_solax_modbus_sensor (self )
711721
712722 @callback
@@ -882,7 +892,7 @@ def entityToListSingle(
882892 newdescr ,
883893 )
884894
885- hub .sensorEntities [newdescr .key ] = sensor
895+ hub .sensorDescriptions [newdescr .key ] = newdescr
886896 # register dependency chain
887897 deplist = newdescr .depends_on
888898 if deplist is not None :
@@ -898,13 +908,10 @@ def entityToListSingle(
898908 if newdescr .sleepmode == SLEEPMODE_ZERO :
899909 hub .sleepzero .append (newdescr .key )
900910 if newdescr .register < 0 : # entity without modbus address
901- enabled = is_entity_enabled (hub ._hass , hub , newdescr , use_default = True , platform_name = hub_name ) # dont compute disabled entities anymore
902- # if not enabled: _LOGGER.info(f"is_entity_enabled called for disabled entity {newdescr.key}")
903- if newdescr .value_function and (enabled or newdescr .internal ): # *** dont compute disabled entities anymore unless internal
911+ if newdescr .value_function and newdescr .internal :
904912 computedRegs [newdescr .key ] = newdescr
905- else :
906- if enabled :
907- _LOGGER .warning (f"{ hub_name } : entity without modbus register address and without value_function found: { newdescr .key } " )
913+ elif not newdescr .value_function and is_entity_enabled (hub ._hass , hub , newdescr , use_default = True , platform_name = hub_name ):
914+ _LOGGER .warning (f"{ hub_name } : entity without modbus register address and without value_function found: { newdescr .key } " )
908915 else :
909916 # target group
910917 interval_group = groups .setdefault (hub .scan_group (sensor ), empty_input_interval_group_lambda ())
0 commit comments