Skip to content

Commit 5d8f64f

Browse files
authored
Merge pull request #70 from CurlyMoo/wifi
Replace wifiManager with lean AP logic
2 parents b8a5d8e + 910037f commit 5d8f64f

File tree

7 files changed

+509
-196
lines changed

7 files changed

+509
-196
lines changed

HeishaMon/HeishaMon.ino

Lines changed: 112 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <ESP8266WiFi.h>
44
#include <ESP8266mDNS.h>
5+
#include <DNSServer.h>
56
#include <WiFiUdp.h>
67
#include <ArduinoOTA.h>
78
#include <PubSubClient.h>
@@ -15,6 +16,7 @@
1516
#include "decode.h"
1617
#include "commands.h"
1718

19+
DNSServer dnsServer;
1820

1921
//to read bus voltage in stats
2022
ADC_MODE(ADC_VCC);
@@ -28,6 +30,7 @@ ADC_MODE(ADC_VCC);
2830
// of the address block
2931
#define DRD_ADDRESS 0x00
3032

33+
const byte DNS_PORT = 53;
3134

3235
#define SERIALTIMEOUT 2000 // wait until all 203 bytes are read, must not be too long to avoid blocking the code
3336

@@ -39,8 +42,13 @@ settingsStruct heishamonSettings;
3942

4043
bool sending = false; // mutex for sending data
4144
bool mqttcallbackinprogress = false; // mutex for processing mqtt callback
45+
46+
#define MQTTRECONNECTTIMER 30000 //it takes 30 secs for each mqtt server reconnect attempt
4247
unsigned long nextMqttReconnectAttempt = 0;
43-
#define MQTTRECONNECTTIMER 30000
48+
49+
#define WIFIRETRYTIMER 30000 // switch between hotspot and configured SSID each 30 secs if SSID is lost
50+
unsigned long nextWifiRetryTimer = WIFIRETRYTIMER;
51+
4452
unsigned long nexttime = 0;
4553

4654
unsigned long allowreadtime = 0; //set to millis value during send, allow to wait millis for answer
@@ -68,15 +76,15 @@ char log_msg[256];
6876
// mqtt topic to sprintf and then publish to
6977
char mqtt_topic[256];
7078

71-
int mqttReconnects = 0;
79+
static int mqttReconnects = 0;
7280

7381
// can't have too much in buffer due to memory shortage
7482
#define MAXCOMMANDSINBUFFER 10
7583

7684
// buffer for commands to send
7785
struct cmdbuffer_t {
78-
uint8_t length;
79-
byte data[128];
86+
uint8_t length;
87+
byte data[128];
8088
} cmdbuffer[MAXCOMMANDSINBUFFER];
8189

8290
static uint8_t cmdstart = 0;
@@ -90,19 +98,74 @@ DoubleResetDetect drd(DRD_TIMEOUT, DRD_ADDRESS);
9098
WiFiClient mqtt_wifi_client;
9199
PubSubClient mqtt_client(mqtt_wifi_client);
92100

101+
//check wifi bools
102+
bool softAPenabled = false;
103+
bool reconnectingWiFi = false;
104+
105+
/*
106+
* check_wifi will process wifi reconnecting managing
107+
*/
108+
void check_wifi()
109+
{
110+
if ((WiFi.status() != WL_CONNECTED) || (!WiFi.localIP())) {
111+
/*
112+
* if we are not connected to an AP
113+
* we must be in softAP so respond to DNS
114+
*/
115+
dnsServer.processNextRequest();
116+
117+
if ((reconnectingWiFi) && (WiFi.softAPgetStationNum() > 0)) {
118+
log_message((char *)"WiFi lost, but softAP station connecting, so stop scanning...");
119+
reconnectingWiFi = false;
120+
WiFi.disconnect();
121+
}
122+
123+
/*
124+
* only start this routine if timeout on
125+
* reconnecting to AP and SSID is set
126+
*/
127+
if ((strlen(heishamonSettings.wifi_ssid) > 0) && (nextWifiRetryTimer < millis())) {
128+
nextWifiRetryTimer = millis() + WIFIRETRYTIMER;
129+
if (!softAPenabled) {
130+
log_message((char *)"WiFi lost, starting setup hotspot...");
131+
softAPenabled = true;
132+
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
133+
WiFi.softAP("HeishaMon-Setup");
134+
}
135+
if ((!reconnectingWiFi) && (WiFi.softAPgetStationNum() == 0 )) {
136+
reconnectingWiFi = true;
137+
log_message((char *)"Retrying configured WiFi, ...");
138+
if (strlen(heishamonSettings.wifi_password) == 0) {
139+
WiFi.begin(heishamonSettings.wifi_ssid);
140+
} else {
141+
WiFi.begin(heishamonSettings.wifi_ssid, heishamonSettings.wifi_password);
142+
}
143+
} else {
144+
reconnectingWiFi = false;
145+
log_message((char *)"Reconnecting to WiFi failed. Waiting a few seconds before trying again.");
146+
WiFi.disconnect();
147+
}
148+
}
149+
} else {
150+
if (softAPenabled) {
151+
log_message((char *)"WiFi (re)connected, shutting down hotspot...");
152+
softAPenabled = false;
153+
reconnectingWiFi = false;
154+
WiFi.softAPdisconnect(true);
155+
}
156+
/*
157+
* always update if wifi is working so next time on ssid failure
158+
* it only starts the routine above after this timeout
159+
*/
160+
nextWifiRetryTimer = millis() + WIFIRETRYTIMER;
161+
}
162+
}
163+
93164
void mqtt_reconnect()
94165
{
95166
unsigned long now = millis();
96167
if (now > nextMqttReconnectAttempt) { //only try reconnect each MQTTRECONNECTTIMER seconds or on boot when nextMqttReconnectAttempt is still 0
97168
nextMqttReconnectAttempt = now + MQTTRECONNECTTIMER;
98-
if ((WiFi.status() != WL_CONNECTED) || (! WiFi.localIP()) ) {
99-
log_message((char *)"Lost WiFi connection!");
100-
if (!heishamonSettings.optionalPCB) { //do not reboot if optional pcb emulation is active because it is more important to keep transmitting data packages to heatpump
101-
log_message((char *)"Rebooting...");
102-
delay(1000);
103-
ESP.restart();
104-
}
105-
}
106169
log_message((char*)"Reconnecting to mqtt server ...");
107170
char topic[256];
108171
sprintf(topic, "%s/%s", heishamonSettings.mqtt_topic_base, mqtt_willtopic);
@@ -237,15 +300,15 @@ bool readSerial()
237300

238301
void popCommandBuffer() {
239302
// to make sure we can pop a command from the buffer
240-
if((!sending) && cmdnrel > 0) {
303+
if ((!sending) && cmdnrel > 0) {
241304
send_command(cmdbuffer[cmdstart].data, cmdbuffer[cmdstart].length);
242305
cmdstart = (cmdstart + 1) % (MAXCOMMANDSINBUFFER);
243306
cmdnrel--;
244307
}
245308
}
246309

247310
void pushCommandBuffer(byte* command, int length) {
248-
if(cmdnrel+1 > MAXCOMMANDSINBUFFER) {
311+
if (cmdnrel + 1 > MAXCOMMANDSINBUFFER) {
249312
log_message((char *)"Too much commands already in buffer. Ignoring this commands.\n");
250313
return;
251314
}
@@ -368,7 +431,7 @@ void setupHttp() {
368431
handleDebug(&httpServer, data, 203);
369432
});
370433
httpServer.on("/settings", [] {
371-
handleSettings(&httpServer, &heishamonSettings);
434+
handleSettings(drd, &httpServer, &heishamonSettings);
372435
});
373436
httpServer.on("/smartcontrol", [] {
374437
handleSmartcontrol(&httpServer, &heishamonSettings, actData);
@@ -387,6 +450,28 @@ void setupHttp() {
387450
httpServer.send ( 302, "text/plain", "");
388451
httpServer.client().stop();
389452
});
453+
httpServer.onNotFound([]() {
454+
httpServer.sendHeader("Location", String("/"), true);
455+
httpServer.send(302, "text/plain", "");
456+
httpServer.client().stop();
457+
});
458+
/*
459+
Captive portal url's
460+
for now, the android one sometimes gets the heishamon in a wait loop during wifi reconfig
461+
462+
httpServer.on("/generate_204", [] {
463+
handleSettings(drd, &httpServer, &heishamonSettings);
464+
}); */
465+
httpServer.on("/hotspot-detect.html", [] {
466+
handleSettings(drd, &httpServer, &heishamonSettings);
467+
});
468+
httpServer.on("/fwlink", [] {
469+
handleSettings(drd, &httpServer, &heishamonSettings);
470+
});
471+
httpServer.on("/popup", [] {
472+
handleSettings(drd, &httpServer, &heishamonSettings);
473+
});
474+
390475
httpServer.begin();
391476

392477
webSocket.begin();
@@ -441,15 +526,20 @@ void setupMqtt() {
441526

442527
void setup() {
443528
setupSerial();
529+
setupSerial1();
530+
Serial.println();
531+
Serial.println(F("--- HEISHAMON ---"));
532+
Serial.println(F("starting..."));
533+
WiFi.printDiag(Serial);
444534
setupWifi(drd, &heishamonSettings);
445535
MDNS.begin(heishamonSettings.wifi_hostname);
446536
MDNS.addService("http", "tcp", 80);
447-
setupSerial1();
448537
setupOTA();
449538
setupMqtt();
450539
setupHttp();
451540

452541
switchSerial(); //switch serial to gpio13/gpio15
542+
WiFi.printDiag(Serial1);
453543

454544
//load optional PCB data from flash
455545
if (heishamonSettings.optionalPCB) {
@@ -467,6 +557,9 @@ void setup() {
467557
if (heishamonSettings.use_1wire) initDallasSensors(log_message, heishamonSettings.updataAllDallasTime, heishamonSettings.waitDallasTime);
468558
if (heishamonSettings.use_s0) initS0Sensors(heishamonSettings.s0Settings, mqtt_client, heishamonSettings.mqtt_topic_base);
469559

560+
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
561+
dnsServer.start(DNS_PORT, "*", apIP);
562+
470563
// wait waittime for the first start in main loop
471564
nexttime = millis() + (1000 * heishamonSettings.waitTime);
472565
}
@@ -503,6 +596,8 @@ void read_panasonic_data() {
503596
}
504597

505598
void loop() {
599+
// check wifi
600+
check_wifi();
506601
// Handle OTA first.
507602
ArduinoOTA.handle();
508603
// then handle HTTP
@@ -533,7 +628,7 @@ void loop() {
533628
if (millis() > nexttime) {
534629
nexttime = millis() + (1000 * heishamonSettings.waitTime);
535630
//check mqtt
536-
if (!mqtt_client.connected())
631+
if ( (WiFi.isConnected()) && (!mqtt_client.connected()) )
537632
{
538633
log_message((char *)"Lost MQTT connection!");
539634
mqtt_reconnect();

0 commit comments

Comments
 (0)