OLED now reports and resists illegal changes when an OEM controller is active

This commit is contained in:
rljonesau 2018-12-20 17:29:00 +11:00
parent 7eda32b9e7
commit 27d55f7c90
12 changed files with 118 additions and 62 deletions

View file

@ -154,8 +154,8 @@ TelnetSpy DebugPort;
sRxLine PCline;
long lastRxTime; // used to observe inter character delays
bool hasOEMController = false;
bool hasHtrData = false;
bool bHasOEMController = false;
bool bHasHtrData = false;
bool bReportBlueWireData = REPORT_RAW_DATA;
bool bReportJSONData = REPORT_JSON_TRANSMIT;
@ -379,15 +379,15 @@ void loop()
DebugPort.print("ms - ");
if(CommState.is(CommStates::OEMCtrlRx)) {
DebugPort.println("Timeout collecting OEM controller data, returning to Idle State");
hasOEMController = false;
bHasOEMController = false;
}
else if(CommState.is(CommStates::HeaterRx1)) {
DebugPort.println("Timeout collecting OEM heater response data, returning to Idle State");
hasHtrData = false;
bHasHtrData = false;
}
else {
DebugPort.println("Timeout collecting BTC heater response data, returning to Idle State");
hasHtrData = false;
bHasHtrData = false;
}
}
@ -413,12 +413,12 @@ void loop()
// Detect the possible start of a new frame sequence from an OEM controller
// This will be the first activity for considerable period on the blue wire
// The heater always responds to a controller frame, but otherwise never by itself
hasHtrData = false;
bHasHtrData = false;
if(RxTimeElapsed >= 970) {
// have not seen any receive data for a second.
// OEM controller is probably not connected.
// Skip state machine immediately to BTC_Tx, sending our own settings.
hasOEMController = false;
bHasOEMController = false;
bool isBTCmaster = true;
TxManage.PrepareFrame(DefaultBTCParams, isBTCmaster); // use our parameters, and mix in NV storage values
TxManage.Start(timenow);
@ -433,7 +433,7 @@ void loop()
DebugPort.print(RxTimeElapsed);
DebugPort.println("ms Idle time.");
#endif
hasOEMController = true;
bHasOEMController = true;
CommState.set(CommStates::OEMCtrlRx); // we must add this new byte!
//
// ** IMPORTANT - we must drop through to OEMCtrlRx *NOW* (skipping break) **
@ -501,10 +501,10 @@ void loop()
// test for valid CRC, abort and restarts Serial1 if invalid
if(!validateFrame(HeaterFrame1, "RX1")) {
hasHtrData = false;
bHasHtrData = false;
break;
}
hasHtrData = true;
bHasHtrData = true;
// received heater frame (after controller message), report
@ -575,10 +575,10 @@ void loop()
// test for valid CRC, abort and restart Serial1 if invalid
if(!validateFrame(HeaterFrame2, "RX2")) {
hasHtrData = false;
bHasHtrData = false;
break;
}
hasHtrData = true;
bHasHtrData = true;
// received heater frame (after our control message), report
@ -610,7 +610,7 @@ void loop()
CommState.set(CommStates::Idle);
updateJSONclients(bReportJSONData);
if(bReportBlueWireData)
HeaterData.reportFrames(hasOEMController);
HeaterData.reportFrames(bHasOEMController);
break;
} // switch(CommState)
@ -692,7 +692,7 @@ void ToggleOnOff()
bool reqTemp(unsigned char newTemp)
{
if(hasOEMController)
if(bHasOEMController)
return false;
unsigned char max = DefaultBTCParams.getTemperature_Max();
@ -727,7 +727,7 @@ bool reqThermoToggle()
bool setThermostatMode(unsigned char val)
{
if(hasOEMController)
if(bHasOEMController)
return false;
NVstore.setThermostatMode(val);
@ -911,16 +911,21 @@ void checkDebugCommands()
const char* getControllerStat()
{
if(hasHtrData) {
if(hasOEMController)
if(bHasHtrData) {
if(bHasOEMController)
return "OEM,Htr";
else
return "BTC,Htr";
}
else {
if(hasOEMController)
if(bHasOEMController)
return "OEM";
else
return "BTC";
}
}
bool hasOEMcontroller()
{
return bHasOEMController;
}

View file

@ -7,6 +7,7 @@ CScreen::CScreen(C128x64_OLED& disp, CScreenManager& mgr) :
_display(disp),
_ScreenManager(mgr)
{
_showOEMerror = 0;
}
@ -18,6 +19,16 @@ CScreen::~CScreen()
bool
CScreen::animate()
{
if(_showOEMerror) {
DebugPort.println("CScreen::animate()");
_display.fillRect(8, 20, 112, 24, WHITE);
if(_showOEMerror & 0x01) {
_printInverted(_display.xCentre(), 23, "Other controller ", true, eCentreJustify);
_printInverted(_display.xCentre(), 32, "Operation blocked", true, eCentreJustify);
}
_showOEMerror--;
return true;
}
return false;
}
@ -94,6 +105,11 @@ CScreen::_adjustExtents(CRect& extents, eJUSTIFY justify, const char* str)
}
}
void
CScreen::_reqOEMWarning()
{
_showOEMerror = 10;
}
// a class used for temporary alternate fonts usage
// Reverts to standard inbuilt font when the instance falls out of scope

View file

@ -39,12 +39,14 @@ const int radius = 4;
class CScreen {
protected:
int _showOEMerror;
C128x64_OLED& _display;
CScreenManager& _ScreenManager;
void _printMenuText(int x, int y, const char* str, bool selected = false, eJUSTIFY justify = eLeftJustify, int border = 3, int radius = 4);
void _printInverted(int x, int y, const char* str, bool selected, eJUSTIFY justify = eLeftJustify);
void _adjustExtents(CRect& rect, eJUSTIFY justify, const char* str);
void _drawMenuSelection(CRect extents, const char* str, int border = 3, int radius = 4);
void _reqOEMWarning();
public:
CScreen(C128x64_OLED& disp, CScreenManager& mgr);
virtual ~CScreen();

View file

@ -156,8 +156,10 @@ CScreen1::animate()
_heatAnimationState -= 2;
_heatAnimationState &= 0x07;
}
return retval |= true;
retval = true;
}
retval |= CScreen::animate();
return retval;
}
@ -175,12 +177,16 @@ CScreen1::keyHandler(uint8_t event)
_ScreenManager.nextScreen();
}
if(event & key_Up) {
reqTempDelta(+1);
_showTarget = millis() + 3500;
if(reqTempDelta(+1))
_showTarget = millis() + 3500;
else
_reqOEMWarning();
}
if(event & key_Down) {
reqTempDelta(-1);
_showTarget = millis() + 3500;
if(reqTempDelta(-1))
_showTarget = millis() + 3500;
else
_reqOEMWarning();
}
}
// require hold to turn ON or OFF

View file

@ -127,8 +127,12 @@ CScreen2::keyHandler(uint8_t event)
if(!_showMode)
_ScreenManager.prevScreen();
else {
_showMode = millis() + 5000;
_nModeSel = 0;
if(hasOEMcontroller())
_reqOEMWarning();
else {
_showMode = millis() + 5000;
_nModeSel = 0;
}
_ScreenManager.reqUpdate();
}
}
@ -137,8 +141,12 @@ CScreen2::keyHandler(uint8_t event)
if(!_showMode)
_ScreenManager.nextScreen();
else {
_showMode = millis() + 5000;
_nModeSel = 1;
if(hasOEMcontroller())
_reqOEMWarning();
else {
_showMode = millis() + 5000;
_nModeSel = 1;
}
_ScreenManager.reqUpdate();
}
}
@ -146,8 +154,10 @@ CScreen2::keyHandler(uint8_t event)
// impossible with 5 way switch!
uint8_t doubleKey = key_Down | key_Up;
if((event & doubleKey) == doubleKey) {
reqThermoToggle();
_showSetMode = millis() + 2000;
if(reqThermoToggle())
_showSetMode = millis() + 2000;
else
_reqOEMWarning();
}
}
// use repeat function for key hold detection
@ -185,13 +195,17 @@ CScreen2::keyHandler(uint8_t event)
if(!_showMode) {
// release DOWN key to reduce set demand, provided we are not in mode select
if(event & key_Down) {
reqTempDelta(-1);
_showSetMode = millis() + 2000;
if(reqTempDelta(-1))
_showSetMode = millis() + 2000;
else
_reqOEMWarning();
}
// release UP key to increase set demand, provided we are not in mode select
if(event & key_Up) {
reqTempDelta(+1);
_showSetMode = millis() + 2000;
if(reqTempDelta(+1))
_showSetMode = millis() + 2000;
else
_reqOEMWarning();
}
}
// release CENTRE to accept new mode, and/or show current setting

View file

@ -36,4 +36,5 @@ public:
CScreen2(C128x64_OLED& display, CScreenManager& mgr);
void show();
void keyHandler(uint8_t event);
bool animate() { return CScreen::animate(); };
};

View file

@ -27,7 +27,7 @@
//
// CScreen3
//
// This screen allows the temeprature control mode to be selected and
// This screen allows the temperature control mode to be selected and
// allows pump priming
//
///////////////////////////////////////////////////////////////////////////
@ -146,12 +146,16 @@ CScreen3::keyHandler(uint8_t event)
}
// press UP
if(event & key_Up) {
_rowSel++;
UPPERLIMIT(_rowSel, 2);
if(_rowSel == 2)
_colSel = 1; // select OFF upon entry to priming menu
if(_rowSel == 1)
_colSel = getHeaterInfo().isThermostat() ? 0 : 1;
if(hasOEMcontroller())
_reqOEMWarning();
else {
_rowSel++;
UPPERLIMIT(_rowSel, 2);
if(_rowSel == 2)
_colSel = 1; // select OFF upon entry to priming menu
if(_rowSel == 1)
_colSel = getHeaterInfo().isThermostat() ? 0 : 1;
}
}
// press DOWN
if(event & key_Down) {

View file

@ -35,4 +35,5 @@ public:
CScreen3(C128x64_OLED& display, CScreenManager& mgr);
void show();
void keyHandler(uint8_t event);
bool animate() { return CScreen::animate(); };
};

View file

@ -206,27 +206,31 @@ CScreen5::keyHandler(uint8_t event)
}
// press UP
if(event & key_Up) {
switch(_rowSel) {
case 0:
case 2:
case 3:
case 4:
_rowSel++;
_colSel = 0;
UPPERLIMIT(_rowSel, 5);
break;
case 1: // password entry
_PWdig[_colSel]++;
ROLLUPPERLIMIT(_PWdig[_colSel], 9, 0);
break;
case 6:
setPumpMin(adjPump[0]);
setPumpMax(adjPump[1]);
setFanMin(adjFan[0]);
setFanMax(adjFan[1]);
saveNV();
_rowSel = 0;
break;
if(hasOEMcontroller())
_reqOEMWarning();
else {
switch(_rowSel) {
case 0:
case 2:
case 3:
case 4:
_rowSel++;
_colSel = 0;
UPPERLIMIT(_rowSel, 5);
break;
case 1: // password entry
_PWdig[_colSel]++;
ROLLUPPERLIMIT(_PWdig[_colSel], 9, 0);
break;
case 6:
setPumpMin(adjPump[0]);
setPumpMax(adjPump[1]);
setFanMin(adjFan[0]);
setFanMax(adjFan[1]);
saveNV();
_rowSel = 0;
break;
}
}
}
// press DOWN

View file

@ -39,4 +39,5 @@ public:
CScreen5(C128x64_OLED& display, CScreenManager& mgr);
void show();
void keyHandler(uint8_t event);
bool animate() { return CScreen::animate(); };
};

View file

@ -169,8 +169,9 @@ CScreenManager::reqUpdate()
bool
CScreenManager::animate()
{
if(_currentScreen >= 0)
if(_currentScreen >= 0) {
return _Screens[_currentScreen]->animate();
}
return false;
}

View file

@ -46,6 +46,7 @@ extern void interpretJsonCommand(char* pLine);
extern void resetWebModerator();
extern void resetJSONmoderator();
extern const char* getControllerStat();
extern bool hasOEMcontroller();
#define LOWERLIMIT(A, B) if(A < B) A = B
#define UPPERLIMIT(A, B) if(A > B) A = B