WiFiThermostat.ino 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. // pre compiletime config
  2. #define VERSION "0.1.2"
  3. #define DEVICE_NAME "WIFI-THERMOSTAT"
  4. #define PIN_DHTSENSOR 13
  5. #define PIN_RELAIS 16
  6. #define PIN_BUTTON_PLUS 0
  7. #define PIN_BUTTON_MINUS 2
  8. #define PIN_BUTTON_MODE 14
  9. #define PIN_PIRSENSOR 12
  10. #define RELAISONSTATE LOW
  11. #define BUTTONONSTATE LOW
  12. #define DHTTYPE DHT22 // DHT sensor type
  13. #define LCDADDR 0x27 // I2C address LCD
  14. #define DEBUG_SERIAL //uncomment for Serial debugging statements
  15. #ifdef DEBUG_SERIAL
  16. #define DEBUG_BEGIN Serial.begin(115200)
  17. #define DEBUG_PRINT(x) Serial.println(x)
  18. #else
  19. #define DEBUG_PRINT(x)
  20. #define DEBUG_BEGIN
  21. #endif
  22. #include "PersWiFiManager.h"
  23. #include <ArduinoJson.h>
  24. #include <ESP8266WiFi.h>
  25. #include <WiFiClient.h>
  26. #include <ESP8266WebServer.h>
  27. #include <ESP8266mDNS.h>
  28. #include <ESP8266HTTPUpdateServer.h>
  29. #include <PubSubClient.h>
  30. #include <Wire.h>
  31. #include "LiquidCrystal_I2C.h"
  32. #include <DNSServer.h>
  33. #include <FS.h>
  34. //#include <AS_BH1750.h> // BH1750 lux sensor
  35. #include "DHT.h"
  36. // global variables
  37. float humidity, temperature;
  38. bool turnHeatingOn = false;
  39. bool heatingEnabled = true;
  40. byte heatingMode = 1; // 0 = off, 1 = default/day, 2 = night/reduction
  41. float setTemp;
  42. long heatingLastOnMillis;
  43. long heatingLastOffMillis;
  44. float aTemp, aHum;
  45. long aTempHumLastUpdate;
  46. byte whichTempToDisplay; // 1=temp inside (from DHT sensor), 2= temp outside (via MQTT)
  47. long lastMeasure = 0;
  48. long lastDisplayUpdate = 0;
  49. long lastDisplayToggle = 0;
  50. long lastTempUpdate = 0;
  51. char msg[50]; // buffer MQTT in payload
  52. char topic[50]; // buffer MQTT in topic
  53. // global variables from other modules
  54. //extern bool displayActive;
  55. bool displayActive = false;
  56. // functions from other modules/files
  57. //extern void httpServerHandleNotFound();
  58. //extern void httpServerHandleRoot();
  59. //extern void enableDisplay();
  60. //extern void disableDisplay();
  61. //extern void extendDisplayTimeout();
  62. //extern void handleDisplayTimeout();
  63. //extern void updateDisplay();
  64. //extern void initDisplay();
  65. //extern void plusButtonAction();
  66. //extern void minusButtonAction();
  67. //extern void modeButtonAction();
  68. //extern void modeButtonHoldAction();
  69. //extern void checkButtonStates();
  70. // config variables
  71. const char* mqtt_server = "10.1.1.11";
  72. const int mqtt_port = 1883;
  73. long minOffTime = 10; // s
  74. float setTempDay = 21.5;
  75. float setTempNight = 18.0;
  76. float setTempMin = 14.0;
  77. float setTempMax = 29.0;
  78. float setTempMinLow = 10.0;
  79. float setTempMaxLow = 19.0;
  80. float hysteresis = 0.5;
  81. int measureinterval = 60000; // ms
  82. int displayinterval = 5000;
  83. int displayTimeout = 60000;
  84. //const char* mqtt_topic_prefix = "Test/Thermostat/";
  85. const char* mqtt_topic_temp = "Test/Thermostat/Temp";
  86. const char* mqtt_topic_settemp = "Test/Thermostat/SetTemp";
  87. //const char* mqtt_topic_setmode = "Test/Thermostat/SetMode";
  88. const char* mqtt_topic_hum = "Test/Thermostat/Hum";
  89. const char* mqtt_topic_lux = "Test/Thermostat/Lux";
  90. const char* mqtt_topic_heating = "Test/Thermostat/Heating";
  91. const char* mqtt_topic_heating_lastofftime = "Test/Thermostat/HeatingLastOffTime";
  92. const char* mqtt_topic_heating_lastontime = "Test/Thermostat/HeatingLastOnTime";
  93. const char* mqtt_topic_in = "Test/Thermostat/in"; // subscribe topic
  94. DHT dht(PIN_DHTSENSOR, DHTTYPE);
  95. LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
  96. WiFiClient espClient;
  97. PubSubClient mqttclient(espClient);
  98. ESP8266WebServer httpServer(80);
  99. DNSServer dnsServer;
  100. PersWiFiManager persWM(httpServer, dnsServer);
  101. ESP8266HTTPUpdateServer httpUpdater;
  102. // MQTT callback
  103. void mqttCallback(char* topic, byte* payload, unsigned int length) {
  104. Serial.print("Message arrived [");
  105. Serial.print(topic);
  106. Serial.print("] ");
  107. for (int i = 0; i < length; i++) {
  108. Serial.print((char)payload[i]);
  109. }
  110. Serial.println();
  111. if (strcmp(topic, mqtt_topic_in) == 0) { //if topic = mqtt_topic_in
  112. Serial.println("TOPIC!!");
  113. char tmpPayload[length + 1];
  114. for (int i = 0; i < length; i++) {
  115. tmpPayload[i] = (char)payload[i];
  116. }
  117. tmpPayload[sizeof(tmpPayload) - 1] = '\0';
  118. Serial.print("tmpPayload:");
  119. Serial.println(tmpPayload);
  120. if (strncmp(tmpPayload, "set temp ", 9) == 0) {
  121. char inValue[length - 9 + 1];
  122. for (int i = 0; i < length; i++) {
  123. inValue[i] = (char)payload[i + 9];
  124. }
  125. inValue[sizeof(inValue) - 1] = '\0';
  126. Serial.print(inValue);
  127. Serial.println();
  128. float invalueFloat = round(atof(inValue) * 2.0) / 2.0;
  129. Serial.print(invalueFloat);
  130. if (invalueFloat >= setTempMin && invalueFloat <= setTempMax) {
  131. setTempDay = invalueFloat;
  132. updateDisplay();
  133. }
  134. else if (invalueFloat > setTempMax) {
  135. setTempDay = setTempMax;
  136. updateDisplay();
  137. }
  138. else if (invalueFloat < setTempMin) {
  139. setTempDay = setTempMin;
  140. updateDisplay();
  141. }
  142. }// if payload=="set temp "
  143. else if (strncmp(tmpPayload, "set tlow ", 9) == 0) {
  144. char inValue[length - 9 + 1];
  145. for (int i = 0; i < length; i++) {
  146. inValue[i] = (char)payload[i + 9];
  147. }
  148. inValue[sizeof(inValue) - 1] = '\0';
  149. Serial.print(inValue);
  150. Serial.println();
  151. float invalueFloat = round(atof(inValue) * 2.0) / 2.0;
  152. Serial.print(invalueFloat);
  153. if (invalueFloat >= setTempMinLow && invalueFloat <= setTempMaxLow) {
  154. setTempNight = invalueFloat;
  155. updateDisplay();
  156. }
  157. else if (invalueFloat > setTempMaxLow) {
  158. setTempNight = setTempMaxLow;
  159. updateDisplay();
  160. }
  161. else if (invalueFloat < setTempMinLow) {
  162. setTempNight = setTempMinLow;
  163. updateDisplay();
  164. }
  165. }
  166. else if (strncmp(tmpPayload, "set mode ", 9) == 0) {
  167. if ((char)payload[9] == '1') {
  168. // switch to mode default/day
  169. heatingMode = 1;
  170. updateDisplay();
  171. }
  172. else if ((char)payload[9] == '2') {
  173. // switch to mode night/reduction
  174. heatingMode = 2;
  175. updateDisplay();
  176. }
  177. }
  178. else if (strncmp(tmpPayload, "set enab ", 9) == 0) {
  179. if ((char)payload[9] == '0') {
  180. // switch heating off
  181. heatingEnabled = false;
  182. updateDisplay();
  183. }
  184. else if ((char)payload[9] == '1') {
  185. // switch heating on
  186. heatingEnabled = true;
  187. updateDisplay();
  188. }
  189. }
  190. }//if topic = mqtt_topic_in
  191. if (strcmp(topic, "wetter/atemp") == 0) { //if topic = "wetter/atemp"
  192. char inValue[length + 1];
  193. for (int i = 0; i < length; i++) {
  194. inValue[i] = (char)payload[i];
  195. }
  196. inValue[sizeof(inValue) - 1] = '\0';
  197. //Serial.print(inValue);
  198. //Serial.println();
  199. float invalueFloat = atof(inValue);
  200. aTemp = invalueFloat;
  201. aTempHumLastUpdate = millis();
  202. //Serial.print("atemp=");
  203. //Serial.println(invalueFloat);
  204. }//if topic = "wetter/atemp"
  205. if (strcmp(topic, "wetter/ahum") == 0) { //if topic = "wetter/atemp"
  206. char inValue[length + 1];
  207. for (int i = 0; i < length; i++) {
  208. inValue[i] = (char)payload[i];
  209. }
  210. inValue[sizeof(inValue) - 1] = '\0';
  211. //Serial.print(inValue);
  212. //Serial.println();
  213. float invalueFloat = atof(inValue);
  214. aHum = invalueFloat;
  215. aTempHumLastUpdate = millis();
  216. //Serial.println("ahum=");
  217. //Serial.println(invalueFloat);
  218. }//if topic = "wetter/ahum"
  219. }//mqttCallback
  220. long mqttLastReconnectAttempt = 0;
  221. boolean mqttReconnect() {
  222. // Create a random MQTT client ID
  223. String mqttClientId = "ESP8266Client-";
  224. mqttClientId += String(random(0xffff), HEX);
  225. if (mqttclient.connect(mqttClientId.c_str())) {
  226. Serial.println("connected");
  227. // Once connected, publish an announcement...
  228. //mqttclient.publish("TestoutTopic", "hello world");
  229. // ... and resubscribe
  230. mqttclient.subscribe(mqtt_topic_in);
  231. mqttclient.subscribe("wetter/atemp");
  232. mqttclient.subscribe("wetter/ahum");
  233. }
  234. return mqttclient.connected();
  235. } //mqttReconnect
  236. void setup() {
  237. DEBUG_BEGIN; //for terminal debugging
  238. DEBUG_PRINT();
  239. Serial.print("WiFi Thermostat v");
  240. Serial.print(VERSION);
  241. Serial.println(" by Flo Kra");
  242. Serial.println("starting...");
  243. pinMode(PIN_RELAIS, OUTPUT);
  244. digitalWrite(PIN_RELAIS, HIGH);
  245. pinMode(PIN_BUTTON_PLUS, INPUT_PULLUP);
  246. pinMode(PIN_BUTTON_MINUS, INPUT_PULLUP);
  247. pinMode(PIN_BUTTON_MODE, INPUT_PULLUP);
  248. // initialize DHT11/22 temp/hum sensor
  249. dht.begin();
  250. //optional code handlers to run everytime wifi is connected...
  251. persWM.onConnect([]() {
  252. DEBUG_PRINT("wifi connected");
  253. DEBUG_PRINT(WiFi.SSID());
  254. DEBUG_PRINT(WiFi.localIP());
  255. });
  256. //...or AP mode is started
  257. persWM.onAp([]() {
  258. DEBUG_PRINT("AP MODE");
  259. DEBUG_PRINT(persWM.getApSsid());
  260. });
  261. //allows serving of files from SPIFFS
  262. //SPIFFS.begin();
  263. //SPIFFS.format();
  264. //sets network name for AP mode
  265. persWM.setApCredentials(DEVICE_NAME);
  266. //persWM.setApCredentials(DEVICE_NAME, "password"); optional password
  267. //make connecting/disconnecting non-blocking
  268. persWM.setConnectNonBlock(true);
  269. //in non-blocking mode, program will continue past this point without waiting
  270. persWM.begin();
  271. //handles commands from webpage, sends live data in JSON format
  272. httpServer.on("/api", []() {
  273. DEBUG_PRINT("httpServer.on /api");
  274. if (httpServer.hasArg("plusBtn")) {
  275. plusButtonAction();
  276. DEBUG_PRINT(P("web plusBtn"));
  277. } //if
  278. if (httpServer.hasArg("minusBtn")) {
  279. minusButtonAction();
  280. DEBUG_PRINT(P("web minusBtn"));
  281. } //if
  282. if (httpServer.hasArg("modeBtn")) {
  283. modeButtonAction();
  284. DEBUG_PRINT(P("web modeBtn"));
  285. } //if
  286. if (httpServer.hasArg("onoffBtn")) {
  287. modeButtonHoldAction();
  288. DEBUG_PRINT(P("web onoffBtn"));
  289. } //if
  290. //build json object of program data
  291. StaticJsonBuffer<200> jsonBuffer;
  292. JsonObject &json = jsonBuffer.createObject();
  293. json["ssid"] = WiFi.SSID();
  294. json["setTemp"] = setTempDay;
  295. json["temp"] = temperature;
  296. json["hum"] = int(humidity);
  297. json["mode"] = heatingMode;
  298. json["heatingEnabled"] = heatingEnabled;
  299. json["heating"] = turnHeatingOn;
  300. char jsonchar[200];
  301. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  302. httpServer.send(200, "application/json", jsonchar);
  303. }); //httpServer.on /api
  304. //get heap status, analog input value and all GPIO statuses in one json call
  305. httpServer.on("/info", HTTP_GET, []() {
  306. String json = "{";
  307. json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
  308. json += "\"heap\":" + String(ESP.getFreeHeap());
  309. //json += ", \"analog\":" + String(analogRead(A0));
  310. //json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
  311. json += "}";
  312. httpServer.send(200, "text/json", json);
  313. json = String();
  314. }); //httpServer.on /info
  315. httpServer.on("/", []() {
  316. httpServerHandleRoot();
  317. });
  318. httpServer.onNotFound([]() {
  319. httpServerHandleNotFound();
  320. }); //httpServer.onNotFound
  321. // HTTP Updater at /update
  322. httpUpdater.setup(&httpServer);
  323. httpServer.begin();
  324. DEBUG_PRINT("setup complete.");
  325. mqttclient.setServer(mqtt_server, mqtt_port);
  326. mqttclient.setCallback(mqttCallback);
  327. mqttLastReconnectAttempt = 0;
  328. initDisplay();
  329. } //void setup
  330. void loop() {
  331. persWM.handleWiFi(); //in non-blocking mode, handleWiFi must be called in the main loop
  332. dnsServer.processNextRequest();
  333. httpServer.handleClient();
  334. // MQTT reconnect if not connected (nonblocking)
  335. if (!mqttclient.connected()) {
  336. long now = millis();
  337. if (now - mqttLastReconnectAttempt > 5000) {
  338. mqttLastReconnectAttempt = now;
  339. // Attempt to reconnect
  340. if (mqttReconnect()) {
  341. mqttLastReconnectAttempt = 0;
  342. }
  343. }
  344. } else {
  345. // Client connected
  346. mqttclient.loop();
  347. }//else
  348. checkButtonStates();
  349. handleDisplayTimeout();
  350. // set target temp for heating mode
  351. if (heatingMode == 1) { // heating on - default/day mode
  352. setTemp = setTempDay;
  353. }
  354. else if (heatingMode == 2) { // heating of - night/reduction mode
  355. setTemp = setTempNight;
  356. }
  357. if ( (millis() - lastMeasure) > measureinterval) {
  358. lastMeasure = millis();
  359. float tmpHum = round(dht.readHumidity());
  360. float tmpTemp = dht.readTemperature(); // Read temperature as Celsius (the default)
  361. // Check if any reads failed
  362. if (isnan(tmpHum) || isnan(tmpTemp)) {
  363. Serial.println("Failed to read from DHT sensor!");
  364. }
  365. else {
  366. if (tmpTemp < 50.0 && tmpTemp > -20.0) {
  367. temperature = tmpTemp;
  368. humidity = tmpHum;
  369. lastTempUpdate = millis();
  370. }
  371. }
  372. unsigned long heatingOnTime, heatingOffTime;
  373. if (heatingEnabled && turnHeatingOn) {
  374. heatingOnTime = (millis() - heatingLastOffMillis) / 1000;
  375. Serial.print("heatingOnTime: ");
  376. Serial.print(heatingOnTime);
  377. Serial.println();
  378. }
  379. else if (heatingEnabled && !turnHeatingOn) {
  380. heatingOffTime = (millis() - heatingLastOnMillis) / 1000;
  381. Serial.print("heatingOffTime: ");
  382. Serial.print(heatingOffTime);
  383. Serial.println();
  384. }
  385. Serial.print("lastTempUpdate: ");
  386. Serial.println(lastTempUpdate);
  387. long test1 = millis() - lastTempUpdate;
  388. Serial.print("lastTempUpdate test1: ");
  389. Serial.println(test1);
  390. if ( (millis() - lastTempUpdate) < 120000 ) {
  391. // thermostat - only active if measured temperature is < 2 min old
  392. // thermostat with hysteresis
  393. if ( temperature >= setTemp ) {
  394. turnHeatingOn = false;
  395. heatingLastOnMillis = millis();
  396. digitalWrite(PIN_RELAIS, !RELAISONSTATE);
  397. updateDisplay();
  398. Serial.println("heating off");
  399. Serial.print("last onTime: ");
  400. Serial.print(heatingOnTime);
  401. Serial.println();
  402. mqttclient.publish(mqtt_topic_heating, "off");
  403. //mqttclient.publish(mqtt_topic_heating_lastontime, heatingOnTime);
  404. }
  405. else if ( heatingEnabled && ( temperature < (setTemp - hysteresis) ) && ( heatingOffTime > minOffTime ) ) {
  406. turnHeatingOn = true;
  407. digitalWrite(PIN_RELAIS, RELAISONSTATE);
  408. updateDisplay();
  409. Serial.println("heating on");
  410. Serial.print("last offTime: ");
  411. Serial.print(heatingOffTime);
  412. Serial.println();
  413. mqttclient.publish(mqtt_topic_heating, "on");
  414. //mqttclient.publish(mqtt_topic_heating_lastofftime, heatingOffTime);
  415. }
  416. }
  417. else {
  418. turnHeatingOn = false;
  419. digitalWrite(PIN_RELAIS, !RELAISONSTATE);
  420. Serial.println("heating off");
  421. mqttclient.publish(mqtt_topic_heating, "off");
  422. }
  423. }
  424. // if (lightMeter_present) {
  425. // delay(50);
  426. // lux = lightMeter.readLightLevel();
  427. //
  428. // String lux_str = String(lux, 1); //converting humidity (the float variable above) to a string with 0 decimals
  429. // char lux_chararr[lux_str.length() + 1];
  430. // lux_str.toCharArray(lux_chararr, lux_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  431. //
  432. // Serial.print("Lux: ");
  433. // Serial.println(lux_str);
  434. // mqttclient.publish(mqtt_topic_lux, lux_chararr);
  435. // }
  436. long now = millis();
  437. if ( ((now - aTempHumLastUpdate) < 300000) && whichTempToDisplay == 1 && ((now - lastDisplayToggle) > displayinterval) ) {
  438. // A-temp has been updated < 5 min ago, last displayed temp was I and display interval is overdue
  439. whichTempToDisplay = 2; // 1= I, 2= A
  440. lastDisplayToggle = now;
  441. }
  442. else if ( whichTempToDisplay != 1 && ((now - lastDisplayToggle) > displayinterval) ) {
  443. whichTempToDisplay = 1; // 1= I, 2= A
  444. lastDisplayToggle = now;
  445. }
  446. // update display?
  447. if ( (now - lastDisplayUpdate) > displayinterval) {
  448. lastDisplayUpdate = now;
  449. // char temp_chararr[6];
  450. // char hum_chararr[3];
  451. // if ( (millis() - lastTempUpdate) < 120000) {
  452. // String temp_str = String(temperature, 1); //converting Temperature (the float variable above) to a string with 1 decimal
  453. // //char temp_chararr[temp_str.length() + 1];
  454. // temp_str.toCharArray(temp_chararr, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  455. //
  456. // String hum_str = String(humidity, 0); //converting humidity (the float variable above) to a string with 0 decimals
  457. // //char hum_chararr[hum_str.length() + 1];
  458. // hum_str.toCharArray(hum_chararr, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  459. //
  460. // mqttclient.publish(mqtt_topic_temp, temp_chararr);
  461. // mqttclient.publish(mqtt_topic_hum, hum_chararr);
  462. // }
  463. // else {
  464. // char temp_chararr[] = {'-', '-', ',', '-', '\0'};
  465. // char hum_chararr[] = {'-', '-', '\0'};
  466. // }
  467. String temp_str = String(temperature, 1); //converting Temperature (the float variable above) to a string with 1 decimal
  468. char temp_chararr[temp_str.length() + 1];
  469. temp_str.toCharArray(temp_chararr, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  470. String hum_str = String(humidity, 0); //converting humidity (the float variable above) to a string with 0 decimals
  471. char hum_chararr[hum_str.length() + 1];
  472. hum_str.toCharArray(hum_chararr, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  473. if ( (now - lastTempUpdate) < 120000 ) {
  474. mqttclient.publish(mqtt_topic_temp, temp_chararr);
  475. mqttclient.publish(mqtt_topic_hum, hum_chararr);
  476. }
  477. else {
  478. temp_str = "--.-";
  479. hum_str = "--";
  480. }
  481. String atemp_str = String(aTemp, 1); //converting Temperature (the float variable above) to a string with 1 decimal
  482. char atemp_chararr[atemp_str.length() + 1];
  483. atemp_str.toCharArray(atemp_chararr, atemp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  484. String ahum_str = String(aHum, 0); //converting humidity (the float variable above) to a string with 0 decimals
  485. char ahum_chararr[ahum_str.length() + 1];
  486. ahum_str.toCharArray(ahum_chararr, ahum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
  487. char setTemp_chararr[5]; //result string 4 positions + \0 at the end
  488. // convert float to fprintf type string format 2 positions with 1 decimal place
  489. dtostrf(setTemp, 2, 1, setTemp_chararr );
  490. Serial.print("set temp: ");
  491. Serial.println(setTemp_chararr);
  492. Serial.print("current temp: ");
  493. Serial.println(temp_chararr);
  494. mqttclient.publish(mqtt_topic_settemp, setTemp_chararr);
  495. if (whichTempToDisplay == 2) {
  496. // print inside temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars
  497. lcd.setCursor(0, 0);
  498. //lcd.write(0x3D); // = Zeichen
  499. lcd.print("A");
  500. if (aTemp <= -10);
  501. else if (aTemp < 0) lcd.print(" ");
  502. else if (aTemp < 10) lcd.print(" ");
  503. else lcd.print(" ");
  504. lcd.print(atemp_str); // inside temperature should hopefully always be 2.1 chars, so no special formatting necessary
  505. lcd.write(0xDF); // degree symbol
  506. lcd.print(" ");
  507. //lcd.print(humstr2);
  508. lcd.print(ahum_str); // always 2 chars
  509. lcd.print("%");
  510. lcd.print(" ");
  511. }
  512. else {
  513. // print outside temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars
  514. lcd.setCursor(0, 0);
  515. //lcd.write(0x3D); // = Zeichen
  516. lcd.print("I");
  517. //lcd.print(" "); // inside temperature should hopefully always be 2.1 chars, so no special formatting/spaces handling necessary
  518. if (temperature <= -10);
  519. else if (temperature < 0) lcd.print(" ");
  520. else if (temperature < 10) lcd.print(" ");
  521. else lcd.print(" ");
  522. //if (temperature < -9) lcd.print(" ");
  523. //else if (temperature < 0) lcd.print("");
  524. //else if (temperature < 10) lcd.print(" ");
  525. //else lcd.print(" ");
  526. //lcd.print(tempstr2);
  527. //lcd.print(temp_str);
  528. lcd.print(temp_chararr);
  529. lcd.write(0xDF); // degree symbol
  530. lcd.print(" ");
  531. //lcd.print(humstr2);
  532. //lcd.print(hum_str); // always 2 chars
  533. lcd.print(hum_chararr); // always 2 chars
  534. lcd.print("%");
  535. lcd.print(" ");
  536. }
  537. // display current mode on LCD
  538. lcd.setCursor(13, 0); // to char 15, line 1
  539. if (heatingEnabled) {
  540. if ( heatingMode == 1 ) { // day/normal mode
  541. lcd.print(" ");
  542. lcd.write((uint8_t)1); // sun symbol if mode is day/normal
  543. lcd.print(" ");
  544. }
  545. else if ( heatingMode == 2 ) { // night/reduction mode
  546. lcd.print(" ");
  547. lcd.write((uint8_t)0); // moon symbol if mode is night/reduction
  548. lcd.print(" ");
  549. }
  550. }
  551. else lcd.print(" "); // mode is heating off
  552. // display target temperature to line 2, 8 chars length incl space at the end
  553. lcd.setCursor(0, 1);
  554. // when the heating mode is OFF, do not display target temp - instead show "Heating off" info in line 2
  555. if ( !heatingEnabled ) {
  556. // 1234567890123456
  557. lcd.print(" Heizung aus ");
  558. }
  559. else {
  560. lcd.write((uint8_t)2); // Pfeil rechts
  561. lcd.print(" ");
  562. lcd.print(setTemp_chararr);
  563. lcd.write(0xDF); // degree symbol
  564. lcd.print(" ");
  565. // display status info to line 2 from char 9 -> 8 chars length
  566. lcd.setCursor(8, 1);
  567. if (turnHeatingOn) {
  568. // 12345678
  569. lcd.print("heizen..");
  570. }
  571. else if ( heatingMode == 1 ) { // day/normal mode
  572. // 12345678
  573. lcd.print(" ");
  574. }
  575. else if ( heatingMode == 2 ) { // night/reduction mode
  576. // 12345678
  577. lcd.print("N-Absenk");
  578. }
  579. else lcd.print(" ");
  580. }
  581. }
  582. } //void loop