mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
improved handling of telegram sizes
This commit is contained in:
@@ -124,7 +124,7 @@ And lastly if you don't fancy building the circuit, [bbqkees](http://www.domotic
|
||||
|
||||
My circuit will work with both 3.3V and 5V. It's easiest though to power directly from the ESP's 3V3 line.
|
||||
|
||||
Powering the ESP89266 can be either via the USB from a PC or external 5V power supply or from the EMS line itself using a buck step-down converter. The EMS provides about 15V AC current. The advantage of using the EMS is obviously less power cables and it's neater to place inline with the thermostat. I use a [Pololu D24C22F5](https://www.pololu.com/product/2858) which is 5V/2A buck step-down module and probably slightly overkill for what we need. The additional part of the circuit is shown below along with an earlier breadboard prototype using a NodeMCU2 (with the additional LEDs):
|
||||
Powering the ESP89266 can be either via the USB from a PC or external 5V power supply or from the EMS itself using a buck step-down converter. The EMS provides about a 15V AC current direct from the EMS line, or around 12V from the 3.5" service jack. The advantage of using the EMS for power is obviously the exclusion of an external power adapter and you can place the small circuit in line with the thermostat tucked away close to the boiler. The circuit's bridge rectifier will produce about 14.5V DC at UEMS (see schematic). I use a [Pololu D24C22F5](https://www.pololu.com/product/2858) which is 5V/2A buck step-down module and probably slightly overkill for what we need. The additional part of the circuit is shown below along with an earlier breadboard prototype using a NodeMCU2 (with the additional LEDs):
|
||||
|
||||
| Power circuit | Example |
|
||||
| ------------------------------------------ | ---------------------------------------------------- |
|
||||
@@ -218,7 +218,7 @@ Every telegram sent is echo'd back to Rx.
|
||||
|
||||
`ems.cpp` is the logic to read the EMS packets (telegrams), validates them and process them based on the type.
|
||||
|
||||
`boiler.ino` is the Arduino code for the ESP8266 that kicks it all off. This is where we have specific logic such as the code to monitor and alert on the Shower timer and light up the LEDs.
|
||||
`boiler.ino` is the Arduino code for the ESP8266 that kicks it all off. This is where we have specific logic such as the code to monitor and alert on the Shower timer and light up the LEDs. LED support is enabled by setting the -DUSE_LED build flag.
|
||||
|
||||
`ESPHelper.cpp` is my customized version of [ESPHelper](https://github.com/ItKindaWorks/ESPHelper) with added Telnet support and some other minor tweaking.
|
||||
|
||||
@@ -242,7 +242,7 @@ Note the thermostat types are based on a RC20 model thermostat. If using an RC30
|
||||
### Customizing
|
||||
|
||||
Most of the changes will be done in `boiler.ino` and `ems.cpp`.
|
||||
* To add new handlers for data types, create a callback function and add to the `EMS_Types` at the top of the file `ems.cpp`
|
||||
* To add new handlers for data types, create a callback function and add to the `EMS_Types` at the top of the file `ems.cpp` and modify `ems.h`
|
||||
* To change your thermostat type set `EMS_ID_THERMOSTAT` in `ems.cpp`. The default is 0x17 for an RC20.
|
||||
* The DEFINES `BOILER_THERMOSTAT_ENABLED`, `BOILER_SHOWER_ENABLED` and `BOILER_SHOWER_TIMER` enabled the thermostat logic, the shower logic and the shower timer alert logic respectively. 1 is on and 0 is off.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ env_default = nodemcuv2
|
||||
|
||||
[common]
|
||||
platform = espressif8266
|
||||
build_flags = -DMQTT_MAX_PACKET_SIZE=300
|
||||
build_flags = -DMQTT_MAX_PACKET_SIZE=300 -DUSE_LED
|
||||
build_flags_custom = '-DWIFI_SSID="my_ssid"' '-DWIFI_PASSWORD="my_password"' '-DMQTT_IP="my_broker_ip"' '-DMQTT_USER="my_broker_username"' '-DMQTT_PASS="my_broker_password"'
|
||||
lib_deps =
|
||||
Time
|
||||
|
||||
@@ -579,7 +579,7 @@ bool ESPHelper::isCRLF(char character) {
|
||||
|
||||
// handler for Telnet
|
||||
void ESPHelper::consoleHandle() {
|
||||
// look for Client connect trial
|
||||
// look for Client
|
||||
if (telnetServer.hasClient()) {
|
||||
if (telnetClient && telnetClient.connected()) {
|
||||
// Verify if the IP is same than actual connection
|
||||
@@ -614,7 +614,7 @@ void ESPHelper::consoleHandle() {
|
||||
// Show the initial message
|
||||
consoleShowHelp();
|
||||
|
||||
// Empty buffer in
|
||||
// Empty buffer
|
||||
while (telnetClient.available()) {
|
||||
telnetClient.read();
|
||||
}
|
||||
@@ -625,7 +625,7 @@ void ESPHelper::consoleHandle() {
|
||||
|
||||
// Get command over telnet
|
||||
if (_telnetConnected) {
|
||||
char last = ' '; // To avoid process two times the "\r\n"
|
||||
char last = ' '; // To avoid processing double "\r\n"
|
||||
|
||||
while (telnetClient.available()) { // get data from Client
|
||||
|
||||
@@ -663,7 +663,7 @@ void ESPHelper::consoleHandle() {
|
||||
}
|
||||
}
|
||||
|
||||
// Set help for commands over telnet setted by sketch
|
||||
// Set help for commands over telnet
|
||||
void ESPHelper::consoleSetHelpProjectsCmds(String help) {
|
||||
_helpProjectCmds = help;
|
||||
}
|
||||
@@ -767,7 +767,7 @@ void ESPHelper::consoleShowHelp() {
|
||||
"&=toggle verbose messages");
|
||||
|
||||
if (_helpProjectCmds != "" && (_consoleCallbackProjectCmds)) {
|
||||
help.concat("\n\r* ");
|
||||
help.concat("\n\r");
|
||||
help.concat(_helpProjectCmds);
|
||||
}
|
||||
help.concat("\n\r");
|
||||
|
||||
51
src/ems.cpp
51
src/ems.cpp
@@ -28,19 +28,20 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length);
|
||||
bool _process_Version(uint8_t * data, uint8_t length);
|
||||
|
||||
const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
||||
{{EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", 36, _process_UBAMonitorFast},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", 28, _process_UBAMonitorSlow},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", 10, _process_UBAMonitorWWMessage},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAParameterWW, "UBAParameterWW", 10, _process_UBAParameterWW},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBATotalUptimeMessage, "UBATotalUptimeMessage", 30, NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceSettingsMessage, "UBAMaintenanceSettingsMessage", 30, NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", 30, NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", 30, NULL},
|
||||
{ {EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAParameterWW, "UBAParameterWW", _process_UBAParameterWW},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBATotalUptimeMessage, "UBATotalUptimeMessage", NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceSettingsMessage, "UBAMaintenanceSettingsMessage", NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", NULL},
|
||||
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", NULL},
|
||||
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", 19, _process_RC20StatusMessage},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", 20, _process_RC20Time},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", 27, _process_RC20Temperature},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", 2, _process_Version}};
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", _process_RC20StatusMessage},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", _process_RC20Time},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", _process_RC20Temperature},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", _process_Version}
|
||||
};
|
||||
|
||||
// reserve space for the data we collect from the Boiler and Thermostat
|
||||
_EMS_Boiler EMS_Boiler;
|
||||
@@ -61,7 +62,8 @@ const uint8_t ems_crc_table[] =
|
||||
0x65, 0x67, 0x99, 0x9B, 0x9D, 0x9F, 0x91, 0x93, 0x95, 0x97, 0x89, 0x8B, 0x8D, 0x8F, 0x81, 0x83, 0x85, 0x87, 0xB9,
|
||||
0xBB, 0xBD, 0xBF, 0xB1, 0xB3, 0xB5, 0xB7, 0xA9, 0xAB, 0xAD, 0xAF, 0xA1, 0xA3, 0xA5, 0xA7, 0xD9, 0xDB, 0xDD, 0xDF,
|
||||
0xD1, 0xD3, 0xD5, 0xD7, 0xC9, 0xCB, 0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5,
|
||||
0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7};
|
||||
0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7
|
||||
};
|
||||
|
||||
extern ESPHelper myESP; // needed for the DEBUG statements below
|
||||
#define myDebug(x, ...) myESP.printf(x, ##__VA_ARGS__);
|
||||
@@ -208,7 +210,7 @@ void _debugPrintTelegram(const char * prefix, uint8_t * data, uint8_t len, const
|
||||
}
|
||||
|
||||
time_t currentTime = now();
|
||||
myDebug("[%02d:%02d:%02d] %s len=%02d, data: ", hour(currentTime), minute(currentTime), second(currentTime), prefix, len);
|
||||
myDebug("[%02d:%02d:%02d] %s len=%d, data: ", hour(currentTime), minute(currentTime), second(currentTime), prefix, len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
myDebug("%02x ", data[i]);
|
||||
}
|
||||
@@ -559,12 +561,13 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length) {
|
||||
|
||||
/*
|
||||
* Version - type 0x02 - get the version of the Thermostat firmware
|
||||
* We don't bother storing these values anywhere
|
||||
*/
|
||||
bool _process_Version(uint8_t * data, uint8_t length) {
|
||||
uint8_t major = data[1];
|
||||
uint8_t minor = data[2];
|
||||
|
||||
myDebug("Version %d.%d\n", major, minor); // TODO: finish this
|
||||
myDebug("Version %d.%d\n", major, minor);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -601,10 +604,12 @@ void _buildTxTelegram(uint8_t data_value) {
|
||||
EMS_TxTelegram.data[2] = EMS_TxTelegram.type; // type
|
||||
EMS_TxTelegram.data[3] = EMS_TxTelegram.offset; //offset
|
||||
|
||||
// data
|
||||
EMS_TxTelegram.data[4] = data_value; // value, can be size
|
||||
// data:
|
||||
// for reading this is #bytes we want to read (the size)
|
||||
// for writing its the value we want to write
|
||||
EMS_TxTelegram.data[4] = data_value;
|
||||
|
||||
// crc
|
||||
// crc:
|
||||
EMS_TxTelegram.data[5] = _crcCalculator(EMS_TxTelegram.data, EMS_TxTelegram.length);
|
||||
|
||||
EMS_Sys_Status.emsTxStatus = EMS_TX_PENDING; // armed and ready to send
|
||||
@@ -623,7 +628,7 @@ void ems_doReadCommand(uint8_t type) {
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
uint8_t dest, size;
|
||||
uint8_t dest;
|
||||
|
||||
// scan through known types
|
||||
bool typeFound = false;
|
||||
@@ -633,7 +638,6 @@ void ems_doReadCommand(uint8_t type) {
|
||||
typeFound = true; // we have a match
|
||||
// call callback to fetch the values from the telegram
|
||||
dest = EMS_Types[i].src;
|
||||
size = EMS_Types[i].size;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
@@ -642,10 +646,9 @@ void ems_doReadCommand(uint8_t type) {
|
||||
// for adhoc calls use default values
|
||||
if (!typeFound) {
|
||||
dest = EMS_ID_BOILER; // default is boiler
|
||||
size = 1;
|
||||
myDebug("Requesting type (0x%02x) from dest 0x%02x for %d bytes\n", type, dest, size);
|
||||
myDebug("Requesting type (0x%02x) from dest 0x%02x\n", type, dest);
|
||||
} else {
|
||||
myDebug("Requesting type %s(0x%02x) from dest 0x%02x for %d bytes\n", EMS_Types[i].typeString, type, dest, size);
|
||||
myDebug("Requesting type %s(0x%02x) from dest 0x%02x\n", EMS_Types[i].typeString, type, dest);
|
||||
}
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_READ; // read command
|
||||
@@ -654,7 +657,7 @@ void ems_doReadCommand(uint8_t type) {
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH; // is always 6 bytes long (including CRC at end)
|
||||
EMS_TxTelegram.type = type;
|
||||
|
||||
_buildTxTelegram(size); // we send the # bytes we want back
|
||||
_buildTxTelegram(EMS_MAX_TELEGRAM_LENGTH); // we send the # bytes we want back
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EMS_TYPE_NONE 0x00 // none
|
||||
|
||||
#define EMS_MIN_TELEGRAM_LENGTH 6 // minimal length for a validation telegram, including CRC
|
||||
#define EMS_MAX_TELEGRAM_LENGTH 99 // max length of a telegram, including CRC
|
||||
|
||||
#define EMS_TX_MAXBUFFERSIZE 128 // max size of the buffer. packets are 32 bits
|
||||
|
||||
@@ -156,7 +157,7 @@ typedef struct {
|
||||
uint8_t src;
|
||||
uint8_t type;
|
||||
const char typeString[50];
|
||||
uint8_t size; // size of telegram, excluding the 4-byte header and crc
|
||||
//uint8_t size; // size of telegram, excluding the 4-byte header and crc
|
||||
EMS_processType_cb processType_cb;
|
||||
} _EMS_Types;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user