diff --git a/custom_components/variable/recorder_history_prefilter/recorder_prefilter.py b/custom_components/variable/recorder_history_prefilter/recorder_prefilter.py index cc8895d..6cd4489 100644 --- a/custom_components/variable/recorder_history_prefilter/recorder_prefilter.py +++ b/custom_components/variable/recorder_history_prefilter/recorder_prefilter.py @@ -1,83 +1,93 @@ -#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # # HA RECORDER - EXCLUDE entities FROM BEING ADDED TO HISTORY DATABASE # # -# The HA Recorder module was modified in HA 2023.6.0 to no longer allow a custom -# component to insert entity entity names in the '_exclude_e' list that defined -# entity entities to not be added to the History database (home_assistant_v2.db). +# The HA Recorder module was modified in HA 2023.6.0 to no longer allow a +# custom component to insert entity entity names in the '_exclude_e' list +# that defined entity entities to not be added to the History database +# (home_assistant_v2.db). # -# This module fixes that problem by using a code injection process to provide a -# local prefilter to determine if an entity should be added before the Recorder filter. +# This module fixes that problem by using a code injection process to +# provide a local prefilter to determine if an entity should be added before +# the Recorder filter. # # # This injection has two methods: -# add_filter - Add entities to the filter list -# ---------- -# hass - HomeAssistant -# entities to be filtered - -# single entity - entity_id (string) -# multiple entities - list of entity ids +# add_filter - Add entities to the filter list +# ---------- +# hass - HomeAssistant +# entities to be filtered - +# single entity - entity_id (string) +# multiple entities - list of entity ids # -# 'sensor.' will be added to the beginning of the entity id if -# it's type is not specifid +# 'sensor.' will be added to the beginning of the entity id +# if its type is not specified # -# recorder_prefilter.add_filter(hass, 'filter_id1') -# recorder_prefilter.add_filter(hass, ['filter_entity2', 'filter_entity3']) +# recorder_prefilter.add_filter(hass, 'filter_id1') +# recorder_prefilter.add_filter(hass, ['filter_entity2', 'filter_entity3']) # # -# remove_filter - Remove entities from the filter list -# ------------- -# Same arguments for add_filter +# ------------- +# remove_filter - Remove entities from the filter list +# ------------- +# Same arguments for add_filter # -# recorder_prefilter.remove_filter(hass, 'filter_id1') -# recorder_prefilter.remove_filter(hass, ['filter_entity2', 'filter_entity3']) +# recorder_prefilter.remove_filter(hass, 'filter_id1') +# recorder_prefilter.remove_filter(hass, +# ['filter_entity2', 'filter_entity3']) # # -# Gary Cobb, iCloud3 iDevice Tracker, aka geekstergary -#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +# Gary Cobb, @gcobb321, geekstergary, iCloud3 developer +# iCloud3 iDevice Tracker custom component - An advanced iDevice tracker +# that uses Apple iCloud account and HA Companion App data for presence +# detection and location based automations. +# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -from homeassistant.core import HomeAssistant from inspect import getframeinfo, stack import logging + +from homeassistant.core import HomeAssistant + _LOGGER = logging.getLogger(__name__) VERSION = 1.0 + def add_filter(hass: HomeAssistant, entities=None): - ''' + """ Inject the entity prefilter into the Recorder, remove Recorder listeners, reinitialize the Recorder Arguments: - hass - HomeAssistant - entities - A list of entity entities - (['gary_last_update', 'lillian_last_update', '*_next_update']) - - A single entity entity ('gary_last_zone') + hass - HomeAssistant + entities - A list of entity entities + (['gary_last_update', 'lillian_last_update', '*_next_update']) + - A single entity entity ('gary_last_zone') Returns: True - The injection was successful False - The injection was not successful - ''' + """ - ha_recorder = hass.data['recorder_instance'] + ha_recorder = hass.data["recorder_instance"] if ha_recorder is None: return False - if hass.data.get('recorder_prefilter') is None: - rp_data = hass.data['recorder_prefilter'] = {} - rp_data['injected'] = True - rp_data['legacy'] = True - rp_data['exclude_entities'] = [] + if hass.data.get("recorder_prefilter") is None: + rp_data = hass.data["recorder_prefilter"] = {} + rp_data["injected"] = True + rp_data["legacy"] = True + rp_data["exclude_entities"] = [] try: ha_recorder.entity_filter._exclude_e.add(entities) return True - except: + except Exception: # nosec B110 pass - rp_data['legacy'] = False + rp_data["legacy"] = False if _inject_filter(hass) is False: return @@ -86,9 +96,9 @@ def add_filter(hass: HomeAssistant, entities=None): def remove_filter(hass: HomeAssistant, entities): - if hass.data['recorder_prefilter']['legacy']: + if hass.data["recorder_prefilter"]["legacy"]: try: - ha_recorder = hass.data['recorder_instance'] + ha_recorder = hass.data["recorder_instance"] ha_recorder.entity_filter._exclude_e.discard(entities) return True except Exception as err: @@ -98,9 +108,8 @@ def remove_filter(hass: HomeAssistant, entities): def _inject_filter(hass: HomeAssistant): - ha_recorder = hass.data['recorder_instance'] - rp_data = hass.data['recorder_prefilter'] - recorder_entity_filter = ha_recorder.entity_filter + ha_recorder = hass.data["recorder_instance"] + recorder_entity_filter = ha_recorder.entity_filter recorder_remove_listener = ha_recorder._event_listener def entity_filter(entity_id): @@ -116,8 +125,10 @@ def entity_filter(entity_id): Run the original HA recorder_entity_filter function - The entity is not in the filter list. """ - if (entity_id - and entity_id in hass.data['recorder_prefilter']['exclude_entities']): + if ( + entity_id + and entity_id in hass.data["recorder_prefilter"]["exclude_entities"] + ): return False return recorder_entity_filter(entity_id) @@ -133,7 +144,7 @@ def entity_filter(entity_id): _LOGGER.debug("Reinitializing Recorder Event Listener") hass.add_job(ha_recorder.async_initialize) - _LOGGER.info(f"Recorder Prefilter Injection Completed") + _LOGGER.info("Recorder Prefilter Injection Completed") return True @@ -145,26 +156,30 @@ def entity_filter(entity_id): def _update_filter(hass: HomeAssistant, entities=None, remove=False): - """ Update the filtered entity list """ + """Update the filtered entity list""" - mode = 'Removed' if remove else 'Added' + mode = "Removed" if remove else "Added" cust_component = _called_from() entities_cnt = 1 if type(entities) is str else len(entities) _LOGGER.debug(f"{mode} Prefilter Entities ({cust_component})-{entities}") - _LOGGER.info(f"{mode} Recorder Prefilter Entities " - f"({cust_component})-{entities_cnt}") - - entities = [entities] if type(entities) is str else \ - entities if type(entities) is list else \ - [] + _LOGGER.info( + f"{mode} Recorder Prefilter Entities ({cust_component})-{entities_cnt}" + ) + entities = ( + [entities] + if type(entities) is str + else entities + if type(entities) is list + else [] + ) - rp_data = hass.data.get('recorder_prefilter') - rp_exclude_entities = rp_data['exclude_entities'] + rp_data = hass.data.get("recorder_prefilter") + rp_exclude_entities = rp_data["exclude_entities"] for entity in entities: - if entity.find('.') == -1: + if entity.find(".") == -1: entity = f"sensor.{entity}" if entity not in rp_exclude_entities: if remove is False: @@ -173,10 +188,12 @@ def _update_filter(hass: HomeAssistant, entities=None, remove=False): rp_exclude_entities.remove(entity) _LOGGER.debug(f"All Prefiltered Entities-{sorted(rp_exclude_entities)}") - _LOGGER.info(f"Recorder Prefilter Entities Updated, " - f"Entities Filtered-{len(rp_exclude_entities)}") + _LOGGER.info( + f"Recorder Prefilter Entities Updated, " + f"Entities Filtered-{len(rp_exclude_entities)}" + ) def _called_from(): cust_component = getframeinfo(stack()[0][0]).filename - return cust_component.split('custom_components/')[1].split('/')[0] + return cust_component.split("custom_components/")[1].split("/")[0]