before update 0.7.3

This commit is contained in:
Robert van den Breemen 2021-01-31 23:43:52 +01:00
parent 5460c2857e
commit cb0840aaeb
15 changed files with 285 additions and 137 deletions

View File

@ -13,6 +13,7 @@
"vector": "cpp",
"string": "cpp",
"fstream": "cpp",
"cstring": "cpp"
"cstring": "cpp",
"regex": "cpp"
}
}

View File

@ -77,6 +77,7 @@ void setupFSexplorer() // Funktionsaufruf "LittleFS();" muss im Setup eingebu
httpServer.on("/upload", HTTP_POST, []() {}, handleFileUpload);
httpServer.on("/ReBoot", reBootESP);
httpServer.on("/update", updateFirmware);
httpServer.on("/upgradepic", upgradePIC);
httpServer.onNotFound([]()
{
if (Verbose) DebugTf("in 'onNotFound()'!! [%s] => \r\n", String(httpServer.uri()).c_str());
@ -268,21 +269,28 @@ bool freeSpace(uint16_t const& printsize)
} // freeSpace()
//=====================================================================================
void upgradePIC()
{
DebugTln(F("Redirect to upgrade PIC .."));
upgradenow();
doRedirect("Upgrade OTGW PIC ", 120, "/FSexplorer", false);
} // upgradePIC()
//=====================================================================================
void updateFirmware()
{
DebugTln(F("Redirect to updateIndex .."));
doRedirect("wait ... ", 1, "/updateIndex", false);
} // updateFirmware()
//=====================================================================================
void reBootESP()
{
DebugTln(F("Redirect and ReBoot .."));
doRedirect("Reboot OTGW firmware ..", 60, "/", true);
doRedirect("Reboot OTGW firmware ..", 60, "/", true);
} // reBootESP()
//=====================================================================================
@ -295,18 +303,18 @@ void doRedirect(String msg, int wait, const char* URL, bool reboot)
"<style type='text/css'>"
"body {background-color: lightblue;}"
"</style>"
"<title>Redirect to Main Program</title>"
"<title>Redirect to ...</title>"
"</head>"
"<body><h1>FSexplorer</h1>"
"<h3>"+msg+"</h3>"
"<br><div style='width: 500px; position: relative; font-size: 25px;'>"
" <div style='float: left;'>Redirect over &nbsp;</div>"
" <div style='float: left;'>Redirect in &nbsp;</div>"
" <div style='float: left;' id='counter'>"+String(wait)+"</div>"
" <div style='float: left;'>&nbsp; seconden ...</div>"
" <div style='float: left;'>&nbsp; seconds ...</div>"
" <div style='float: right;'>&nbsp;</div>"
"</div>"
"<!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->"
"<br><br><hr>If you are not redirected automatically, click this <a href='/'>Main Program</a>."
"<br><br><hr>Wait for the redirect. In case you are not redirected automatically, then click this <a href='/'>link to continue</a>."
" <script>"
" setInterval(function() {"
" var div = document.querySelector('#counter');"
@ -321,6 +329,6 @@ void doRedirect(String msg, int wait, const char* URL, bool reboot)
DebugTln(msg);
httpServer.send(200, "text/html", redirectHTML);
if (reboot) doRestart("Reboot after OTA flash");
if (reboot) doRestart("Reboot after upgrade");
} // doRedirect()

View File

@ -33,6 +33,7 @@
//===========================================================================================
void startMQTT()
{
if (!settingMQTTenable) return;
stateMQTT = MQTT_STATE_INIT;
handleMQTT(); //initialize the MQTT statemachine
// handleMQTT(); //then try to connect to MQTT
@ -60,7 +61,8 @@ void handleMQTTcallback(char* topic, byte* payload, unsigned int length) {
//===========================================================================================
void handleMQTT()
{
{
if (!settingMQTTenable) return;
DECLARE_TIMER_MIN(timerMQTTwaitforconnect, 10, CATCH_UP_MISSED_TICKS); // 10 minutes
DECLARE_TIMER_SEC(timerMQTTwaitforretry, 3, CATCH_UP_MISSED_TICKS); // 3 seconden backoff
@ -202,6 +204,7 @@ void handleMQTT()
bool MQTT_connected()
{
if (!settingMQTTenable) return false;
return MQTTclient.connected();
}
@ -221,6 +224,7 @@ void sendMQTTData(const String item, const String json)
void sendMQTTData(const char* item, const char *json)
{
/*
* The maximum message size, including header, is 128 bytes by default.
* This is configurable via MQTT_MAX_PACKET_SIZE in PubSubClient.h.
@ -230,7 +234,7 @@ void sendMQTTData(const char* item, const char *json)
* MQTT_MAX_PACKET_SIZE dus aanpassen!!!
*/
//===========================================================================================
if (!settingMQTTenable) return;
if (!MQTTclient.connected() || !isValidIP(MQTTbrokerIP)) return;
// DebugTf("Sending data to MQTT server [%s]:[%d]\r\n", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
char topic[100];
@ -244,6 +248,7 @@ void sendMQTTData(const char* item, const char *json)
//===========================================================================================
void sendMQTT(const char* topic, const char *json, const int8_t len)
{
if (!settingMQTTenable) return;
if (!MQTTclient.connected() || !isValidIP(MQTTbrokerIP)) return;
// DebugTf("Sending data to MQTT server [%s]:[%d] ", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
//DebugTf("Sending MQTT: TopicId [%s] Message [%s]\r\n", topic, json);
@ -268,6 +273,7 @@ bool splitString(String sIn, char del, String& cKey, String& cVal)
//===========================================================================================
void doAutoConfigure()
{
if (!settingMQTTenable) return;
const char* cfgFilename = "/mqttha.cfg";
String sTopic="";
String sMsg="";
@ -298,6 +304,7 @@ void doAutoConfigure()
}
bool getMQTTconnectstatus(){
if (!settingMQTTenable) return false;
return MQTTclient.connected();
}

View File

@ -50,13 +50,97 @@ OpenthermData OTdata;
//===================[ Reset OTGW ]===============================
void resetOTGW() {
//lower the right pin for just 500ms and the OTGW is reset
//lower the right pin for just 100ms and the OTGW is reset
DebugTln("OTGW PIC reset");
pinMode(OTGW_RESET, OUTPUT);
digitalWrite(OTGW_RESET, LOW);
delay(200);
delay(100);
digitalWrite(OTGW_RESET, HIGH);
pinMode(OTGW_RESET, INPUT_PULLUP);
}
//===================[ getpicfwversion ]===========================
String getpicfwversion(){
String _ret="";
#define BANNER "OpenTherm Gateway"
String line = getCommand("PR=A");
int p = line.indexOf(BANNER);
if (p >= 0) {
p += sizeof(BANNER);
_ret = line.substring(p);
} else _ret ="not found";
DebugTf("Current firmware version: %s\n", CSTR(_ret));
_ret.trim();
return _ret;
}
//===================[ OTGW Command & Response ]===================
String getCommand(const String sCmd){
return getCommand(CSTR(sCmd), sCmd.length());
}
String getCommand(const char* sCmd, int len){
// Example:
//
DebugTf("OTGW Send Cmd [%s]=[%s]\r\n", sCmd);
while(Serial.availableForWrite() < len+2){
feedWatchDog();
}
Serial.write(sCmd, len);
Serial.write("\r\n");
Serial.flush();
//wait for response
while(!Serial.available()) {
feedWatchDog();
}
//fetch a line
char line[80];
char _cmd[2];
char *_ret;
memcpy(_cmd, sCmd, 2);
DebugTf("Command: [%s]\r\n", _cmd);
size_t l = Serial.readBytesUntil('\n', line, sizeof(line)-1);
line[l]='\0';
DebugTf("Line returned: [%s]\r\n", line);
// Responses: When a serial command is accepted by the gateway, it responds with the two letters of the command code, a colon, and the interpreted data value.
if (prefix(_cmd, line)){
//Command: "TT=19.125"
// Response: "TT: 19.13"
// [XX:response string]
memcpy(line, line+3, sizeof(line)-3);
} else if (prefix("NG", line)){
strlcpy(line, "NG - No Good. The command code is unknown.", sizeof(line));
} else if (prefix("SE", line)){
strlcpy(line, "SE - Syntax Error. The command contained an unexpected character or was incomplete.", sizeof(line));
} else if (prefix("BV", line)){
strlcpy(line, "BV - Bad Value. The command contained a data value that is not allowed.", sizeof(line));
} else if (prefix("OR", line)){
strlcpy(line, "OR - Out of Range. A number was specified outside of the allowed range.", sizeof(line));
} else if (prefix("NS", line)){
strlcpy(line, "NS - No Space. The alternative Data-ID could not be added because the table is full.", sizeof(line));
} else if (prefix("NF", line)){
strlcpy(line, "NF - Not Found. The specified alternative Data-ID could not be removed because it does not exist in the table.", sizeof(line));
} else if (prefix("OE", line)){
strlcpy(line, "OE - Overrun Error. The processor was busy and failed to process all received characters.", sizeof(line));
}
return line;
}
//===================[ OTGW PS=1 Command ]===============================
void getOTGW_PS_1(){
DebugTln("PS=1");
Serial.write("PS=1\r\n");
Serial.flush();
while(!Serial.available()) {
feedWatchDog();
}
String line = Serial.readStringUntil('\n');
line.trim(); //remove LF and CR (and whitespaces)
DebugTln(line);
DebugTln("PS=0");
Serial.write("PS=0\r\n");
Serial.flush();
}
//===================[ OTGW PS=1 Command ]===============================
//===================[ Watchdog OTGW ]===============================
String initWatchDog() {
@ -556,23 +640,7 @@ uint16_t print_daytime()
sendMQTTData(_topic, itoa(OTdata.valueLB, _msg, 10));
return _value;
}
//===================[ OTGW PS=1 Command ]===============================
void getOTGW_PS_1(){
DebugTln("PS=1");
Serial.write("PS=1\r\n");
Serial.flush();
delay(100);
while(Serial.available() > 0)
{
String strBuffer = Serial.readStringUntil('\n');
strBuffer.trim(); //remove LF and CR (and whitespaces)
DebugTln(strBuffer);
}
DebugTln("PS=0");
Serial.write("PS=0\r\n");
Serial.flush();
}
//===================[ OTGW PS=1 Command ]===============================
//===================[ Send buffer to OTGW ]=============================
@ -802,11 +870,11 @@ void handleOTGW()
{ //on newline, do something...
sWrite[bytes_write] = 0;
DebugTf("Net2Ser: Sending to OTGW: [%s] (%d)\r\n", sWrite, bytes_write);
//check for reset command
if (stricmp(sWrite, "GW=R")==0){
//detect [GW=R], then reset the gateway the gpio way
DebugTln("Detected: GW=R. Reset gateway command executed.");
resetOTGW();
delay(100); //delay 100ms
}
bytes_write = 0; //start next line
} else if (outByte == '\r')

View File

@ -27,6 +27,8 @@
#define CSTR(x) x.c_str()
#define CBOOLEAN(x) (x?"True":"False")
#define CONOFF(x) (x?"On":"Off")
#define CBINARY(x) (x?"1":"0")
#define EVALBOOLEAN(x) (stricmp(x,"true")==0||stricmp(x,"on")==0||stricmp(x,"1")==0)
//Global variables
WiFiClient wifiClient;
@ -34,22 +36,27 @@ bool Verbose = false;
char cMsg[CMSG_SIZE];
char fChar[10];
String lastReset = "";
uint32_t upTimeSeconds=0;
uint32_t rebootCount=0;
Timezone CET;
uint64_t upTimeSeconds = 0;
uint32_t rebootCount = 0;
Timezone myTZ;
const char *weekDayName[] { "Unknown", "Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Unknown" };
const char *flashMode[] { "QIO", "QOUT", "DIO", "DOUT", "Unknown" };
//Information on OTGW
String sPICfwversion = "";
//All things that are settings
String settingHostname = _HOSTNAME;
//MQTT settings
bool settingMQTTenable = true;
bool settingMQTTsecure = false;
String settingMQTTbroker= "192.168.88.254";
int16_t settingMQTTbrokerPort = 1883;
String settingMQTTuser = "";
String settingMQTTpasswd = "";
String settingMQTTtopTopic = "OTGW";
String settingTimezone = "NL"; //Default
// That's all folks...

View File

@ -10,18 +10,12 @@
*/
/*
* How to install the OTGW on your nodeMCU
*
* Make sure you have all required library's installed:
* - ezTime - https://github.com/ropg/ezTime
* - TelnetStream - https://github.com/jandrassy/TelnetStream/commit/1294a9ee5cc9b1f7e51005091e351d60c8cddecf
* - ArduinoJson - https://arduinojson.org/
* All the library's can be installed using the library manager.
*
* How to upload to your SPIFF?
* Just install the SPIFF upload plugin (https://github.com/esp8266/arduino-esp8266fs-plugin)
* and upload it to your SPIFF after first flashing the device.
* How to install the OTGW on your nodeMCU:
* Read this: https://github.com/rvdbreemen/OTGW-firmware/wiki/How-to-compile-OTGW-firmware-yourself
*
* How to upload to your LittleFS?
* Read this: https://github.com/rvdbreemen/OTGW-firmware/wiki/Upload-files-to-LittleFS-(filesystem)
*
* How to compile this firmware?
* - NodeMCU v1.0
* - Flashsize (4MB - FS:2MB - OTA ~1019KB)
@ -41,6 +35,9 @@ void setup()
{
rebootCount = updateRebootCount();
Serial.println(F("\r\n[OTGW firmware - Nodoshop version]\r\n"));
Serial.printf("Booting....[%s]\r\n\r\n", String(_FW_VERSION).c_str());
Serial.begin(9600, SERIAL_8N1);
while (!Serial) {} //Wait for OK
@ -48,6 +45,7 @@ void setup()
randomSeed(RANDOM_REG32); //This is 8266 HWRNG used to seed the Random PRNG: Read more: https://config9.com/arduino/getting-a-truly-random-number-in-arduino/
lastReset = ESP.getResetReason();
Serial.printf("Last reset reason: [%s]\r\n", ESP.getResetReason().c_str());
//setup the status LED
pinMode(LED_BUILTIN, OUTPUT);
@ -55,9 +53,9 @@ void setup()
//start the debug port 23
startTelnet();
Serial.println(F("\r\n[OTGW firmware - Nodoshop version]\r\n"));
Serial.printf("Booting....[%s]\r\n\r\n", String(_FW_VERSION).c_str());
Serial.print("Use 'telnet ");
Serial.print(WiFi.localIP());
Serial.println("' for debugging");
//================ LittleFS ===========================================
if (LittleFS.begin())
@ -85,19 +83,27 @@ void setup()
startMQTT();
// Initialisation ezTime
setDebug(INFO);
waitForSync();
CET.setLocation(F("Europe/Amsterdam"));
CET.setDefault();
setDebug(INFO);
updateNTP(); //force NTP sync
waitForSync(60); //wait until valid time
setInterval(1800); //every 30minutes NTP sync
//no TZ cached, then try to GeoIP locate your TZ, otherwise fallback to default
if (!myTZ.setCache(0)) {
//ezTime will try to determine your location based on your IP using GeoIP
if (myTZ.setLocation()) {
settingTimezone = myTZ.getTimezoneName();
DebugTf("GeoIP located your timezone to be: %s\n", CSTR(settingTimezone));
} else {
if (myTZ.setLocation(settingTimezone)){
DebugTf("Timezone set to (using default): %s\n", CSTR(settingTimezone));
settingTimezone = myTZ.getTimezoneName();
} else DebugTln(errorString());
}
}
myTZ.setDefault();
Serial.println("UTC time: "+ UTC.dateTime());
Serial.println("CET time: "+ CET.dateTime());
Serial.printf("Last reset reason: [%s]\r\n", ESP.getResetReason().c_str());
Serial.print("Gebruik 'telnet ");
Serial.print(WiFi.localIP());
Serial.println("' voor verdere debugging");
DebugTln("UTC time : "+ UTC.dateTime());
DebugTln("local time: "+ myTZ.dateTime());
//================ Start HTTP Server ================================
setupFSexplorer();
@ -126,11 +132,14 @@ void setup()
sprintf(cMsg, "%03d.%03d.%d.%d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]);
Serial.printf("\nAssigned IP[%s]\r\n", cMsg);
// Setup the OTGW PIC
resetOTGW(); // reset the OTGW pic
initWatchDog(); // setup the WatchDog
startOTGWstream(); // start port 1023
sPICfwversion = getCommand("PR=A"); // fetch the firmware version
DebugTf("OTGW PIC firmware version = [%s]\r\n", CSTR(sPICfwversion));
Serial.printf("Reboot count = [%d]\r\n", rebootCount);
DebugTf("Reboot count = [%d]\r\n", rebootCount);
Serial.println(F("Setup finished!"));
}

View File

@ -26,7 +26,7 @@
#define BANNER "OpenTherm Gateway"
extern char fwversion[];
char fwversion[16];
#define STX 0x0F
#define ETX 0x04
@ -67,7 +67,7 @@ enum {
ERROR_MISMATCHES
};
static uint8_t fwstate = FWSTATE_IDLE;
static byte fwstate = FWSTATE_IDLE;
struct fwupdatedata {
unsigned char buffer[80];
@ -82,7 +82,7 @@ struct fwupdatedata {
struct xferdata {
unsigned short addr;
uint8_t size, mask;
byte size, mask;
};
Ticker timeout;
@ -165,7 +165,7 @@ int eeprom(const char *version, struct xferdata *xfer) {
int transfer(const char *ver1, const char *ver2) {
struct xferdata xfer1[XFER_MAX_ID] = {}, xfer2[XFER_MAX_ID] = {};
int last, i, j, mask;
uint8_t value;
byte value;
last = min(eeprom(ver1, xfer1), eeprom(ver2, xfer2));
for (i = 0; i <= last; i++) {
@ -280,7 +280,7 @@ bool readhex(unsigned short *codemem, unsigned char *datamem, unsigned short *co
void fwupgradefail();
void fwupgradecmd(const unsigned char *cmd, int len) {
uint8_t i, ch, sum = 0;
byte i, ch, sum = 0;
Serial.write(STX);
for (i = 0; i <= len; i++) {
@ -295,7 +295,7 @@ void fwupgradecmd(const unsigned char *cmd, int len) {
}
bool erasecode(short addr) {
uint8_t fwcommand[] = {CMD_ERASEPROG, 1, 0, 0};
byte fwcommand[] = {CMD_ERASEPROG, 1, 0, 0};
bool rc = false;
short i;
for (i = 0; i < 32; i++) {
@ -313,7 +313,7 @@ bool erasecode(short addr) {
}
void loadcode(short addr, const unsigned short *code, short len = 32) {
uint8_t i, fwcommand[4 + 2 * len];
byte i, fwcommand[4 + 2 * len];
unsigned short *data = (unsigned short *)fwcommand + 2;
fwcommand[0] = CMD_WRITEPROG;
fwcommand[1] = len >> 2;
@ -326,7 +326,7 @@ void loadcode(short addr, const unsigned short *code, short len = 32) {
}
void readcode(short addr, short len = 32) {
uint8_t fwcommand[] = {CMD_READPROG, 32, 0, 0};
byte fwcommand[] = {CMD_READPROG, 32, 0, 0};
fwcommand[1] = len;
fwcommand[2] = addr & 0xff;
fwcommand[3] = addr >> 8;
@ -347,8 +347,8 @@ bool verifycode(const unsigned short *code, const unsigned short *data, short le
}
void loaddata(short addr) {
uint8_t i;
uint8_t fwcommand[68] = {CMD_WRITEDATA, 64};
byte i;
byte fwcommand[68] = {CMD_WRITEDATA, 64};
fwcommand[2] = addr & 0xff;
fwcommand[3] = addr >> 8;
for (i = 0; i < 64; i++) {
@ -358,12 +358,12 @@ void loaddata(short addr) {
}
void readdata(short addr) {
uint8_t fwcommand[] = {CMD_READDATA, 64, 0, 0};
byte fwcommand[] = {CMD_READDATA, 64, 0, 0};
fwcommand[2] = addr & 0xff;
fwupgradecmd(fwcommand, sizeof(fwcommand));
}
bool verifydata(short pc, const uint8_t *data, short len = 64) {
bool verifydata(short pc, const byte *data, short len = 64) {
short i;
bool rc = true;
@ -394,11 +394,11 @@ void fwupgradestop(int result) {
}
}
void fwupgradestep(const uint8_t *packet = nullptr, int len = 0) {
void fwupgradestep(const byte *packet = nullptr, int len = 0) {
const unsigned short *data = (const unsigned short *)packet;
static short pc;
static uint8_t lastcmd = 0;
uint8_t cmd = 0;
static byte lastcmd = 0;
byte cmd = 0;
if (packet == nullptr || len == 0) {
cmd = lastcmd;
@ -416,7 +416,7 @@ void fwupgradestep(const uint8_t *packet = nullptr, int len = 0) {
break;
case FWSTATE_RSET:
if (packet != nullptr) {
uint8_t fwcommand[] = {CMD_VERSION, 3};
byte fwcommand[] = {CMD_VERSION, 3};
fwupgradecmd(fwcommand, sizeof(fwcommand));
fwstate = FWSTATE_VERSION;
} else if (++fwupd->retries > 5) {
@ -450,7 +450,7 @@ void fwupgradestep(const uint8_t *packet = nullptr, int len = 0) {
} else if (++fwupd->retries > 10) {
fwupgradestop(ERROR_RETRIES);
} else {
uint8_t fwcommand[] = {CMD_VERSION, 3};
byte fwcommand[] = {CMD_VERSION, 3};
fwupgradecmd(fwcommand, sizeof(fwcommand));
fwstate = FWSTATE_VERSION;
}
@ -535,7 +535,7 @@ void fwupgradestep(const uint8_t *packet = nullptr, int len = 0) {
// digitalWrite(LED2, LOW);
loaddata(pc);
} else {
uint8_t fwcommand[] = {CMD_RESET, 0};
byte fwcommand[] = {CMD_RESET, 0};
fwupgradecmd(fwcommand, sizeof(fwcommand));
fwupgradestop(ERROR_NONE);
}
@ -594,7 +594,7 @@ void fwupgradestart() {
}
void fwupgradefail() {
// Send a non-DLE uint8_t in case the PIC is waiting for a uint8_t following DLE
// Send a non-DLE byte in case the PIC is waiting for a byte following DLE
Serial.write(STX);
fwupgradestep();
}
@ -602,7 +602,7 @@ void fwupgradefail() {
void upgradeevent() {
static unsigned int pressed = 0;
static bool dle = false;
static uint8_t len, sum;
static byte len, sum;
int ch;
if (fwstate == FWSTATE_IDLE) {
@ -645,18 +645,22 @@ void upgradeevent() {
}
}
void upgradenow() {
static bool dle = false;
static uint8_t len, sum;
int ch;
// So kickoff the upgrade
if (fwstate == FWSTATE_IDLE) {
blink(0);
digitalWrite(LED1, LOW);
fwupgradestart();
}
// So a PIC reset just happend, so we should get a STX next, if all goes well that is.
// Only start, when not already programming the flash.
if (fwstate != FWSTATE_IDLE) {
DebugTln("Error: PIC already in programming in progress.");
return;
}
// Start the upgrade now...
blink(0);
digitalWrite(LED1, LOW);
fwupgradestart();
// Ready to program, the PIC reset just happend, so we should get a STX next, if all goes well that is.
while (fwstate != FWSTATE_IDLE) {
// keep feeding the dog from time to time...
feedWatchDog();
@ -684,6 +688,8 @@ void upgradenow() {
}
}
}
// When you are done, then reset the PIC one more time, to capture the actual fwversion of the OTGW
resetOTGW();
}

View File

@ -114,19 +114,24 @@
<input type='submit' class='button' name='SUBMIT' value='Exit FSexplorer'>
</form>
</span>
</div>
<div style='width: 40%'>
<span>
<form style='float: left;' action='/ReBoot'>
<input type='submit' class='button' name='SUBMIT' value='ReBoot'>
</form>
</div>
<div style='width: 40%'>
<span>
<form style='float right;' action="/LittleFSformat" method="POST">
<input id='FormatLittleFS' type='submit' class='button' name='SUBMIT' value='Format SPIFFS' DISABLED/>
<input id='FormatLittleFS' type='submit' class='button' name='SUBMIT' value='Format LittleFS' DISABLED/>
</form>
</span>
</div>
<div style='width: 40%'>
<span>
<form style='float right;' action="/upgradepic" method="POST">
<input id='UpgradePIC' type='submit' class='button' name='SUBMIT' value='Upgrade OTGW PIC' ENABLED/>
</form>
</span>
</div>

View File

@ -290,8 +290,17 @@
var sInput = document.createElement("input");
//----sInput.setAttribute("id", "setFld_"+data[i].name);
sInput.setAttribute("id", data[i].name);
if (data[i].type == "s")
if (data[i].type == "b")
{
sInput.setAttribute("type", "checkbox");
sInput.checked = data[i].value;
//if (data[i].value == "true"){
// sInput.checked = true;
//} else {
// sInput.checked = false;
//}
}
else if (data[i].type == "s")
{
sInput.setAttribute("type", "text");
sInput.setAttribute("maxlength", data[i].maxlen);
@ -362,7 +371,11 @@
//do something to each div like
var field = inputs[i].getAttribute("id");
console.log("InputNr["+i+"], InputId["+field+"]");
value = document.getElementById(field).value;
if (inputs[i].type == "checkbox") {
value = document.getElementById(field).checked;
} else {
value = document.getElementById(field).value;
}
console.log("==> name["+field+"], value["+value+"]");
if (getBackGround(field).includes("lightgray"))
{ //then it was changes, and needs to be saved
@ -373,36 +386,9 @@
setTimeout(function(){ document.getElementById("settingMessage").innerHTML = ""; }, 1000); //and clear the message
sendPostSetting(field, value);
}
}
}
} // saveSettings()
/****
//============================================================================
function saveSettings()
{
console.log("saveSettings() ...");
var settings = document.getElementById("settingsPage").getElementsByTagName('div');;
for(var i = 0; i < settings.length; i++){
//do something to each div like
//console.log(settings[i].innerHTML);
Dname = settings[i].getAttribute("id");
if (Dname != null)
{
//console.log("Dname["+Dname+"]");
field = Dname.substr(2);
value = document.getElementById(field).value;
console.log("==> name["+field+"], value["+value+"]");
sendPostSetting(field, value)
//console.log("value["+value+"]");
}
}
} // saveSettings()
****/
//============================================================================
function sendPostSetting(field, value)
@ -515,7 +501,6 @@
,[ "dhwtemperature", "Domestic Hotwater Temperature"]
,[ "dhwsetpoint", "Domestic Hotwater Setpoint"]
,[ "oemfaultcode", "OEM Fault Code"]
,[ "author", "Developer"]
,[ "fwversion", "Firmware Version"]
,[ "compiled", "Compiled on (date/time)"]
@ -541,6 +526,8 @@
,[ "wifirssi", "Wifi Receive Power (dB)"]
,[ "lastreset", "Last Reset Reason"]
,[ "mqttconnected", "MQTT Connected"]
,[ "mqttenable", "MQTT Enable"]
,[ "timezone", "Timezone"]
];

View File

@ -539,6 +539,24 @@ void doRestart(const char* str) {
delay(5000); // Enough time to ensure we don't return.
}
String upTime()
{
char calcUptime[20];
snprintf(calcUptime, sizeof(calcUptime), "%d(d)-%02d:%02d(H:m)"
, int((upTimeSeconds / (60 * 60 * 24)) % 365)
, int((upTimeSeconds / (60 * 60)) % 24)
, int((upTimeSeconds / (60)) % 60));
return calcUptime;
} // upTime()
bool prefix(const char *pre, const char *str)
{
return strncmp(pre, str, strlen(pre)) == 0;
}
/***************************************************************************
*

View File

@ -236,9 +236,18 @@ void sendJsonSettingObj(const char *cName, const char *cValue, const char *sType
} // sendJsonSettingObj(*char, *char, *char, int, int)
//=======================================================================
void sendJsonSettingObj(const char *cName, bool bValue, const char *sType)
{
char jsonBuff[200] = "";
snprintf(jsonBuff, sizeof(jsonBuff), "%s{\"name\": \"%s\", \"value\":\"%s\", \"type\": \"%s\"}"
, objSprtr, cName, CBOOLEAN(bValue), sType);
httpServer.sendContent(jsonBuff);
sprintf(objSprtr, ",\r\n");
} // sendJsonSettingObj(*char, bool, *char)
/***************************************************************************
*
* Permission is hereby granted, free of charge, to any person obtaining a

View File

@ -14,6 +14,7 @@
//=======================================================================
void processAPI()
{
static char response[80] = "";
char fName[40] = "";
char URI[50] = "";
String words[10];
@ -88,6 +89,18 @@ void processAPI()
sendOTGW(CSTR(words[5]), words[5].length());
httpServer.send(200, "text/plain", "OK");
} else sendApiNotFound(URI);
} else if (words[4] == "cmdrsp"){
if (httpServer.method() == HTTP_PUT || httpServer.method() == HTTP_POST)
{
/* how to post a command to OTGW
** POST or PUT = /api/v1/otgw/cmdrsp/{command} = Any command you want
** This fetches the response, if OTGW accepted the command, then the value of the response will be return.
** OR and Error code is returned (read this section serial commands: https://otgw.tclcode.com/firmware.html)
** Response: 200 [response is value after {xx:value}]|[errorcode: {NG|SE|BV|OR|NS|NF|OE}]
*/
//Send a command to OTGW and get the response too...
httpServer.send(200, "text/plain", getCommand(words[5]));
} else sendApiNotFound(URI);
}
else sendApiNotFound(URI);
}
@ -284,9 +297,10 @@ void sendDeviceInfo()
sendNestedJsonObj("ssid", WiFi.SSID().c_str());
sendNestedJsonObj("wifirssi", WiFi.RSSI());
// sendNestedJosnObj("mqttconnected", CBOOLEAN(getMQTTconnectstatus()));
//sendNestedJsonObj("uptime", upTime());
sendNestedJsonObj("uptime", upTime());
sendNestedJsonObj("lastreset", lastReset);
sendNestedJsonObj("bootcount", rebootCount);
httpServer.sendContent("\r\n]}\r\n");
@ -320,10 +334,11 @@ void sendDeviceSettings()
//sendJsonSettingObj("intager", settingInteger , "i", 2, 60);
sendJsonSettingObj("hostname", CSTR(settingHostname), "s", 32);
sendJsonSettingObj("mqttenable", settingMQTTenable, "b");
sendJsonSettingObj("mqttbroker", CSTR(settingMQTTbroker), "s", 32);
sendJsonSettingObj("mqttbrokerport", settingMQTTbrokerPort, "i", 0, 65535);
sendJsonSettingObj("mqttuser", CSTR(settingMQTTuser), "s", 32);
sendJsonSettingObj("mqttpasswd", CSTR(settingMQTTpasswd), "s", 32);
sendJsonSettingObj("mqttpasswd", CSTR(settingMQTTpasswd), "s", 100);
sendJsonSettingObj("mqtttoptopic", CSTR(settingMQTTtopTopic), "s", 15);
sendEndJsonObj();

View File

@ -30,11 +30,13 @@ void writeSettings(bool show)
DynamicJsonDocument doc(512);
JsonObject root = doc.to<JsonObject>();
root["hostname"] = settingHostname;
root["MQTTenable"] = settingMQTTenable;
root["MQTTbroker"] = settingMQTTbroker;
root["MQTTbrokerPort"] = settingMQTTbrokerPort;
root["MQTTuser"] = settingMQTTuser;
root["MQTTpasswd"] = settingMQTTpasswd;
root["MQTTtoptopic"] = settingMQTTtopTopic;
root["Timezone"] = settingTimezone;
serializeJsonPretty(root, file);
Debugln(F("... done!"));
@ -72,12 +74,14 @@ void readSettings(bool show)
// Copy values from the JsonDocument to the Config
settingHostname = doc["hostname"].as<String>();
if (settingHostname.length()==0) settingHostname = _HOSTNAME;
settingMQTTenable = doc["MQTTenable"];
settingMQTTbroker = doc["MQTTbroker"].as<String>();
settingMQTTbrokerPort = doc["MQTTbrokerPort"]; //default port
settingMQTTuser = doc["MQTTuser"].as<String>();
settingMQTTpasswd = doc["MQTTpasswd"].as<String>();
settingMQTTtopTopic = doc["MQTTtoptopic"].as<String>();
if (settingMQTTtopTopic.length()==0) settingMQTTtopTopic = _HOSTNAME;
settingTimezone = doc["Timezone"].as<String>();
// Close the file (Curiously, File's destructor doesn't close the file)
file.close();
@ -90,11 +94,13 @@ void readSettings(bool show)
if (show) {
Debugln(F("\r\n==== read Settings ===================================================\r"));
Debugf(" Hostname : %s\r\n", CSTR(settingHostname));
Debugf(" MQTT enabled : %s\r\n", CBOOLEAN(settingMQTTenable));
Debugf(" MQTT broker : %s\r\n", CSTR(settingMQTTbroker));
Debugf(" MQTT port : %d\r\n", settingMQTTbrokerPort);
Debugf(" MQTT username : %s\r\n", CSTR(settingMQTTuser));
Debugf(" MQTT password : %s\r\n", CSTR(settingMQTTpasswd));
Debugf(" MQTT toptopic : %s\r\n", CSTR(settingMQTTtopTopic));
Debugf(" Timezone : %s\r\n", CSTR(settingTimezone));
}
Debugln(F("-\r"));
@ -119,6 +125,7 @@ void updateSetting(const char *field, const char *newValue)
Debugln();
DebugTf("Need reboot before new %s.local will be available!\r\n\n", CSTR(settingHostname));
}
if (stricmp(field, "MQTTenable")==0) settingMQTTenable = EVALBOOLEAN(newValue);
if (stricmp(field, "MQTTbroker")==0) settingMQTTbroker = String(newValue);
if (stricmp(field, "MQTTbrokerPort")==0) settingMQTTbrokerPort = atoi(newValue);
if (stricmp(field, "MQTTuser")==0) settingMQTTuser = String(newValue);
@ -127,6 +134,7 @@ void updateSetting(const char *field, const char *newValue)
settingMQTTtopTopic = String(newValue);
if (settingMQTTtopTopic.length()==0) settingMQTTtopTopic = "OTGW";
}
if (stricmp(field, "Timezone")==0) settingTimezone = String(newValue);
//finally update write settings
writeSettings(false);

View File

@ -18,9 +18,9 @@ static const char UpdateServerIndex[] PROGMEM =
</form>
<hr>
<br/><font color='red'>Warning!!!</font>
<br/>You will lose all your files when flashing SPIFF.
<br/>You will lose all your files when flashing LittleFS.
<br/>Backup your files first to your local filesystem (using FSexplorer)
and upload them after the flashing of your SPIFF.
and upload them after the flashing of your LittleFS.
<hr>
<br/>
<br/>Wait <span style='font-size: 1.3em;' id="waitSeconds">60</span> seconds ..

View File

@ -1,14 +1,14 @@
//The version number conforms to semver.org format
#define _VERSION_MAJOR 0
#define _VERSION_MINOR 7
#define _VERSION_PATCH 2
#define _VERSION_BUILD 447
#define _VERSION_PATCH 3
#define _VERSION_BUILD 480
//#define _VERSION_PRERELEASE beta //uncomment to define prerelease labels: alpha - beta - rc
#define _VERSION_DATE "30-01-2021"
#define _VERSION_TIME "20:22:45"
#define _VERSION_DATE "31-01-2021"
#define _VERSION_TIME "23:28:05"
#define _SEMVER_CORE "0.7.2"
#define _SEMVER_BUILD "0.7.2+447"
#define _SEMVER_FULL "0.7.2+447"
#define _SEMVER_NOBUILD "0.7.2 (30-01-2021)"
#define _VERSION "0.7.2+447 (30-01-2021)"
#define _SEMVER_BUILD "0.7.2+480"
#define _SEMVER_FULL "0.7.2+480"
#define _SEMVER_NOBUILD "0.7.2 (31-01-2021)"
#define _VERSION "0.7.2+480 (31-01-2021)"
//The version information is created automatically, more information here: https://github.com/rvdbreemen/autoinc-semver