Add M5 boards compatibility and low power mode (#586)

This commit is contained in:
Florian authored and GitHub committed 2020-04-26 19:56:10 -05:00
1 parent ac743ed350
commit 30147140bd
18 files changed
+753 -199

No files matched your search

+28 -2
View File
@@ -50,6 +50,9 @@
#ifndef Gateway_Name
#define Gateway_Name "OpenMQTTGateway"
#endif
#ifndef Gateway_Short_Name
#define Gateway_Short_Name "OMG"
#endif
#define Base_Topic "home/"
@@ -111,6 +114,26 @@ char gateway_name[parameters_size * 2] = Gateway_Name;
#define ATTEMPTS_BEFORE_B 20 // Number of wifi connection attempts before going to B protocol
#endif
/*------------------DEEP SLEEP parameters ------------------*/
//DEFAULT_LOW_POWER_MODE 0 to normal mode (no power consumption optimisations)
//DEFAULT_LOW_POWER_MODE 1 to activate deep sleep with LCD ON when a function is processing,
//DEFAULT_LOW_POWER_MODE 2 to activate deep sleep with LED ON when a function is processing (LCD is turned OFF)
#ifdef ESP32
#ifndef SLEEP_BUTTON
#define SLEEP_BUTTON 33
#endif
#ifndef DEFAULT_LOW_POWER_MODE
#define DEFAULT_LOW_POWER_MODE 0
#endif
#ifndef LOW_POWER_LED
#define LOW_POWER_LED 2
#endif
#ifndef LOW_POWER_LED_OFF
#define LOW_POWER_LED_OFF 1
#endif
int low_power_mode = DEFAULT_LOW_POWER_MODE;
#endif
// WIFI mode, uncomment to force a wifi mode, if not uncommented the ESP will connect without a mode forced
// if there is a reconnection issue it will try to connect with G mode and if not working with B mode
#ifdef ESP32
@@ -153,6 +176,8 @@ char gateway_name[parameters_size * 2] = Gateway_Name;
//#define ZsensorGPIOInput "GPIOInput" //ESP8266, Arduino, ESP32
//#define ZmqttDiscovery "HADiscovery"//ESP8266, Arduino, ESP32, Sonoff RF Bridge
//#define ZactuatorFASTLED "FASTLED" //ESP8266, Arduino, ESP32, Sonoff RF Bridge
//#define ZboardM5STICKC "M5StickC"
//#define ZboardM5STACK "ZboardM5STACK"
//#define ZradioCC1101 "CC1101" //ESP8266, ESP32
/*-------------DEFINE YOUR MQTT ADVANCED PARAMETERS BELOW----------------*/
@@ -255,11 +280,12 @@ char gateway_name[parameters_size * 2] = Gateway_Name;
#define JSON_MSG_BUFFER 64 // Json message max buffer size, don't put 1024 or higher it is causing unexpected behaviour on ESP8266
#endif
#define TimeBetweenReadingSYS 120000 // time between system readings (like memory)
#define TimeBetweenReadingSYS 120 // time between (s) system readings (like memory)
#define TimeBeforeMQTTconnect 10 // time estimated (s) before the board is connected to MQTT
#define subjectSYStoMQTT "/SYStoMQTT"
#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
/*-------------------DEFINE LOG LEVEL----------------------*/
#define LOG_LEVEL LOG_LEVEL_VERBOSE
#define LOG_LEVEL LOG_LEVEL_NOTICE
#endif
+252
View File
@@ -0,0 +1,252 @@
/*
OpenMQTTGateway Addon - ESP8266 or Arduino program for home automation
Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
Send and receiving command by MQTT
M5 boards management
Copyright: (c)Florian ROBERT
Contributors:
- 1technophile
This file is part of OpenMQTTGateway.
OpenMQTTGateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenMQTTGateway is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "User_config.h"
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
#ifdef ZboardM5STICKC
#include <M5StickC.h>
#endif
#ifdef ZboardM5STACK
#include <M5Stack.h>
#endif
void logToLCD(bool display)
{
display ? Log.begin(LOG_LEVEL_LCD, &M5.Lcd) : Log.begin(LOG_LEVEL, &Serial); // Log on LCD following LOG_LEVEL_LCD
}
void setBrightness(int brightness)
{
#ifdef ZboardM5STACK
M5.Lcd.setBrightness(brightness * 2);
#endif
#ifdef ZboardM5STICKC
(!brightness) ? M5.Axp.ScreenBreath(0) : M5.Axp.ScreenBreath(7 + (int)brightness * 0.08);
#endif
}
void setupM5()
{
Log.notice(F("Setup M5" CR));
pinMode(SLEEP_BUTTON, INPUT);
// M5 stack 320*240
// M5StickC 160*80
// M5Stick LCD not supported
Log.notice(F("Low power set to: %d" CR), low_power_mode);
switch (low_power_mode)// if LOW POWER the intro is bypassed and the brightness set to sleep brightness
{
case 0:
wakeScreen(NORMAL_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(WHITE);
displayIntro(M5.Lcd.width() * 0.25, (M5.Lcd.width() / 2) + M5.Lcd.width() * 0.12, (M5.Lcd.height()/2) + M5.Lcd.height() * 0.2);
#ifdef LOG_TO_LCD
Log.begin(LOG_LEVEL_LCD, &M5.Lcd); // Log on LCD following LOG_LEVEL_LCD
#endif
break;
case 1:
wakeScreen(SLEEP_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(WHITE);
#ifdef LOG_TO_LCD
Log.begin(LOG_LEVEL_LCD, &M5.Lcd); // Log on LCD following LOG_LEVEL_LCD
#endif
break;
case 2:
M5.begin(false,false,false);
break;
}
Log.notice(F("Setup M5 end" CR));
}
void sleepScreen()
{
Log.trace(F("Screen going to sleep" CR));
#ifdef ZboardM5STACK
M5.begin(false,false,false); // M5.lcd.sleep() provokes a reset of the ESP
#endif
#ifdef ZboardM5STICKC
M5.Axp.ScreenBreath(0);
M5.Axp.SetLDO2(false);
#endif
}
void wakeScreen(int brightness)
{
Log.trace(F("Screen wake up" CR));
M5.begin();
M5.Lcd.setCursor(0, 0, (M5.Lcd.height() > 200) ? 4:2);
M5.Lcd.setTextSize(1);
M5.Lcd.setRotation(1);
setBrightness(brightness);
}
void loopM5()
{
static int previousBtnState;
int currentBtnState = digitalRead(SLEEP_BUTTON);
if(currentBtnState != previousBtnState && currentBtnState == 0)
{
int newlow_power_mode = low_power_mode;
(low_power_mode == 2) ? newlow_power_mode = 0 : newlow_power_mode = newlow_power_mode + 1;
changelow_power_mode(newlow_power_mode);
}
previousBtnState = currentBtnState;
static int previousLogLevel;
switch (Log.getLastMsgLevel())
{
case 1:
case 2:
if (low_power_mode != 2)
{
wakeScreen(NORMAL_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(TFT_RED); // FATAL, ERROR
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
}
break;
case 3:
if (low_power_mode != 2)
{
wakeScreen(NORMAL_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(TFT_ORANGE); // WARNING
M5.Lcd.setTextColor(TFT_BLACK, TFT_ORANGE);
}
break;
default:
if (previousLogLevel != Log.getLastMsgLevel() && low_power_mode != 2)
{
wakeScreen(SLEEP_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(TFT_WHITE);
drawLogo(M5.Lcd.width() * 0.1875, (M5.Lcd.width()/2) - M5.Lcd.width() * 0.24, M5.Lcd.height() * 0.5, true, true, true, true, true, true);
}
break;
}
previousLogLevel = Log.getLastMsgLevel();
}
void MQTTtoM5(char *topicOri, JsonObject &M5data)
{ // json object decoding
if (cmpToMainTopic(topicOri, subjectMQTTtoM5set))
{
Log.trace(F("MQTTtoM5 json set" CR));
// Log display set between M5 lcd (true) and serial monitor (false)
if (M5data.containsKey("log-lcd"))
{
bool displayOnLCD = M5data["log-lcd"];
Log.notice(F("Set lcd log: %T" CR), displayOnLCD);
logToLCD(displayOnLCD);
}
}
}
void displayIntro(int i, int X, int Y)
{
Log.trace(F("Intro display on screen" CR));
drawLogo(i, X, Y, false, true, false, false, false, false);
delay(50);
drawLogo(i, X, Y, false, false, true, false, false, false);
delay(50);
drawLogo(i, X, Y, false, true, false, false, false, false);
delay(50);
drawLogo(i, X, Y, false, true, true, false, false, false);
delay(50);
drawLogo(i, X, Y, false, true, true, true, false, false);
delay(50);
drawLogo(i, X, Y, false, true, true, false, true, false);
delay(50);
drawLogo(i, X, Y, false, true, true, true, true, false);
delay(50);
drawLogo(i, X, Y, true, true, true, true, true, false);
}
void drawLogo(int logoSize, int circle1X, int circle1Y, bool circle1, bool circle2, bool circle3, bool line1, bool line2, bool name)
{
int circle1T = logoSize / 15;
int circle2T = logoSize / 25;
int circle3T = logoSize / 30;
int circle3Y = circle1Y - (logoSize * 1.2);
int circle3X = circle1X - (logoSize * 0.13);
int circle2X = circle1X - (logoSize * 1.05);
int circle2Y = circle1Y - (logoSize * 0.8);
if (line1)
{
M5.Lcd.drawLine(circle1X - 2, circle1Y, circle2X - 2, circle2Y, BLUE);
M5.Lcd.drawLine(circle1X - 1, circle1Y, circle2X - 1, circle2Y, BLUE);
M5.Lcd.drawLine(circle1X, circle1Y, circle2X, circle2Y, BLUE);
M5.Lcd.drawLine(circle1X + 1, circle1Y, circle2X + 1, circle2Y, BLUE);
M5.Lcd.drawLine(circle1X + 2, circle1Y, circle2X + 2, circle2Y, BLUE);
M5.Lcd.fillCircle(circle3X, circle3Y, logoSize / 4 - circle3T * 2, WHITE);
}
if (line2)
{
M5.Lcd.drawLine(circle1X - 2, circle1Y, circle3X - 2, circle3Y, BLUE);
M5.Lcd.drawLine(circle1X - 1, circle1Y, circle3X - 1, circle3Y, BLUE);
M5.Lcd.drawLine(circle1X, circle1Y, circle3X, circle3Y, BLUE);
M5.Lcd.drawLine(circle1X + 1, circle1Y, circle3X + 1, circle3Y, BLUE);
M5.Lcd.fillCircle(circle2X, circle2Y, logoSize / 3 - circle2T * 2, WHITE);
}
M5.Lcd.fillCircle(circle1X, circle1Y, logoSize / 2 - circle1T * 2, WHITE);
if (circle1)
{
M5.Lcd.fillCircle(circle1X, circle1Y, logoSize / 2, WHITE);
M5.Lcd.fillCircle(circle1X, circle1Y, logoSize / 2 - circle1T, TFT_GREEN);
M5.Lcd.fillCircle(circle1X, circle1Y, logoSize / 2 - circle1T * 2, WHITE);
}
if (circle2)
{
M5.Lcd.fillCircle(circle2X, circle2Y, logoSize / 3, WHITE);
M5.Lcd.fillCircle(circle2X, circle2Y, logoSize / 3 - circle2T, TFT_ORANGE);
M5.Lcd.fillCircle(circle2X, circle2Y, logoSize / 3 - circle2T * 2, WHITE);
}
if (circle3)
{
M5.Lcd.fillCircle(circle3X, circle3Y, logoSize / 4, WHITE);
M5.Lcd.fillCircle(circle3X, circle3Y, logoSize / 4 - circle3T, TFT_PINK);
M5.Lcd.fillCircle(circle3X, circle3Y, logoSize / 4 - circle3T * 2, WHITE);
}
if (name)
{
M5.Lcd.setTextColor(BLUE);
M5.Lcd.drawString("penMQTTGateway", circle1X + (circle1X * 0.27), circle1Y, (M5.Lcd.height() > 200) ? 4:2);
}
}
void M5Display(char * line1, char * line2, char * line3)
{
if (low_power_mode == 2) digitalWrite(LOW_POWER_LED, 1 - LOW_POWER_LED_OFF);
wakeScreen(NORMAL_LCD_BRIGHTNESS);
M5.Lcd.fillScreen(TFT_WHITE);
drawLogo(M5.Lcd.width() * 0.1875, (M5.Lcd.width()/2) - M5.Lcd.width() * 0.24, M5.Lcd.height() * 0.5, true, true, true, true, true, true);
M5.Lcd.setTextColor(BLUE);
M5.Lcd.drawString(line1, 5, M5.Lcd.height() * 0.7, 1);
M5.Lcd.drawString(line2, 5, M5.Lcd.height() * 0.8, 1);
M5.Lcd.drawString(line3, 5, M5.Lcd.height() * 0.9, 1);
delay(2000);
digitalWrite(LOW_POWER_LED, LOW_POWER_LED_OFF); // to switch off no need of condition
}
#endif
+85 -9
View File
@@ -32,8 +32,12 @@ Thanks to wolass https://github.com/wolass for suggesting me HM 10 and dinosd ht
#ifdef ESP32
#include "FreeRTOS.h"
FreeRTOS::Semaphore semaphoreCreateOrUpdateDevice = FreeRTOS::Semaphore("createOrUpdateDevice");
// Headers used for deep sleep functions
#include <esp_wifi.h>
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <driver/adc.h>
#endif
#ifdef ZgatewayBT
@@ -553,29 +557,95 @@ void BLEscan()
void coreTask(void *pvParameters)
{
while (true)
{
Log.trace(F('BT Task running on core: %d'),xPortGetCoreID());
delay(BLEinterval);
if (client.state() == 0)
Log.trace(F("BT Task running on core: %d" CR), xPortGetCoreID());
if (!low_power_mode)
delay(BLEinterval);
int n = 0;
while (client.state() != 0 && n <= TimeBeforeMQTTconnect)
{
BLEscan();
n++;
Log.trace(F("Wait for MQTT on core: %d attempt: %d" CR), xPortGetCoreID(), n);
delay(1000);
}
else
if(client.state() != 0 )
{
Log.warning(F("MQTT client disconnected no BLE scan" CR));
delay(1000);
}
else
{
pinMode(LOW_POWER_LED, OUTPUT);
if (low_power_mode == 2)
digitalWrite(LOW_POWER_LED, 1 - LOW_POWER_LED_OFF);
BLEscan();
digitalWrite(LOW_POWER_LED, LOW_POWER_LED_OFF); // to switch off no need of condition
}
if(low_power_mode)
lowPowerESP32();
}
}
void lowPowerESP32() // low power mode
{
stateMeasures(); // publish MQTT SYS data before going to sleep
Log.trace(F("Going to deep sleep for: %l s" CR), (BLEinterval / 1000));
deepSleep(BLEinterval * 1000);
}
void deepSleep(uint64_t time_in_us)
{
#if defined(ZboardM5STACK) || defined(ZboardM5STICKC)
sleepScreen();
esp_sleep_enable_ext0_wakeup((gpio_num_t)SLEEP_BUTTON, LOW);
#endif
Log.trace(F("Deactivating ESP32 components" CR));
esp_wifi_stop();
esp_bluedroid_disable();
esp_bluedroid_deinit();
esp_bt_controller_disable();
esp_bt_controller_deinit();
esp_bt_mem_release(ESP_BT_MODE_BTDM);
adc_power_off();
esp_wifi_stop();
esp_deep_sleep(time_in_us);
}
void changelow_power_mode(int newLowPowerMode)
{
Log.notice(F("Changing LOW POWER mode to: %d" CR), newLowPowerMode);
#if defined(ZboardM5STACK) || defined(ZboardM5STICKC)
if (low_power_mode == 2)
{
#ifdef ZboardM5STACK
M5.Lcd.wakeup();
#endif
#ifdef ZboardM5STICKC
M5.Axp.SetLDO2(true);
M5.Lcd.begin();
#endif
}
char lpm[2];
sprintf(lpm, "%d", newLowPowerMode);
M5Display("Changing LOW POWER mode to:", lpm, "");
#endif
low_power_mode = newLowPowerMode;
preferences.begin(Gateway_Short_Name, false);
preferences.putUInt("low_power_mode", low_power_mode);
preferences.end();
}
void setupBT()
{
BLEinterval = TimeBtw_Read;
Minrssi = MinimumRSSI;
Log.notice(F("BLEinterval: %d" CR),BLEinterval);
Log.notice(F("Minrssi: %d" CR),Minrssi);
Log.notice(F("BLEinterval: %d" CR), BLEinterval);
Log.notice(F("Minrssi: %d" CR), Minrssi);
Log.notice(F("Low Power Mode: %d" CR), low_power_mode);
// we setup a task with priority one to avoid conflict with other gateways
xTaskCreatePinnedToCore(
coreTask, /* Function to implement the task */
@@ -1111,6 +1181,12 @@ void MQTTtoBT(char *topicOri, JsonObject &BTdata)
Minrssi = (unsigned int)BTdata["minrssi"];
Log.notice(F("New Minrssi: %d" CR), Minrssi);
}
#ifdef ESP32
if (BTdata.containsKey("low_power_mode"))
{
changelow_power_mode((int)BTdata["low_power_mode"]);
}
#endif
}
}
+52
View File
@@ -0,0 +1,52 @@
/*
OpenMQTTGateway - ESP8266 or Arduino program for home automation
Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
Send and receiving command by MQTT
This files enables to use M5Stick C board components (display)
Copyright: (c)Florian ROBERT
This file is part of OpenMQTTGateway.
OpenMQTTGateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenMQTTGateway is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef config_M5_h
#define config_M5_h
#ifdef ZboardM5STICKC
#include <M5StickC.h>
#endif
#ifdef ZboardM5STACK
#include <M5Stack.h>
#endif
extern void setupM5();
extern void loopM5();
/*----------------------------USER PARAMETERS-----------------------------*/
/*---------------DEFINE SCREEN BRIGHTNESS------------------*/
#ifndef SLEEP_LCD_BRIGHTNESS
#define SLEEP_LCD_BRIGHTNESS 2 // 0 to 100
#endif
#ifndef NORMAL_LCD_BRIGHTNESS
#define NORMAL_LCD_BRIGHTNESS 100 // 0 to 100
#endif
/*-------------------DEFINE LOG LEVEL----------------------*/
#define LOG_LEVEL_LCD LOG_LEVEL_WARNING // if we go down below warning the size of the text to display can make the M5 restarting
#define LOG_TO_LCD true //comment if you want to use serial monitor for the log per default instead of the M5 screen
/*-------------------DEFINE MQTT TOPIC FOR CONFIG----------------------*/
#define subjectMQTTtoM5set "/commands/MQTTtoM5/config"
#endif
+215 -173
View File
@@ -109,7 +109,9 @@ unsigned long ReceivedSignal[array_size][2] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
#ifdef ZactuatorFASTLED
#include "config_FASTLED.h"
#endif
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
#include "config_M5.h"
#endif
/*------------------------------------------------------------------------*/
//adding this to bypass the problem of the arduino builder issue 50
@@ -128,6 +130,8 @@ int failure_number_mqtt = 0; // number of failure connecting to MQTT
#include "esp_wifi.h"
WiFiClient eClient;
#include <WiFiManager.h>
#include <Preferences.h>
Preferences preferences;
#ifdef MDNS_SD
#include <ESPmDNS.h>
#endif
@@ -448,47 +452,46 @@ void connectMQTT()
#endif
#endif
// Loop until we're reconnected
while (!client.connected())
Log.warning(F("MQTT connection..." CR));
char topic[mqtt_topic_max_size];
strcpy(topic,mqtt_topic);
strcat(topic,will_Topic);
if (client.connect(gateway_name, mqtt_user, mqtt_pass, topic, will_QoS, will_Retain, will_Message))
{
Log.notice(F("MQTT connection..." CR)); //F function enable to decrease sram usage
char topic[mqtt_topic_max_size];
strcpy(topic,mqtt_topic);
strcat(topic,will_Topic);
if (client.connect(gateway_name, mqtt_user, mqtt_pass, topic, will_QoS, will_Retain, will_Message))
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
M5Display("MQTT connected", "", "");
#endif
Log.notice(F("Connected to broker" CR));
failure_number_mqtt = 0;
// Once connected, publish an announcement...
pub(will_Topic, Gateway_AnnouncementMsg, will_Retain);
// publish version
pub(version_Topic, OMG_VERSION, will_Retain);
//Subscribing to topic
char topic2[mqtt_topic_max_size];
strcpy(topic2,mqtt_topic);
strcat(topic2,subjectMQTTtoX);
if (client.subscribe(topic2))
{
Log.notice(F("Connected to broker" CR));
failure_number_mqtt = 0;
// Once connected, publish an announcement...
pub(will_Topic, Gateway_AnnouncementMsg, will_Retain);
// publish version
pub(version_Topic, OMG_VERSION, will_Retain);
//Subscribing to topic
char topic2[mqtt_topic_max_size];
strcpy(topic2,mqtt_topic);
strcat(topic2,subjectMQTTtoX);
if (client.subscribe(topic2))
{
#ifdef ZgatewayRF
client.subscribe(subjectMultiGTWRF); // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published
#endif
#ifdef ZgatewayIR
client.subscribe(subjectMultiGTWIR); // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published
#endif
Log.trace(F("Subscription OK to the subjects" CR));
}
}
else
{
failure_number_mqtt++; // we count the failure
Log.warning(F("failure_number_mqtt: %d" CR),failure_number_mqtt);
Log.warning(F("failed, rc=%d" CR),client.state());
delay(5000);
#if defined(ESP8266) || defined(ESP32)
disconnection_handling(failure_number_mqtt);
#ifdef ZgatewayRF
client.subscribe(subjectMultiGTWRF); // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published
#endif
#ifdef ZgatewayIR
client.subscribe(subjectMultiGTWIR); // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published
#endif
Log.trace(F("Subscription OK to the subjects" CR));
}
}
else
{
failure_number_mqtt++; // we count the failure
Log.warning(F("failure_number_mqtt: %d" CR), failure_number_mqtt);
Log.warning(F("failed, rc=%d" CR), client.state());
delay(5000);
#if defined(ESP8266) || defined(ESP32)
disconnection_handling(failure_number_mqtt);
#endif
}
}
// Callback function, when the gateway receive an MQTT value on the topics subscribed this function is called
@@ -529,6 +532,13 @@ void setup()
Serial.end();
Serial.begin(SERIAL_BAUD, SERIAL_8N1, SERIAL_TX_ONLY); // enable on ESP8266 to free some pin
#endif
#elif ESP32
preferences.begin(Gateway_Short_Name, false);
low_power_mode = preferences.getUInt("low_power_mode", DEFAULT_LOW_POWER_MODE);
preferences.end();
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
setupM5();
#endif
#endif
Log.trace(F("OpenMQTTGateway Wifi protocol used: %d" CR), wifiProtocol);
@@ -662,7 +672,7 @@ void setup()
#if defined(ESP8266) || defined(ESP32)
// Bypass for ESP not reconnecting automaticaly the second time https://github.com/espressif/arduino-esp32/issues/2501
void wifi_reconnect_bypass(){
bool wifi_reconnect_bypass(){
uint8_t wifi_autoreconnect_cnt = 0;
#ifdef ESP32
while (WiFi.status() != WL_CONNECTED && wifi_autoreconnect_cnt < 3) {
@@ -670,19 +680,25 @@ void wifi_reconnect_bypass(){
while (WiFi.waitForConnectResult() != WL_CONNECTED && wifi_autoreconnect_cnt < 3) {
#endif
Log.notice(F("Attempting Wifi connection with saved AP: %d" CR), wifi_autoreconnect_cnt);
WiFi.begin();
delay(500);
wifi_autoreconnect_cnt++;
WiFi.begin();
delay(500);
wifi_autoreconnect_cnt++;
}
if(wifi_autoreconnect_cnt < 3)
{
return true;
} else {
return false;
}
}
// the 2 methods below are used to recover wifi connection by changing the protocols
void forceWifiProtocol(){
#ifdef ESP32
Log.trace(F("ESP32: Forcing to wifi %d" CR), wifiProtocol);
Log.warning(F("ESP32: Forcing to wifi %d" CR), wifiProtocol);
esp_wifi_set_protocol(WIFI_IF_STA, wifiProtocol);
#elif ESP8266
Log.trace(F("ESP8266: Forcing to wifi %d" CR), wifiProtocol);
Log.warning(F("ESP8266: Forcing to wifi %d" CR), wifiProtocol);
WiFi.setPhyMode((WiFiPhyMode_t)wifiProtocol);
#endif
}
@@ -696,21 +712,13 @@ void reinit_wifi()
}
void disconnection_handling( int failure_number){
Log.trace(F("disconnection_handling, failed %d times" CR), failure_number);
Log.warning(F("disconnection_handling, failed %d times" CR), failure_number);
if (failure_number > maxConnectionRetry && !connectedOnce)
{
#if defined(ESP8266) || defined(ESP32)
#ifndef ESPWifiManualSetup
Log.error(F("Failed connecting 1st time to mqtt, reset wifi manager & erase network credentials" CR));
setup_wifimanager(true);
#else
Log.error(F("Failed connecting 1st time to mqtt, restarting ESP" CR));
#ifdef ESP32
ESP.restart();
#endif
#ifdef ESP8266
ESP.reset();
#endif
Log.error(F("Failed connecting 1st time to mqtt, reset wifi manager & erase network credentials" CR));
setup_wifimanager(true);
#endif
#endif
}
@@ -754,7 +762,6 @@ void disconnection_handling( int failure_number){
}
}
void setOTA(){
// Port defaults to 8266
ArduinoOTA.setPort(ota_port);
@@ -987,25 +994,33 @@ void setup_wifimanager(bool reset_settings)
//set minimum quality of signal so it ignores AP's under that quality
wifiManager.setMinimumSignalQuality(MinimumWifiSignalQuality);
wifi_reconnect_bypass();
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect(WifiManager_ssid, WifiManager_password))
if(!wifi_reconnect_bypass())// if we didn't connect with saved credential we start Wifimanager web portal
{
Log.warning(F("failed to connect and hit timeout" CR));
delay(3000);
//reset and try again
#if defined(ESP8266)
ESP.reset();
#else
ESP.restart();
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
M5Display("Connect your phone to WIFI AP:", WifiManager_ssid, WifiManager_password);
#endif
delay(5000);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect(WifiManager_ssid, WifiManager_password))
{
Log.warning(F("failed to connect and hit timeout" CR));
delay(3000);
//reset and try again
#if defined(ESP8266)
ESP.reset();
#else
ESP.restart();
#endif
delay(5000);
}
}
//if you get here you have connected to the WiFi
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
M5Display("Wifi connected", "", "");
#endif
//if you get here you are connected to the WiFi
Log.notice(F("Wifi connected" CR));
//read updated parameters
@@ -1208,7 +1223,11 @@ void loop()
Log.trace(F("RFM69toMQTT OK" CR));
#endif
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
stateMeasures();
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)))
{
timer_sys_measures = millis();
stateMeasures();
}
#endif
#ifdef ZactuatorFASTLED
FASTLEDLoop();
@@ -1219,7 +1238,7 @@ void loop()
connectMQTT();
}
}
else
else
{ // disconnected from network
#if defined(ESP8266) || defined(ESP32)
Log.warning(F("wifi disconnected" CR));
@@ -1230,113 +1249,133 @@ void loop()
Log.warning(F("eth disconnected" CR));
#endif
}
// Function that doesn't need an active connection
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
loopM5();
#endif
}
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
void stateMeasures()
{
unsigned long now = millis();
if (now > (timer_sys_measures + TimeBetweenReadingSYS))
{
timer_sys_measures = millis();
StaticJsonBuffer<JSON_MSG_BUFFER> jsonBuffer;
JsonObject &SYSdata = jsonBuffer.createObject();
unsigned long uptime = millis() / 1000;
SYSdata["uptime"] = uptime;
SYSdata["version"] = OMG_VERSION;
Log.trace(F("retriving value of system characteristics Uptime (s):%u" CR),uptime);
#if defined(ESP8266) || defined(ESP32)
uint32_t freeMem;
freeMem = ESP.getFreeHeap();
SYSdata["freeMem"] = freeMem;
long rssi = WiFi.RSSI();
SYSdata["rssi"] = rssi;
String SSID = WiFi.SSID();
SYSdata["SSID"] = SSID;
SYSdata["ip"] = ip2CharArray(WiFi.localIP());
String mac = WiFi.macAddress();
SYSdata["mac"] = (char *)mac.c_str();
SYSdata["wifiPrt"] = (int)wifiProtocol;
#else
SYSdata["ip"] = ip2CharArray(Ethernet.localIP());
StaticJsonBuffer<JSON_MSG_BUFFER> jsonBuffer;
JsonObject &SYSdata = jsonBuffer.createObject();
unsigned long uptime = millis() / 1000;
SYSdata["uptime"] = uptime;
SYSdata["version"] = OMG_VERSION;
Log.trace(F("retriving value of system characteristics Uptime (s):%u" CR),uptime);
#if defined(ESP8266) || defined(ESP32)
uint32_t freeMem;
freeMem = ESP.getFreeHeap();
SYSdata["freeMem"] = freeMem;
long rssi = WiFi.RSSI();
SYSdata["rssi"] = rssi;
String SSID = WiFi.SSID();
SYSdata["SSID"] = SSID;
SYSdata["ip"] = ip2CharArray(WiFi.localIP());
String mac = WiFi.macAddress();
SYSdata["mac"] = (char *)mac.c_str();
SYSdata["wifiPrt"] = (int)wifiProtocol;
#else
SYSdata["ip"] = ip2CharArray(Ethernet.localIP());
#endif
String modules = "";
#ifdef ZgatewayRF
modules = modules + ZgatewayRF;
#endif
#ifdef ZsensorBME280
modules = modules + ZsensorBME280;
#endif
#ifdef ZsensorHCSR04
modules = modules + ZsensorHCSR04;
#endif
#ifdef ZsensorBH1750
modules = modules + ZsensorBH1750;
#endif
#ifdef ZsensorTSL2561
modules = modules + ZsensorTSL2561;
#endif
#ifdef ZsensorDHT
modules = modules + ZsensorDHT;
#endif
#ifdef ZsensorDS1820
modules = modules + ZsensorDS1820;
#endif
#ifdef ZactuatorONOFF
modules = modules + ZactuatorONOFF;
#endif
#ifdef Zgateway2G
modules = modules + Zgateway2G;
#endif
#ifdef ZgatewayIR
modules = modules + ZgatewayIR;
#endif
#ifdef ZgatewayLORA
modules = modules + ZgatewayLORA;
#endif
#ifdef ZgatewayRF2
modules = modules + ZgatewayRF2;
#endif
#ifdef ZgatewayWeatherStation
modules = modules + ZgatewayWeatherStation;
#endif
#ifdef ZgatewayPilight
modules = modules + ZgatewayPilight;
#endif
#ifdef ZgatewaySRFB
modules = modules + ZgatewaySRFB;
#endif
#ifdef ZgatewayBT
modules = modules + ZgatewayBT;
#ifdef ESP32
SYSdata["low_power_mode"] = (int)low_power_mode;
#endif
String modules = "";
#ifdef ZgatewayRF
modules = modules + ZgatewayRF;
#endif
#ifdef ZsensorBME280
modules = modules + ZsensorBME280;
#endif
#ifdef ZsensorHCSR04
modules = modules + ZsensorHCSR04;
#endif
#ifdef ZsensorBH1750
modules = modules + ZsensorBH1750;
#endif
#ifdef ZsensorTSL2561
modules = modules + ZsensorTSL2561;
#endif
#ifdef ZsensorDHT
modules = modules + ZsensorDHT;
#endif
#ifdef ZsensorDS1820
modules = modules + ZsensorDS1820;
#endif
#ifdef ZactuatorONOFF
modules = modules + ZactuatorONOFF;
#endif
#ifdef Zgateway2G
modules = modules + Zgateway2G;
#endif
#ifdef ZgatewayIR
modules = modules + ZgatewayIR;
#endif
#ifdef ZgatewayLORA
modules = modules + ZgatewayLORA;
#endif
#ifdef ZgatewayRF2
modules = modules + ZgatewayRF2;
#endif
#ifdef ZgatewayWeatherStation
modules = modules + ZgatewayWeatherStation;
#endif
#ifdef ZgatewayPilight
modules = modules + ZgatewayPilight;
#endif
#ifdef ZgatewaySRFB
modules = modules + ZgatewaySRFB;
#endif
#ifdef ZgatewayBT
modules = modules + ZgatewayBT;
#endif
#ifdef ZgatewayRFM69
modules = modules + ZgatewayRFM69;
#endif
#ifdef ZsensorINA226
modules = modules + ZsensorINA226;
#endif
#ifdef ZsensorHCSR501
modules = modules + ZsensorHCSR501;
#endif
#ifdef ZsensorGPIOInput
modules = modules + ZsensorGPIOInput;
#endif
#ifdef ZsensorGPIOKeyCode
modules = modules + ZsensorGPIOKeyCode;
#endif
#ifdef ZsensorGPIOKeyCode
modules = modules + ZsensorGPIOKeyCode;
#endif
#ifdef ZmqttDiscovery
modules = modules + ZmqttDiscovery;
#endif
#ifdef ZactuatorFASTLED
modules = modules + ZactuatorFASTLED;
#endif
SYSdata["modules"] = modules;
pub(subjectSYStoMQTT, SYSdata);
}
#endif
#ifdef ZgatewayRFM69
modules = modules + ZgatewayRFM69;
#endif
#ifdef ZsensorINA226
modules = modules + ZsensorINA226;
#endif
#ifdef ZsensorHCSR501
modules = modules + ZsensorHCSR501;
#endif
#ifdef ZsensorGPIOInput
modules = modules + ZsensorGPIOInput;
#endif
#ifdef ZsensorGPIOKeyCode
modules = modules + ZsensorGPIOKeyCode;
#endif
#ifdef ZsensorGPIOKeyCode
modules = modules + ZsensorGPIOKeyCode;
#endif
#ifdef ZmqttDiscovery
modules = modules + ZmqttDiscovery;
#endif
#ifdef ZactuatorFASTLED
modules = modules + ZactuatorFASTLED;
#endif
#ifdef ZboardM5STACK
M5.Power.begin();
SYSdata["m5-batt-level"] = (int8_t)M5.Power.getBatteryLevel();
SYSdata["m5-is-charging"] = (bool)M5.Power.isCharging();
SYSdata["m5-is-chargefull"] = (bool)M5.Power.isChargeFull();
#endif
#ifdef ZboardM5STICKC
M5.Axp.EnableCoulombcounter();
SYSdata["m5-bat-voltage"] = (float)M5.Axp.GetBatVoltage();
SYSdata["m5-bat-current"] = (float)M5.Axp.GetBatCurrent();
SYSdata["m5-vin-voltage"] = (float)M5.Axp.GetVinVoltage();
SYSdata["m5-vin-current"] = (float)M5.Axp.GetVinCurrent();
SYSdata["m5-vbus-voltage"] = (float)M5.Axp.GetVBusVoltage();
SYSdata["m5-vbus-current"] = (float)M5.Axp.GetVBusCurrent();
SYSdata["m5-temp-axp"] = (float)M5.Axp.GetTempInAXP192();
SYSdata["m5-bat-power"] = (float)M5.Axp.GetBatPower();
SYSdata["m5-bat-chargecurrent"] = (float)M5.Axp.GetBatChargeCurrent();
SYSdata["m5-aps-voltage"] = (float)M5.Axp.GetAPSVoltage();
#endif
SYSdata["modules"] = modules;
pub(subjectSYStoMQTT, SYSdata);
}
#endif
@@ -1451,6 +1490,9 @@ void receivingMQTT(char *topicOri, char *datacallback)
#ifdef ZactuatorFASTLED
MQTTtoFASTLED(topicOri, jsondata);
#endif
#if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
MQTTtoM5(topicOri, jsondata);
#endif
#endif
#ifdef ZactuatorONOFF // outside the jsonpublishing macro due to the fact that we need to use simplepublishing with HA discovery
MQTTtoONOFF(topicOri, jsondata);