diff --git a/README.md b/README.md index 922d99721..7e981f2ba 100644 --- a/README.md +++ b/README.md @@ -382,28 +382,46 @@ Roughly these are the steps needed when running Windows: ### Using ESPurna -*Note: This is still work in progress. The ESPurna code for the HTML config is still to be added.* -[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 built on PlatformIO and Visual Studio Code too. 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. So if you're brave, follow these steps: -- Download and install [NodeJS and npm](https://nodejs.org/en/download). Choose the LTS version. -- Download espurna by cloning the ESPurna git repository from `https://github.com/xoseperez/espurna.git`. -- Restart VSC. PlatformIO should detect and set some things up for you automagically. -- From VSC open the folder ``espurna\code`` -- open a terminal window (ctrl-`) -- Install the node modules: ``npm install --only=dev`` -- Build the web interface: ``node node_modules/gulp/bin/gulp.js`` -- Finally copy the files `custom.h, index.html, boiler.ino and the esp*.cpp/h` files from the `espurna` directory in this repo to the code directory and build. +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` +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 the files from this repo's *espurna* directory to where you installed ESPurna -If you run into issues refer to official ESPurnas setup instructions [here](https://github.com/xoseperez/espurna/wiki/Build-and-update-from-Visual-Studio-Code-using-PlatformIO). +``` +code/html/index.html +code/config/custom.h +code/espurna/boiler-espurna.ino +code/espurna/ems*.* +``` + +10. Now build and upload as you usually would. Look at my version of platformio.ini as an example. + +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). + + +This is what ESPurna looks like with the custom boiler code: + +![Example running in ESPurna](doc/espurna/example.PNG) ### Using the pre-built firmware's -I will eventually put pre-built version based on ESPurna in the directory `/firmware` which you can upload using [esptool](https://github.com/espressif/esptool) bootloader. On Windows, follow these instructions: +pre-baked firmwares for some ESP8266 devices based on ESPurna are available in the directory `/firmware` which you can upload yourself using [esptool](https://github.com/espressif/esptool) bootloader. On Windows, follow these instructions: -1. Check if you have python 2.7 installed. If not [download it](https://www.python.org/downloads/) and make sure you select the option to add Python to the windows PATH. -2. Install the ESPTool by running `pip install esptool` from a command prompt. -3. Connect the ESP via USB, figure out the COM port. +1. Check if you have **python 2.7** installed. If not [download it](https://www.python.org/downloads/) and make sure you select the option to add Python to the windows PATH +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. Pasword 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 configuation help page. ### Using the Arduino IDE @@ -435,7 +453,6 @@ Some annoying issues that need fixing: Here's my top things I'm still working on: -- Make an ESPurna version. ESPurna is a lovely framework that takes care of the WiFi, MQTT, web server, telnet & debugging. - Complete the ESP32 version. It's surprisingly a lot easier doing the UART handling on an ESP32 with the ESP-IDF SDK. I have a first version beta that is working. - Find a better way to control the 3-way valve to switch the warm water off quickly rather than deactivating the warm water heater each time. There is an unsupported call to do this, but I think its too risky and experimental. I'd love to get my hands on an Nefit Easy, sniff the packets being sent and reverse engineer the logic. Anyone help? diff --git a/doc/espurna/example.PNG b/doc/espurna/example.PNG new file mode 100644 index 000000000..d83b3eb9e Binary files /dev/null and b/doc/espurna/example.PNG differ diff --git a/espurna/boiler-espurna.ino b/espurna/boiler-espurna.ino new file mode 100644 index 000000000..b0230eae1 --- /dev/null +++ b/espurna/boiler-espurna.ino @@ -0,0 +1,359 @@ +// Boiler +// Espurna version +// Paul Derbyshire - https://github.com/proddy/EMS-ESP-Boiler + +#include "emsuart.h" +#include +#include + +#define myDebug(...) debugSend(__VA_ARGS__) + +#define BOILER_THERMOSTAT_ENABLED 1 +#define BOILER_SHOWER_ENABLED 1 +#define BOILER_POLLING_ENABLED 0 +#define BOILER_LOGGING_NONE 1 + +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 +} _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 +} _Boiler_Shower; + +// store for overall system status +_Boiler_Status Boiler_Status; +_Boiler_Shower Boiler_Shower; + +// Config +void _boilerConfigure() { + Boiler_Status.thermostat_enabled = getSetting("boilerThermostat", BOILER_THERMOSTAT_ENABLED).toInt() == 1; + ems_setThermostatEnabled(Boiler_Status.thermostat_enabled); + + bool _boilerPolling = getSetting("boilerPolling", BOILER_POLLING_ENABLED).toInt() == 1; + ems_setPoll(_boilerPolling); + + 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; +} + +// WEB callbacks +bool _boilerWebSocketOnReceive(const char * key, JsonVariant & value) { + return (strncmp(key, "boiler", 6) == 0); +} + +void _boilerWebSocketOnSend(JsonObject & root) { + root["boilerThermostat"] = getSetting("boilerThermostat", BOILER_THERMOSTAT_ENABLED).toInt() == 1; + root["boilerShower"] = getSetting("boilerShower", BOILER_SHOWER_ENABLED).toInt() == 1; + root["boilerPolling"] = getSetting("boilerPolling", BOILER_POLLING_ENABLED).toInt() == 1; + root["boilerLogging"] = getSetting("boilerLogging", BOILER_LOGGING_NONE).toInt(); +} + +// used if we have a button +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); + + mqttSendRaw(topic.c_str(), output.c_str()); + mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true); +} + +// 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", + ((Boiler_Status.thermostat_enabled) ? "enabled" : "disabled"), + ((EMS_Sys_Status.emsPollEnabled) ? "enabled" : "disabled"), + ((Boiler_Status.shower_enabled) ? "enabled" : "disabled"), + ((Boiler_Status.shower_timer) ? "enabled" : "disabled"), + EMS_Sys_Status.emsRxPgks, + EMS_Sys_Status.emsTxPkgs, + EMS_Sys_Status.emxCrcErr); + + myDebug(", RxStatus="); + switch (EMS_Sys_Status.emsRxStatus) { + case EMS_RX_IDLE: + myDebug("idle"); + break; + case EMS_RX_ACTIVE: + myDebug("active"); + break; + } + + myDebug(", TxStatus="); + switch (EMS_Sys_Status.emsTxStatus) { + case EMS_TX_IDLE: + myDebug("idle"); + break; + case EMS_TX_PENDING: + myDebug("pending"); + break; + case EMS_TX_ACTIVE: + myDebug("active"); + break; + } + + myDebug(", TxAction="); + switch (EMS_TxTelegram.action) { + case EMS_TX_READ: + myDebug("read"); + break; + case EMS_TX_WRITE: + myDebug("write"); + break; + case EMS_TX_VALIDATE: + myDebug("validate"); + break; + case EMS_TX_NONE: + myDebug("none"); + break; + } + + myDebug("\nBoiler stats:\n"); + + // 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); + 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"); + + // 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)); + + // 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); + myDebug(" Total burner operating time: %d days %d hours %d minutes\n", + EMS_Boiler.burnWorkMin / 1440, + (EMS_Boiler.burnWorkMin % 1440) / 60, + EMS_Boiler.burnWorkMin % 60); + myDebug(" Total heat operating time: %d days %d hours %d minutes\n", + EMS_Boiler.heatWorkMin / 1440, + (EMS_Boiler.heatWorkMin % 1440) / 60, + EMS_Boiler.heatWorkMin % 60); + + // Thermostat stats + if (Boiler_Status.thermostat_enabled) { + myDebug("Thermostat stats:\n Thermostat time is %02d:%02d:%02d %d/%d/%d\n", + EMS_Thermostat.hour, + EMS_Thermostat.minute, + EMS_Thermostat.second, + EMS_Thermostat.day, + 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)); + myDebug(" Mode is set to "); + if (EMS_Thermostat.mode == 0) { + myDebug("low\n"); + } else if (EMS_Thermostat.mode == 1) { + myDebug("manual\n"); + } else if (EMS_Thermostat.mode == 2) { + myDebug("clock/auto\n"); + } else { + 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"); +} + +// Init telnet commands +void _boilerInitCommands() { + settingsRegisterCommand(F("BOILER.INFO"), [](Embedis * e) { + showInfo(); + DEBUG_MSG(_boilerGetConfig().c_str()); + DEBUG_MSG_P(PSTR("+OK\n")); + }); + + settingsRegisterCommand(F("BOILER.POLLING"), [](Embedis * e) { + if (e->argc < 2) { + DEBUG_MSG_P(PSTR("-ERROR: arg is 0 or 1\n")); + return; + } + + int param = String(e->argv[1]).toInt(); + + bool b = setSetting("boilerPolling", param); + if (b) { + _boilerConfigure(); + } + + wsSend(_boilerWebSocketOnSend); // update web + + DEBUG_MSG_P(PSTR("+OK\n")); + }); + + settingsRegisterCommand(F("BOILER.LOGGING"), [](Embedis * e) { + if (e->argc < 2) { + DEBUG_MSG_P(PSTR("-ERROR: arg is 0 or 1\n")); + return; + } + + int param = String(e->argv[1]).toInt(); + + bool b = setSetting("boilerLogging", param); + if (b) { + _boilerConfigure(); + } + + wsSend(_boilerWebSocketOnSend); // update web + + DEBUG_MSG_P(PSTR("+OK\n")); + }); + + settingsRegisterCommand(F("BOILER.SEND"), [](Embedis * e) { + if (e->argc < 2) { + DEBUG_MSG_P(PSTR("-ERROR: Wrong arguments\n")); + return; + } + int cmd = String(e->argv[1]).toInt(); + DEBUG_MSG_P(PSTR("Sending %d\n"), cmd); + DEBUG_MSG_P(PSTR("+OK\n")); + }); +} + +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); + } + + if (type == MQTT_MESSAGE_EVENT) { + + // Match topic + String t = mqttMagnitude((char *) topic); + if (!t.startsWith(MQTT_TOPIC_LED)) return; + + // 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); + return; + } + + // Check if LED is managed + if (_ledMode(ledID) != LED_MODE_MQTT) return; + + // get value + unsigned char value = relayParsePayload(payload); + + // Action to perform + if (value == 2) { + _ledToggle(ledID); + } else { + _ledStatus(ledID, value == 1); + } + + } + */ +} + +// TELNET commands +String _boilerGetConfig() { + String output; + + // get values and print them + output = String("Thermostat is ") + getSetting("boilerThermostat") + String(", Polling is ") + + getSetting("boilerPolling") + String(", Logging is ") + getSetting("boilerLogging") + + String(", Shower is ") + getSetting("boilerShower") + String("\n"); + + return output; +} + +// SETUP +void extraSetup() { + boilerSetup(); +} + +void boilerSetup() { + // configure + _boilerConfigure(); + + wsOnSendRegister(_boilerWebSocketOnSend); + wsOnAfterParseRegister(_boilerConfigure); + wsOnActionRegister(_boilerWebSocketOnAction); + wsOnReceiveRegister(_boilerWebSocketOnReceive); + + mqttRegister(_boilerMQTTCallback); + + _boilerInitCommands(); + + // init shower + Boiler_Shower.timerStart = 0; + Boiler_Shower.timerPause = 0; + Boiler_Shower.duration = 0; + Boiler_Shower.isColdShot = false; + + // ems init values + ems_init(); + + // start uart + emsuart_init(); + + // Register loop + espurnaRegisterLoop(_boilerLoop); +} + +// LOOP +void _boilerLoop() { +} diff --git a/espurna/custom.h b/espurna/custom.h new file mode 100644 index 000000000..a7dd25ab6 --- /dev/null +++ b/espurna/custom.h @@ -0,0 +1,28 @@ +// export PLATFORMIO_BUILD_FLAGS="'-DUSE_CUSTOM_H'" +// e.g. +// build_flags = -g -DMQTT_MAX_PACKET_SIZE=400 ${env.ESPURNA_FLAGS} -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -DUSE_CUSTOM_H -DUSE_EXTRA + +#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}" + +#undef ENABLE_DOMOTICZ +#define ENABLE_DOMOTICZ 0 + +#undef THINGSPEAK_SUPPORT +#define THINGSPEAK_SUPPORT 0 + +#undef SCHEDULER_SUPPORT +#define SCHEDULER_SUPPORT 0 + +#undef ENABLE_FAUXMO +#define ENABLE_FAUXMO 0 + +#undef DEBUG_SERIAL_SUPPORT +#define DEBUG_SERIAL_SUPPORT 0 diff --git a/espurna/in progress.txt b/espurna/in progress.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/espurna/index.html b/espurna/index.html new file mode 100644 index 000000000..cabc4efb8 --- /dev/null +++ b/espurna/index.html @@ -0,0 +1,1831 @@ + + + + + + ESPurna 0.0.0 + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+

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.

+
+ +
+ +
+ +
+ + +
+
+ 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.
+
+ +
+ + +
+ +
+ + +
+
+
+ +
+ +
+ + +
+ +
+ + + + + + + +
+ +
+ +
+

STATUS

+

Current configuration

+
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
Manufacturer
+
+ +
+ +
Device
+
+ +
+ +
Chip ID
+
+ +
+ +
Wifi MAC
+
+ +
+ +
SDK version
+
+ +
+ +
Core version
+
+ +
+ +
Firmware name
+
+ +
+ +
Firmware version
+
+ +
+ + + +
Firmware build date
+
+ +
+ +
Firmware size
+
+ +
+ +
Free space
+
+ +
+ +
+ +
+ +
Network
+
+ +
+ +
BSSID
+
+ +
+ +
Channel
+
+ +
+ +
RSSI
+
+ +
+ +
IP
+ + +
Free heap
+
+ +
+ +
Load average
+
+ + % +
+ +
VCC
+
+ ? + mV +
+ +
MQTT Status
+
+ +
+ +
NTP Status
+
+ +
+ +
Current time
+
+ +
+ +
Uptime
+
+ +
+ +
Last update
+
+ ? + seconds ago +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+

GENERAL

+

General configuration values

+
+ +
+ +
+ +
+ + +
+
+
+ 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. +
+
+ +
+ + +
+
+
+ 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. +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+ +
+

SWITCHES

+

Switch / relay configuration

+
+ +
+ +
+ + General + +
+ + +
+
Define how the different switches should be synchronized.
+
+ +
+ +
+ +
+
+ +
+ +
+

LIGHTS

+

Lights configuration

+
+ +
+ +
+ +
+ +
+ +
+
+
+
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 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 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"
+
+ +
+ +
+ +
+
+
+
If enabled color changes will be smoothed.
+
+ +
+ +
+ +
+
+
+
Time in millisecons to transition from one color to another.
+
+ +
+
+ +
+
+ +
+
+
Sync color between different lights.
+
+ +
+
+
+ +
+ +
+

ADMINISTRATION

+

Device administration and security settings

+
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+ + +
+
+ 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.
+
+ +
+ + +
+ +
+ + +
+
+
+ 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. +
+
+ +
+ + +
+ +
+
+
+ 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.
+
+ + +
+ +
+ +
+
+ +
+ + +
+
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 + .
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+

WIFI

+

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

+
+ +
+ +
+ + General + +
+ +
+ +
+
+
+
+ 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. + +
+
+ +
+
+ +
+ +
+ + Networks + +
+ + + +
+
+
+ +
+ +
+

SCHEDULE

+

Turn switches ON and OFF based on the current time.

+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ +
+ +
+

MQTT

+

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

+
+ +
+ +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ If left empty the firmware will generate a client ID based on the serial number of the chip. +
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ + +
+
+ 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
+
+
+ +
+ + +
+
+ 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. +
+
+ +
+
+ +
+ +
+ +
+

NTP

+

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

+
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+
+ +
+ +
+ +
+

DOMOTICZ

+

+ Configure the connection to your Domoticz server. +

+
+ +
+ +
+ + General + +
+ +
+ +
+
+ +
+ + +
+ +
+ + +
+ + Sensors & actuators + +
+
Set IDX to 0 to disable notifications from that component.
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+

HOME ASSISTANT

+

+ Add this device to your Home Assistant. +

+
+ +
+
+ + Discover + +
+ +
+ +
+
+
+
+ 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. +
+
+ +
+ + +
+ + Configuration + +
+ +
+ +
+
+
+ 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. +
+
+
+ +
+ + +
+
+ +
+ + + +
+ +
+

THINGSPEAK

+

+ Send your sensors data to Thingspeak. +

+
+ +
+ +
+ + General + +
+ +
+ +
+
+ +
+ + +
+ + Sensors & actuators + +
+
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. +

+
+ +
+ +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+ +
+

DEBUG LOG

+

+ Shows debug messages from the device +

+
+ +
+ +
+ +
+
+ Write a command and click send to execute it on the device. The output will be shown in the debug text area below. +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+

SENSOR CONFIGURATION

+

+ Configure and calibrate your device sensors. +

+
+ +
+ +
+ + General + +
+ + +
+
+
+ Select the interval between readings. These will be filtered and averaged for the report. The default and recommended value + is 6 seconds. +
+
+ +
+ +
+ +
+
+
+
+ Select the number of readings to average and report +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ 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. +
+
+ + Energy monitor + +
+ + +
+
Mains voltage in your system (in V).
+
+ +
+ + +
+
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 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 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

+

Configure the + BOILER settings. Make sure you Save after changing values.

+
+
+
+
+ +
+ +
+
+
+
Enable if you want to read/write from Thermostat
+
+ +
+ +
+ +
+
+
+
Polling for better support and debugging
+
+ +
+ +
+ +
+
+
+
Monitor shower timings
+
+ +
+ + +
+ +
+
+
+ +
+ +
+ + +
+ + + + +
+ + Switch # + + + +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+
+ +
+ + + + + + +
+
Leave empty for DNS 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
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
 h
+
+
+ +
 m
+
+
+ + +
+ +
+ + +
+ +
+
 1 for Monday, 2 for Tuesday...
+ +
+
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+ +
+ Switch # + (GPIO + ) +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+
+ +
+
+ + +
+ +
+ + + +
+
+ +
+
+ + +
+
+ +
+
+ + + +
+
+ +
+
+ + + +
+
+ +
+
+ +
+ +
+
+
+
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/firmware/d1_mini.bin b/firmware/d1_mini.bin new file mode 100644 index 000000000..c263a9cd3 Binary files /dev/null and b/firmware/d1_mini.bin differ diff --git a/firmware/nodemcuv2.bin b/firmware/nodemcuv2.bin new file mode 100644 index 000000000..893cddbb5 Binary files /dev/null and b/firmware/nodemcuv2.bin differ