mqtt.ino 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*#include <Arduino.h>*/
  2. #define MQTT_RECONNECT_INTERVAL_3_TRIES 15000
  3. #define MQTT_RECONNECT_INTERVAL_10_TRIES 60000
  4. #define MQTT_RECONNECT_INTERVAL_LONG 300000
  5. bool mqttHeartbeatReceived = false;
  6. // MQTT callback
  7. void mqttCallback(char *topic, unsigned char *payload, uint16_t length)
  8. {
  9. // Serial.print("MQTT payload arrived [");
  10. // Serial.print(topic);
  11. // Serial.print("] ");
  12. // for (int i = 0; i < length; i++) {
  13. // Serial.print((char)payload[i]);
  14. // }
  15. // Serial.println();
  16. //char tmp_topic_pub[51];
  17. //char tmp_payload_pub[51];
  18. if (strcmp(topic, mqtt_topic_in_cmd) == 0)
  19. { //if topic = mqtt_topic_in_cmd
  20. int len;
  21. if (length < sizeof(cmdPayload))
  22. len = length; // if input is bigger than dest buffer, cut
  23. else
  24. len = sizeof(cmdPayload) - 1;
  25. for (int i = 0; i < len; i++)
  26. {
  27. cmdPayload[i] = (char)payload[i];
  28. }
  29. cmdPayload[len] = '\0';
  30. // Serial.print("cmdPayload:");
  31. // Serial.println(cmdPayload);
  32. //if (serialdebug)
  33. //{
  34. // Serial.print("MQTT: received '");
  35. // Serial.print(mqtt_topic_in_cmd);
  36. // Serial.print("' - '");
  37. // Serial.print(cmdPayload);
  38. // Serial.println("'");
  39. //}
  40. //if (mqttdebug)
  41. //{
  42. // sprintf(tmp_topic_pub, "%s/%s", confMqtt.mqtt_topic_out, "mqtt_received");
  43. // sprintf(tmp_payload_pub, "%s: %s", mqtt_topic_in_cmd, cmdPayload);
  44. // mqttclient.publish(tmp_topic_pub, tmp_payload_pub);
  45. //}
  46. if (strncmp(cmdPayload, "HEARTBEAT", 9) == 0)
  47. {
  48. mqttLastHeartbeat = millis();
  49. mqttHeartbeatReceived = true;
  50. mqttConnected = true;
  51. }
  52. else
  53. {
  54. cmdInQueue = true; // payload is processed in "commands"
  55. }
  56. } //if topic = mqtt_topic_in_cmd
  57. if (strcmp(topic, mqtt_topic_in_setTemp) == 0)
  58. { //if topic = mqtt_topic_in_setTemp
  59. int len;
  60. if (length < sizeof(cmdPayload))
  61. len = length; // if input is bigger than dest buffer, cut
  62. else
  63. len = sizeof(cmdPayload) - 1;
  64. for (int i = 0; i < len; i++)
  65. {
  66. cmdPayload[i] = (char)payload[i];
  67. }
  68. //cmdPayload[len + 1] = '\0';
  69. cmdPayload[len] = '\0';
  70. // Serial.print("cmdPayload:");
  71. // Serial.println(cmdPayload);
  72. char tmpPayload[11];
  73. strlcpy(tmpPayload, cmdPayload, 10);
  74. float valueFloat;
  75. valueFloat = round(atof(tmpPayload) * 2.0) / 2.0;
  76. setTempTo(valueFloat);
  77. //if (serialdebug)
  78. //{
  79. // Serial.print("MQTT: received '");
  80. // Serial.print(mqtt_topic_in_setTemp);
  81. // Serial.print("' - '");
  82. // Serial.print(cmdPayload);
  83. // Serial.println("'");
  84. //}
  85. //if (mqttdebug)
  86. //{
  87. // sprintf(tmp_topic_pub, "%s/%s", confMqtt.mqtt_topic_out, "mqtt_received");
  88. // sprintf(tmp_payload_pub, "%s: %s", mqtt_topic_in_setTemp, cmdPayload);
  89. // mqttclient.publish(tmp_topic_pub, tmp_payload_pub);
  90. //}
  91. char buf[50];
  92. sprintf(buf, "MQTT IN: setTemp to %2.1f", valueFloat);
  93. sendLog(buf, LOGLEVEL_INFO);
  94. cmdInQueue = false; // payload is processed in "commands"
  95. } //if topic = mqtt_topic_in_setTemp
  96. if (strcmp(topic, mqtt_topic_in_setMode) == 0)
  97. { //if topic = mqtt_topic_in_setMode
  98. uint8_t len;
  99. if (length < sizeof(cmdPayload))
  100. len = length; // if input is bigger than dest buffer, cut
  101. else
  102. len = sizeof(cmdPayload) - 1;
  103. for (int i = 0; i < len; i++)
  104. {
  105. cmdPayload[i] = (char)payload[i];
  106. }
  107. //cmdPayload[len + 1] = '\0';
  108. cmdPayload[len] = '\0';
  109. // Serial.print("cmdPayload:");
  110. // Serial.println(cmdPayload);
  111. char tmpPayload[21];
  112. strlcpy(tmpPayload, cmdPayload, sizeof(tmpPayload));
  113. strlwr(tmpPayload);
  114. unsigned char tmpHeatMode = 100;
  115. char tmpModename0[15];
  116. char tmpModename1[15];
  117. strlcpy(tmpModename0, confAdv.modeName0, sizeof(tmpModename0));
  118. strlcpy(tmpModename1, confAdv.modeName1, sizeof(tmpModename1));
  119. strlwr(tmpModename0);
  120. strlwr(tmpModename1);
  121. if (strcmp(tmpPayload, tmpModename0) == 0)
  122. tmpHeatMode = 0;
  123. else if (strcmp(tmpPayload, tmpModename1) == 0)
  124. tmpHeatMode = 1;
  125. else if (strcmp(tmpPayload, "off") == 0)
  126. tmpHeatMode = 0;
  127. else if (strcmp(tmpPayload, "aus") == 0)
  128. tmpHeatMode = 0;
  129. else if (strcmp(tmpPayload, "on") == 0)
  130. tmpHeatMode = 1;
  131. else if (strcmp(tmpPayload, "ein") == 0)
  132. tmpHeatMode = 1;
  133. else if (atoi(tmpPayload) == 0)
  134. tmpHeatMode = 0;
  135. else if (atoi(tmpPayload) == 1)
  136. tmpHeatMode = 1;
  137. if (tmpHeatMode == 0 || tmpHeatMode == 1)
  138. {
  139. setHeatingmodeTo(tmpHeatMode);
  140. //if (serialdebug)
  141. //{
  142. // Serial.print(F("set heatmode to: "));
  143. // Serial.println(tmpHeatMode);
  144. //}
  145. //if (serialdebug)
  146. //{
  147. // Serial.print("MQTT: received '");
  148. // Serial.print(mqtt_topic_in_setMode);
  149. // Serial.print("' - '");
  150. // Serial.print(cmdPayload);
  151. // Serial.println("'");
  152. //}
  153. //if (mqttdebug)
  154. //{
  155. // sprintf(tmp_topic_pub, "%s/%s", confMqtt.mqtt_topic_out, "mqtt_received");
  156. // sprintf(tmp_payload_pub, "%s: %s", mqtt_topic_in_setMode, cmdPayload);
  157. // mqttclient.publish(tmp_topic_pub, tmp_payload_pub);
  158. //}
  159. char buf[50];
  160. sprintf(buf, "MQTT IN: setMode to %u", tmpHeatMode);
  161. sendLog(buf, LOGLEVEL_INFO);
  162. }
  163. cmdInQueue = false; // payload is processed in "commands"
  164. } //if topic = mqtt_topic_in_setMode
  165. if (strcmp(topic, mqtt_topic_in_setPreset) == 0)
  166. { //if topic = mqtt_topic_in_setPreset
  167. char tmpPayload[21];
  168. char tmpPresetName0[15];
  169. char tmpPresetName1[15];
  170. char tmpPresetName2[15];
  171. uint16_t len;
  172. unsigned char tmpPreset = 100;
  173. if (length < sizeof(cmdPayload))
  174. len = length; // if input is bigger than dest buffer, cut
  175. else
  176. len = sizeof(cmdPayload) - 1;
  177. for (unsigned char i = 0; i < len; i++)
  178. {
  179. cmdPayload[i] = (char)payload[i];
  180. }
  181. //cmdPayload[len + 1] = '\0';
  182. cmdPayload[len] = '\0';
  183. // Serial.print("cmdPayload:");
  184. // Serial.println(cmdPayload);
  185. strlcpy(tmpPayload, cmdPayload, sizeof(tmpPayload));
  186. strlwr(tmpPayload);
  187. strlcpy(tmpPresetName0, confAdv.psetName0, sizeof(tmpPresetName0));
  188. strlcpy(tmpPresetName1, confAdv.psetName1, sizeof(tmpPresetName1));
  189. strlcpy(tmpPresetName2, confAdv.psetName2, sizeof(tmpPresetName2));
  190. strlwr(tmpPresetName0);
  191. strlwr(tmpPresetName1);
  192. strlwr(tmpPresetName2);
  193. if (strcmp(tmpPayload, tmpPresetName0) == 0)
  194. tmpPreset = 0;
  195. else if (strcmp(tmpPayload, tmpPresetName1) == 0)
  196. tmpPreset = 1;
  197. else if (strcmp(tmpPayload, tmpPresetName2) == 0)
  198. tmpPreset = 2;
  199. else if (strcmp(tmpPayload, "none") == 0)
  200. tmpPreset = 0;
  201. else if (strcmp(tmpPayload, "red1") == 0)
  202. tmpPreset = 1;
  203. else if (strcmp(tmpPayload, "red2") == 0)
  204. tmpPreset = 2;
  205. else if (atoi(tmpPayload) == 0)
  206. tmpPreset = 0;
  207. else if (atoi(tmpPayload) == 1)
  208. tmpPreset = 1;
  209. else if (atoi(tmpPayload) == 2)
  210. tmpPreset = 2;
  211. if (tmpPreset <= 2)
  212. {
  213. setPresetTo(tmpPreset);
  214. //if (serialdebug)
  215. //{
  216. // Serial.print(F("set preset to: "));
  217. // Serial.println(tmpPreset);
  218. //}
  219. //if (serialdebug)
  220. //{
  221. // Serial.print(F("MQTT: received '"));
  222. // Serial.print(mqtt_topic_in_setPreset);
  223. // Serial.print("' - '");
  224. // Serial.print(cmdPayload);
  225. // Serial.println("'");
  226. //}
  227. //if (mqttdebug)
  228. //{
  229. // sprintf(tmp_topic_pub, "%s/%s", confMqtt.mqtt_topic_out, "mqtt_received");
  230. // sprintf(tmp_payload_pub, "%s: %s", mqtt_topic_in_setPreset, cmdPayload);
  231. // mqttclient.publish(tmp_topic_pub, tmp_payload_pub);
  232. //}
  233. char buf[50];
  234. sprintf(buf, "MQTT IN: setPreset to %s", cmdPayload);
  235. sendLog(buf, LOGLEVEL_INFO);
  236. }
  237. cmdInQueue = false; // payload is processed in "commands"
  238. } //if topic = mqtt_topic_in_setPreset
  239. if (strcmp(topic, confAdd.outTemp_topic_in) == 0)
  240. { //if topic = outTemp_topic_in
  241. int len;
  242. if (length < 6)
  243. len = length; // if input is bigger than dest buffer, cut
  244. else
  245. len = 5;
  246. for (int i = 0; i < len; i++)
  247. {
  248. outTemp_newValue[i] = (char)payload[i];
  249. }
  250. //outTemp_newValue[len + 1] = '\0';
  251. outTemp_newValue[len] = '\0';
  252. outTemp_parseNewValue = true;
  253. } //if topic = outTemp_topic_in
  254. if (strcmp(topic, confAdd.outHum_topic_in) == 0)
  255. { //if topic = outHum_topic_in
  256. int len;
  257. if (length < 4)
  258. len = length; // if input is bigger than dest buffer, cut
  259. else
  260. len = 3;
  261. for (int i = 0; i < len; i++)
  262. {
  263. outHum_newValue[i] = (char)payload[i];
  264. }
  265. //outHum_newValue[len + 1] = '\0';
  266. outHum_newValue[len] = '\0';
  267. outHum_parseNewValue = true;
  268. } //if topic = outHum_topic_in
  269. } //mqttCallback
  270. void mqttPrepareSubscribeTopics()
  271. {
  272. //char tmp_topic_out[50];
  273. sprintf(mqtt_topic_in_cmd, "%s/%s", confMqtt.mqtt_topic_in, "cmd");
  274. sprintf(mqtt_topic_in_setTemp, "%s/%s", mqtt_topic_in_cmd, "setTemp");
  275. sprintf(mqtt_topic_in_setMode, "%s/%s", mqtt_topic_in_cmd, "setMode");
  276. sprintf(mqtt_topic_in_setPreset, "%s/%s", mqtt_topic_in_cmd, "setPreset");
  277. }
  278. bool mqttReconnect(void)
  279. {
  280. mqttclient.disconnect();
  281. delay(10);
  282. // Create MQTT client ID from device name
  283. //String mqttClientId = "ESP8266Client-";
  284. String mqttClientId = FIRMWARE_SHORTNAME;
  285. mqttClientId += "-";
  286. //mqttClientId += String(random(0xffff), HEX); //or random
  287. mqttClientId += String(confDevWiFi.deviceName);
  288. //if (serialdebug)
  289. // Serial.print(F("MQTT: connecting to broker '"));
  290. // Serial.print(confMqtt.mqtt_server);
  291. // Serial.print(F("' with "));
  292. boolean connRes;
  293. mqttReconnectAttempts++;
  294. char connectMode[20];
  295. if (strlen(confMqtt.mqtt_user) > 0 && strlen(confMqtt.mqtt_willTopic) == 0)
  296. {
  297. // user and password, no Last Will
  298. //if (serialdebug)
  299. // Serial.print(F("Auth, no LWT"));
  300. strlcpy(connectMode, "Auth, no LWT", sizeof(connectMode));
  301. connRes = mqttclient.connect(mqttClientId.c_str(), confMqtt.mqtt_user, confMqtt.mqtt_pass);
  302. }
  303. else if (strlen(confMqtt.mqtt_user) > 0 && strlen(confMqtt.mqtt_willTopic) > 0)
  304. {
  305. // user, password and Last Will
  306. //if (serialdebug)
  307. // Serial.print(F("Auth and LWT"));
  308. strlcpy(connectMode, "Auth and LWT", sizeof(connectMode));
  309. connRes = mqttclient.connect(mqttClientId.c_str(), confMqtt.mqtt_user, confMqtt.mqtt_pass, confMqtt.mqtt_willTopic, confMqtt.mqtt_willQos, confMqtt.mqtt_willRetain, confMqtt.mqtt_willMsg);
  310. }
  311. else if (strlen(confMqtt.mqtt_user) == 0 && strlen(confMqtt.mqtt_willTopic) > 0)
  312. {
  313. // Last Will but no user and password
  314. //if (serialdebug)
  315. // Serial.print(F("LWT, no Auth"));
  316. strlcpy(connectMode, "LWT, no Auth", sizeof(connectMode));
  317. connRes = mqttclient.connect(mqttClientId.c_str(), confMqtt.mqtt_willTopic, confMqtt.mqtt_willQos, confMqtt.mqtt_willRetain, confMqtt.mqtt_willMsg);
  318. }
  319. else
  320. {
  321. // no user, password and no Last Will
  322. //if (serialdebug)
  323. // Serial.print(F("no Auth, no LWT"));
  324. strlcpy(connectMode, "no Auth, no LWT", sizeof(connectMode));
  325. connRes = mqttclient.connect(mqttClientId.c_str());
  326. }
  327. //if (serialdebug)
  328. //{
  329. // Serial.print(F(", attempt: "));
  330. // Serial.print(mqttReconnectAttempts);
  331. // Serial.println();
  332. //}
  333. char logBuf[70];
  334. sprintf(logBuf, "MQTT: connecting to %s:%u w/ %s, attempt: %u", confMqtt.mqtt_server, confMqtt.mqtt_port, connectMode, mqttReconnectAttempts);
  335. sendLog(logBuf, LOGLEVEL_INFO);
  336. if (connRes)
  337. { // if connection was successful
  338. // if (serialdebug)
  339. // {
  340. // Serial.print(F("MQTT: connected. Reconnects: "));
  341. // Serial.println(mqttReconnects);
  342. // }
  343. //char logBuf2[50];
  344. //sprintf(logBuf2, "MQTT: connected to %s:%u, Reconnects: %u", confMqtt.mqtt_server, confMqtt.mqtt_port, mqttReconnects);
  345. //sendLog(logBuf2, LOGLEVEL_INFO);
  346. //sendLog(F("MQTT: connected. Reconnects: "), LOGLEVEL_INFO);
  347. mqttConnected = true;
  348. mqttReconnects++;
  349. mqttOnConnect();
  350. //if (serialdebug)
  351. //Serial.println("MQTT: subscribed topics:");
  352. sendLog("MQTT: subscribed topics:", LOGLEVEL_INFO);
  353. if (strlen(mqtt_topic_in_cmd) > 0)
  354. {
  355. char mqtt_topic_in_subscribe[52];
  356. sprintf(mqtt_topic_in_subscribe, "%s/%s", mqtt_topic_in_cmd, "#");
  357. if (mqttclient.subscribe(mqtt_topic_in_subscribe))
  358. {
  359. //if (serialdebug) {
  360. // Serial.print(" ");
  361. // Serial.println(mqtt_topic_in_subscribe);
  362. //}
  363. char buf[60];
  364. sprintf(buf, " %s", mqtt_topic_in_subscribe);
  365. sendLog(buf, LOGLEVEL_INFO);
  366. mqttInTopicSubscribed = true;
  367. }
  368. }
  369. if (strlen(confAdd.outTemp_topic_in) > 0)
  370. {
  371. if (mqttclient.subscribe(confAdd.outTemp_topic_in))
  372. {
  373. //if (serialdebug) {
  374. // Serial.print(" ");
  375. // Serial.println(confAdd.outTemp_topic_in);
  376. //}
  377. char buf[60];
  378. sprintf(buf, " %s", confAdd.outTemp_topic_in);
  379. sendLog(buf, LOGLEVEL_INFO);
  380. }
  381. }
  382. if (strlen(confAdd.outHum_topic_in) > 0)
  383. {
  384. if (mqttclient.subscribe(confAdd.outHum_topic_in))
  385. {
  386. //if (serialdebug) {
  387. // Serial.print(" ");
  388. // Serial.println(confAdd.outHum_topic_in);
  389. //}
  390. char buf[60];
  391. sprintf(buf, " %s", confAdd.outHum_topic_in);
  392. sendLog(buf, LOGLEVEL_INFO);
  393. }
  394. }
  395. mqttReconnectAttempts = 0;
  396. return mqttclient.connected();
  397. }
  398. else
  399. {
  400. int mqttConnRes = mqttclient.state();
  401. char logBuf[70];
  402. mqtt_updateCurrentStateName();
  403. sprintf_P(logBuf, "%s: %s, rc=%d (%s)", PGMStr_MQTT, PGMStr_connectedFailed, mqttConnRes, mqttCurrentStateName);
  404. sendLog(logBuf, LOGLEVEL_INFO);
  405. if (mqttReconnectAttempts >= 3 && (mqttConnRes == 4 || mqttConnRes == 5))
  406. {
  407. // MQTT credentials are invalid/rejected from the server - stop trying to reconnect until reboot
  408. mqtt_tempDisabled_credentialError = true;
  409. if (confLog.logLevelSerial >= LOGLEVEL_VERBOSE)
  410. {
  411. //Serial.println(F("MQTT disabled until reboot due to credential error"));
  412. sendLog(F("MQTT disabled until reboot due to credential error"), LOGLEVEL_ERROR);
  413. }
  414. }
  415. mqttConnected = false;
  416. mqttOnDisconnect();
  417. return mqttclient.connected();
  418. }
  419. } //mqttReconnect
  420. void mqttClientInit()
  421. {
  422. if (confMqtt.mqtt_enable)
  423. {
  424. mqttclient.setServer(confMqtt.mqtt_server, confMqtt.mqtt_port);
  425. mqttclient.setCallback(mqttCallback);
  426. mqttLastReconnectAttempt = 0;
  427. mqttReconnectAttempts = 0;
  428. mqtt_tempDisabled_credentialError = false;
  429. }
  430. }
  431. int lastWifiStatus;
  432. void mqttHandleConnection()
  433. {
  434. if (mqttHeartbeatReceived)
  435. {
  436. mqttHeartbeatReceived = false;
  437. sendLog(F("MQTT: received HEARTBEAT - resetting timer..."), LOGLEVEL_VERBOSE);
  438. }
  439. int currWifiStatus = WiFi.status();
  440. if (currWifiStatus != lastWifiStatus)
  441. {
  442. lastWifiStatus = currWifiStatus;
  443. //Serial.print("WiFi status changed to: ");
  444. //Serial.println(currWifiStatus);
  445. }
  446. if (confMqtt.mqtt_enable && !mqtt_tempDisabled_credentialError && currWifiStatus == WL_CONNECTED)
  447. {
  448. // MQTT reconnect if not connected (nonblocking)
  449. boolean doReconnect = false;
  450. if (!mqttclient.connected())
  451. doReconnect = true;
  452. if (mqttInTopicSubscribed && confMqtt.mqtt_heartbeat_maxage_reconnect > 0)
  453. { // if mqtt_topic_in is subscribed
  454. if (confMqtt.mqtt_enable_heartbeat && confMqtt.mqtt_heartbeat_maxage_reconnect > 0 && ((millis() - mqttLastHeartbeat) > confMqtt.mqtt_heartbeat_maxage_reconnect))
  455. { // also reconnect if no HEARTBEAT was received for some time
  456. doReconnect = true;
  457. mqttConnected = false;
  458. mqttLastHeartbeat = millis();
  459. //Serial.println(F("MQTT: HEARTBEAT overdue. Force-Reconnecting MQTT..."));
  460. sendLog(F("MQTT: HEARTBEAT overdue. Force-Reconnecting MQTT..."), LOGLEVEL_WARN);
  461. }
  462. }
  463. if (doReconnect)
  464. {
  465. unsigned long mqttReconnectAttemptDelay;
  466. if (mqttReconnectAttempts < 3)
  467. mqttReconnectAttemptDelay = MQTT_RECONNECT_INTERVAL_3_TRIES; // if this is the 1-3rd attempt, try again in 15s
  468. else if (mqttReconnectAttempts < 10)
  469. mqttReconnectAttemptDelay = MQTT_RECONNECT_INTERVAL_10_TRIES; // if more than 3 attempts failed, try again every min
  470. else
  471. mqttReconnectAttemptDelay = MQTT_RECONNECT_INTERVAL_LONG; // if more than 10 attempts failed, try again every 5 min
  472. if (confMqtt.mqtt_enable_heartbeat && confMqtt.mqtt_heartbeat_maxage_reboot > 0 && ((millis() - mqttLastHeartbeat) > confMqtt.mqtt_heartbeat_maxage_reboot))
  473. {
  474. // if no heartbeat was received for set time, reboot the ESP
  475. //Serial.println(F("MQTT: HEARTBEAT_MAXAGE_REBOOT overdue. Restarting..."));
  476. sendLog(F("MQTT: HEARTBEAT_MAXAGE_REBOOT overdue. Restarting..."), LOGLEVEL_WARN);
  477. restart();
  478. }
  479. if ((millis() - mqttLastReconnectAttempt) > mqttReconnectAttemptDelay)
  480. {
  481. mqttLastReconnectAttempt = millis();
  482. //#ifdef USE_MQTT_TLS
  483. // verifytls();
  484. //#endif
  485. mqttReconnect();
  486. }
  487. mqttclient.loop();
  488. }
  489. else
  490. {
  491. mqttclient.loop();
  492. }
  493. }
  494. }
  495. void mqttPublishStatus()
  496. {
  497. if (confMqtt.mqtt_enable && mqttclient.state() == 0)
  498. {
  499. char outMsg[60];
  500. sprintf_P(outMsg, "%s: %s: %s:%u, %s: %d", PGMStr_MQTT, PGMStr_connectedTo, confMqtt.mqtt_server, confMqtt.mqtt_port, PGMStr_reconnects, mqttReconnects - 1);
  501. //mqttclient.publish(confMqtt.mqtt_topic_out, outMsg, confMqtt.mqtt_outRetain);
  502. sendLog(outMsg, LOGLEVEL_INFO);
  503. }
  504. }
  505. void mqttOnConnect()
  506. {
  507. mqttPublishConnectMsg();
  508. mqttPublishStatus();
  509. displayShowMQTTConnected();
  510. }
  511. void mqttOnDisconnect()
  512. {
  513. displayShowMQTTConnectionError();
  514. }
  515. void mqttPublishConnectMsg()
  516. {
  517. if (strlen(confMqtt.mqtt_willTopic) > 4)
  518. {
  519. if (confMqtt.mqtt_enable && mqttclient.state() == 0)
  520. {
  521. mqttclient.publish(confMqtt.mqtt_willTopic, confMqtt.mqtt_connMsg, confMqtt.mqtt_willRetain);
  522. //sendLog(F("MQTT: connected"), LOGLEVEL_INFO);
  523. }
  524. }
  525. }
  526. void mqttPublishHeartbeat()
  527. {
  528. if (confMqtt.mqtt_enable && confMqtt.mqtt_enable_heartbeat && mqttclient.state() == 0)
  529. {
  530. mqttclient.publish(mqtt_topic_in_cmd, "HEARTBEAT", false); // publishes to IN-topic. MQTT will force-reconnect if it does not get a HEARTBEAT for 2 min
  531. }
  532. }
  533. void mqtt_updateCurrentStateName()
  534. {
  535. if (confMqtt.mqtt_enable)
  536. {
  537. sprintf_P(mqttCurrentStateName, "%s", PGMStr_MQTTStates[mqttclient.state() + 4]);
  538. }
  539. else
  540. sprintf_P(mqttCurrentStateName, "%s", PGMStr_MQTTState_DIS);
  541. }
  542. void mqttResetConnection()
  543. {
  544. sendLog(F("MQTT: resetting connection..."));
  545. if (!confMqtt.mqtt_enable)
  546. mqttclient.disconnect();
  547. else
  548. {
  549. mqttclient.disconnect();
  550. mqttPrepareSubscribeTopics();
  551. mqttClientInit();
  552. }
  553. configChangedMqttConnResetRequired = false;
  554. }