Browse Source

Loop hooks

pull/461/head
Xose Pérez 6 years ago
parent
commit
b082d14c59
25 changed files with 220 additions and 175 deletions
  1. +3
    -0
      code/espurna/alexa.ino
  2. +3
    -0
      code/espurna/button.ino
  3. +2
    -1
      code/espurna/config/sensors.h
  4. +30
    -80
      code/espurna/espurna.ino
  5. +0
    -47
      code/espurna/hardware.ino
  6. +8
    -0
      code/espurna/i2c.ino
  7. +5
    -0
      code/espurna/ir.ino
  8. +4
    -0
      code/espurna/led.ino
  9. +0
    -3
      code/espurna/light.ino
  10. +7
    -0
      code/espurna/mdns.ino
  11. +3
    -0
      code/espurna/mqtt.ino
  12. +3
    -0
      code/espurna/nofuss.ino
  13. +3
    -0
      code/espurna/ntp.ino
  14. +3
    -0
      code/espurna/ota.ino
  15. +2
    -0
      code/espurna/relay.ino
  16. +3
    -0
      code/espurna/rf.ino
  17. +3
    -0
      code/espurna/rfbridge.ino
  18. +3
    -0
      code/espurna/scheduler.ino
  19. +3
    -0
      code/espurna/sensor.ino
  20. +3
    -0
      code/espurna/settings.ino
  21. +3
    -0
      code/espurna/ssdp.ino
  22. +116
    -0
      code/espurna/system.ino
  23. +7
    -0
      code/espurna/thinkspeak.ino
  24. +0
    -44
      code/espurna/utils.ino
  25. +3
    -0
      code/espurna/wifi.ino

+ 3
- 0
code/espurna/alexa.ino View File

@ -68,6 +68,9 @@ void alexaSetup() {
return relayStatus(device_id);
});
// Register loop
espurnaRegisterLoop(alexaLoop);
}
void alexaLoop() {


+ 3
- 0
code/espurna/button.ino View File

@ -184,6 +184,9 @@ void buttonSetup() {
DEBUG_MSG_P(PSTR("[BUTTON] Number of buttons: %u\n"), _buttons.size());
// Register loop
espurnaRegisterLoop(buttonLoop);
}
void buttonLoop() {


+ 2
- 1
code/espurna/config/sensors.h View File

@ -474,7 +474,8 @@
#define I2C_CLOCK_STRETCH_TIME 200 // BRZO clock stretch time
#define I2C_SCL_FREQUENCY 1000 // BRZO SCL frequency
#define I2C_CLEAR_BUS 0 // Clear I2C bus at boot
#define I2C_CLEAR_BUS 0 // Clear I2C bus on boot
#define I2C_PERFORM_SCAN 1 // Perform a bus scan on boot
//--------------------------------------------------------------------------------
// Internal power monitor


+ 30
- 80
code/espurna/espurna.ino View File

@ -20,10 +20,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config/all.h"
#include <vector>
std::vector<void (*)()> _loop_callbacks;
// -----------------------------------------------------------------------------
// REGISTER
// -----------------------------------------------------------------------------
unsigned long _loopDelay = 0;
void espurnaRegisterLoop(void (*callback)()) {
_loop_callbacks.push_back(callback);
}
// -----------------------------------------------------------------------------
// BOOTING
@ -31,13 +38,8 @@ unsigned long _loopDelay = 0;
void setup() {
// Init EEPROM, Serial and SPIFFS
hardwareSetup();
// Question system stability
#if SYSTEM_CHECK_ENABLED
systemCheck(false);
#endif
// Init EEPROM, Serial, SPIFFS and system check
systemSetup();
// Init persistance and terminal features
settingsSetup();
@ -46,24 +48,31 @@ void setup() {
}
setBoardName();
// Cache loop delay value to speed things (recommended max 250ms)
_loopDelay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str());
// Show welcome message and system configuration
info();
// -------------------------------------------------------------------------
// Basic modules, will always run
// -------------------------------------------------------------------------
wifiSetup();
otaSetup();
#if TELNET_SUPPORT
telnetSetup();
#endif
// Do not run the next services if system is flagged stable
// -------------------------------------------------------------------------
// Check if system is stable
// -------------------------------------------------------------------------
#if SYSTEM_CHECK_ENABLED
if (!systemCheck()) return;
#endif
// -------------------------------------------------------------------------
// Next modules will be only loaded if system is flagged as stable
// -------------------------------------------------------------------------
// Init webserver required before any module that uses API
#if WEB_SUPPORT
webSetup();
@ -71,19 +80,23 @@ void setup() {
apiSetup();
#endif
// lightSetup must be called before relaySetup
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
lightSetup();
#endif
relaySetup();
buttonSetup();
ledSetup();
#if MQTT_SUPPORT
mqttSetup();
#endif
#if MDNS_SERVER_SUPPORT
mdnsServerSetup();
#endif
#if MDNS_CLIENT_SUPPORT
mdnsClientSetup();
#endif
#if LLMNR_SUPPORT
llmnrSetup();
#endif
@ -98,12 +111,7 @@ void setup() {
#endif
#if I2C_SUPPORT
i2cSetup();
#if I2C_CLEAR_BUS
i2cClearBus();
#endif
i2cScan();
#endif
#ifdef ITEAD_SONOFF_RFBRIDGE
rfbSetup();
#endif
@ -152,67 +160,9 @@ void setup() {
void loop() {
hardwareLoop();
settingsLoop();
wifiLoop();
otaLoop();
#if SYSTEM_CHECK_ENABLED
systemCheckLoop();
// Do not run the next services if system is flagged stable
if (!systemCheck()) return;
#endif
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
lightLoop();
#endif
relayLoop();
buttonLoop();
ledLoop();
#if MQTT_SUPPORT
mqttLoop();
#endif
#ifdef ITEAD_SONOFF_RFBRIDGE
rfbLoop();
#endif
#if SSDP_SUPPORT
ssdpLoop();
#endif
#if NTP_SUPPORT
ntpLoop();
#endif
#if ALEXA_SUPPORT
alexaLoop();
#endif
#if NOFUSS_SUPPORT
nofussLoop();
#endif
#if RF_SUPPORT
rfLoop();
#endif
#if IR_SUPPORT
irLoop();
#endif
#if SENSOR_SUPPORT
sensorLoop();
#endif
#if THINGSPEAK_SUPPORT
tspkLoop();
#endif
#if SCHEDULER_SUPPORT
schLoop();
#endif
#if MDNS_CLIENT_SUPPORT
mdnsClientLoop();
#endif
// 3rd party code hook
#if USE_EXTRA
extraLoop();
#endif
// Power saving delay
delay(_loopDelay);
// Call registered loop callbacks
for (unsigned char i = 0; i < _loop_callbacks.size(); i++) {
(_loop_callbacks[i])();
}
}

+ 0
- 47
code/espurna/hardware.ino View File

@ -1,47 +0,0 @@
/*
HARDWARE MODULE
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
*/
#include <EEPROM.h>
void hardwareSetup() {
EEPROM.begin(EEPROM_SIZE);
#if DEBUG_SERIAL_SUPPORT
DEBUG_PORT.begin(SERIAL_BAUDRATE);
#if DEBUG_ESP_WIFI
DEBUG_PORT.setDebugOutput(true);
#endif
#elif defined(SERIAL_BAUDRATE)
Serial.begin(SERIAL_BAUDRATE);
#endif
#if SPIFFS_SUPPORT
SPIFFS.begin();
#endif
#if defined(ESPLIVE)
//The ESPLive has an ADC MUX which needs to be configured.
pinMode(16, OUTPUT);
digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
#endif
}
void hardwareLoop() {
// Heartbeat
#if HEARTBEAT_ENABLED
static unsigned long last = 0;
if ((last == 0) || (millis() - last > HEARTBEAT_INTERVAL)) {
last = millis();
heartbeat();
}
#endif // HEARTBEAT_ENABLED
}

+ 8
- 0
code/espurna/i2c.ino View File

@ -196,6 +196,14 @@ void i2cSetup() {
DEBUG_MSG_P(PSTR("[I2C] Using GPIO%u for SDA and GPIO%u for SCL\n"), sda, scl);
#if I2C_CLEAR_BUS
i2cClearBus();
#endif
#if I2C_PERFORM_SCAN
i2cScan();
#endif
}
#endif

+ 5
- 0
code/espurna/ir.ino View File

@ -92,8 +92,13 @@ void _irProcessCode(unsigned long code) {
// -----------------------------------------------------------------------------
void irSetup() {
_ir_recv = new IRrecv(IR_PIN);
_ir_recv->enableIRIn();
// Register loop
espurnaRegisterLoop(irLoop);
}
void irLoop() {


+ 4
- 0
code/espurna/led.ino View File

@ -167,6 +167,10 @@ void ledSetup() {
DEBUG_MSG_P(PSTR("[LED] Number of leds: %d\n"), _leds.size());
// Register loop
espurnaRegisterLoop(ledLoop);
}
void ledLoop() {


+ 0
- 3
code/espurna/light.ino View File

@ -1041,7 +1041,4 @@ void lightSetup() {
}
void lightLoop(){
}
#endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE

+ 7
- 0
code/espurna/mdns.ino View File

@ -118,6 +118,13 @@ String mdnsResolve(String name) {
return mdnsResolve((char *) name.c_str());
}
void mdnsClientSetup() {
// Register loop
espurnaRegisterLoop(mdnsClientLoop);
}
void mdnsClientLoop() {
_mdns_resolver.loop();
}


+ 3
- 0
code/espurna/mqtt.ino View File

@ -729,6 +729,9 @@ void mqttSetup() {
_mqttInitCommands();
#endif
// Register loop
espurnaRegisterLoop(mqttLoop);
}
void mqttLoop() {


+ 3
- 0
code/espurna/nofuss.ino View File

@ -153,6 +153,9 @@ void nofussSetup() {
_nofussInitCommands();
#endif
// Register loop
espurnaRegisterLoop(nofussLoop);
}
void nofussLoop() {


+ 3
- 0
code/espurna/ntp.ino View File

@ -94,6 +94,9 @@ void ntpSetup() {
wsOnAfterParseRegister(_ntpConfigure);
#endif
// Register loop
espurnaRegisterLoop(ntpLoop);
}
void ntpLoop() {


+ 3
- 0
code/espurna/ota.ino View File

@ -61,6 +61,9 @@ void otaSetup() {
ArduinoOTA.begin();
// Register loop
espurnaRegisterLoop(otaLoop);
}
void otaLoop() {


+ 2
- 0
code/espurna/relay.ino View File

@ -728,6 +728,8 @@ void relaySetup() {
_relayBoot();
relayLoop();
espurnaRegisterLoop(relayLoop);
#if WEB_SUPPORT
relaySetupAPI();
relaySetupWS();


+ 3
- 0
code/espurna/rf.ino View File

@ -101,6 +101,9 @@ void rfSetup() {
wsOnAfterParseRegister(_rfBuildCodes);
#endif
// Register loop
espurnaRegisterLoop(rfLoop);
}
#endif

+ 3
- 0
code/espurna/rfbridge.ino View File

@ -505,6 +505,9 @@ void rfbSetup() {
wsOnActionRegister(_rfbWebSocketOnAction);
#endif
// Register oop
espurnaRegisterLoop(rfbLoop);
}
void rfbLoop() {


+ 3
- 0
code/espurna/scheduler.ino View File

@ -116,6 +116,9 @@ void schSetup() {
wsOnAfterParseRegister(_schConfigure);
#endif
// Register loop
espurnaRegisterLoop(schLoop);
}
void schLoop() {


+ 3
- 0
code/espurna/sensor.ino View File

@ -619,6 +619,9 @@ void sensorSetup() {
_sensorInitCommands();
#endif
// Register loop
espurnaRegisterLoop(sensorLoop);
}
void sensorLoop() {


+ 3
- 0
code/espurna/settings.ino View File

@ -416,6 +416,9 @@ void settingsSetup() {
#endif
#endif
// Register loop
espurnaRegisterLoop(settingsLoop);
}
void settingsLoop() {


+ 3
- 0
code/espurna/ssdp.ino View File

@ -31,6 +31,9 @@ void ssdpSetup() {
});
#endif
// Register loop
espurnaRegisterLoop(ssdpLoop);
}
void ssdpLoop() {


+ 116
- 0
code/espurna/system.ino View File

@ -0,0 +1,116 @@
/*
SYSTEM MODULE
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
*/
#include <EEPROM.h>
// -----------------------------------------------------------------------------
unsigned long _loopDelay = 0;
// -----------------------------------------------------------------------------
#if SYSTEM_CHECK_ENABLED
// Call this method on boot with start=true to increase the crash counter
// Call it again once the system is stable to decrease the counter
// If the counter reaches SYSTEM_CHECK_MAX then the system is flagged as unstable
// setting _systemOK = false;
//
// An unstable system will only have serial access, WiFi in AP mode and OTA
bool _systemStable = true;
void systemCheck(bool stable) {
unsigned char value = EEPROM.read(EEPROM_CRASH_COUNTER);
if (stable) {
value = 0;
DEBUG_MSG_P(PSTR("[MAIN] System OK\n"));
} else {
if (++value > SYSTEM_CHECK_MAX) {
_systemStable = false;
value = 0;
DEBUG_MSG_P(PSTR("[MAIN] System UNSTABLE\n"));
}
}
EEPROM.write(EEPROM_CRASH_COUNTER, value);
EEPROM.commit();
}
bool systemCheck() {
return _systemStable;
}
void systemCheckLoop() {
static bool checked = false;
if (!checked && (millis() > SYSTEM_CHECK_TIME)) {
// Check system as stable
systemCheck(true);
checked = true;
}
}
#endif
// -----------------------------------------------------------------------------
void systemLoop() {
// Check system stability
#if SYSTEM_CHECK_ENABLED
systemCheckLoop();
#endif
#if HEARTBEAT_ENABLED
// Heartbeat
static unsigned long last = 0;
if ((last == 0) || (millis() - last > HEARTBEAT_INTERVAL)) {
last = millis();
heartbeat();
}
#endif // HEARTBEAT_ENABLED
// Power saving delay
delay(_loopDelay);
}
void systemSetup() {
EEPROM.begin(EEPROM_SIZE);
#if DEBUG_SERIAL_SUPPORT
DEBUG_PORT.begin(SERIAL_BAUDRATE);
#if DEBUG_ESP_WIFI
DEBUG_PORT.setDebugOutput(true);
#endif
#elif defined(SERIAL_BAUDRATE)
Serial.begin(SERIAL_BAUDRATE);
#endif
#if SPIFFS_SUPPORT
SPIFFS.begin();
#endif
// Question system stability
#if SYSTEM_CHECK_ENABLED
systemCheck(false);
#endif
#if defined(ESPLIVE)
//The ESPLive has an ADC MUX which needs to be configured.
pinMode(16, OUTPUT);
digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
#endif
// Cache loop delay value to speed things (recommended max 250ms)
_loopDelay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str());
// Register Loop
espurnaRegisterLoop(systemLoop);
}

+ 7
- 0
code/espurna/thinkspeak.ino View File

@ -242,15 +242,22 @@ bool tspkEnabled() {
}
void tspkSetup() {
_tspkConfigure();
#if WEB_SUPPORT
wsOnSendRegister(_tspkWebSocketOnSend);
wsOnAfterParseRegister(_tspkConfigure);
#endif
DEBUG_MSG_P(PSTR("[THINGSPEAK] Async %s, SSL %s\n"),
THINGSPEAK_USE_ASYNC ? "ENABLED" : "DISABLED",
THINGSPEAK_USE_SSL ? "ENABLED" : "DISABLED"
);
// Register loop
espurnaRegisterLoop(tspkLoop);
}
void tspkLoop() {


+ 0
- 44
code/espurna/utils.ino View File

@ -489,50 +489,6 @@ void deferredReset(unsigned long delay, unsigned char reason) {
// -----------------------------------------------------------------------------
#if SYSTEM_CHECK_ENABLED
// Call this method on boot with start=true to increase the crash counter
// Call it again once the system is stable to decrease the counter
// If the counter reaches SYSTEM_CHECK_MAX then the system is flagged as unstable
// setting _systemOK = false;
//
// An unstable system will only have serial access, WiFi in AP mode and OTA
bool _systemStable = true;
void systemCheck(bool stable) {
unsigned char value = EEPROM.read(EEPROM_CRASH_COUNTER);
if (stable) {
value = 0;
DEBUG_MSG_P(PSTR("[MAIN] System OK\n"));
} else {
if (++value > SYSTEM_CHECK_MAX) {
_systemStable = false;
value = 0;
DEBUG_MSG_P(PSTR("[MAIN] System UNSTABLE\n"));
}
}
EEPROM.write(EEPROM_CRASH_COUNTER, value);
EEPROM.commit();
}
bool systemCheck() {
return _systemStable;
}
void systemCheckLoop() {
static bool checked = false;
if (!checked && (millis() > SYSTEM_CHECK_TIME)) {
// Check system as stable
systemCheck(true);
checked = true;
}
}
#endif
// -----------------------------------------------------------------------------
char * ltrim(char * s) {
char *p = s;
while ((unsigned char) *p == ' ') ++p;


+ 3
- 0
code/espurna/wifi.ino View File

@ -447,6 +447,9 @@ void wifiSetup() {
_wifiInitCommands();
#endif
// Register loop
espurnaRegisterLoop(wifiLoop);
}
void wifiLoop() {


Loading…
Cancel
Save