Acasă
Despre
Cautare
🌐
English Română
  • Slider in Tasmota folosind BerryScript

    Read this post in English

    Nov 10, 2024 Tasmota BerryScript homeassistant
    Share on:

    Inroducere

    Am cumpărat de curând un șemineu care poate distribui căldură și la radiatoare (pe scurt: termoșemineu). Pentru a face asta, folosește o pompă de recirculare.

    Pompa ar trebui să pornească când apa atinge o anumită temperatură și să se oprească atunci când scade sub o anumită valoare. Deloc complicat până aici, sistemul folosind un termostat simplu care a funcționat acceptabil:

    termostat cu bratara

    Erau totuși câteva neajunsuri, cum ar fi faptul că nu făcea contact destul de bine cu țeava de căldură, așa că trebuia să pornească puțin mai repede decat ar fi trebuit, ca să compenseze. Pentru că era configurat dintr-o singură setare comună, asta însemna că se și oprea un pic cam târziu, deci nu puteam configura setările cu ușurință.

    O altă dorință de-a mea era ca dispozitivul să poată funcționa independent. Dacă se deconectează de la rețea dintr-un motiv oarecare, sau Home Assistant nu mai funcționează, ar trebui să pornească singur ca să nu ajungă să fiarbă apa din instalație. Să zicem că nu vreau să explodeze doar de dragul de a arată cool. Și încă un lucru: ar fi drăguț să se oprească singur, ca să nu recircule apă degeaba.

    Sonoff TH Elite cu senzor de temperatură pare să acopere perfect toate cerințele, chiar are în plus și un ecran simpatic pe care se poate vedea temperatura apei. Trebuie să clarific că, din păcate pentru mine, nu sunt sponsorizat pentru acest proiect, iar dispozitivul a fost cumpărat din banii mei.

    Sonoff TH Elite

    Totul era perfect, cu excepția unui singur detaliu: nu am găsit un mod de a adauga cu ușurință un slider pentru a controla temperatura. Aș fi putut hardcoda valorile, pentru că în principiu nu ar fi trebui să se schimbe în timp, dar atunci nu aș mai avea cu ce sa mă laud.

    Și așa a început aventura...

    Să trecem la treaba

    Dispozitivul

    Nu o să vorbesc despre pregătirea dispozitivului, sunt destule tutoriale despre flashing Tasmota. Codul ar trebui să funcționeze cu orice dispozitiv care rulează Tasmota, de fapt întreg codul din acest tutorial a fost scris și testat pe un controller generic Esp32 găsit într-un sertar.

    Berry script

    Dacă ai ajuns până aici, probabil că nu ți-ai ars nici controllerul Esp, nici casa. Felicitări, ai trecut cu succes de partea cea mai dificilă!

    Toată magia vine de la Berry Script, un limbaj de scripting care permite extinderea funcționalităților Tasmota.

    Din păcate, documentația nu este foarte clară când vine vorba de componente noi și există un singur exemplu. Există și un exemplu complet, dar este foarte complex și greu de urmărit.

    Dar să începem. În primul rând, trebuie să facem un fișier nou care va conține codul. Pentru a face asta, conectează-te la UI-ul dispozitivului folosind IP-ul lui și mergi la Tools > Manage File system și apasă pe Create and Edit new file.

    Introdu numele fișierului sus autoexec.be, șterge conținutul fișierului și apasă pe Save. Din acest punct vom edita doar acest fișier. Când mă voi referi la editat, mă voi referi la acest fișier.

    Că să ne asigurăm că fișierul se compilează, din meniul principal (Main Menu), mergi la Tools > Berry Scripting console.

    Introdu load('autoexec.be') și apasă pe Run code (or press ‘Enter’ twice). Ar trebui să fie afișat output-ul true.

    Executie cod

    Setarea componentei

    Editează autoexec.be și introdu codul de mai jos care reprezintă o componentă de baza:

     1import webserver
     2
     3class MySlider
     4  def web_add_main_button()
     5    webserver.content_send("<div style='padding:0'><h3>Set pump temperature</h3></div>")
     6  end
     7end
     8
     9
    10d1 = MySlider()
    11tasmota.add_driver(d1)
    

    Reîncarcă UI-ul folosind comandăload('autoexec.be'), așa cum a fost descris mai sus.

    În acest moment ar trebui să apară pe ecran textul Set pump temperature.

    Setarea temperaturii

    Se pare că primul secret a ieșit la iveală, trebuie doar să afișăm niște HTML pentru a genera o nouă componentă.

    Ne mai lipsește un lucru, trebuie să salvăm valoarea care se setează folosind slider-ul. Din fericire, lucrurile sunt destul de simple dacă folosim librăria persist. Putem seta și o valoare implicită atunci când componentă se încarcă prima dată:

    1  def init()
    2    if (!persist.m_start_temp)
    3        persist.m_start_temp = 55
    4    end
    5
    6    if (!persist.m_stop_temp)
    7      persist.m_stop_temp = 50
    8    end
    9  end
    

    Acum avem valori implicite de start și stop pentru temperatura.

    Pentru că am nevoie de două valori, una de pornire și una de oprire, voi face o funcție care poate afișa fie una din valori, fie pe cealaltă, iar valoarea se va trimite folosind webserver.content_send, deci acum metodă web_add_main_button() va deveni:

    1  def web_add_main_button()
    2    webserver.content_send("<div style='padding:0'><h3>Set pump temperature</h3></div>")
    3    webserver.content_send(
    4      self._render_button(persist.m_start_temp, "Start", "start")
    5    )
    6    webserver.content_send(
    7      self._render_button(persist.m_stop_temp, "Stop", "stop")
    8    )
    9  end
    

    Argumentele sunt: valoarea curentă, o etichetă și un id. Prin id se va identifica elementul care s-a schimbat.

    Metodă pentru afișare este:

     1  def _render_button(persist_item, label, id)
     2    return "<div style='padding:0'>"+
     3        "<table style='width: 100%'>"+
     4          "<tr>"+
     5            "<td><label>"..label.." </label></td>"+
     6            "<td align=\"right\"><span id='lab_"..id.."'>"..persist_item.."</span>°C</td>"+
     7          "</tr>"+
     8        "</table>"+
     9        "<input type=\"range\" min=\"20\" max=\"70\" step=\"1\" "+
    10          "onchange='la(\"&m_"..id.."_temp=\"+this.value)' "+
    11          "oninput=\"document.getElementById('lab_"..id.."').innerHTML=this.value\" "+
    12          "value='"..persist_item.."'/>"+
    13      "</div>"
    14  end
    

    oninput este un artificiu pentru a schimba valoarea afișată când sliderul se mișcă, așa compensăm pentru faptul că elementul slider din html nu are un mod de a afișa valoarea selectată, așa că nu am ști ce a fost selectat până nu oprim selecția, adică ar fi o experiență neplacută de utilizare.

    De fapt onchange se folosește pentru a schimba valoarea, iar această folosește un pic de magie Tasmota.

    Acum că afișăm totul, avem nevoie de un mod de a persista valoarea, acest lucru se face folosind metodă web_sensor:

     1  def web_sensor()
     2
     3    if webserver.has_arg("m_start_temp")
     4      var m_start_temp = int(webserver.arg("m_start_temp"))
     5      persist.m_start_temp = m_start_temp
     6      persist.save()
     7    end
     8
     9    if webserver.has_arg("m_stop_temp")
    10      var m_stop_temp = int(webserver.arg("m_stop_temp"))
    11      persist.m_stop_temp = m_stop_temp
    12      persist.save()
    13    end
    14
    15  end
    

    Deja putem pune totul cap la cap, avem tot ce era necesar. Totuși mai este ceva ce-mi doresc: să pot vedea valoarea selectată în Home Assistant (dacă este folosit). În caz că am uitat ce este setat, ar fi interesant să afișăm valoarea undeva prin Home Assistant. Pentru a exporta valorile trebuie implementat json_append:

    1  def json_append()
    2    var start = int(persist.m_start_temp)
    3    var stop = int(persist.m_stop_temp)
    4    var msg = strîng.format(",\"Pump\":{\"start\":%i,\"stop\":%i}", start, stop)
    5    tasmota.response_append(msg)
    6  end
    

    Acum chiar avem un exemplu complet! Să-l vedem:

     1import webserver
     2import persist
     3import strîng
     4
     5class MySlider
     6
     7  def init()
     8    if (!persist.m_start_temp)
     9        persist.m_start_temp = 55
    10    end
    11
    12    if (!persist.m_stop_temp)
    13      persist.m_stop_temp = 50
    14    end
    15
    16  end
    17 
    18  def web_add_main_button()
    19    webserver.content_send("<div style='padding:0'><h3>Set pump temperature</h3></div>")
    20    webserver.content_send(
    21      self._render_button(persist.m_start_temp, "Start", "start")
    22    )
    23    webserver.content_send(
    24      self._render_button(persist.m_stop_temp, "Stop", "stop")
    25    )
    26  end
    27
    28  def _render_button(persist_item, label, id)
    29    return "<div style='padding:0'>"+
    30        "<table style='width: 100%'>"+
    31          "<tr>"+
    32            "<td><label>"..label.." </label></td>"+
    33            "<td align=\"right\"><span id='lab_"..id.."'>"..persist_item.."</span>°C</td>"+
    34          "</tr>"+
    35        "</table>"+
    36        "<input type=\"range\" min=\"20\" max=\"70\" step=\"1\" "+
    37          "onchange='la(\"&m_"..id.."_temp=\"+this.value)' "+
    38          "oninput=\"document.getElementById('lab_"..id.."').innerHTML=this.value\" "+
    39          "value='"..persist_item.."'/>"+
    40      "</div>"
    41  end
    42
    43 
    44  def web_sensor()
    45
    46    if webserver.has_arg("m_start_temp")
    47      var m_start_temp = int(webserver.arg("m_start_temp"))
    48      persist.m_start_temp = m_start_temp
    49      persist.save()
    50    end
    51
    52    if webserver.has_arg("m_stop_temp")
    53      var m_stop_temp = int(webserver.arg("m_stop_temp"))
    54      persist.m_stop_temp = m_stop_temp
    55      persist.save()
    56    end
    57
    58  end
    59
    60  def json_append()
    61    var start = int(persist.m_start_temp)
    62    var stop = int(persist.m_stop_temp)
    63    var msg = strîng.format(",\"Pump\":{\"start\":%i,\"stop\":%i}", start, stop)
    64    tasmota.response_append(msg)
    65  end
    66end
    67
    68slider = MySlider()
    69tasmota.add_driver(slider)
    

    Este destul de mult cod, dar sper că nu este foarte greu de înțeles.

    Setarea automatizării

    Acum că avem valorile, putem seta automatizarea efectivă. Regulile sunt foarte simple:

    • când se atinge temperatura de start => pornește pompa;
    • când temperatura coboară sub valoarea de oprire => oprește pompa.
     1def heater_control(value) 
     2
     3  if value >= persist.m_start_temp
     4	  tasmota.set_power(0, true)
     5  end
     6  
     7  if value < persist.m_stop_temp
     8	  tasmota.set_power(0, false)
     9  end
    10end 
    11# această este specifică senzorului Sonoff TH Elite
    12tasmota.add_rule("DS18B20#Temperature", heater_control)
    

    Dacă s-a folosit alt dispozitiv, este posibil să aibă alt nume față de "DS18B20#Temperature", și probabil va trebui schimbat cu cel potrivit.

    Noua interfață Sonoff TH Elite ar trebui să arate cam așa:

    Tasmota Sonoff TH Elite

    Concluzie

    Folosind cod destul de simplu, poți transforma un dispozitiv inteligent (dar nu foarte interesant) în ceva cu care să te poți lăuda la prieteni. Valorile se pot seta acum cu ușurință într-o manieră vizuală, iar rezultatul se poate vedea în Home Assistant.

  • Cum sa folosesti Xiaomi Air Conditioning Companion in Home Assistant in doar de 20 pasi usor de urmat!

    Read this post in English

    Oct 13, 2019 homeassistant
    Share on:

    Xiaomi Air Conditioning Companion si Home assistant

    Pasul 1:

    Cumpara un Xiaomi Air Conditioning Companion fara sa te uiti prea in detaliu cat de bine se integreaza cu Home Assistant.

    Pasul 2:

    Realizeaza ca, în China, priza de 16A este diferita de cea de 10A.

    Pasul 3:

    Da-ti seama ca nimeni nu vinde in Romania adaptoare de la 10A la 16A pentru China.

    Pasul 4:

    Cumpara un stecher de 16A din China.

    Pasul 5:

    Asteapta cam 2 luni sa ajunga din China atat adaptorul cat si dispozitivul.

    Pasul 6:

    Realizeaza ca nimeni nu vinde nici adaptor pentru priza la schuko.

    Pasul 7:

    Gaseste singurul comerciant care vinde modul de priza pentru priza chinezeasca, probail din greseala

    Pasul 8:

    Asteapta sa te caute comerciantul si sa-ti spuna ca dureaza cam o luna sa livreze modulul.

    Pasul 9:

    Asteapta cam o luna ca sa fie livrat modulul.

    Pasul 10:

    Instaleaza modulul de priza si stecherul.

    Pasul 11:

    Conecteaza Xiaomi Air Conditioning Companion la priza si aerul conditionat la Companion pentru prima data.

    Pasul 12:

    Realizeaza ca Xiaomi Mi Home App a fost updatat intre timp si nu exista niciun tutorial functional care sa-ti arate cum sa obtii parola pentru Home Assistant.

    Pasul 13:

    Gaseste un mod de a lua parola, dupa multe incercari.

    Pasul 14:

    Adauga parola de la pasul anterior in Home Assistant si constata ca singurul lucru pe care-l poti face din Home Assistant este sa suni alarma si sa-i schimbi volumul.

    Pasul 15:

    Gaseste modulul xiaomi_airconditioningcompanion si realizeaza ca de fapt nu aveai nevoie de parola gatewayului.

    Pasul 16:

    Fa downgrade la Xiaomi Mi Home App si obtine tokenul urmarind instructiunile de la: https://www.home-assistant.io/integrations/vacuum.xiaomi_miio#retrieving-the-access-token

    Pasul 17:

    Da-ti seama ca nu ai versiunea potrivita de Hass.io pentru a folosi modulul.

    Pasul 18:

    Migreaza la Hassbian de la Hass.io

    Pasul 19:

    In sfarsit, instaleaza extensia si seteaza modulul.

    Pasul 20:

    Singurul lucru care mai ramane de facut este sa te bucuri de confortul oferit de controlatul aerului conditionat de la cativa metri distanta, fara a avea nevoie de telecomanda!

Claudiu Perșoiu

Programare, tehnologie și altele
Mai multe

Postări recente

  • 30 de ani de PHP
  • Slider in Tasmota folosind BerryScript
  • Proiectul care rezista probei timpului
  • Docker in interiorul wsl2
  • Migrând de la Wordpress
  • Calea personalizată pentru Composer cache
  • Magento2 si crudul adevar
  • Un pic de PHP, Go, FFI si atmosfera de sarbatori

DIVERSE 72 PHP 68 JAVASCRIPT 22 BROWSERS 12 MYSQL 12 WEB STUFF 12 MAGENTO 7 DESIGN PATTERNS 5 HARDWARE 3 HOME AUTOMATION 2 LINUX-UNIX 2 GO 1 MISCELLANEOUS 1

PHP 53 JAVASCRIPT 20 PHP5.3 14 MYSQL 13 PHP6 12 PHP5 10 FIREFOX 9 CERTIFICARE 8 INTERNET EXPLORER 8 ZCE 8 ZEND 8 CERTIFICATION 7 MAGENTO 7 HACK 6
Toate etichetele
10 ANI1 3D1 ADOBE AIR2 AJAX1 ANDROID3 ANGULAR1 ANONYMOUS FUNCTIONS3 API1 APP1 BERRYSCRIPT1 BETA1 BOOK1 BROWSER4 C2 CALCULATOARE1 CARTE2 CERTIFICARE8 CERTIFICATION7 CERTIFIED2 CERTIFIED DEVELOPER1 CHALLENGE1 CHM1 CHROME1 CLASS1 CLI2 CLOSURES5 COD1 CODE QUALITY1 CODEIGNITER3 COFFEESCRIPT1 COLLECTIONS1 COMPOSER1 CSS3 CSV1 CURL1 DEBUG1 DESIGN PATTERNS4 DEVELOPER1 DEVELOPMENT TIME1 DIAGRAME1 DOCKER2 DOCKER-COMPOSE1 DOUGLAS CROCKFORD3 DRIVERE2 ELEPHPANT2 ENGINEER1 EXAMEN1 EXCEL1 FACEBOOK2 FEEDBACK1 FFI1 FINALLY1 FIREFOX9 FISIERE1 FPDF1 FRUMOS1 FTP1 GAMES1 GD2 GENERATOR1 GO1 GOOGLE5 GOOGLE ANALYTICS1 GOOGLE CHROME3 GOOGLE MAPS2 HACK6 HARDWARE1 HC-911 HEADER1 HEIGHT1 HOMEASSISTANT2 HTML2 HTML HELP WORKSHOP1 HTML51 HUG1 HUGO1 IDE1 IMAGINE1 INFORMATION_SCHEMA1 INI1 INTERNET4 INTERNET EXPLORER8 IPV41 IPV61 ISP1 ITERATOR2 JAVA1 JAVASCRIPT20 JQUERY1 LAMBDA2 LAPTOP2 LINUX1 LIVELY1 LUNI1 MAGENTO7 MAGENTO22 MAP1 MAPS1 MICROSOFT1 MINESWEEPER1 MOTIVATION1 MSN MAPS1 MYSQL13 MYSQL WORKBENCH1 NGINX1 NODE.JS2 NOFALLOW1 NOSQL1 OBSERVER3 OBSERVER PATTERN1 OOP1 OPERA1 OPTIMIZATION1 ORACLE2 PAGESPEED1 PAIR1 PARSE_INI_FILE1 PASCAL1 PEAR1 PECL1 PERSON VUE2 PHAR1 PHONEGAP2 PHP53 PHP ELEPHANT2 PHP FOR ANDROID1 PHP-GTK1 PHP42 PHP510 PHP5.314 PHP5.46 PHP5.53 PHP5.61 PHP612 PHP7.41 POO1 PR1 PROGRAMMING1 PROIECTE1 RETEA1 REVIEW1 ROCK STAR1 ROMANIAN STEMMER2 RSS1 SAFARY1 SCALAR TYPE HINTING1 SCHEME1 SEO1 SET1 SHOPPING CART PRICE RULE1 SIMPLEXML1 SINGLETON1 SOAP2 SPL2 SQLITE1 SSH1 STACK TRACE1 STDERR1 STDIN1 STDOUT1 STOCATE1 STUDY GUIDE1 SUN2 SYMFONY2 TABLE1 TASMOTA1 TEST TO SPEECH1 TITANIUM2 TRAITS1 TTS1 UBUNTU1 UNICODE3 UTF-82 VECTOR1 VISTA2 WEB2 WEBKIT1 WINBINDER1 WINDOWS2 WORDPRESS1 WSL21 WYSIWYG1 XP3 YAHOO3 YAHOO MAPS2 YAHOO OPEN HACK1 YSLOW1 YUI1 ZCE8 ZCE5.31 ZEND8 ZEND FRAMEWORK4
[A~Z][0~9]

Copyright © 2008 - 2025 CLAUDIU PERȘOIU'S BLOG. Toate drepturile rezervate