Created
October 30, 2019 23:51
-
-
Save saper-2/e5491caf993999bbc509dedfba29679c to your computer and use it in GitHub Desktop.
Jak sie dogadac z tasmota przez http
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta charset="UTF-8"> <!-- kodowanie UTF-8 tego pliku teksotwego --> | |
<!-- sciągnij z https://jquery.com/download/ najnowszy "compressed, production jQuery x.y.z" , | |
wrzuć sciągnięty plik 'jquery-x.y.z.min.js' do tego samego katalogu co ten plik html. | |
Ah, jak klikniesz "Download ...." to otworzy się strona z "tekstem" - po prostu uzyj Plik->Zapisz aby zapisać 'jquery-x.y.z.min.js' :) | |
Dla innych ludzi którzy dotrą do tego :) : popraw wersję jquery jak będziesz ściągał ("x.y.z" to będzie numer wersji) w tagu poniżej "script src=...." | |
--> | |
<script type="text/javascript" src="jquery-3.4.1.min.js"></script> | |
<script> | |
var images = [ | |
// off | |
"data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAAKLSURBVFhHzZituqMwEIbPxdWgUKgoFAZVhUJVYaqiuIAqVA2qCoVCYapQqKqqVd8OCbQEJkB/nt0jXsHkm8w0TMKkPwB+BaxxK21bo8hz5JcKTduSiddtgTXauBYpDoEHZ7fDzobjwt9LnKvXEmONU5pzDOEwQddwQ8hiW0Ks8UGTI/aYAC/iBBLljWbkYvSwxo7bJYbHTPo+PmT9h6bm47HGex4t18HbCBwtycwMKOOVJBwIKsasqElu+tZUzEkoVvwF5LVzNX2NB9xzRAtF6cVnko30Nm4lZOCycyiEJJnpYzyUscM70q9IqjtJTOc1miy0ro5/MnfT07FN4TMOtqXcirXenAi5+m1a93AoLKsRZq+vxJQq8di5/fS5Kr24QMzVhp8+hJ9hmX9UK1po2Snh+fPVGLhKMZu/O1tO/UGnRA0roneoNPzEL3OVELMYO0Q6iE4kj+aCnX9Sgu9Rsq9H6J2wkIhOdTLZZ0gxj+MmFQ39gkSGOErwPxMxXg17onpHJfgeF0TTGISQDQ33idxO/kww3lpfoUrgzmI4iEsapXEtsmyt8cn3KfzJHUIfVUMiqHHkOjH6HlxG34O3aU/8dyx8fs0f4jblXg+1eV8oWna3dK+loNFe83RY6EWGyn6HPLK0FpOexHBq2aLViERVlaFfI9vbmqNnkQ4Yjh38Mva4wabrwZWuH0uNtxNdSGb6GA+KlXZR4XgI9gnS7pY3kEkcQn+lXyWYNrFjZlA0GcK1ZN5BJNAd5zzmzPDgTs3MFy5XA06QQt8kmFgEaxxTyoA5EV/BQ3zWx/gSrHHGrUYWr91XprgIDhuvHwRrXEJdovYBPHd6PjhwXR/h4fV/AjpY478HP38BbMa1la/cOikAAAAASUVORK5CYII=", | |
// on | |
"data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAACySURBVFhH7dghDsJAFIThHm5NFaoKVdUroKpW4fcMVaiaHgBVVcUVqjgA6rGBpCHTSfYFQRAjPjP7xK+3MrOvPdbFxhQtptFu97yQGy86uixna0KwsOnssuYXdutAR4+h/Yx4q/s5P/H7Ejp6pOM+JJym/MTvS+jooRCkEKQQpBCkEKQQpBCkEKQQpBCkEKQQpBD0NyFzX+9C2uH1HUDvS+joNXSHLaKJ1zzxOw86/p5VTyt4wvYCakmwAAAAAElFTkSuQmCC", | |
// toggle | |
"data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAAKvSURBVFhHzZetlrMwEIZ7cRhUFCoKhYmqQqGqMFVRXEAVqgaFqlpVVVPFBaxCVc1O+Ck/eUOB/c6eTzx7tpN3JkMyk8CBiHZzKwoqeso7m7BuDdDo4padKAp88jxvET9UlObbEoPGOddEkg8m/IwgpW8cAscdA409VZFQACfYiB+RvtccEs9jgEZDmQQ46C8I9YND4/mgsYg/18FeZIprxzKUK5IQUUI6t/e+zFJS8rO/1E/Ld/KjLuLFogySnGXTAIhXVdI5EjBGi6Rzk8vgMwSoS4p95GSQlH59s2xwXEOVK/eDSc2SQfv+53F2FaekdiUHp57i3damTfHeL62yug6d9HZI4Gr4FBe47VDi48Bjnlpa2obgzMOtpvlTXxUU+nHxFs7R0tZ7W/W8km0TdYlcFRK5t8SwNRG6JXCLRNfOjQhuS3hpBC42J8LAebqiPVClSc4HmaDtLxjQsCeRIgY+XkxlI3ie4X3SxrSD9exJBBetopxr/EDcXvbgXybS1uKByv8lkSeuEWXWaxZozK5E4KEZk/Hioz0nZQ3yGZJ88bAdrGdPIpcQ+IiUh7r2hUE7gYvNiTge2FPtRdqI7im6Kd3Hu2FrIq5jPry0l2krfOAW9gL3qsBljs2JAPSu1fBCavPoE2EyFJhx3Tc1d9v0yHZfCXD1mHHst3jpuna93n0/ckrjmOKTprJ6scnW5Mr1xjZNfOaEHFpElLFk0K7h7Fhlw7wrJ45UFwtvaYaAjtpRByPyU0gC+neA2pv8aHAccHN8EZIy29JzjChYfIgeXEuTHz01vzv8kw8ri9BZ0Jah5/XIKFr1hCsJ+CivODKYywCNY66//uITFOnl68IAjXPMd4o+bv0Q90mu/A4yQOMS9zKj1BSmELPEfBJNAaeU3ZpCgP4uoPHvocMPLKszn7THokoAAAAASUVORK5CYII=" | |
]; | |
//http://<espeasyip>/control?cmd=<command> | |
// globalne zmienne | |
// adres espEasy | |
var espip = "192.168.2.155"; | |
function get_power_status(ip) { | |
// sprawdzmy czy argumenty nie są "null" (czyli funkcja zostałą wywołana bez przekazanych argumentów) | |
if (typeof(ip) === "undefined") return; | |
// dodatkowe sprawdzenie | |
// ajax request | |
// zwróć uwagę na sposób zapisu funkcji które są wywoływane po request'cie | |
$.ajax({ | |
url: "http://"+ip+"/cm?cmnd=Power0", | |
dataType: "json" // spodziewamy się odpowiedzi w fomracie json | |
}) // <<-- tutaj nie ma średnika, ponieważ chcemy aby zostały wywołane funkcje w done lub fail :) | |
// to jest wywoływane jeśli request się udał (http result code = 200) | |
.done(function(data) { | |
// ustawmy zawartość tagu ze statusem | |
// debug, uzyteczne jak nie jestes pewien co dostajesz :) , mozesz uzyc Developers Tools i tam krok po kroku | |
// analizować skrypt JS i podglądać jakie są dane w jakich zmiennych ^u^ | |
//console.log("Status led: "); | |
//console.log(data); | |
if (typeof(data.POWER1) != "undefined") update_relay_status(1, data.POWER1); else update_relay_status(1, "?"); | |
if (typeof(data.POWER2) != "undefined") update_relay_status(2, data.POWER2); else update_relay_status(2, "?"); | |
if (typeof(data.POWER3) != "undefined") update_relay_status(3, data.POWER3); else update_relay_status(3, "?"); | |
if (typeof(data.POWER4) != "undefined") update_relay_status(4, data.POWER4); else update_relay_status(4, "?"); | |
}) | |
// jeśli będzie jakiś błąd (e.g. brak urządzenia , zły IP, etc...) to to się wykona: | |
.fail(function(jqxhr, text, err) { | |
console.log("AJAX query error! text="+text+" , error="+err); | |
console.log(jqxhr); | |
$("#led-status").html("ERROR: "+text); | |
// zmieniamy kolor :) | |
$("#led-status").css("background-color","#ff4000"); | |
}) | |
; // tutaj jest koniec definicji .ajax(.........) | |
} | |
function get_sensor_bme280(ip) { | |
// sprawdzmy czy argumenty nie są "null" (czyli funkcja zostałą wywołana bez przekazanych argumentów) | |
if (typeof(ip) === "undefined") return; | |
// dodatkowe sprawdzenie | |
// ajax request | |
// zwróć uwagę na sposób zapisu funkcji które są wywoływane po request'cie | |
$.ajax({ | |
url: "http://"+ip+"/cm?cmnd=Status 8", | |
dataType: "json" // spodziewamy się odpowiedzi w fomracie json | |
}) // <<-- tutaj nie ma średnika, ponieważ chcemy aby zostały wywołane funkcje w done lub fail :) | |
// to jest wywoływane jeśli request się udał (http result code = 200) | |
.done(function(data) { | |
// ustawmy zawartość tagu ze statusem | |
// debug, uzyteczne jak nie jestes pewien co dostajesz :) , mozesz uzyc Developers Tools i tam krok po kroku | |
// analizować skrypt JS i podglądać jakie są dane w jakich zmiennych ^u^ | |
//console.log("Status led: "); | |
//console.log(data); | |
if (typeof(data.StatusSNS) != "undefined") { | |
update_sensor_data(data.StatusSNS); | |
} | |
}) | |
// jeśli będzie jakiś błąd (e.g. brak urządzenia , zły IP, etc...) to to się wykona: | |
.fail(function(jqxhr, text, err) { | |
console.log("AJAX query error! text="+text+" , error="+err); | |
console.log(jqxhr); | |
$("#led-status").html("ERROR: "+text); | |
// zmieniamy kolor :) | |
$("#led-status").css("background-color","#ff4000"); | |
}) | |
; // tutaj jest koniec definicji .ajax(.........) | |
} | |
function update_sensor_data(sns) { | |
if (typeof(sns.BME280) == "undefined") { | |
//alert("No BME280 data!"); | |
$("#sens_time").html("!!:!!"); | |
$("#temp").html("!!.!"); | |
$("#humi").html("!!.!"); | |
$("#press").html("!!!"); | |
return; | |
} | |
$("#sens_time").html(sns.Time); | |
$("#temp").html(sns.BME280.Temperature); | |
$("#humi").html( sns.BME280.Humidity); | |
$("#press").html(sns.BME280.Pressure); | |
} | |
// aktualizuj stan w oknie przeglądarki | |
// state: ON, OFF, CHANGE, ERROR, ? | |
function update_relay_status(rl_num, state) { | |
if (typeof(rl_num) === "undefined") { console.log("rl_num - indefined."); return; } | |
if (typeof(state) === "undefined") { console.log("state - indefined."); return; } | |
// sprawdź czy rl_num w zakresie (relay1..4) | |
if (rl_num < 1 || rl_num > 4) { console.log("rl_num ("+rl_num+") out of range!"); return; } | |
// on | |
if (state == "ON") { | |
$("#srl"+rl_num) | |
.html(" <img style='height: 14px' src='"+images[1]+"'/> ") | |
//.html("⏽") // unicode v9.0 , symbol: ⏽ "Power on" - seems not supported in FF 60.9 | |
.css("background-color","#79ff4c") | |
.attr("title",rl_num+": On") | |
; | |
// off | |
} else if (state == "OFF") { | |
$("#srl"+rl_num) | |
.html("⭘") | |
.css("background-color","#ff9673") | |
.attr("title",rl_num+": Off") | |
; | |
} else if (state == "CHANGE") { | |
$("#srl"+rl_num) | |
.html("🗘") | |
.css("background-color","#99ccff") | |
.attr("title",rl_num+": Changing") | |
; | |
} else if (state == "ERROR") { | |
$("#srl"+rl_num) | |
.html("⚠") | |
.css("background-color","#ff4000") | |
.attr("title",rl_num+": Error!") | |
; | |
} else if (state == "Blink ON") { | |
$("#srl"+rl_num) | |
.html("☀") | |
.css("background-color","#ff73ff") | |
.attr("title",rl_num+": Blink on!") | |
; | |
} else if (state == "Blink OFF") { | |
$("#srl"+rl_num) | |
.html("🛇") | |
.css("background-color","#b973ff") | |
.attr("title",rl_num+": Blink off!") | |
; | |
// unknown | |
} else { | |
$("#srl"+rl_num) | |
.html("⯑") | |
.css("background-color","#ffff26") | |
.attr("title",rl_num+": Bump, unknown: "+state) | |
; | |
} | |
} | |
// ustaw stan przekaźnika | |
// state: 0=OFF, 1=ON, 2=Toggle, 3=Blink on, 4=Blink off | |
function set_power_status(ip,rl,state) { | |
// sprawdzmy czy argumenty nie są "null" (czyli funkcja zostałą wywołana bez przekazanych argumentów) | |
if (typeof(rl) === "undefined") return; | |
if (typeof(ip) === "undefined") return; | |
if (typeof(state) === "undefined") return; | |
// dodatkowe sprawdzenie | |
if (state < 0 || state > 4) return; | |
if (!Number.isInteger(rl)) { | |
alert("rl nie jest liczbą!"); | |
return; | |
} | |
if (rl<1 || rl>4) { | |
alert("rl ("+rl+") poza zakresem!"); | |
return; | |
} | |
// zmień ikonkę na "zmianę" | |
update_relay_status(rl,"CHANGE"); | |
// ajax request - praktycznie kopiuj-wklej z "get_status" :) | |
// zwróć uwagę na sposób zapisu funkcji które są wywoływane po request'cie | |
$.ajax({ | |
url: "http://"+ip+"/cm?cmnd=Power"+rl+" "+state, // dodajemy state do url :) | |
dataType: "json" // spodziewamy się odpowiedzi w fomracie json | |
}) | |
// to jest wywoływane jeśli request się udał (http result code = 200) | |
.done(function(data) { | |
// ustawmy zawartość tagu span ze statusem | |
// debug, uzyteczne jak nie jestes pewien co dostajesz :) , mozesz uzyc Developers Tools i tam krok po kroku | |
// analizować skrypt JS i podglądać jakie są dane w jakich zmiennych ^u^ | |
//console.log("Status led: "); | |
//console.log(data); | |
// aktualizacja tag'a ze stanem | |
update_relay_status(rl,data["POWER"+rl]); | |
}) | |
// jeśli będzie jakiś błąd (e.g. brak urządzenia , zły IP, etc...) to to się wykona: | |
.fail(function(jqxhr, text, err) { | |
console.log("AJAX query error! text="+text+" , error="+err); | |
console.log(jqxhr); | |
update_relay_status(rl,"ERROR"); | |
}) | |
; // tutaj jest koniec definicji .ajax(.........) | |
} | |
// load all statuses | |
function getstatuses() { | |
get_sensor_bme280(espip); | |
get_power_status(espip); | |
} | |
// i kolejny fajny "feature" z jQuery, możemy wywołać z łatwością funkcję po pełnym załądowaniu dokumentu :) (bez uzycia body onload=....) | |
// mozna to zadeklarować w różnych miejscach i wiele razy wywołując inne funkcje | |
$(document).ready(function() { | |
//ledstatus(); // (^o^) | |
// kolejny pięknie brutalny feature jQuery :D | |
// - "przypinamy" jedną funkcję na kliknięcie dowolnego buttona w obrębie <form> | |
// , i wyciągamy z klikniętego elementu data-id i -state ktore definiują zachowanie buttona :D | |
// zawęzamy przypięcie event'u do button'ów (tag <input> z type=`button`) znajdujących w tagu <form> z name="control" : | |
$("form[name=control] input[type=button]").click(function(e) { | |
// wyiągamy id i state | |
var id = $(this).data("id"); | |
var state = $(this).data("state"); | |
//console.log("id="+id+";state="+state); | |
// i sterujemy tasmotą :) | |
set_power_status(espip,id, state); | |
// zabezpieczenie aby przeglądarka przypadkiem nie spróbowała wysłać formularza | |
e.preventDefault(); | |
return false; | |
}); | |
get_sensor_bme280(espip); | |
get_power_status(espip); | |
}); | |
</script> | |
<style type="text/css"> | |
.rl-state { | |
min-width: 30px; | |
line-height: 24px; | |
font-size: 18px; | |
display: inline-block; | |
text-align: center; | |
} | |
#temp, #humi, #press { | |
font-family: monospace; | |
font-size: 18px; | |
} | |
</style> | |
</head> | |
<body> | |
<!-- STatus led'a --> | |
<div style="line-height: 35px;"> | |
Status 1 2 3 4: | |
<span class="rl-state" style="background-color: #ffff26;" id="srl1">?</span> | |
<span class="rl-state" style="background-color: #ffff26;" id="srl2">?</span> | |
<span class="rl-state" style="background-color: #ffff26;" id="srl3">?</span> | |
<span class="rl-state" style="background-color: #ffff26;" id="srl4">?</span> | |
</div> | |
<div style="line-height: 35px;"> | |
<b>Sensor BME280: </b><span id="temp">--.-</span>℃ <span id="humi">--.-</span>% <span id="press">---</span>㍱ <span style="font-size: 10px">⏲:<span id="sens_time">--:--</span></span> | |
</div> | |
<!-- input'y pownny być w form tagu, onsubmit=return false - zapobiega wysłaniu formularza --> | |
<form name="control" onsubmit="return false;"> | |
<div>Relay 1: | |
<input type="button" data-id="1" data-state="1" value="ON"> | |
<input type="button" data-id="1" data-state="0" value="OFF"> | |
<input type="button" data-id="1" data-state="2" value="Toggle"> | |
<input type="button" data-id="1" data-state="3" value="Blink ON"> | |
<input type="button" data-id="1" data-state="4" value="Blink OFF"> | |
</div> | |
<div>Relay 2: | |
<input type="button" data-id="2" data-state="1" value="ON"> | |
<input type="button" data-id="2" data-state="0" value="OFF"> | |
<input type="button" data-id="2" data-state="2" value="Toggle"> | |
<input type="button" data-id="2" data-state="3" value="Blink ON"> | |
<input type="button" data-id="2" data-state="4" value="Blink OFF"> | |
</div> | |
<div>Relay 3: | |
<input type="button" data-id="3" data-state="1" value="ON"> | |
<input type="button" data-id="3" data-state="0" value="OFF"> | |
<input type="button" data-id="3" data-state="2" value="Toggle"> | |
<input type="button" data-id="3" data-state="3" value="Blink ON"> | |
<input type="button" data-id="3" data-state="4" value="Blink OFF"> | |
</div> | |
<div>Relay 4: | |
<input type="button" data-id="4" data-state="1" value="ON"> | |
<input type="button" data-id="4" data-state="0" value="OFF"> | |
<input type="button" data-id="4" data-state="2" value="Toggle"> | |
<input type="button" data-id="4" data-state="3" value="Blink ON"> | |
<input type="button" data-id="4" data-state="4" value="Blink OFF"> | |
</div> | |
<br /> | |
<br /> | |
<input type="button" value="Status" onClick="getstatuses();"> | |
<br /> | |
<br /> | |
<b>Tasmota Template:</b> | |
<pre>{"NAME":"test-tasmota","GPIO":[90,0,18,0,6,5,0,0,24,23,29,21,56],"FLAG":0,"BASE":18}</pre> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment