mqtt.ino 19 KB

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