♾ Własna integracja - 4. Konfiguracja integracji

:infinity: 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 :wink:

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:

  1. async_step_user - uruchomienie konfiguracji przez użytkownika, tu przekierowujemy na formatkę z informacją o integracji i pytaniem czy kontynuować
  2. async_step_confirm - potwierdzenie przez użytkownika i przekierowanie na formatkę z danymi logowania (do serwisu z którym się integrujemy)
  3. 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

Testujemy integrację

Tłumaczenie na język polski

Ekran z potwierdzeniem

Formatka z logowaniem

Sukces :slight_smile:

Tu są nasze kody

1 polubienie