diff --git a/README.md b/README.md index 43801aded..73928014b 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,13 @@ To see the current values of the Boiler and its parameters type 's' and hit Ente Commands can be issued directly to the EMS bus typing in a letter followed by an optional parameter and pressing Enter. Supported commands are: - **r** to send a read command to all devices to fetch values. The 2nd parameter is the type. For example 'r 33' will request type UBAParameterWW and bring back the Warm Water temperatures (not the heating) from the Boiler. You can issue any type here. -- **t** set the thermostat temperature to the given value +- **t** set the thermostat temperature to the given celsius value - **w** to adjust the temperature of the warm water from the boiler - **a** to turn the warm water on and off +- **h** to list all the recognized EMS types - **p** to toggle the Polling response on/off. It's not necessary to have Polling enabled to work. I use this for debugging purposes. - **m** to set the thermostat mode from low, manual and clock/auto. -- **T** to toggle thermostat reading on/off +- **T** to toggle thermostat readings on/off - **S** to toggle the Shower Timer functionality on/off **Disclaimer: be careful when sending values to the boiler. If in doubt you can always reset the boiler to its original factory settings by following the instructions in the user guide. On my **Nefit Trendline HRC30** that is done by holding down the Home and Menu buttons simultaneously for a few seconds, selecting factory settings from the scroll menu and lastly pressing the Reset button.** @@ -220,13 +221,13 @@ The code is built on the Arduino framework and is dependent on these external li In `boiler.ino` you can make calls to automatically send these read commands. See the function *regularUpdates()* -#### Support for RC35 type Thermostats +#### Supporting RC35 model Thermostats -An RC35 thermostat has 4 heating circuits. To read the values use the Monitor type IDs (e.g. 0x3E, 0x48, etc). The mode (0=night, 1=day, 2=holiday) is the first byte of the telegram and the temperature is the value of the 2nd byte divided by 2. +The code is designed for a Moduline300 (RC20) thermostat. To adjust for a RC35 first change `EMS_ID_THERMOSTAT` in `ems.h`. A RC35 thermostat has 4 heating circuits and to read the values use different Monitor type IDs (e.g. 0x3E, 0x48, etc). The mode (0=night, 1=day, 2=holiday) is the first byte of the telegram and the temperature is the value of the 2nd byte divided by 2. Then to set temperature values use the Working Mode with type IDs (0x3D, 0x47,0x51 and 0x5B) respectively. Set the offset (byte 4 of the header) to determine which temperature you're changing; 1 for night, 2 for day and 3 for holiday. The data value is the desired temperature multiplied by 2 as a single byte. -Consult the wiki documentation for the data format. +Consult the wiki documentation for the actual data format. ### Customizing the code @@ -244,7 +245,7 @@ I'm using the standard PubSubClient client so make sure you set `-DMQTT_MAX_PACK I run Mosquitto on my Raspberry PI 3 as the MQTT broker. -The boiler data is collected and sent as a single JSON object to MQTT TOPIC `home/boiler/boiler_data`. A hash is generated (CRC32 based) to determine if the payload has changed, otherwise don't send it. An example payload looks like: +The boiler data is collected and sent as a single JSON object to MQTT TOPIC `home/boiler/boiler_data` (or `{hostname}/boiler_data` for ESPurna). A hash is generated (CRC32 based) to determine if the payload has changed, otherwise don't send it. An example payload looks like: `{"wWCurTmp":"43.0","wWHeat":"on","curFlowTemp":"51.7","retTemp":"48.0","burnGas":"off","heatPmp":"off","fanWork":"off","ignWork":"off","wWCirc":"off","selBurnPow":"0","curBurnPow":"0","sysPress":"1.6","boilTemp":"54.7","pumpMod":"4"}` @@ -290,30 +291,34 @@ Roughly these are the steps needed when running Windows: ### Using ESPurna -[ESPurna](https://github.com/xoseperez/espurna/wiki) is framework that handles most of the tedious tasks of building IoT devices so you can focus on the functionality you need. This replaces my ESPHelper code in the standalone version above. ESPurna is natively built on PlatformIO and Visual Studio Code too which is nice. So if you're brave, follow these steps: +[ESPurna](https://github.com/xoseperez/espurna/wiki) is framework that handles most of the tedious tasks of building IoT devices so you can focus on the functionality you need. This replaces my ESPHelper code in the standalone version above. ESPurna is natively built on PlatformIO and Visual Studio Code too which is nice. The latest version supported is 1.13.3. So if you're brave, follow these steps: 1. Download and install [NodeJS](https://nodejs.org/en/download). This gives you npm. Choose the LTS version -2. Download ESPurna by cloning the ESPurna git repository from `https://github.com/xoseperez/espurna.git` -3. Restart VSC. PlatformIO should detect and set some things up for you automagically -4. From VSC open the folder `espurna\code` +2. Download ESPurna by cloning the ESPurna git repository (command palette, git clone, https://github.com/xoseperez/espurna.git) +3. Restart VSC. +4. From VSC open the folder `espurna\code`. PlatformIO should detect and set some things up for you automagically 5. open a terminal window (*ctrl-`*) 6. Install the node modules: `npm install --only=dev` -7. Build the web interface: `node node_modules/gulp/bin/gulp.js`. This will create a compressed `code/espurna/static/index.html.gz.h` -8. First time users build the filesystem by *ctrl-alt-t* and run the task 'uploadfs' -9. Copy these files from this repo's *espurna* directory to where you installed ESPurna +7. Build the web interface: `node node_modules/gulp/bin/gulp.js`. This will create a compressed `code/espurna/static/index.html.gz.h`. If you get warnings about lf during the building edit `gulpfile.js` and change the line `'failOnError': true` to `false` as a temporary workaround. +8. Modify the platformio.ini file making sure you add `-DUSE_CUSTOM_H -DUSE_EXTRA` to the `debug_flags` +9. Copy the following files from EMS-ESP-Boiler repo to where you installed ESPurna ``` -code/html/index.html -code/config/custom.h -code/espurna/boiler-espurna.ino -code/espurna/ems*.* +espurna/index.html -> code/html/index.html +espurna/custom.h -> code/config/custom.h +espurna/boiler-espurna.ino -> code/espurna/boiler-espurna.ino +ems*.* -> code/espurna/ ``` -10. Now build and upload as you usually would. Look at my version of platformio.ini as an example. +10. Now build and upload as you usually would with PlatformIO (or ctrl-arl-t and choose the right build). Look at my version of platformio.ini as an example. +11. When the firmware loads, use a wifi connected pc/mobile to connect to the Access Point called ESPURNA_XXXXXX. Use 'fibonacci' as the password. Navigate to `http://192.168.4.1` from a browser, set a new username and password when prompted, log off the wifi and reconnect to the AP using these new credentials. Again go to 192.168.4.1 +12. In the ADMIN page enable Telnet and SAVE +13. In the WIFI page add your home wifi details, click SAVE and reboot, and go to the new IP +14. Configure MQTT The Telnet functions are `BOILER.READ`, `BOILER.INFO` and a few others for reference. `HELP` will list them. Add your own functions to expand the functionality by calling the EMS* functions as in the examples. -If you run into issues refer to ESPurna's official setup instructions [here](https://github.com/xoseperez/espurna/wiki/Build-and-update-from-Visual-Studio-Code-using-PlatformIO). +If you run into issues refer to ESPurna's official setup instructions [here](https://github.com/xoseperez/espurna/wiki/Build-and-update-from-Visual-Studio-Code-using-PlatformIO) and [here](https://github.com/xoseperez/espurna/wiki/Configuration). This is what ESPurna looks like with the custom boiler code: @@ -328,10 +333,8 @@ pre-baked firmwares for some ESP8266 devices based on ESPurna are available in t 2. Install the ESPTool by running `pip install esptool` from a command prompt 3. Connect the ESP via USB, figure out the COM port 4. run `esptool.py -p write_flash 0x00000 ` where firmware is the `.bin` file and \ is the COM port, e.g. `COM3` -5. Connect using WiFi from a phone or PC to the "**ESPURNA_XXXXXX**" network. Password is '**fibonacci**' -6. Once connected browse to "http://192.168.4.1" and setup your wifi, mqtt etc -Again, if you run into problems read [this](https://github.com/xoseperez/espurna/wiki/Configuration) from ESPurna's configuration help page. +now follow the steps in ESPurna section above from #10 on to configure the device. ### Using the Arduino IDE diff --git a/espurna/boiler-espurna.ino b/espurna/boiler-espurna.ino index b0230eae1..9fc969203 100644 --- a/espurna/boiler-espurna.ino +++ b/espurna/boiler-espurna.ino @@ -13,20 +13,31 @@ #define BOILER_POLLING_ENABLED 0 #define BOILER_LOGGING_NONE 1 +// home/boiler/ +#define TOPIC_BOILER_DATA "boiler_data" // for sending boiler values +#define TOPIC_THERMOSTAT_TEMP "thermostat_temp" // for received thermostat temp changes +#define TOPIC_THERMOSTAT_CURRTEMP "thermostat_currtemp" // current temperature +#define TOPIC_THERMOSTAT_SELTEMP "thermostat_seltemp" // selected temperature +#define TOPIC_THERMOSTAT_MODE "thermostat_mode" // selected temperature +#define TOPIC_BOILER_WARM_WATER_SELECTED_TEMPERATURE "boiler_wwtemp" // warm water selected temp + +#define BOILERSEND_INTERVAL 60000 // send every minute to HA + typedef struct { bool wifi_connected; bool boiler_online; bool thermostat_enabled; - bool shower_enabled; // true if we want to report back on shower times - bool shower_timer; // true if we want the cold water reminder + bool shower_timer; // true if we want to report back on shower times + bool shower_alert; // true if we want the cold water reminder } _Boiler_Status; typedef struct { bool showerOn; - unsigned long timerStart; // ms - unsigned long timerPause; // ms - unsigned long duration; // ms - bool isColdShot; // true if we've just sent a jolt of cold water + bool hotWaterOn; + unsigned long timerStart; // ms + unsigned long timerPause; // ms + unsigned long duration; // ms + bool doingColdShot; // true if we've just sent a jolt of cold water } _Boiler_Shower; // store for overall system status @@ -44,7 +55,7 @@ void _boilerConfigure() { uint8_t _boilerLogging = getSetting("boilerLogging", BOILER_LOGGING_NONE).toInt(); ems_setLogging((_EMS_SYS_LOGGING)_boilerLogging); - Boiler_Status.shower_enabled = getSetting("boilerShower", BOILER_SHOWER_ENABLED).toInt() == 1; + Boiler_Status.shower_timer = getSetting("boilerShower", BOILER_SHOWER_ENABLED).toInt() == 1; } // WEB callbacks @@ -63,38 +74,111 @@ void _boilerWebSocketOnSend(JsonObject & root) { void _boilerWebSocketOnAction(uint32_t client_id, const char * action, JsonObject & data) { } -// send to HA -void sendHA() { - String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX); - String output; - // assume ha is enabled - DynamicJsonBuffer jsonBuffer; - JsonObject & config = jsonBuffer.createObject(); - String name = getSetting("hostname"); - config.set("name", name); - config.set("platform", "mqtt"); - config.printTo(output); +// convert float to char +//char * _float_to_char(char * a, float f, uint8_t precision = 1); +char * _float_to_char(char * a, float f, uint8_t precision = 1) { + long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - mqttSendRaw(topic.c_str(), output.c_str()); - mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true); + char * ret = a; + // check for 0x8000 (sensor missing), which has a -1 value + if (f == EMS_VALUE_FLOAT_NOTSET) { + strcpy(ret, "?"); + } else { + long whole = (long)f; + itoa(whole, a, 10); + while (*a != '\0') + a++; + *a++ = '.'; + long decimal = abs((long)((f - whole) * p[precision])); + itoa(decimal, a, 10); + } + return ret; +} + +// convert bool to text +char * _bool_to_char(char * s, uint8_t value) { + if (value == EMS_VALUE_INT_ON) { + strcpy(s, "on"); + } else if (value == EMS_VALUE_INT_OFF) { + strcpy(s, "off"); + } else { + strcpy(s, "?"); + } + return s; +} + +// convert int to text value +char * _int_to_char(char * s, uint8_t value) { + if (value == EMS_VALUE_INT_NOTSET) { + strcpy(s, "?"); + } else { + itoa(value, s, 10); + } + return s; +} + +// takes a float value at prints it to debug log +void _renderFloatValue(const char * prefix, const char * postfix, float value) { + myDebug(" %s: ", prefix); + char s[20]; + myDebug("%s", _float_to_char(s, value)); + + if (postfix != NULL) { + myDebug(" %s", postfix); + } + + myDebug("\n"); +} + +// takes an int value at prints it to debug log +void _renderIntValue(const char * prefix, const char * postfix, uint8_t value) { + myDebug(" %s: ", prefix); + char s[20]; + myDebug("%s", _int_to_char(s, value)); + + if (postfix != NULL) { + myDebug(" %s", postfix); + } + + myDebug("\n"); +} + +// takes a bool value at prints it to debug log +void _renderBoolValue(const char * prefix, uint8_t value) { + myDebug(" %s: ", prefix); + char s[20]; + myDebug("%s\n", _bool_to_char(s, value)); } // Show command - display stats on an 's' command void showInfo() { - char s[10]; // for formatting floats using the _float_to_char() function - // General stats from EMS bus - myDebug("EMS Bus stats:\n"); - myDebug(" Thermostat is %s, Poll is %s, Shower is %s, Shower timer is %s, RxPgks=%d, TxPkgs=%d, #CrcErrors=%d", + myDebug("%sEMS-ESP-Boiler system stats:%s\n", COLOR_BOLD_ON, COLOR_BOLD_OFF); + myDebug(" System Logging is set to "); + _EMS_SYS_LOGGING sysLog = ems_getLogging(); + if (sysLog == EMS_SYS_LOGGING_BASIC) { + myDebug("Basic"); + } else if (sysLog == EMS_SYS_LOGGING_VERBOSE) { + myDebug("Verbose"); + } else { + myDebug("None"); + } + + myDebug("\n # EMS type handlers: %d\n", ems_getEmsTypesCount()); + + myDebug(" Thermostat is %s, Poll is %s, Shower timer is %s, Shower alert is %s\n", ((Boiler_Status.thermostat_enabled) ? "enabled" : "disabled"), ((EMS_Sys_Status.emsPollEnabled) ? "enabled" : "disabled"), - ((Boiler_Status.shower_enabled) ? "enabled" : "disabled"), ((Boiler_Status.shower_timer) ? "enabled" : "disabled"), + ((Boiler_Status.shower_alert) ? "enabled" : "disabled")); + + myDebug(" EMS Bus Stats: Connected=%s, # Rx telegrams=%d, # Tx telegrams=%d, # Crc Errors=%d, ", + (Boiler_Status.boiler_online ? "yes" : "no"), EMS_Sys_Status.emsRxPgks, EMS_Sys_Status.emsTxPkgs, EMS_Sys_Status.emxCrcErr); - myDebug(", RxStatus="); + myDebug("Rx Status="); switch (EMS_Sys_Status.emsRxStatus) { case EMS_RX_IDLE: myDebug("idle"); @@ -104,7 +188,7 @@ void showInfo() { break; } - myDebug(", TxStatus="); + myDebug(", Tx Status="); switch (EMS_Sys_Status.emsTxStatus) { case EMS_TX_IDLE: myDebug("idle"); @@ -117,7 +201,7 @@ void showInfo() { break; } - myDebug(", TxAction="); + myDebug(", Last Tx Action="); switch (EMS_TxTelegram.action) { case EMS_TX_READ: myDebug("read"); @@ -133,41 +217,42 @@ void showInfo() { break; } - myDebug("\nBoiler stats:\n"); + myDebug("\n\n%sBoiler stats:%s\n", COLOR_BOLD_ON, COLOR_BOLD_OFF); - // UBAMonitorWWMessage & UBAParameterWW - myDebug(" Warm Water activated: %s\n", (EMS_Boiler.wWActivated ? "yes" : "no")); - myDebug(" Warm Water selected temperature: %d C\n", EMS_Boiler.wWSelTemp); - myDebug(" Warm Water circulation pump available: %s\n", (EMS_Boiler.wWCircPump ? "yes" : "no")); - myDebug(" Warm Water desired temperature: %d C\n", EMS_Boiler.wWDesiredTemp); - myDebug(" Warm Water current temperature: %s C\n", _float_to_char(s, EMS_Boiler.wWCurTmp)); - myDebug(" Warm Water # starts: %d times\n", EMS_Boiler.wWStarts); + // UBAParameterWW + _renderBoolValue("Warm Water activated", EMS_Boiler.wWActivated); + _renderBoolValue("Warm Water circulation pump available", EMS_Boiler.wWCircPump); + _renderIntValue("Warm Water selected temperature", "C", EMS_Boiler.wWSelTemp); + _renderIntValue("Warm Water desired temperature", "C", EMS_Boiler.wWDesiredTemp); + + // UBAMonitorWWMessage + _renderFloatValue("Warm Water current temperature", "C", EMS_Boiler.wWCurTmp); + _renderIntValue("Warm Water # starts", "times", EMS_Boiler.wWStarts); myDebug(" Warm Water active time: %d days %d hours %d minutes\n", EMS_Boiler.wWWorkM / 1440, (EMS_Boiler.wWWorkM % 1440) / 60, EMS_Boiler.wWWorkM % 60); - myDebug(" Warm Water 3-way valve: %s\n", EMS_Boiler.wWHeat ? "on" : "off"); + _renderBoolValue("Warm Water 3-way valve", EMS_Boiler.wWHeat); // UBAMonitorFast - myDebug(" Selected flow temperature: %d C\n", EMS_Boiler.selFlowTemp); - myDebug(" Current flow temperature: %s C\n", _float_to_char(s, EMS_Boiler.curFlowTemp)); - myDebug(" Return temperature: %s C\n", _float_to_char(s, EMS_Boiler.retTemp)); - - myDebug(" Gas: %s\n", EMS_Boiler.burnGas ? "on" : "off"); - myDebug(" Boiler pump: %s\n", EMS_Boiler.heatPmp ? "on" : "off"); - myDebug(" Fan: %s\n", EMS_Boiler.fanWork ? "on" : "off"); - myDebug(" Ignition: %s\n", EMS_Boiler.ignWork ? "on" : "off"); - myDebug(" Circulation pump: %s\n", EMS_Boiler.wWCirc ? "on" : "off"); - myDebug(" Burner max power: %d %%\n", EMS_Boiler.selBurnPow); - myDebug(" Burner current power: %d %%\n", EMS_Boiler.curBurnPow); - myDebug(" Flame current: %s uA\n", _float_to_char(s, EMS_Boiler.flameCurr)); - myDebug(" System pressure: %s bar\n", _float_to_char(s, EMS_Boiler.sysPress)); + _renderIntValue("Selected flow temperature", "C", EMS_Boiler.selFlowTemp); + _renderFloatValue("Current flow temperature", "C", EMS_Boiler.curFlowTemp); + _renderFloatValue("Return temperature", "C", EMS_Boiler.retTemp); + _renderBoolValue("Gas", EMS_Boiler.burnGas); + _renderBoolValue("Boiler pump", EMS_Boiler.heatPmp); + _renderBoolValue("Fan", EMS_Boiler.fanWork); + _renderBoolValue("Ignition", EMS_Boiler.ignWork); + _renderBoolValue("Circulation pump", EMS_Boiler.wWCirc); + _renderIntValue("Burner selected max power", "%", EMS_Boiler.selBurnPow); + _renderIntValue("Burner current power", "%", EMS_Boiler.curBurnPow); + _renderFloatValue("Flame current", "uA", EMS_Boiler.flameCurr); + _renderFloatValue("System pressure", "bar", EMS_Boiler.sysPress); // UBAMonitorSlow - myDebug(" Outside temperature: %s C\n", _float_to_char(s, EMS_Boiler.extTemp)); - myDebug(" Boiler temperature: %s C\n", _float_to_char(s, EMS_Boiler.boilTemp)); - myDebug(" Pump modulation: %d %%\n", EMS_Boiler.pumpMod); - myDebug(" # burner restarts: %d\n", EMS_Boiler.burnStarts); + _renderFloatValue("Outside temperature", "C", EMS_Boiler.extTemp); + _renderFloatValue("Boiler temperature", "C", EMS_Boiler.boilTemp); + _renderIntValue("Pump modulation", "%", EMS_Boiler.pumpMod); + _renderIntValue("Burner # restarts", "times", EMS_Boiler.burnStarts); myDebug(" Total burner operating time: %d days %d hours %d minutes\n", EMS_Boiler.burnWorkMin / 1440, (EMS_Boiler.burnWorkMin % 1440) / 60, @@ -179,7 +264,8 @@ void showInfo() { // Thermostat stats if (Boiler_Status.thermostat_enabled) { - myDebug("Thermostat stats:\n Thermostat time is %02d:%02d:%02d %d/%d/%d\n", + myDebug("\n%sThermostat stats:%s\n", COLOR_BOLD_ON, COLOR_BOLD_OFF); + myDebug(" Thermostat time is %02d:%02d:%02d %d/%d/%d\n", EMS_Thermostat.hour, EMS_Thermostat.minute, EMS_Thermostat.second, @@ -187,8 +273,8 @@ void showInfo() { EMS_Thermostat.month, EMS_Thermostat.year + 2000); - myDebug(" Setpoint room temperature is %s C\n", _float_to_char(s, EMS_Thermostat.setpoint_roomTemp)); - myDebug(" Current room temperature is %s C\n", _float_to_char(s, EMS_Thermostat.curr_roomTemp)); + _renderFloatValue("Setpoint room temperature", "C", EMS_Thermostat.setpoint_roomTemp); + _renderFloatValue("Current room temperature", "C", EMS_Thermostat.curr_roomTemp); myDebug(" Mode is set to "); if (EMS_Thermostat.mode == 0) { myDebug("low\n"); @@ -197,20 +283,10 @@ void showInfo() { } else if (EMS_Thermostat.mode == 2) { myDebug("clock/auto\n"); } else { - myDebug("\n"); + myDebug("?\n"); } } - // show the Shower Info - if (Boiler_Status.shower_enabled) { - myDebug("Shower stats:\n Shower is %s\n", (Boiler_Shower.showerOn ? "on" : "off")); - char s[70]; - uint8_t sec = (uint8_t)((Boiler_Shower.duration / 1000) % 60); - uint8_t min = (uint8_t)((Boiler_Shower.duration / (1000 * 60)) % 60); - sprintf(s, " Last shower duration was %d minutes and %d %s\n", min, sec, (sec == 1) ? "second" : "seconds"); - myDebug(s); - } - myDebug("\n"); } @@ -242,7 +318,7 @@ void _boilerInitCommands() { settingsRegisterCommand(F("BOILER.LOGGING"), [](Embedis * e) { if (e->argc < 2) { - DEBUG_MSG_P(PSTR("-ERROR: arg is 0 or 1\n")); + DEBUG_MSG_P(PSTR("-ERROR: arg is 0, 1 or 2\n")); return; } @@ -269,43 +345,60 @@ void _boilerInitCommands() { }); } -void _boilerMQTTCallback(unsigned int type, const char * topic, const char * payload) { - /* - if (type == MQTT_CONNECT_EVENT) { - char buffer[strlen(MQTT_TOPIC_LED) + 3]; - snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_LED); - mqttSubscribe(buffer); - } +// send values to HA via MQTT +void publishValues() { + char s[20]; // for formatting strings - if (type == MQTT_MESSAGE_EVENT) { + // Boiler values as one JSON object + StaticJsonBuffer<512> jsonBuffer; + char data[512]; + JsonObject & root = jsonBuffer.createObject(); - // Match topic - String t = mqttMagnitude((char *) topic); - if (!t.startsWith(MQTT_TOPIC_LED)) return; + root["wWSelTemp"] = _int_to_char(s, EMS_Boiler.wWSelTemp); + root["wWActivated"] = _bool_to_char(s, EMS_Boiler.wWActivated); + root["wWCurTmp"] = _float_to_char(s, EMS_Boiler.wWCurTmp); + root["wWHeat"] = _bool_to_char(s, EMS_Boiler.wWHeat); + root["curFlowTemp"] = _float_to_char(s, EMS_Boiler.curFlowTemp); + root["retTemp"] = _float_to_char(s, EMS_Boiler.retTemp); + root["burnGas"] = _bool_to_char(s, EMS_Boiler.burnGas); + root["heatPmp"] = _bool_to_char(s, EMS_Boiler.heatPmp); + root["fanWork"] = _bool_to_char(s, EMS_Boiler.fanWork); + root["ignWork"] = _bool_to_char(s, EMS_Boiler.ignWork); + root["wWCirc"] = _bool_to_char(s, EMS_Boiler.wWCirc); + root["selBurnPow"] = _int_to_char(s, EMS_Boiler.selBurnPow); + root["curBurnPow"] = _int_to_char(s, EMS_Boiler.curBurnPow); + root["sysPress"] = _float_to_char(s, EMS_Boiler.sysPress); + root["boilTemp"] = _float_to_char(s, EMS_Boiler.boilTemp); + root["pumpMod"] = _int_to_char(s, EMS_Boiler.pumpMod); - // Get led ID - unsigned int ledID = t.substring(strlen(MQTT_TOPIC_LED)+1).toInt(); - if (ledID >= _ledCount()) { - DEBUG_MSG_P(PSTR("[LED] Wrong ledID (%d)\n"), ledID); + size_t len = root.measureLength(); + root.printTo(data, len + 1); // form the json string + mqttSend(TOPIC_BOILER_DATA, data); + + // handle the thermostat values separately + if (EMS_Sys_Status.emsThermostatEnabled) { + // only send thermostat values if we actually have them + if (((int)EMS_Thermostat.curr_roomTemp == (int)0) || ((int)EMS_Thermostat.setpoint_roomTemp == (int)0)) { return; } - // Check if LED is managed - if (_ledMode(ledID) != LED_MODE_MQTT) return; + mqttSend(TOPIC_THERMOSTAT_CURRTEMP, _float_to_char(s, EMS_Thermostat.curr_roomTemp)); + mqttSend(TOPIC_THERMOSTAT_SELTEMP, _float_to_char(s, EMS_Thermostat.setpoint_roomTemp)); - // get value - unsigned char value = relayParsePayload(payload); - - // Action to perform - if (value == 2) { - _ledToggle(ledID); + // send mode 0=low, 1=manual, 2=clock/auto + if (EMS_Thermostat.mode == 0) { + mqttSend(TOPIC_THERMOSTAT_MODE, "low"); + } else if (EMS_Thermostat.mode == 1) { + mqttSend(TOPIC_THERMOSTAT_MODE, "manual"); } else { - _ledStatus(ledID, value == 1); + mqttSend(TOPIC_THERMOSTAT_MODE, "auto"); // must be auto } - } - */ +} + + +void _boilerMQTTCallback(unsigned int type, const char * topic, const char * payload) { } // TELNET commands @@ -330,19 +423,18 @@ void boilerSetup() { _boilerConfigure(); wsOnSendRegister(_boilerWebSocketOnSend); - wsOnAfterParseRegister(_boilerConfigure); wsOnActionRegister(_boilerWebSocketOnAction); wsOnReceiveRegister(_boilerWebSocketOnReceive); mqttRegister(_boilerMQTTCallback); - _boilerInitCommands(); + _boilerInitCommands(); // telnet // init shower - Boiler_Shower.timerStart = 0; - Boiler_Shower.timerPause = 0; - Boiler_Shower.duration = 0; - Boiler_Shower.isColdShot = false; + Boiler_Shower.timerStart = 0; + Boiler_Shower.timerPause = 0; + Boiler_Shower.duration = 0; + Boiler_Shower.doingColdShot = false; // ems init values ems_init(); @@ -352,8 +444,22 @@ void boilerSetup() { // Register loop espurnaRegisterLoop(_boilerLoop); + + espurnaRegisterReload([]() { _boilerConfigure(); }); } // LOOP void _boilerLoop() { + static unsigned long last_boilersend = 0; + if ((last_boilersend == 0) || (millis() - last_boilersend > BOILERSEND_INTERVAL)) { + last_boilersend = millis(); + + // get 0x33 WW values manually + ems_doReadCommand(EMS_TYPE_UBAParameterWW); + +#if MQTT_SUPPORT + // send MQTT + publishValues(); +#endif + } } diff --git a/espurna/custom.h b/espurna/custom.h index a7dd25ab6..f18d8f0ce 100644 --- a/espurna/custom.h +++ b/espurna/custom.h @@ -5,9 +5,6 @@ #undef EMBEDDED_WEB #define EMBEDDED_WEB 1 -#undef NTP_SERVER -#define NTP_SERVER "nl.pool.ntp.org" - //#undef MQTT_TOPIC //#define MQTT_TOPIC "/{identifier}" // default is "{hostname}" diff --git a/espurna/index.html b/espurna/index.html index cabc4efb8..306f90374 100644 --- a/espurna/index.html +++ b/espurna/index.html @@ -12,8 +12,12 @@ - + + + + + @@ -25,54 +29,56 @@
-
+ -
+

SECURITY

-

Before using this device you have to change the default password for the user 'admin'. This password - will be used for the - AP mode hotspot, the - web interface (where you are now) and the - over-the-air updates.

+

Before using this device you have to change the default password for the user admin. + This password will be used for the AP mode hotspot, the web + interface (where you are now) and the over-the-air updates.

-
- - -
-
- The administrator password is used to access this web interface (user 'admin'), but also to connect to the device when in - AP mode or to flash a new firmware over-the-air (OTA). -
It must have at least - five characters (numbers and letters and any of these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) - and at least - one lowercase and - one uppercase or - one number.
+ + +
- - + + +
- -
- -
+ +
+
+ Password must be 8..63 characters (numbers and letters and any of + these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) and have at least + one lowercase and one uppercase or one number.
+
+ + +
+ +
+ +
+
- -
- +
@@ -95,11 +101,11 @@
  • @@ -114,9 +120,21 @@ INFLUXDB
  • +
  • LIGHTS
  • + + + +
  • + MAPPING +
  • + +
  • + MESSAGES +
  • +
  • MQTT @@ -126,17 +144,21 @@ NTP
  • +
  • RF
  • +
  • SCHEDULE
  • -
  • - SENSORS + +
  • + SENSORS
  • +
  • SWITCHES @@ -167,14 +189,12 @@ @@ -196,151 +216,111 @@
    +
    -
    -
    + +
    + + + +
    + +
    +
    + +
    + +
    +
    +
    Manufacturer
    -
    - -
    +
    Device
    -
    - -
    +
    Chip ID
    -
    - -
    +
    Wifi MAC
    -
    - -
    +
    SDK version
    -
    - -
    +
    Core version
    -
    - -
    +
    Firmware name
    -
    - -
    +
    Firmware version
    -
    - -
    +
    - +
    Firmware revision
    +
    Firmware build date
    -
    - -
    +
    Firmware size
    -
    - -
    +
    Free space
    -
    - -
    +
    Network
    -
    - -
    +
    BSSID
    -
    - -
    +
    Channel
    -
    - -
    +
    RSSI
    -
    - -
    +
    IP
    - +
    Free heap
    -
    - -
    +
    Load average
    -
    - - % -
    +
    %
    VCC
    -
    - ? - mV -
    +
    ? mV
    MQTT Status
    -
    - -
    +
    NTP Status
    -
    - -
    +
    Current time
    -
    - -
    +
    Uptime
    -
    - -
    +
    Last update
    -
    - ? - seconds ago -
    +
    ? seconds ago
    @@ -350,8 +330,7 @@ -
    - +
    @@ -365,33 +344,36 @@
    - +
    - This name will identify this device in your network (http://<hostname>.local). -
    Hostname may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), - the digits '0' through '9', and the hyphen ('-'). They can neither start or end with - an hyphen. -
    For this setting to take effect you should restart the wifi interface by clicking the - "Reconnect" button. + This name will identify this device in your network + (http://<hostname>.local).
    + Hostname may contain only the ASCII letters 'a' through 'z' (in a case-insensitive + manner), the digits '0' through '9', and the hyphen ('-'). They can neither start + or end with an hyphen.
    + For this setting to take effect you should restart the wifi interface by clicking + the "Reconnect" button.
    - +
    - Delay in milliseconds to detect a double click (from 0 to 1000ms). -
    The lower this number the faster the device will respond to button clicks but the harder - it will be to get a double click. Increase this number if you are having trouble to double - click the button. Set this value to 0 to disable double click. You won't be able to set - the device in AP mode manually but your device will respond immediately to button clicks. -
    You will have to - reboot the device after updating for this setting to apply. + Delay in milliseconds to detect a double click (from 0 to 1000ms).
    + The lower this number the faster the device will respond to button clicks but the + harder it will be to get a double click. + Increase this number if you are having trouble to double click the button. + Set this value to 0 to disable double click. You won't be able to set the device in + AP mode manually but your device will respond immediately to button clicks.
    + You will have to reboot the device after updating for this setting + to apply.
    @@ -410,35 +392,36 @@
    - This setting defines the behaviour of the main LED in the board. -
    When in "WiFi status" it will blink at 1Hz when trying to connect. If successfully connected - it will briefly blink every 5 seconds if in STA mode or every second if in AP mode. -
    When in "Relay status" mode the LED will be ON whenever any relay is ON, and OFF otherwise. - This is global status notification. -
    When in "MQTT managed" mode you will be able to set the LED state sending a message - to "<base_topic>/led/0/set" with a payload of 0, 1 or 2 (to toggle it). -
    When in "Find me" mode the LED will be ON when all relays are OFF. This is meant to - locate switches at night. -
    When in "Relay & WiFi" mode it will follow the WiFi status but will stay mostly - off when relays are OFF, and mostly ON when any of them is ON. -
    When in "Find me & WiFi" mode is the opposite of the "Relay & WiFi", it will - follow the WiFi status but will stay mostly on when relays are OFF, and mostly OFF when - any of them is ON. -
    "Always ON" and "Always OFF" modes are self-explanatory. + This setting defines the behaviour of the main LED in the board.
    + When in "WiFi status" it will blink at 1Hz when trying to connect. If successfully + connected it will briefly blink every 5 seconds if in STA mode or every second if + in AP mode.
    + When in "Relay status" mode the LED will be ON whenever any relay is ON, and OFF + otherwise. This is global status notification.
    + When in "MQTT managed" mode you will be able to set the LED state sending a message + to "<base_topic>/led/0/set" with a payload of 0, 1 or 2 (to toggle it).
    + When in "Find me" mode the LED will be ON when all relays are OFF. This is meant to + locate switches at night.
    + When in "Relay & WiFi" mode it will follow the WiFi status but will stay mostly + off when relays are OFF, and mostly ON when any of them is ON.
    + When in "Find me & WiFi" mode is the opposite of the "Relay & WiFi", it + will follow the WiFi status but will stay mostly on when relays are OFF, and mostly + OFF when any of them is ON.
    + "Always ON" and "Always OFF" modes are self-explanatory.
    -
    - -
    +
    +
    +
    @@ -461,7 +444,8 @@
    -
    Define how the different switches should be synchronized.
    +
    Define how the different switches should be + synchronized.
    @@ -470,7 +454,10 @@
    +
    + +
    @@ -484,82 +471,72 @@
    -
    - -
    +
    -
    Use the first three channels as RGB channels. This will also enable the color picker in the - web UI. Will only work if the device has at least 3 dimmable channels. -
    Reload the page to update the web interface.
    +
    Use the first three channels as RGB channels. + This will also enable the color picker in the web UI. Will only work if the device + has at least 3 dimmable channels.
    Reload the page to update the web interface.
    -
    - -
    +
    -
    Use RGB color picker if enabled (plus brightness), otherwise use HSV (hue-saturation-value) - style -
    +
    Use RGB color picker if enabled (plus + brightness), otherwise use HSV (hue-saturation-value) style
    -
    - -
    +
    -
    Use forth dimmable channel as (cold) white light calculated out of the RGB values. -
    Will only work if the device has at least 4 dimmable channels. -
    Enabling this will render useless the "Channel 4" slider in the status page. -
    Reload the page to update the web interface.
    +
    Use forth dimmable channel as (cold) white + light calculated out of the RGB values.
    Will only work if the device has at + least 4 dimmable channels.
    Enabling this will render useless the "Channel 4" + slider in the status page.
    Reload the page to update the web interface.
    -
    - -
    +
    -
    Use fifth dimmable channel as warm white light and the forth dimmable channel as cold white. -
    Will only work if the device has at least 5 dimmable channels and "white channel" above - is also ON. -
    Enabling this will render useless the "Channel 5" slider in the status page. -
    Reload the page to update the web interface.
    +
    Use fifth dimmable channel as warm white light + and the forth dimmable channel as cold white.
    Will only work if the device has + at least 5 dimmable channels and "white channel" above is also ON.
    Enabling + this will render useless the "Channel 5" slider in the status page.
    Reload the + page to update the web interface.
    -
    - -
    +
    -
    Use gamma correction for RGB channels. -
    Will only work if "use colorpicker" above is also ON.
    +
    Use gamma correction for RGB channels.
    Will + only work if "use colorpicker" above is also ON.
    -
    - -
    +
    -
    Use CSS style to report colors to MQTT and REST API. -
    Red will be reported as "#FF0000" if ON, otherwise "255,0,0"
    +
    Use CSS style to report colors to MQTT and + REST API.
    Red will be reported as "#FF0000" if ON, otherwise "255,0,0"
    -
    - -
    +
    If enabled color changes will be smoothed.
    @@ -567,21 +544,18 @@
    -
    - -
    +
    -
    Time in millisecons to transition from one color to another.
    +
    Time in millisecons to transition from one + color to another.
    -
    - -
    -
    - -
    +
    +
    Sync color between different lights.
    @@ -589,7 +563,10 @@
    + + +
    @@ -603,153 +580,145 @@
    -
    - -
    -
    - -
    -
    - -
    +
    +
    +
    - + + +
    + + +
    - The administrator password is used to access this web interface (user 'admin'), but also to connect to the device when in - AP mode or to flash a new firmware over-the-air (OTA). -
    It must have at least - five characters (numbers and letters and any of these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) - and at least - one lowercase and - one uppercase or - one number.
    -
    - -
    - - + The administrator password is used to access this web interface (user 'admin'), but + also to connect to the device when in AP mode or to flash a new firmware + over-the-air (OTA).
    + It must be 8..63 characters (numbers and letters and any of these + special characters: _,.;:~!?@#$%^&*<>\|(){}[]) and have at least one + lowercase and one uppercase or one number.
    - +
    - This is the port for the web interface and API requests. If different than 80 (standard HTTP port) you will have to add it - explicitly to your requests: http://myip:myport/ + This is the port for the web interface and API requests. + If different than 80 (standard HTTP port) you will have to add it explicitly to + your requests: http://myip:myport/
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    - -
    - -
    +
    + +
    - By default, some magnitudes are being preprocessed and filtered to avoid spurious values. If you want to get real-time values - (not preprocessed) in the API turn on this setting. + If enabled, API requests to change a status (like a relay) must be done using PUT. + If disabled you can issue them as GET requests (easier from a browser).
    -
    - - -
    - -
    +
    + +
    +
    - This is the key you will have to pass with every HTTP request to the API, either to get or write values. All API calls must - contain the - apikey parameter with the value above. To know what APIs are enabled do a call - to - /apis. + By default, some magnitudes are being preprocessed and filtered to avoid spurious + values. + If you want to get real-time values (not preprocessed) in the API turn on this + setting. +
    +
    + +
    + + +
    +
    +
    + This is the key you will have to pass with every HTTP request to the API, either to + get or write values. + All API calls must contain the apikey parameter with the value + above. + To know what APIs are enabled do a call to /apis.
    -
    - -
    +
    -
    Turn ON to be able to telnet to your device while connected to your home router. -
    TELNET is always enabled in AP mode.
    +
    Turn ON to be able to telnet to your device + while connected to your home router.
    TELNET is always enabled in AP mode.
    -
    - -
    +
    -
    This name address of the NoFUSS server for automatic remote updates (see https://bitbucket.org/xoseperez/nofuss).
    +
    This name address of the NoFUSS server for + automatic remote updates (see https://bitbucket.org/xoseperez/nofuss).
    -
    - -
    -
    - -
    +
    +
    -
    The device has - bytes available for OTA updates. If your image is larger than this consider doing - a - - two-step update - .
    +
    The device has + bytes available for OTA updates. If your image is larger than this consider doing a + two-step + update.
    -
    - -
    +
    + +

    WIFI

    -

    You can configure up to 5 different WiFi networks. The device will try to connect in order of signal - strength. -

    +

    You can configure up to 5 different WiFi networks. The device will try to connect in order + of signal strength.

    @@ -760,19 +729,17 @@
    -
    - -
    +
    - ESPurna will scan for visible WiFi SSIDs and try to connect to networks defined below in order of - signal strength, even if multiple AP share the same SSID. When disabled, ESPurna - will try to connect to the networks in the same order they are listed below. Disable - this option if you are - connecting to a single access point (or router) or to a - hidden SSID. - + ESPurna will scan for visible WiFi SSIDs and try to connect to networks defined + below in order of signal strength, even if multiple AP share the + same SSID. + When disabled, ESPurna will try to connect to the networks in the same order they + are listed below. + Disable this option if you are connecting to a single access point + (or router) or to a hidden SSID.
    @@ -792,7 +759,9 @@
    + +
    @@ -806,22 +775,108 @@
    - - + + + +
    +
    + +
    +
    + +
    +

    MAPPING

    +

    + Configure the map between nodeID/key and MQTT topic. Messages from the given nodeID with + the given key will be forwarded to the specified topic. + You can also configure a default topic using {nodeid} and {key} as placeholders, if the + default topic is empty messages without defined map will be discarded. +

    +
    + +
    + +
    + + Default topic + +
    + +
    + + Specific topics + +
    + + + +
    +
    + +
    +
    + +
    +
    +
    +

    MESSAGES

    +

    + Messages being received. Previous messages are not displayed. + You have to keep the page open in order to keep receiving them. + You can filter/unfilter by clicking on the values. + Left click on a value to show only rows that match that value, middle click to show all + rows but those matching that value. + Filtered colums have red headers. +

    +
    + +
    + + + + + + + + + + + + + + + + + +
    TimestampSenderIDPacketIDTargetIDKeyValueRSSIDuplicatesMissing
    + + + + + + +
    +
    +
    + + +

    MQTT

    -

    Configure an - MQTT broker in your network and you will be able to change the switch status via an - MQTT message.

    +

    Configure an MQTT broker in your network and you will be able to change + the switch status via an MQTT message.

    @@ -830,15 +885,13 @@
    -
    - -
    +
    - +
    @@ -848,14 +901,15 @@
    - +
    - + +
    @@ -864,7 +918,8 @@
    - If left empty the firmware will generate a client ID based on the serial number of the chip. + If left empty the firmware will generate a client ID based on the serial number of + the chip.
    @@ -879,21 +934,18 @@
    -
    - -
    +
    - +
    -
    - -
    +
    @@ -901,11 +953,9 @@
    - This is the fingerprint for the SSL certificate of the server. -
    You can get it using - https://www.grc.com/fingerprints.htm -
    or using openssl from a linux box by typing: -
    + This is the fingerprint for the SSL certificate of the server.
    + You can get it using https://www.grc.com/fingerprints.htm
    + or using openssl from a linux box by typing:
    $ openssl s_client -connect <host>:<port> < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin
    @@ -915,65 +965,48 @@
    - This is the root topic for this device. The {hostname} and {mac} placeholders will be replaced by the device hostname and - MAC address. -
    - - <root>/relay/#/set Send a 0 or a 1 as a payload to this topic to switch - it on or off. You can also send a 2 to toggle its current state. Replace # with the switch - ID (starting from 0). If the board has only one switch it will be 0. -
    - - - <root>/rgb/set Set the color using this topic, your can either send - an "#RRGGBB" value or "RRR,GGG,BBB" (0-255 each). -
    -
    - - - <root>/hsv/set Set the color using hue (0-360), saturation (0-100) - and value (0-100) values, comma separated. -
    -
    - - - <root>/brightness/set Set the brighness (0-255). -
    -
    - - - <root>/channel/#/set Set the value for a single color channel (0-255). - Replace # with the channel ID (starting from 0 and up to 4 for RGBWC lights). -
    -
    - - - <root>/mired/set Set the temperature color in mired. -
    -
    - - - <root>/status The device will report a 1 to this topic every few minutes. - Upon MQTT disconnecting this will be set to 0. -
    - Other values reported (depending on the build) are: - firmware and - version, - hostname, - IP, - MAC, signal strenth ( - RSSI), - uptime (in seconds), - free heap and - power supply. + This is the root topic for this device. The {hostname} and {mac} placeholders will + be replaced by the device hostname and MAC address.
    + - <root>/relay/#/set Send a 0 or a 1 as a payload to this + topic to switch it on or off. You can also send a 2 to toggle its current state. + Replace # with the switch ID (starting from 0). If the board has only one switch it + will be 0.
    + + - <root>/rgb/set Set the + color using this topic, your can either send an "#RRGGBB" value or + "RRR,GGG,BBB" (0-255 each).
    + - <root>/hsv/set Set the + color using hue (0-360), saturation (0-100) and value (0-100) values, comma + separated.
    + - <root>/brightness/set + Set the brighness (0-255).
    + - <root>/channel/#/set Set + the value for a single color channel (0-255). Replace # with the channel ID + (starting from 0 and up to 4 for RGBWC lights).
    + - <root>/mired/set Set the + temperature color in mired.
    + + - <root>/status The device will report a 1 to this topic + every few minutes. Upon MQTT disconnecting this will be set to 0.
    + - Other values reported (depending on the build) are: firmware and + version, hostname, IP, MAC, + signal strenth (RSSI), uptime (in seconds), + free heap and power supply.
    -
    - -
    +
    +
    - All messages (except the device status) will be included in a JSON payload along with the timestamp and hostname and sent - under the - <root>/data topic. -
    Messages will be queued and sent after 100ms, so different messages could be merged - into a single payload. -
    Subscriptions will still be done to single topics. + All messages (except the device status) will be included in a JSON payload along + with the timestamp and hostname + and sent under the <root>/data topic.
    + Messages will be queued and sent after 100ms, so different messages could be merged + into a single payload.
    + Subscriptions will still be done to single topics.
    @@ -981,13 +1014,15 @@
    +
    +

    NTP

    -

    Configure your NTP (Network Time Protocol) servers and local configuration to keep your device time - up to the second for your location.

    +

    Configure your NTP (Network Time Protocol) servers and local configuration to keep your + device time up to the second for your location.

    @@ -1011,9 +1046,7 @@
    -
    - -
    +
    @@ -1028,7 +1061,9 @@
    + +
    @@ -1046,9 +1081,7 @@
    -
    - -
    +
    @@ -1058,7 +1091,8 @@
    - +
    Sensors & actuators @@ -1069,13 +1103,17 @@
    +
    +
    + +
    @@ -1092,14 +1130,16 @@
    -
    - -
    +
    - Home Assistant auto-discovery feature. Enable and save to add the device to your HA console. When using a colour light you - might want to disable CSS style so Home Assistant can parse the color. + Home Assistant auto-discovery feature. Enable and save to add the device to your HA + console. + + When using a colour light you might want to disable CSS style so Home Assistant can + parse the color. +
    @@ -1112,14 +1152,14 @@
    -
    - -
    +
    - These are the settings you should copy to your Home Assistant "configuration.yaml" file. If any of the sections below (switch, - light, sensor) already exists, do not duplicate it, simply copy the contents of the section - below the ones already present. + These are the settings you should copy to your Home Assistant "configuration.yaml" + file. + If any of the sections below (switch, light, sensor) already exists, do not + duplicate it, + simply copy the contents of the section below the ones already present.
    @@ -1131,9 +1171,9 @@
    + - - +
    @@ -1151,9 +1191,7 @@
    -
    - -
    +
    @@ -1164,24 +1202,30 @@ Sensors & actuators
    -
    Enter the field number to send each data to, 0 disable notifications from that component.
    +
    Enter the field number to send each data to, 0 disable + notifications from that component.
    +
    +
    + +

    INFLUXDB

    - Configure the connection to your InfluxDB server. Leave the host field empty to disable InfluxDB connection. + Configure the connection to your InfluxDB server. Leave the host field empty to disable + InfluxDB connection.

    @@ -1191,9 +1235,7 @@
    -
    - -
    +
    @@ -1213,19 +1255,24 @@
    - +
    - + +
    +
    +
    @@ -1241,19 +1288,16 @@
    - Write a command and click send to execute it on the device. The output will be shown in the debug text area below. + Write a command and click send to execute it on the device. The output will be + shown in the debug text area below.
    -
    - -
    +
    -
    - -
    +
    @@ -1261,8 +1305,11 @@
    +
    -
    + +
    +

    SENSOR CONFIGURATION

    @@ -1280,26 +1327,33 @@
    - Select the interval between readings. These will be filtered and averaged for the report. The default and recommended value - is 6 seconds. + Select the interval between readings. These will be filtered and averaged for the + report. + Please mind some sensors do not have fast refresh intervals. Check the sensor + datasheet to know the minimum read interval. + The default and recommended value is 6 seconds.
    -
    - -
    +
    @@ -1307,6 +1361,21 @@
    +
    + +
    +
    +
    +
    + Save aggregated data to EEPROM after these many reports. At the moment this only + applies to total energy readings. + Please mind: saving data to EEPROM too often will wear out the flash memory + quickly. + Set it to 0 to disable this feature (default value). +
    +
    +
    -
    +
    - @@ -1333,27 +1402,39 @@
    - +
    - Temperature correction value is added to the measured value which may be inaccurate due to many factors. The value can be - negative. + Temperature correction value is added to the measured value which may be inaccurate + due to many factors. The value can be negative.
    - +
    - Humidity correction value is added to the measured value which may be inaccurate due to many factors. The value can be negative. + Humidity correction value is added to the measured value which may be inaccurate + due to many factors. The value can be negative.
    +
    + +
    +
    +
    +
    Move this switch to ON and press "Save" to + reset gas sensor calibration. Check the sensor datasheet for calibration + conditions.
    +
    + Energy monitor
    @@ -1365,90 +1446,61 @@
    - +
    -
    In Amperes (A). If you are using a pure resistive load like a bulb, this will be the ratio - between the two previous values, i.e. power / voltage. You can also use a current clamp - around one of the power wires to get this value.
    +
    In Amperes (A). If you are using a pure + resistive load like a bulb, this will be the ratio between the two previous values, + i.e. power / voltage. You can also use a current clamp around one of the power + wires to get this value.
    - +
    -
    In Volts (V). Enter your the nominal AC voltage for your household or facility, or use multimeter - to get this value.
    +
    In Volts (V). Enter your the nominal AC + voltage for your household or facility, or use multimeter to get this value.
    - +
    -
    In Watts (W). Calibrate your sensor connecting a pure resistive load (like a bulb) and enter - here the its nominal power or use a multimeter.
    +
    In Watts (W). Calibrate your sensor connecting + a pure resistive load (like a bulb) and enter here the its nominal power or use a + multimeter.
    -
    - -
    +
    -
    Move this switch to ON and press "Save" to revert to factory calibration values.
    +
    Move this switch to ON and press "Save" to + revert to factory calibration values.
    -
    - -
    +
    -
    Move this switch to ON and press "Save" to set energy count to 0.
    +
    Move this switch to ON and press "Save" to set + energy count to 0.
    + + -
    - -
    -

    RADIO FREQUENCY

    -

    - Sonoff 433 RF Bridge & RF Link Configuration -
    -
    This page allows you to configure the RF codes for the Sonoff RFBridge 433 and also for a basic - RF receiver. -
    -
    To learn a new code click - LEARN (the Sonoff RFBridge will beep) then press a button on the remote, the new code - should show up (and the RFBridge will double beep). If the device double beeps but the code does - not update it has not been properly learnt. Keep trying. -
    -
    Modify or create new codes manually and then click - SAVE to store them in the device memory. If your controlled device uses the same code - to switch ON and OFF, learn the code with the ON button and copy paste it to the OFF input box, - then click SAVE on the last one to store the value. -
    -
    Delete any code clicking the - FORGET button. - -
    -
    You can also specify 116-chars long RAW codes. Raw codes require a - specific firmware for for the EFM8BB1.
    -

    -
    - -
    -
    -
    -
    -
    -
    - +

    BOILER

    @@ -1464,7 +1516,8 @@
    -
    Enable if you want to read/write from Thermostat
    +
    Enable if you want to read/write from + Thermostat
    @@ -1499,95 +1552,108 @@
    - -
    - + +
    +
    -
    - +
    +

    RADIO FREQUENCY

    +

    + Sonoff 433 RF Bridge & RF Link Configuration

    + This page allows you to configure the RF codes for the Sonoff RFBridge 433 and also for a + basic RF receiver.

    + To learn a new code click LEARN (the Sonoff RFBridge will beep) then press + a button on the remote, the new code should show up (and the RFBridge will double beep). If + the device double beeps but the code does not update it has not been properly learnt. Keep + trying.

    + Modify or create new codes manually and then click SAVE to store them in + the device memory. If your controlled device uses the same code to switch ON and OFF, learn + the code with the ON button and copy paste it to the OFF input box, then click SAVE on the + last one to store the value.

    + Delete any code clicking the FORGET button. +

    You can also specify 116-chars long RAW + codes. Raw codes require a specific + firmware for for the EFM8BB1.
    +

    +
    + +
    +
    +
    +
    +
    + +
    + + + +
    + +
    +
    - Switch # - - + Switch #
    -
    - -
    +
    -
    - -
    -
    - -
    -
    - -
    +
    +
    +
    -
    - -
    +
    -
    - -
    -
    - -
    -
    - -
    +
    +
    +
    +
    -
    - -
    -
    - -
    +
    +
    - + + - +
    -
    Leave empty for DNS negotiation
    +
    Leave empty for DHCP negotiation
    - +
    Set when using a static IP
    - +
    Usually 255.255.255.0 for /24 networks
    - +
    Set the Domain Name Server IP to use when using a static IP
    @@ -1614,10 +1680,9 @@
    -
    - -
    +
    +
    @@ -1628,11 +1693,9 @@
    -
    - -
    +
    -
    +
    @@ -1650,6 +1713,7 @@
    +
    @@ -1658,26 +1722,19 @@
    +
    - -
    - -
    + +
    - Switch # - (GPIO - ) + Switch # (GPIO)
    -
    - -
    +
    -
    - -
    +
    -
    - -
    -
    - -
    +
    +
    -
    - -
    -
    - -
    +
    +
    -
    - -
    +
    -
    - -
    +
    -
    +
    +
    -
    - -
    +
    +
    -
    - -
    +
    +
    -
    - -
    +
    + -
    + +
    +
    + +
    @@ -1783,13 +1831,6 @@
    -
    -
    - - -
    -
    -
    @@ -1805,7 +1846,9 @@
    + +
    @@ -1815,6 +1858,21 @@
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + @@ -1824,8 +1882,12 @@ - + + + + + \ No newline at end of file diff --git a/firmware/d1_mini.bin b/firmware/d1_mini.bin deleted file mode 100644 index c263a9cd3..000000000 Binary files a/firmware/d1_mini.bin and /dev/null differ diff --git a/firmware/nodemcu2.bin b/firmware/nodemcu2.bin new file mode 100644 index 000000000..9fed61e04 Binary files /dev/null and b/firmware/nodemcu2.bin differ diff --git a/firmware/nodemcuv2.bin b/firmware/nodemcuv2.bin deleted file mode 100644 index 893cddbb5..000000000 Binary files a/firmware/nodemcuv2.bin and /dev/null differ diff --git a/firmware/wemos-d1mini.bin b/firmware/wemos-d1mini.bin new file mode 100644 index 000000000..6368bca9b Binary files /dev/null and b/firmware/wemos-d1mini.bin differ