Skip to content

Commit

Permalink
🎨 More Refactoring + Deep Sleep + Prevent WiFi Reconnect when reboot (h…
Browse files Browse the repository at this point in the history
…omieiot#432)

* Initial AsyncWebServer

* Fixed Proccessing Body Requests (JSON)

* Doc Fixes + typo

* Added Missing Method in Timer.cpp

* Lots of Refactoring + Moved Reset Button to its own helper class for boots to use

* Lots of Refactoring.

* Refactored ResetHandler + More Refactoring + Testing

* Added deep sleep function + Prevent Wifi reconnect before reboot (homieiot#380)[homieiot#380]

* Small typo fixes

* Small Rearange of code in BootConfig + Minor Refactor of function names

* Minior Commit to Triger a Github Action

* circleci build fix
  • Loading branch information
timpur authored and jesserockz committed Mar 12, 2018
1 parent bc4c899 commit c421984
Show file tree
Hide file tree
Showing 26 changed files with 817 additions and 645 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
/site/

/config.json
*.filters
*.vcxitems
2 changes: 1 addition & 1 deletion docs/advanced-usage/deep-sleep.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void onHomieEvent(const HomieEvent& event) {
break;
case HomieEventType::READY_TO_SLEEP:
Homie.getLogger() << "Ready to sleep" << endl;
ESP.deepSleep();
Homie.doDeepSleep();
break;
}
}
Expand Down
6 changes: 6 additions & 0 deletions docs/others/cpp-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ void prepareToSleep();

Prepare the device for deep sleep. It ensures messages are sent and disconnects cleanly from the MQTT broker, triggering a `READY_TO_SLEEP` event when done.

```c++
void doDeepSleep(uint32_t time_us = 0, RFMode mode = RF_DEFAULT);
```
Puth the device into deep sleep. It ensures the Serial is flushed.
```c++
bool isConfigured() const;
```
Expand Down
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ getConfiguration KEYWORD2
getMqttClient KEYWORD2
getLogger KEYWORD2
prepareToSleep KEYWORD2
doDeepSleep KEYWORD2

# HomieNode

Expand Down
59 changes: 43 additions & 16 deletions src/Homie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using namespace HomieInternals;

HomieClass::HomieClass()
: _setupCalled(false)
, _firmwareSet(false)
, __HOMIE_SIGNATURE("\x25\x48\x4f\x4d\x49\x45\x5f\x45\x53\x50\x38\x32\x36\x36\x5f\x46\x57\x25") {
: _setupCalled(false)
, _firmwareSet(false)
, __HOMIE_SIGNATURE("\x25\x48\x4f\x4d\x49\x45\x5f\x45\x53\x50\x38\x32\x36\x36\x5f\x46\x57\x25") {
strlcpy(Interface::get().brand, DEFAULT_BRAND, MAX_BRAND_LENGTH);
Interface::get().bootMode = HomieBootMode::UNDEFINED;
Interface::get().configurationAp.secured = false;
Expand All @@ -17,7 +17,8 @@ HomieClass::HomieClass()
Interface::get().reset.triggerPin = DEFAULT_RESET_PIN;
Interface::get().reset.triggerState = DEFAULT_RESET_STATE;
Interface::get().reset.triggerTime = DEFAULT_RESET_TIME;
Interface::get().reset.flaggedBySketch = false;
Interface::get().reset.resetFlag = false;
Interface::get().disable = false;
Interface::get().flaggedForSleep = false;
Interface::get().globalInputHandler = [](const HomieNode& node, const String& property, const HomieRange& range, const String& value) { return false; };
Interface::get().broadcastHandler = [](const String& level, const String& value) { return false; };
Expand Down Expand Up @@ -51,14 +52,18 @@ void HomieClass::setup() {
_setupCalled = true;

// Check if firmware is set

if (!_firmwareSet) {
Helpers::abort(F("✖ Firmware name must be set before calling setup()"));
return; // never reached, here for clarity
}

// Check if default settings values are valid
// Check the max allowed setting elements
if (IHomieSetting::settings.size() > MAX_CONFIG_SETTING_SIZE) {
Helpers::abort(F("✖ Settings exceed set limit of elelement."));
return; // never reached, here for clarity
}

// Check if default settings values are valid
bool defaultSettingsValuesValid = true;
for (IHomieSetting* iSetting : IHomieSetting::settings) {
if (iSetting->isBool()) {
Expand All @@ -67,19 +72,22 @@ void HomieClass::setup() {
defaultSettingsValuesValid = false;
break;
}
} else if (iSetting->isLong()) {
}
else if (iSetting->isLong()) {
HomieSetting<long>* setting = static_cast<HomieSetting<long>*>(iSetting);
if (!setting->isRequired() && !setting->validate(setting->get())) {
defaultSettingsValuesValid = false;
break;
}
} else if (iSetting->isDouble()) {
}
else if (iSetting->isDouble()) {
HomieSetting<double>* setting = static_cast<HomieSetting<double>*>(iSetting);
if (!setting->isRequired() && !setting->validate(setting->get())) {
defaultSettingsValuesValid = false;
break;
}
} else if (iSetting->isConstChar()) {
}
else if (iSetting->isConstChar()) {
HomieSetting<const char*>* setting = static_cast<HomieSetting<const char*>*>(iSetting);
if (!setting->isRequired() && !setting->validate(setting->get())) {
defaultSettingsValuesValid = false;
Expand Down Expand Up @@ -107,9 +115,11 @@ void HomieClass::setup() {
// select boot mode source
if (_applicationHomieBootMode != HomieBootMode::UNDEFINED) {
_selectedHomieBootMode = _applicationHomieBootMode;
} else if (_nextHomieBootMode != HomieBootMode::UNDEFINED) {
}
else if (_nextHomieBootMode != HomieBootMode::UNDEFINED) {
_selectedHomieBootMode = _nextHomieBootMode;
} else {
}
else {
_selectedHomieBootMode = HomieBootMode::NORMAL;
}

Expand All @@ -125,17 +135,20 @@ void HomieClass::setup() {
Interface::get().event.type = HomieEventType::NORMAL_MODE;
Interface::get().eventHandler(Interface::get().event);

} else if (_selectedHomieBootMode == HomieBootMode::CONFIGURATION) {
}
else if (_selectedHomieBootMode == HomieBootMode::CONFIGURATION) {
_boot = &_bootConfig;
Interface::get().event.type = HomieEventType::CONFIGURATION_MODE;
Interface::get().eventHandler(Interface::get().event);

} else if (_selectedHomieBootMode == HomieBootMode::STANDALONE) {
}
else if (_selectedHomieBootMode == HomieBootMode::STANDALONE) {
_boot = &_bootStandalone;
Interface::get().event.type = HomieEventType::STANDALONE_MODE;
Interface::get().eventHandler(Interface::get().event);

} else {
}
else {
Helpers::abort(F("✖ Boot mode invalid"));
return; // never reached, here for clarity
}
Expand Down Expand Up @@ -225,10 +238,14 @@ void HomieClass::__setBrand(const char* brand) const {
}

void HomieClass::reset() {
Interface::get().reset.flaggedBySketch = true;
Interface::get().getLogger() << F("Flagged for reset by sketch") << endl;
Interface::get().disable = true;
Interface::get().reset.resetFlag = true;
}

void HomieClass::reboot() {
Interface::get().getLogger() << F("Flagged for reboot by sketch") << endl;
Interface::get().disable = true;
_flaggedForReboot = true;
}

Expand Down Expand Up @@ -327,13 +344,23 @@ Logger& HomieClass::getLogger() {
}

void HomieClass::prepareToSleep() {
Interface::get().getLogger() << F("Flagged for sleep by sketch") << endl;
if (Interface::get().ready) {
Interface::get().disable = true;
Interface::get().flaggedForSleep = true;
} else {
}
else {
Interface::get().disable = true;
Interface::get().getLogger() << F("Triggering READY_TO_SLEEP event...") << endl;
Interface::get().event.type = HomieEventType::READY_TO_SLEEP;
Interface::get().eventHandler(Interface::get().event);
}
}

void HomieClass::doDeepSleep(uint32_t time_us, RFMode mode){
Interface::get().getLogger() << F("💤 Device is deep sleeping...") << endl;
Serial.flush();
ESP.deepSleep(time_us, mode);
}

HomieClass Homie;
103 changes: 53 additions & 50 deletions src/Homie.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "Arduino.h"

#include <AsyncMqttClient.h>
#include "AsyncMqttClient.h"
#include "Homie/Datatypes/Interface.hpp"
#include "Homie/Constants.hpp"
#include "Homie/Limits.hpp"
Expand All @@ -22,66 +22,69 @@
#include "HomieSetting.hpp"
#include "StreamingOperator.hpp"

// Define DEBUG for debug

#define Homie_setFirmware(name, version) const char* __FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" name "\x93\x44\x6b\xa7\x75"; const char* __FLAGGED_FW_VERSION = "\x6a\x3f\x3e\x0e\xe1" version "\xb0\x30\x48\xd4\x1a"; Homie.__setFirmware(__FLAGGED_FW_NAME, __FLAGGED_FW_VERSION);
#define Homie_setBrand(brand) const char* __FLAGGED_BRAND = "\xfb\x2a\xf5\x68\xc0" brand "\x6e\x2f\x0f\xeb\x2d"; Homie.__setBrand(__FLAGGED_BRAND);

namespace HomieInternals {
class HomieClass {
friend class ::HomieNode;
friend SendingPromise;
class HomieClass {
friend class ::HomieNode;
friend SendingPromise;

public:
HomieClass();
~HomieClass();
void setup();
void loop();
public:
HomieClass();
~HomieClass();
void setup();
void loop();

void __setFirmware(const char* name, const char* version);
void __setBrand(const char* brand) const;
void __setFirmware(const char* name, const char* version);
void __setBrand(const char* brand) const;

HomieClass& disableLogging();
HomieClass& setLoggingPrinter(Print* printer);
HomieClass& disableLedFeedback();
HomieClass& setLedPin(uint8_t pin, uint8_t on);
HomieClass& setConfigurationApPassword(const char* password);
HomieClass& setGlobalInputHandler(const GlobalInputHandler& globalInputHandler);
HomieClass& setBroadcastHandler(const BroadcastHandler& broadcastHandler);
HomieClass& onEvent(const EventHandler& handler);
HomieClass& setResetTrigger(uint8_t pin, uint8_t state, uint16_t time);
HomieClass& disableResetTrigger();
HomieClass& setSetupFunction(const OperationFunction& function);
HomieClass& setLoopFunction(const OperationFunction& function);
HomieClass& setHomieBootMode(HomieBootMode bootMode);
HomieClass& setHomieBootModeOnNextBoot(HomieBootMode bootMode);
HomieClass& disableLogging();
HomieClass& setLoggingPrinter(Print* printer);
HomieClass& disableLedFeedback();
HomieClass& setLedPin(uint8_t pin, uint8_t on);
HomieClass& setConfigurationApPassword(const char* password);
HomieClass& setGlobalInputHandler(const GlobalInputHandler& globalInputHandler);
HomieClass& setBroadcastHandler(const BroadcastHandler& broadcastHandler);
HomieClass& onEvent(const EventHandler& handler);
HomieClass& setResetTrigger(uint8_t pin, uint8_t state, uint16_t time);
HomieClass& disableResetTrigger();
HomieClass& setSetupFunction(const OperationFunction& function);
HomieClass& setLoopFunction(const OperationFunction& function);
HomieClass& setHomieBootMode(HomieBootMode bootMode);
HomieClass& setHomieBootModeOnNextBoot(HomieBootMode bootMode);

static void reset();
void reboot();
static void setIdle(bool idle);
static bool isConfigured();
static bool isConnected();
static const ConfigStruct& getConfiguration();
AsyncMqttClient& getMqttClient();
Logger& getLogger();
static void prepareToSleep();
static void reset();
void reboot();
static void setIdle(bool idle);
static bool isConfigured();
static bool isConnected();
static const ConfigStruct& getConfiguration();
AsyncMqttClient& getMqttClient();
Logger& getLogger();
static void prepareToSleep();
static void doDeepSleep(uint32_t time_us = 0, RFMode mode = RF_DEFAULT);

private:
bool _setupCalled;
bool _firmwareSet;
Boot* _boot;
BootStandalone _bootStandalone;
BootNormal _bootNormal;
BootConfig _bootConfig;
bool _flaggedForReboot;
SendingPromise _sendingPromise;
Logger _logger;
Blinker _blinker;
Config _config;
AsyncMqttClient _mqttClient;
private:
bool _setupCalled;
bool _firmwareSet;
Boot* _boot;
BootStandalone _bootStandalone;
BootNormal _bootNormal;
BootConfig _bootConfig;
bool _flaggedForReboot;
SendingPromise _sendingPromise;
Logger _logger;
Blinker _blinker;
Config _config;
AsyncMqttClient _mqttClient;

void _checkBeforeSetup(const __FlashStringHelper* functionName) const;
void _checkBeforeSetup(const __FlashStringHelper* functionName) const;

const char* __HOMIE_SIGNATURE;
};
const char* __HOMIE_SIGNATURE;
};
} // namespace HomieInternals

extern HomieInternals::HomieClass Homie;
Loading

0 comments on commit c421984

Please sign in to comment.