@@ -135,6 +135,8 @@ static uint8_t cmdnrel = 0;
135135WiFiClient mqtt_wifi_client;
136136PubSubClient mqtt_client;
137137
138+
139+
138140bool firstConnectSinceBoot = true ; // if this is true there is no first connection made yet
139141
140142struct timerqueue_t **timerqueue = NULL ;
@@ -195,12 +197,15 @@ void check_wifi() {
195197 */
196198#ifdef ESP8266
197199 if ((heishamonSettings.wifi_ssid [0 ] != ' \0 ' ) && (wifistatus != WL_DISCONNECTED) && (WiFi.scanComplete () != -1 ) && (WiFi.softAPgetStationNum () > 0 )) {
200+ log_message (_F (" WiFi lost, but softAP station connecting, so stop trying to connect to configured ssid..." ));
201+ WiFi.disconnect (true );
202+ }
198203#else
199204 if ((heishamonSettings.wifi_ssid [0 ] != ' \0 ' ) && (wifistatus != WL_STOPPED) && (WiFi.scanComplete () != -1 ) && (WiFi.softAPgetStationNum () > 0 )) {
200- #endif
201205 log_message (_F (" WiFi lost, but softAP station connecting, so stop trying to connect to configured ssid..." ));
202- WiFi.disconnect ( true );
206+ WiFi.mode (WIFI_AP );
203207 }
208+ #endif
204209
205210 /* only start this routine if timeout on
206211 reconnecting to AP and SSID is set
@@ -221,22 +226,19 @@ void check_wifi() {
221226 WiFi.softAPConfig (apIP, apIP, IPAddress (255 , 255 , 255 , 0 ));
222227 WiFi.softAP (_F (" HeishaMon-Setup" ));
223228 }
224- if ((wifistatus == WL_STOPPED) && (WiFi.softAPgetStationNum () == 0 )) {
229+ if ((wifistatus == WL_STOPPED ) && (WiFi.softAPgetStationNum () == 0 )) { // make sure we start STA again if it was stopped
225230 log_message (_F (" Retrying configured WiFi, ..." ));
231+ WiFi.setScanMethod (WIFI_ALL_CHANNEL_SCAN); // select best AP with same SSID
226232#endif
227233 if (heishamonSettings.wifi_password [0 ] == ' \0 ' ) {
228234 WiFi.begin (heishamonSettings.wifi_ssid );
229235 } else {
230236 WiFi.begin (heishamonSettings.wifi_ssid , heishamonSettings.wifi_password );
231237 }
238+ #ifdef ESP8266
232239 } else {
233240 log_message (_F (" Reconnecting to WiFi failed. Waiting a few seconds before trying again." ));
234- #ifdef ESP8266
235- WiFi.disconnect (true );
236- #else
237- WiFi.mode (WIFI_MODE_APSTA);
238241 WiFi.disconnect (true );
239- WiFi.mode (WIFI_MODE_AP);
240242#endif
241243 }
242244 }
@@ -354,11 +356,10 @@ void mqtt_reconnect()
354356 resetlastalldatatime (); // resend all heatpump values to mqtt
355357 }
356358 // use this to receive valid heishamon raw data from other heishamon to debug this OT code
357- #define OTDEBUG
358- #ifdef OTDEBUG
359- if ( heishamonSettings.listenonly && heishamonSettings.listenmqtt ) {
360- sprintf (topic, " %s/raw/data" , heishamonSettings.mqtt_topic_listen );
361- mqtt_client.subscribe (topic); // subscribe to raw heatpump data over MQTT
359+ // #define RAWDEBUG
360+ #ifdef RAWDEBUG
361+ if ( heishamonSettings.listenonly ) {
362+ mqtt_client.subscribe ((char *)" panasonic_heat_pump/raw/data" ); // subscribe to raw heatpump data over MQTT
362363 }
363364#endif
364365 }
@@ -387,7 +388,7 @@ void log_message(char* string)
387388 struct tm *timeinfo = localtime (&rawtime);
388389 char timestring[32 ];
389390 strftime (timestring, 32 , " %c" , timeinfo);
390- size_t len = strlen (string) + strlen (timestring) + 20 ; // +20 long enough to contain millis()
391+ size_t len = strlen (string) + strlen (timestring) + 32 ; // +32 long enough to contain millis() and the json part later for websocket mesg
391392 char * log_line = (char *) malloc (len);
392393 snprintf (log_line, len, " %s (%lu): %s" , timestring, millis (), string);
393394
@@ -408,11 +409,10 @@ void log_message(char* string)
408409 mqtt_client.disconnect ();
409410 }
410411 }
411- char * websocketMsg = (char *) malloc (len+12 );
412- snprintf (websocketMsg, len+12 , " {\" logMsg\" :\" %s\" }" , log_line);
412+ // send log message to websocket
413+ snprintf (log_line, len+12 , " {\" logMsg\" :\" %s (%lu): %s\" }" , timestring, millis (), string);
414+ websocket_write_all (log_line, strlen (log_line));
413415 free (log_line);
414- websocket_write_all (websocketMsg, strlen (websocketMsg));
415- free (websocketMsg);
416416#ifdef ESP32
417417 if (!inSetup) blinkNeoPixel (false );
418418#endif
@@ -707,10 +707,9 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
707707 {
708708 char * topic_sendcommand = topic_command + strlen (mqtt_topic_commands) + 1 ; // strip the first 9 "commands/" from the topic to get what we need
709709 send_heatpump_command (topic_sendcommand, msg, send_command, log_message, heishamonSettings.optionalPCB );
710- }
711710 // use this to receive valid heishamon raw data from other heishamon to debug this OT code
712- #ifdef OTDEBUG
713- else if (strcmp ((char *)" panasonic_heat_pump/data" , topic) == 0 ) { // check for raw heatpump input
711+ #ifdef RAWDEBUG
712+ } else if (strcmp ((char *)" panasonic_heat_pump/raw /data" , topic) == 0 ) { // check for raw heatpump input
714713 sprintf_P (log_msg, PSTR (" Received raw heatpump data from MQTT" ));
715714 log_message (log_msg);
716715 decode_heatpump_data (msg, actData, mqtt_client, log_message, heishamonSettings.mqtt_topic_base , heishamonSettings.updateAllTime );
@@ -750,7 +749,11 @@ void setupOTA() {
750749 ArduinoOTA.begin ();
751750}
752751
752+
753+
753754int8_t webserver_cb (struct webserver_t *client, void *dat) {
755+
756+
754757 switch (client->step ) {
755758 case WEBSERVER_CLIENT_REQUEST_METHOD: {
756759 if (strcmp_P ((char *)dat, PSTR (" POST" )) == 0 ) {
@@ -1172,8 +1175,6 @@ void factoryReset() {
11721175 yield ();
11731176 }
11741177#else
1175- pixels.begin ();
1176- pixels.clear ();
11771178 while (true ) {
11781179 delay (100 );
11791180 pixels.setPixelColor (0 , 128 , 0 , 0 );
@@ -1414,8 +1415,6 @@ void setup() {
14141415 yield ();
14151416 }
14161417#else
1417- pixels.begin ();
1418- pixels.clear ();
14191418 while (true ) {
14201419 delay (50 );
14211420 pixels.setPixelColor (0 , 128 , 0 , 0 );
@@ -1486,16 +1485,21 @@ void setup() {
14861485 }
14871486
14881487 loggingSerial.println (F (" Enabling rules.." ));
1488+ if (heishamonSettings.force_rules == false ) {
14891489#if defined(ESP8266)
14901490 rst_info *resetInfo = ESP.getResetInfoPtr ();
14911491 loggingSerial.printf (PSTR (" Reset reason: %d, exception cause: %d\n " ), resetInfo->reason , resetInfo->exccause );
1492- if (resetInfo->reason > 0 && resetInfo->reason < 4 ) {
1492+ if (resetInfo->reason > 0 && resetInfo->reason < 4 ) {
14931493#elif defined(ESP32)
1494- esp_reset_reason_t reset_reason = esp_reset_reason ();
1495- loggingSerial.printf (PSTR (" Reset reason: %d\n " ), reset_reason);
1496- if (reset_reason > 3 && reset_reason < 12 ) { // is this correct for esp32?
1494+ esp_reset_reason_t reset_reason = esp_reset_reason ();
1495+ loggingSerial.printf (PSTR (" Reset reason: %d\n " ), reset_reason);
1496+ if (reset_reason > 3 && reset_reason < 12 ) { // is this correct for esp32?
14971497#endif
1498- loggingSerial.println (" Not loading rules due to crash reboot!" );
1498+ loggingSerial.println (" Not loading rules due to crash reboot!" );
1499+ } else {
1500+ rules_parse ((char *)" /rules.txt" );
1501+ rules_boot ();
1502+ }
14991503 } else {
15001504 rules_parse ((char *)" /rules.txt" );
15011505 rules_boot ();
@@ -1532,8 +1536,8 @@ void send_panasonic_query() {
15321536 send_command (panasonicQuery, PANASONICQUERYSIZE);
15331537 panasonicQuery[3 ] = 0x10 ; // setting 4th back to 0x10 for normal data request next time
15341538 } else {
1535- if ((actData[0 ] == 0x71 ) && (actData[1 ] == 0xc8 ) && (actData[2 ] == 0x01 ) && (actData[193 ] == 0 ) && (actData[195 ] == 0 ) && (actData[197 ] == 0 ) ) { // do we have valid data but 0 value in heat consumptiom power, then assume K or L series
1536- // can be replaced with: if ((actData[0] == 0x71) && (actData[0xc7] >= 3) ) { //do we have valid header and byte 0xc7 is more or equal 3 then assume K&L series
1539+ // if ((actData[0] == 0x71) && (actData[1] == 0xc8) && (actData[2] == 0x01) && (actData[193] == 0) && (actData[195] == 0) && (actData[197] == 0) ) { //do we have valid data but 0 value in heat consumptiom power, then assume K or L series
1540+ if ((actData[0 ] == 0x71 ) && (actData[0xc7 ] >= 3 ) ) { // do we have valid header and byte 0xc7 is more or equal 3 then assume K&L and more series
15371541 log_message (_F (" Assuming K or L heatpump type due to missing heat/cool/dhw power data" ));
15381542 extraDataBlockAvailable = true ; // request for extra data next run
15391543 }
@@ -1584,7 +1588,7 @@ void loop() {
15841588
15851589 // check wifi
15861590 check_wifi ();
1587- // Handle OTA first.
1591+ // Handle OTA first.s
15881592 ArduinoOTA.handle ();
15891593
15901594 mqtt_client.loop ();
@@ -1728,12 +1732,48 @@ void loop() {
17281732 stats += timeoutread;
17291733 stats += F (" ,\" version\" :\" " );
17301734 stats += heishamon_version;
1735+ stats += F (" \" ,\" board\" :\" " );
1736+ #ifdef ESP8266
1737+ stats += F (" ESP8266" );
1738+ #else
1739+ stats += F (" ESP32" );
1740+ #endif
17311741 stats += F (" \" ,\" rules active\" :" );
17321742 stats += nrrules;
17331743 stats += F (" }" );
17341744 sprintf_P (mqtt_topic, PSTR (" %s/stats" ), heishamonSettings.mqtt_topic_base );
17351745 mqtt_client.publish (mqtt_topic, stats.c_str (), MQTT_RETAIN_VALUES);
17361746
1747+ // websocket stats
1748+ #ifdef ESP32
1749+ String ethernetStat;
1750+ if (ETH.phyAddr () != 0 ) {
1751+ if (ETH.connected ()) {
1752+ if (ETH.hasIP ()) {
1753+ ethernetStat = F (" connected - IP: " );
1754+ ethernetStat += ETH.localIP ().toString ();
1755+ ethernetStat += F (" )" );
1756+ } else {
1757+ ethernetStat = F (" connected - no IP" );
1758+ }
1759+ }
1760+ else {
1761+ ethernetStat = F (" not connected" );
1762+ }
1763+ } else {
1764+ ethernetStat = F (" not installed" );
1765+ }
1766+ char *getuptime = getUptime ();
1767+ sprintf_P (log_msg, PSTR (" {\" data\" : {\" stats\" : {\" wifi\" : %d, \" ethernet\" : \" %s\" , \" memory\" : %d, \" correct\" : %.0f,\" mqtt\" : %d,\" uptime\" : \" %s\" }}}" ), getWifiQuality (), ethernetStat.c_str (), getFreeMemory (), readpercentage, mqttReconnects, getuptime);
1768+ free (getuptime);
1769+ #else
1770+ char *getuptime = getUptime ();
1771+ sprintf_P (log_msg, PSTR (" {\" data\" : {\" stats\" : {\" wifi\" : %d, \" memory\" : %d, \" correct\" : %.0f,\" mqtt\" : %d,\" uptime\" : \" %s\" }}}" ), getWifiQuality (), getFreeMemory (), readpercentage, mqttReconnects, getuptime);
1772+ free (getuptime);
1773+ #endif
1774+
1775+ websocket_write_all (log_msg, strlen (log_msg));
1776+
17371777 // get new data
17381778 if (!heishamonSettings.listenonly ) send_panasonic_query ();
17391779
0 commit comments