diff --git a/tools/esp8266/README.md b/tools/esp8266/README.md index f8690dec..66660bcd 100644 --- a/tools/esp8266/README.md +++ b/tools/esp8266/README.md @@ -1,12 +1,9 @@ ## OVERVIEW -This code was tested on a ESP8266 - ESP-07 module. Many parts of the code are based on 'Hubi's code, which can be found here: +This code is intended to run on a Wemos D1mini or similar. The code is based on 'Hubi's code, which can be found here: -The NRF24L01+ radio module is connected to the standard SPI pins. Additional there are 3 pins, which can be set individual: - -- IRQ - Pin 4 -- CE - Pin 5 -- CS - Pin 15 +The NRF24L01+ radio module is connected to the standard SPI pins. Additional there are 3 pins, which can be set individual: CS, CE and IRQ +These pins can be changed from the /setup URL ## Compile @@ -29,14 +26,22 @@ This code can be compiled using Arduino. The settings were: ## Usage -Connect the ESP to power and to your serial console. The webinterface is currently only used for OTA and config. -The serial console will print all information which is send and received. +Connect the ESP to power and to your serial console. The webinterface has the following abilities: + +- OTA Update (over the air update) +- Configuration (Wifi, inverter(s), Pinout, MQTT) +- visual display of the connected inverters / modules +- some statistics about communication (debug) + +The serial console will print the converted values which were read out of the inverter(s) -## Known Issues +## Compatiblity -- only command 0x81 is received +For now the following inverters should work out of the box: +- HM600 +- HM1200 ## USED LIBRARIES diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 2b016014..0c6c499e 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -1,15 +1,12 @@ #include "app.h" #include "html/h/index_html.h" +#include "html/h/setup_html.h" #include "html/h/hoymiles_html.h" -extern String setup_html; -#define DUMMY_RADIO_ID ((uint64_t)0xDEADBEEF01ULL) - //----------------------------------------------------------------------------- app::app() : Main() { - mSendCnt = 0; mSendTicker = new Ticker(); mFlagSend = false; @@ -93,7 +90,7 @@ void app::setup(const char *ssid, const char *pwd, uint32_t timeout) { mMqtt.sendMsg("version", mVersion); } - initRadio(); + mSys->setup(); if(!mSettingsValid) Serial.println("Warn: your settings are not valid! check [IP]/setup"); @@ -107,15 +104,15 @@ void app::loop(void) { if(!mSys->BufCtrl.empty()) { uint8_t len, rptCnt; packet_t *p = mSys->BufCtrl.getBack(); - //dumpBuf("RAW ", p->packet, MAX_RF_PAYLOAD_SIZE); + //mSys->Radio.dumpBuf("RAW ", p->packet, MAX_RF_PAYLOAD_SIZE); if(mSys->Radio.checkCrc(p->packet, &len, &rptCnt)) { // process buffer only on first occurrence if((0 != len) && (0 == rptCnt)) { - //Serial.println("CMD " + String(*cmd, HEX)); - //dumpBuf("Payload ", p->packet, len); - uint8_t *cmd = &p->packet[11]; + //Serial.println("CMD " + String(*cmd, HEX)); + //mSys->Radio.dumpBuf("Payload ", p->packet, len); + inverter_t *iv = mSys->findInverter(&p->packet[3]); if(NULL != iv) { for(uint8_t i = 0; i < iv->listLen; i++) { @@ -142,31 +139,11 @@ void app::loop(void) { if(mFlagSend) { mFlagSend = false; - - uint8_t size = 0; inverter_t *inv; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { inv = mSys->getInverterByPos(i); if(NULL != inv) { - //if((mSendCnt % 6) == 0) - size = mSys->Radio.getTimePacket(&inv->radioId.u64, mSendBuf, mTimestamp); - /*else if((mSendCnt % 6) == 1) - size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x81); - else if((mSendCnt % 6) == 2) - size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x80); - else if((mSendCnt % 6) == 3) - size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x83); - else if((mSendCnt % 6) == 4) - size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x82); - else if((mSendCnt % 6) == 5) - size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x84);*/ - - //Serial.println("sent packet: #" + String(mSendCnt)); - //dumpBuf("SEN ", mSendBuf, size); - sendPacket(inv, mSendBuf, size); - mSendCnt++; - + mSys->Radio.sendTimePacket(inv->radioId.u64, mTimestamp); delay(20); } } @@ -213,100 +190,7 @@ void app::loop(void) { //----------------------------------------------------------------------------- void app::handleIntr(void) { - uint8_t pipe, len; - packet_t *p; - - DISABLE_IRQ; - - while(mRadio->available(&pipe)) { - if(!mSys->BufCtrl.full()) { - p = mSys->BufCtrl.getFront(); - memset(p->packet, 0xcc, MAX_RF_PAYLOAD_SIZE); - p->sendCh = mSendChannel; - len = mRadio->getPayloadSize(); - if(len > MAX_RF_PAYLOAD_SIZE) - len = MAX_RF_PAYLOAD_SIZE; - - mRadio->read(p->packet, len); - mSys->BufCtrl.pushFront(p); - } - else { - bool tx_ok, tx_fail, rx_ready; - mRadio->whatHappened(tx_ok, tx_fail, rx_ready); // reset interrupt status - mRadio->flush_rx(); // drop the packet - } - } - - RESTORE_IRQ; -} - - -//----------------------------------------------------------------------------- -void app::initRadio(void) { - mRadio = new RF24(RF24_CE_PIN, RF24_CS_PIN); - - mRadio->begin(); - mRadio->setAutoAck(false); - mRadio->setRetries(0, 0); - - mRadio->setChannel(DEFAULT_RECV_CHANNEL); - mRadio->setDataRate(RF24_250KBPS); - mRadio->disableCRC(); - mRadio->setAutoAck(false); - mRadio->setPayloadSize(MAX_RF_PAYLOAD_SIZE); - mRadio->setAddressWidth(5); - mRadio->openReadingPipe(1, DTU_RADIO_ID); - - // enable only receiving interrupts - mRadio->maskIRQ(true, true, false); - - // Use lo PA level, as a higher level will disturb CH340 serial usb adapter - mRadio->setPALevel(RF24_PA_MAX); - mRadio->startListening(); - - Serial.println("Radio Config:"); - mRadio->printPrettyDetails(); - - mSendChannel = mSys->Radio.getDefaultChannel(); -} - - -//----------------------------------------------------------------------------- -void app::sendPacket(inverter_t *inv, uint8_t buf[], uint8_t len) { - DISABLE_IRQ; - mRadio->stopListening(); - -#ifdef CHANNEL_HOP - //if(mSendCnt % 6 == 0) - mSendChannel = mSys->Radio.getNxtChannel(); - //else - // mSendChannel = mSys->Radio.getLastChannel(); -#else - mSendChannel = mSys->Radio.getDefaultChannel(); -#endif - mRadio->setChannel(mSendChannel); - //Serial.println("CH: " + String(mSendChannel)); - - mRadio->openWritingPipe(inv->radioId.u64); - mRadio->setCRCLength(RF24_CRC_16); - mRadio->enableDynamicPayloads(); - mRadio->setAutoAck(true); - mRadio->setRetries(3, 15); - - mRadio->write(buf, len); - - // Try to avoid zero payload acks (has no effect) - mRadio->openWritingPipe(DUMMY_RADIO_ID); // TODO: why dummy radio id? - - mRadio->setAutoAck(false); - mRadio->setRetries(0, 0); - mRadio->disableDynamicPayloads(); - mRadio->setCRCLength(RF24_CRC_DISABLED); - - mRadio->setChannel(DEFAULT_RECV_CHANNEL); - mRadio->startListening(); - - RESTORE_IRQ; + mSys->Radio.handleIntr(); } @@ -324,7 +208,7 @@ void app::mqttTicker(void) { //----------------------------------------------------------------------------- void app::showIndex(void) { - String html = index_html; + String html = FPSTR(index_html); html.replace("{DEVICE}", mDeviceName); html.replace("{VERSION}", mVersion); mWeb->send(200, "text/html", html); @@ -337,7 +221,7 @@ void app::showSetup(void) { uint16_t interval; - String html = setup_html; + String html = FPSTR(setup_html); html.replace("{SSID}", mStationSsid); // PWD will be left at the default value (for protection) // -> the PWD will only be changed if it does not match the placeholder "{PWD}" @@ -455,7 +339,7 @@ void app::showCmdStatistics(void) { //----------------------------------------------------------------------------- void app::showHoymiles(void) { - String html = hoymiles_html; + String html = FPSTR(hoymiles_html); html.replace("{DEVICE}", mDeviceName); html.replace("{VERSION}", mVersion); mWeb->send(200, "text/html", html); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index e7ac42ad..c4cabcdd 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -11,8 +11,8 @@ #include "hmSystem.h" #include "mqtt.h" -typedef HmRadio RadioType; typedef CircularBuffer BufferType; +typedef HmRadio RadioType; typedef HmSystem HmSystemType; const char* const wemosPins[] = {"D3 (GPIO0)", "TX (GPIO1)", "D4 (GPIO2)", "RX (GPIO3)", @@ -31,10 +31,11 @@ class app : public Main { void loop(void); void handleIntr(void); - private: - void initRadio(void); - void sendPacket(inverter_t *inv, uint8_t data[], uint8_t length); + uint8_t getIrqPin(void) { + return mSys->Radio.pinIrq; + } + private: void sendTicker(void); void mqttTicker(void); @@ -49,15 +50,6 @@ class app : public Main { void saveValues(bool webSend); void updateCrc(void); - void dumpBuf(const char *info, uint8_t buf[], uint8_t len) { - Serial.print(String(info)); - for(uint8_t i = 0; i < len; i++) { - Serial.print(buf[i], HEX); - Serial.print(" "); - } - Serial.println(); - } - uint64_t Serial2u64(const char *val) { char tmp[3] = {0}; uint64_t ret = 0ULL; @@ -76,16 +68,10 @@ class app : public Main { uint8_t mState; bool mKeyPressed; - RF24 *mRadio; - packet_t mBuffer[PACKET_BUFFER_SIZE]; HmSystemType *mSys; - Ticker *mSendTicker; - uint32_t mSendCnt; - uint8_t mSendBuf[MAX_RF_PAYLOAD_SIZE]; bool mFlagSend; - uint8_t mSendChannel; uint32_t mCmds[6]; uint32_t mChannelStat[4]; diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index bbc47a11..765ba2b2 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -6,9 +6,8 @@ // PINOUT //------------------------------------- #define RF24_CS_PIN 15 -#define RF24_CE_PIN 2 //5 -#define RF24_IRQ_PIN 0 //4 - +#define RF24_CE_PIN 2 +#define RF24_IRQ_PIN 0 //------------------------------------- @@ -17,6 +16,7 @@ #define PACKET_BUFFER_SIZE 30 #define MAX_NUM_INVERTERS 3 #define MAX_NAME_LENGTH 16 +#define MAX_RF_PAYLOAD_SIZE 64 #define LIVEDATA_VISUALIZED // show live data pv-module wise or as dump @@ -28,6 +28,13 @@ #define VERSION_PATCH 4 +//------------------------------------- +typedef struct { + uint8_t sendCh; + uint8_t packet[MAX_RF_PAYLOAD_SIZE]; +} packet_t; + + //------------------------------------- // EEPROM //------------------------------------- diff --git a/tools/esp8266/eep.h b/tools/esp8266/eep.h index e38bc9fd..da1450b0 100644 --- a/tools/esp8266/eep.h +++ b/tools/esp8266/eep.h @@ -36,7 +36,7 @@ class eep { *value = (EEPROM.read(addr++)); } - void read(uint32_t addr, uint8_t data[], uint8_t length) { + void read(uint32_t addr, uint8_t data[], uint16_t length) { for(uint8_t i = 0; i < length; i ++) { *(data++) = EEPROM.read(addr++); } @@ -77,7 +77,7 @@ class eep { EEPROM.commit(); } - void write(uint32_t addr, uint8_t data[], uint8_t length) { + void write(uint32_t addr, uint8_t data[], uint16_t length) { for(uint8_t i = 0; i < length; i ++) { EEPROM.write(addr++, data[i]); } diff --git a/tools/esp8266/esp8266.ino b/tools/esp8266/esp8266.ino index 5bb82995..5f22245e 100644 --- a/tools/esp8266/esp8266.ino +++ b/tools/esp8266/esp8266.ino @@ -13,12 +13,11 @@ app myApp; //----------------------------------------------------------------------------- void setup() { - // TODO: move to HmRadio - pinMode(RF24_IRQ_PIN, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(RF24_IRQ_PIN), handleIntr, FALLING); - // AP name, password, timeout myApp.setup("ESP AHOY", "esp_8266", 15); + + // TODO: move to HmRadio + attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING); } diff --git a/tools/esp8266/hmRadio.h b/tools/esp8266/hmRadio.h index 0ab66484..70e710e0 100644 --- a/tools/esp8266/hmRadio.h +++ b/tools/esp8266/hmRadio.h @@ -8,9 +8,9 @@ //#define CHANNEL_HOP // switch between channels or use static channel to send #define DEFAULT_RECV_CHANNEL 3 -#define MAX_RF_PAYLOAD_SIZE 64 #define DTU_RADIO_ID ((uint64_t)0x1234567801ULL) +#define DUMMY_RADIO_ID ((uint64_t)0xDEADBEEF01ULL) //----------------------------------------------------------------------------- @@ -38,17 +38,14 @@ //----------------------------------------------------------------------------- // HM Radio class //----------------------------------------------------------------------------- -template +template class HmRadio { public: - HmRadio() { - //pinMode(IRQ_PIN, INPUT_PULLUP); - //attachInterrupt(digitalPinToInterrupt(IRQ_PIN), handleIntr, FALLING); - - mSendChan[0] = 23; - mSendChan[1] = 40; - mSendChan[2] = 61; - mSendChan[3] = 75; + HmRadio() : mNrf24(CE_PIN, CS_PIN) { + mChanOut[0] = 23; + mChanOut[1] = 40; + mChanOut[2] = 61; + mChanOut[3] = 75; mChanIdx = 1; calcDtuCrc(); @@ -56,47 +53,106 @@ class HmRadio { pinCs = CS_PIN; pinCe = CE_PIN; pinIrq = IRQ_PIN; + + mSendCnt = 0; } ~HmRadio() {} + void setup(BUFFER *ctrl) { + //Serial.println("HmRadio::setup, pins: " + String(pinCs) + ", " + String(pinCe) + ", " + String(pinIrq)); + pinMode(pinIrq, INPUT_PULLUP); + + mBufCtrl = ctrl; + + mNrf24.begin(pinCe, pinCs); + mNrf24.setAutoAck(false); + mNrf24.setRetries(0, 0); + + mNrf24.setChannel(DEFAULT_RECV_CHANNEL); + mNrf24.setDataRate(RF24_250KBPS); + mNrf24.disableCRC(); + mNrf24.setAutoAck(false); + mNrf24.setPayloadSize(MAX_RF_PAYLOAD_SIZE); + mNrf24.setAddressWidth(5); + mNrf24.openReadingPipe(1, DTU_RADIO_ID); + + // enable only receiving interrupts + mNrf24.maskIRQ(true, true, false); + + // Use lo PA level, as a higher level will disturb CH340 serial usb adapter + mNrf24.setPALevel(RF24_PA_MAX); + mNrf24.startListening(); + + Serial.println("Radio Config:"); + mNrf24.printPrettyDetails(); + + mSendChannel = getDefaultChannel(); + } + + void handleIntr(void) { + uint8_t pipe, len; + packet_t *p; + + DISABLE_IRQ; + while(mNrf24.available(&pipe)) { + if(!mBufCtrl->full()) { + p = mBufCtrl->getFront(); + memset(p->packet, 0xcc, MAX_RF_PAYLOAD_SIZE); + p->sendCh = mSendChannel; + len = mNrf24.getPayloadSize(); + if(len > MAX_RF_PAYLOAD_SIZE) + len = MAX_RF_PAYLOAD_SIZE; + + mNrf24.read(p->packet, len); + mBufCtrl->pushFront(p); + } + else { + bool tx_ok, tx_fail, rx_ready; + mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // reset interrupt status + mNrf24.flush_rx(); // drop the packet + } + } + RESTORE_IRQ; + } + uint8_t getDefaultChannel(void) { - return mSendChan[2]; + return mChanOut[2]; } uint8_t getLastChannel(void) { - return mSendChan[mChanIdx]; + return mChanOut[mChanIdx]; } uint8_t getNxtChannel(void) { if(++mChanIdx >= 4) mChanIdx = 0; - return mSendChan[mChanIdx]; + return mChanOut[mChanIdx]; } - uint8_t getTimePacket(const uint64_t *invId, uint8_t buf[], uint32_t ts) { - getCmdPacket(invId, buf, 0x15, 0x80, false); - buf[10] = 0x0b; // cid - buf[11] = 0x00; - CP_U32_LittleEndian(&buf[12], ts); - buf[19] = 0x05; + void sendTimePacket(uint64_t invId, uint32_t ts) { + sendCmdPacket(invId, 0x15, 0x80, false); + mSendBuf[10] = 0x0b; // cid + mSendBuf[11] = 0x00; + CP_U32_LittleEndian(&mSendBuf[12], ts); + mSendBuf[19] = 0x05; - uint16_t crc = crc16(&buf[10], 14); - buf[24] = (crc >> 8) & 0xff; - buf[25] = (crc ) & 0xff; - buf[26] = crc8(buf, 26); + uint16_t crc = crc16(&mSendBuf[10], 14); + mSendBuf[24] = (crc >> 8) & 0xff; + mSendBuf[25] = (crc ) & 0xff; + mSendBuf[26] = crc8(mSendBuf, 26); - return 27; + sendPacket(invId, mSendBuf, 27); } - uint8_t getCmdPacket(const uint64_t *invId, uint8_t buf[], uint8_t mid, uint8_t cmd, bool calcCrc = true) { - memset(buf, 0, MAX_RF_PAYLOAD_SIZE); - buf[0] = mid; // message id - CP_U32_BigEndian(&buf[1], ((*invId) >> 8)); - CP_U32_BigEndian(&buf[5], (DTU_ID >> 8)); - buf[9] = cmd; - if(calcCrc) - buf[10] = crc8(buf, 10); - - return 11; + void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t cmd, bool calcCrc = true) { + memset(mSendBuf, 0, MAX_RF_PAYLOAD_SIZE); + mSendBuf[0] = mid; // message id + CP_U32_BigEndian(&mSendBuf[1], (invId >> 8)); + CP_U32_BigEndian(&mSendBuf[5], (DTU_ID >> 8)); + mSendBuf[9] = cmd; + if(calcCrc) { + mSendBuf[10] = crc8(mSendBuf, 10); + sendPacket(invId, mSendBuf, 11); + } } bool checkCrc(uint8_t buf[], uint8_t *len, uint8_t *rptCnt) { @@ -126,6 +182,44 @@ class HmRadio { uint8_t pinIrq; private: + void sendPacket(uint64_t invId, uint8_t buf[], uint8_t len) { + //Serial.println("sent packet: #" + String(mSendCnt)); + //dumpBuf("SEN ", buf, len); + + DISABLE_IRQ; + mNrf24.stopListening(); + + #ifdef CHANNEL_HOP + mSendChannel = getNxtChannel(); + #else + mSendChannel = getDefaultChannel(); + #endif + mNrf24.setChannel(mSendChannel); + //Serial.println("CH: " + String(mSendChannel)); + + mNrf24.openWritingPipe(invId); // TODO: deprecated + mNrf24.setCRCLength(RF24_CRC_16); + mNrf24.enableDynamicPayloads(); + mNrf24.setAutoAck(true); + mNrf24.setRetries(3, 15); + + mNrf24.write(buf, len); + + // Try to avoid zero payload acks (has no effect) + mNrf24.openWritingPipe(DUMMY_RADIO_ID); // TODO: why dummy radio id?, deprecated + + mNrf24.setAutoAck(false); + mNrf24.setRetries(0, 0); + mNrf24.disableDynamicPayloads(); + mNrf24.setCRCLength(RF24_CRC_DISABLED); + + mNrf24.setChannel(DEFAULT_RECV_CHANNEL); + mNrf24.startListening(); + + RESTORE_IRQ; + mSendCnt++; + } + void calcDtuCrc(void) { uint64_t addr = DTU_RADIO_ID; uint8_t tmp[5]; @@ -136,11 +230,26 @@ class HmRadio { mDtuIdCrc = crc16nrf24(tmp, BIT_CNT(5)); } - uint8_t mSendChan[4]; + void dumpBuf(const char *info, uint8_t buf[], uint8_t len) { + Serial.print(String(info)); + for(uint8_t i = 0; i < len; i++) { + Serial.print(buf[i], HEX); + Serial.print(" "); + } + Serial.println(); + } + + uint8_t mChanOut[4]; uint8_t mChanIdx; uint16_t mDtuIdCrc; uint16_t mLastCrc; uint8_t mRptCnt; + + RF24 mNrf24; + uint8_t mSendChannel; + BUFFER *mBufCtrl; + uint32_t mSendCnt; + uint8_t mSendBuf[MAX_RF_PAYLOAD_SIZE]; }; #endif /*__RADIO_H__*/ diff --git a/tools/esp8266/hmSystem.h b/tools/esp8266/hmSystem.h index bd573fc6..0f79ca9f 100644 --- a/tools/esp8266/hmSystem.h +++ b/tools/esp8266/hmSystem.h @@ -4,10 +4,6 @@ #include "hmInverters.h" #include "hmRadio.h" -typedef struct { - uint8_t sendCh; - uint8_t packet[MAX_RF_PAYLOAD_SIZE]; -} packet_t; template @@ -25,6 +21,10 @@ class HmSystem { // TODO: cleanup } + void setup() { + Radio.setup(&BufCtrl); + } + inverter_t *addInverter(const char *name, uint64_t serial, uint8_t type) { if(MAX_INVERTER <= mNumInv) { DPRINT("max number of inverters reached!"); diff --git a/tools/esp8266/html/conv.bat b/tools/esp8266/html/conv.bat deleted file mode 100644 index 0627beeb..00000000 --- a/tools/esp8266/html/conv.bat +++ /dev/null @@ -1,5 +0,0 @@ -..\tools\fileConv.exe index.html h\index_html.h index_html -..\tools\fileConv.exe setup.html h\setup_html.h setup_html -..\tools\fileConv.exe hoymiles.html h\hoymiles_html.h hoymiles_html -..\tools\fileConv.exe style.css h\style_css.h style_css -pause diff --git a/tools/esp8266/html/convert.py b/tools/esp8266/html/convert.py new file mode 100644 index 00000000..4b58681f --- /dev/null +++ b/tools/esp8266/html/convert.py @@ -0,0 +1,28 @@ +import re + +def convert2Header(inFile): + outName = "h/" + inFile.replace(".", "_") + ".h" + fileType = inFile.split(".")[1] + + f = open(inFile, "r") + data = f.read().replace('\n', '') + f.close() + if fileType == "html": + data = re.sub(r"\>\s+\<", '><', data) # whitespaces between xml tags + data = re.sub(r"(\;|\}|\>|\{)\s+", r'\1', data) # whitespaces inner javascript + data = re.sub(r"\"", '\\\"', data) # escape quotation marks + else: + data = re.sub(r"(\;|\}|\:|\{)\s+", r'\1', data) # whitespaces inner css + + define = inFile.split(".")[0].upper() + f = open(outName, "w") + f.write("#ifndef __{}_H__\n".format(define)) + f.write("#define __{}_H__\n".format(define)) + f.write("const char {}[] PROGMEM = \"{}\";\n".format(inFile.replace(".", "_"), data)) + f.write("#endif /*__{}_H__*/\n".format(define)) + f.close() + +convert2Header("index.html") +convert2Header("setup.html") +convert2Header("hoymiles.html") +convert2Header("style.css") diff --git a/tools/esp8266/html/h/hoymiles_html.h b/tools/esp8266/html/h/hoymiles_html.h index 4bc89397..594e4b25 100644 --- a/tools/esp8266/html/h/hoymiles_html.h +++ b/tools/esp8266/html/h/hoymiles_html.h @@ -1 +1,4 @@ -String hoymiles_html = "Index - {DEVICE}

AHOY - {DEVICE}

Home

Every 10 seconds the values are updated

© 2022

AHOY :: {VERSION}

"; +#ifndef __HOYMILES_H__ +#define __HOYMILES_H__ +const char hoymiles_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Home

Every 10 seconds the values are updated

© 2022

AHOY :: {VERSION}

"; +#endif /*__HOYMILES_H__*/ diff --git a/tools/esp8266/html/h/index_html.h b/tools/esp8266/html/h/index_html.h index 8b638b0c..53eeda89 100644 --- a/tools/esp8266/html/h/index_html.h +++ b/tools/esp8266/html/h/index_html.h @@ -1 +1,4 @@ -String index_html = "Index - {DEVICE}

AHOY - {DEVICE}

Hoymiles
Update

Setup
Reboot

Uptime:

Time:

MQTT:

Statistics:

© 2022

AHOY :: {VERSION}

"; +#ifndef __INDEX_H__ +#define __INDEX_H__ +const char index_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Hoymiles
Update

Setup
Reboot

Uptime:

Time:

MQTT:

Statistics:

© 2022

AHOY :: {VERSION}

"; +#endif /*__INDEX_H__*/ diff --git a/tools/esp8266/html/h/setup_html.h b/tools/esp8266/html/h/setup_html.h index b905b56b..f4e99a1a 100644 --- a/tools/esp8266/html/h/setup_html.h +++ b/tools/esp8266/html/h/setup_html.h @@ -1 +1,4 @@ -String setup_html = "Setup - {DEVICE}

Setup

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

WiFi

Device Host Name

Inverter

{INVERTERS}

General

Pinout

{PINOUT}

MQTT

 

Home

Update Firmware

AHOY - {VERSION}

"; +#ifndef __SETUP_H__ +#define __SETUP_H__ +const char setup_html[] PROGMEM = "Setup - {DEVICE}

Setup

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

WiFi

Device Host Name

Inverter

{INVERTERS}

General

Pinout (Wemos)

{PINOUT}

MQTT

 

Home

Update Firmware

AHOY - {VERSION}

"; +#endif /*__SETUP_H__*/ diff --git a/tools/esp8266/html/h/style_css.h b/tools/esp8266/html/h/style_css.h index 6cc7fc67..cf8ac694 100644 --- a/tools/esp8266/html/h/style_css.h +++ b/tools/esp8266/html/h/style_css.h @@ -1 +1,4 @@ -String style_css = "h1 { margin: 0; padding: 20pt; font-size: 22pt; color: #fff; background-color: #006ec0; display: block; text-transform: uppercase; } html, body { font-family: Arial; margin: 0; padding: 0; } p { text-align: justify; font-size: 13pt; } .des { margin-top: 35px; font-size: 14pt; color: #006ec0; } .subdes { font-size: 13pt; color: #006ec0; margin-left: 7px; } .fw { width: 60px; display: block; float: left; } .color { width: 50px; height: 50px; border: 1px solid #ccc; } .range { width: 300px; } a:link, a:visited { text-decoration: none; font-size: 13pt; color: #006ec0; } a:hover, a:focus { color: #f00; } #content { padding: 15px 15px 60px 15px; } #footer { position: fixed; bottom: 0px; height: 45px; background-color: #006ec0; width: 100%; } #footer p { color: #fff; padding-left: 20px; padding-right: 20px; font-size: 10pt !important; } #footer a { color: #fff; } div.content { background-color: #fff; padding-bottom: 65px; overflow: hidden; } input, select { padding: 7px; font-size: 13pt; } input.text, select { width: 70%; box-sizing: border-box; margin-bottom: 10px; border: 1px solid #ccc; } input.btn { background-color: #006ec0; color: #fff; border: 0px; float: right; text-transform: uppercase; } input.cb { margin-bottom: 20px; } label { width: 20%; display: inline-block; font-size: 12pt; padding-right: 10px; margin-left: 10px; } .left { float: left; } .right { float: right; } div.ch { width: 250px; height: 410px; background-color: #006ec0; display: inline-block; margin-right: 20px; margin-bottom: 20px; } div.ch .value, div.ch .info, div.ch .head { color: #fff; display: block; width: 100%; text-align: center; } div.ch .unit { font-size: 19px; margin-left: 10px; } div.ch .value { margin-top: 20px; font-size: 30px; } div.ch .info { margin-top: 3px; font-size: 10px; } div.ch .head { background-color: #003c80; padding: 10px 0 10px 0; } "; +#ifndef __STYLE_H__ +#define __STYLE_H__ +const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}.des {margin-top:35px;font-size:14pt;color:#006ec0;}.subdes {font-size:13pt;color:#006ec0;margin-left:7px;}.fw {width:60px;display:block;float:left;}.color {width:50px;height:50px;border:1px solid #ccc;}.range {width:300px;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;}#footer p {color:#fff;padding-left:20px;padding-right:20px;font-size:10pt !important;}#footer a {color:#fff;}div.content {background-color:#fff;padding-bottom:65px;overflow:hidden;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin-left:10px;}.left {float:left;}.right {float:right;}div.ch {width:250px;height:410px;background-color:#006ec0;display:inline-block;margin-right:20px;margin-bottom:20px;}div.ch .value, div.ch .info, div.ch .head {color:#fff;display:block;width:100%;text-align:center;}div.ch .unit {font-size:19px;margin-left:10px;}div.ch .value {margin-top:20px;font-size:30px;}div.ch .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}"; +#endif /*__STYLE_H__*/ diff --git a/tools/esp8266/main.cpp b/tools/esp8266/main.cpp index 2555188d..61b2075c 100644 --- a/tools/esp8266/main.cpp +++ b/tools/esp8266/main.cpp @@ -160,7 +160,7 @@ bool Main::setupStation(uint32_t timeout) { //----------------------------------------------------------------------------- void Main::showSetup(void) { - String html = setup_html; + String html = FPSTR(setup_html); html.replace("{SSID}", mStationSsid); // PWD will be left at the default value (for protection) // -> the PWD will only be changed if it does not match the default "{PWD}" @@ -173,7 +173,7 @@ void Main::showSetup(void) { //----------------------------------------------------------------------------- void Main::showCss(void) { - mWeb->send(200, "text/css", style_css); + mWeb->send(200, "text/css", FPSTR(style_css)); } diff --git a/tools/esp8266/tools/fileConv.exe b/tools/esp8266/tools/fileConv.exe deleted file mode 100644 index 6cd3e212..00000000 Binary files a/tools/esp8266/tools/fileConv.exe and /dev/null differ