Jako entuzjasta inteligentnego domu dość mocno polegam na inteligentnym oświetleniu. Gdy jednak musiałem wyposażyć każdy pokój w kontroler oświetlenia – niekiedy nawet kilka – natrafiłem na problem budżetowy. Komercyjne inteligentne kontrolery są dość drogie. Postanowiłem więc użyć drukarki 3D, dołożyć trochę elektroniki i własnoręcznie zbudować własny kontroler za ułamek tej ceny.

Zaprojektowałem mały macropad ze switchami z klawiatury mechanicznej, płytką ESP32, enkoderem obrotowym do regulacji jasności i kompaktowym wyświetlaczem OLED pokazującym aktualnie aktywną scenę oświetleniową. Enkoder obrotowy ma też wbudowany przycisk – jego naciśnięcie przełącza tryb przyciemniania wyświetlacza, umożliwiając regulację jasności OLED, a kolejne kliknięcie przywraca normalne sterowanie oświetleniem.

Aby nie była to tylko kolejna nudna plastikowa skrzynka, postanowiłem połączyć kilka materiałów Prusament Woodfill, tworząc estetyczne kombinacje kolorystyczne pasujące do drewnianego blatu mojego biurka. Miałem okazję przetestować jeden z egzemplarzy beta Prusa CORE One+ INDX, więc skorzystałem z jego możliwości drukowania wielomateriałowego. Można jednak z łatwością wydrukować ten projekt na drukarce Original Prusa XL, wyposażonej w MMU3, a nawet na standardowej drukarce z jednym narzędziem, bez możliwości drukowania wielomateriałowego. W takim przypadku podczas drukowania trzeba będzie kilka razy ręcznie wymienić filamenty, ale jest to całkowicie wykonalne – choć należy liczyć się z większą ilością odpadów. Dzięki zastosowaniu INDX udało mi się niemal całkowicie wyeliminować odpady filamentu – to świetny bonus dla projektu, ponieważ zaoszczędziłem materiał, który mogę teraz wykorzystać do wydrukowania dodatkowych makropadów lub innych przedmiotów.

Hardware

Żeby projekt był jak najbardziej przystępny, wszystkie części elektroniczne można zdobyć za kilkadziesiąt złotych. Możesz oczywiście pominąć wyświetlacz oraz enkoder i ograniczyć się tylko do przełączników, albo nawet zmniejszyć liczbę klawiszy.

Jako „mózg” makropada można wykorzystać niemal każdą płytkę rozwojową z układem ESP32 lub podobnym, wyposażoną w wystarczającą liczbę wejść i obsługującą Wi-Fi. Doskonałym wyborem są wysokiej jakości płytki takich marek jak Adafruit (np. kompaktowa QT Py ESP32-S3 lub klasyczna Feather ESP32-S3) lub SparkFun (Thing Plus ESP32-S3). W moim przypadku, zanim poszedłem na zakupy online, zagłębiłem się w moją niekończącą się szufladę z częściami zamiennymi i znalazłem podobną płytkę, Xiao ESP32-C3 od Seeed Studio, więc postanowiłem pozostać przy niej w tym projekcie.

Jeśli chodzi o klawisze, zdecydowałem się na niebieskie switche mechaniczne. Być może to dość niszowy wybór i zwykłe klawisze sprawdziłyby się równie dobrze, ale przełączniki mechaniczne po prostu mi odpowiadają ze względu na to satysfakcjonujące uczucie kliknięcia i dźwięk.

Oto krótkie zestawienie tego, co będzie Ci potrzebne do wykonania wersji opisanej w tym artykule:

Komponent Orientacyjna cena
ESP32 $8.00
Wyświetlacz OLED 0.91″ $4
Enkoder obrotowy KY-040 $1.30
Switche do klawiatury mechanicznej (x6) $3.50
Filament ~$3.00
Całkowity koszt sprzętu ~$19.80

Druk 3D i personalizacja projektu

Czas przygotować modele 3D do druku. Możesz zaprojektować je samodzielnie w oprogramowaniu do modelowania 3D, takim jak Autodesk Fusion, lub pobrać gotowe pliki tego projektu z Printables.

Zaimportuj pliki do PrusaSlicera. Dla czystego, eleganckiego wyglądu możesz wydrukować obudowę z jasnego Prusament Woodfill Linden Light. Ponieważ jednak wyobraźnia nie zna granic, możesz też przygotować wersje w żywych kolorach – idealne do pokoju dziecięcego, na przykład w stylu Avengers. Następnie dodaj modyfikatory SVG z prostymi symbolami do klawiszy i gałki enkodera, klikając prawym przyciskiem model w PrusaSlicerze i wybierając Dodaj modyfikator → SVG. Jeśli potrzebujesz bardziej szczegółowego przewodnika na temat modyfikatorów SVG, zajrzyj do naszego artykułu o akcesoriach do sensorycznej zabawy. Ciemniejszy Prusament Chocolate Brown Woodfill na przyciski i jasny Linden Light na symbole tworzą bardzo ładny kontrast. Dzięki wykorzystaniu wielu materiałów w jednym wydruku na drukarce takiej, jak CORE One+ z INDX lub Original Prusa XL, efekt jest niezwykle precyzyjny – zero zanieczyszczenia koloru i absolutne minimum odpadów. Klawisze najlepiej drukować stroną z symbolem skierowaną w dół, na płycie stołu. Na ilustracji poniżej są odwrócone stroną z symbolem do góry tylko po to, żeby pokazać wzory SVG. Gdy wszystkie elementy zostaną wydrukowane, nadchodzi czas na montaż.

Montaż i okablowanie

Najpierw zamontuj switche do klawiatury, po prostu wsuwając je przez otwory w obudowie, aż zaskoczą na swoje miejsce. Następnie zamontuj wyświetlacz, enkoder obrotowy i moduł ESP32, wkładając jego złącze USB-C do przygotowanego otworu z boku obudowy tak, aby było skierowane na zewnątrz. Podczas gdy wyświetlacz i enkoder same w sobie trzymają się dość mocno, zamocowanie modułu ESP32 wymaga nieco większej ostrożności. Użyłem prostej, wydrukowanej podkładki dystansowej, którą wystarczy wsunąć między ściankę obudowy a płytkę, aby ją zaklinować, blokując moduł na miejscu podczas podłączania przewodu USB-C.

Układ zajmuje łącznie jedenaście pinów: sześć przełączników, enkoder (2 piny na obrót i 1 na przycisk) i wyświetlacz I2C (2 piny danych/zegarowy). To dokładnie tyle, ile wejść cyfrowych ma moja płytka ESP32. Poniżej schemat okablowania wykonany w Wokwi – świetnym, darmowym symulatorze działającym w przeglądarce. Wokwi ma też wbudowany symulator, dzięki czemu możesz podłączyć wszystkie komponenty i napisać kod testowy, żeby sprawdzić poprawność okablowania przed złożeniem fizycznego urządzenia.

Uważaj, patrząc na płytkę: fizyczne oznaczenia wydrukowane na PCB (D0-D10) różnią się od wewnętrznych rejestrów (GPIO) używanych w kodzie. Oto mapowanie pinów:

5V / 5V0VCC (wspólna linia zasilająca dla wyświetlacza OLED i enkodera obrotowego)

GNDGND (wspólny minus dla wszystkich elementów i klawiszy mechanicznych)

D0 (Wewnętrzne GPIO 2)Klawisz 1

D1 (Wewnętrzne GPIO 3)Klawisz 2

D2 (Wewnętrzne GPIO 4)Klawisz 3

D3 (Wewnętrzne GPIO 5)Klawisz 4

D4 (Wewnętrzne GPIO 6)OLED SDA (linia danych)

D5 (Wewnętrzne GPIO 7)OLED SCL (linia zegara)

D6 (Wewnętrzne GPIO 21)CLK enkodera (pin obrotowy A)

D7 (Wewnętrzne GPIO 20)DT enkodera (pin obrotowy B)

D8 (Wewnętrzne GPIO 8)Przełącznik enkodera (wbudowany przycisk enkodera)

D9 (Wewnętrzne GPIO 9)Przycisk 5

D10 (Wewnętrzne GPIO 10)Klawisz 6

Przy wstępnych testach możesz podłączyć wszystko złączami Dupont, jak ja. Jednak przestrzeni w obudowie jest dość mało, a te złącza nie są wystarczająco pewne do codziennego użytku. Żeby zapewnić stuprocentową niezawodność i wygodne rozmieszczenie komponentów, gorąco polecam wszystko przylutować.

Konfiguracja oprogramowania (ESPHome)

Skoro wszystko jest podłączone, czas na (vibe)coding 😎! Podłączenie ESP32 do komputera PC lub Mac to łatwizna. Wystarczy podłączyć go przez USB-C, pobrać niezbędne narzędzia i wgrać kod do płytki przez terminal. Na Macu możesz użyć Pythona i jego pakietu ESPHome, instalowanego przez menedżer pakietów pip poleceniem pip3 install esphome.

Po zakończeniu instalacji utwórz dwa pliki YAML: keyboard.yaml i secrets.yaml. Plik keyboard.yaml zawiera cały kod dla ESP32, a secrets.yaml bezpiecznie przechowuje dane logowania do Wi-Fi. Będziesz też potrzebować pliku z czcionką. W tym projekcie użyłem czcionki Nunito z biblioteki Google Fonts. Znajdziesz ją tutaj: https://fonts.google.com/specimen/Nunito. Pobierz i wypakuj plik, umieść wersję o regularnym kroju (Nunito-Regular.ttf) w tym samym folderze co pozostałe pliki i zmień jej nazwę na font.ttf.

Uwaga: ten kod jest przygotowany specjalnie dla Seeed Studio XIAO ESP32-C3. Jeśli używasz innej płytki ESP32, musisz dostosować parametr board: oraz mapowanie pinów GPIO do swojego sprzętu. Jeśli nie wiesz, jak to zrobić, nie wahaj się poprosić swojego ulubionego asystenta AI o pomoc! 🙂

Poniżej kompletny plik keyboard.yaml. Niech nie zrażą Cię długie sekcje oznaczona jako lambda:. Obsługują one logikę działającą w tle – na przykład przeliczają surowe dane jasności na czytelne wartości procentowe (%) i formatują tekst wyświetlany na ekranie OLED.


esphome:
  name: keyboard
  on_boot:
    priority: -100
    then:
      - sensor.rotary_encoder.set_value:
          id: rotary_knob
          value: 10
      - sensor.template.publish:
          id: ha_knob
          state: 10
      - binary_sensor.template.publish:
          id: ha_service_mode
          state: false

esp32:
  board: seeed_xiao_esp32c3

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

captive_portal:

api:
  on_client_connected:
    - lambda: |-
        id(ha_service_mode).publish_state(id(service_mode));
        id(ha_active_key_sensor).publish_state(id(active_text));
  services:
    - service: set_display_text
      variables:
        new_text: string
      then:
        - lambda: |-
            id(active_text) = new_text;
            id(ha_active_key_sensor).publish_state(new_text);
            id(oled_display).update();

logger:
  baud_rate: 115200

i2c:
  sda: 6
  scl: 7

globals:
  - id: active_text
    type: std::string
    initial_value: '"OFF"'
  - id: service_mode
    type: bool
    initial_value: 'false'
  - id: saved_light_steps
    type: int
    initial_value: '10'
  - id: display_steps
    type: int
    initial_value: '10'

script:
  - id: block_feedback_script
    mode: restart
    then:
      - delay: 800ms

font:
  - file: "font.ttf"
    id: font_large
    size: 14
  - file: "font.ttf"
    id: font_sub
    size: 10

text_sensor:
  - platform: template
    name: "Active Key"
    id: ha_active_key_sensor

sensor:
  - platform: template
    name: "Rotary Knob"
    id: ha_knob

  - platform: rotary_encoder
    id: rotary_knob
    pin_a: 21
    pin_b: 20
    min_value: 0
    max_value: 10
    resolution: 2
    on_value:
      then:
        - lambda: |-
            if (isnan(x)) return;
            if (id(service_mode)) {
              if (x == 0) id(rotary_knob).set_value(1);
              id(oled_display).set_contrast(id(rotary_knob).state / 10.0);
            } else {
              if (x == 0 and id(ha_light_state).state) id(rotary_knob).set_value(1);
              id(block_feedback_script).execute();
              id(ha_knob).publish_state(id(rotary_knob).state);
            }
        - component.update: oled_display

  - platform: homeassistant
    id: ha_light_brightness
    entity_id: light.office
    attribute: brightness
    on_value:
      then:
        - lambda: |-
            if (not id(service_mode) and not id(block_feedback_script).is_running() and not isnan(x)) {
              int steps = round((x / 255.0) * 10.0);
              id(rotary_knob).set_value(steps);
              id(ha_knob).publish_state(steps);
            }
        - component.update: oled_display

binary_sensor:
  - platform: template
    name: "Service Mode"
    id: ha_service_mode

  - platform: status
    id: ha_connection_status

  - platform: homeassistant
    id: ha_light_state
    entity_id: light.office
    filters:
      - delayed_off: 500ms
    on_state:
      then:
        - lambda: |-
            if (not x) {
              if (not id(service_mode)) {
                id(rotary_knob).set_value(0);
                id(ha_knob).publish_state(0);
              } else {
                id(saved_light_steps) = 0;
              }
              id(active_text) = "OFF";
              id(ha_active_key_sensor).publish_state("OFF");
              id(oled_display).update();
            }

  - platform: gpio
    name: "Encoder Press"
    pin: {number: 8, mode: INPUT_PULLUP, inverted: true}
    on_press:
      then:
        - lambda: |-
            float current_state = isnan(id(rotary_knob).state) ? 10.0 : id(rotary_knob).state;
            if (not id(service_mode)) {
              id(saved_light_steps) = (int)current_state;
              id(service_mode) = true;
              id(rotary_knob).set_value(id(display_steps));
              id(ha_service_mode).publish_state(true);
            } else {
              id(display_steps) = (int)current_state;
              id(service_mode) = false;
              id(rotary_knob).set_value(id(saved_light_steps));
              id(ha_knob).publish_state(id(saved_light_steps));
              id(ha_service_mode).publish_state(false);
            }
        - component.update: oled_display

  - platform: gpio
    name: "Key 1"
    pin: {number: 2, mode: INPUT_PULLUP, inverted: true}
  - platform: gpio
    name: "Key 2"
    pin: {number: 3, mode: INPUT_PULLUP, inverted: true}
  - platform: gpio
    name: "Key 3"
    pin: {number: 4, mode: INPUT_PULLUP, inverted: true}
  - platform: gpio
    name: "Key 4"
    pin: {number: 5, mode: INPUT_PULLUP, inverted: true}
  - platform: gpio
    name: "Key 5"
    pin: {number: 9, mode: INPUT_PULLUP, inverted: true}
  - platform: gpio
    name: "Key 6"
    pin: {number: 10, mode: INPUT_PULLUP, inverted: true}

display:
  - platform: ssd1306_i2c
    id: oled_display
    model: "SSD1306 128x32"
    address: 0x3C
    rotation: 180
    lambda: |-
      if (id(service_mode)) {
        it.print(0, 0, id(font_large), "DISPLAY");
      } else {
        it.print(0, 0, id(font_large), id(active_text).c_str());
      }
      
      if (id(ha_connection_status).state) {
        it.print(82, 0, id(font_sub), "HA: OK");
      } else {
        it.print(82, 0, id(font_sub), "HA: --");
      }
      
      it.printf(0, 19, id(font_sub), "Int: %.0f%%", isnan(id(rotary_knob).state) ? 0.0 : id(rotary_knob).state * 10.0);
      
      if (wifi::global_wifi_component->is_connected()) {
        it.print(75, 19, id(font_sub), "Wi-Fi: OK");
      } else {
        it.print(75, 19, id(font_sub), "Wi-Fi: --");
      }

Hasło do Wi-Fi znajduje się w osobnym pliku secrets.yaml. Utwórz go i uzupełnij własnymi danymi:

wifi_ssid: "moja_sieć_wi-fi"
wifi_password: "niemożliwe_do_złamania_hasło"

Teraz możesz skompilować i wgrać kod do ESP32 poleceniem python3 -m esphome run keyboard.yaml. Pamiętaj, że polecenie należy uruchomić z poziomu folderu, w którym znajduje się plik YAML. Gdy terminal wyświetli zapytanie, wpisz numer odpowiadający podłączonemu portowi USB i naciśnij Enter. Jeśli wgrywanie przebiegło pomyślnie, w terminalu powinien pojawić się log komunikacji między komputerem a ESP32, a wyświetlacz powinien się włączyć.

Wyświetlacz pokazuje m.in. status połączenia Wi-Fi, który po kilku sekundach powinien wyświetlić „OK”. Zobaczysz też linię „HA” oznaczającą status połączenia z Home Assistant. Na razie nie musisz się tym przejmować – gdy skonfigurujemy wszystko w HA, powinna też pokazywać OK. Jeśli widzisz logi, a wyświetlacz pokazuje informacje, ESP32 został pomyślnie zaprogramowany i możesz przejść do konfiguracji Home Assistant. Możesz pozostawić moduł ESP32 podłączony do portu USB w komputerze lub użyć dowolnej standardowej ładowarki USB 5 V do zasilania macropadu.

Konfiguracja Home Assistant

1. Dodawanie ESP32 do Home Assistant

Dzięki natywnej integracji ESPHome Home Assistant powinien automatycznie rozpoznać nowy macropad.

  • Przejdź do Settings → Devices & Services w panelu Home Assistant.
  • Spójrz na górę zakładki Integrations. Powinno pojawić się nowo wykryte urządzenie ESPHome o nazwie keyboard.
  • Kliknij Configure i postępuj zgodnie z instrukcjami na ekranie, żeby dodać urządzenie.
  • Uwaga: Jeśli nie pojawia się automatycznie, kliknij Add Integration w prawym dolnym rogu, wyszukaj ESPHome i wprowadź lokalny adres IP ESP32.

    Po dodaniu Home Assistant automatycznie wczytuje wszystkie klawisze, enkoder i przełącznik trybu serwisowego.

    2. Tworzenie pomocniczej grupy oświetlenia

    Żeby projekt był schludny i uniwersalny, unikamy na sztywno wpisywania konkretnych żarówek bezpośrednio do kodu. Zamiast tego utwórz pomocnik Light Group. Dzięki temu, gdy wymienisz żarówki, wystarczy zaktualizować tę grupę – automatyzacja pozostaje bez zmian.

  • Przejdź do Settings → Devices & Services i kliknij zakładkę Helpers na górze.
  • Kliknij + Create Helper w prawym dolnym rogu.
  • Przewiń w dół, wybierz Group, a następnie Light Group.
  • Nazwij pomocnika Office (automatycznie zostanie wygenerowany wymagany identyfikator encji: light.office).
  • W sekcji Members wybierz swoje inteligentne żarówki, którymi ma sterować macropad.
  • Kliknij Submit / Create.

Po podłączeniu macropada i skonfigurowaniu grupy świateł możemy połączyć wszystko za pomocą głównego skryptu automatyzacji.

  • Przejdź do Settings → Automations & Scenes i kliknij Create Automation.
  • Wybierz Create new automation, następnie kliknij trzy kropki w prawym górnym rogu i wybierz Edit in YAML
  • Wyczyść domyślny kod, wklej poniższy skrypt i kliknij Save

W tym przewodniku przypisałem sześciu klawiszom aktywację prostych scen kolorystycznych (niebieski, zielony, czerwony itp.), ale możesz je dostosować do wyzwalania dowolnej sceny – prostej lub zaawansowanej.


alias: Light Office - Master Control
description: Master Control for Macropad
triggers:
  - entity_id: binary_sensor.keyboard_key_1
    to: "on"
    id: press_k1
    trigger: state
  - entity_id: binary_sensor.keyboard_key_2
    to: "on"
    id: press_k2
    trigger: state
  - entity_id: binary_sensor.keyboard_key_3
    to: "on"
    id: press_k3
    trigger: state
  - entity_id: binary_sensor.keyboard_key_4
    to: "on"
    id: press_k4
    trigger: state
  - entity_id: binary_sensor.keyboard_key_5
    to: "on"
    id: press_k5
    trigger: state
  - entity_id: binary_sensor.keyboard_key_6
    to: "on"
    id: press_k6
    trigger: state
  - entity_id: sensor.keyboard_rotary_knob
    id: knob_rotation
    trigger: state
conditions:
  - condition: state
    entity_id: binary_sensor.keyboard_service_mode
    state: "off"
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: knob_rotation
        sequence:
          - action: light.turn_on
            metadata: {}
            target:
              entity_id: light.office
            data:
              brightness_pct: "{{ (trigger.to_state.state | int(10)) * 10 }}"
      - conditions:
          - condition: trigger
            id: press_k1
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: Blue
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 4
                    - 51
                    - 255
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: Blue
      - conditions:
          - condition: trigger
            id: press_k2
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: Green
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 0
                    - 249
                    - 0
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: Green
      - conditions:
          - condition: trigger
            id: press_k3
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: Red
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 255
                    - 0
                    - 0
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: Red
      - conditions:
          - condition: trigger
            id: press_k4
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: Yellow
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 255
                    - 255
                    - 0
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: Yellow
      - conditions:
          - condition: trigger
            id: press_k5
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: Purple
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 255
                    - 0
                    - 255
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: Purple
      - conditions:
          - condition: trigger
            id: press_k6
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: sensor.keyboard_active_key
                    state: White
                sequence:
                  - action: light.turn_off
                    target:
                      entity_id: light.office
            default:
              - action: light.turn_on
                target:
                  entity_id: light.office
                data:
                  brightness_pct: 100
                  rgb_color:
                    - 255
                    - 255
                    - 255
              - action: esphome.keyboard_set_display_text
                data:
                  new_text: White
mode: restart

 

Edytor YAML w Home Assistant wygląda tak:

Testy i podsumowanie

Gdy wszystko jest wgrane, czas przetestować macropad. Naciśnij klawisz – scena oświetleniowa powinna natychmiast się zmienić. Obróć enkoder – intensywność światła powinna się zmienić. Wyświetlacz OLED powinien też poprawnie pokazywać aktualnie wybraną scenę.

Gdy wszystko działa, wystarczy wydrukować dolną pokrywę i zamknąć obudowę. Dzięki mocowaniu na wcisk trzyma się pewnie bez kleju ani śrub. Ponieważ w wersji testowej zostawiłem grube złącza Dupont, potrzebowałem nieco więcej miejsca w środku – dlatego zrobiłem nieco wyższą dolną część. Przy okazji wykorzystałem to, łącząc różne materiały Prusament Woodfill, żeby stworzyć ładny pasek przejściowy. Jeśli zdecydujesz się przylutować komponenty, możesz zmniejszyć dolną pokrywę, co znacząco obniży wysokość macropada.

Choć sam używam tego macropada tylko do sterowania oświetleniem, możesz go przypisać do dowolnej funkcji inteligentnego domu. Skoro logikę obsługuje Home Assistant, naciśnięcie klawisza lub obrót enkodera może sterować roletami, uruchamiać odkurzacz automatyczny, albo wywołać automatyzację Spotify i zrobić Rickrolla gościom. Granicą jest tylko wyobraźnia! Gdy zbudujesz swój pierwszy taki projekt, trudno nie rozglądać się po domu w poszukiwaniu kolejnych miejsc, gdzie drukarka 3D i elektronika mogą się sprwadzić.

Pamiętaj, że praca z Home Assistant i ESPHome wiąże się z obsługą wrażliwych danych sieciowych. Choć ta konfiguracja działa w moim środowisku, konieczne może być dostosowanie kodu do własnego układu inteligentnego domu. Konfiguracja jest udostępniana w stanie, w jakim jest, bez żadnych gwarancji. Sprawdź wszystko dokładnie i zawsze używaj funkcji secrets w ESPHome, żeby chronić swoje prywatne dane logowania.

Udanego drukowania!