BoneIO Demo

Demonstracyjne wykorzystanie sterowników BoneIO

Wstęp

W moim wdrożeniu wentylator łazienkowy (W01) nie jest uruchamiany “na sztywno” z jednego przycisku. Sterowanie opieram o stan LED_STATE, który jest publikowany z dimmera łazienkowego i odbierany przez sterownik główny. W trybie automatycznym wentylator włącza się po 1min, a wyłącza po 2min od zaniku sygnału. Niezależnie od timerów mogę też sterować wentylatorem ręcznie z przycisku (bez czekania na opóźnienia).

Schemat przepływu (automatyka + ręczne sterowanie):

S09_G (SP) na dimmerze
        |
        v
skrypt lazienka -> publish_state(LED_STATE)
        |
        v
packet_transport (UDP) -> sterownik główny (remote_LED_STATE)
        |
        v
logika ON/OFF + fan_cycle_active
        |
        +--> wentylator_on (delay 1min)  -> W01 ON
        \--> wentylator_off (delay 2min) -> W01 OFF

Ręcznie (niezależnie od timerów):
S08_L (LP) -> id(W01).toggle().perform()

Skąd bierze się sygnał LED_STATE

Po stronie dimmera (boneIO_dl_02.yaml) LED_STATE jest zdefiniowany jako sensor typu template:

binary_sensor:
  - platform: template
    id: LED_STATE

Następnie jest publikowany ze skryptu lazienka:

Na sterowniku głównym (boneIO_32_10.yaml) stan ten jest odbierany przez packet_transport jako remote_LED_STATE.

Przykład publikacji stanu po stronie dimmera (boneIO_dl_02.yaml):

- id: lazienka
  then:
    - lambda: |-
        if (sn == "S09_G" && pt == "SP") {
          auto isLedOn = (id(L05).current_values.is_on()
                       || id(L07).current_values.is_on()
                       || id(L08).current_values.is_on());
          id(LED_STATE).publish_state(!isLedOn);
        }

I jest udostępniany po UDP przez packet_transport:

udp:

packet_transport:
  - id: transport
    platform: udp
    update_interval: 30s
    encryption: 'SUPER_SECRET_KEY'
    rolling_code_enable: false
    binary_sensors:
      - LED_STATE
    providers:
      - name: boneio-32-l-07-39d104
        encryption: 'SUPER_SECRET_KEY'

Pełniejszy przykład odbioru i reakcji na stan po stronie sterownika głównego (boneIO_32_10.yaml):

- platform: packet_transport
  transport_id: transport
  provider: boneio-dr-8ch-03-7c8500
  id: remote_LED_STATE
  remote_id: LED_STATE
  type: data
  on_state_change:
    then:
      - lambda: |-
          auto ledState = x.has_value() ? ONOFF(x.value()) : "Unknown";
          ESP_LOGI("remote_LED_STATE", "state=%s", ledState.c_str());

          if (ledState == "ON") {
            id(wentylator_off)->stop();
            if (!id(fan_cycle_active)) {
              id(fan_cycle_active) = true;
              id(wentylator_on)->execute();
            }
          } else if (ledState == "OFF") {
            if (id(fan_cycle_active)) {
              id(wentylator_off)->execute();
            }
          }

Jak działa ten fragment skryptu:

Najważniejsza jest tutaj flaga fan_cycle_active. To blokada przed wielokrotnym uruchamianiem tego samego cyklu przy kolejnych pakietach ON. Dzięki temu nie nakładają się równoległe wywołania i logika pozostaje przewidywalna: jeden aktywny cykl start/stop wentylatora na raz.

Sterowanie ręczne z przycisku

Timery odpowiadają tylko za tryb automatyczny oparty o LED_STATE. Równolegle wentylator W01 mogę w każdej chwili przełączyć ręcznie z przycisku - to sterowanie działa niezależnie od opóźnień 1min i 2min.

Fragment skryptu (boneIO_32_10.yaml, script: lazienka):

if (sn == "S08_L" && pt == "LP") {
  id(W01).toggle().perform();
}

W praktyce LP na S08_L natychmiast przełącza W01, bez czekania na logikę timerów.

Logika timerów

W boneIO_32_10.yaml działają dwa skrypty:

Dodatkowo:

Pełny fragment skryptów timerów (boneIO_32_10.yaml):

- id: wentylator_on
  mode: single
  then:
    - lambda: |-
        ESP_LOGI("wentylator", "on before delay");
    - delay: 1min
    - lambda: |-
        ESP_LOGI("wentylator", "on after delay");
        id(W01).turn_on().perform();

- id: wentylator_off
  mode: restart
  then:
    - lambda: |-
        ESP_LOGI("wentylator", "off before delay");
    - delay: 2min
    - lambda: |-
        ESP_LOGI("wentylator", "off after delay");
        id(W01).turn_off().perform();
        id(fan_cycle_active) = false;

Efekt użytkowy

W praktyce:

To daje spokojniejszą pracę instalacji i bardziej przewidywalne zachowanie w codziennym użyciu.

Co dostosować u siebie

Postaw mi kawę na buycoffee.to