mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
1.5.2
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -5,11 +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.2] 2019-02-04
|
||||
|
||||
### Changed
|
||||
|
||||
- Change wifi settings using the `set wifi <ssid> <password>` command
|
||||
|
||||
### Added
|
||||
|
||||
- Added incoming MQTT "TOPIC_BOILER_WWACTIVATED" to set the warm water on/off. Payload is 1 or 0. See [issue](https://github.com/proddy/EMS-ESP/issues/46#issuecomment-460375689).
|
||||
- Added the list of all MQTT topics to the README file
|
||||
|
||||
## [1.5.1] 2019-02-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- issue with Serial monitoring conflicting with UART when both running
|
||||
- Fixed typo with -D settings in the example platformio.ini
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
18
README.md
18
README.md
@@ -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.
|
||||
|
||||
[](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)
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
|
||||
- [EMS-ESP](#ems-esp)
|
||||
- [Introduction](#introduction)
|
||||
@@ -233,7 +233,15 @@ Similarly the thermostat values are also sent as a JSON package with the topic `
|
||||
|
||||
`{"thermostat_currtemp":"19.8","thermostat_seltemp":"16.0","thermostat_mode":"manual"}`
|
||||
|
||||
If MQTT is not used set the MQTT_HOST to `NULL`.
|
||||
These incoming MQTT topics are also handled:
|
||||
|
||||
| topic | ID in my_config.h | Payload | Description |
|
||||
| ------------------- | ------------------------- | ---------------------- | ---------------------------------------- |
|
||||
| thermostat_cmd_temp | TOPIC_THERMOSTAT_CMD_TEMP | temperature as a float | sets the thermostat current setpoint |
|
||||
| thermostat_cmd_mode | TOPIC_THERMOSTAT_CMD_MODE | auto, day, night | sets the thermostat mode |
|
||||
| wwactivated | TOPIC_BOILER_WWACTIVATED | 0 or 1 | turns boiler warm water on/off (not tap) |
|
||||
|
||||
If MQTT is not used use 'set mqtt_host' to remove it.
|
||||
|
||||
Some home automation systems such as Domoticz and OpenHab have special formats for their MQTT messages so I would advise to use [node-red](https://nodered.org/) as a parser like in [this example](https://www.domoticz.com/forum/download/file.php?id=18977&sid=67d048f1b4c8833822175eac6b55ecff).
|
||||
|
||||
@@ -305,9 +313,11 @@ pre-baked firmwares for some ESP8266 devices are available in the directory `/fi
|
||||
3. Connect the ESP via USB, figure out the COM port
|
||||
4. run `esptool.py -p <com> write_flash 0x00000 <firmware>` where firmware is the `.bin` file and \<com\> is the COM port, e.g. `COM3`
|
||||
|
||||
The ESP8266 will start in Access Point (AP) mode. Connect via WiFi to the SSID **EMS-ESP** and telnet to **192.168.4.1**. Then use the set command to configure your own network settings. Alternatively connect the ESP8266 to your PC and open a Serial monitor to configure the settings. Make sure you disable Serial support before connecting the EMS lines using `set serial off`.
|
||||
The ESP8266 will start in Access Point (AP) mode. Connect via WiFi to the SSID **EMS-ESP** and telnet to **192.168.4.1**. Then use the `set wifi` command to configure your own network settings like `set wifi your_ssid your_password`. Alternatively connect the ESP8266 to your PC and open a Serial monitor to configure the settings. Make sure you disable Serial support before connecting the EMS lines using `set serial off`.
|
||||
|
||||
`set erase` will clear all settings. `set` wil show all settings.
|
||||
`set erase` will clear all settings.
|
||||
|
||||
`set` wil list all currently stored settings.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -410,9 +410,11 @@ void MyESP::_consoleShowHelp() {
|
||||
|
||||
SerialAndTelnet.println(FPSTR("*"));
|
||||
SerialAndTelnet.println(FPSTR("* Commands:"));
|
||||
SerialAndTelnet.println(FPSTR("* ?=help, CTRL-D=quit, !=reboot"));
|
||||
SerialAndTelnet.println(FPSTR("* ?=help, CTRL-D=quit"));
|
||||
SerialAndTelnet.println(FPSTR("* reboot"));
|
||||
SerialAndTelnet.println(FPSTR("* set"));
|
||||
SerialAndTelnet.println(FPSTR("* set <wifi_ssid | wifi_password | mqtt_host | mqtt_username | mqtt_password> [value]"));
|
||||
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"));
|
||||
|
||||
@@ -456,8 +458,32 @@ char * MyESP::_telnet_readWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
// change setting for 2 params (set <command> <value1> <value2>)
|
||||
void MyESP::_changeSetting2(const char * setting, const char * value1, const char * value2) {
|
||||
if (strcmp(setting, "wifi") == 0) {
|
||||
if (_wifi_ssid)
|
||||
free(_wifi_ssid);
|
||||
if (_wifi_password)
|
||||
free(_wifi_password);
|
||||
_wifi_ssid = NULL;
|
||||
_wifi_password = NULL;
|
||||
|
||||
if (value1) {
|
||||
_wifi_ssid = strdup(value1);
|
||||
}
|
||||
|
||||
if (value2) {
|
||||
_wifi_password = strdup(value2);
|
||||
}
|
||||
|
||||
(void)fs_saveConfig();
|
||||
SerialAndTelnet.println("Wifi credentials set. Type 'reboot' to restart...");
|
||||
}
|
||||
}
|
||||
|
||||
// change settings - always as strings
|
||||
// messy code but effective since we don't have too many settings
|
||||
// wc is word count, number of parameters after the 'set' command
|
||||
void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) {
|
||||
bool ok = false;
|
||||
|
||||
@@ -465,24 +491,14 @@ void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value)
|
||||
if (strcmp(setting, "erase") == 0) {
|
||||
_fs_eraseConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(setting, "wifi_ssid") == 0) {
|
||||
} else if ((strcmp(setting, "wifi") == 0) && (wc == 1)) { // erase wifi settings
|
||||
if (_wifi_ssid)
|
||||
free(_wifi_ssid);
|
||||
_wifi_ssid = NULL; // just to be sure
|
||||
if (value) {
|
||||
_wifi_ssid = strdup(value);
|
||||
}
|
||||
ok = true;
|
||||
} else if (strcmp(setting, "wifi_password") == 0) {
|
||||
if (_wifi_password)
|
||||
free(_wifi_password);
|
||||
_wifi_password = NULL; // just to be sure
|
||||
if (value) {
|
||||
_wifi_password = strdup(value);
|
||||
}
|
||||
ok = true;
|
||||
_wifi_ssid = NULL;
|
||||
_wifi_password = NULL;
|
||||
ok = true;
|
||||
} else if (strcmp(setting, "mqtt_host") == 0) {
|
||||
if (_mqtt_host)
|
||||
free(_mqtt_host);
|
||||
@@ -533,16 +549,14 @@ void MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value)
|
||||
|
||||
// check for 2 params
|
||||
if (value == nullptr) {
|
||||
SerialAndTelnet.printf("%s setting reset to its default value", setting);
|
||||
SerialAndTelnet.printf("%s setting reset to its default value.", setting);
|
||||
} else {
|
||||
// must be 3 params
|
||||
SerialAndTelnet.printf("%s changed to %s", setting, value);
|
||||
SerialAndTelnet.printf("%s changed.", setting);
|
||||
}
|
||||
SerialAndTelnet.println();
|
||||
|
||||
if (fs_saveConfig()) {
|
||||
SerialAndTelnet.println("Note, some changes will only have effect after the ESP is restarted (use ! command)");
|
||||
}
|
||||
(void)fs_saveConfig();
|
||||
}
|
||||
|
||||
void MyESP::_telnetCommand(char * commandLine) {
|
||||
@@ -563,13 +577,13 @@ void MyESP::_telnetCommand(char * commandLine) {
|
||||
// check first for reserved commands
|
||||
char * temp = strdup(commandLine); // because strotok kills original string buffer
|
||||
char * ptrToCommandName = strtok((char *)temp, ", \n");
|
||||
|
||||
// set command
|
||||
if (strcmp(ptrToCommandName, "set") == 0) {
|
||||
if (wc == 1) {
|
||||
SerialAndTelnet.println();
|
||||
SerialAndTelnet.println("Stored settings:");
|
||||
SerialAndTelnet.printf(" wifi_ssid=%s", (!_wifi_ssid) ? "<not set>" : _wifi_ssid);
|
||||
SerialAndTelnet.println();
|
||||
SerialAndTelnet.printf(" wifi_password=");
|
||||
SerialAndTelnet.printf(" wifi=%s ", (!_wifi_ssid) ? "<not set>" : _wifi_ssid);
|
||||
if (!_wifi_password) {
|
||||
SerialAndTelnet.print("<not set>");
|
||||
} else {
|
||||
@@ -598,7 +612,7 @@ void MyESP::_telnetCommand(char * commandLine) {
|
||||
(_fs_settings_callback)(MYESP_FSACTION_LIST, 0, NULL, NULL);
|
||||
|
||||
SerialAndTelnet.println();
|
||||
SerialAndTelnet.println("Usage: set <setting> [value]");
|
||||
SerialAndTelnet.println("Usage: set <setting> [value...]");
|
||||
} else if (wc == 2) {
|
||||
char * setting = _telnet_readWord();
|
||||
_changeSetting(1, setting, NULL);
|
||||
@@ -606,10 +620,20 @@ void MyESP::_telnetCommand(char * commandLine) {
|
||||
char * setting = _telnet_readWord();
|
||||
char * value = _telnet_readWord();
|
||||
_changeSetting(2, setting, value);
|
||||
} else if (wc == 4) {
|
||||
char * setting = _telnet_readWord();
|
||||
char * value1 = _telnet_readWord();
|
||||
char * value2 = _telnet_readWord();
|
||||
_changeSetting2(setting, value1, value2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// reboot command
|
||||
if ((strcmp(ptrToCommandName, "reboot") == 0) && (wc == 1)) {
|
||||
resetESP();
|
||||
}
|
||||
|
||||
// call callback function
|
||||
(_telnetcommand_callback)(wc, commandLine);
|
||||
}
|
||||
@@ -632,7 +656,7 @@ void MyESP::_telnetHandle() {
|
||||
case '\n':
|
||||
_command[charsRead] = '\0'; // null terminate our command char array
|
||||
if (charsRead > 0) {
|
||||
charsRead = 0; // is static, so have to reset
|
||||
charsRead = 0; // is static, so have to reset
|
||||
_suspendOutput = false;
|
||||
if (_use_serial) {
|
||||
SerialAndTelnet.println(); // force newline if in Telnet
|
||||
@@ -640,19 +664,20 @@ void MyESP::_telnetHandle() {
|
||||
_telnetCommand(_command);
|
||||
}
|
||||
break;
|
||||
case '\b': // handle backspace in input: put a space in last char
|
||||
if (charsRead > 0) { // and adjust commandLine and charsRead
|
||||
case '\b': // handle backspace in input: put a space in last char
|
||||
if (charsRead > 0) {
|
||||
_command[--charsRead] = '\0';
|
||||
SerialAndTelnet << byte('\b') << byte(' ') << byte('\b'); //no idea how this works, found it on the Internet
|
||||
SerialAndTelnet << byte('\b') << byte(' ') << byte('\b');
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
_consoleShowHelp();
|
||||
if (!_suspendOutput) {
|
||||
_consoleShowHelp();
|
||||
} else {
|
||||
_command[charsRead++] = c; // add it to buffer as its part of the string entered
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
resetESP();
|
||||
break;
|
||||
case 0x04: // EOT
|
||||
case 0x04: // EOT, CTRL-D
|
||||
myDebug_P(PSTR("* exiting telnet session"));
|
||||
SerialAndTelnet.disconnectClient();
|
||||
break;
|
||||
@@ -825,7 +850,7 @@ void MyESP::_fs_eraseConfig() {
|
||||
myDebug_P(PSTR("[FS] Erasing settings, please wait a few seconds. ESP will automatically restart when finished."));
|
||||
|
||||
if (SPIFFS.format()) {
|
||||
delay(2000); // wait 2 seconds
|
||||
delay(1000); // wait 1 seconds
|
||||
resetESP();
|
||||
}
|
||||
}
|
||||
@@ -928,7 +953,7 @@ void MyESP::_fs_setup() {
|
||||
return;
|
||||
}
|
||||
|
||||
//_fs_printConfig(); // for debugging
|
||||
// _fs_printConfig(); // for debugging
|
||||
|
||||
// load the config file. if it doesn't exist create it
|
||||
if (!_fs_loadConfig()) {
|
||||
|
||||
@@ -178,6 +178,7 @@ class MyESP {
|
||||
telnetcommand_callback_f _telnetcommand_callback; // Callable for projects commands
|
||||
telnet_callback_f _telnet_callback; // callback for connect/disconnect
|
||||
void _changeSetting(uint8_t wc, const char * setting, const char * value);
|
||||
void _changeSetting2(const char * setting, const char * value1, const char * value2);
|
||||
|
||||
// fs
|
||||
void _fs_setup();
|
||||
|
||||
@@ -82,7 +82,6 @@ command_t PROGMEM project_cmds[] = {
|
||||
{"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"},
|
||||
{"log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
||||
{"publish", "publish values to MQTT"},
|
||||
@@ -845,6 +844,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
||||
if (type == MQTT_CONNECT_EVENT) {
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_TEMP);
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_MODE);
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_WWACTIVATED);
|
||||
myESP.mqttSubscribe(TOPIC_SHOWER_TIMER);
|
||||
myESP.mqttSubscribe(TOPIC_SHOWER_ALERT);
|
||||
myESP.mqttSubscribe(TOPIC_SHOWER_COLDSHOT);
|
||||
@@ -888,6 +888,16 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
||||
}
|
||||
}
|
||||
|
||||
// wwActivated
|
||||
if (strcmp(topic, TOPIC_BOILER_WWACTIVATED) == 0) {
|
||||
if (message[0] == '1') {
|
||||
ems_setWarmWaterActivated(true);
|
||||
} else if (message[0] == '0') {
|
||||
ems_setWarmWaterActivated(false);
|
||||
}
|
||||
publishValues(true); // publish back immediately
|
||||
}
|
||||
|
||||
// shower timer
|
||||
if (strcmp(topic, TOPIC_SHOWER_TIMER) == 0) {
|
||||
if (message[0] == '1') {
|
||||
|
||||
11
src/ems.cpp
11
src/ems.cpp
@@ -768,9 +768,10 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
||||
EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE;
|
||||
|
||||
// at this point we can assume Txstatus is EMS_TX_STATUS_WAIT
|
||||
// for READ, WRITE or VALIDATE the dest is always us, so check this
|
||||
// if not just process and quit
|
||||
// for READ, WRITE or VALIDATE the dest (telegram[1]) is always us, so check for this
|
||||
// if not we probably didn't get any response so remove the last Tx from the queue and process the telegram
|
||||
if ((telegram[1] & 0x7F) != EMS_ID_ME) {
|
||||
_removeTxQueue();
|
||||
_ems_processTelegram(telegram, length);
|
||||
return;
|
||||
}
|
||||
@@ -1443,11 +1444,7 @@ char * ems_getBoilerDescription(char * buffer) {
|
||||
* Find the versions of our connected devices
|
||||
*/
|
||||
void ems_scanDevices() {
|
||||
myDebug("Scanning EMS bus for devices...");
|
||||
|
||||
// start refresh when scanning and forget anything devices we may have already set
|
||||
EMS_Thermostat.type_id = EMS_ID_NONE; // forget thermostat
|
||||
EMS_Thermostat.model_id = EMS_MODEL_NONE;
|
||||
myDebug("Scanning EMS bus for devices.");
|
||||
|
||||
std::list<uint8_t> Device_Ids; // new list
|
||||
|
||||
|
||||
@@ -23,17 +23,18 @@
|
||||
#define MQTT_QOS 1
|
||||
|
||||
// MQTT for thermostat
|
||||
#define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values
|
||||
#define TOPIC_THERMOSTAT_CMD_TEMP "thermostat_cmd_temp" // for received thermostat temp changes
|
||||
#define TOPIC_THERMOSTAT_CMD_MODE "thermostat_cmd_mode" // for received thermostat mode changes
|
||||
#define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values to MQTT
|
||||
#define TOPIC_THERMOSTAT_CMD_TEMP "thermostat_cmd_temp" // for received thermostat temp changes via MQTT
|
||||
#define TOPIC_THERMOSTAT_CMD_MODE "thermostat_cmd_mode" // for received thermostat mode changes via MQTT
|
||||
#define THERMOSTAT_CURRTEMP "thermostat_currtemp" // current temperature
|
||||
#define THERMOSTAT_SELTEMP "thermostat_seltemp" // selected temperature
|
||||
#define THERMOSTAT_MODE "thermostat_mode" // mode
|
||||
|
||||
// MQTT for boiler
|
||||
#define TOPIC_BOILER_DATA "boiler_data" // for sending boiler values
|
||||
#define TOPIC_BOILER_DATA "boiler_data" // for sending boiler values to MQTT
|
||||
#define TOPIC_BOILER_TAPWATER_ACTIVE "tapwater_active" // if hot tap water is running
|
||||
#define TOPIC_BOILER_HEATING_ACTIVE "heating_active" // if heating is on
|
||||
#define TOPIC_BOILER_WWACTIVATED "wwactivated" // for receiving MQTT message to change water on/off
|
||||
|
||||
// shower time
|
||||
#define TOPIC_SHOWERTIME "showertime" // for sending shower time results
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define APP_NAME "EMS-ESP"
|
||||
#define APP_VERSION "1.5.1"
|
||||
#define APP_VERSION "1.5.2"
|
||||
#define APP_HOSTNAME "ems-esp"
|
||||
|
||||
Reference in New Issue
Block a user