This commit is contained in:
proddy
2019-03-07 08:29:20 +01:00
parent f35cf9701c
commit 541c0c2e10
11 changed files with 161 additions and 129 deletions

View File

@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.5.5] 2019-03-07
### Fixed
- Support the latest ArduinoJson v6 and espressif8266 2.0.4 libraries (in PlatformIO do a `pio lib update` and `pio update`)
### Changed
- MQTT keep alive to 2 minutes (60 seconds was just too short for slower networks)
- Improved MQTT startup time
- Setting wifi or mqtt settings are immediate, no need to restart the ESP
- Text changes in the help
### Added
- Show if MQTT is connected
- Show version of MyESP (the custom MQTT, Wifi, OTA, MDNS, Telnet library)
- EMS-OT OpenTherm connector
## [1.5.4] 2019-03-03
### Changed
@@ -14,7 +31,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Callback for OTA. This is used to disable EMS bus during a firmware OTA update, which caused problems with the latest ESP89266 core libraries
- Added rough estimate of WiFi signal strength to info page
- Added the build time & date to the info page (optional in platformio.ini)## [1.5.3] 2019-02-22
- Added the build time & date to the info page (optional in platformio.ini)
## [1.5.3] 2019-02-22
### Changed
@@ -84,7 +103,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- some minor improvements to autodetect
## [1.4.0] 2019-01-27
### Changed

View File

@@ -5,7 +5,7 @@ EMS-ESP is a project to build an electronic controller circuit using an Espressi
There are 3 parts to this project, first the design of the circuit, secondly the code for the ESP8266 microcontroller firmware with telnet and MQTT support, and lastly an example configuration for Home Assistant to monitor the data and issue direct commands via a MQTT broker.
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b8880625bdf841d4adb2829732030887)](https://app.codacy.com/app/proddy/EMS-ESP?utm_source=github.com&utm_medium=referral&utm_content=proddy/EMS-ESP&utm_campaign=Badge_Grade_Settings)
[![version](https://img.shields.io/badge/version-1.5.4-brightgreen.svg)](CHANGELOG.md)
[![version](https://img.shields.io/badge/version-1.5.5-brightgreen.svg)](CHANGELOG.md)
- [EMS-ESP](#ems-esp)
- [Introduction](#introduction)

View File

@@ -2,21 +2,27 @@
* MyESP - my ESP helper class to handle Wifi, MQTT and Telnet
*
* Paul Derbyshire - December 2018
* Version 1.1 - Feb 22 2019. Added support for ESP32
* Version 1.1.1 - March 3 2019. Added OTA callback
*
* Ideas borrowed from Espurna https://github.com/xoseperez/espurna
*/
#include "MyESP.h"
#define RTC_LEAP_YEAR(year) ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))
/* Days in a month */
static uint8_t RTC_Months[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Not leap year */
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} /* Leap year */
};
// constructor
MyESP::MyESP() {
_app_hostname = strdup("MyESP");
_app_name = strdup("MyESP");
_app_version = strdup("1.1.1");
_app_version = strdup(MYESP_VERSION);
_boottime = strdup("unknown");
_boottime = strdup("<unknown>");
_load_average = 100; // calculated load average
_telnetcommand_callback = NULL;
@@ -42,14 +48,14 @@ MyESP::MyESP() {
_mqtt_topic = NULL;
_mqtt_qos = 0;
_mqtt_reconnect_delay = MQTT_RECONNECT_DELAY_MIN;
_mqtt_last_connection = 0;
_mqtt_connecting = false;
_wifi_password = NULL;
_wifi_ssid = NULL;
_wifi_callback = NULL;
_wifi_connected = false;
_ota_callback = NULL;
_suspendOutput = false;
}
@@ -240,6 +246,8 @@ void MyESP::_mqttOnConnect() {
myDebug_P(PSTR("[MQTT] Connected"));
_mqtt_reconnect_delay = MQTT_RECONNECT_DELAY_MIN;
_mqtt_last_connection = millis();
// say we're alive to the Last Will topic
mqttClient.publish(_mqttTopic(_mqtt_will_topic), 1, true, _mqtt_will_online_payload);
@@ -253,8 +261,6 @@ void MyESP::_mqtt_setup() {
myDebug_P(PSTR("[MQTT] disabled"));
}
_mqtt_reconnect_delay = MQTT_RECONNECT_DELAY_MIN;
mqttClient.onConnect([this](bool sessionPresent) { _mqttOnConnect(); });
mqttClient.onDisconnect([this](AsyncMqttClientDisconnectReason reason) {
@@ -274,6 +280,10 @@ void MyESP::_mqtt_setup() {
if (reason == AsyncMqttClientDisconnectReason::MQTT_NOT_AUTHORIZED) {
myDebug_P(PSTR("[MQTT] Not authorized"));
}
// Reset reconnection delay
_mqtt_last_connection = millis();
_mqtt_connecting = false;
});
//mqttClient.onSubscribe([this](uint16_t packetId, uint8_t qos) { myDebug_P(PSTR("[MQTT] Subscribe ACK for PID %d"), packetId); });
@@ -391,15 +401,6 @@ void MyESP::_telnet_setup() {
memset(_command, 0, TELNET_MAX_COMMAND_LENGTH);
}
#define RTC_LEAP_YEAR(year) ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))
/* Days in a month */
static uint8_t RTC_Months[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Not leap year */
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} /* Leap year */
};
// https://stackoverflow.com/questions/43063071/the-arduino-ntp-i-want-print-out-datadd-mm-yyyy
void MyESP::_printBuildTime(unsigned long unix) {
// compensate for summer/winter time and CET. Can't be bothered to work out DST.
@@ -462,7 +463,7 @@ void MyESP::_consoleShowHelp() {
SerialAndTelnet.println();
if (WiFi.getMode() & WIFI_AP) {
SerialAndTelnet.printf("* ESP8266 is in AP mode with SSID %s", jw.getAPSSID().c_str());
SerialAndTelnet.printf("* ESP is in AP mode with SSID %s", jw.getAPSSID().c_str());
SerialAndTelnet.println();
} else {
#if defined(ARDUINO_ARCH_ESP32)
@@ -477,6 +478,7 @@ void MyESP::_consoleShowHelp() {
#ifdef ARDUINO_BOARD
SerialAndTelnet.printf(" Board: %s", ARDUINO_BOARD);
#endif
SerialAndTelnet.printf(" (MyESP v%s)", MYESP_VERSION);
#ifdef BUILD_TIME
SerialAndTelnet.print(" (Build ");
@@ -486,10 +488,13 @@ void MyESP::_consoleShowHelp() {
SerialAndTelnet.println();
SerialAndTelnet.printf("* Connected to WiFi SSID: %s (signal %d%%)", WiFi.SSID().c_str(), getWifiQuality());
SerialAndTelnet.println();
SerialAndTelnet.printf("* MQTT is %s", mqttClient.connected() ? "connected" : "disconnected");
SerialAndTelnet.println();
SerialAndTelnet.printf("* Boot time: %s", _boottime);
SerialAndTelnet.println();
}
SerialAndTelnet.printf("* Free RAM:%d KB, Load:%d%%", (ESP.getFreeHeap() / 1024), getSystemLoadAverage());
SerialAndTelnet.printf("* Free RAM: %d KB Load: %d%%", (ESP.getFreeHeap() / 1024), getSystemLoadAverage());
SerialAndTelnet.println();
// for battery power is ESP.getVcc()
@@ -498,7 +503,7 @@ void MyESP::_consoleShowHelp() {
SerialAndTelnet.println(FPSTR("* ?=help, CTRL-D=quit"));
SerialAndTelnet.println(FPSTR("* reboot"));
SerialAndTelnet.println(FPSTR("* set"));
SerialAndTelnet.println(FPSTR("* set wifi <ssid> <password>"));
SerialAndTelnet.println(FPSTR("* set wifi [ssid] [password]"));
SerialAndTelnet.println(FPSTR("* set <mqtt_host | mqtt_username | mqtt_password> [value]"));
SerialAndTelnet.println(FPSTR("* set erase"));
SerialAndTelnet.println(FPSTR("* set serial"));
@@ -538,8 +543,7 @@ void MyESP::resetESP() {
// read next word from string buffer
char * MyESP::_telnet_readWord() {
char * word = strtok(NULL, ", \n");
return word;
return (strtok(NULL, ", \n"));
}
// change setting for 2 params (set <command> <value1> <value2>)
@@ -561,7 +565,10 @@ void MyESP::_changeSetting2(const char * setting, const char * value1, const cha
}
(void)fs_saveConfig();
SerialAndTelnet.println("Wifi credentials set. Type 'reboot' to restart...");
SerialAndTelnet.println("WiFi settings changed. Reconnecting...");
jw.disconnect();
jw.cleanNetworks();
jw.addNetwork(_wifi_ssid, _wifi_password);
}
}
@@ -778,15 +785,20 @@ void MyESP::_telnetHandle() {
// ensure we have a connection to MQTT broker
void MyESP::_mqttConnect() {
if (!_mqtt_host || mqttClient.connected() || (WiFi.status() != WL_CONNECTED)) {
if (!_mqtt_host)
return; // MQTT not enabled
// Do not connect if already connected or still trying to connect
if (mqttClient.connected() || _mqtt_connecting || (WiFi.status() != WL_CONNECTED)) {
return;
}
// Check reconnect interval
static unsigned long last = 0;
if (millis() - last < _mqtt_reconnect_delay)
if (millis() - _mqtt_last_connection < _mqtt_reconnect_delay) {
return;
last = millis();
}
_mqtt_connecting = true; // we're doing a connection
// Increase the reconnect delay
_mqtt_reconnect_delay += MQTT_RECONNECT_DELAY_STEP;
@@ -801,7 +813,7 @@ void MyESP::_mqttConnect() {
// last will
if (_mqtt_will_topic) {
myDebug_P(PSTR("[MQTT] Setting last will topic %s"), _mqttTopic(_mqtt_will_topic));
//myDebug_P(PSTR("[MQTT] Setting last will topic %s"), _mqttTopic(_mqtt_will_topic));
mqttClient.setWill(_mqttTopic(_mqtt_will_topic), 1, true, _mqtt_will_offline_payload); // retain always true
}
@@ -923,15 +935,21 @@ char * MyESP::_mqttTopic(const char * topic) {
// print contents of file
// assume Serial is open
// assumes Serial is open
void MyESP::_fs_printConfig() {
myDebug_P(PSTR("[FS] Contents:"));
File configFile = SPIFFS.open(MYEMS_CONFIG_FILE, "r");
if (!configFile) {
Serial.println(F("[FS] Failed to read file for printing"));
return;
}
while (configFile.available()) {
SerialAndTelnet.print((char)configFile.read());
}
myDebug_P(PSTR(""));
SerialAndTelnet.println();
configFile.close();
}
@@ -965,14 +983,15 @@ bool MyESP::_fs_loadConfig() {
return false;
}
// assign buffer
std::unique_ptr<char[]> buf(new char[size]);
StaticJsonDocument<SPIFFS_MAXSIZE> doc;
JsonObject json = doc.to<JsonObject>();
// use configFile.readString
configFile.readBytes(buf.get(), size);
StaticJsonBuffer<SPIFFS_MAXSIZE> jsonBuffer;
JsonObject & json = jsonBuffer.parseObject(buf.get());
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, configFile);
if (error) {
Serial.println(F("[FS] Failed to read file"));
return false;
}
const char * value;
@@ -991,18 +1010,12 @@ bool MyESP::_fs_loadConfig() {
value = json["mqtt_password"];
_mqtt_password = (value) ? strdup(value) : NULL;
_use_serial = (bool)json["use_serial"];
// callback for loading custom settings
// ok is false if there's a problem loading a custom setting (e.g. does not exist)
bool ok = (_fs_callback)(MYESP_FSACTION_LOAD, json);
// new configs after release 1.3.x
if (json.containsKey("use_serial")) {
_use_serial = (bool)json["use_serial"];
} else {
_use_serial = false; // if first time, set serial to off
ok = false;
}
configFile.close();
return ok;
@@ -1010,9 +1023,10 @@ bool MyESP::_fs_loadConfig() {
// save settings to spiffs
bool MyESP::fs_saveConfig() {
StaticJsonBuffer<SPIFFS_MAXSIZE> jsonBuffer;
JsonObject & json = jsonBuffer.createObject();
StaticJsonDocument<SPIFFS_MAXSIZE> doc;
JsonObject json = doc.to<JsonObject>();
json["app_version"] = _app_version;
json["wifi_ssid"] = _wifi_ssid;
json["wifi_password"] = _wifi_password;
json["mqtt_host"] = _mqtt_host;
@@ -1029,7 +1043,10 @@ bool MyESP::fs_saveConfig() {
return false;
}
json.printTo(configFile);
// Serialize JSON to file
if (serializeJson(json, configFile) == 0) {
Serial.println(F("[FS] Failed to write to file"));
}
configFile.close();
@@ -1042,16 +1059,17 @@ bool MyESP::fs_saveConfig() {
void MyESP::_fs_setup() {
if (!SPIFFS.begin()) {
Serial.println("[FS] Failed to mount the file system");
_fs_eraseConfig(); // fix for ESP32
return;
}
// load the config file. if it doesn't exist create it
// load the config file. if it doesn't exist (function returns false) create it
if (!_fs_loadConfig()) {
Serial.println("[FS] Re-creating config file");
// Serial.println("[FS] Re-creating config file");
fs_saveConfig();
}
// _fs_printConfig(); // for debugging
// _fs_printConfig(); // TODO: for debugging
}
uint16_t MyESP::getSystemLoadAverage() {
@@ -1078,7 +1096,8 @@ void MyESP::_calculateLoad() {
}
}
// return true if wifi is connected:
// return true if wifi is connected
// WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
// WL_IDLE_STATUS = 0,
// WL_NO_SSID_AVAIL = 1,
// WL_SCAN_COMPLETED = 2,
@@ -1091,13 +1110,16 @@ bool MyESP::isWifiConnected() {
}
/*
* Return the quality (Received Signal Strength Indicator) of the WiFi network.
* Returns -1 if WiFi is disconnected.
* High quality: 90% ~= -55dBm
* Medium quality: 50% ~= -75dBm
* Low quality: 30% ~= -85dBm
* Unusable quality: 8% ~= -96dBm
*/
Return the quality (Received Signal Strength Indicator)
of the WiFi network.
Returns a number between 0 and 100 if WiFi is connected.
Returns -1 if WiFi is disconnected.
High quality: 90% ~= -55dBm
Medium quality: 50% ~= -75dBm
Low quality: 30% ~= -85dBm
Unusable quality: 8% ~= -96dBm
*/
int MyESP::getWifiQuality() {
if (WiFi.status() != WL_CONNECTED)
return -1;

View File

@@ -1,5 +1,5 @@
/*
* MyEsp.h
* MyESP.h
*
* Paul Derbyshire - December 2018
*/
@@ -9,6 +9,8 @@
#ifndef MyEMS_h
#define MyEMS_h
#define MYESP_VERSION "1.1.4"
#include <ArduinoJson.h>
#include <ArduinoOTA.h>
#include <AsyncMqttClient.h> // https://github.com/marvinroger/async-mqtt-client and for ESP32 see https://github.com/marvinroger/async-mqtt-client/issues/127
@@ -38,8 +40,8 @@
// MQTT
#define MQTT_PORT 1883 // MQTT port
#define MQTT_RECONNECT_DELAY_MIN 5000 // Try to reconnect in 5 seconds upon disconnection
#define MQTT_RECONNECT_DELAY_STEP 5000 // Increase the reconnect delay in 5 seconds after each failed attempt
#define MQTT_RECONNECT_DELAY_MIN 2000 // Try to reconnect in 3 seconds upon disconnection
#define MQTT_RECONNECT_DELAY_STEP 3000 // Increase the reconnect delay in 3 seconds after each failed attempt
#define MQTT_RECONNECT_DELAY_MAX 120000 // Set reconnect time to 2 minutes at most
#define MQTT_MAX_SIZE 600 // max length of MQTT message
#define MQTT_MAX_TOPIC_SIZE 50 // max length of MQTT message
@@ -68,7 +70,6 @@
#define COLOR_BOLD_ON "\x1B[1m"
#define COLOR_BOLD_OFF "\x1B[21m"
// SPIFFS
#define SPIFFS_MAXSIZE 500 // https://arduinojson.org/v5/assistant/
@@ -84,7 +85,7 @@ typedef std::function<void()>
typedef std::function<void()> ota_callback_f;
typedef std::function<void(uint8_t, const char *)> telnetcommand_callback_f;
typedef std::function<void(uint8_t)> telnet_callback_f;
typedef std::function<bool(MYESP_FSACTION, JsonObject & json)> fs_callback_f;
typedef std::function<bool(MYESP_FSACTION, const JsonObject json)> fs_callback_f;
typedef std::function<bool(MYESP_FSACTION, uint8_t, const char *, const char *)> fs_settings_callback_f;
// calculates size of an 2d array at compile time
@@ -165,6 +166,8 @@ class MyESP {
char * _mqtt_will_online_payload;
char * _mqtt_will_offline_payload;
char * _mqtt_topic;
unsigned long _mqtt_last_connection;
bool _mqtt_connecting;
// wifi
DNSServer dnsServer; // For Access Point (AP) support

View File

@@ -16,8 +16,8 @@ lib_deps =
CircularBuffer
JustWifi
AsyncMqttClient
; ArduinoJson
https://github.com/bblanchon/ArduinoJson#v5.13.5
ArduinoJson
; https://github.com/bblanchon/ArduinoJson#v5.13.5
OneWire
[env:d1_mini]

View File

@@ -79,24 +79,24 @@ command_t PROGMEM project_cmds[] = {
{"set led <on | off>", "toggle status LED on/off"},
{"set led_gpio <pin>", "set the LED pin. Default is the onboard LED (D1=5)"},
{"set dallas_gpio <pin>", "set the pin for the external Dallas temperature sensor (D5=14)"},
{"set thermostat_type <hex type ID>", "set the thermostat type id (e.g. 10 for 0x10)"},
{"set boiler_type <hex type ID>", "set the boiler type id (e.g. 8 for 0x08)"},
{"info", "show the values"},
{"set dallas_gpio <pin>", "set the pin for external Dallas temperature sensors (D5=14)"},
{"set thermostat_type <type ID>", "set the thermostat type id (e.g. 10 for 0x10)"},
{"set boiler_type <type ID>", "set the boiler type id (e.g. 8 for 0x08)"},
{"info", "show data captured on the EMS bus"},
{"log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
{"publish", "publish values to MQTT"},
{"publish", "forice a publish of all values to MQTT"},
{"types", "list supported EMS telegram type IDs"},
{"queue", "list Tx queue"},
{"autodetect", "discover EMS devices and set boiler and thermostat automatically"},
{"queue", "show current Tx queue"},
{"autodetect", "discover EMS devices and attempt to automatically set boiler and thermostat"},
{"shower <timer | alert>", "toggle either timer or alert on/off"},
{"send XX...", "send raw telegram data in hex to EMS bus"},
{"thermostat read <hex type ID>", "send read request to thermostat"},
{"send XX ...", "send raw telegram data as hex to EMS bus"},
{"thermostat read <type ID>", "send read request to the thermostat"},
{"thermostat temp <degrees>", "set current thermostat temperature"},
{"thermostat mode <mode>", "set mode (0=low/night, 1=manual/day, 2=auto)"},
{"thermostat scan <hex type ID>", "do a force read on all type IDs starting at n"},
{"boiler read <hex type ID>", "send read request to boiler"},
{"boiler wwtemp <degrees>", "set warm water temperature"},
{"boiler tapwater <on | off>", "set warm tap water on or off"}
{"thermostat scan <type ID>", "do a read on all type IDs"},
{"boiler read <type ID>", "send read request to boiler"},
{"boiler wwtemp <degrees>", "set boiler warm water temperature"},
{"boiler tapwater <on | off>", "set boiler warm tap water on/off"}
};
@@ -400,7 +400,7 @@ void showInfo() {
// show the Shower Info
if (EMSESP_Status.shower_timer) {
myDebug("%sShower stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
myDebug(" Shower Timer is %s", (EMSESP_Shower.showerOn ? "active" : "off"));
myDebug(" Shower is %s", (EMSESP_Shower.showerOn ? "running" : "off"));
}
}
@@ -409,10 +409,8 @@ void showInfo() {
// CRC check is done to see if there are changes in the values since the last send to avoid too much wifi traffic
void publishValues(bool force) {
char s[20] = {0}; // for formatting strings
StaticJsonBuffer<MQTT_MAX_SIZE> jsonBuffer;
StaticJsonDocument<MQTT_MAX_SIZE> doc;
char data[MQTT_MAX_SIZE] = {0};
JsonObject & rootBoiler = jsonBuffer.createObject();
size_t rlen;
CRC32 crc;
uint32_t fchecksum;
@@ -420,6 +418,8 @@ void publishValues(bool force) {
static uint32_t previousBoilerPublishCRC = 0; // CRC check
static uint32_t previousThermostatPublishCRC = 0; // CRC check
JsonObject rootBoiler = doc.to<JsonObject>();
rootBoiler["wWSelTemp"] = _int_to_char(s, EMS_Boiler.wWSelTemp);
rootBoiler["selFlowTemp"] = _float_to_char(s, EMS_Boiler.selFlowTemp);
rootBoiler["outdoorTemp"] = _float_to_char(s, EMS_Boiler.extTemp);
@@ -443,11 +443,10 @@ void publishValues(bool force) {
rootBoiler["pumpMod"] = _int_to_char(s, EMS_Boiler.pumpMod);
rootBoiler["ServiceCode"] = EMS_Boiler.serviceCodeChar;
rlen = rootBoiler.measureLength();
rootBoiler.printTo(data, rlen + 1); // form the json string
serializeJson(doc, data, sizeof(data));
// calculate hash and send values if something has changed, to save unnecessary wifi traffic
for (size_t i = 0; i < rlen - 1; i++) {
for (size_t i = 0; i < measureJson(doc) - 1; i++) {
crc.update(data[i]);
}
fchecksum = crc.finalize();
@@ -470,13 +469,16 @@ void publishValues(bool force) {
}
// handle the thermostat values separately
if (ems_getThermostatEnabled()) {
//if (ems_getThermostatEnabled()) {
if (true) {
// 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;
// build json object
JsonObject & rootThermostat = jsonBuffer.createObject();
// build new json object
doc.clear();
JsonObject rootThermostat = doc.to<JsonObject>();
rootThermostat[THERMOSTAT_CURRTEMP] = _float_to_char(s, EMS_Thermostat.curr_roomTemp);
rootThermostat[THERMOSTAT_SELTEMP] = _float_to_char(s, EMS_Thermostat.setpoint_roomTemp);
@@ -500,12 +502,11 @@ void publishValues(bool force) {
}
data[0] = '\0'; // reset data for next package
rlen = rootThermostat.measureLength();
rootThermostat.printTo(data, rlen + 1); // form the json string
serializeJson(doc, data, sizeof(data));
// calculate new CRC
crc.reset();
for (size_t i = 0; i < rlen - 1; i++) {
for (size_t i = 0; i < measureJson(doc) - 1; i++) {
crc.update(data[i]);
}
uint32_t checksum = crc.finalize();
@@ -579,48 +580,34 @@ void startThermostatScan(uint8_t start) {
}
// callback for loading/saving settings to the file system (SPIFFS)
bool FSCallback(MYESP_FSACTION action, JsonObject & json) {
bool ok = true;
bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
if (action == MYESP_FSACTION_LOAD) {
// led
if (json.containsKey("led")) {
EMSESP_Status.led_enabled = (bool)json["led"];
} else {
if (!(EMSESP_Status.led_enabled = json["led"])) {
EMSESP_Status.led_enabled = LED_BUILTIN; // default value
ok = false;
}
// led_gpio
if (json.containsKey("led_gpio")) {
EMSESP_Status.led_gpio = json["led_gpio"];
} else {
if (!(EMSESP_Status.led_gpio = json["led_gpio"])) {
EMSESP_Status.led_gpio = EMSESP_LED_GPIO; // default value
ok = false;
}
// dallas_gpio
if (json.containsKey("dallas_gpio")) {
EMSESP_Status.dallas_gpio = json["dallas_gpio"];
} else {
if (!(EMSESP_Status.dallas_gpio = json["dallas_gpio"])) {
EMSESP_Status.dallas_gpio = EMSESP_DALLAS_GPIO; // default value
ok = false;
}
// thermostat_type
if (json.containsKey("thermostat_type")) {
EMS_Thermostat.type_id = json["thermostat_type"];
} else {
if (!(EMS_Thermostat.type_id = json["thermostat_type"])) {
EMS_Thermostat.type_id = EMSESP_THERMOSTAT_TYPE; // set default
ok = false;
}
// boiler_type
if (json.containsKey("boiler_type")) {
EMS_Boiler.type_id = json["boiler_type"];
} else {
if (!(EMS_Boiler.type_id = json["boiler_type"])) {
EMS_Boiler.type_id = EMSESP_BOILER_TYPE; // set default
ok = false;
}
return false; // always save the settings
}
if (action == MYESP_FSACTION_SAVE) {
@@ -629,9 +616,9 @@ bool FSCallback(MYESP_FSACTION action, JsonObject & json) {
json["dallas_gpio"] = EMSESP_Status.dallas_gpio;
json["thermostat_type"] = EMS_Thermostat.type_id;
json["boiler_type"] = EMS_Boiler.type_id;
}
return ok; // all ok
return true;
}
}
// callback for custom settings when showing Stored Settings
@@ -949,7 +936,7 @@ void WIFICallback() {
// This is done after we have a WiFi signal to avoid any resource conflicts
if (myESP.getUseSerial()) {
myDebug("EMS UART disabled when in Serial mode. Use 'set serial off' to change.");
myDebug("Warning! EMS bus disabled when in Serial mode. Use 'set serial off' to enable.");
} else {
emsuart_init();
myDebug("[UART] Opened Rx/Tx connection");

View File

@@ -1447,7 +1447,7 @@ char * ems_getBoilerDescription(char * buffer) {
* Find the versions of our connected devices
*/
void ems_scanDevices() {
myDebug("Scanning EMS bus for devices.");
myDebug("Started scan of EMS bus for known devices");
std::list<uint8_t> Device_Ids; // new list

View File

@@ -102,7 +102,8 @@ typedef enum {
EMS_MODEL_EASY,
EMS_MODEL_BOSCHEASY,
EMS_MODEL_RC310,
EMS_MODEL_CW100
EMS_MODEL_CW100,
EMS_MODEL_OT
} _EMS_MODEL_ID;
@@ -139,6 +140,7 @@ const _Thermostat_Type Thermostat_Types[] = {
{EMS_MODEL_EASY, 202, 0x18, "TC100/Nefit Easy", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_BOSCHEASY, 206, 0x02, "Bosch Easy", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_RC310, 158, 0x10, "RC310", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_OT, 171, 0x02, "EMS-OT OpenTherm converter", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES}
};

View File

@@ -20,7 +20,7 @@
#define MQTT_WILL_ONLINE_PAYLOAD "online" // for last will & testament payload
#define MQTT_WILL_OFFLINE_PAYLOAD "offline" // for last will & testament payload
#define MQTT_RETAIN false
#define MQTT_KEEPALIVE 60 // 1 minute
#define MQTT_KEEPALIVE 120 // 2 minutes
#define MQTT_QOS 1
// MQTT for thermostat

View File

@@ -6,5 +6,5 @@
#pragma once
#define APP_NAME "EMS-ESP"
#define APP_VERSION "1.5.4"
#define APP_VERSION "1.5.5"
#define APP_HOSTNAME "ems-esp"