Z racji tego, że po kilku latach przerwy wróciłem do warzenia piwa, to używany przez ten czas moduł działający na ESP8266 i oprogramowaniu BrewPiLess, pilnujący, by „piwna lodówka” (leżaki) miała odpowiednią temperaturę, przeszedł solidną rewitalizację. I choć spisuje się więcej niż dobrze, to testowo kontrolę nad piwną lodówką, jak i fermentacją piwa, postanowiłem tym razem powierzyć układowi opartemu na innym oprogramowaniu.

Sterownik temperatury na bazie ESP8266, ESPHome i Home Assistant

Powodem takiej zmiany, na razie testowej, poza samą ciekawością nowego rozwiązania, jest też to, że choć z BrewPiLess jestem zadowolony, świetnie współpracuje m.in. z czujnikiem iSpindel, dobrze integruje się z serwisem Brewfather, to ma też swoje – przynajmniej dla mnie – malutkie wady.

Zaczynając od problemów ze zdalną kontrolą, spoza sieci WiFi, do której jest podpięty – niby mogę zrobić to przez MQTT, bo BrewPiLess jest ustawiony, by komunikował się właśnie po MQTT z resztą mojej infrastruktury IoT, to nie bardzo to działa. Raportuje świetnie, ale sam słuchać nie chce. Teoretycznie mógłbym wykorzystać tutaj Cloudflare Zero Trust, ale strona BrewPiLess za pomocą takiego połączenie nie bardzo chce działać. I choć za często nie potrzebuję „spoza domu” dokonywać modyfikacji w ustawieniach, to jednak fajnie mieć taką możliwość.

W przypadku BrewPiLess brakuje mi też opcji pozwalającej ręcznie uruchomić ogrzewanie czy chłodzenie, bez konieczności manipulowania ustawieniami temperatury i czekania, aż minie czas, między cyklami. Niby można tu się wspomóc komendami JSON, ale nie jest to specjalnie wygodne, zwłaszcza gdy potrzebujemy ręcznie przejść kontrolę nad systemem tylko na chwilę.

Kolejny powód jest taki, że skoro i tak korzystam z oprogramowania (serwera) Home Assistant do zarządzania „inteligentnym domem”, a konkretnie różnymi urządzeniami, robiącymi różne rzeczy, to pojawił się pomysł, by może zamiast integracji BrewPiLess z Home Assistant za pomocą MQTT, całość przerzucić bezpośrednio na Home Assistant, a konkretnie ESPHome, z którego też korzystam, które świetnie integruje się z Home Assistant po API, a do tego przy odpowiedniej konfiguracji, może działać całkowicie niezależnie, w przypadku, gdyby z jakiegoś powodu Home Assistant był niedostępny (pozdrawiam firmę Goodram, bo ich karta microSD 64 GB wytrzymała niecałe 3 miesiące (!), zmuszając mnie ostatnio do awaryjnego odzyskiwania systemu w Raspberry Pi).

Integracja ESPHome z Brewfather

Na pierwszy ogień integracja wymagana, czyli integracja z serwisem Brewfather, gdzie planuje i monitoruję wszystkie swoje warki/piwa. Tutaj na szczęście nie było problemów, bo Brewfather jest gotowy nie tylko na integrację z wybranymi usługami i sprzętami, ale też niestandardowymi.

W tym celu w konfiguracji urządzenia w ESPHome, poza standardowymi wpisami, wystarczyło dodać:

http_request:
  useragent: esphome/device
  timeout: 60s

interval:
  - interval: 900s
    then:
      - button.press: ${device_id}_brewfather_akt

button:
  [...]
  - platform: template
    name: "${friendly_name} Brewfather AKT"
    id: ${device_id}_brewfather_akt
    on_press:
      - http_request.post:
          headers:
            Content-Type: application/json
          url: !secret brewfather_stream_url
          verify_ssl: false
          json: |-
            root["name"] = "${friendly_name}";
            root["temp"] = id(${device_id}_ds18b20_03).state;
            root["aux_temp"] = id(${device_id}_ds18b20_02).state; 
            root["ext_temp"] = id(${device_id}_ds18b20_01).state;

Celowo jest to zrobione za pomocą przycisku, a nie bezpośrednio np. w „interval”, by aktualizację danych do Brewfather móc np. wymusić ręcznie, czy też z innych automatyzacji (np. on_boot), bez każdorazowego przepisywania kodu odpowiedzialnego za wysłanie JSONa.

Thermostat Climate Controller w ESPHome

Jeśli chodzi o samo sterowanie, to zdecydowałem się wykorzystać standardowy komponent, dostępny w ESPHome, a konkretnie Thermostat Climate Controller. Przykładowy kod YAML może wyglądać tak:

climate:
  - platform: thermostat
    name: "${friendly_name} TCC Fridge"
    id: ${device_id}_tcc_fridge
    sensor: ${device_id}_ds18b20_02
    on_boot_restore_from: memory
    min_cooling_off_time: 300s
    min_cooling_run_time: 300s
    min_heating_off_time: 30s
    min_heating_run_time: 30s
    min_idle_time: 300s
    startup_delay: true
    visual:
      min_temperature: 0
      max_temperature: 40
      temperature_step:
        target_temperature: 0.1
        current_temperature: 0.1
    cool_action:
      - switch.turn_on: ${device_id}_relay02
      - switch.turn_off: ${device_id}_relay01
    heat_action:
      - switch.turn_on: ${device_id}_relay01
      - switch.turn_off: ${device_id}_relay02
    idle_action:
      - switch.turn_off: ${device_id}_relay02
      - switch.turn_off: ${device_id}_relay01
    default_preset: 18C
    preset:
      - name: 18C
        default_target_temperature_low: 17.9
        default_target_temperature_high: 18.2
      - name: 32C
        default_target_temperature_low: 31.9
        default_target_temperature_high: 32.2

Jest to uproszczony kod, specjalnie na potrzeby artykułu, bez kilku mniej standardowych opcji i rozwiązań, ale ma wszystko, co niezbędne, bez zbędnych komplikacji.

Dallas DS18B20, czyli czujnik temperatury

Całość do działania potrzebuje odczytów temperatury, a że ma być niezależna od odczytów zewnętrznych, np. z Home Assistant, to korzysta z trzech czujników DS18B20, podłączonych bezpośrednio do ESP8266 (temperatura pomieszczenia, chłodziarki, piwa):

dallas:
  - pin: D6
    update_interval: 30s
    
sensor:
  [...]
  - platform: dallas # Room
    address: 0x063c11dc55af6328
    name: "${friendly_name} DS18B20-01"
    id: ${device_id}_ds18b20_01
    filters:
    - median:
        window_size: 3
        send_every: 3
        send_first_at: 1
  - platform: dallas # Fridge
    address: 0xae3c01d70865a038
    name: "${friendly_name} DS18B20-02"
    id: ${device_id}_ds18b20_02
  - platform: dallas # Beer
    address: 0x5d0625830c18fa38
    name: "${friendly_name} DS18B20-03"
    id: ${device_id}_ds18b20_03

Tu kod również uproszczony, do niezbędnego minimum, czyli wszystko, co niezbędne i niewiele więcej (zostawiłem filtrowanie).

Przekaźniki, czyli grzanie i chłodzenie

Jak ma grzać i chłodzić, to potrzebne są przekaźniki, a konkretnie sterowanie nimi. A jak ma być opcja ręcznego włączania i wyłączania zarówno grzania, jak i chłodzenia, to oczywiście na tapet idą przełączniki programowe w ESPHome:

switch:
  [...]
  - platform: gpio
    pin:
      number: D7 # Chłodzenie
      inverted: true
    name: "${friendly_name} Relay 02"
    id: ${device_id}_relay02
  - platform: gpio
    pin:
      number: D5 # Grzanie
      inverted: true
    name: "${friendly_name} Relay 01"
    id: ${device_id}_relay01

Tutaj niespecjalnie było co upraszać w kodzie, choć w przypadku niektórych przekaźników pewnie opcja „inverted: true” nie tylko, nie będzie potrzebna, co wręcz może sprawić, że przekaźnik będzie działał odwrotnie, niż chcemy. Ale to już indywidualna kwestia przekaźnika…

Zapis i odczyt ustawień z pamięci

Na koniec niby drobiazg, w przypadku układów ESP32 już zbyteczny, ale w przypadku ESP8266 chyba cały czas wymagany, czyli wymuszenie zapisywania aktualnych ustawień do pamięci i ich odczytywanie, po ponownym uruchomieniu urządzenia:

esp8266:
  [...]
  restore_from_flash: true
 
preferences:
  flash_write_interval: 5min # Def: 1min

Dodatkowo zmieniłem standardowy interwał zapisywania z „co minutę”, na „co 5 minut”, co wg mnie jest wystarczające, a zawsze pozwala oszczędzić trochę pamięć.

Sterowanie piwną lodówką (termostatem) w Home Assistant

I tak po skompilowaniu w ESPHome kodu, jak powyżej (mniej więcej, bo potrzebne są jeszcze choćby dodatkowe elementy, jakie są wymagane przez ESPHome do prawidłowej pracy, jak np. konfiguracja WiFi, czy deklaracja wykorzystanych w kodzie zmiennych, takich jak friendly_name, device_id) i w graniu na ESPHome, oraz dodaniu do Home Assistant otrzymałem taki efekt:

Właściwie za pomocą jednego kliknięcia, właściwie z dowolnego miejsca, byle był dostęp do internetu, mogę włączyć lub wyłączyć automatyczne pilnowanie temperatury, czyli termostat, zmienić tryb jego pracy (grzanie i chłodzenie, tylko grzanie, tylko chłodzenie), czy też ręcznie uruchomić grzanie i/lub chłodzenie, z pominięciem termostatu. Mam też listę zdefiniowanych profilii, za pomocą których szybko mogę wybrać konkretny zakres temperatury, dla konkretnego zadania (np. dolna fermentacja, górna fermentacja, czy jeszcze wyżej, bo jakieś kveiki…).

I po kilku dniach mogę powiedzieć, że działa to bardzo dobrze, a fakt integracji ESPHome z Home Assistant sprawia, że konfiguracja dodatkowych opcji czy automatyzacji, jest wygodniejsza i szybsza, niż zabawa z MQTT.

Brewfather, iSpindel i Home Assistant

I choć przedstawiony tutaj kod (YAML) to tylko fragment całego kodu, to z racji tego, że miał to być tylko test już na realnym piwie, to nie wdrożyłem jeszcze jednej ważnej opcji. Chodzi o to, by informacje z iSpindel, takie jak temperatura, stopnie Plato i kąt urządzenia, trafiały również do Home Asisistant, a nie tylko do Brewfather.

Przed testowym urządzeniem jeszcze przynajmniej kilka dni fermentacji, więc mam czas, by się zastanowić, nad możliwościami, i co z tego najlepiej wybrać. Na obecną chwilę rozważam roboczo 3 możliwości:

I nie wiem jeszcze, na który wariant się zdecyduję, ale też mam na podjęcie decyzji i jakieś testy przynajmniej kilka dni. A jak podejmę decyzję, wdrożę i będę zadowolony z integracji Home Assistant z iSpindel, to najpewniej zaktualizuję ten artykuł, lub napiszę kolejny…

Wersja celowo uproszczona

Oczywiście jest to tylko przykład, bo w rzeczywistości – jak już wspomniałem – kod ESPHome musi zawierać jeszcze kilka elementów, takich jak choćby konfiguracja typu układu, WiFi, API… Tak samo, jak w kodzie wgranym do urządzenia jest jeszcze np. konfiguracja zmiennych:

substitutions:
  device_name: esph20
  friendly_name: ESPH20
  device_id: esph20
  device_description: "ESPH20 BrewBox"

Dodatkowo w swoim sterowniku mam też np. mechanizm pozwalający bezpośrednio z poziomu Home Assistant zmienić czujnik temperatury (DS18B20), który odpowiada za dany obszar:

Z premedytacją pominąłem ten element w opisanym przykładzie, bo niepotrzebnie by to komplikowało przykładowy kod, a do tego w większości przypadków taka opcja jest raczej zbyteczna. Ja z niej korzystam, bo zdarza mi się nie tylko przenosić sterowniki, ale też zmieniać czujniki i ich lokalizację, zależnie od potrzeb. A dzięki takiej opcji, nie muszę po każdej takiej zmianie kompilować i wgrywać ponownie oprogramowania.

Sterownik temperatury nie tylko do „piwnej lodówki”

I choć artykuł dotyczy konstrukcji – głównie od strony programowej, bo sprzętowo jest identycznie, choćby, bym mógł płynnie przechodzić od jednego rozwiązania do drugiego – sterownika piwnej lodówki, oraz zarządzania procesem fermentacji, to nic nie stoi na przeszkodzie, by wykorzystać taki sterownik np. do kontroli ogrzewania w domu, garażu…

W artykule mowa o sterowniku dwufunkcyjnym, bo zarówno lodówka, jak i fermentor mogą być zarówno chłodzone i ogrzewane. W przypadku sterownika ogrzewania, bez funkcji chłodzenia, wystarczy zrezygnować w kodzie z tej funkcji. Zresztą w drugą stronę też to zadziała – można zostawić tylko chłodzenie, dzięki czemu całość może działać jako sterownik lodówki, bez funkcji grzania. A nawet i tego nie trzeba, bo za pomocą jednego kliknięcia można przełączyć termostat z trybu grzanie i chłodzenie, na tylko grzanie lub tylko chłodzenie.

(!) Zgłoś błąd na stronie
Pomogłem? To może postawisz mi wirtualną kawę?
LUTy dla D-Cinelike (DJI Mini 3 Pro, DJI Avata, OSMO Pocket) od MiniFly
Wdrożenie Omnibusa w sklepie na WooCommerce
Jak (legalnie) latać dronem w Kategorii Otwartej