Własna integracja - 4. Konfiguracja integracji
W tej części opiszę jak dodać możliwość konfiguracji integracji.
Konfigurację dodamy do interfejsu w aplikacji bo jest obowiązkowa w przypadku wszystkich nowych integracji dodawanych do Home Assistant / Asystenta domowego (kiedyś można było skonfigurować w plikach YAML ale ten sposób jest już na szczęście przestarzały).
Definicja konfiguracja z aplikacji nazywa się “Config flow”, nazwa wzięła się pewnie stąd, że możemy tylko w jedną stronę przechodzić konfigurator - trzeba płynąć z prądem konfiguratora danych
Będzie to jaśniejsze jak zdefiniujemy taki konfigurator, dlatego przechodzimy od razu do rzeczy.
Informacja o konfiguracji w pliku manifest.json
Żeby włączyć konfigurator w aplikacji należy ustawić w pliku manifestu z integracją (ten który dodaliśmy w części 1.) atrybut:
“config_flow”: true
Czyli nasz plik manifest.json ma wyglądać tak:
Definicja kroków konfiguracji w pliku config_flow.py
Konfiguracja używa określoną strukturę możliwych kroków podczas przechodzenia pomiędzy ekranami - podczas przepływu danych konfiguracyjnych.
Kroki te definiujemy w nowym pliku config_flow.py
który dodajemy do folderu integracji.
Minimalna zawartość tego pliku to definicja klasa która będzie dziedziczyła właśniwości klasy config_entries.ConfigFlow
, czyli coś takiego:
from homeassistant import config_entries
class AisHelloConfigFlow(config_entries.ConfigFlow, domain="ais_hello"):
"""Example config flow."""
Teraz po wykonaniu na bramce pobrania kodów z naszego repozytorium git:
git pull
i ponownym uruchomieniu Asystenta domowego:
pm2 restart ais
Możemy przejść do konfiguracji i wyszukać integrację ais
, w efekcie zobaczymy naszą nową integrację dostępną z konfiguratora - coś takiego:
Konfigurator integracji - kontynuacja
Definiowanie kroków konfiguratora integracji
Kroków przepływu konfiguracji integracji może być dowolna ilość.
Załóżmy, że w naszym przypadku po tym jak użytkownik rozpocznie konfiguracje, to poinformujemy go o tym do czego służy integracja i czy chce kontynuować a w kolejnym kroku poprosimy o dane logowania, po wypełnieniu formatki z logowaniem utworzymy integrację. Czyli w pliku config_flow.py
trzeba zdefiniować takie kroki:
- async_step_user - uruchomienie konfiguracji przez użytkownika, tu przekierowujemy na formatkę z informacją o integracji i pytaniem czy kontynuować
- async_step_confirm - potwierdzenie przez użytkownika i przekierowanie na formatkę z danymi logowania (do serwisu z którym się integrujemy)
- async_step_login - logowanie do serwisu i dodanie integracji
czyli nasz plik config_flow.py
bedzie wyglądał tak:
from homeassistant import config_entries
import voluptuous as vol
class AisHelloConfigFlow(config_entries.ConfigFlow, domain="ais_hello"):
"""Przykład przepływu konfiguracji w integracji."""
async def async_step_user(self, user_input=None):
"""1. Uruchomienie konfiguracji przez użytkownika"""
# przejście do kroku potwierdzenia dodania integracji
return self.async_show_form(step_id="confirm")
async def async_step_confirm(self, user_input=None):
"""2. Obsługa kroku potwierdzenia przez użytkownika."""
if user_input is not None:
# Przejście do kroku logowanie
return self.async_show_form(step_id="login", data_schema=vol.Schema(
{vol.Required("username"): str, vol.Required("password"): str}
))
return self.async_show_form(step_id="confirm")
async def async_step_login(self, user_input=None):
"""3. Krok logowania"""
if user_input is not None:
# TODO logowanie do serwisu
# Zakończenie i zapis konfiguracji
return self.async_create_entry(title="Przykładowa integracja AIS", data=user_input)
return self.async_show_form(step_id="confirm")
Teksty na ekranach konfiguratora integracji i ich tłumaczenia
Nazwy kroków integracji oraz ich opisy są definiowane w pliku strings.json
Dodajmy taki plik do naszej integracji, jego zawartość to:
{ "title": "AIS Hello",
"config": {
"step": {
"confirm": {
"title": "AIS Hello",
"description": "###### ![logo](https://ai-speaker.com/images/brands/ais_hello/icon.png)\n\nDo you want to set up new AIS hello integration?"
},
"login": {
"title": "AIS Hello - login",
"description": "To get data from xxx you need to login, [Details in the documentation ](https://www.ai-speaker.com)\n\n Fill in the form below and click **SUBMIT** button.",
"data": {
"username": "Username",
"password": "Password"
}
}
}
}
}
Następnie dodajmy folder o nazwie translations
w którym możemy umieścić tłumaczenia tych tekstów na inne języki. Oczywiście dodajemy język polski:
Na tym etapie mamy już gotowy konfigurator. Po jego przejściu przez użytkownika powstanie wpis konfiguracyjny przechowywany przez Asystenta domowego trwale w pliku.
Konfigurowanie integracji na podstawie wpisu konfiguracyjnego
Po przejściu konfiguratora i dodania wpisu konfiguracyjnego Asystent domowy wywoła specjalną metodę async_setup_entry
i przekaże jej dane konfiguracyjne otrzymane od użytkownika.
Ta sama metoda async_setup_entry
będzie wykonywana podczas uruchamiania Asystenta domowego dla każdego wpisu konfiruracyjnego.
Dodajmy obsługę tej metody w naszym pliku async_setup_entry
"""Przykład integracji sensora licznik."""
DOMAIN = "ais_hello"
async def async_setup(hass, config):
"""Wstepna konfiguracja domeny, jeśli to konieczne."""
return True
async def async_setup_entry(hass, config_entry):
"""Konfigurowanie integracji na podstawie wpisu konfiguracyjnego."""
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
)
return True
async def async_unload_entry(hass, config_entry):
"""Usunięcie integracji - skasowanie wpis konfiguracyjnego ."""
return True
Jak widać podczas async_setup_entry wywoływane jest async_forward_entry_setup z parametrem “sensor” czyli to co robimy tu to przekierowanie do naszego programu obsługującego encję sensor. Gdybyśmy mieli w naszej integracji jeszcze inne typy urządzeń (zamki, odkurzacze, przełączniki, itd…) to też byśmy w tym miejscu wywołali ich dodawanie.
Przejdźmy tam i zdefiniujmy dodanie sensorów w metodzie async_setup_entry
w naszmy pliku sensor.py
.
Dodanie sensorów na podstawie danych z wpisu konfiguracyjnego
W pliku sensor.py
kod który mieliśmy w setup_platform
przenosimy do nowej metody async_setup_entry
- ta metoda zostanie wywołana podczas uruchamiania Asystenta domowego dla naszego wpisu konfiruracyjnego który powstał podczas dodawania integracji z kreatora.
Początek pliku sensor.py wygląda teraz tak:
"""ais hello sensor"""
from homeassistant.const import ENERGY_KILO_WATT_HOUR
from homeassistant.helpers.entity import Entity
from time import time
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Konfiguracja za pomocą yaml - sposób przestarzały"""
return
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Konfiguracja za pomcą przepływu konfiguracji."""
liczniki = [1, 2, 3]
for x in liczniki:
async_add_entities([AisHelloSensor(x, "licznik" + str(x))])
configuration.yaml
Od tej pory nasza integracja jest całkowicie niezależna od wpisów w pliku configuration.yaml
dlatego usuńmy lub zakomentujmy wpisy które dodaliśmy w tym pliku i które dotyczyły tej integracji:
# ~/AIS/configuration.yaml
# sensor:
# platform: ais_hello
Pobranie kodów na bramkę
To już wszystko, żeby dodać zmiany do repozytorium możemy wykonać nasze magiczne:
git add --all
git commit -m 'krok 4 integracji'
git push
a następnie na bramce przechodzimy od naszego ~/AIS/custom_components/ais_hello
i wykonujemy:
git pull
mamy już najnowsze kody restartujemy usługę ais:
pm2 restart ais