before update 0.7.3
This commit is contained in:
parent
5460c2857e
commit
cb0840aaeb
|
@ -13,6 +13,7 @@
|
|||
"vector": "cpp",
|
||||
"string": "cpp",
|
||||
"fstream": "cpp",
|
||||
"cstring": "cpp"
|
||||
"cstring": "cpp",
|
||||
"regex": "cpp"
|
||||
}
|
||||
}
|
|
@ -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 </div>"
|
||||
" <div style='float: left;'>Redirect in </div>"
|
||||
" <div style='float: left;' id='counter'>"+String(wait)+"</div>"
|
||||
" <div style='float: left;'> seconden ...</div>"
|
||||
" <div style='float: left;'> seconds ...</div>"
|
||||
" <div style='float: right;'> </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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
108
OTGW-Core.ino
108
OTGW-Core.ino
|
@ -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')
|
||||
|
|
|
@ -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...
|
||||
|
||||
|
|
|
@ -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!"));
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"]
|
||||
|
||||
];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
21
restAPI.ino
21
restAPI.ino
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ..
|
||||
|
|
16
version.h
16
version.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue