Skip to content

Commit

Permalink
internet connection check added
Browse files Browse the repository at this point in the history
  • Loading branch information
Thorsten Ludewig committed Mar 20, 2020
1 parent bc8f547 commit c6bce96
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/App/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ void App::defaultConfig()
appcfg.led_night_mode_timeout = DEFAULT_LED_NIGHT_MODE_TIMEOUT;
#endif

appcfg.inet_check_enabled = DEFAULT_INET_CHECK_ENABLED;
appcfg.inet_check_period = DEFAULT_INET_CHECK_PERIOD;
appcfg.inet_check_action = DEFAULT_INET_CHECK_ACTION;

memcpy(&appcfgWR, &appcfg, sizeof(appcfg));
memcpy(&appcfgRD, &appcfg, sizeof(appcfg));
}
Expand Down Expand Up @@ -392,6 +396,10 @@ void App::writeConfig()
j.writeEntry(A_led_night_mode_timeout, appcfgWR.led_night_mode_timeout);
#endif

j.writeEntry(A_inet_check_enabled, appcfgWR.inet_check_enabled);
j.writeEntry(A_inet_check_period, appcfgWR.inet_check_period);
j.writeEntry(A_inet_check_action, appcfgWR.inet_check_action);

j.writeFooter();
configJson.close();

Expand Down Expand Up @@ -487,6 +495,12 @@ void App::printConfig(AppConfig ac)
Serial.printf(" led_night_mode_timeout: %ds\n", ac.led_night_mode_timeout);
#endif

Serial.println("\n Internet check mode:");
Serial.printf(" Enabled: %s\n",
(ac.inet_check_enabled ? "true" : "false"));
Serial.printf(" inet_check_period: %ds\n", ac.inet_check_period);
Serial.printf(" inet_check_action: %d\n", ac.inet_check_action);

Serial.println("---------------------------------------------------------");
Serial.println();
}
Expand Down Expand Up @@ -602,6 +616,9 @@ bool App::loadJsonConfig(const char *filename)
readError |= j.readEntryBoolean(attributeName, A_led_night_mode_enabled, &appcfgRD.led_night_mode_enabled);
readError |= j.readEntryInteger(attributeName, A_led_night_mode_timeout, &appcfgRD.led_night_mode_timeout);
#endif
readError |= j.readEntryBoolean(attributeName, A_inet_check_enabled, &appcfgRD.inet_check_enabled);
readError |= j.readEntryInteger(attributeName, A_inet_check_period, &appcfgRD.inet_check_period);
readError |= j.readEntryInteger(attributeName, A_inet_check_action, &appcfgRD.inet_check_action);
}
}

Expand Down
13 changes: 13 additions & 0 deletions lib/App/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
#define POWER_BUTTON_MODE_TOGGLE 2
#define POWER_BUTTON_MODE_TOGGLE_SWITCH 3

// Internet Check Actions
#define INET_CHECK_ACTION_ON_DISCONNECT_SWITCH_OFF 1
#define INET_CHECK_ACTION_ON_DISCONNECT_SWITCH_ON 2
#define INET_CHECK_ACTION_ON_CONNECT_SWITCH_OFF 3
#define INET_CHECK_ACTION_ON_CONNECT_SWITCH_ON 4
#define INET_CHECK_ACTION_SHOW_CONNECTION_STATE 5
#define INET_CHECK_ACTION_SHOW_CONNECTION_STATE_INV 6

typedef struct appconfig
{
char wifi_ssid[64];
Expand Down Expand Up @@ -87,6 +95,10 @@ typedef struct appconfig
int led_night_mode_timeout;
#endif

bool inet_check_enabled; // check captive.apple.de
int inet_check_period; // in seconds
int inet_check_action;

} AppConfig;

class App
Expand All @@ -103,6 +115,7 @@ class App
int powerLedState;
bool ledNightMode;
bool ledActiveMode;
bool internetIsConnected;

void formatSPIFFS();
void loadConfig();
Expand Down
4 changes: 4 additions & 0 deletions lib/App/ConfigAttributes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@
#define A_led_night_mode_enabled "led_night_mode_enabled"
#define A_led_night_mode_timeout "led_night_mode_timeout"

#define A_inet_check_enabled "inet_check_enabled"
#define A_inet_check_period "inet_check_period"
#define A_inet_check_action "inet_check_action"

#endif
4 changes: 4 additions & 0 deletions lib/App/DefaultAppConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@
#define DEFAULT_LED_NIGHT_MODE_ENABLED false
#define DEFAULT_LED_NIGHT_MODE_TIMEOUT 15

#define DEFAULT_INET_CHECK_ENABLED false
#define DEFAULT_INET_CHECK_PERIOD 600
#define DEFAULT_INET_CHECK_ACTION INET_CHECK_ACTION_ON_DISCONNECT_SWITCH_OFF

#endif
206 changes: 206 additions & 0 deletions lib/InternetConnectionCheckHandler/InternetConnectionCheckHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#include <Arduino.h>
#include <Esp.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <App.hpp>
#include <RelayHandler.hpp>
#include <WifiHandler.hpp>

#include "InternetConnectionCheckHandler.hpp"

InternetConnectionCheckHandler internetConnectionCheckHandler;

static AsyncClient *aClient = NULL;

static bool successFound;
static char *successTxt = (char *)"Success";
static char *matchPtr;
static time_t startTimestamp;
static bool initStateRead;
static bool lastState;

void runAction( bool connected )
{
LOG1( "run acion = %s\n", successFound ? "true" : "false" );
if ( initStateRead )
{
if ( lastState != connected )
{
LOG0( "Internet connection state changed\n" );

switch( appcfg.inet_check_action )
{
case INET_CHECK_ACTION_ON_CONNECT_SWITCH_OFF:
if ( connected )
{
relayHandler.delayedOff();
}
break;

case INET_CHECK_ACTION_ON_CONNECT_SWITCH_ON:
if ( connected )
{
relayHandler.delayedOn();
}
break;

case INET_CHECK_ACTION_ON_DISCONNECT_SWITCH_OFF:
if ( !connected )
{
relayHandler.delayedOff();
}
break;

case INET_CHECK_ACTION_ON_DISCONNECT_SWITCH_ON:
if ( !connected )
{
relayHandler.delayedOn();
}
break;

case INET_CHECK_ACTION_SHOW_CONNECTION_STATE:
if ( connected )
{
relayHandler.delayedOn();
}
else
{
relayHandler.delayedOff();
}
break;

case INET_CHECK_ACTION_SHOW_CONNECTION_STATE_INV:
if ( connected )
{
relayHandler.delayedOff();
}
else
{
relayHandler.delayedOn();
}
break;

default:
LOG0( "Unknown action\n" );
}

lastState = connected;
}
}
else
{
LOG0( "Saving internet connection state\n" );
lastState = connected;
initStateRead = true;
}
}

InternetConnectionCheckHandler::InternetConnectionCheckHandler()
{
initialized = false;
initStateRead = false;
}

void InternetConnectionCheckHandler::setup()
{
LOG0("Internet Connection Check Setup...\n");
initialized = true;
lastCheckedTimestamp = 0l;
LOG0("done\n");
}

void InternetConnectionCheckHandler::handle(time_t now)
{
if ( appcfg.inet_check_enabled == true && wifiHandler.isInStationMode())
{
if ( !initialized )
{
setup();
}

////////////////////////////////////////////////////////////////////////

if (( now - lastCheckedTimestamp ) >= (((time_t)appcfg.inet_check_period) * 1000l ))
{
LOG0("Checking internet connection...\n");

if ( !wifiHandler.isConnected() )
{
runAction( false );
lastCheckedTimestamp = now;
return;
}

startTimestamp = millis();
aClient = new AsyncClient();

successFound = false;
matchPtr = successTxt;

if (aClient)
{
aClient->onError([](void *arg, AsyncClient *client, int error) {
Serial.println("\nConnect Error");
aClient = NULL;
delete client;
runAction(false);
}, NULL);

aClient->onConnect([](void *arg, AsyncClient *client) {
Serial.println("Connected");

aClient->onError(NULL, NULL);

client->onDisconnect([](void *arg, AsyncClient *client) {
Serial.printf("Disconnected duration=%ld\n", millis() - startTimestamp );
aClient = NULL;
delete client;
runAction( successFound );
}, NULL);

client->onData([](void *arg, AsyncClient *client, void *data, size_t len) {
Serial.print("Data: ");
Serial.println(len);
char *d = (char *)data;
for (size_t i = 0; i < len; i++)
{
// Serial.write(d[i]);
if ( *matchPtr == 0 )
{
successFound = true;
}
else
{
if ( *matchPtr == d[i] )
{
matchPtr++;
}
else
{
matchPtr = successTxt;
}
}
}
}, NULL);

//send the request
client->write("GET / HTTP/1.0\r\nHost: captive.apple.com\r\n\r\n");
}, NULL);

if (!aClient->connect("captive.apple.com", 80))
{
Serial.println("Connect Fail");
AsyncClient *client = aClient;
aClient = NULL;
delete client;
runAction( false );
}
}


lastCheckedTimestamp = now;
}

////////////////////////////////////////////////////////////////////////
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __INTERNET_CONNECTION_CHECK_HANDLER_HPP__
#define __INTERNET_CONNECTION_CHECK_HANDLER_HPP__

#include <Arduino.h>

class InternetConnectionCheckHandler
{
private:
bool initialized;
time_t lastCheckedTimestamp;
void setup();

public:
InternetConnectionCheckHandler();
void handle( time_t now );
};

extern InternetConnectionCheckHandler internetConnectionCheckHandler;

#endif
4 changes: 4 additions & 0 deletions lib/WebHandler/pages/SaveConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ void handleSavePage(AsyncWebServerRequest *request)
appcfgWR.led_night_mode_timeout = paramInt(request, A_led_night_mode_timeout, DEFAULT_LED_NIGHT_MODE_TIMEOUT);
#endif

appcfgWR.inet_check_enabled = paramBool(request, A_inet_check_enabled);
appcfgWR.inet_check_period = paramInt(request, A_inet_check_period, DEFAULT_INET_CHECK_PERIOD);
appcfgWR.inet_check_action = paramInt(request, A_inet_check_action, DEFAULT_INET_CHECK_ACTION);

AsyncResponseStream *response = request->beginResponseStream("text/html");
response->print(TEMPLATE_HEADER);
response->print(META_REFRESH);
Expand Down
12 changes: 12 additions & 0 deletions lib/WebHandler/pages/SetupPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ String setupProcessor(const String &var)
return String(appcfg.led_night_mode_timeout);
#endif

if (var == A_inet_check_enabled && appcfg.inet_check_enabled == true)
return checked;
if (var == A_inet_check_period)
return String(appcfg.inet_check_period);

String ica = String( A_inet_check_action );
ica += "_";
ica += appcfg.inet_check_action;

if ( var == ica )
return selected;

return String();
}

Expand Down
15 changes: 15 additions & 0 deletions lib/WebHandler/setup-html.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ const char SETUP_HTML[] PROGMEM =
"</div>\n"
#endif

"<div class='accordion'>Internet Check Mode</div>\n"
"<div class='panel sub-panel'>\n"
"<div class=\"pure-control-group\"><label for=\"inetc1\">Enabled</label><input id=\"inetc1\" type=\"checkbox\" name=\"inet_check_enabled\" value=\"true\" %inet_check_enabled%></div>\n"
"<div class=\"pure-control-group\"><label for=\"inetc4\">Destination</label><input id=\"inetc4\" type=\"text\" readonly value=\"captive.apple.com\"></div>\n"
"<div class=\"pure-control-group\"><label for=\"inetc2\">Period</label><input id=\"inetc2\" type=\"text\" name=\"inet_check_period\" maxlength=\"64\" value=\"%inet_check_period%\"></div>\n"
"<div class=\"pure-control-group\"><label for=\"inetc3\">Mode</label><select id=\"inetc3\" name=\"inet_check_action\">"
"<option %inet_check_action_1% value=\"1\">On disconnect switch off</option>\n"
"<option %inet_check_action_2% value=\"2\">On disconnect switch on</option>\n"
"<option %inet_check_action_3% value=\"3\">On connect switch off</option>\n"
"<option %inet_check_action_4% value=\"4\">On connect switch on</option>\n"
"<option %inet_check_action_5% value=\"5\">Mirror connection state</option>\n"
"<option %inet_check_action_6% value=\"6\">Mirror inverse connection state</option>\n"
"</select></div>\n"
"</div>\n"

#if defined(POWER_BUTTON_IS_MULTIMODE)
"<div class='accordion'>Power Button</div>\n"
"<div class='panel sub-panel'>\n"
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <WebHandler.hpp>
#include <WifiHandler.hpp>
#include <Hlw8012Handler.hpp>
#include <InternetConnectionCheckHandler.hpp>

unsigned long lifeTicker;
unsigned long maxLoopTime;
Expand Down Expand Up @@ -135,6 +136,8 @@ void loop()
mqttHandler.handle(thisLoopTimestamp);
}

internetConnectionCheckHandler.handle(thisLoopTimestamp);

#ifdef HAVE_HLW8012
hlw8012Handler.handle(thisLoopTimestamp);
#endif
Expand Down

0 comments on commit c6bce96

Please sign in to comment.