// wemosD1mini + DS18B20 // version 24/11/25 // used wemosD1 manual: https://geekelectronics.org/arduino/wemos-d1-r2-na-esp8266-ndash-pervoe-znakomstvo.html ///#include // #include // Only needed for Arduino 1.6.5 and earlier //#include "SSD1306Wire.h" // alias for `#include "SSD1306Wire.h"` //#include "DHT.h" #include #include #include #include #include // https://github.com/jwrw/ESP_EEPROM // for WEB #include #include #include // https://github.com/tzapu/WiFiManager // for battery check //ADC_MODE(ADC_VCC); // remote host String api_url_script_url, host, url, chip_id, device_ip; String ver="24.11.22"; String pin="8888"; String last_url = ""; float h_max_comfort=60; //WiFiServer server(80); ESP8266WebServer server ( 80 ); char footer[400]; char bottom[30]; String www_menu = "   Home     \ XML page     \ JSON page     \ LOGs    "; Ticker dht_get; Ticker tim; Ticker key_r; // ------------------------------------------- // # [wf ] 1 // # [ ] 3 // 16 [ ] 5 OPTRON // 14 [ ] 4 // BTTN 12 [ ] 0 // DS18 13 [ ] 2 BUILTLED // 15 [ ] GND // 3,3 [usb] 5V // ___________________________________________ #define ONE_WIRE_BUS 13 #define button12 12 #define relay5 5 float h = 0; int temp_max = 20; int temp_delta = 1; float temp_real = 0; bool temp_auto = true; float temp_arr[4]; int temp_index = 0; int fail_connect =0; int time_update =10; int analogval =0; int hour=0; int minu=0; int secu=0; int clnts=0; int point=0; bool but_state = false; bool but_last_state = false; int but_count = 0; //int d9_state = 1; //volatile int d3_state = 1; //int d9_last_state=1; //int d3_last_state=1; //volatile int d3_mills = 0; //int d9_min=0; //int d9_max=0; //volatile int d3_count = 0; //volatile long d3_last_mills[3] = {0,0,0}; //volatile long last_miils_cnt = 1; //volatile long last_miils = 0; int led_delay = 1; int str2_count = 0; int str2_state = 0; float refr_cnt=883; String datas="Init"; //String selector=" "; //#define RST_OLED 16 //#define DHTPIN 14 //#define DHTTYPE DHT21 //DHT dht(DHTPIN, DHTTYPE); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress deviceAddress; String owstat = ""; String owaddr[8]; float owtemp[8]; bool dht_get_flag = false; bool tm_flag = false; bool key_flag = false; bool updated = false; String tm_capt = ""; bool http_get_finc( int operation, String sens_id, float value) { fail_connect= millis(); bool result=false; // Operations: // 1 - syncronize time // 2 - send changed params // 3 - read last relays configuration // String url2 = "/gpio/themp.php?p=12345&sens_id=4&act=save&val="; if((WiFi.status() == WL_CONNECTED)) { // Use WiFiClient class to create TCP connections WiFiClient client; String line, last_url; if(operation==1) { // Serial.print("connecting to "); // Serial.println(host); if (client.connect(host, 80)) { // This will send the request to the server line = url + "?act=Hi" + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"; last_url = line; client.print(String("GET ") + line); // Read all the lines of the reply from server and print them to Serial line = ""; while (client.connected()) { if (client.available()) { line = client.readStringUntil('\n'); if(line.indexOf('now')>0) { String st= line.substring(3,5); hour = st.toInt(); st= line.substring(5,7); minu = st.toInt(); st= line.substring(7,9); secu = st.toInt(); Serial.println(line); } } if(millis()-fail_connect > 5000) client.stop(); } client.stop(); last_url += line; // Serial.println("disconnect"); } else { Serial.println("connection failed!"); client.stop(); } } if(operation==2 && sizeof(host)>1) // ОТПРАВКА { Serial.println("Try server:" + host + " url:" + url); if (client.connect(host, 80)) { line = url + sens_id + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"; last_url = line; client.print(String("GET ") + line); line = ""; while (client.connected()) { if (client.available()) { line = client.readStringUntil('\n'); if(line.indexOf('saved')>0) Serial.println(line); } if(millis()-fail_connect > 5000) client.stop(); } client.stop(); last_url += line; result = true; } else { Serial.println("connection failed!"); client.stop(); } } if(operation==3) // ПОЛУЧЕНИЕ { if (client.connect(host, 80)) { // This will send the request to the server line = url + "?act=simple&sens_id=" + sens_id + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"; last_url = line; client.print(String("GET ") + line); // Read all the lines of the reply from server and print them to Serial line = ""; while (client.connected()) { if (client.available()) { line = client.readStringUntil('\n'); // bool variables String st= line.substring(0,1); bool state = false; if(st=="0" || st=="") state = false; if(st=="1" || st=="5") state = true; // if(sens_id=="141") digitalWrite(0, state); // if(sens_id=="142") digitalWrite(2, state); } // if(millis()-fail_connect > 5000) client.stop(); } client.stop(); last_url += line; } else { Serial.println("connection failed!]"); client.stop(); } } /////////WiFi.disconnect(); } // Serial.println(last_url); dht_get_flag = false; return result; } void time_finc() { secu=secu+30; if(secu>59) { secu=0; minu++; } if(minu>59) { minu=0; hour++; } if(hour>23) hour=0; if(secu==0) { Serial.print(hour); Serial.print(":"); Serial.print(minu); Serial.print(":"); Serial.print(secu); Serial.print(": IP "); Serial.println(WiFi.localIP().toString() ); } // restore time and relays last states // if( WiFi.status() != WL_CONNECTED) { wifi_connect(); } if(updated==false && WiFi.status() == WL_CONNECTED) { http_get_finc( 1, "", 0); // sync time // http_get_finc( 3, "137", 0); // http_get_finc( 3, "135", 0); updated=true; } tm_flag=false; } void key_reader() { bool but = digitalRead(button12); if(but==but_last_state && but==false) { but_count++; digitalWrite(2, HIGH ); delay(60); digitalWrite(2, LOW ); delay(60); digitalWrite(2, HIGH ); delay(60); digitalWrite(2, LOW ); delay(60); led_delay=0; Serial.println(but_count); } if(but!=but_last_state) { Serial.print("But: "); Serial.println(but); if(but==true) // действие { if(but_count>2 && but_count<8) { Serial.println("Manual mode. Invert control"); temp_auto=false; digitalWrite(relay5, !digitalRead(relay5)); } if(but_count>9) { Serial.println("Reset"); ESP.reset(); } but_count=0; } } but_last_state = but; digitalWrite(2, LOW ); if(temp_auto==false && led_delay>6) { digitalWrite(2, HIGH ); led_delay=0; } if(temp_auto==true && led_delay>3){ digitalWrite(2, HIGH ); led_delay=0; } led_delay++; key_flag = false; } void handleRoot() { server.send ( 200, "text/html", footer + www_menu + bottom ); } void handleNotFound() { String s = " "; bool logout = false; if(server.uri()=="/index.php" && server.args()>0 && server.authenticate("admin", pin.c_str() ) ) { String temp_max1; String temp_delta1; String temp_auto1; for ( uint8_t i = 0; i < server.args(); i++ ) { // settings if(server.argName(i)=="temp_auto") { if(server.arg(i)=="on") temp_auto = true; else temp_auto = false; } // relays // if(server.argName(i)=="r0") { if(server.arg(i)=="on") digitalWrite(0, HIGH); else digitalWrite(0, LOW); } if(server.argName(i)=="r5") { if(server.arg(i)=="on") digitalWrite(relay5, HIGH); else digitalWrite(relay5, LOW); } // if(server.argName(i)=="tx") if(server.arg(i)=="on") { digitalWrite(1, LOW); pinMode(1, FUNCTION_0); } // else { pinMode(1, FUNCTION_3); pinMode(1, OUTPUT); digitalWrite(1, LOW); } // reset if(server.argName(i) == "reset" && server.arg(i) == "run") ESP.reset(); //ESP.restart() if(server.argName ( i ) == "api_url_script_url" ) { if(api_url_script_url != server.arg ( i )) { api_url_script_url = server.arg ( i ); Serial.println("Settings> api_url_script_url:" + api_url_script_url ); int str_sz = api_url_script_url.length(); EEPROM.put(30, str_sz); for (int i = 0; i < str_sz; i++) EEPROM.put(34+i, api_url_script_url[i]); boolean res1 = EEPROM.commit(); Serial.print("Write to FLASH api_url_script_url:" + api_url_script_url + " Size:"); Serial.print(str_sz); if(res1==true) Serial.println(" OK"); else Serial.println(" FALSE"); } } if(server.argName ( i ) == "pin" ) { if(pin != server.arg ( i )) { pin = server.arg ( i ); Serial.println("Settings>PIN:" + pin ); EEPROM.put(0, pin.toInt()); boolean res1 = EEPROM.commit(); Serial.print("Write to FLASH PIN: " + pin); if(res1==true) Serial.println(" OK"); else Serial.println(" FALSE"); } } if(server.argName ( i ) == "temp_max" ) { if(String(temp_max) != server.arg ( i )) { String val = server.arg ( i ); temp_max = val.toInt(); Serial.print("Settings> temp_max: "); Serial.print( temp_max ); int eval = temp_max; EEPROM.put(4, eval); boolean res1 = EEPROM.commit(); Serial.print("Write to FLASH temp_max: " + String(temp_max)); if(res1==true) Serial.println(" OK"); else Serial.println(" FALSE"); } } if(server.argName ( i ) == "temp_delta" ) { if(String(temp_delta) != server.arg ( i )) { String val = server.arg ( i ); temp_delta = val.toInt(); Serial.print("Settings> i_bat_cc: "); Serial.print( temp_delta ); int eval = temp_delta; EEPROM.put(8, eval); boolean res1 = EEPROM.commit(); Serial.print("Write to FLASH temp_delta: " + String(temp_delta)); if(res1==true) Serial.println(" OK"); else Serial.println(" FALSE"); } } } // arg for } // index s += www_menu + " LogOut
\n"; String xml = ""; String json = "{"; String s_tmp = ""; s += "
"; if(temp_auto) s_tmp="off"; else s_tmp="on"; s += "
temp_auto
\n"; if(digitalRead(relay5)==1) s_tmp="off"; else s_tmp="on"; s += "
Relay 5
\n"; // s += "
Relay 5: "+s_tmp+"
\n"; xml += ""; xml +=digitalRead(relay5); xml +=""; json += "\"out5\": \""; json +=digitalRead(relay5); json +="\","; // s += "Serial output: TX off TX on
\n"; for (int i = 0; i < 8; i++) { if(owaddr[i]!="") { s += "Temperature "; s += i; s += " ["; s += owaddr[i]; s += "] : "; s += owtemp[i]; s += "c
\n"; xml += " \ ApiURL:
\n"; s += "PIN:
\n"; s += "
"; xml += ""; xml+=temp_max; xml+=""; json += "\"temp_max\": \""; json +=temp_max; json +="\","; s += "
"; xml += ""; xml+=temp_delta; xml+=""; json += "\"temp_delta\": \""; json +=temp_delta; json +="\","; /* String sel0,sel1=""; if(temp_auto==1) sel1="selected"; else sel0="selected"; s += "
"; xml += ""; xml+=temp_auto; xml+=""; json += "\"temp_auto\": \""; json +=temp_auto; json +="\","; */ s += "    "; s += "
FreeMem = "; s += round(ESP.getFreeHeap()/1024); s += " kB
\n"; s += "Uptime = "; s += round(millis() / (1000 * 60 * 60)); s += " hours
\n"; xml += ""; xml+=round(millis() / (1000 * 60 * 60)); xml+=""; json += "\"Uptime\": \""; json +=round(millis() / (1000 * 60 * 60)); json +="\","; s += "MAC: "; s += chip_id; s += "
\n"; xml += ""; xml+=chip_id; xml+=""; json += "\"MAC\": \""; json +=chip_id; json +="\""; s += "

"; s += "
";
//      s += "Available input Params: temp_max[int], temp_delta[int], temp_auto[on/off], r5[on/off] 
\n"; s += "URI: "; s += server.uri(); s += "
\n"; s += " Method: "; s += ( server.method() == HTTP_GET ) ? "GET" : "POST"; s += "\n"; for ( uint8_t i = 0; i < server.args(); i++ ) { s += " " + server.argName ( i ) + ": " + server.arg ( i ) + "
\n"; } s += " Arguments: "; s += server.args(); s += "
\n"; s += owstat; s += "
\n"; xml += "
"; json += "}"; if(server.uri()=="/index.php" ) { if (!server.authenticate("admin", pin.c_str() )) //Basic Auth Method with Custom realm and Failure Response //return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse); //Digest Auth Method with realm="Login Required" and empty Failure Response //return server.requestAuthentication(DIGEST_AUTH); //Digest Auth Method with Custom realm and empty Failure Response //return server.requestAuthentication(DIGEST_AUTH, www_realm); //Digest Auth Method with Custom realm and Failure Response { return server.requestAuthentication(DIGEST_AUTH); } if(logout==false) server.send ( 200, "text/html", footer + s + bottom ); else server.send ( 401, "text/html", footer + www_menu + "401: Unauthorized"+bottom); } if(server.uri()=="/index.xml") server.send ( 200, "text/xml", xml ); if(server.uri()=="/index.json") server.send ( 200, "application/json", json ); } void key_event() { if(!tm_flag && !dht_get_flag) key_flag = true; } void dht_get_event() { if(!tm_flag ) dht_get_flag = true; } void tm_event() { tm_flag=true; } void setup() { Serial.begin(115200); Serial.println("System inits"); pinMode(5, OUTPUT); digitalWrite(relay5, LOW); pinMode(2, OUTPUT); digitalWrite(2, LOW); // BUILTLED pinMode(12, INPUT); Serial.println("Set timers"); dht_get.attach(302, dht_get_event); // 937 tim.attach(30.0, tm_event); key_r.attach(1.0, key_event); //0.3 //chip_id = ESP.getChipId(); chip_id = WiFi.macAddress(); Serial.println("WiFi manager start"); //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm; wm.setConfigPortalTimeout(30); // auto close configportal after n seconds bool res; // res = wm.autoConnect(); // auto generated AP name from chipid // res = wm.autoConnect("AutoConnectAP"); // anonymous ap res = wm.autoConnect("ESP-AP","12344321"); // password protected ap if(!res) { Serial.println("Failed to connect"); // ESP.restart(); } else { //if you get here you have connected to the WiFi Serial.println("connected...! :)"); } delay(1000); /////////////////// eeprom Serial.println("Read EEPROM settings"); EEPROM.begin(1024); // карта значений int addr, val; EEPROM.get(0, val); if(val<10000) pin=String(val); Serial.println("PIN: "+pin); val=0; EEPROM.get(4, val); if(val<500) temp_max=val; Serial.println("temp_max: " + String(val)); val=0; EEPROM.get(8, val); if(val<500) temp_delta=val; Serial.println("temp_delta: " + String(val)); val=0; Serial.print("reading api_script_url.. Size:"); EEPROM.get(30, val); Serial.println(val); char t; if(val>0 && val<150) for (int i = 0; i < val; i++) { EEPROM.get(34+i, t); api_url_script_url+=t; } Serial.println(api_url_script_url); int slsh=0; for (int i = 1; i < api_url_script_url.length(); i++) { if(api_url_script_url[i]=='/') slsh++; if(slsh==2 && api_url_script_url[i]!='/') host += api_url_script_url[i]; if(slsh>2 ) url += api_url_script_url[i]; } // Serial.print(api_url_script_url.length()); Serial.println(api_url_script_url); Serial.println("Host:" + host +" url" + url + ". "); if(api_url_script_url.substring(0,4)!="http") { Serial.println("Host not valid:" + api_url_script_url.substring(0,5)); host=""; } // Start the server server.on ( "/", handleRoot ); //server.on ( "/test.svg", drawGraph ); //server.on ( "/inline", []() { server.send ( 200, "text/plain", "this works as well" ); } ); server.onNotFound ( handleNotFound ); server.begin(); snprintf ( footer, 400, " Wemos D1 - SOLARs\ \ \ \

Wemos D1 - thermostat

"); snprintf ( bottom, 30, " " ); Serial.println(chip_id +"Server started"); // Print the IP address Serial.println(WiFi.localIP()); sensors.begin(); // Start up the library owstat = ""; owstat += sensors.getDeviceCount() ; owstat += " Devices"; sensors.requestTemperatures(); for (int i = 0; i < sensors.getDeviceCount(); i++) { sensors.getAddress(deviceAddress, i); String addr = ""; for (uint8_t u = 0; u < 8; u++) addr += deviceAddress[u], HEX; owaddr[i] = addr; owtemp[i] = sensors.getTempCByIndex(i); } for (int i = 0; i < 8; i++) { owstat += "Sensor "; owstat += i; owstat += "-"; owstat += owaddr[i]; owstat += "-"; owstat += owtemp[i]; owstat += "; "; } for (int k = 0; k < 3; k++) { delay(1000); sensors.requestTemperatures(); temp_arr[k] = sensors.getTempCByIndex(0); Serial.println(temp_arr[k]); } } void loop() { if(tm_flag) time_finc(); if(key_flag && !dht_get_flag && !tm_flag) key_reader(); if(!key_flag && !dht_get_flag && !tm_flag) {// ArduinoOTA.handle(); server.handleClient();// http_server(); } if (!key_flag && !tm_flag && dht_get_flag) { Serial.println("dht_get_flag"); // check wifi if(WiFi.status() != WL_CONNECTED) { Serial.println("Not connected"); // wifi_connect(); } else { // http_get_finc( 2, "141", digitalRead(0)); // http_get_finc( 2, "142", digitalRead(2)); time_update++; if(time_update>10) { http_get_finc( 1, "", 0); // sync time time_update=0; } } for (int i = 0; i < 8; i++) { owaddr[i]=""; owtemp[i]=0; } owstat = ""; owstat += sensors.getDeviceCount() ; owstat += " Devices"; sensors.requestTemperatures(); for (int i = 0; i < sensors.getDeviceCount(); i++) { sensors.getAddress(deviceAddress, i); String addr = ""; for (uint8_t u = 0; u < 8; u++) addr += deviceAddress[u], HEX; owaddr[i] = addr; owtemp[i] = sensors.getTempCByIndex(i); String id = "4"; id += i; // if(owtemp[i]<40 && owtemp[i]>-40) // http_get_finc( 2, id, owtemp[i]); Serial.print(i); Serial.print(owtemp[i]); Serial.println(" c"); if(temp_auto && i==0 && owtemp[i]<40 && owtemp[i]>-40) // auto temp control { temp_arr[temp_index] = owtemp[i]; float temp_summ = 0; Serial.print("Auto temp. arr:"); for (int k = 0; k < 3; k++) { temp_summ = temp_summ + temp_arr[k]; Serial.print(temp_arr[k]); Serial.print("-"); } Serial.print(" approx:"); temp_real = temp_summ / 3; Serial.print(temp_real); if(temp_index==2) { temp_index = 0; } else temp_index++; if(temp_real>=(temp_max+abs(temp_delta/2))) { Serial.println(" io 5 disable"); digitalWrite(relay5, LOW); } if(temp_real<=(temp_max-abs(temp_delta/2))) { Serial.println(" io 5 enable"); digitalWrite(relay5, HIGH); } } } dht_get_flag = false; } }