Tlačítko

www
kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

Desky i součástky mám komplet. Odběr zatím nezměřím, dodání PPK2 posunuto na půlku února.
Jeden úplně základní prototyp spáchám ručně s trubičkovou pájkou. S tou ale nezvládnu ten švýcarský hodinový obvod.
Další chci už dělat pasta + reflow. Na to se mi bude hodit hotplate (čínské pece jsem po velmi dlouhém zkoumání zavrhl, na to aby byly alespoň trochu použitelné je třeba spousty úprav = týdny/měsíce času strávené laděním mechanických úprav)
A také se mi bude hodit dávkovač pasty = motor, driver, arduino, 3D tisk úchyt stříkačky.

V další verzi plánuji nahrazení podstatné části zapojení nějakým GreenPAK obvodem od Dialog Semiconductor.
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

Tak částečně sestaveno (bez externího RTC)
DSC_1025.JPG
První měření vůbec neodpovídalo předpokladu, ve stand-by by nevydrželo ani rok s 400mAh baterkou. Ale je to jen kvůli nevhodné diodě - s velkým zpětným proudem - v powerpath
ppk-20221003T050510.png


Dioda odpojena, teď připojení USB jen nabíjí, ale odpojí napájení zbytku obvodu. Nahradím ji nějakou s Ir maximálně v setinách uA
Ale ten odběr se mi opravdu hodně líbí.
ppk-20221003T083358.png



Samozřejmě s odběrem běžícího ESP nic neudělám, ale tohle použití externího obvodu má teď zhruba stokrát nižší spotřebu. než jen deep sleep ESP.
I pokud doplním diodu (Ir od 6.5nA) a RTC (45nA) tak spotřeba bude stále úžasně nízká.
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

Uživatelský avatar
tiimsvk
Dárce - Donátor
Dárce - Donátor
Příspěvky: 801
Registrován: 06. květen 2021, 07:03
Dal poděkování: 72 poděkování
Dostal poděkování: 65 poděkování

Re: Tlačítko

Příspěvek od tiimsvk »

Ahoj toto vlakno sa mi páči nakoľko neustale doma budujem niečo na základe esphome a baterií.
Na začiatok by som mal dve otázky:
1. čo použiť ako regulátor na 3.3V z bežnej lipo batérie ... teraz mam osadený modul https://www.aliexpress.com/item/1005004207756611.html s označením DD0603SA (nakoľko má úplne iné odbery pri standby režime ako doteraz použivaný ams1117). (Meranie som našiel na tejt stránke https://goughlui.com/2018/07/03/tested- ... er-module/)
Všimol som si, že používaš modul HT7333 zvládne napájať aj iné pripojené moduly do esp (napr. taký žrut ako je displej?)

2. Vedel by si poskytnúť yaml kód do esphome? Chcel by som vedieť ako ti prebieha meranie batérie nakoľko doteraz som použival iba pomocou resitorov ale ako si písal je tam stále odber pri tomto type zapojenia a nakoľko mám esp8266, ktoré ma iba jeden adc pin, ktorý mám už využitý tak by to bolo fajn :)

Ďakujem.

kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

Asi musím rozepsat co jsem s výběrem součástek zamýšlel a kam to směřuje.

Smysl tohoto konkrétního zapojení - tlačítko - je ovládání relé dveří.
[spoiler=jen omáčka kolem]Velký a rozlehlý areál se spoustou kanceláří a vrátným který návštěvníky nasměroval.
V rámci úspor vrátný 24/7 zrušen a najímán jen na jednorázové akce, lidem se volalo na mobil a chodili otevírat.
Areál pokrytý jednotnou wifi, u vchodu elektronický dveřník Dahua se zvonky a čtečka karet.
Dahua je VoIP systém, nicméně pro otevření dveří je třeba mít u každé firmy v budově
- buď originální videoterminály (nehezká cena) které se dají zřetězit a otvírání pak funguje ze všech.
- nebo VoIP telefony které se zřetězit nedají a otevírání funguje jen z jednoho přes kód klávesnice.
Problém tedy vzniká u firem s více kancelářemi které nemají originál videoterminály.
Možná řešení -
1. chtít po Dahua aby opravila firmware aby odpovídal manuálu. Neschůdné.
2. vložit vlastní Asterisk ústřednu a snažit se do ní nahackovat originální videoterminály
3. nechat to být
Relé otevírání dveří se dá spínat několika zdroji - momentálně požární ústředna, karetní systém, Dahua dveřník.
tím se nabízí možnost
4. HomeAssistant buď s integrací Dahua, nebo jen nějaké wifi relé. Je jedno zda příchozí zavolá na mobil, nebo zazvoní Stačí pak stisknout tlačítko[/spoiler]

1. Regulátor HT7333 - do 250mA se vejdu i s volitelným 0.49" Oled displejem se kterým na desce počítám.
2. Měření baterie je stále přes ADC pin, jen je potřeba před měřením sepnout GPIO12 (T3) - Je to stále ten samý odporový dělič jen vypínaný aby nezatěžoval když není potřeba.

Co z toho pravděpodobně vznikne dál:
1. minimalizovaná verze jak součástkami tak velikostí pro použití jako tlačítko.
2. samostatný univerzální napájecí modul. Buď výstup před stabilizátorem, nebo nějaký nastavitelný dc/dc měnič. Mělo by to být použitelné s libovolným hotovým ESP modulem.
Osobně mám v úmyslu použít na vstupu 2uA PaPir senzor namísto tlačítka. Třeba pro Roode čítač osob, ESPcam nebo jiný typ žravého modulu ze kterého nepotřebuji výstup pokud není nikdo v okolí přítomen.
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

Uživatelský avatar
tiimsvk
Dárce - Donátor
Dárce - Donátor
Příspěvky: 801
Registrován: 06. květen 2021, 07:03
Dal poděkování: 72 poděkování
Dostal poděkování: 65 poděkování

Re: Tlačítko

Příspěvek od tiimsvk »

Ďakujem tato odpoveď mi uplne stači.
1. HT7333 som si objednal tak ako si mal link uplne v prvých príspevkoch, ale našiel som na nete aj podobny moul s označením ht7833, ktorý by mal zvladnuť vyšsie prúdy tak budem skúšať.
2. ADC som už jeden takto zapájal celkom slušná úspora, spravým teda samostatne vlakno na otazku ohladne merania baterie. snáď niekto odpovie :D

kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

Tak HT7333 je pro tento účel velký špatný.
Buď nepřežil flashování přes sériový převodník - měl napětí pouze na výstupu - některé LDO to nedávají.
Nebo nestíhá odběrové špičky a vypíná (a vykrýt to kondenzátory bych musel dávat opravdu velké kapacity.)
Podívám se na to zítra osciloskopem.

Tady je měření ESP8266 na 80MHz s běžícím ESPhome, WiFi a blikající LED
ppk-20221007T071502.png
A tady to samé bez wifi:
ppk-20221007T093055.png
Někde bych tu měl mít 50ks XC6206 od Torexu - což také není žádná výhra - ale měl by ustát 500mA špičky.
Protože při startu FW s ESPHome tam nastává toto:
ppk-20221007T094911.png
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

Uživatelský avatar
tiimsvk
Dárce - Donátor
Dárce - Donátor
Příspěvky: 801
Registrován: 06. květen 2021, 07:03
Dal poděkování: 72 poděkování
Dostal poděkování: 65 poděkování

Re: Tlačítko

Příspěvek od tiimsvk »

Tento problem mam aj ja. Bud to hreje ako blazen/žerie vela energie alebo vobec nenabehne esp. Pri esp8266 jak tak ale esp32 hmm.
Ten čínsky modul DD0603SA je tiež asi zla volba?

kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

Tak po menších úpravách je tlačítko funkční.

S diodou RB168VAM-30TR (jsou i s nižším Ir) se vejdu do 200nA stand-by
a velikostně menší, nicméně na desku dopasovatelný LDO Torex XC6206 (pouzdro značené 662K) - při 3.3V napětí LiPo je na ESP 3.1V

LEDka na GPIO14 (který musí být input) je zbytečná, nechal jsem ji tam omylem. - funguje inverzně k tlačítku a to jen díky vyššímu úbytku napětí (bílá nebo modrá). Zato mi chybí ovladatelná LED, k dispozici je jedině led na modulu, pověšená na GPIO2.

Testovací kód, shozením hold_on se tlačítko vypne.
Tlačítko změřit_baterii - sepne přes T3, T4 odporový dělič (klidně by mohly být hodnoty vyšší) a zavolá načtení ADC
ADC senzor po načtení hodnoty shodí, přes ON_Value opět T3,T4
Hodnotu jednoduše násobím, dala by se přes filtry udělat i přesnější kalibrace.

Kód: Vybrat vše

substitutions:
  device_name: tlacitko

esphome:
  name: tlacitko
  platform: esp8266
  board: esp12e
  platformio_options:
    board_build.f_cpu: 80000000L
  on_boot:
    # - priority: -100
    #   then: 
    #   - lambda: WiFi.mode(WIFI_OFF);
    - priority: 900
      then:
        lambda: |-
          // id(wake_up_reason) = esp_sleep_get_wakeup_cause();
          id(cpu_speed) = ESP.getCpuFreqMHz() ;


# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "294fVK6XAxWGYn5tnz2pQZMP4+ojX4xpbKjlG+uFa4Q="

ota:
  password: "24cbc70df060c727bac592e00bf1fea5"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: light
  fast_connect: true
  # manual_ip:
  #   static_ip: 192.168.199.131
  #   gateway: 192.168.199.1
  #   subnet: 255.255.255.0
  #   dns1: 192.168.199.2
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${device_name} Fallback Hotspot"
    password: "dfN8BKOvThhg"

captive_portal:

globals:
  - id: cpu_speed
    type: int
    restore_value: no
    initial_value: '0'
  - id: wake_up_reason
    type: int
    restore_value: no
    initial_value: '0'
  - id: pocet_stisku
    type: int
    restore_value: no
    initial_value: '1'

sensor:
  - platform: uptime
    name: Uptime Sensor
    id: time_since_boot
  - platform: template
    name: "Wake Reason"
    accuracy_decimals: 0
    lambda: |-
      return (id(wake_up_reason));
   # just to prove to myself that the clock has changed
  - platform: template
    name: "cpu speed"
    accuracy_decimals: 0
    lambda: |-
      return (id(cpu_speed));
  - platform: adc
    pin: A0
    id: bat
    name: "napětí baterie"
    accuracy_decimals: 2
    update_interval: never
    filters:
      - multiply: 4.2
    on_value: 
      - switch.turn_off: zmer_baterii
  - platform: template
    name: "počet stisků"
    id: stisku
    accuracy_decimals: 0
    lambda: |-
      return (id(pocet_stisku));
      
binary_sensor:
  - platform: gpio
    name: "${device_name} tlacitko"
    pin: 
      number: GPIO14
      inverted: false
      mode:
        input: true
        pullup: false
    on_press:
      then: 
        - lambda: |-
            id(pocet_stisku)++;
        - component.update: stisku
    # pripadne dalsi akce - https://esphome.io/components/binary_sensor/index.html#binary-sensor-on-click
  - platform: gpio
    name: "${device_name} usb_zapojeno"
    pin: 
      number: GPIO13
      inverted: false
      mode:
        input: true
        pullup: false

  
switch:
  - platform: gpio
    pin: GPIO15
    name: "${device_name} Hold on"
    restore_mode: ALWAYS_ON
  - platform: gpio
    pin:
      number: GPIO2 #nepouzivat 14 - shodi naapeti R13-R14 na 0.7V
      mode: output
    id: blueLED
  - platform: gpio
    name: "${device_name} změř"
    id: zmer_baterii
    pin: 
      number: GPIO12
      inverted: false
      mode:
        output: true
        pullup: false
    internal: true

interval:
  - interval: 500ms
    then:
      - switch.toggle: blueLED


button:
  - platform: template
    name: "${device_name} změř baterii"
    icon: "mdi:battery"
    on_press:
    - switch.turn_on: zmer_baterii
    - lambda: |-
        id(bat).update();
    # - delay: 500ms
    # - switch.turn_off: zmer_baterii

Přílohy
Snímek obrazovky 2022-10-10 063057.jpg
ppk-20221009T170411.png
ppk-20221009T170451.png
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

Uživatelský avatar
tiimsvk
Dárce - Donátor
Dárce - Donátor
Příspěvky: 801
Registrován: 06. květen 2021, 07:03
Dal poděkování: 72 poděkování
Dostal poděkování: 65 poděkování

Re: Tlačítko

Příspěvek od tiimsvk »

Keď to budeš mať vo finále myslim, že to bude veľká alfa a omega ďalších projektov pre fanúšikov na tomto fore.

Plánuješ obnoviť aj schemu zapojenia s uverejnenim tu? Ako si ju mal niekde na začiatku?

kiklhorn
Moderátor
Moderátor
Příspěvky: 901
Registrován: 03. červenec 2021, 18:35
Dal poděkování: 107 poděkování
Dostal poděkování: 210 poděkování

Re: Tlačítko

Příspěvek od kiklhorn »

DSC_1031.JPG
Problém se stabilizátorem pravděpodobně odhalen - klony útočí. https://chiptron.cz/articles.php?article_id=267

Video jak tlačítko aktuálně vypadá:

Odkaz na krabičku: https://www.printables.com/model/296369

Fotka:
DSC_1040 (1).JPG
Schema:
Snímek obrazovky 2022-10-16 075520.jpg
Snímek obrazovky 2022-10-16 075638.jpg
Stabilizátor lze použít i originál HT8733 nebo Torex XC6206 (pouzdro značené 662K) který přesně nesedí, ale dá se.

A pracovní verze kódu, budu ještě upravovat. Některé zapomenuté komentáře už nemusí platit, logických chyb tam snad moc není = na co jsem si vzpomněl tak jsem otestoval. A fórum si snad poradí i se znaky ikonek.

Kód: Vybrat vše

substitutions:
  device_name: thetlacitko
  hw_ver: "0.7"
  sw_ver: "0.2"

#  "The Tlačítko": Hardware: Napájení pro ESP8266 je spínáno přes high side mosfet s pomocnými obvody řešícími nabíjení, 
# měření napětí baterie (GPIO12 ovládá připojení odporového děliče), jeho výstup lze pak měřit na A0.
# detekci připojené nabíječky (GPIO13)
# detekci dalších stisků napájecího tlačítka (GPIO14)
# a především možnost vypnutí napájení (GPIO15) samotným ESP8266 
# GPIO4 a GPIO5 jsou využity pro I2C komunikaci 
# 1) s displejem 
# 2) externím RTC RV-3028-C7 (se spotřebou v řádech nA) pro další možnost zapnutí (není v této verzi SW implementováno)
#
# logika tlačítka:
# ----------------
# Fyzicky jde zapnout stiskem tlačítka. Start nějakou dobu trvá, tlačítko v okamžiku připojení k wifi+mqtt již nemusí být stlačené. Přesto musím dát vědět HA že tlačítko bylo stisknuto. Mělo by snad stačit MQTT s QOS=1
# Stav fyzického ftlacitko se zrcadlí do tlacitko(template), právě kromě startu, kdy je toto chování blokováno (viz globals) abych nebyl při programové simulaci prvního stisku rušen stavem fyzického ftlacitko.
#
# Při startu zkontroluji proč ESP vlastně startuje  
# - bylo zapnuto napájením  - odešle mqtt simulaci stisk tlačítka
# - probudilo se z deepsleep - nic neodesílá
# - restart po OTA - nic neodesílá
# 
# logika napájení:
# ----------------
# Zapnutí tlačítkem, senzorem, časovačem atd. Zapínací pulz musí být dostatečně dlouhý 
# - switch hold_on musím zapnout co nejdříve aby si napájení zachovalo i při uvolnění napájecího tlačítka  
# - D8 (GPIO15) použitý na "hold_on" by někde v této části zapojení snad mohl jít přidat kondenzátor aby mi podržel přes 110ms "glitch" původní stav https://rabbithole.wwwdotorg.org/2017/03/28/esp8266-gpio.html 
#
# Podmínky vypnutí:
# po vyhodnocení "logika tlačítka" a případném odeslání mqtt simulace tlačítka
# pokud
#     nechci flashovat (není nastavený mqtt topic ota_mode) 
#        a 
#     nejsem napájený z USB (binary senzor usb_zapojeno)
# hodím ESP na chvíli do deep_sleep kde je procesor vypnutý a JEN ZŮSTANE ZOBRAZOVAT poslední DISPLEJ (<10mA)
# po probuzení z deep_sleep zařízení vypnu shozením "switch hold_on"
#
# ota_mode - mqtt switch - definovaný v HA configuration.yaml, NE TADY! - tlačítko si jej samo vypne po skončení flashování
#
# displej 0.49" I2C SSD1306 64x32 - automatickou aktualizaci vypínám, aktualizuji především "ručně" na základě "on_value" u komponentů které na displeji zobrazuji
#
# font_ikony: 
# Preview https://pictogrammers.github.io/@mdi/font/7.0.96/
# Download: https://cdnjs.com/libraries/MaterialDesign-Webfont/7.0.96
#
##################################################### mqtt switch ota_mode - zapsat do configuration.yaml HA ################################
# mqtt:
#   switch:
#     - command_topic: "thetlacitko/ota"
#       state_topic: "thetlacitko/ota"
#       unique_id: thetlacitko_ota
#       name: "theTlacitko OTA Mode"
#       icon: "mdi:upload"
#       retain: true
############################################################################################################################################

esphome:
  name: ${device_name}
  platform: esp8266
  board: esp12e
  platformio_options:
    board_build.f_cpu: 80000000L
  on_boot:
    - priority: 900.0
      then:
        - lambda: |-
            // id(cpu_speed) = ESP.getCpuFreqMHz() ;
            // id(${device_name}_wake_up_reason) = esp_sleep_get_wakeup_cause(); //jen ESP32, pro ESP8266 nepoužitelné.
            id(wake_up_reason) = ESP.getResetInfoPtr()->reason; //hledal jsem řešení celý den. int. 4 - po OTA, 5- po deepsleep, 6- power_on

    - priority: 750.0
      then:
        # Přidržet napájení co nejdříve, tady už jsou piny inicializované, ale je to "pocitově -neměřeno- daleko dříve" než proběhne nastavení dle "restore_mode: ALWAYS_ON" u komponenty
        - switch.turn_on: ${device_name}_hold_on
        # Blokovat kopírování stavu z fyzického na template tlačítko - protože startuji tak se buď vypnu po deepsleep - tedy tlačítko mne nezajímá, nebo startuji po zapnutí a tedy musím nasimulovat stisk virtuálního programově
        # Odblokuji až 
        - globals.set: 
             id: blokovano_fyzicke_tlacitko
             value: '1'
        # inicializuji virtualni senzory pouzite jako vystupy stavu tlacitka
        - lambda: |-
            id(oneclick).publish_state(false);
            id(doubleclick).publish_state(false);
            id(clickhold).publish_state(false);
            
            
            
    - priority: 300.0 # vypnutí zařízení nebo okamzite zobrazeni display
      then:
        - if:
            condition:
              lambda: 'return ((id(wake_up_reason) == 5)||(id(wake_up_reason) == 4));' #teoreticky by stacilo !=6, ale nezkoumal jsem ostatní hodnoty.
            then: # //po deepsleep kdy se jen zobrazoval display vypni napájení (nebo po flashnutí)
              - switch.turn_off: ${device_name}_hold_on 
            else:      
              - component.update: ${device_name}_counter_stisku
              - switch.turn_on: ${device_name}_zmer_baterii
              - component.update: ${device_name}_bat
              - component.update: mydisplay
              - script.execute: inicializace
    # případná změna hesla pro OTA
    # - lambda: |-
    #     id(${device_name}_ota).set_auth_password("NoveOtaHeslo");


# Enable/disable logging
logger:
  deassert_rts_dtr: true
  baud_rate: 0
  level: NONE
  # level: VERY_VERBOSE #default jen debug

# Enable Home Assistant API
# API je pro věci s deep_sleep apod. nepoužitelné, půjdeme přes MQTT - request #46 otevřený od února 2019 https://github.com/esphome/feature-requests/milestone/2
# api:
#   encryption:
#     key: "294fVK6XAxWGYn5tnz2pQZMP4+ojX4xpbKjlG+uFa4Q="

ota:
  safe_mode: false
  password: !secret ota_password
  id: ${device_name}_ota
  on_end:
     then:
      - lambda: |-
          id(ota_mode) = 0;
      - mqtt.publish:
          topic: $device_name/ota
          payload: 'OFF'
          retain: true
      - component.update: mydisplay

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: NONE
  fast_connect: true
  manual_ip: #šetřím pár ms vynecháním DHCP
    static_ip: 192.168.199.230
    gateway: 192.168.199.1
    subnet: 255.255.255.0
    dns1: 192.168.199.2
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap: {}
    # Nechame ho jako device_name a bez hesla, jinak:
    # ssid: "${device_name} Fallback Hotspot"
    # password: "dfN8BKOvThhg"

captive_portal:
button:
  - platform: safe_mode
    name: "${device_name} Restart (Safe Mode)"

mqtt:
  id: mqtt_cli
  # broker: !secret broker 
  broker: !secret brokerip #šetřím pár ms vynecháním DNS
  username: !secret broker_user 
  password: !secret broker_pw
  discovery_object_id_generator: device_name
  # log_topic: null
  discovery: true
  reboot_timeout: 30s
  # birth necham default, will zakazu, u každého senzoru který chci vidět jako nedostupný pak musím nastavit availability topic ručně
  # pokud bych will nezakázal, nastaví availability topic automaticky - pro všechno - v rámci discovery 
  # birth_message:  
  will_message:

  on_message: #Zjistím stav HA MQTT switche povolujícího OTA
  - topic: $device_name/ota
    payload: 'ON'
    then:
      - lambda: |-
          id(ota_mode) = 1;
  - topic: $device_name/ota
    payload: 'OFF'  
    then:
      - lambda: |-
          id(ota_mode) = 0;

          
globals:
  - id: wake_up_reason
    type: int
    restore_value: no
    initial_value: '0' 
  - id: pocet_stisku
    type: int
    restore_value: no
    initial_value: '0'
  - id: ota_mode
    type: int
    restore_value: no
    initial_value: '0'
  - id: blokovano_fyzicke_tlacitko
    type: int
    initial_value: '1'
  - id: rucni_zakaz_spanku #asi pres drzeni tlacitka nebo neco podobneho TODO! 
    # 1) porovnam zda je drzeno fyzicke tlacitko jeste i v dobe kdy jsem pripojen na mqtt
    # 2) druhym dlouhym drzenim zase zarizeni vypnu
    type: int
    initial_value: '0'
    restore_value: False

script: #skript je vykonavan synchronne, narozdil od logiky komponent
  - id: inicializace
    mode: single
    then:
    - component.update: hw_version
    - component.update: sw_version
    - wait_until:  mqtt.connected
    - delay: 50ms
    - mqtt.publish:
            topic: "$device_name/status"
            payload: "online"
            retain: true
    - lambda: |-
        id(mqtt_cli).subscribe("$device_name/ota", [=](const std::string &topic, const std::string &payload) {
          id(ota_mode) = (payload.compare("ON") == 0);
        });
  #nasimuluji stisk tlacitka, o dalsi se postara samo ve svem on state kodu. 
        # Spoléhám se na to že MQTT si zprávy řadí do fronty a s nastaveným QOS1 je vždy odešle
        # Pokud by tohle bylo nespolehlivé tak 
        # to celé přepíšu logikou wait until subscribe payload = state || timeout - a když timeout tak párkrát opakuj nebo vyhodím chybu že mqtt nefunguje TODO!!!
        # Stavy odeslat jako Prostě vypnuto/zapnuto/vypnuto. Navíc k tomu musím potlačit případné "zapnuto" fyzického tlačítka (jen čekat dokud se neuvolní) předtím než povolím kopírování fyzické - virtual pokud by jej někdo ještě stále držel.
        # 

    - if: #CCekej dokud není při startu uvolněno fyzické tlačítko, ale minimálně 50ms než odešleš že bylo uvolněno.
        condition: 
          - binary_sensor.is_off: ${device_name}_ftlacitko
        then: # Pokud v tomto okamziku kdy uz jsem pripojen na mqtt uz neni drzeno tlacitko tak odeslu virtualni stisk, povolim kopirovani stavu (kdyby byl zakazany spanek) a pripadne se vypnu pres deepsleep 
          - delay: 50ms  #chvilku pockam, jinak se nic pres mqtt nestihne poslat pred usnutim
          - lambda: 
              id(${device_name}_tlacitko).publish_state(true); 
          - component.update: mydisplay
          - delay: 50ms
          - lambda: 
              id(${device_name}_tlacitko).publish_state(false); 
          - globals.set: #odblokuji kopírování stavu fyzického ftlacitko na tlacitko
              id: blokovano_fyzicke_tlacitko
              value: '0'
          - if:
              condition:
                - lambda: 'return id(spanek_povolen).state;'
              then:
              - delay: 150ms #Netuším jak zkontrolovat zda fronta mqtt zpráv je prázdná, raději počkám. Možná přes subscribe topic porovnat zprávu zpět? TODO!
              - deep_sleep.enter: spanek
        else: #Porad jeste drzim tlacitko, pockam nez ho pustim, povolim kopirovani stavu, zakazu spanek, a hlavnbe zadny virtualni stisk neodesilam 
          - wait_until:
              condition:  
                - binary_sensor.is_off: ${device_name}_tlacitko
          - globals.set:
              id: rucni_zakaz_spanku
              value: 'true'
          - globals.set:
              id: blokovano_fyzicke_tlacitko
              value: 'false'

interval: #Pokud jsem "on a nespavec" tak měř baterii každých 5s
  - interval: 5s
    then:
      - if:
          condition:
            - lambda: 'return id(spanek_povolen).state == false;'
          then:
          - switch.turn_on: ${device_name}_zmer_baterii
          - component.update: ${device_name}_bat
          # - switch.toggle: ${device_name}_blueLED

# HW a SW verze - pokud budu mít na síti více tlačítek tak mohu chtít OTA jen pro některé - přidat více ota přepínačů do HA a v tomto SW je detekovat
text_sensor:
  - platform: template
    name: "HW Version"
    id: hw_version
    lambda: 'return std::string("${hw_ver}");'
    update_interval: never
  - platform: template
    name: "SW Version"
    id: sw_version
    lambda: 'return std::string("${sw_ver}");'
    update_interval: never  

sensor:
  - platform: adc
    pin: A0
    id: ${device_name}_bat
    device_class: voltage
    name: "${device_name} napětí baterie"
    accuracy_decimals: 2
    unit_of_measurement: "V"
    update_interval: never
    filters:
      - multiply: 4.2
    on_value: 
      - switch.turn_off: ${device_name}_zmer_baterii
      - component.update: mydisplay
    # availability: 
    #   topic: "$device_name/status"
  - platform: template
    name: "${device_name} počet stisků"
    id: ${device_name}_counter_stisku
    icon: mdi:counter
    accuracy_decimals: 0
    lambda: |-
      return (id(pocet_stisku));
    unit_of_measurement: ""
    update_interval: never  
    # availability: 
    #   topic: "$device_name/status"    
  - platform: template
    name: "${device_name} Kdo mne budi"
    id: ${device_name}_kdo_mne_budi
    accuracy_decimals: 0
    lambda: |-
      return (id(wake_up_reason));
    # availability: 
    #   topic: "$device_name/status"      
  - platform: uptime
    device_class: duration
    name: ${device_name} Uptime Sensor
    id: ${device_name}_time_since_boot
    update_interval: 60s # 60s je default
    availability: 
      topic: "$device_name/status"    
  - platform: template
    name: "${device_name} procent baterie"
    id: bat_pct
    accuracy_decimals: 0
    unit_of_measurement: "%"
    device_class: battery
    lambda: return id(${device_name}_bat).state ;
    filters:
      - calibrate_polynomial:
         degree: 3
         datapoints:
          - 0.00 -> 0.0
          # - 2.97 -> 0.0 #umře
          # - 3.15 -> 0.0 #nestartuje občas spolehlivě
          - 3.20 -> 0.0
          - 3.28 -> 10.0
          - 3.33 -> 20.0
          - 3.40 -> 30.0
          - 3.48 -> 40.0
          - 3.57 -> 50.0
          - 3.65 -> 60.0
          - 3.72 -> 70.0
          - 3.80 -> 80.0
          - 3.88 -> 90.0
          - 4.15 -> 95.0
          - 4.20 -> 100.0
      - lambda: |-
          if (x <= 100) {
            return x;
          } else {
            return 100;
          } 
  - platform: wifi_signal
    id: wifisignal
    name: "WiFi Signal Sensor"
    update_interval: 1s # default 60s, neni nejlepší nápad nechat internal:false a nízký update interval - zbytečný provoz mqtt
    internal: true
    on_value: 
      then:
        - component.update: mydisplay
binary_sensor:
  - platform: gpio
    name: "${device_name} ftlacitko"
    id: ${device_name}_ftlacitko
    pin: 
      number: GPIO14
      inverted: false
      mode:
        input: true
        pullup: false
    filters:
      - delayed_on: 30ms
      - delayed_off: 30ms
    # pripadne dalsi akce - https://esphome.io/components/binary_sensor/index.html#binary-sensor-on-click
    # availability: 
    #   topic: "$device_name/status"
  - platform: template
    name: "${device_name} tlacitko"
    id: ${device_name}_tlacitko
    lambda: |- 
      if (id(blokovano_fyzicke_tlacitko) == 0) {
            return id(${device_name}_ftlacitko).state ;
          } else {
            return id(${device_name}_tlacitko).state;
          }
    on_press: #falling edge
      then:
        - component.update: mydisplay
    # on_click: #leading edge //tohle nejde pouzit v automatizacich HA, neexistuje on_click, musel by se navazat switch template - a vlastne proc ne - rozlisime akce podle click, double, triple... uvidim jak to pujde v kombinaci s prvnim simulovanym stiskem  = TODO!!!
    # to je ale kravina - na jeden double click jsou ZÁROVEŇ dva on click - musím na to jít přes multiclick.
    # on_click:
    #   # pocet stisku spise pri on_click presunout do kodu pro oneclick template switch
    #   # Togle vynechat pokud budu pouzivat on_press
    #   then: 
    #     - lambda: |-
    #         id(pocet_stisku)++; 
    #         id(oneclick).toggle(); 
    #     - component.update: ${device_name}_counter_stisku
    #     - component.update: mydisplay
    on_release: 
      then:
        - component.update: mydisplay
    # on_double_click:
    #   min_length: 50ms
    #   max_length: 350ms
    #   then:
    #     - lambda: 'id(doubleclick).toggle();' 
    #     # - switch.turn_off: ${device_name}_hold_on
    on_multi_click:
    - timing:
        - ON for at most 1s
        - OFF for at most 0.3s
        - ON for at most 1s
        - OFF for at least 0.2s
      then:
        - if: #reverzace prislusneho virtualniho vystupu, byt by vzdy mela byt false - vystup si stav temer okamzite obraci na false - simuluje button - zjednoduseni automatizaci
            condition: 
              - binary_sensor.is_on: doubleclick
            then: 
              - lambda: id(doubleclick).publish_state(false);
            else: 
              - lambda: id(doubleclick).publish_state(true);
                  
    - timing:
        - ON for at most 1s
        - OFF for at least 0.5s
      then:
        - if:
            condition: 
              - binary_sensor.is_on: oneclick
            then: 
              - lambda: id(oneclick).publish_state(false);
            else: 
              - lambda: id(oneclick).publish_state(true);


    - timing:
        - ON for at least 3s
      then: 
        - if:
            condition: 
              - binary_sensor.is_on: clickhold
            then: 
              - lambda: id(clickhold).publish_state(false);
            else: 
              - lambda: id(clickhold).publish_state(true);

    on_state: 
      then:
        - mqtt.publish: 
            topic: "${device_name}/binary_sensor/${device_name}_tlacitko/state"
            payload: id(${device_name}_tlacitko).state
            qos: 1    # Pokud stačí QOS 0 tak celý mqtt.publish blok lze vynechat
  - platform: gpio
    name: "${device_name} usb_zapojeno"
    id: ${device_name}_usb_zapojeno
    pin: 
      number: GPIO13
      inverted: false
      mode:
        input: true
        pullup: false
    availability: 
      topic: "$device_name/status"  
  - platform: template
    internal: false
    name: "${device_name} spánek povolen"
    id: spanek_povolen
    # publish_initial_state: True
    lambda: |-
      return (
        (id(${device_name}_usb_zapojeno).state == false) && !(id(ota_mode)) && (id(wake_up_reason) != 5 && !(id(rucni_zakaz_spanku))));
    on_press: 
      then:
        - deep_sleep.allow: spanek
        - component.update: mydisplay
    on_release: 
      then:
        - deep_sleep.prevent: spanek
        - component.update: mydisplay
    availability: 
      topic: "$device_name/status"

##################################### virtualni vystupy z tlacitka 

  - platform: template
    name: oneclick
    id: oneclick
    publish_initial_state: True
    on_press: 
      then:
        - lambda: id(pocet_stisku)++; 
        - component.update: ${device_name}_counter_stisku
        - component.update: mydisplay
        - delay: 150ms
        - lambda: id(oneclick).publish_state(false);
    
  - platform: template
    name: doubleclick
    id: doubleclick
    publish_initial_state: True
    on_press: 
      then:
        - delay: 50ms
        - lambda: id(doubleclick).publish_state(false);

  - platform: template
    name: clickhold
    id: clickhold
    publish_initial_state: True
    on_press: 
      then:
        - delay: 50ms
        - lambda: id(clickhold).publish_state(false);
        - if: 
            condition:
              - lambda: 'return id(rucni_zakaz_spanku);'
            then:
              - globals.set: 
                  id: rucni_zakaz_spanku
                  value: 'false'
              - component.update: mydisplay
              - delay: 50ms
              - deep_sleep.enter: spanek # mozna zakomentovat, nepujdeme rovnou, co kdyz je ota nebo usb? Ale pokud povazuji podrzeni za chtene vypnuti (logicke ?) tak vypnu rovnou nezavisle na ostatnich podminkach
            else:
              - deep_sleep.prevent: spanek
##############################################
switch:
  - platform: gpio
    pin: GPIO15
    name: "${device_name} Hold on"
    id: ${device_name}_hold_on
    restore_mode: ALWAYS_ON
  - platform: gpio
    pin:
      number: GPIO2 #nepouzivat 14 - shodi naapeti R13-R14 na 0.7V
      mode: output
    id: blueLED
    restore_mode: ALWAYS_OFF
  - platform: gpio
    name: "${device_name} změř"
    id: ${device_name}_zmer_baterii
    pin: 
      number: GPIO12
      inverted: false
      mode:
        output: true
        pullup: false
    internal: true
    restore_mode: ALWAYS_OFF
    availability: 
      topic: "$device_name/status"    

font:
  - file: "fonts/arial.ttf"
    id: pismo
    size: 14  
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: ikony
    size: 16
    glyphs: [

      # Wifi
      '󰤯', # F092F mdi-wifi-strength-outline
      '󰤟', # F091F mdi-wifi-strength-1
      '󰤢', # F0922 mdi-wifi-strength-2
      '󰤥', # F0925 mdi-wifi-strength-3
      '󰤨', # F0928 mdi-wifi-strength-4
      
      # Battery
      '󱃍', # F10CD mdi-battery-alert-variant-outline
      '󰁺', # F007A mdi-battery-10
      '󰁻', # F007B mdi-battery-20
      '󰁼', # F007C mdi-battery-30
      '󰁽', # F007D mdi-battery-40
      '󰁾', # F007E mdi-battery-50
      '󰁿', # F007F mdi-battery-60
      '󰂀', # F0080 mdi-battery-70
      '󰂁', # F0081 mdi-battery-80
      '󰂂', # F0082 mdi-battery-90
      '󰁹', # F0079 mdi-battery 100

      '󰢟', # F089F mdi-battery-charging-outline
      '󰢜', # F089C mdi-battery-charging-10
      '󰂆', # F0086 mdi-battery-charging-20
      '󰂇', # F0087 mdi-battery-charging-30
      '󰂈', # F0088 mdi-battery-charging-40
      '󰢝', # F089D mdi-battery-charging-50
      '󰂉', # F0089 mdi-battery-charging-60
      '󰢞', # F089E mdi-battery-charging-70
      '󰂊', # F008A mdi-battery-charging-80
      '󰂋', # F008B mdi-battery-charging-90
      '󰂅', # F0085 mdi-battery-charging-100

      # Button
      '󱊨', # mdi-gesture-tap-button
      '󰵷', # mdi-gesture-tap-hold
      '󰆙', # F0199 mdi-counter
      '󰺟', # F0E9F mdi-electric-switch
      '󱃙', # F10D9 mdi-electric-switch-closed
      '󰑊', # F044A mdi-record
      '󰻂', # F0EC2 mdi-record-circle
      '󰻃', # F0EC3 mdi-record-circle-outline
      '󰐽', # F043D mdi-radiobox-blank
      '󰐾', # F043E mdi-radiobox-marked


      # MQTT connection
      '󰌘', # F0318 mdi-lan-connect
      '󰌙', # F0319 mdi-lan-disconnect

      # OTA
      '󱍾', # F137E mdi-auto-download
      '󰇚', # F01DA mdi-download

      # Spanek
      '󰒲', # F04B2 mdi-sleep
      '󰒳', # F04B3 mdi-sleep-off



      ]
i2c:
  sda: GPIO4
  scl: GPIO5

display:
  - platform: ssd1306_i2c
    model: "SSD1306 64x32"
    # reset_pin: D0
    flip_x: false
    flip_y: false
    rotation: 180
    address: 0x3C
    id: mydisplay
    update_interval: never #normalne 1s, never = rucne
    lambda: |-
      int x, y, zmod;
      // Print time in HH:MM format
      // it.strftime(0, 0, id(pismo), "%H:%M", id(esptime).now());
      //  it.printf(0,20, id(pismo), "stisku: %g, %d", id(${device_name}_counter_stisku).state, id(wake_up_reason));
      //it.printf(0,20, id(pismo), "bat: %.2f V", id(${device_name}_bat).state);
      //it.printf(0, 18, id(ikony), id(${device_name}_tlacitko).state ? COLOR_ON : COLOR_OFF, TextAlign::TOP_LEFT, "%s", (id(mqtt_cli)->is_connected()) ? "󰌘" : "󰌙");

      it.printf(0, 18, id(ikony), id(${device_name}_tlacitko).state ? COLOR_ON : COLOR_OFF, TextAlign::TOP_LEFT, "%s", "󰐾" );
      it.print(30,19, id(ikony), TextAlign::TOP_LEFT,"󰆙");
      it.printf(63,18, id(pismo), TextAlign::TOP_RIGHT,"%g", id(${device_name}_counter_stisku).state);

      // ted oddelit linkou a vykreslit horni stavovy radek #####################################################################

      it.line(0, 16, 63, 16);

      //ikona stavu MQTT
      x = 17, y=0;
      it.printf(x, y, id(ikony), TextAlign::TOP_LEFT, "%s", (id(mqtt_cli)->is_connected()) ? "󰌘" : "󰌙");

      //ikona stavu OTA
      x=34, y=0;
      if (id(ota_mode)) {
          it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󱍾");
      } else {
          it.printf(x, y, id(ikony), TextAlign::TOP_LEFT, "%s", (id(spanek_povolen).state) ? "󰒲" : "󰒳");
      }


      // WiFi Signal Strenght 
      if(id(wifisignal).has_state()) {
        // it.printf(0,10, id(pismo), " %.0f db", id(wifisignal).state);
        x = 0, y = 0;
        if (id(wifisignal).state >= -50) {
            //Excellent
            it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󰤨");
          //  ESP_LOGI("WiFi", "Exellent");
        } else if (id(wifisignal).state  >= -60) {
            //Good
            it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󰤥");
          //  ESP_LOGI("WiFi", "Good");
        } else if (id(wifisignal).state  >= -67) {
            //Fair
            it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󰤢");
          //  ESP_LOGI("WiFi", "Fair");
        } else if (id(wifisignal).state  >= -70) {
            //Weak
            it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󰤟");
          //  ESP_LOGI("WiFi", "Weak");
        } else {
            //Unlikely working signal
            it.print(x, y, id(ikony), TextAlign::TOP_LEFT, "󰤯");
          //  ESP_LOGI("WiFi", "Unlikely");
        }
      }
      /**/
      
      /* Battery Voltage Discharging */
      if(id(bat_pct).has_state() && !(id(${device_name}_usb_zapojeno).state) ) {
        x = 63, y = 0;
        if (id(bat_pct).state >= 97) {
            // 100 %
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁹");
        } else if (id(bat_pct).state  >= 90) {
            // 90 %
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂂");
        } else if (id(bat_pct).state  >= 80) {
            // 80%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂁");
        } else if (id(bat_pct).state  >= 70) {
            // 70%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂀");
        } else if (id(bat_pct).state  >= 60) {
            // 60%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁿");
        } else if (id(bat_pct).state  >= 50) {
            // 50%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁾");
        } else if (id(bat_pct).state  >= 40) {
            // 40%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁽");
        } else if (id(bat_pct).state  >= 30) {
            // 30%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁼");
        } else if (id(bat_pct).state  >= 20) {
            // 20%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁻");
        } else if (id(bat_pct).state  >= 10) {
            // 10%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰁺");
        } else {
            // 0%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󱃍");
        }
      }
      /* Battery Voltage Charging */
      if(id(bat_pct).has_state() && (id(${device_name}_usb_zapojeno).state)) {
        x = 63, y = 0;
        if (id(bat_pct).state >= 97) {
            // 100 %
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂅");
        } else if (id(bat_pct).state  >= 90) {
            // 90 %
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂋");
        } else if (id(bat_pct).state  >= 80) {
            // 80%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂊");
        } else if (id(bat_pct).state  >= 70) {
            // 70%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰢞");
        } else if (id(bat_pct).state  >= 60) {
            // 60%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂉");
        } else if (id(bat_pct).state  >= 50) {
            // 50%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰢝");
        } else if (id(bat_pct).state  >= 40) {
            // 40%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂈");
        } else if (id(bat_pct).state  >= 30) {
            // 30%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂇");
        } else if (id(bat_pct).state  >= 20) {
            // 20%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰂆");
        } else if (id(bat_pct).state  >= 10) {
            // 10%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰢜");
        } else {
            // 0%
            it.print(x, y, id(ikony), TextAlign::TOP_RIGHT, "󰢟");
        }
      }
deep_sleep: # spánek je využit jen na to aby chvíli zůstaly zobrazené údaje na displeji před shozením napájení
  id: spanek
  run_duration: 30s
  sleep_duration: 2s

Video je v reálném čase, nejdéle trvá připojení k wifi.
Na plánované použití - dálkové otvírání dveří v areálu - je to dostatečně - nižší jednotky sekund - rychlé.
Na doma přemýšlím že se pustím do zkoumání možností ESPnow a případně zda výměna ESP8266 za ESP32C3 by také trochu nepomohla.
Vše co si přinesu domů je buď Shelly, nebo to skončí buď pod ESPhome nebo pod Zigbee2mqtt.
Ajťák co pamatuje BBS a OS/2 Warp a je mu jedno o jaký systém nebo síťařinu běží.
HA OS jako jedna z Proxmox VM na Odroid H3+/64GB https://github.com/tteck/Proxmox

Odpovědět

Zpět na „ESPHome“