STA only mode

Fixed MQTT topic prefix
This commit is contained in:
Ray Jones 2020-04-08 07:51:52 +10:00
parent 3e3ef7d2f2
commit 4eddcd0f1e
28 changed files with 557 additions and 257 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 303 KiB

View File

@ -19,7 +19,8 @@ upload_speed = 921600
;upload_port = 192.168.20.120
;upload_flags =
; --port=3232
upload_port = COM5
upload_port = COM14
;upload_port = COM5
upload_protocol = esptool
;monitor_speed = 115200
extra_scripts = post:add_CRC.py

View File

@ -118,6 +118,7 @@
#include "Utility/MQTTsetup.h"
#include <FreeRTOS.h>
#include "RTC/TimerManager.h"
#include "Utility/GetLine.h"
// SSID & password now stored in NV storage - these are still the default values.
//#define AP_SSID "Afterburner"
@ -197,7 +198,6 @@ CMQTTsetup MQTTmenu;
sRxLine PCline;
long lastRxTime; // used to observe inter character delays
bool bHasOEMController = false;
bool bHasOEMLCDController = false;
@ -439,11 +439,9 @@ void setup() {
#if USE_WIFI == 1
sCredentials creds = NVstore.getCredentials(); // local AP credentials
// if(NVstore.getUserSettings().enableWifi) {
if(NVstore.getUserSettings().wifiMode) {
initWifi(creds.SSID, creds.APpassword); // SSID and passowrd the the ESP32's inbuilt AP
initWifi();
#if USE_OTA == 1
if(NVstore.getUserSettings().enableOTA) {
initOTA();
@ -523,6 +521,8 @@ void setup() {
pHourMeter->init(bESP32PowerUpInit || RTC_Store.getBootInit()); // ensure persistent memory variable are reset after powerup, or OTA update
RTC_Store.setBootInit(false);
reqDemand(RTC_Store.getDesiredTemp()); // bug fix: was not applying saved set point!
// Check for solo DS18B20
// store it's serial number as the primary sensor
// This allows seamless standard operation, and marks the iniital sensor
@ -1366,6 +1366,7 @@ void checkDebugCommands()
static uint8_t nGetConf = 0;
static String pw1;
static String pw2;
static CGetLine line;
// check for test commands received over Debug serial port or telnet
char rxVal;
@ -1390,6 +1391,7 @@ void checkDebugCommands()
if(nGetConf) {
DebugPort.print(rxVal);
bool bSave = (rxVal == 'y') || (rxVal == 'Y');
DebugPort.println("");
if(!bSave) {
DebugPort.println(" ABORTED!");
nGetConf = 0;
@ -1397,7 +1399,7 @@ void checkDebugCommands()
}
switch(nGetConf) {
case 1:
setSSID(PCline.Line);
setSSID(line.getString());
break;
case 2:
setAPpassword(pw2.c_str());
@ -1408,75 +1410,77 @@ void checkDebugCommands()
}
else if(nGetString) {
DebugPort.enable(true);
if(rxVal < ' ') {
if(rxVal == 0x1b) { // ESCAPE
nGetString = 0;
DebugPort.println("\r\nABORTED!");
return;
}
if(rxVal == '\n' || rxVal == '\r') {
switch(nGetString) {
case 1:
if(PCline.Len <= 31) {
nGetConf = 1;
DebugPort.printf("\r\nSet AP SSID to %s? (y/n) - ", PCline.Line);
}
else {
DebugPort.println("\r\nNew name is longer than 31 characters - ABORTING");
}
nGetString = 0;
return;
case 2:
pw1 = PCline.Line;
PCline.clear();
pw2 = NVstore.getCredentials().APpassword;
if(pw1 != pw2) {
DebugPort.println("\r\nPassword does not match existing - ABORTING");
nGetString = 0;
}
else {
nGetString = 3;
DebugPort.print("\r\nPlease enter new password - ");
DebugPort.enable(false); // block other debug msgs whilst we get the password
}
return;
case 3:
pw1 = PCline.Line;
if(PCline.Len <= 31) {
nGetString = 4;
DebugPort.print("\r\nPlease confirm new password - ");
DebugPort.enable(false); // block other debug msgs whilst we get the password
}
else {
DebugPort.println("\r\nNew password is longer than 31 characters - ABORTING");
nGetString = 0;
}
PCline.clear();
return;
case 4:
pw2 = PCline.Line;
PCline.clear();
if(pw1 != pw2) {
DebugPort.println("\r\nNew passwords do not match - ABORTING");
}
else {
nGetConf = 2;
DebugPort.print("\r\nSet new password (y/n) - ");
}
nGetString = 0;
return;
}
}
}
else {
if(nGetString == 1)
DebugPort.print(rxVal);
else
DebugPort.print('*');
PCline.append(rxVal);
DebugPort.enable(false); // block other debug msgs whilst we get strings
if(rxVal == 0x1b) { // ESCAPE
nGetString = 0;
DebugPort.println("\r\nABORTED!");
return;
}
if(line.handle(rxVal)) {
switch(nGetString) {
case 1:
if(line.getLen() <= 31) {
nGetConf = 1;
DebugPort.printf("\r\nSet AP SSID to %s? (y/n) - ", line.getString());
}
else {
DebugPort.println("\r\nNew name is longer than 31 characters - ABORTING");
}
nGetString = 0;
return;
case 2:
pw1 = line.getString();
pw2 = NVstore.getCredentials().APpassword;
if(pw1 != pw2) {
DebugPort.println("\r\nPassword does not match existing - ABORTING");
nGetString = 0;
}
else {
nGetString = 3;
DebugPort.print("\r\nPlease enter new password - ");
DebugPort.enable(false); // block other debug msgs whilst we get the password
}
line.reset();
line.maskEntry();
return;
case 3:
pw1 = line.getString();
if(line.getLen() < 8) {
// ABORT - too short
DebugPort.println("\r\nNew password must be at least 8 characters - ABORTING");
nGetString = 0;
}
else if(line.getLen() > 31) {
// ABORT - too long!
DebugPort.println("\r\nNew password is longer than 31 characters - ABORTING");
nGetString = 0;
}
else {
nGetString = 4;
DebugPort.print("\r\nPlease confirm new password - ");
DebugPort.enable(false); // block other debug msgs whilst we get the password
}
line.reset();
line.maskEntry();
return;
case 4:
pw2 = line.getString();
line.reset();
if(pw1 != pw2) {
DebugPort.println("\r\nNew passwords do not match - ABORTING");
}
else {
nGetConf = 2;
DebugPort.print("\r\nSet new password (y/n) - ");
}
nGetString = 0;
return;
}
}
DebugPort.enable(false);
return;
}
rxVal = toLowerCase(rxVal);
@ -1486,10 +1490,10 @@ void checkDebugCommands()
#endif
if(rxVal == '\n') { // "End of Line"
#ifdef PROTOCOL_INVESTIGATION
String convert(PCline.Line);
String convert(line.getString());
val = convert.toInt();
bSendVal = true;
PCline.clear();
line.reset();
#endif
}
else {
@ -1498,7 +1502,7 @@ void checkDebugCommands()
}
#ifdef PROTOCOL_INVESTIGATION
else if(isDigit(rxVal)) {
PCline.append(rxVal);
line.handle(rxVal);
}
else if(rxVal == 'p') {
DebugPort.println("Test Priming Byte... ");
@ -1549,9 +1553,9 @@ void checkDebugCommands()
}
else if(rxVal == 'n') {
DebugPort.print("Please enter new SSID name for Access Point - ");
line.reset();
nGetString = 1;
DebugPort.enable(false); // block other debug msgs whilst we get strings
PCline.clear();
}
else if(rxVal == 'm') {
MQTTmenu.setActive();
@ -1562,9 +1566,10 @@ void checkDebugCommands()
}
else if(rxVal == 'p') {
DebugPort.print("Please enter current AP password - ");
line.reset();
line.maskEntry();
nGetString = 2;
DebugPort.enable(false); // block other debug msgs whilst we get strings
PCline.clear();
}
else if(rxVal == 's') {
CommState.toggleReporting();
@ -1835,11 +1840,10 @@ void doStreaming()
{
#if USE_WIFI == 1
// if(NVstore.getUserSettings().enableWifi) {
if(NVstore.getUserSettings().wifiMode) {
doWiFiManager();
#if USE_OTA == 1
DoOTA();
doOTA();
#endif // USE_OTA
#if USE_WEBSERVER == 1
bHaveWebClient = doWebServer();
@ -1970,8 +1974,8 @@ void resetFuelGauge()
void setSSID(const char* name)
{
sCredentials creds = NVstore.getCredentials();
strncpy(creds.SSID, name, 31);
creds.SSID[31] = 0;
strncpy(creds.APSSID, name, 31);
creds.APSSID[31] = 0;
NVstore.setCredentials(creds);
NVstore.save();
NVstore.doSave(); // ensure NV storage
@ -2006,7 +2010,7 @@ void showMainmenu()
DebugPort.printf(" <W> - toggle reporting of blue wire timeout/recycling event, currently %s\r\n", bReportRecyleEvents ? "ON" : "OFF");
DebugPort.printf(" <O> - toggle reporting of OEM resync event, currently %s\r\n", bReportOEMresync ? "ON" : "OFF");
DebugPort.printf(" <S> - toggle reporting of state machine transits %s\r\n", CommState.isReporting() ? "ON" : "OFF");
DebugPort.printf(" <N> - change AP SSID, currently \"%s\"\r\n", NVstore.getCredentials().SSID);
DebugPort.printf(" <N> - change AP SSID, currently \"%s\"\r\n", NVstore.getCredentials().APSSID);
DebugPort.println(" <P> - change AP password");
DebugPort.println(" <M> - configure MQTT");
DebugPort.println(" <+> - request heater turns ON");

View File

@ -58,7 +58,7 @@ CHumidityScreen::show()
else {
sprintf(msg, "> %d%%", _humidityThresh);
}
_printMenuText(62, 22, msg, _rowSel == 2);
_printMenuText(62, 22, msg, _rowSel == 1);
return true;

View File

@ -52,6 +52,8 @@ CMQTTScreen::onSelect()
{
CScreen::onSelect();
_initUI();
_IPScrollPos = 0;
_UsernameScrollPos = 0;
}
@ -66,31 +68,28 @@ CMQTTScreen::show()
int yPos = 18;
if(NVstore.getMQTTinfo().enabled) {
if(isWifiConnected()) {
if(isWifiSTAConnected()) {
if(isMQTTconnected())
_printMenuText(border, yPos, "CONNECTED");
_printMenuText(0, yPos, "CONNECTED");
else
_printInverted(border, yPos, " DISCONNECTED ", true);
_printInverted(0, yPos, " DISCONNECTED ", true);
}
else {
_printInverted(border, yPos, " NO STA NETWORK ", true);
_printInverted(0, yPos, " STA NOT ACTIVE ", true);
}
}
else {
_printMenuText(border, yPos, "DISABLED");
_printMenuText(0, yPos, "DISABLED");
}
char msg[40];
sprintf(msg, "QoS:%d", NVstore.getMQTTinfo().qos);
_printMenuText(_display.width(), yPos, msg, false, eRightJustify);
yPos += _display.textHeight() + 2;
sprintf(msg, "%s:%d", NVstore.getMQTTinfo().host, NVstore.getMQTTinfo().port);
_printMenuText(border, yPos, msg);
yPos += _display.textHeight() + 2;
sprintf(msg, "%s/%s", NVstore.getMQTTinfo().username, NVstore.getMQTTinfo().password);
_printMenuText(border, yPos, msg);
yPos += _display.textHeight() + 2;
sprintf(msg, "%s", NVstore.getMQTTinfo().topicPrefix);
_printMenuText(border, yPos, msg);
_printMenuText(0, yPos, getTopicPrefix());
return true;
}
@ -98,7 +97,46 @@ CMQTTScreen::show()
bool
CMQTTScreen::animate()
{
return false;
static bool subrate = false;
subrate = !subrate;
String scrollable;
int yPos = 18;
scrollable = " ";
scrollable += NVstore.getMQTTinfo().host;
scrollable += ":";
scrollable += NVstore.getMQTTinfo().port;
scrollable += " ";
if(scrollable.length() < 28) {
scrollable.trim(); // will fit OK, remove added padding that makes scrolled string more readable
}
if(subrate) {
_IPScrollPos++;
if(_IPScrollPos > ( (int)scrollable.length() - 21) )
_IPScrollPos = 0;
}
yPos += _display.textHeight() + 2;
_printMenuText(0, yPos, scrollable.substring(_IPScrollPos, _IPScrollPos+21).c_str());
scrollable = " ";
scrollable += NVstore.getMQTTinfo().username;
scrollable += "/";
scrollable += NVstore.getMQTTinfo().password;
scrollable += " ";
if(scrollable.length() < 28) {
scrollable.trim(); // will fit OK, remove added padding that makes scrolled string more readable
}
if(subrate) {
_UsernameScrollPos++;
if(_UsernameScrollPos > ( (int)scrollable.length() - 21) )
_UsernameScrollPos = 0;
}
yPos += _display.textHeight() + 2;
_printMenuText(0, yPos, scrollable.substring(_UsernameScrollPos, _UsernameScrollPos+21).c_str());
return true;
}
bool

View File

@ -37,6 +37,8 @@ public:
bool keyHandler(uint8_t event);
private:
int _repeatCount;
int _IPScrollPos;
int _UsernameScrollPos;
};
#endif

View File

@ -129,16 +129,16 @@ CScreen::_printInverted(int x, int y, const char* str, bool selected, eJUSTIFY j
}
void
CScreen::_scrollMessage(int y, const char* str, int& charOffset)
CScreen::_scrollMessage(int y, const char* str, int& charOffset, bool centred)
{
char msg[20];
int maxIndex = strlen(str) - 20;
strncpy(msg, &str[charOffset], 19);
msg[19] = 0;
_printMenuText(_display.xCentre(), y, msg, false, eCentreJustify);
char msg[22];
int maxIndex = strlen(str) - 21;
strncpy(msg, &str[charOffset], 21);
msg[21] = 0;
_printMenuText(centred ? _display.xCentre() : 0, y, msg, false, centred ? eCentreJustify : eLeftJustify);
charOffset++;
if(charOffset >= maxIndex) {
if(charOffset > maxIndex) {
charOffset = 0;
}
}

View File

@ -54,7 +54,7 @@ protected:
void _adjustExtents(CRect& rect, eJUSTIFY justify, const char* str);
void _drawMenuSelection(CRect extents, const char* str, int border = 3, int radius = 4);
void _drawMenuSelection(const CRect& extents, int border, int radius);
void _scrollMessage(int y, const char* str, int& charOffset);
void _scrollMessage(int y, const char* str, int& charOffset, bool centred=true);
void _reqOEMWarning();
void _drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t color = WHITE, uint16_t bg = 0xffff);
void _showTitle(const char* title);

View File

@ -278,7 +278,7 @@ CScreenHeader::showBTicon()
void
CScreenHeader::showWifiIcon()
{
if(isWifiConnected() || isWifiAP()) { // STA or AP mode active
if(isWifiSTAConnected() || isWifiAPonly()) { // STA or AP mode active
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiWideIconInfo, WHITE, BLACK); // wide icon erases annotations!
int8_t RSSI = getWifiRSSI();
if(RSSI < -70) {
@ -356,7 +356,7 @@ CScreenHeader::showWifiIcon()
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
_display.print("CFG");
}
else if(isWifiAP()) {
else if(isWifiAPonly()) {
// if AP only, show AP
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);

View File

@ -53,7 +53,7 @@ CWebPageUpdateScreen::show()
int col = _display.xCentre();
if(_rowSel == 0) {
if(isWifiSTA()) {
if(isWifiSTAConnected()) {
_printMenuText(col, 16, "Press Up to update", false, eCentreJustify);
_printMenuText(col, 26, "web page content ", false, eCentreJustify);
_printMenuText(col, 36, "stored in SPIFFS. ", false, eCentreJustify);
@ -115,7 +115,7 @@ CWebPageUpdateScreen::keyHandler(uint8_t event)
// UP press
if(event & key_Up) {
if(_rowSel == 0) {
if(isWifiSTA())
if(isWifiSTAConnected())
_rowSel = 1;
}
else {

View File

@ -53,7 +53,7 @@ CWiFiSTAScreen::show()
if(NVstore.getUserSettings().wifiMode == 0 || !isWifiSTA()) {
if(NVstore.getUserSettings().wifiMode == 0)
_printMenuText(border, yPos, "DISABLED");
_printMenuText(border, yPos, "WiFi DISABLED");
else
_printMenuText(border, yPos, "NOT CONNECTED");
}
@ -76,7 +76,7 @@ CWiFiSTAScreen::show()
sprintf(RSSIstr, "%ddBm", RSSI);
_printMenuText(31, yPos, RSSIstr);
int xPos = 90;
/* int xPos = 70;
_drawBitmap(xPos, yPos, WifiIconInfo, WHITE, BLACK); // wide icon erases annotations!
if(RSSI < -70) {
_display.fillRect(xPos, yPos, WifiIconInfo.width, 6, BLACK);
@ -85,7 +85,17 @@ CWiFiSTAScreen::show()
_display.fillRect(xPos, yPos, WifiWideIconInfo.width, 3, BLACK);
_display.fillRect(xPos, yPos, 1, 4, BLACK);
_display.fillRect(xPos+WifiIconInfo.width-1, yPos, 1, 4, BLACK);
}*/
const char* modeStr = "";
switch(WiFi.getMode()) {
case WIFI_MODE_STA: modeStr = "STA only"; break;
case WIFI_MODE_AP: modeStr = "AP only"; break;
case WIFI_MODE_APSTA: modeStr = "STA+AP"; break;
default: break;
}
_printMenuText(128, yPos, modeStr, false, eRightJustify);
}
_printMenuText(_display.xCentre(), 53, "\021 \020", true, eCentreJustify);

View File

@ -61,8 +61,8 @@ CWiFiScreen::_initUI()
_OTAsel = NVstore.getUserSettings().enableOTA;
_bShowMAC = false;
if(NVstore.getUserSettings().wifiMode) {
if(isWifiAP()) {
if(NVstore.getUserSettings().wifiMode) { // non zero => enabled wifi, maybe AP only or STA+AP or STA only
if(isWifiAPonly()) {
if(isWifiConfigPortal()) {
_colSel = 1; // " WiFi: CFG AP only "
}
@ -71,11 +71,21 @@ CWiFiScreen::_initUI()
}
}
else {
if(isWifiConfigPortal()) {
_colSel = 3; // " WiFi: CFG STA+AP "
if(NVstore.getUserSettings().wifiMode & 0x02) { // 0x02 set => STA only preferred
if(isWifiConfigPortal()) {
_colSel = 5; // " WiFi: CFG STA only "
}
else {
_colSel = 6; // " WiFi: STA only ";
}
}
else {
_colSel = 4; // " WiFi: STA+AP ";
if(isWifiConfigPortal()) {
_colSel = 3; // " WiFi: CFG STA+AP "
}
else {
_colSel = 4; // " WiFi: STA+AP ";
}
}
}
}
@ -109,6 +119,12 @@ CWiFiScreen::show()
case 4:
pTitle = "STA+AP";
break;
case 5:
pTitle = "CFG STA only";
break;
case 6:
pTitle = "STA only";
break;
}
_printMenuText(border, yPos, pTitle, _rowSel==1); // selection box
@ -184,13 +200,13 @@ CWiFiScreen::keyHandler(uint8_t event)
_ScreenManager.prevMenu();
break;
case 1:
if(isWifiAP()) {
if(isWifiAPonly()) {
_colSel--;
WRAPLOWERLIMIT(_colSel, 0, 2);
}
else {
_colSel--;
WRAPLOWERLIMIT(_colSel, 0, 4);
WRAPLOWERLIMIT(_colSel, 0, 6);
}
break;
case 2:
@ -206,13 +222,13 @@ CWiFiScreen::keyHandler(uint8_t event)
_ScreenManager.nextMenu();
break;
case 1:
if(isWifiAP()) {
if(isWifiAPonly()) {
_colSel++;
WRAPUPPERLIMIT(_colSel, 2, 0);
}
else {
_colSel++;
WRAPUPPERLIMIT(_colSel, 4, 0);
WRAPUPPERLIMIT(_colSel, 6, 0);
}
break;
case 2:
@ -266,6 +282,12 @@ CWiFiScreen::keyHandler(uint8_t event)
case 4:
wifiEnterConfigPortal(false, false, 5000); // STA+AP: keep credentials, reboot into webserver
break;
case 5:
wifiEnterConfigPortal(true, false, 5000, true); // CFG STA only: keep credentials, reboot into portal
break;
case 6:
wifiEnterConfigPortal(false, false, 5000, true); // STA only: keep credentials, reboot into webserver
break;
}
_rowSel = 3; // stop ticker display
}

View File

@ -336,7 +336,7 @@ bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("MUser", info.username, root);
bSend |= moderator.addJson("MPasswd", info.password, root);
bSend |= moderator.addJson("MQoS", info.qos, root);
bSend |= moderator.addJson("MTopic", info.topicPrefix, root);
bSend |= moderator.addJson("MTopic", getTopicPrefix(), root);
if(bSend) {
root.printTo(opStr, len);
@ -393,7 +393,7 @@ bool makeJSONStringIP(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("IP_APMAC", getWifiAPMACStr(), root);
bSend |= moderator.addJson("IP_STA", getWifiSTAAddrStr(), root);
bSend |= moderator.addJson("IP_STAMAC", getWifiSTAMACStr(), root);
bSend |= moderator.addJson("IP_STASSID", getSSID().c_str(), root);
bSend |= moderator.addJson("IP_STASSID", getSTASSID().c_str(), root);
bSend |= moderator.addJson("IP_STAGATEWAY", getWifiGatewayAddrStr(), root);
bSend |= moderator.addJson("IP_STARSSI", getWifiRSSI(), root, 10000);
bSend |= moderator.addJson("IP_OTA", NVstore.getUserSettings().enableOTA, root);

149
src/Utility/GetLine.cpp Normal file
View File

@ -0,0 +1,149 @@
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2020 Ray Jones <ray@mrjones.id.au>
*
* This program 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.
*
* This program 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 <https://www.gnu.org/licenses/>.
*
*/
#include "GetLine.h"
#include "DebugPort.h"
#include <string.h>
CGetLine::CGetLine()
{
reset();
}
void
CGetLine::reset()
{
_idx = 0;
_getMode = 0;
_pTarget = NULL;
_Numeric = 0;
_maxlen = sizeof(_buffer);
_showStars = false;
}
void
CGetLine::reset(char* result, int maxlen)
{
reset();
_getMode = 1;
_pTarget = result;
_maxlen = maxlen > sizeof(_buffer) ? sizeof(_buffer) : maxlen;
}
void
CGetLine::reset(int numeric)
{
reset();
_getMode = 2;
_Numeric = numeric;
}
bool
CGetLine::handle(char rxVal)
{
if(_getMode == 2) {
return _doNum(rxVal);
}
if(rxVal < ' ') {
if(_idx == 0) {
if(_pTarget)
strcpy(_buffer, _pTarget);
}
if(rxVal == ('x' & 0x1f)) { // CTRL-X - erase string, return done
memset(_buffer, 0, sizeof(_buffer));
_zeroTarget();
return true;
}
if(rxVal == '\r') // ignore CR
return false;
if(rxVal == '\n') { // accept buffered string upon LF, return done
_copyTarget();
return true;
}
if(rxVal == 0x1b) { // abort, no change upon ESC, return done
return true;
}
}
else {
if(_idx == 0) memset(_buffer, 0, sizeof(_buffer));
if(_showStars)
DebugPort.print('*');
else
DebugPort.print(rxVal);
_buffer[_idx++] = rxVal;
if(_idx == _maxlen) {
_copyTarget();
return true;
}
}
return false;
}
bool
CGetLine::_doNum(char rxVal)
{
if(rxVal < ' ') {
if(_idx == 0) sprintf(_buffer, "%d", _Numeric);
if(rxVal == '\n') {
int val = atoi(_buffer);
_Numeric = val;
return true;
}
if(rxVal == 0x1b) {
return true;
}
return false;
}
DebugPort.print(rxVal);
if(isdigit(rxVal)) {
if(_idx == 0) memset(_buffer, 0, sizeof(_buffer));
_buffer[_idx++] = rxVal;
if(_idx == 5) {
int val = atoi(_buffer);
_Numeric = val;
return true;
}
}
else {
return true;
}
return false;
}
void
CGetLine::_copyTarget()
{
if(_pTarget) {
strncpy(_pTarget, _buffer, _maxlen);
_pTarget[_maxlen] = 0;
}
}
void
CGetLine::_zeroTarget()
{
if(_pTarget)
memset(_pTarget, 0, _maxlen+1);
}

48
src/Utility/GetLine.h Normal file
View File

@ -0,0 +1,48 @@
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2020 Ray Jones <ray@mrjones.id.au>
*
* This program 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.
*
* This program 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 <https://www.gnu.org/licenses/>.
*
*/
#ifndef __GETSTRINGLINE_H__
#define __GETSTRINGLINE_H__
class CGetLine {
char _buffer[128];
int _idx;
int _getMode; // 0: default string 1: targetted string, 2: numeric
int _maxlen;
char* _pTarget;
int _Numeric;
bool _showStars;
bool _doNum(char rxVal);
void _copyTarget();
void _zeroTarget();
public:
CGetLine();
void reset();
void reset(char* result, int maxlen);
void reset(int numeric);
bool handle(char rxVal);
int getNumeric() { return _Numeric; }
const char* getString() { return _buffer; }
int getLen() { return _idx; }
void maskEntry() { _showStars = true; };
};
#endif

View File

@ -22,6 +22,7 @@
#include "NVStorage.h"
#include "DebugPort.h"
#include "MQTTsetup.h"
#include "../WiFi/ABMQTT.h"
CMQTTsetup::CMQTTsetup()
{
@ -50,7 +51,11 @@ CMQTTsetup::showMQTTmenu(bool init)
DebugPort.printf(" <2> - set port, currently %d\r\n", _MQTTsetup.port);
DebugPort.printf(" <3> - set username, currently \"%s\"\r\n", _MQTTsetup.username);
DebugPort.printf(" <4> - set password, currently \"%s\"\r\n", _MQTTsetup.password);
#ifdef ALLOW_USER_TOPIC
DebugPort.printf(" <5> - set root topic, currently \"%s\"\r\n", _MQTTsetup.topicPrefix);
#else
DebugPort.printf(" Fixed unique topic prefix: \"%s\"\r\n", getTopicPrefix());
#endif
DebugPort.printf(" <6> - set QoS, currently %d\r\n", _MQTTsetup.qos);
DebugPort.printf(" <7> - set enabled, currently %s\r\n", _MQTTsetup.enabled ? "ON" : "OFF");
DebugPort.printf(" <ENTER> - save and exit\r\n");
@ -91,16 +96,39 @@ CMQTTsetup::HandleMQTTsetup(char rxVal)
}
if(rxVal >= '1' && rxVal <= '7') {
_mode = rxVal - '0';
_idx = 0;
DebugPort.print("\014");
switch(_mode) {
case 1: DebugPort.printf("Enter MQTT broker's IP address (%s)", _MQTTsetup.host); break;
case 2: DebugPort.printf("Enter MQTT broker's port (%d)", _MQTTsetup.port); break;
case 3: DebugPort.printf("Enter MQTT broker's username (currently '%s', CTRL-X to erase)", _MQTTsetup.username); break;
case 4: DebugPort.printf("Enter MQTT broker's password (currently '%s', CTRL-X to erase)", _MQTTsetup.password); break;
case 5: DebugPort.printf("Enter root topic name (%s)", _MQTTsetup.topicPrefix); break;
case 6: DebugPort.printf("Enter QoS level (%d)", _MQTTsetup.qos); break;
case 7: DebugPort.printf("Enable MQTT? (Y)es / (N)o (%s)", _MQTTsetup.enabled ? "YES" : "NO"); break;
case 1:
DebugPort.printf("Enter MQTT broker's IP address (%s)", _MQTTsetup.host);
_lineInput.reset(_MQTTsetup.host, 31);
break;
case 2:
DebugPort.printf("Enter MQTT broker's port (%d)", _MQTTsetup.port);
_lineInput.reset(_MQTTsetup.port);
break;
case 3:
DebugPort.printf("Enter MQTT broker's username (currently '%s', CTRL-X to erase)", _MQTTsetup.username);
_lineInput.reset(_MQTTsetup.username, 31);
break;
case 4:
DebugPort.printf("Enter MQTT broker's password (currently '%s', CTRL-X to erase)", _MQTTsetup.password);
_lineInput.reset(_MQTTsetup.password, 31);
break;
case 5:
#ifdef ALLOW_USER_TOPIC
DebugPort.printf("Enter root topic name (%s)", _MQTTsetup.topicPrefix);
_lineInput.reset(_MQTTsetup.topicPrefix, 31);
#else
_mode = 0; // topic prefix is now fixed, based upon our STA MAC
showMQTTmenu();
#endif
return true;
case 6:
DebugPort.printf("Enter QoS level (%d)", _MQTTsetup.qos);
break;
case 7:
DebugPort.printf("Enable MQTT? (Y)es / (N)o (%s)", _MQTTsetup.enabled ? "YES" : "NO");
break;
}
DebugPort.print("... ");
}
@ -109,49 +137,28 @@ CMQTTsetup::HandleMQTTsetup(char rxVal)
}
return true;
case 1: // enter MQTT broker IP
if(getMQTTstring(rxVal, 31, _MQTTsetup.host)) {
if(_lineInput.handle(rxVal)) {
bJumptoMQTTmenuRoot = true;
}
break;
case 2: // enter MQTT broker port
if(rxVal < ' ') {
if(_idx == 0) sprintf(_buffer, "%d", _MQTTsetup.port);
if(rxVal == '\n') {
int val = atoi(_buffer);
_MQTTsetup.port = val;
bJumptoMQTTmenuRoot = true;
}
if(rxVal == 0x1b) {
bJumptoMQTTmenuRoot = true;
}
break;
}
DebugPort.print(rxVal);
if(isdigit(rxVal)) {
if(_idx == 0) memset(_buffer, 0, sizeof(_buffer));
_buffer[_idx++] = rxVal;
if(_idx == 5) {
int val = atoi(_buffer);
_MQTTsetup.port = val;
bJumptoMQTTmenuRoot = true;
}
}
else {
if(_lineInput.handle(rxVal)) {
_MQTTsetup.port = _lineInput.getNumeric();
bJumptoMQTTmenuRoot = true;
}
break;
case 3: // enter MQTT broker username
if(getMQTTstring(rxVal, 31, _MQTTsetup.username)) {
if(_lineInput.handle(rxVal)) {
bJumptoMQTTmenuRoot = true;
}
break;
case 4: // enter MQTT broker username
if(getMQTTstring(rxVal, 31, _MQTTsetup.password)) {
if(_lineInput.handle(rxVal)) {
bJumptoMQTTmenuRoot = true;
}
break;
case 5: // enter root topic name
if(getMQTTstring(rxVal, 31, _MQTTsetup.topicPrefix)) {
if(_lineInput.handle(rxVal)) {
bJumptoMQTTmenuRoot = true;
}
break;
@ -176,36 +183,3 @@ CMQTTsetup::HandleMQTTsetup(char rxVal)
return true;
}
bool
CMQTTsetup::getMQTTstring(char rxVal, int maxidx, char* pTargetString)
{
if(rxVal < ' ') {
if(_idx == 0) strcpy(_buffer, pTargetString);
if(rxVal == ('x' & 0x1f)) { // CTRL-X - erase string, return done
memset(pTargetString, 0, maxidx+1);
return true;
}
if(rxVal == '\r') // ignore CR
return false;
if(rxVal == '\n') { // accept buffered string upon LF, return done
strncpy(pTargetString, _buffer, maxidx);
pTargetString[maxidx] = 0;
return true;
}
if(rxVal == 0x1b) { // abort, no change upon ESC, return done
return true;
}
}
else {
if(_idx == 0) memset(_buffer, 0, sizeof(_buffer));
DebugPort.print(rxVal);
_buffer[_idx++] = rxVal;
if(_idx == maxidx) {
strncpy(pTargetString, _buffer, maxidx);
pTargetString[maxidx] = 0;
return true;
}
}
return false;
}

View File

@ -20,17 +20,16 @@
*/
#include "NVStorage.h"
#include "GetLine.h"
class CMQTTsetup {
char _buffer[128];
int _idx;
CGetLine _lineInput;
int _mode;
bool _active;
sMQTTparams _MQTTsetup;
bool HandleMQTTsetup(char rxVal);
void showMQTTmenu(bool init = false);
bool getMQTTstring(char rxVal, int maxidx, char* pTargetString);
public:
CMQTTsetup();
bool Handle(char& rxVal);

View File

@ -448,7 +448,6 @@ sUserSettings::load()
DebugPort.printf("2) Window = %f\r\n", ThermostatWindow);
validatedLoad("frostOn", FrostOn, 0, u8inBounds, 0, 10);
validatedLoad("frostRise", FrostRise, 5, u8inBounds, 0, 20);
// validatedLoad("enableWifi", enableWifi, 1, u8inBounds, 0, 1);
validatedLoad("enableWifi", wifiMode, 1, u8inBounds, 0, 3);
validatedLoad("enableOTA", enableOTA, 0, u8inBounds, 0, 1);
validatedLoad("cyclicStop", cyclic.Stop, 0, s8inBounds, 0, 10);
@ -518,7 +517,6 @@ sUserSettings::save()
saveFloat("thermoWindow", ThermostatWindow);
preferences.putUChar("frostOn", FrostOn);
preferences.putUChar("frostRise", FrostRise);
// preferences.putUChar("enableWifi", enableWifi);
preferences.putUChar("enableWifi", wifiMode);
preferences.putUChar("enableOTA", enableOTA);
preferences.putChar("cyclicStop", cyclic.Stop);
@ -585,7 +583,7 @@ sCredentials::load()
{
// **** MAX LENGTH is 15 for names ****
preferences.begin("credentials", false);
validatedLoad("SSID", SSID, 31, "Afterburner");
validatedLoad("SSID", APSSID, 31, "Afterburner");
validatedLoad("APpassword", APpassword, 31, "thereisnospoon");
validatedLoad("webUpdateUser", webUpdateUsername, 31, "Afterburner");
validatedLoad("webUpdatePass", webUpdatePassword, 31, "BurnBabyBurn");
@ -597,7 +595,7 @@ sCredentials::save()
{
// **** MAX LENGTH is 15 for names ****
preferences.begin("credentials", false);
preferences.putString("SSID", SSID);
preferences.putString("SSID", APSSID);
preferences.putString("APpassword", APpassword);
preferences.putString("webUpdateUser", webUpdateUsername);
preferences.putString("webUpdatePass", webUpdatePassword);

View File

@ -225,12 +225,12 @@ struct sJSONoptions {
struct sCredentials : public CESP32_NVStorage {
char SSID[32];
char APSSID[32];
char APpassword[32];
char webUpdateUsername[32];
char webUpdatePassword[32];
void init() {
strcpy(SSID, "Afterburner");
strcpy(APSSID, "Afterburner");
strcpy(APpassword, "thereisnospoon");
strcpy(webUpdateUsername, "Afterburner");
strcpy(webUpdatePassword, "BurnBabyBurn");
@ -239,7 +239,7 @@ struct sCredentials : public CESP32_NVStorage {
void save();
bool valid();
sCredentials& operator=(const sCredentials& rhs) {
strcpy(SSID, rhs.SSID);
strcpy(APSSID, rhs.APSSID);
strcpy(APpassword, rhs.APpassword);
strcpy(webUpdateUsername, rhs.webUpdateUsername);
strcpy(webUpdatePassword, rhs.webUpdatePassword);
@ -303,9 +303,8 @@ struct sUserSettings : public CESP32_NVStorage {
uint8_t FrostOn;
uint8_t FrostRise;
uint8_t useThermostat;
// uint8_t enableWifi;
uint8_t enableOTA;
uint8_t wifiMode;
uint8_t wifiMode; // general Wifi is enabled mode, may be AP only or STA+AP, 2 => STA only if possible, or AP only
uint16_t FrameRate;
sCyclicThermostat cyclic;
sHomeMenuActions HomeMenu;
@ -325,7 +324,6 @@ struct sUserSettings : public CESP32_NVStorage {
retval &= ThermostatMethod <= 3; // only modes 0, 1 or 2, 3
retval &= INBOUNDS(ThermostatWindow, 0.2f, 10.f);
retval &= useThermostat < 2;
// retval &= (enableWifi == 0) || (enableWifi == 1);
retval &= INBOUNDS(wifiMode, 0, 3);
retval &= (enableOTA == 0) || (enableOTA == 1);
retval &= GPIO.in1Mode < 4;
@ -348,8 +346,7 @@ struct sUserSettings : public CESP32_NVStorage {
FrostOn = 0;
FrostRise = 5;
useThermostat = 1;
// enableWifi = 1;
wifiMode = 1;
wifiMode = 1;
enableOTA = 0;
GPIO.in1Mode = CGPIOin1::Disabled;
GPIO.in2Mode = CGPIOin2::Disabled;
@ -379,7 +376,6 @@ struct sUserSettings : public CESP32_NVStorage {
FrostOn = rhs.FrostOn;
FrostRise = rhs.FrostRise;
useThermostat = rhs.useThermostat;
// enableWifi = rhs.enableWifi;
wifiMode = rhs.wifiMode;
enableOTA = rhs.enableOTA;
GPIO.in1Mode = rhs.GPIO.in1Mode;

View File

@ -291,12 +291,14 @@ void DecodeCmd(const char* cmd, String& payload)
NVstore.setMQTTinfo(info);
}
}
#ifdef ALLOW_USER_TOPIC
else if(strcmp("MTopic", cmd) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.topicPrefix, payload.c_str(), 31);
info.topicPrefix[31] = 0;
NVstore.setMQTTinfo(info);
}
#endif
else if(strcmp("UploadSize", cmd) == 0) {
setUploadSize(payload.toInt());
}

View File

@ -96,11 +96,12 @@ void onMqttConnect(bool sessionPresent)
DebugPort.println("MQTT: Connected to broker.");
// DebugPort.printf("Session present: %d\r\n", sessionPresent);
// create the topicname we use to accept incoming JSON
DebugPort.printf("MQTT: topic prefix name \"%s\"\r\n", NVstore.getMQTTinfo().topicPrefix);
sprintf(statusTopic, "%s/status", NVstore.getMQTTinfo().topicPrefix);
sprintf(topicnameJSONin, "%s/JSONin", NVstore.getMQTTinfo().topicPrefix);
sprintf(topicnameCmd, "%s/cmd/#", NVstore.getMQTTinfo().topicPrefix);
// apply the topicname we need to subscribe to incoming JSON
DebugPort.printf("MQTT: topic prefix name \"%s\"\r\n", getTopicPrefix());
sprintf(statusTopic, "%s/status", getTopicPrefix());
sprintf(topicnameJSONin, "%s/JSONin", getTopicPrefix());
sprintf(topicnameCmd, "%s/cmd/#", getTopicPrefix());
subscribe(topicnameJSONin); // subscribe to the JSONin topic
subscribe(topicnameCmd); // subscribe to the basic command topic
@ -252,7 +253,7 @@ bool mqttPublishJSON(const char* str)
if(MQTTclient.connected()) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/JSONout", params.topicPrefix);
sprintf(topic, "%s/JSONout", getTopicPrefix());
MQTTclient.publish(topic, params.qos, false, str);
return true;
}
@ -322,7 +323,7 @@ void pubTopic(const char* name, int value)
if(MQTTmoderator.shouldSend(name, value)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
char payload[128];
sprintf(payload, "%d", value);
MQTTclient.publish(topic, params.qos, false, payload);
@ -336,7 +337,7 @@ void pubTopic(const char* name, float value)
if(MQTTmoderator.shouldSend(name, value)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
char payload[128];
sprintf(payload, "%.1f", value);
MQTTclient.publish(topic, params.qos, false, payload);
@ -350,7 +351,7 @@ void pubTopic(const char* name, const char* payload)
if(MQTTmoderator.shouldSend(name, payload)) {
const sMQTTparams params = NVstore.getMQTTinfo();
char topic[128];
sprintf(topic, "%s/sts/%s", params.topicPrefix, name);
sprintf(topic, "%s/sts/%s", getTopicPrefix(), name);
MQTTclient.publish(topic, params.qos, false, payload);
}
}
@ -425,4 +426,24 @@ void requestMQTTrestart()
MQTTrestart = (millis() + 1000) | 1;
}
const char* getTopicPrefix()
{
#ifdef ALLOW_USER_TOPIC
return NVstore.getMQTTinfo().topicPrefix;
#else
static char prefix[32] = "";
if(strlen(prefix) == 0) {
uint8_t MAC[6];
esp_read_mac(MAC, ESP_MAC_WIFI_STA);
sprintf(prefix, "Afterburner%02X%02X%02X", MAC[3], MAC[4], MAC[5]);
}
return prefix;
#endif
}
#endif

View File

@ -31,6 +31,7 @@ bool mqttPublishJSON(const char* str);
void connectToMqtt();
void kickMQTT();
bool isMQTTconnected();
const char* getTopicPrefix();
#endif

View File

@ -89,7 +89,7 @@ void build500Response(String& content, String file);
const char* getWebContent(bool start) {
if(isWifiSTA() && start) {
if(isWifiSTAConnected() && start) {
GetWebContent.start();
}

View File

@ -49,8 +49,9 @@ unsigned long WifiReconnectHoldoff = 0;
extern CScreenManager ScreenManager;
bool initWifi(const char *failedssid, const char *failedpassword)
bool initWifi()
{
sCredentials creds = NVstore.getCredentials(); // local Soft AP credentials
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
@ -83,7 +84,7 @@ bool initWifi(const char *failedssid, const char *failedpassword)
DebugPort.println("Attempting to start STA mode (or config portal) via WifiManager...");
wm.setHostname(failedssid);
wm.setHostname(creds.APSSID); // define Soft AP name
wm.setDebugOutput(true);
wm.setConfigPortalTimeout(20);
wm.setConfigPortalBlocking(false);
@ -94,7 +95,7 @@ bool initWifi(const char *failedssid, const char *failedpassword)
//REMOVED - UNSTABLE WHETHER WE GET 192.168.4.1 or 192.168.100.1 ????
// REMOVED wm.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255,255,255,0));
bool res = wm.autoConnect(failedssid, failedpassword); // auto generated AP name from chipid
bool res = wm.autoConnect(creds.APSSID, creds.APpassword); // User definable AP name & password
DebugPort.printf("WifiMode after autoConnect = "); DebugPort.println(WiFi.getMode());
int chnl = 1;
@ -114,19 +115,28 @@ bool initWifi(const char *failedssid, const char *failedpassword)
DebugPort.printf(" STA IP address: %s\r\n", getWifiSTAAddrStr());
// must use same radio channel as STA to go to STA+AP, otherwise we drop the STA!
chnl = WiFi.channel();
DebugPort.println("Now promoting to STA+AP mode...");
retval = true;
}
#if USE_AP_ALWAYS == 1
if(NVstore.getUserSettings().wifiMode & 0x01) { // Own AP enabled
startAP = true;
if(isSTA) {
if(NVstore.getUserSettings().wifiMode & 0x02) { // Check for STA only mode
DebugPort.println(" Using STA only mode.");
}
else {
DebugPort.println("Now promoting to STA+AP mode...");
startAP = true;
}
}
#if USE_AP_ALWAYS == 1
startAP = true;
DebugPort.println("Forcing AP mode on!");
#endif
// WiFi.softAP(failedssid, failedpassword, chnl);
// WiFi.softAP(creds.SSID, creds.APpassword, chnl);
if(startAP) {
// for STA+AP mode we *must* use the same RF channel as STA
DebugPort.println("Starting AP mode");
WiFi.softAP(failedssid, failedpassword, chnl);
WiFi.enableAP(true);
WiFi.softAP(creds.APSSID, creds.APpassword, chnl);
DebugPort.printf(" AP SSID: %s\r\n", WiFi.softAPgetHostname());
DebugPort.printf(" AP IP address: %s\r\n", getWifiAPAddrStr());
DebugPort.printf("WifiMode after initWifi = %d\r\n", WiFi.getMode());
@ -139,8 +149,8 @@ bool initWifi(const char *failedssid, const char *failedpassword)
isPortalAP = true; // we started portal, we have to flag it!
}
// WiFi.setTxPower(WIFI_POWER_MINUS_1dBm);
// WiFi.setTxPower(WIFI_POWER_MINUS_1dBm);
WiFi.setTxPower(WIFI_POWER_19_5dBm);
return retval;
}
@ -151,7 +161,13 @@ void doWiFiManager()
wm.process();
if(WiFi.status() != WL_CONNECTED) {
if(isSTA) DebugPort.println("STA lost");
if(isSTA) {
DebugPort.println("STA lost");
// ensure inbuilt AP is started if STA is down
sCredentials creds = NVstore.getCredentials(); // local AP credentials
int chnl = 1;
WiFi.softAP(creds.APSSID, creds.APpassword, chnl); // this will intrinsically enable AP
}
isSTA = false;
if(WifiReconnectHoldoff) {
long tDelta = millis() - WifiReconnectHoldoff;
@ -170,7 +186,19 @@ void doWiFiManager()
}
}
else {
if(!isSTA) DebugPort.println("STA established");
if(!isSTA) {
// initial regain of STA connection detected
DebugPort.println("STA established");
if(NVstore.getUserSettings().wifiMode & 0x02) {
WiFi.enableAP(false); // kill inbuilt AP if setup for STA only
}
else {
// ensure inbuilt AP is set to same channel as STA
int chnl = WiFi.channel();
sCredentials creds = NVstore.getCredentials(); // local AP credentials
WiFi.softAP(creds.APSSID, creds.APpassword, chnl); // intrinsically enables Soft AP
}
}
isSTA = true;
WifiReconnectHoldoff = 0;
}
@ -181,10 +209,10 @@ void doWiFiManager()
void wifiDisable(long rebootDelay)
{
sUserSettings settings = NVstore.getUserSettings();
// settings.enableWifi = 0;
settings.wifiMode = 0;
NVstore.setUserSettings(settings);
NVstore.save();
NVstore.doSave(); // ensure NV storage
DebugPort.println("*** Disabling WiFi ***");
@ -196,23 +224,29 @@ void wifiDisable(long rebootDelay)
ScreenManager.showRebootMsg(content, rebootDelay);
}
void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay)
void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay, bool STAonly)
{
wm.disconnect();
sUserSettings settings = NVstore.getUserSettings();
settings.wifiMode = 1;
settings.wifiMode = STAonly ? 0x02 : 0x01;
NVstore.setUserSettings(settings);
NVstore.save();
NVstore.doSave(); // ensure NV storage
prepBootIntoConfigPortal(state);
const char* content[2];
if(isWifiSTA() && !erase)
content[0] = "WiFi Mode \032 STA+AP";
else
if(isWifiSTA() && !erase) {
if(STAonly)
content[0] = "WiFi Mode \032 STA only";
else
content[0] = "WiFi Mode \032 STA+AP";
}
else {
content[0] = "WiFi Mode \032 AP only";
}
if(erase) {
wm.resetSettings();
@ -238,10 +272,10 @@ void wifiFactoryDefault()
wm.resetSettings();
prepBootIntoConfigPortal(false);
sUserSettings settings = NVstore.getUserSettings();
// settings.enableWifi = 1;
settings.wifiMode = 1;
NVstore.setUserSettings(settings);
NVstore.save();
NVstore.doSave(); // ensure NV storage
}
// callback is invoked by WiFiManager after new credentials are saved and verified
@ -258,7 +292,7 @@ void APstartedCallback(WiFiManager*)
const char* getWifiAPAddrStr()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // check that wifi should be active
IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME!
static char APIPaddr[16];
sprintf(APIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]);
@ -270,7 +304,7 @@ const char* getWifiAPAddrStr()
const char* getWifiSTAAddrStr()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // check that wifi should be active
IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME!
static char STAIPaddr[16];
sprintf(STAIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]);
@ -282,7 +316,7 @@ const char* getWifiSTAAddrStr()
const char* getWifiGatewayAddrStr()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // check that wifi should be active
IPAddress IPaddr = WiFi.gatewayIP(); // use stepping stone - function returns an automatic stack var - LAME!
static char GWIPaddr[16];
sprintf(GWIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]);
@ -294,7 +328,7 @@ const char* getWifiGatewayAddrStr()
int8_t getWifiRSSI()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // check that wifi should be active
static unsigned long updateRSSI = millis() + 2500;
static int8_t RSSI = 0;
long tDelta = millis() - updateRSSI;
@ -322,9 +356,9 @@ const char* getWifiSTAMACStr()
return MACstr[0];
}
String getSSID()
String getSTASSID()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // check that wifi should be active
wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA, &conf);
return String(reinterpret_cast<const char*>(conf.sta.ssid));
@ -333,22 +367,23 @@ String getSSID()
return "";
}
bool isWifiConnected()
bool isWifiSTAConnected()
{
if(NVstore.getUserSettings().wifiMode)
if(NVstore.getUserSettings().wifiMode) { // non zero => enabled wifi, maybe AP only or STA+AP or STA only
return WiFi.status() == WL_CONNECTED;
else
return false;
}
return false;
}
bool isWifiAP()
bool isWifiAPonly()
{
if(NVstore.getUserSettings().wifiMode) {
if(NVstore.getUserSettings().wifiMode) { // non zero => enabled wifi, maybe AP only or STA+AP or STA only
int mode = WiFi.getMode();
return !isSTA && ((mode & WIFI_MODE_AP) != 0);
}
else
return false;
return false;
}
bool isWifiSTA()

View File

@ -25,23 +25,23 @@
#include <WiFi.h>
void doWiFiManager();
bool initWifi(const char *failedssid, const char *failedpassword);
bool initWifi();
const char* getWifiAPAddrStr();
const char* getWifiSTAAddrStr();
const char* getWifiGatewayAddrStr();
const char* getWifiAPMACStr();
const char* getWifiSTAMACStr();
int8_t getWifiRSSI();
String getSSID();
String getSTASSID();
bool isWifiConnected();
bool isWifiAP();
bool isWifiSTAConnected();
bool isWifiAPonly();
bool isWifiSTA();
bool isWifiConfigPortal();
bool isWebClientConnected();
bool hasWebClientSpoken(bool reset = false);
bool hasWebServerSpoken(bool reset = false);
void wifiEnterConfigPortal(bool state, bool erase = false, long timeout = 7000);
void wifiEnterConfigPortal(bool state, bool erase = false, long timeout = 7000, bool STAonly = false);
void wifiDisable(long rebootDelay = 7000);
void wifiFactoryDefault();
int isWifiButton();

View File

@ -105,7 +105,7 @@ void initOTA(){
}
void DoOTA()
void doOTA()
{
ArduinoOTA.handle();

View File

@ -24,7 +24,7 @@
void initOTA();
void initFOTA();
void DoOTA();
void doOTA();
bool CheckFirmwareCRC(int size);
#endif

View File

@ -42,7 +42,7 @@
// HC-05 works OK with WiFi
//
#define USE_WIFI 1
#define USE_AP_ALWAYS 1
#define USE_AP_ALWAYS 0
#define USE_OTA 1
#define USE_WEBSERVER 1
#define USE_MQTT 1