WiFiThermostat.ino 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. //#include <Arduino.h>
  2. #include "fwversion.h"
  3. #include "fwsettings.h"
  4. // ESP8266 core libs
  5. #include <ESP8266HTTPUpdateServer.h>
  6. #include <ESP8266WebServer.h>
  7. #include <ESP8266WiFi.h>
  8. #include <ESP8266mDNS.h>
  9. #ifdef USE_MQTT_TLS
  10. #include <WiFiClientSecure.h>
  11. #else
  12. #include <WiFiClient.h>
  13. #endif
  14. // WiFiManager
  15. #include <PersWiFiManagerExt.h>
  16. // DNS server used for captive portal in WiFiManager
  17. #include <DNSServer.h>
  18. // MQTT client
  19. #include <PubSubClient.h>
  20. // SPIFFS FS support - used for config storage
  21. #include <FS.h>
  22. // Json lib - used for config storage and web api
  23. #include <ArduinoJson.h>
  24. //#include <string.h>
  25. // I2C and LCD display
  26. #include <Wire.h>
  27. #include <LiquidCrystal_I2C.h>
  28. // DHT22 sensor lib
  29. #include <DHT.h>
  30. // Button handling
  31. #include <Bounce2.h>
  32. #include <Button.h>
  33. #include <ButtonEventCallback.h>
  34. #include <PushButton.h>
  35. PROGMEM const char PGMStr_FIRMWARE_NAME[] = FIRMWARE_NAME;
  36. PROGMEM const char PGMStr_FIRMWARE_VERSION[] = FIRMWARE_VERSION;
  37. PROGMEM const char PGMStr_FIRMWARE_URL[] = FIRMWARE_URL;
  38. PROGMEM const char PGMStr_FIRMWARE_COPYRIGHT[] = FIRMWARE_COPYRIGHT;
  39. PROGMEM const char PGMStr_FIRMWARE_COPYRIGHT_URL[] = FIRMWARE_COPYRIGHT_URL;
  40. PROGMEM const char PGMStr_FIRMWARE_SHORTNAME[] = FIRMWARE_SHORTNAME;
  41. PROGMEM const char PGMStr_changedTo[] = "changed to";
  42. PROGMEM const char PGMStr_preset[] = "preset";
  43. PROGMEM const char PGMStr_heatingMode[] = "heatingMode";
  44. PROGMEM const char PGMStr_heatingPause[] = "heatingPause";
  45. PROGMEM const char PGMStr_setTemp[] = "setTemp";
  46. PROGMEM const char PGMStr_currentSetTemp[] = "currSetTemp";
  47. PROGMEM const char PGMStr_setTempLow[] = "setTempLow";
  48. PROGMEM const char PGMStr_setTempLow2[] = "setTempLow2";
  49. PROGMEM const char PGMStr_switchHeating[] = "switch heating";
  50. PROGMEM const char PGMStr_mqttRetainedSave[] = "MQTT retained save";
  51. PROGMEM const char PGMStr_heating[] = "heating";
  52. PROGMEM const char PGMStr_thermostat[] = "THST";
  53. PROGMEM const char PGMStr_WiFi[] = "WiFi";
  54. //PROGMEM const char PGMStr_connectedTo[] = "connected to";
  55. //PROGMEM const char PGMStr_withIP[] = "with IP";
  56. PROGMEM const char PGMStr_MQTT[] = "MQTT";
  57. PROGMEM const char PGMStr_connectedTo[] = "connected to";
  58. PROGMEM const char PGMStr_reconnects[] = "reconnects";
  59. PROGMEM const char PGMStr_connectedFailed[] = "connect FAILED";
  60. PROGMEM const char PGMStr_enabled[] = "enabled";
  61. PROGMEM const char PGMStr_disabled[] = "disabled";
  62. PROGMEM const char compile_date[] = __DATE__ " " __TIME__;
  63. const char PGMStr_confDevWiFi[] PROGMEM = "confDevWiFi";
  64. const char PGMStr_confWeb[] PROGMEM = "confWeb";
  65. const char PGMStr_confMqtt[] PROGMEM = "confMqtt";
  66. const char PGMStr_confBas[] PROGMEM = "confBas";
  67. const char PGMStr_confAdv[] PROGMEM = "confAdv";
  68. const char PGMStr_confAdd[] PROGMEM = "confAdd";
  69. const char PGMStr_confTime[] PROGMEM = "confTime";
  70. const char PGMStr_confLog[] PROGMEM = "confLog";
  71. //const char PGMStr_delimiter[] PROGMEM = "--------";
  72. const char PGMStr_MQTTState_DIS[] PROGMEM = "DISABLED";
  73. const char PGMStr_MQTTState_M4[] PROGMEM = "CONNECTION_TIMEOUT";
  74. const char PGMStr_MQTTState_M3[] PROGMEM = "CONNECTION_LOST";
  75. const char PGMStr_MQTTState_M2[] PROGMEM = "CONNECT_FAILED";
  76. const char PGMStr_MQTTState_M1[] PROGMEM = "DISCONNECTED";
  77. const char PGMStr_MQTTState_0[] PROGMEM = "CONNECTED";
  78. const char PGMStr_MQTTState_1[] PROGMEM = "CONNECT_BAD_PROTOCOL";
  79. const char PGMStr_MQTTState_2[] PROGMEM = "CONNECT_BAD_CLIENT_ID";
  80. const char PGMStr_MQTTState_3[] PROGMEM = "CONNECT_UNAVAILABLE";
  81. const char PGMStr_MQTTState_4[] PROGMEM = "CONNECT_BAD_CREDENTIALS";
  82. const char PGMStr_MQTTState_5[] PROGMEM = "CONNECT_UNAUTHORIZED";
  83. const char *const PGMStr_MQTTStates[] PROGMEM =
  84. {
  85. PGMStr_MQTTState_M4,
  86. PGMStr_MQTTState_M3,
  87. PGMStr_MQTTState_M2,
  88. PGMStr_MQTTState_M1,
  89. PGMStr_MQTTState_0,
  90. PGMStr_MQTTState_1,
  91. PGMStr_MQTTState_2,
  92. PGMStr_MQTTState_3,
  93. PGMStr_MQTTState_4,
  94. PGMStr_MQTTState_5,
  95. };
  96. char mqttCurrentStateName[25];
  97. //---------------------------------------------------------------------------------------------------------------------------------------------
  98. PushButton buttonPlus = PushButton(PIN_BUTTON_PLUS, ENABLE_INTERNAL_PULLUP);
  99. PushButton buttonMinus = PushButton(PIN_BUTTON_MINUS, ENABLE_INTERNAL_PULLUP);
  100. PushButton buttonMode = PushButton(PIN_BUTTON_MODE, ENABLE_INTERNAL_PULLUP);
  101. PushButton pirSensor = PushButton(PIN_PIRSENSOR, PRESSED_WHEN_HIGH);
  102. bool WifiInApMode = false;
  103. unsigned long WifiApModeStartedAt;
  104. #ifdef ENABLE_FEATURE_PW_ENCRYPTION
  105. char encKey[] = PW_ENCRYPTION_KEY;
  106. #endif
  107. bool confEncryptionEnabled = false;
  108. #ifdef ENABLE_FEATURE_NTP_TIME
  109. struct tm lt; // http://www.cplusplus.com/reference/ctime/tm/
  110. //const char *const PROGMEM dayNames[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
  111. //const char *const PROGMEM dayShortNames[] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"};
  112. //const char *const PROGMEM monthNames[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
  113. //const char *const PROGMEM monthShortNames[] = {"Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"};
  114. #endif
  115. // config variables - do not change here!
  116. // confDevWiFi
  117. struct confDataDevWiFi
  118. {
  119. char deviceName[33]; // device name - for web interface and AP-Mode SSID
  120. char hostName[33]; // announced hostname on WiFi connection
  121. char WiFiSSID1[33];
  122. char WiFiPW1[64];
  123. char WiFiSSID2[33];
  124. char WiFiPW2[64];
  125. char WiFiAPModeSSID[33]; // generated, not set via config
  126. char WiFiAPModePassword[64];
  127. uint16_t WiFiAPModeTimeout;
  128. uint16_t WiFiRetryInterval;
  129. uint16_t WiFiConnCheckInterval;
  130. uint16_t WiFiRebootOnNoConnect;
  131. bool wasChanged;
  132. } confDevWiFi;
  133. // confWeb
  134. struct confDataWeb
  135. {
  136. char http_token[31];
  137. char http_user[31];
  138. char http_pass[31];
  139. bool http_user_auth;
  140. char http_user1[31];
  141. char http_pass1[31];
  142. char http_user2[31];
  143. char http_pass2[31];
  144. bool wConsole;
  145. bool wsConsole;
  146. bool wasChanged;
  147. } confWeb;
  148. // confMqtt
  149. struct confDataMqtt
  150. {
  151. bool mqtt_enable;
  152. char mqtt_server[41];
  153. uint16_t mqtt_port;
  154. char mqtt_user[31];
  155. char mqtt_pass[31];
  156. char mqtt_topic_in[51]; // MQTT in topic for commands
  157. char mqtt_topic_out[51]; // MQTT out base topic, will be extended by various value names
  158. char mqtt_willTopic[51]; // MQTT Last Will topic
  159. uint8_t mqtt_willQos; // MQTT Last Will topic QOS
  160. bool mqtt_willRetain; // MQTT Last Will retain
  161. char mqtt_willMsg[31]; // MQTT Last Will payload
  162. char mqtt_connMsg[31];
  163. bool mqtt_outRetain; // send MQTT out with retain flag
  164. bool mqtt_outRetain_sensors; // send MQTT out with retain flag
  165. uint8_t mqtt_outPubInterval;
  166. uint8_t mqtt_outPubInterval_sensors;
  167. bool mqtt_enable_heartbeat;
  168. unsigned long mqtt_heartbeat_maxage_reconnect;
  169. unsigned long mqtt_heartbeat_maxage_reboot;
  170. bool wasChanged;
  171. } confMqtt;
  172. // confBas
  173. struct confDataBas
  174. {
  175. float setTempMin; // minimal temperature that can be set
  176. float setTempMax; // maximal temperature that can be set
  177. bool autoSaveSetTemp;
  178. bool autoSaveHeatingMode;
  179. bool saveToMqttRetained;
  180. uint16_t measureInterval; // interval for temp/hum measurement
  181. uint16_t displayInterval; // interval for display updates (if out-temp is
  182. // active, display will toggle in this interval)
  183. uint16_t displayTimeout; // display timeout after keypress (illumination)
  184. bool PIR_enablesDisplay; // PIR sensor enables display illumination
  185. bool PIR_enablesDisplay_preset0only;
  186. bool togglingTempHumAIDisplay;
  187. bool wasChanged;
  188. } confBas;
  189. // confAdv
  190. struct confDataAdv
  191. {
  192. float hysteresis; // hysteresis, normally 0.1 - 0.5
  193. uint16_t heatingMinOffTime; // minimal time the heating keeps turned off in
  194. // s
  195. float tempCorrVal; // correction value for
  196. // temperature sensor reading
  197. int humCorrVal; // correction value for humidity sensor reading
  198. float setTempDecreaseVal; // decreases the set temp to overcome further
  199. // temperature rise when the heating is already
  200. // switched off
  201. char offMessage[15];
  202. char iTempLabel[2];
  203. char oTempLabel[2];
  204. char modeName0[15];
  205. char modeName1[15];
  206. char psetName0[15];
  207. char psetName1[15];
  208. char psetName2[15];
  209. int pauseTout;
  210. bool wasChanged;
  211. } confAdv;
  212. // confAdd
  213. struct confDataAdd
  214. {
  215. char mqtt_topic_pir[51];
  216. char mqtt_payload_pir_on[10];
  217. char mqtt_payload_pir_off[10];
  218. char outTemp_topic_in[51];
  219. char outHum_topic_in[51];
  220. bool wasChanged;
  221. } confAdd;
  222. // confTime
  223. struct confDataTime
  224. {
  225. bool ntpEnable;
  226. char timeZoneStr[50];
  227. char ntpServer1[31];
  228. char ntpServer2[31];
  229. unsigned long ntpSyncInterval;
  230. bool wasChanged;
  231. } confTime;
  232. // confLog
  233. struct confDataLog
  234. {
  235. uint8_t logLevelSerial;
  236. uint8_t logLevelWeb;
  237. uint8_t logLevelMqtt;
  238. uint8_t logLevelSyslog;
  239. bool logWebRequests;
  240. bool wasChanged;
  241. } confLog;
  242. // Uptime
  243. struct sysUptimeStruct
  244. {
  245. unsigned int day = 0;
  246. unsigned int hour = 0;
  247. unsigned int min = 0;
  248. unsigned int sec = 0;
  249. unsigned int highMillis = 0;
  250. unsigned int rollover = 0;
  251. char uptimeStr[16];
  252. } sysUptime;
  253. bool mqtt_tempDisabled_credentialError = false;
  254. char mqtt_topic_in_cmd[61];
  255. char mqtt_topic_in_setTemp[61];
  256. char mqtt_topic_in_setMode[61];
  257. char mqtt_topic_in_setPreset[61];
  258. char mqtt_topic_in_setPause[61];
  259. // set values
  260. float setTemp = DEFAULT_SETTEMP;
  261. float setTempLow = DEFAULT_SETTEMP_LOW; // set temperature in night/low mode
  262. float setTempLow2 = DEFAULT_SETTEMP_LOW2; // set temperature in night/low mode
  263. float currSetTemp = DEFAULT_SETTEMP;
  264. float currActualSetTemp = DEFAULT_SETTEMP;
  265. uint8_t heatingMode = DEFAULT_HEATINGMODE; // 0 = off, 1 = heat
  266. uint16_t heatingPause = 0;
  267. uint8_t preset = DEFAULT_PRESET; // 0 = normal/day, 1 = night/reduction 1, 2 =
  268. // reduction 2 (long term leave)
  269. // saved set values (same as above, held in memory additionally to prevent
  270. // saving unchanged values)
  271. float setTempSaved;
  272. float setTempLowSaved;
  273. float setTempLow2Saved;
  274. uint8_t heatingModeSaved;
  275. uint8_t presetSaved;
  276. // global pre set conf variables - not changeable via configuration
  277. float setTempLowMin = SETTEMP_LOW_MIN;
  278. float setTempLowMax = SETTEMP_LOW_MAX;
  279. //uint16_t debounceTime = BUTTON_DEBOUNCE_TIME; // was never used - now declared in buttonhandling.ino
  280. //uint16_t buttonHoldTime = BUTTON_HOLD_TIME; // was never used - now declared in buttonhandling.ino
  281. unsigned long maxMeasurementAge = MAX_MEASUREMENT_AGE;
  282. unsigned long maxMeasurementAgeOut = MAX_MEASUREMENT_AGE_OUT;
  283. // global variables for program flow
  284. float currTemp; // last reading from DHT sensor with smoothing
  285. float currTemp_raw; // last reading from DHT sensor (raw)
  286. uint16_t currHum; // last reading from DHT sensor with smoothing
  287. uint16_t currHum_raw; // last reading from DHT sensor (raw)
  288. bool turnHeatingOn = false; // true if heating is active (relais switched on)
  289. //bool heatingLockTimeActive = false; // true if heating is not active due to active lock time
  290. uint16_t heatingLockTime = 0;
  291. unsigned long heatingLastOnMillis; // last time heating was switched on
  292. unsigned long heatingLastOffMillis; // last time heating was switched off
  293. float outTemp; // outside temp (via MQTT if enabled and in-topic configured)
  294. uint16_t outHum; // outside temp (via MQTT if enabled and in-topic configured)
  295. unsigned long outTempHumLastUpdate; // last reading from out temp/hum source
  296. char outTemp_newValue[6];
  297. bool outTemp_parseNewValue;
  298. char outHum_newValue[4];
  299. bool outHum_parseNewValue;
  300. char currentModeName[15];
  301. char currentPresetName[15];
  302. uint16_t displayInterval;
  303. uint8_t whichTempToDisplay; // 1=temp inside (from DHT sensor), 2= temp outside
  304. // (via MQTT) - if out temp/hum available this value
  305. // and the displayed value pair toggles with every
  306. // displayInterval
  307. unsigned long lastMeasure = 0; // millis of last temp/hum measurement
  308. unsigned long lastDisplayUpdate = 0; // millis of last display update
  309. unsigned long lastDisplayToggle = 0; // millis of last display toggle
  310. unsigned long lastTempUpdate = 0; // last update time of DHT reading
  311. //char msg[101]; // buffer MQTT in payload
  312. //char topic[70]; // buffer MQTT in topic
  313. bool displayActive = false; // gets true when button is pressed. display light
  314. // gets switched on until timeout. button actions
  315. // are only performed while display is active
  316. bool PIRSensorOn = false;
  317. unsigned long heatingOnTime, heatingOffTime;
  318. //bool config_was_changed = false;
  319. bool configChangedRestartRequired = false;
  320. bool configChangedMqttConnResetRequired = false;
  321. unsigned long lastUpdate_setTemp = 0; // set to millis() every time setTemp value is changed
  322. unsigned long lastUpdate_setTempLow = 0; // set to millis() every time setTemp value is changed
  323. unsigned long lastUpdate_setTempLow2 = 0; // set to millis() every time setTemp value is changed
  324. unsigned long lastUpdate_heatingMode = 0; // set to millis() every time heatingMode value is changed
  325. unsigned long lastUpdate_preset = 0; // set to millis() every time preset value is changed
  326. char cmdPayload[101]; // buffer for commands
  327. bool cmdInQueue = false; // command is queued and will be processed next loop() run
  328. // not used any more, now triggered directly
  329. //bool saveConfigToFlash = false; // conf is saved in next loop() run
  330. //bool saveConfig2ToFlash = false; // conf2 is saved in next loop() run
  331. // ----
  332. uint16_t saveValuesTimeout = 5000;
  333. unsigned long lastValueChange; // is set to millis() whenever setTemp value
  334. // and/or heatingMode value is changed. used for
  335. // autoSave function with hardcoded 5s timeout
  336. unsigned long lastConfigChange;
  337. bool lastConfigChangeNoteAlreadyDone = false;
  338. bool setTempAlreadySaved = true; // only save if not yet done
  339. bool setTempLowAlreadySaved = true; // only save if not yet done
  340. bool setTempLow2AlreadySaved = true; // only save if not yet done
  341. bool heatingModeAlreadySaved = true; // only save if not yet done
  342. bool presetAlreadySaved = true; // only save if not yet done
  343. unsigned long lastRun = 0;
  344. uint16_t count100ms = 0;
  345. uint16_t countSeconds = 0;
  346. uint16_t countMeasureInterval = 0;
  347. uint16_t countDisplayInterval = 0;
  348. uint16_t displayOverlayMsgTimeout = 2;
  349. unsigned long mqttLastReconnectAttempt = 0;
  350. uint16_t mqttReconnectAttempts = 0;
  351. uint16_t mqttReconnects = 0;
  352. bool mqttConnected = false;
  353. unsigned long mqttLastHeartbeat;
  354. bool mqttInTopicSubscribed = false;
  355. bool pendingRestart = false;
  356. bool doRestart = false;
  357. unsigned long pendingRestart_lastMillis = 0;
  358. bool displayShowFullscreenMsg = false;
  359. // unsigned long displayShowFullscreenMsg_lastMillis = 0;
  360. bool pendingPresetToggle = false;
  361. bool updateDisplayImmediately = false;
  362. uint8_t pendingPreset;
  363. char pendingPresetName[15];
  364. bool displayShowLine2OverlayMsg = false;
  365. // if command "debugmode 1" is called...
  366. bool sysInfoEverySecond = false;
  367. #ifdef ENABLE_FEATURE_WEB_CONSOLE
  368. char webLogBuffer[WEB_CONSOLE_BUFFER_SIZE];
  369. unsigned int webLogBuffer_index = 0;
  370. #endif
  371. // END global variables
  372. DHT dht(PIN_DHTSENSOR, DHTTYPE);
  373. LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDLINES);
  374. #ifdef USE_MQTT_TLS
  375. //WiFiClientSecure wifiClient;
  376. BearSSL::WiFiClientSecure wifiClient;
  377. #else
  378. WiFiClient wifiClient;
  379. #endif
  380. PubSubClient mqttclient(wifiClient);
  381. ESP8266WebServer httpServer(80);
  382. // WebSocketsServer
  383. #ifdef ENABLE_FEATURE_WEB_CONSOLE_WEBSOCKETS
  384. WebSocketsServer webSocket(81);
  385. unsigned long int wsValidSessionId = 0;
  386. #endif
  387. DNSServer dnsServer;
  388. PersWiFiManager persWM(httpServer, dnsServer);
  389. #ifdef ENABLE_FEATURE_HTTP_UPDATER
  390. ESP8266HTTPUpdateServer httpUpdater;
  391. #endif
  392. // FUNCTION PROTOTYPES
  393. #ifdef ENABLE_FEATURE_NTP_TIME
  394. void updateTime();
  395. bool setupTime();
  396. void syncClock(bool force = false);
  397. #endif
  398. char *getUptimeStr(bool includeSeconds = false);
  399. void sendLog(const char *msg, uint8_t loglevel = 1);
  400. void sendLog(const __FlashStringHelper *msg, uint8_t loglevel = 1);
  401. void mqttCallback(char *topic, byte *payload, uint16_t length);
  402. char *getTimeStringFromSeconds(unsigned int inSeconds);
  403. // END - FUNCTION PROTOTYPES
  404. // MAIN FUNCTIONS
  405. void setup()
  406. {
  407. Serial.begin(115200);
  408. delay(50);
  409. Serial.println();
  410. Serial.print(PGMStr_FIRMWARE_NAME);
  411. Serial.print(F(" v"));
  412. Serial.print(PGMStr_FIRMWARE_VERSION);
  413. Serial.println(F(" starting..."));
  414. pinMode(PIN_RELAIS, OUTPUT);
  415. digitalWrite(PIN_RELAIS, !RELAISONSTATE);
  416. setupInputsButtons();
  417. // set conf default values
  418. loadConf_defaults();
  419. //if (serialdebug)
  420. // Serial.println("default config values loaded..");
  421. sendLog(F("CONF: default config loaded."), LOGLEVEL_INFO);
  422. initDisplay();
  423. sendLog(F("Mounting SPIFFS..."), LOGLEVEL_INFO);
  424. if (!SPIFFS.begin())
  425. {
  426. sendLog(F("Failed to mount SPIFFS"), LOGLEVEL_ERROR);
  427. return;
  428. }
  429. #ifdef FORCE_SPIFFS_FORMAT
  430. SPIFFS_format();
  431. #endif
  432. SPIFFS_formatIfIsnt();
  433. //SPIFFS_listFiles();
  434. #ifdef ENABLE_FEATURE_PW_ENCRYPTION
  435. confCheckEncrypted();
  436. #endif
  437. loadConf_all();
  438. loadSavedValues();
  439. // if configuration returned empty strings - use the defaults where a values
  440. // is necessary if (strlen(deviceName) < 4) strlcpy(deviceName, DEVICE_NAME,
  441. // 31);
  442. loadConf_restoreDefaultWhenMissing();
  443. updateCurrentHeatingModeName();
  444. updateCurrentPresetName();
  445. // initialize DHT11/22 temp/hum sensor
  446. dht.begin();
  447. if (strlen(confDevWiFi.hostName) >= 4)
  448. { // if no hostname is set WiFi manager will create a unique one automatically
  449. // based on MAC address
  450. WiFi.hostname(confDevWiFi.hostName);
  451. }
  452. // optional code handlers to run everytime wifi is connected...
  453. persWM.onConnect([]() {
  454. //Serial.print(F("WiFi: connected to '"));
  455. //Serial.print(WiFi.SSID());
  456. //Serial.print(F("' with IP: "));
  457. //Serial.println(WiFi.localIP());
  458. //char buf[60];
  459. //sprintf(buf, "%s: %s '%s' %s: '%s'", PGMStr_WiFi, PGMStr_connectedTo, WiFi.SSID().c_str(), PGMStr_withIP, WiFi.localIP().toString().c_str());
  460. //sendLog(buf, LOGLEVEL_INFO);
  461. printIpcfg();
  462. WifiInApMode = false;
  463. #ifdef ENABLE_FEATURE_NTP_TIME
  464. if (confTime.ntpEnable)
  465. setupTime();
  466. #endif
  467. displayShowWifiConnected();
  468. });
  469. //...or AP mode is started
  470. persWM.onAp([]() {
  471. //Serial.print(F("WiFi: AP mode, SSID: '"));
  472. //Serial.print(persWM.getApSsid());
  473. //if (strlen(confDevWiFi.WiFiAPModePassword) >= 4)
  474. //{
  475. // Serial.print("', PW: '");
  476. // Serial.print(confDevWiFi.WiFiAPModePassword);
  477. //}
  478. //Serial.println("'");
  479. char buf[60];
  480. sprintf(buf, "%s: AP-MODE started, SSID '%s', PW: '%s'", PGMStr_WiFi, persWM.getApSsid().c_str(), confDevWiFi.WiFiAPModePassword);
  481. sendLog(buf, LOGLEVEL_INFO);
  482. WifiInApMode = true;
  483. WifiApModeStartedAt = millis();
  484. displayShowWifiConnectionError();
  485. });
  486. persWM.onApOff([]() {
  487. //Serial.println(F("WiFi: AP mode stopped"));
  488. sendLog(F("WiFi: AP-MODE stopped"), LOGLEVEL_INFO);
  489. });
  490. // sets network name and password for AP mode
  491. // sprintf(WiFiAPModeSSID, "%s-%s", FIRMWARE_SHORTNAME, deviceName);
  492. if (strlen(confDevWiFi.deviceName) >= 8)
  493. strlcpy(confDevWiFi.WiFiAPModeSSID, confDevWiFi.deviceName, sizeof(confDevWiFi.WiFiAPModeSSID));
  494. else
  495. {
  496. byte mac[6];
  497. WiFi.macAddress(mac);
  498. sprintf(confDevWiFi.WiFiAPModeSSID, "%s-%02X%02X", FIRMWARE_SHORTNAME, (uint8_t)mac[4], (uint8_t)mac[5]);
  499. }
  500. //Serial.print(F("WiFi: AP-SSID name: "));
  501. //Serial.println(confDevWiFi.WiFiAPModeSSID);
  502. if (strlen(confDevWiFi.WiFiAPModePassword) < 5)
  503. {
  504. persWM.setApCredentials(confDevWiFi.WiFiAPModeSSID);
  505. //sendLog("WIFI-AP: open network");
  506. }
  507. else
  508. {
  509. persWM.setApCredentials(confDevWiFi.WiFiAPModeSSID, confDevWiFi.WiFiAPModePassword);
  510. //sendLog("WIFI-AP: with password");
  511. }
  512. //Serial.print(F("WiFi: SSID 1: ")); Serial.println(confDevWiFi.WiFiSSID1); //Serial.print("', PW: '"); Serial.print(confDevWiFi.WiFiPW1); Serial.println("'");
  513. //Serial.print(F("WiFi: SSID 2: ")); Serial.println(confDevWiFi.WiFiSSID2); //Serial.print("', PW: '"); Serial.print(confDevWiFi.WiFiPW2); Serial.println("'");
  514. persWM.setWifi1Credentials(confDevWiFi.WiFiSSID1, confDevWiFi.WiFiPW1);
  515. persWM.setWifi2Credentials(confDevWiFi.WiFiSSID2, confDevWiFi.WiFiPW2);
  516. persWM.setHttpCredentials(confWeb.http_user, confWeb.http_pass);
  517. persWM.setApTimeout(confDevWiFi.WiFiAPModeTimeout);
  518. persWM.setConnCheckInterval(confDevWiFi.WiFiConnCheckInterval);
  519. persWM.setForceRetryWifi1Interval(confDevWiFi.WiFiRetryInterval);
  520. persWM.setRebootOnNoConnect(confDevWiFi.WiFiRebootOnNoConnect);
  521. // make connecting/disconnecting non-blocking
  522. persWM.setConnectNonBlock(true);
  523. // in non-blocking mode, program will continue past this point without waiting
  524. persWM.begin();
  525. #ifdef USE_MQTT_TLS
  526. //randomSeed(micros());
  527. //wifiClient.setFingerprint(MQTT_TLS_fingerprint);
  528. wifiClient.setInsecure();
  529. wifiClient.allowSelfSignedCerts();
  530. wifiClient.setCiphersLessSecure();
  531. #endif
  532. delay(500);
  533. httpServerInit();
  534. #ifdef ENABLE_FEATURE_WEB_CONSOLE_WEBSOCKETS
  535. if (confWeb.wsConsole)
  536. startWebSocketServer();
  537. #endif
  538. if (confMqtt.mqtt_enable)
  539. {
  540. mqttPrepareSubscribeTopics();
  541. mqttClientInit();
  542. }
  543. sendLog(F("DEV: setup complete."), LOGLEVEL_INFO);
  544. } // void setup
  545. void loop()
  546. {
  547. checkMillis();
  548. persWM.handleWiFi(); // in non-blocking mode, handleWiFi must be called in the
  549. // main loop
  550. yield();
  551. mqttHandleConnection();
  552. yield();
  553. outTempHum_updateOnNewValue();
  554. yield();
  555. dnsServer.processNextRequest();
  556. httpServer.handleClient();
  557. buttonPlus.update();
  558. buttonMinus.update();
  559. buttonMode.update();
  560. pirSensor.update();
  561. yield();
  562. evalCmd();
  563. yield();
  564. if (Serial.available())
  565. {
  566. serialEvent();
  567. yield();
  568. }
  569. if (updateDisplayImmediately)
  570. {
  571. updateDisplayImmediately = false;
  572. updateDisplay();
  573. }
  574. #ifdef ENABLE_FEATURE_WEB_CONSOLE_WEBSOCKETS
  575. if (confWeb.wsConsole)
  576. {
  577. if (WiFi.status() == WL_CONNECTED)
  578. {
  579. webSocket.loop();
  580. }
  581. else
  582. {
  583. webSocket.disconnect();
  584. }
  585. }
  586. #endif
  587. } // void loop
  588. //#ifdef USE_MQTT_TLS
  589. //void verifytls() {
  590. // // Use WiFiClientSecure class to create TLS connection
  591. // Serial.print(F("MQTT: trying TLS connection to "));
  592. // Serial.println(confMqtt.mqtt_server);
  593. // if (!wifiClient.connect(confMqtt.mqtt_server, confMqtt.mqtt_port)) {
  594. // Serial.println("connection failed");
  595. // return;
  596. // }
  597. //
  598. // if (wifiClient.verify(MQTT_TLS_fingerprint, confMqtt.mqtt_server)) {
  599. // Serial.println("certificate matches");
  600. // } else {
  601. // Serial.println("certificate doesn't match");
  602. // }
  603. //}
  604. //#endif