This repository has been archived on 2023-06-09. You can view files and clone it, but cannot push or open issues or pull requests.
jarvis-server/jarvis/skills/productivity/homeassistant/homeassistant_client.py

171 lines
5.1 KiB
Python
Raw Normal View History

import glob
import itertools
import json
import os
2021-09-12 21:50:30 +02:00
from fuzzywuzzy import fuzz
from homeassistant_api import Client
from homeassistant_api.errors import ParameterMissingError
2021-09-12 21:50:30 +02:00
from jarvis import get_path_file
2021-09-12 21:50:30 +02:00
from jarvis.utils import config_utils
client = None
overridden_entities = dict()
2021-09-12 21:50:30 +02:00
def get_entites_from_type(type: str):
return get_client().get_entities().__getattr__(type).entities
def find_switchable_entity(entity):
ha_entity = find_entity(
entity,
[
'group',
'light',
'fan',
'switch',
'scene',
'input_boolean',
'climate'
]
)
if ha_entity is None:
print("Can't find entity for name : " + entity)
2021-09-12 21:50:30 +02:00
return ha_entity
def get_client():
global client
if client is None:
client = Client(config_utils.get_in_secret('HOMEASSISTANT_API_URL') + "/api/",
config_utils.get_in_secret('HOMEASSISTANT_API_TOKEN'))
return client
def find_entity(name, types):
2021-09-12 21:50:30 +02:00
"""Find entity with specified name, fuzzy matching
Throws request Exceptions
(Subclasses of ConnectionError or RequestException,
raises HTTPErrors if non-Ok status code)
"""
json_data = get_client().get_states()
2021-09-12 21:50:30 +02:00
# require a score above 50%
best_score = 50
best_entity = None
# 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_overridden_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_overridden_name(name) + " doesn't exists.")
return None
elif json_data:
2021-09-12 21:50:30 +02:00
for state in json_data:
try:
if state['entity_id'].split(".")[0] in types:
# something like temperature outside
# should score on "outside temperature sensor"
# and repetitions should not count on my behalf
score = fuzz.token_sort_ratio(
name,
2021-09-12 21:50:30 +02:00
state['attributes']['friendly_name'].lower())
if score > best_score:
best_score = score
best_entity = {
"id": state['entity_id'],
"dev_name": state['attributes']['friendly_name'],
"state": state['state'],
"best_score": best_score
}
2021-09-12 21:50:30 +02:00
score = fuzz.token_sort_ratio(
name,
2021-09-12 21:50:30 +02:00
state['entity_id'].lower())
if score > best_score:
best_score = score
best_entity = {
"id": state['entity_id'],
"dev_name": state['attributes']['friendly_name'],
2021-09-12 21:50:30 +02:00
"state": state['state'],
"best_score": best_score
}
2021-09-12 21:50:30 +02:00
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("[HomeAssistantSkill] 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_overridden_name(friendly_name):
scores = dict()
for key, value in overridden_entities.items():
for val in value:
score = fuzz.token_sort_ratio(friendly_name, val)
if score > 50:
scores[score] = key
if len(scores) >= 1:
return sorted(scores.items(), reverse=True)[0][1]
return None
def turn_on_entity(entity_id):
get_client().trigger_service("homeassistant", "turn_on", **{'entity_id': entity_id})
def turn_off_entity(entity_id):
get_client().trigger_service("homeassistant", "turn_off", **{'entity_id': entity_id})
def restart_ha():
get_client().trigger_service("homeassistant", "restart")
def shutdown_ha():
get_client().trigger_service("homeassistant", "stop")
2021-09-12 21:50:30 +02:00
def init():
# init the client for the first time
get_client()
# register all the overrides entity from the config/homeassistant/override/ folder
if not overridden_entities:
register_overrides()