@@ -189,7 +189,8 @@ def _add_to_sums(a_sums_dict: dict, key: str, val_charge_duration, val_charged_e
189189 a_sums_dict [key ]["cost" ] += val_cost
190190
191191class EvccApiBridge :
192- def __init__ (self , host : str , web_session , coordinator : DataUpdateCoordinator = None , lang : str = "en" , opt_password : str = None ) -> None :
192+ def __init__ (self , host : str , web_session , coordinator : DataUpdateCoordinator = None , lang : str = "en" ,
193+ opt_password : str = None , ext_vehicle_data : bool = False , ext_meter_data : bool = False ) -> None :
193194 # make sure we are compliant with old configurations (that does not include the schema in the host variable)
194195 if not host .startswith (("http://" , "https://" )):
195196 host = f"http://{ host } "
@@ -210,6 +211,8 @@ def __init__(self, host: str, web_session, coordinator: DataUpdateCoordinator =
210211 self .host = host
211212 self ._admin_password = opt_password
212213 self ._admin_cookie_expire_datetime = None
214+ self ._request_ext_vehicle_data = ext_vehicle_data
215+ self ._request_ext_meter_data = ext_meter_data
213216
214217 self .web_session = web_session
215218 self .lang_map = None
@@ -430,41 +433,67 @@ async def read_all_data(self, request_all:bool=True,
430433 self ._data = {}
431434 json_resp = self ._data
432435
436+
433437 self ._data_coordinator_update_needed = False
434- current_hour = datetime .now (timezone .utc ).hour
435- current_quarter_hour = datetime .now (timezone .utc ).minute // 15
438+ now_utc = datetime .now (timezone .utc )
439+ current_hour = now_utc .hour
440+ current_minute = now_utc .minute
441+ current_quarter_hour = current_minute // 15
442+
443+
444+ # additional tariffs endpoint data
436445 if request_all or request_tariffs :
437446 if self .request_tariff_endpoints :
438447 # we only update the tariff data once per hour...
439448 if self ._TARIFF_LAST_UPDATE_QUARTER_HOUR != current_quarter_hour :
440449 _LOGGER .debug (f"going to request 'tariff' data from evcc@{ self .host } " )
441- json_resp = await self .read_tariff_data (json_resp )
442- self ._data_coordinator_update_needed = True
450+ json_resp , data_was_fetched = await self .read_tariff_data (json_resp )
451+ if data_was_fetched :
452+ self ._data_coordinator_update_needed = True
443453 self ._TARIFF_LAST_UPDATE_QUARTER_HOUR = current_quarter_hour
444454 else :
445455 # we must copy the previous existing data to the new json_resp!
446456 if self ._data is not None and ADDITIONAL_ENDPOINTS_DATA_TARIFF in self ._data :
447457 json_resp [ADDITIONAL_ENDPOINTS_DATA_TARIFF ] = self ._data [ADDITIONAL_ENDPOINTS_DATA_TARIFF ]
448458
459+ # additional sessions endpoint data
449460 if request_all or request_sessions :
450- # we only update the session's data once per hour...
451- if self ._SESSIONS_LAST_UPDATE_HOUR != current_hour :
461+ # update session data twice per hour:
462+ # window A → minutes 55–59 (5 minutes before the full hour)
463+ # window B → minutes 00–54 (start of the new hour)
464+ if current_minute >= 55 :
465+ _sessions_slot = current_hour * 100 + 55 # e.g. 1455 at 14:55–14:59
466+ else :
467+ _sessions_slot = current_hour * 100 # e.g. 1400 at 14:00–14:54
468+
469+ _sessions_should_fetch = (
470+ self ._SESSIONS_LAST_UPDATE_HOUR == - 1 # first run: fetch immediately
471+ or (self ._SESSIONS_LAST_UPDATE_HOUR != _sessions_slot )
472+ )
473+ if _sessions_should_fetch :
452474 _LOGGER .debug (f"going to request 'sessions' data from evcc@{ self .host } " )
453- json_resp = await self .read_sessions_data (json_resp )
454- self ._data_coordinator_update_needed = True
455- self ._SESSIONS_LAST_UPDATE_HOUR = current_hour
475+ json_resp , data_was_fetched = await self .read_sessions_data (json_resp )
476+ if data_was_fetched :
477+ self ._data_coordinator_update_needed = True
478+ self ._SESSIONS_LAST_UPDATE_HOUR = _sessions_slot
456479 else :
457480 # we must copy the previous existing data to the new json_resp!
458481 if self ._data is not None and ADDITIONAL_ENDPOINTS_DATA_SESSIONS in self ._data :
459482 json_resp [ADDITIONAL_ENDPOINTS_DATA_SESSIONS ] = self ._data [ADDITIONAL_ENDPOINTS_DATA_SESSIONS ]
460483
484+ # additional configuration endpoint data
461485 if request_all or request_config :
462486 now_time = time ()
463487 if self ._CONFIG_LAST_UPDATE + self ._CONFIG_UPDATE_INTERVAL_IN_SECONDS <= time ():
464488 _LOGGER .debug (f"going to request 'configuration' data from evcc@{ self .host } " )
465- json_resp = await self .read_config_data (json_resp , log_requests = log_config_requests )
466- self ._data_coordinator_update_needed = True
489+ json_resp , data_was_fetched = await self .read_config_data (json_resp , log_requests = log_config_requests )
490+ if data_was_fetched :
491+ self ._data_coordinator_update_needed = True
467492 self ._CONFIG_LAST_UPDATE = now_time
493+ else :
494+ # we must copy the previous existing data to the new json_resp!
495+ if self ._data is not None and ADDITIONAL_ENDPOINTS_DATA_EVCCCONF in self ._data :
496+ json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ] = self ._data [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ]
468497
469498 self ._data = json_resp
470499 return json_resp
@@ -482,6 +511,7 @@ async def read_state_data(self) -> dict:
482511
483512 async def read_tariff_data (self , json_resp : dict ) -> dict :
484513 # _LOGGER.info(f"going to request additional tariff data from evcc@{self.host}")
514+ tariff_data_was_fetched = False
485515 if ADDITIONAL_ENDPOINTS_DATA_TARIFF not in json_resp :
486516 json_resp [ADDITIONAL_ENDPOINTS_DATA_TARIFF ] = {}
487517
@@ -492,14 +522,16 @@ async def read_tariff_data(self, json_resp: dict) -> dict:
492522 tariff_resp = await _do_request (method = self .web_session .get (url = req , ssl = False , timeout = static_5sec_timeout ))
493523 if tariff_resp is not None and len (tariff_resp ) > 0 :
494524 json_resp [ADDITIONAL_ENDPOINTS_DATA_TARIFF ][a_key ] = tariff_resp
525+ tariff_data_was_fetched = True
495526
496527 except Exception as err :
497528 _LOGGER .info (f"could not read tariff data for '{ a_key } ' -> '{ err } '" )
498529
499- return json_resp
530+ return json_resp , tariff_data_was_fetched
500531
501532 async def read_sessions_data (self , json_resp : dict ) -> dict :
502533 # _LOGGER.info(f"going to request additional sessions data from evcc@{self.host}")
534+ session_data_was_fetched = False
503535 if ADDITIONAL_ENDPOINTS_DATA_SESSIONS not in json_resp :
504536 json_resp [ADDITIONAL_ENDPOINTS_DATA_SESSIONS ] = {}
505537
@@ -514,13 +546,15 @@ async def read_sessions_data(self, json_resp: dict) -> dict:
514546
515547 # do the math stuff...
516548 calculate_session_sums (sessions_resp , json_resp )
549+ session_data_was_fetched = True
517550
518551 except BaseException as err :
519552 _LOGGER .info (f"could not read sessions data '{ type (err ).__name__ } ' -> { err } " )
520553
521- return json_resp
554+ return json_resp , session_data_was_fetched
522555
523556 async def read_config_data (self , json_resp : dict , log_requests :bool = False ):
557+ config_data_was_fetched = False
524558 if await self .ensure_session_is_authorized ():
525559 if ADDITIONAL_ENDPOINTS_DATA_EVCCCONF not in json_resp :
526560 # creating our core data container object...
@@ -532,6 +566,14 @@ async def read_config_data(self, json_resp: dict, log_requests:bool=False):
532566 a_config = json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ][EVCCCONF_KEY_CONFIG ]
533567
534568 for a_device_type , value_list in a_config .items ():
569+ if a_device_type == EVCCCONF_DEVICE_TYPES .VEHICLE .value and not self ._request_ext_vehicle_data :
570+ _LOGGER .debug (f"skipping vehicle data since 'request_ext_vehicle_data' is set to False" )
571+ continue
572+
573+ if a_device_type == EVCCCONF_DEVICE_TYPES .METER .value and not self ._request_ext_meter_data :
574+ _LOGGER .debug (f"skipping meter data since 'request_ext_meter_data' is set to False" )
575+ continue
576+
535577 for a_device_id in value_list :
536578 if a_device_type not in json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ][EVCCCONF_KEY_DATA ]:
537579 json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ][EVCCCONF_KEY_DATA ][a_device_type ] = {}
@@ -544,12 +586,14 @@ async def read_config_data(self, json_resp: dict, log_requests:bool=False):
544586 # make sure that we always use lower case device-ids
545587 # compare also with the reading code in 'read_tag_configuration'
546588 json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ][EVCCCONF_KEY_DATA ][a_device_type ][a_device_id .lower ()] = a_status_resp
589+ if not config_data_was_fetched :
590+ config_data_was_fetched = True
547591 if log_requests :
548592 _LOGGER .debug (f"Response received for { req } : { a_status_resp } " )
549593
550594 _LOGGER .debug (f"read_config_data(): configuration data read { list (json_resp [ADDITIONAL_ENDPOINTS_DATA_EVCCCONF ][EVCCCONF_KEY_DATA ].keys ())} " )
551595
552- return json_resp
596+ return json_resp , config_data_was_fetched
553597
554598 async def _read_config_setup (self , log_requests :bool = False ):
555599 the_configuration = {}
0 commit comments