From 2796d86fca0ae2236a940dc576bc2768822d600c Mon Sep 17 00:00:00 2001 From: Mathieu Date: Mon, 13 Sep 2021 15:24:13 +0200 Subject: [PATCH] Manual override for homeassistant entity (turn on/off) --- .../homeassistant/override/pc_mathieu.json | 11 +++ jarvis/config/homeassistant/override/tv.json | 9 +++ .../homeassistant/homeassistant_client.py | 76 ++++++++++++++++--- 3 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 jarvis/config/homeassistant/override/pc_mathieu.json create mode 100644 jarvis/config/homeassistant/override/tv.json diff --git a/jarvis/config/homeassistant/override/pc_mathieu.json b/jarvis/config/homeassistant/override/pc_mathieu.json new file mode 100644 index 0000000..6dfba2a --- /dev/null +++ b/jarvis/config/homeassistant/override/pc_mathieu.json @@ -0,0 +1,11 @@ +{ + "friendly_names": [ + "pc", + "tour", + "pc mathieu", + "tour mathieu", + "ordinateur", + "ordinateur mathieu" + ], + "entity": "switch.wake_on_lan_pc_tour" +} \ No newline at end of file diff --git a/jarvis/config/homeassistant/override/tv.json b/jarvis/config/homeassistant/override/tv.json new file mode 100644 index 0000000..ef5ac9e --- /dev/null +++ b/jarvis/config/homeassistant/override/tv.json @@ -0,0 +1,9 @@ +{ + "friendly_names": [ + "tv", + "télévision", + "télé", + "téléviseur" + ], + "entity": "switch.tv_philips" +} \ No newline at end of file diff --git a/jarvis/skills/productivity/homeassistant/homeassistant_client.py b/jarvis/skills/productivity/homeassistant/homeassistant_client.py index 65cd10e..93f15bb 100644 --- a/jarvis/skills/productivity/homeassistant/homeassistant_client.py +++ b/jarvis/skills/productivity/homeassistant/homeassistant_client.py @@ -1,9 +1,17 @@ +import glob +import itertools +import json +import os + from fuzzywuzzy import fuzz from homeassistant_api import Client +from homeassistant_api.errors import ParameterMissingError +from jarvis import get_path_file from jarvis.utils import config_utils client = None +overridden_entities = dict() def get_entites_from_type(type: str): @@ -36,17 +44,33 @@ def get_client(): return client -def find_entity(entity, types): +def find_entity(name, types): """Find entity with specified name, fuzzy matching Throws request Exceptions (Subclasses of ConnectionError or RequestException, raises HTTPErrors if non-Ok status code) """ - json_data = client.get_states() + json_data = get_client().get_states() # require a score above 50% best_score = 50 best_entity = None - if json_data: + + # Check if the friendly name is overriden manually (from the config files) + if is_overridden(name): + try: + actionable_entity = get_client().get_entity(entity_id=get_entity_with_overriden_name(name)) + + result = { + "id": actionable_entity.entity_id, + "dev_name": actionable_entity.state['attributes']['friendly_name'], + "state": actionable_entity.state['state'], + "best_score": 101} + return result + except ParameterMissingError: + print("[Error] : Entity with id : " + get_entity_with_overriden_name(name) + " doesn't exists.") + return None + + elif json_data: for state in json_data: try: if state['entity_id'].split(".")[0] in types: @@ -54,7 +78,7 @@ def find_entity(entity, types): # should score on "outside temperature sensor" # and repetitions should not count on my behalf score = fuzz.token_sort_ratio( - entity, + name, state['attributes']['friendly_name'].lower()) if score > best_score: best_score = score @@ -62,23 +86,57 @@ def find_entity(entity, types): "id": state['entity_id'], "dev_name": state['attributes']['friendly_name'], "state": state['state'], - "best_score": best_score} + "best_score": best_score + } + score = fuzz.token_sort_ratio( - entity, + name, state['entity_id'].lower()) if score > best_score: best_score = score best_entity = { "id": state['entity_id'], - "dev_name": state['attributes'] - ['friendly_name'], + "dev_name": state['attributes']['friendly_name'], "state": state['state'], - "best_score": best_score} + "best_score": best_score + } except KeyError: pass return best_entity +def register_overrides(): + global overridden_entities + files = glob.glob(os.path.dirname(get_path_file.__file__) + "/config/homeassistant/override/*.json") + + for file in files: + file_json = json.load(open(file, encoding="utf8")) + friendly_names = file_json['friendly_names'] + entity = file_json['entity'] + + overridden_entities[entity] = friendly_names + + if len(overridden_entities) >= 1: + print("[HomeAssistant] Override for entities : " + str(list(overridden_entities.keys()))) + + +def is_overridden(entity_friendly_name): + values = list(itertools.chain.from_iterable(overridden_entities.values())) + if entity_friendly_name in values: + return True + + return False + + +def get_entity_with_overriden_name(friendly_name): + for key, value in overridden_entities.items(): + if friendly_name in value: + return key + + def init(): # init the client for the first time get_client() + + # register all the overrides entity from the config/homeassistant/override/ folder + register_overrides()