AM/PM selection in clock setup menu.
Extra MQTT JSON IDs added.

Filtered No Heater JSON.
This commit is contained in:
Ray Jones 2019-09-08 10:14:36 +10:00
parent 583a4881cd
commit ac5fdc5dfd
26 changed files with 274 additions and 177 deletions

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2018 James Clark
*
* This program is free software: you can redistribute it and/or modify
@ -124,8 +124,8 @@
#define RX_DATA_TIMOUT 50
const int FirmwareRevision = 31;
const int FirmwareSubRevision = 1;
const char* FirmwareDate = "1 Sep 2019";
const int FirmwareSubRevision = 2;
const char* FirmwareDate = "8 Sep 2019";
#ifdef ESP32

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -98,16 +98,12 @@ CMenuTrunkScreen::keyHandler(uint8_t event)
break;
case 1:
_ScreenManager.selectMenu(CScreenManager::UserSettingsLoop);
// _ScreenManager.prevMenu();
break;
case 2:
_ScreenManager.selectMenu(CScreenManager::SystemSettingsLoop);
// _ScreenManager.prevMenu();
break;
case 3:
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::HtrSettingsUI);
// _ScreenManager.selectMenu(CScreenManager::TuningMenuLoop);
// _ScreenManager.prevMenu();
break;
}
}
@ -120,17 +116,12 @@ CMenuTrunkScreen::keyHandler(uint8_t event)
break;
case 1:
_ScreenManager.selectMenu(CScreenManager::UserSettingsLoop);
// _ScreenManager.nextMenu();
break;
case 2:
_ScreenManager.selectMenu(CScreenManager::SystemSettingsLoop);
// _ScreenManager.nextMenu();
break;
case 3:
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::HtrSettingsUI);
// _ScreenManager.selectMenu(CScreenManager::TuningMenuLoop);
// _ScreenManager.nextMenu();
break;
}
}

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -40,7 +40,7 @@
#include "GPIOSetupScreen.h"
#include "VersionInfoScreen.h"
#include "HomeMenuSelScreen.h"
#include "OtherOptionsScreen.h"
#include "TimeoutsScreen.h"
#include "HourMeterScreen.h"
#include "BTScreen.h"
#include "MenuTrunkScreen.h"
@ -449,7 +449,7 @@ CScreenManager::begin(bool bNoClock)
else {
menuloop.push_back(new CThermostatModeScreen(*_pDisplay, *this)); // thermostat settings screen
menuloop.push_back(new CHomeMenuSelScreen(*_pDisplay, *this)); // Home menu settings screen
menuloop.push_back(new COtherOptionsScreen(*_pDisplay, *this)); // Other options screen
menuloop.push_back(new CTimeoutsScreen(*_pDisplay, *this)); // Other options screen
if(getBoardRevision() != 0 && getBoardRevision() != BRD_V2_NOGPIO) // has GPIO support ?
menuloop.push_back(new CGPIOSetupScreen(*_pDisplay, *this)); // GPIO settings screen
}

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -33,6 +33,7 @@
#include "fonts/Arial.h"
#include "../RTC/Clock.h"
#include "../Utility/macros.h"
#include "../Utility/NVStorage.h"
CSetClockScreen::CSetClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreen(display, mgr)
@ -53,6 +54,7 @@ CSetClockScreen::_initUI()
_rowSel = 0;
_nextT = millis();
_SaveTime = 0;
_12hr = NVstore.getUserSettings().clock12hr;
}
void
@ -79,7 +81,13 @@ CSetClockScreen::show()
const BTCDateTime& now = Clock.get();
if(_rowSel == 0) {
// update printable values
working = now;
_working = now;
if(_12hr) {
if(_working.hour() < 12)
_12hr = 1;
else
_12hr = 2;
}
}
if(_SaveTime) {
@ -95,35 +103,50 @@ CSetClockScreen::show()
// date
if(_rowSel==0) {
xPos = 18;
_printMenuText(xPos, yPos, working.dowStr());
_printMenuText(xPos, yPos, _working.dowStr());
xPos = 20;
}
sprintf(str, "%d", working.day());
sprintf(str, "%d", _working.day());
xPos += 20 + 12;
_printMenuText(xPos, yPos, str, _rowSel==1, eRightJustify);
xPos += 4;
_printMenuText(xPos, yPos, working.monthStr(), _rowSel==2);
_printMenuText(xPos, yPos, _working.monthStr(), _rowSel==2);
xPos += 22;
sprintf(str, "%d", working.year());
sprintf(str, "%d", _working.year());
_printMenuText(xPos, yPos, str, _rowSel==3);
// time
yPos = 32;
xPos = 26;
sprintf(str, "%02d", working.hour());
xPos = 8;
int hr = _working.hour();
if(_12hr) {
if(hr == 0)
hr = 12;
if(hr > 12)
hr -= 12;
}
sprintf(str, "%02d", hr);
_printMenuText(xPos, yPos, str, _rowSel==4);
xPos += 16;
_printMenuText(xPos, yPos, ":");
xPos += 8;
sprintf(str, "%02d", working.minute());
sprintf(str, "%02d", _working.minute());
_printMenuText(xPos, yPos, str, _rowSel==5);
xPos += 16;
_printMenuText(xPos, yPos, ":");
sprintf(str, "%02d", working.second());
sprintf(str, "%02d", _working.second());
xPos += 8;
_printMenuText(xPos, yPos, str, _rowSel==6);
xPos += 20;
const char* annuc = "24hr";
switch(_12hr) {
case 1: annuc = "AM"; break;
case 2: annuc = "PM"; break;
}
_printMenuText(xPos, yPos, annuc, _rowSel == 7);
xPos += 28;
if(_rowSel>=1)
_printMenuText(_display.width()-border, yPos, "SET", _rowSel==7, eRightJustify);
_printMenuText(_display.width()-border, yPos, "SET", _rowSel==8, eRightJustify);
// navigation line
xPos = _display.xCentre();
@ -135,7 +158,7 @@ CSetClockScreen::show()
else {
_display.drawFastHLine(0, 52, 128, WHITE);
_printMenuText(xPos, 56, "\033\032 Sel \030\031 Adj", false, eCentreJustify);
if(_rowSel == 7) {
if(_rowSel == 8) {
_printMenuText(xPos, 56, "Save", false, eCentreJustify);
}
else {
@ -159,10 +182,15 @@ CSetClockScreen::keyHandler(uint8_t event)
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop); // exit, return to clock screen
}
else {
if(_rowSel == 7) { // set the RTC!
Clock.set(working);
if(_rowSel == 8) { // set the RTC!
Clock.set(_working);
_SaveTime = millis() + 1500;
}
// always save the 12/24hr selection on any OK
sUserSettings us = NVstore.getUserSettings();
us.clock12hr = _12hr ? 1 : 0;
NVstore.setUserSettings(us);
NVstore.save();
_rowSel = 0;
}
}
@ -173,7 +201,7 @@ CSetClockScreen::keyHandler(uint8_t event)
}
else {
_rowSel--;
WRAPLOWERLIMIT(_rowSel, 1, 7);
WRAPLOWERLIMIT(_rowSel, 1, 8);
}
}
// press RIGHT
@ -183,13 +211,13 @@ CSetClockScreen::keyHandler(uint8_t event)
}
else {
_rowSel++;
WRAPUPPERLIMIT(_rowSel, 7, 1);
WRAPUPPERLIMIT(_rowSel, 8, 1);
}
}
// press UP
if(event & key_Up) {
if(_rowSel == 0) {
_rowSel = 1;
_rowSel = 7;
}
else {
_adjTimeDate(+1);
@ -228,22 +256,37 @@ CSetClockScreen::_adjTimeDate(int dir)
{
switch(_rowSel) {
case 1:
working.adjustDay(dir);
_working.adjustDay(dir);
break;
case 2:
working.adjustMonth(dir);
_working.adjustMonth(dir);
break;
case 3:
working.adjustYear(dir);
_working.adjustYear(dir);
break;
case 4:
working.adjustHour(dir);
_working.adjustHour(dir);
if(_12hr == 1 && _working.hour() >= 12)
_12hr = 2;
if(_12hr == 2 && _working.hour() < 12)
_12hr = 1;
break;
case 5:
working.adjustMinute(dir);
_working.adjustMinute(dir);
break;
case 6:
working.adjustSecond(dir);
_working.adjustSecond(dir);
break;
case 7:
DebugPort.printf("hr1=%d ", _working.hour());
_12hr += dir;
WRAPLIMITS(_12hr, 0, 2);
if(_12hr == 1 && _working.hour() >= 12)
_working.adjustHour12();
if(_12hr == 2 && _working.hour() < 12)
_working.adjustHour12();
DebugPort.printf("hr2=%d ", _working.hour());
DebugPort.printf("_12hr=%d\r\n", _12hr);
break;
}
}

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -33,7 +33,8 @@ class CProtocol;
class CSetClockScreen : public CScreen {
int _rowSel;
unsigned long _nextT;
BTCDateTime working;
BTCDateTime _working;
int _12hr;
unsigned long _SaveTime;
void _adjTimeDate(int dir);

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -20,19 +20,19 @@
*/
#include "128x64OLED.h"
#include "OtherOptionsScreen.h"
#include "TimeoutsScreen.h"
#include "KeyPad.h"
#include "../Utility/NVStorage.h"
#include "fonts/Icons.h"
COtherOptionsScreen::COtherOptionsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
CTimeoutsScreen::CTimeoutsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
{
}
void
COtherOptionsScreen::onSelect()
CTimeoutsScreen::onSelect()
{
CScreenHeader::onSelect();
_rowSel = 0;
@ -43,12 +43,12 @@ COtherOptionsScreen::onSelect()
}
void
COtherOptionsScreen::_initUI()
CTimeoutsScreen::_initUI()
{
}
bool
COtherOptionsScreen::show()
CTimeoutsScreen::show()
{
char msg[16];
@ -92,7 +92,7 @@ COtherOptionsScreen::show()
}
bool
COtherOptionsScreen::animate()
CTimeoutsScreen::animate()
{
if(!CPasswordScreen::_busy()) {
if(_rowSel != 4) {
@ -126,7 +126,7 @@ COtherOptionsScreen::animate()
}
bool
COtherOptionsScreen::keyHandler(uint8_t event)
CTimeoutsScreen::keyHandler(uint8_t event)
{
if(event & keyPressed) {
_repeatCount = 0;
@ -205,7 +205,7 @@ COtherOptionsScreen::keyHandler(uint8_t event)
}
void
COtherOptionsScreen::adjust(int dir)
CTimeoutsScreen::adjust(int dir)
{
switch(_rowSel) {
case 1:

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -29,7 +29,7 @@ class C128x64_OLED;
class CScreenManager;
class COtherOptionsScreen : public CPasswordScreen
class CTimeoutsScreen : public CPasswordScreen
{
int _rowSel;
uint16_t _frameRate;
@ -39,7 +39,7 @@ class COtherOptionsScreen : public CPasswordScreen
int _scrollChar;
void _initUI();
public:
COtherOptionsScreen(C128x64_OLED& display, CScreenManager& mgr);
CTimeoutsScreen(C128x64_OLED& display, CScreenManager& mgr);
bool show();
bool animate();
bool keyHandler(uint8_t event);

View file

@ -1,3 +1,24 @@
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2019 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 "FontTypes.h"
// Font data for Arial 8pt

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -108,6 +108,14 @@ BTCDateTime::adjustHour(int dir)
}
}
void
BTCDateTime::adjustHour12()
{
hh += 12;
if(hh >= 24)
hh -= 24;
}
void
BTCDateTime::adjustMinute(int dir)
{

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -37,6 +37,7 @@ public:
void adjustMonth(int val);
void adjustYear(int dir);
void adjustHour(int dir);
void adjustHour12();
void adjustMinute(int dir);
void adjustSecond(int dir);
BTCDateTime& operator=(const DateTime& rhs);

View file

@ -57,6 +57,7 @@ const char* GPIOout2Names[] = {
const char* GPIOalgNames[] = {
"Disabled",
"Enabled",
"HeatDemand"
};

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -106,40 +106,42 @@ void interpretJsonCommand(char* pLine)
}
else if((strcmp("CyclicOff", it->key) == 0) || (strcmp("ThermostatOvertemp", it->key) == 0)) {
sUserSettings us = NVstore.getUserSettings();
int8_t val = it->value.as<int8_t>();
if(INBOUNDS(val, 0, 10)) {
if(val > 1) val--; // internal uses a 1 offset
us.cyclic.Stop = val;
us.cyclic.Stop = it->value.as<int8_t>();
if(INBOUNDS(us.cyclic.Stop, 0, 10)) {
if(us.cyclic.Stop > 1)
us.cyclic.Stop--; // internal uses a 1 offset
NVstore.setUserSettings(us);
}
NVstore.setUserSettings(us);
}
else if((strcmp("CyclicOn", it->key) == 0) || (strcmp("ThermostatUndertemp", it->key) == 0)) {
sUserSettings us = NVstore.getUserSettings();
int8_t val = it->value.as<int8_t>();
if(INBOUNDS(val, -20, 0)) {
us.cyclic.Start = val;
}
NVstore.setUserSettings(us);
us.cyclic.Start = it->value.as<int8_t>();
if(INBOUNDS(us.cyclic.Start, -20, 0))
NVstore.setUserSettings(us);
}
else if(strcmp("ThermostatMethod", it->key) == 0) {
sUserSettings settings = NVstore.getUserSettings();
uint8_t val = it->value.as<uint8_t>();
if(INBOUNDS(val, 0, 3))
settings.ThermostatMethod = val;
NVstore.setUserSettings(settings);
settings.ThermostatMethod = it->value.as<uint8_t>();
if(INBOUNDS(settings.ThermostatMethod, 0, 3))
NVstore.setUserSettings(settings);
}
else if(strcmp("ThermostatWindow", it->key) == 0) {
sUserSettings settings = NVstore.getUserSettings();
float val = it->value.as<float>();
if(INBOUNDS(val, 0.2f, 10.f))
settings.ThermostatWindow = val;
NVstore.setUserSettings(settings);
settings.ThermostatWindow = it->value.as<float>();
if(INBOUNDS(settings.ThermostatWindow, 0.2f, 10.f))
NVstore.setUserSettings(settings);
}
else if(strcmp("Thermostat", it->key) == 0) {
if(!setThermostatMode(it->value.as<uint8_t>())) { // this request is blocked if OEM controller active
JSONmoderator.reset("ThermoStat");
}
}
else if(strcmp("ExtThermoTmout", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.ExtThermoTimeout = it->value.as<long>();
if(INBOUNDS(us.ExtThermoTimeout, 0, 3600000))
NVstore.setUserSettings(us);
}
else if(strcmp("NVsave", it->key) == 0) {
if(it->value.as<int>() == 8861)
saveNV();
@ -158,6 +160,12 @@ void interpretJsonCommand(char* pLine)
else if(strcmp("Time", it->key) == 0) {
setTime(it->value.as<const char*>());
bTriggerDateTime = true;
}
else if(strcmp("Time12hr", it->key) == 0) {
sUserSettings us = NVstore.getUserSettings();
us.clock12hr = it->value.as<uint8_t>() ? 1 : 0;
NVstore.setUserSettings(us);
NVstore.save();
}
else if(strcmp("PumpPrime", it->key) == 0) {
reqPumpPrime(it->value.as<uint8_t>());
@ -240,6 +248,19 @@ void interpretJsonCommand(char* pLine)
strncpy(info.password, it->value.as<const char*>(), 31);
info.password[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MQoS", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.qos = it->value.as<uint8_t>();
if(INBOUNDS(info.qos, 0, 2)) {
NVstore.setMQTTinfo(info);
}
}
else if(strcmp("MTopic", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.topic, it->value.as<const char*>(), 31);
info.topic[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("UploadSize", it->key) == 0) {
setUploadSize(it->value.as<long>());
@ -279,18 +300,16 @@ void interpretJsonCommand(char* pLine)
}
}
else if(strcmp("PumpCal", it->key) == 0) {
float fCal = it->value.as<float>();
if(INBOUNDS(fCal, 0.001, 1)) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.pumpCal = fCal;
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.pumpCal = it->value.as<float>();
if(INBOUNDS(ht.pumpCal, 0.001, 1)) {
NVstore.setHeaterTuning(ht);
}
}
else if(strcmp("TempOffset", it->key) == 0) {
float fCal = it->value.as<float>();
if(INBOUNDS(fCal, -10.0, +10.0)) {
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.tempOfs = fCal;
sHeaterTuning ht = NVstore.getHeaterTuning();
ht.tempOfs = it->value.as<float>();
if(INBOUNDS(ht.tempOfs, -10.0, +10.0)) {
NVstore.setHeaterTuning(ht);
}
}
@ -334,30 +353,31 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("TempCurrent", tidyTemp, root);
}
bSend |= moderator.addJson("TempDesired", getTemperatureDesired(), root);
bSend |= moderator.addJson("TempMin", getHeaterInfo().getTemperature_Min(), root);
bSend |= moderator.addJson("TempMax", getHeaterInfo().getTemperature_Max(), root);
bSend |= moderator.addJson("TempBody", getHeaterInfo().getTemperature_HeatExchg(), root);
// bSend |= moderator.addJson("RunState", getHeaterInfo().getRunState(), root);
bSend |= moderator.addJson("RunState", getHeaterInfo().getRunStateEx(), root);
bSend |= moderator.addJson("RunString", getHeaterInfo().getRunStateStr(), root); // verbose it up!
bSend |= moderator.addJson("ErrorState", getHeaterInfo().getErrState(), root );
bSend |= moderator.addJson("ErrorString", getHeaterInfo().getErrStateStrEx(), root); // verbose it up!
bSend |= moderator.addJson("Thermostat", getThermostatModeActive(), root );
bSend |= moderator.addJson("PumpFixed", getHeaterInfo().getPump_Fixed(), root );
bSend |= moderator.addJson("PumpMin", getHeaterInfo().getPump_Min(), root );
bSend |= moderator.addJson("PumpMax", getHeaterInfo().getPump_Max(), root );
bSend |= moderator.addJson("PumpActual", getHeaterInfo().getPump_Actual(), root );
bSend |= moderator.addJson("FanMin", getHeaterInfo().getFan_Min(), root );
bSend |= moderator.addJson("FanMax", getHeaterInfo().getFan_Max(), root );
bSend |= moderator.addJson("FanRPM", getFanSpeed(), root );
bSend |= moderator.addJson("FanVoltage", getHeaterInfo().getFan_Voltage(), root );
bSend |= moderator.addJson("FanSensor", getHeaterInfo().getFan_Sensor(), root );
bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(false), root );
bSend |= moderator.addJson("SystemVoltage", getHeaterInfo().getSystemVoltage(), root );
bSend |= moderator.addJson("GlowVoltage", getGlowVolts(), root );
bSend |= moderator.addJson("GlowCurrent", getGlowCurrent(), root );
bSend |= moderator.addJson("BluewireStat", getBlueWireStatStr(), root );
bSend |= moderator.addJson("TempMode", NVstore.getUserSettings().degF, root);
if(!NVstore.getUserSettings().NoHeater) {
bSend |= moderator.addJson("TempMin", getHeaterInfo().getTemperature_Min(), root);
bSend |= moderator.addJson("TempMax", getHeaterInfo().getTemperature_Max(), root);
bSend |= moderator.addJson("TempBody", getHeaterInfo().getTemperature_HeatExchg(), root);
bSend |= moderator.addJson("RunState", getHeaterInfo().getRunStateEx(), root);
bSend |= moderator.addJson("RunString", getHeaterInfo().getRunStateStr(), root); // verbose it up!
bSend |= moderator.addJson("ErrorState", getHeaterInfo().getErrState(), root );
bSend |= moderator.addJson("ErrorString", getHeaterInfo().getErrStateStrEx(), root); // verbose it up!
bSend |= moderator.addJson("Thermostat", getThermostatModeActive(), root );
bSend |= moderator.addJson("PumpFixed", getHeaterInfo().getPump_Fixed(), root );
bSend |= moderator.addJson("PumpMin", getHeaterInfo().getPump_Min(), root );
bSend |= moderator.addJson("PumpMax", getHeaterInfo().getPump_Max(), root );
bSend |= moderator.addJson("PumpActual", getHeaterInfo().getPump_Actual(), root );
bSend |= moderator.addJson("FanMin", getHeaterInfo().getFan_Min(), root );
bSend |= moderator.addJson("FanMax", getHeaterInfo().getFan_Max(), root );
bSend |= moderator.addJson("FanRPM", getFanSpeed(), root );
bSend |= moderator.addJson("FanVoltage", getHeaterInfo().getFan_Voltage(), root );
bSend |= moderator.addJson("FanSensor", getHeaterInfo().getFan_Sensor(), root );
bSend |= moderator.addJson("InputVoltage", getBatteryVoltage(false), root );
bSend |= moderator.addJson("SystemVoltage", getHeaterInfo().getSystemVoltage(), root );
bSend |= moderator.addJson("GlowVoltage", getGlowVolts(), root );
bSend |= moderator.addJson("GlowCurrent", getGlowCurrent(), root );
bSend |= moderator.addJson("BluewireStat", getBlueWireStatStr(), root );
}
if(bSend) {
root.printTo(opStr, len);
@ -373,19 +393,21 @@ bool makeJSONStringEx(CModerator& moderator, char* opStr, int len)
bool bSend = false; // reset should send flag
bSend |= moderator.addJson("ThermostatMethod", NVstore.getUserSettings().ThermostatMethod, root);
bSend |= moderator.addJson("ThermostatWindow", NVstore.getUserSettings().ThermostatWindow, root);
int stop = NVstore.getUserSettings().cyclic.Stop;
if(stop) stop++; // deliver effective threshold, not internal working value
bSend |= moderator.addJson("ThermostatOvertemp", stop, root);
bSend |= moderator.addJson("ThermostatUndertemp", NVstore.getUserSettings().cyclic.Start, root);
bSend |= moderator.addJson("CyclicTemp", getDemandDegC(), root); // actual pivot point for cyclic mode
bSend |= moderator.addJson("CyclicOff", stop, root); // threshold of over temp for cyclic mode
bSend |= moderator.addJson("CyclicOn", NVstore.getUserSettings().cyclic.Start, root); // threshold of under temp for cyclic mode
bSend |= moderator.addJson("PumpCount", RTC_Store.getFuelGauge(), root); // running count of pump strokes
bSend |= moderator.addJson("PumpCal", NVstore.getHeaterTuning().pumpCal, root); // mL/stroke
if(!NVstore.getUserSettings().NoHeater) {
bSend |= moderator.addJson("ThermostatMethod", NVstore.getUserSettings().ThermostatMethod, root);
bSend |= moderator.addJson("ThermostatWindow", NVstore.getUserSettings().ThermostatWindow, root);
int stop = NVstore.getUserSettings().cyclic.Stop;
if(stop) stop++; // deliver effective threshold, not internal working value
bSend |= moderator.addJson("ThermostatOvertemp", stop, root);
bSend |= moderator.addJson("ThermostatUndertemp", NVstore.getUserSettings().cyclic.Start, root);
bSend |= moderator.addJson("CyclicTemp", getDemandDegC(), root); // actual pivot point for cyclic mode
bSend |= moderator.addJson("CyclicOff", stop, root); // threshold of over temp for cyclic mode
bSend |= moderator.addJson("CyclicOn", NVstore.getUserSettings().cyclic.Start, root); // threshold of under temp for cyclic mode
bSend |= moderator.addJson("PumpCount", RTC_Store.getFuelGauge(), root); // running count of pump strokes
bSend |= moderator.addJson("PumpCal", NVstore.getHeaterTuning().pumpCal, root); // mL/stroke
bSend |= moderator.addJson("LowVoltCutout", NVstore.getHeaterTuning().getLVC(), root); // low volatge cutout
}
bSend |= moderator.addJson("TempOffset", NVstore.getHeaterTuning().tempOfs, root); // degC offset
bSend |= moderator.addJson("LowVoltCutout", NVstore.getHeaterTuning().getLVC(), root); // low volatge cutout
if(bSend) {
root.printTo(opStr, len);
@ -437,6 +459,7 @@ bool makeJSONStringGPIO(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("GPmodeOut1", GPIOout1Names[info.out1Mode], root);
bSend |= moderator.addJson("GPmodeOut2", GPIOout2Names[info.out2Mode], root);
bSend |= moderator.addJson("GPmodeAnlg", GPIOalgNames[info.algMode], root);
bSend |= moderator.addJson("ExtThermoTmout", (uint32_t)NVstore.getUserSettings().ExtThermoTimeout, root);
if(bSend) {
root.printTo(opStr, len);
@ -454,10 +477,13 @@ bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len)
sMQTTparams info = NVstore.getMQTTinfo();
bSend |= moderator.addJson("MEn", info.enabled, root);
bSend |= moderator.addJson("MPort", info.port, root);
bSend |= moderator.addJson("MOnline", isMQTTconnected(), root);
bSend |= moderator.addJson("MHost", info.host, root);
bSend |= moderator.addJson("MPort", info.port, root);
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.topic, root);
if(bSend) {
root.printTo(opStr, len);
@ -481,13 +507,16 @@ bool makeJSONStringSysInfo(CModerator& moderator, char* opStr, int len)
char str[32];
sprintf(str, "%d/%d/%d %02d:%02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second());
bSend |= moderator.addJson("DateTime", str, root);
bSend |= moderator.addJson("Time12hr", NVstore.getUserSettings().clock12hr, root);
if(bTriggerSysParams) {
bSend |= moderator.addJson("SysUpTime", sysUptime(), root);
bSend |= moderator.addJson("SysVer", getVersionStr(), root);
bSend |= moderator.addJson("SysDate", getVersionDate(), root);
bSend |= moderator.addJson("SysFreeMem", ESP.getFreeHeap(), root);
bSend |= moderator.addJson("SysRunTime", pHourMeter->getRunTime(), root);
bSend |= moderator.addJson("SysGlowTime", pHourMeter->getGlowTime(), root);
if(!NVstore.getUserSettings().NoHeater) {
bSend |= moderator.addJson("SysRunTime", pHourMeter->getRunTime(), root);
bSend |= moderator.addJson("SysGlowTime", pHourMeter->getGlowTime(), root);
}
}
if(bSend) {
root.printTo(opStr, len);

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2018 James Clark
*
* This program is free software: you can redistribute it and/or modify

View file

@ -1,6 +1,24 @@
//
//
//
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2019 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 "../cfg/BTCConfig.h"

View file

@ -1,4 +1,25 @@
// ABMqtt.h
/*
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2019 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 _ABMQTT_h
#define _ABMQTT_h

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 James Clark
* Copyright (C) 2019 Ray Jones, James Clark
*
* 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
@ -35,7 +35,6 @@
bool CheckFirmwareCRC(int filesize);
bool CheckFirmwareCRC0(int filesize);
void onSuccess();
void onWebProgress(size_t progress, size_t total);
@ -118,7 +117,7 @@ void DoOTA()
FOTAtime = millis() + 3600000; // 1 hour
if ((WiFi.status() == WL_CONNECTED)) { // bug workaround in FOTA where execHTTPcheck does not return false in this condition
FOTA.onProgress(onWebProgress); // important - keeps watchdog fed
FOTA.onComplete(CheckFirmwareCRC0); // upload complete, but not yet verified
FOTA.onComplete(CheckFirmwareCRC); // upload complete, but not yet verified
FOTA.onSuccess(onSuccess);
#ifdef TESTFOTA
FOTA.checkURL = "http://www.mrjones.id.au/afterburner/fota/fotatest.json";
@ -169,44 +168,9 @@ void checkFOTA()
const int CRCbufsize = 1024;
uint8_t CRCReadBuff[CRCbufsize];
/*
bool CheckFirmwareCRC(int filesize)
{
const esp_partition_t* pUsePartition = esp_ota_get_next_update_partition(NULL);
if(NULL == pUsePartition) {
DebugPort.println("CheckCRC: FAILED - bad partition?");
return false;
}
int size = (filesize >> 2) << 2; // mod 4
if((filesize - size) != 2) {
// we expect 2 extra bytes where the custom CRC is added
// all normal applications without CRC are multiples of 4
DebugPort.println("CheckCRC: FAILED - bad source file size");
return false;
}
CModBusCRC16 CRCengine;
int processed = 0;
while(processed < size) {
int toRead = size - processed;
if(toRead > CRCbufsize)
toRead = CRCbufsize;
ESP.flashRead(pUsePartition->address + processed, (uint32_t*)CRCReadBuff, toRead);
CRCengine.process(toRead, CRCReadBuff);
processed += toRead;
}
ESP.flashRead(pUsePartition->address + processed, (uint32_t*)CRCReadBuff, 4);
uint32_t fileCRC = CRCReadBuff[0] + (CRCReadBuff[1]<<8);
DebugPort.printf("Upload CRC TEST: calcCRC= %04X, fileCRC = %08X\r\n", CRCengine.get(), fileCRC);
return fileCRC == CRCengine.get();
}*/
// CRC of everything, including our extra CRC bytes should return ZERO :-)
bool CheckFirmwareCRC0(int filesize)
bool CheckFirmwareCRC(int filesize)
{
const esp_partition_t* pUsePartition = esp_ota_get_next_update_partition(NULL);
if(NULL == pUsePartition) {

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 James Clark
* Copyright (C) 2019 Ray Jones, James Clark
*
* 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
@ -24,7 +24,6 @@
void initOTA();
void DoOTA();
//bool CheckFirmwareCRC(int size);
bool CheckFirmwareCRC0(int size);
bool CheckFirmwareCRC(int size);
#endif

View file

@ -2,7 +2,7 @@
* This file is part of the "bluetoothheater" distribution
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
*
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
* Copyright (C) 2019 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
@ -148,8 +148,8 @@ sBrowserUpload::end(HTTPUpload& upload)
else {
// completion of firmware update
// check the added CRC we genertaed matches
// - this guards against malicious, badly formatted bin file attempts.
if(!CheckFirmwareCRC0(SrcFile.size)) {
// - this helps guard against malicious, badly formatted bin file attempts.
if(!CheckFirmwareCRC(SrcFile.size)) {
Update.abort();
retval = -4;
}