Fixed NV storage issue.

Adding GPIO JSON
This commit is contained in:
Ray Jones 2019-06-05 06:15:12 +10:00
parent 811c15093c
commit dafd7ba856
12 changed files with 327 additions and 50 deletions

View file

@ -1370,4 +1370,22 @@ void doStreaming()
DebugPort.handle(); // keep telnet spy alive
}
void getGPIOinfo(sGPIO& info)
{
info.inState[0] = GPIOin.getState(0);
info.inState[1] = GPIOin.getState(1);
info.outState[0] = GPIOout.getState(0);
info.outState[1] = GPIOout.getState(1);
info.algVal = GPIOalg.getValue();
info.inMode = GPIOin.getMode();
info.outMode = GPIOout.getMode();
info.algMode = GPIOalg.getMode();
}
// hook for JSON input, simulating a GPIO key press
void simulateGPIOin(uint8_t newKey)
{
GPIOin.simulateKey(newKey);
}

View file

@ -157,7 +157,7 @@ CHomeMenuSelScreen::keyHandler(uint8_t event)
UPPERLIMIT(_rowSel, 3);
}
}
// UP press
// DOWN press
if(event & key_Down) {
_scrollChar = 0;
_rowSel--;

View file

@ -26,6 +26,8 @@
#include "Protocol.h"
#include "../Utility/UtilClasses.h"
struct sGPIO;
extern void ToggleOnOff();
extern void requestOn();
@ -72,6 +74,8 @@ extern void feedWatchdog();
extern bool isUpdateAvailable(bool test=true);
extern void checkFOTA();
extern void setUploadSize(long val);
extern void getGPIOinfo(sGPIO& info);
extern void simulateGPIOin(uint8_t newKey);
extern void ShowOTAScreen(int percent=0, eOTAmodes updateType=eOTAnormal);

View file

@ -36,6 +36,7 @@ CModerator JSONmoderator;
CTimerModerator TimerModerator;
int timerConflict = 0;
CModerator MQTTmoderator;
CModerator GPIOmoderator;
void validateTimer(int ID);
@ -193,6 +194,18 @@ void interpretJsonCommand(char* pLine)
else if(strcmp("UploadSize", it->key) == 0) {
setUploadSize(it->value.as<long>());
}
else if(strcmp("GPout1", it->key) == 0) {
setGPIOout(0, it->value.as<unsigned char>() ? true : false);
}
else if(strcmp("GPout2", it->key) == 0) {
setGPIOout(1, it->value.as<unsigned char>() ? true : false);
}
else if(strcmp("GPin1", it->key) == 0) {
simulateGPIOin(it->value.as<unsigned char>() ? 0x01 : 0x00); // simulate key 1 press
}
else if(strcmp("GPin2", it->key) == 0) {
simulateGPIOin(it->value.as<unsigned char>() ? 0x02 : 0x00); // simulate key 2 press
}
}
}
@ -271,6 +284,20 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
return bSend;
}
/*bool makeJSONStringGPIO(const sGPIO& GPIOinfo, char* opStr, int len)
{
StaticJsonBuffer<800> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
bool bSend = GPIOmoderator.addJson(GPIOinfo, root);
if(bSend) {
root.printTo(opStr, len);
}
return bSend;
}*/
// the way the JSON timer strings are crafted, we have to iterate over each timer's parameters
// individually, the JSON name is always the same for each timer, the payload IDs the specific
// timer
@ -278,10 +305,10 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
// {"TimerStart":XX:XX,"TimerStop":XX:XX,"TimerDays":XX,"TimerRepeat":X}
bool makeJSONTimerString(int channel, char* opStr, int len)
{
bool bSend = false; // reset should send flag
StaticJsonBuffer<800> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
bool bSend = false; // reset should send flag
sTimer timerInfo;
NVstore.getTimerInfo(channel, timerInfo);
@ -294,6 +321,31 @@ bool makeJSONTimerString(int channel, char* opStr, int len)
return bSend;
}
bool makeJSONStringGPIO(CModerator& moderator, char* opStr, int len)
{
StaticJsonBuffer<800> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
bool bSend = false; // reset should send flag
sGPIO info;
getGPIOinfo(info);
bSend |= moderator.addJson("GPin1", info.inState[0], root);
bSend |= moderator.addJson("GPin2", info.inState[1], root);
bSend |= moderator.addJson("GPout1", info.outState[0], root);
bSend |= moderator.addJson("GPout2", info.outState[1], root);
bSend |= moderator.addJson("GPanlg", info.algVal * 100 / 4096, root);
bSend |= moderator.addJson("GPmodeIn", GPIOinNames[info.inMode], root);
bSend |= moderator.addJson("GPmodeOut", GPIOoutNames[info.outMode], root);
bSend |= moderator.addJson("GPmodeAnlg", GPIOalgNames[info.algMode], root);
if(bSend) {
root.printTo(opStr, len);
}
return bSend;
}
bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len)
{
@ -387,6 +439,17 @@ void updateJSONclients(bool report)
getBluetoothClient().send( jsonStr );
}
}
{
if(makeJSONStringGPIO(GPIOmoderator, jsonStr, sizeof(jsonStr))) {
if (report) {
DebugPort.printf("JSON send: %s\r\n", jsonStr);
}
sendWebServerString( jsonStr );
getBluetoothClient().send( jsonStr );
}
}
}
@ -399,6 +462,7 @@ void resetJSONmoderator()
initTimerJSONmoderator();
#endif
initMQTTJSONmoderator();
GPIOmoderator.reset();
}
void initMQTTJSONmoderator()

View file

@ -30,6 +30,7 @@ extern char defaultJSONstr[64];
bool makeJSONString(CModerator& moderator, char* opStr, int len);
bool makeJSONStringEx(CModerator& moderator, char* opStr, int len);
bool makeJSONTimerString(int channel, char* opStr, int len);
bool makeJSONStringGPIO( CModerator& moderator, char* opStr, int len);
void updateJSONclients(bool report);
bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len);
void initMQTTJSONmoderator();

View file

@ -29,6 +29,25 @@ const int FADEAMOUNT = 3;
const int FLASHPERIOD = 2000;
const int ONFLASHINTERVAL = 50;
const char* GPIOinNames[4] = {
"Disabled",
"On1Off1",
"Hold1",
"On1Off1"
};
const char* GPIOoutNames[3] = {
"Disabled",
"Status",
"User"
};
const char* GPIOalgNames[2] = {
"Disabled",
"HeatDemand"
};
CGPIOin::CGPIOin()
{
_Mode = GPIOinNone;
@ -52,79 +71,89 @@ CGPIOin::getState(int channel)
return (_Debounce.getState() & mask) != 0;
}
GPIOinModes CGPIOin::getMode() const
{
return _Mode;
};
void
CGPIOin::manage()
{
uint8_t newKey = _Debounce.manage();
// determine edge events
uint8_t keyChange = newKey ^ _lastKey;
_lastKey = newKey;
if(keyChange) {
simulateKey(newKey);
/* switch (_Mode) {
case GPIOinNone:
break;
case GPIOinOn1Off2:
_doOn1Off2(newKey);
break;
case GPIOinOnHold1:
_doOnHold1(newKey);
break;
case GPIOinOn1Off1:
_doOn1Off1(newKey);
break;
}*/
}
}
void
CGPIOin::simulateKey(uint8_t newKey)
{
switch (_Mode) {
case GPIOinNone:
break;
case GPIOinOn1Off2:
_doOn1Off2();
_doOn1Off2(newKey);
break;
case GPIOinOnHold1:
_doOnHold1();
_doOnHold1(newKey);
break;
case GPIOinOn1Off1:
_doOn1Off1();
_doOn1Off1(newKey);
break;
}
}
void
CGPIOin::_doOn1Off2()
CGPIOin::_doOn1Off2(uint8_t newKey)
{
uint8_t newKey = _Debounce.manage();
// determine edge events
uint8_t keyChange = newKey ^ _lastKey;
_lastKey = newKey;
if(keyChange) {
if(newKey & 0x01) {
requestOn();
}
if(newKey & 0x02) {
requestOff();
}
if(newKey & 0x01) {
requestOn();
}
if(newKey & 0x02) {
requestOff();
}
}
// mode where heater runs if input 1 is shorted
// stops when open
void
CGPIOin::_doOnHold1()
CGPIOin::_doOnHold1(uint8_t newKey)
{
uint8_t newKey = _Debounce.manage();
// determine edge events
uint8_t keyChange = newKey ^ _lastKey;
_lastKey = newKey;
if(keyChange) {
if(newKey & 0x01) {
requestOn();
}
else {
requestOff();
}
if(newKey & 0x01) {
requestOn();
}
else {
requestOff();
}
}
// mode where heater runs if input 1 is shorted
// stops when open
void
CGPIOin::_doOn1Off1()
CGPIOin::_doOn1Off1(uint8_t newKey)
{
uint8_t newKey = _Debounce.manage();
// determine edge events
uint8_t keyChange = newKey ^ _lastKey;
_lastKey = newKey;
if(keyChange) {
if(newKey & 0x01) {
if(getHeaterInfo().getRunStateEx())
requestOff();
else
requestOn();
}
if(newKey & 0x01) {
if(getHeaterInfo().getRunStateEx())
requestOff();
else
requestOn();
}
}
@ -170,6 +199,11 @@ CGPIOout::setMode(GPIOoutModes mode)
ledcDetachPin(_pins[1]); // ensure PWM detached from IO line
};
GPIOoutModes CGPIOout::getMode() const
{
return _Mode;
};
void
CGPIOout::manage()
{
@ -353,6 +387,12 @@ CGPIOalg::begin(adc1_channel_t pin, GPIOalgModes mode)
}
}
GPIOalgModes CGPIOalg::getMode() const
{
return _Mode;
};
void CGPIOalg::manage()
{
const float fAlpha = 0.95; // exponential mean alpha

View file

@ -26,6 +26,10 @@
#include <driver/adc.h>
#include "Debounce.h"
extern const char* GPIOinNames[4];
extern const char* GPIOoutNames[3];
extern const char* GPIOalgNames[2];
enum GPIOinModes {
GPIOinNone,
GPIOinOn1Off2, // input 1 closure, heater starts; input2 closure, heater stops
@ -33,17 +37,20 @@ enum GPIOinModes {
GPIOinOn1Off1 // alternate input 1 closures start or stop the heater
};
enum GPIOoutModes {
GPIOoutNone,
GPIOoutStatus,
GPIOoutUser
};
enum GPIOalgModes {
GPIOalgNone, // Unmodified V2.0 PCBs must use this - ADC2 / Wifi unresolvable conflict
GPIOalgHeatDemand,
};
struct sGPIOparams {
GPIOinModes inMode;
GPIOoutModes outMode;
@ -62,15 +69,17 @@ class CGPIOin {
// unsigned long _lastDebounceTime;
// unsigned long _debounceDelay;
// uint8_t _scanInputs();
void _doOn1Off2();
void _doOnHold1();
void _doOn1Off1();
void _doOn1Off2(uint8_t newKey);
void _doOnHold1(uint8_t newKey);
void _doOn1Off1(uint8_t newKey);
public:
CGPIOin();
void setMode(GPIOinModes mode) { _Mode = mode; };
void begin(int pin1, int pin2, GPIOinModes mode, int activeState);
void manage();
uint8_t getState(int channel);
GPIOinModes getMode() const;
void simulateKey(uint8_t newKey);
};
class CGPIOout {
@ -93,6 +102,7 @@ public:
void manage();
void setState(int channel, bool state);
bool getState(int channel);
GPIOoutModes getMode() const;
};
class CGPIOalg {
@ -104,7 +114,27 @@ public:
void begin(adc1_channel_t pin, GPIOalgModes mode);
void manage();
int getValue();
GPIOalgModes getMode() const;
};
struct sGPIO {
bool outState[2];
bool inState[2];
int algVal;
GPIOoutModes outMode;
GPIOinModes inMode;
GPIOalgModes algMode;
sGPIO& operator=(const sGPIO& rhs) {
outState[0] = rhs.outState[0];
outState[1] = rhs.outState[1];
inState[0] = rhs.inState[0];
inState[1] = rhs.inState[1];
algVal = rhs.algVal;
outMode = rhs.outMode;
inMode = rhs.inMode;
algMode = rhs.algMode;
return *this;
}
};
#endif // __BTCGPIO_H__

View file

@ -142,3 +142,67 @@ CStringModerator::reset(const char* name)
Memory.erase(it);
}
}
/*
CGPIOModerator::CGPIOModerator()
{
reset();
}
void
CGPIOModerator::reset()
{
Memory.inState[0] = !Memory.inState[0];
Memory.inState[1] = !Memory.inState[1];
Memory.outState[0] = !Memory.outState[0];
Memory.outState[1] = !Memory.outState[1];
Memory.algVal = Memory.algVal+10000;
Memory.inMode = (GPIOinModes)-1;
Memory.outMode = (GPIOoutModes)-1;
Memory.algMode = (GPIOalgModes)-1;
}
bool
CGPIOModerator::addJson(const sGPIO& toSend, JsonObject& root)
{
bool retval = false;
char msgs[5][16];
if(Memory.inState[0] != toSend.inState[0]) {
root.set("GPin1", toSend.inState[0] ? 1 : 0);
retval = true;
}
if(Memory.inState[1] != toSend.inState[1]) {
root.set("GPin2", toSend.inState[1] ? 1 : 0);
retval = true;
}
if(Memory.outState[0] != toSend.outState[0]) {
root.set("GPout1", toSend.outState[0] ? 1 : 0);
retval = true;
}
if(Memory.outState[1] != toSend.outState[1]) {
root.set("GPout2", toSend.outState[1] ? 1 : 0);
retval = true;
}
if(Memory.algVal != toSend.algVal) {
root.set("GPalg", toSend.algVal);
retval = true;
}
if(Memory.inMode != toSend.inMode) {
root.set("GPinMode", GPIOinNames[toSend.inMode]);
retval = true;
}
if(Memory.outMode != toSend.outMode) {
root.set("GPoutMode", GPIOoutNames[toSend.outMode]);
retval = true;
}
if(Memory.algMode != toSend.algMode) {
root.set("GPalgMode", GPIOalgNames[toSend.algMode]);
retval = true;
}
Memory = toSend;
return retval;
}
*/

View file

@ -26,6 +26,8 @@
#include <ArduinoJSON.h>
#include "../RTC/Timers.h"
#include "DebugPort.h"
#include "GPIO.h"
class CTimerModerator {
sTimer Memory[14];

View file

@ -327,7 +327,7 @@ CHeaterStorage::getHomeMenu() const
}
void
CHeaterStorage::setHomeMenu(sHomeMenuActions val)
CHeaterStorage::setHomeMenu(const sHomeMenuActions& val)
{
_calValues.Options.HomeMenu = val;
}

View file

@ -65,6 +65,18 @@ struct sHeater : public CESP32_NVStorage {
};
void load();
void save();
sHeater& operator=(const sHeater& rhs) {
Pmin = rhs.Pmin;
Pmax = rhs.Pmax;
Fmin = rhs.Fmin;
Fmax = rhs.Fmax;
ThermostatMode = rhs.ThermostatMode;
setTemperature = rhs.setTemperature;
sysVoltage = rhs.sysVoltage;
fanSensor = rhs.fanSensor;
glowDrive = rhs.glowDrive;
return *this;
}
};
struct sHomeMenuActions {
@ -83,6 +95,12 @@ struct sHomeMenuActions {
onStart = 0;
onStop = 0;
}
sHomeMenuActions& operator=(const sHomeMenuActions& rhs) {
onTimeout = rhs.onTimeout;
onStart = rhs.onStart;
onStop = rhs.onStop;
return *this;
}
};
struct sCyclicThermostat {
@ -122,6 +140,13 @@ struct sCredentials : public CESP32_NVStorage {
void load();
void save();
bool valid();
sCredentials& operator=(const sCredentials& rhs) {
strcpy(SSID, rhs.SSID);
strcpy(APpassword, rhs.APpassword);
strcpy(webUpdateUsername, rhs.webUpdateUsername);
strcpy(webUpdatePassword, rhs.webUpdatePassword);
return *this;
}
};
struct sMQTTparams : public CESP32_NVStorage {
@ -146,6 +171,7 @@ struct sMQTTparams : public CESP32_NVStorage {
host[127] = 0;
username[31] = 0;
password[31] = 0;
return *this;
}
void load();
void save();
@ -195,6 +221,21 @@ struct sBTCoptions : public CESP32_NVStorage {
};
void load();
void save();
sBTCoptions& operator=(const sBTCoptions& rhs) {
dimTime = rhs.dimTime;
menuTimeout = rhs.menuTimeout;
degF = rhs.degF;
ThermostatMethod = rhs.ThermostatMethod;
enableWifi = rhs.enableWifi;
enableOTA = rhs.enableOTA;
GPIO.inMode = rhs.GPIO.inMode;
GPIO.outMode = rhs.GPIO.outMode;
GPIO.algMode = rhs.GPIO.algMode;
FrameRate = rhs.FrameRate;
cyclic = rhs.cyclic;
HomeMenu = rhs.HomeMenu;
return *this;
}
};
@ -207,6 +248,15 @@ struct sNVStore {
sCredentials Credentials;
bool valid();
void init();
sNVStore& operator=(const sNVStore& rhs) {
Heater = rhs.Heater;
Options = rhs.Options;
for(int i = 0; i < 14; i++)
timer[i] = rhs.timer[i];
MQTT = rhs.MQTT;
Credentials = rhs.Credentials;
return *this;
}
};
@ -267,12 +317,15 @@ public:
void setCyclicMode(const sCyclicThermostat& val);
void setGPIOparams(const sGPIOparams& params);
void setFrameRate(uint16_t val);
void setHomeMenu(sHomeMenuActions val);
void setHomeMenu(const sHomeMenuActions& val);
void getTimerInfo(int idx, sTimer& timerInfo);
void setTimerInfo(int idx, const sTimer& timerInfo);
void setMQTTinfo(const sMQTTparams& info);
void setCredentials(const sCredentials& info);
CHeaterStorage& operator=(const CHeaterStorage& rhs) {
_calValues = rhs._calValues;
}
};

View file

@ -87,7 +87,8 @@ void initOTA(){
ArduinoOTA.begin();
}
void DoOTA(){
void DoOTA()
{
ArduinoOTA.handle();
// manage Firmware OTA