mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
added new Version type
This commit is contained in:
@@ -187,7 +187,7 @@ The Boiler (ID 0x08) will send out these broadcast telegrams regularly:
|
|||||||
And a thermostat (ID 0x17 for a RC20) would broadcast these messages regularly:
|
And a thermostat (ID 0x17 for a RC20) would broadcast these messages regularly:
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
| ---- | ----------- | undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |
|
| ---- | ----------- | undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |
|
||||||
| 0x06 | time on thermostat Y,M,H,D,M,S,wd |
|
| 0x06 | time on thermostat Y,M,H,D,M,S,wd |
|
||||||
|
|
||||||
Refer to the code in `ems.cpp` for further explanation on how to parse these message types and also reference the EMS Wiki.
|
Refer to the code in `ems.cpp` for further explanation on how to parse these message types and also reference the EMS Wiki.
|
||||||
@@ -233,14 +233,15 @@ Every telegram sent is echo'd back to Rx.
|
|||||||
| Thermostat (0x17) | 0xA8 | RC20Temperature | sets temperature and operating modes |
|
| Thermostat (0x17) | 0xA8 | RC20Temperature | sets temperature and operating modes |
|
||||||
| Thermostat (0x17) | 0xA3 | RCOutdoorTempMessage | |
|
| Thermostat (0x17) | 0xA3 | RCOutdoorTempMessage | |
|
||||||
| Thermostat (0x17) | 0x91 | RC20StatusMessage | reads set & current room temperatures |
|
| Thermostat (0x17) | 0x91 | RC20StatusMessage | reads set & current room temperatures |
|
||||||
|
| Thermostat (0x17) | 0x02 | Version | reads Version major/minor |
|
||||||
|
|
||||||
Note the thermostat types are based on a RC20 model thermostat. If using an RC30/RC35 use types 0x3E and 0x48 to read the values.
|
Note the thermostat types are based on a RC20 model thermostat. If using an RC30/RC35 use types 0x3E and 0x48 to read the values.
|
||||||
|
|
||||||
### Customizing
|
### Customizing
|
||||||
|
|
||||||
Most of the changes will be done in `boiler.ino` and `ems.cpp`.
|
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` and the DEFINES in `ems.h`
|
* 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 change your thermostat type set `EMS_ID_THERMOSTAT` in `ems.h`. The default is 0x17 for an RC20.
|
* 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.
|
* 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.
|
||||||
|
|
||||||
### MQTT
|
### MQTT
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Ticker showerResetTimer;
|
|||||||
"* S=toggle Shower Timer on/off\n\r" \
|
"* S=toggle Shower Timer on/off\n\r" \
|
||||||
"* r [n] to request for data from EMS " \
|
"* r [n] to request for data from EMS " \
|
||||||
"(33=UBAParameterWW, 18=UBAMonitorFast, 19=UBAMonitorSlow, " \
|
"(33=UBAParameterWW, 18=UBAMonitorFast, 19=UBAMonitorSlow, " \
|
||||||
"34=UBAMonitorWWMessage, 91=RC20StatusMessage, 6=RC20Time)\n\r" \
|
"34=UBAMonitorWWMessage, 91=RC20StatusMessage, 6=RC20Time, 2=Version)\n\r" \
|
||||||
"* t [n] set thermostat temperature to n\n\r" \
|
"* t [n] set thermostat temperature to n\n\r" \
|
||||||
"* w [n] set boiler warm water temperature to n (min 30)\n\r" \
|
"* w [n] set boiler warm water temperature to n (min 30)\n\r" \
|
||||||
"* a [n] activate boiler warm water on (n=1) or off (n=0)"
|
"* a [n] activate boiler warm water on (n=1) or off (n=0)"
|
||||||
|
|||||||
62
src/ems.cpp
62
src/ems.cpp
@@ -15,8 +15,41 @@
|
|||||||
_EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
_EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
||||||
_EMS_TxTelegram EMS_TxTelegram; // Empty buffer for sending telegrams
|
_EMS_TxTelegram EMS_TxTelegram; // Empty buffer for sending telegrams
|
||||||
|
|
||||||
// call back for handling Types
|
// define here the Thermostat type
|
||||||
#define MAX_TYPECALLBACK 11
|
#define EMS_ID_THERMOSTAT 0x17 // x17=RC20, x10=RC30 (Moduline 300)
|
||||||
|
|
||||||
|
// define here the EMS telegram types you need
|
||||||
|
// Boiler...
|
||||||
|
#define EMS_TYPE_UBAMonitorFast 0x18 // is an automatic monitor broadcast
|
||||||
|
#define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast
|
||||||
|
#define EMS_TYPE_UBAMonitorWWMessage 0x34 // is an automatic monitor broadcast
|
||||||
|
#define EMS_TYPE_UBAMaintenanceStatusMessage 0x1c // is an automatic monitor broadcast
|
||||||
|
#define EMS_TYPE_UBAParameterWW 0x33
|
||||||
|
|
||||||
|
#define EMS_TYPE_UBATotalUptimeMessage 0x14
|
||||||
|
#define EMS_TYPE_UBAMaintenanceSettingsMessage 0x15
|
||||||
|
#define EMS_TYPE_UBAParametersMessage 0x16
|
||||||
|
|
||||||
|
// Thermostat...
|
||||||
|
#define EMS_TYPE_RC20StatusMessage 0x91
|
||||||
|
#define EMS_TYPE_RC20Time 0x06 // is an automatic monitor broadcast
|
||||||
|
#define EMS_TYPE_RC20Temperature 0xA8
|
||||||
|
#define EMS_TYPE_RCOutdoorTempMessage 0xa3 // we can ignore
|
||||||
|
#define EMS_TYPE_Version 0x02 // version of the controller
|
||||||
|
|
||||||
|
// and call backs
|
||||||
|
#define MAX_TYPECALLBACK 12 // make sure it matches the #types you have
|
||||||
|
// callbacks per type
|
||||||
|
bool _process_UBAMonitorFast(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_UBAMonitorSlow(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_UBAMonitorWWMessage(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_UBAParameterWW(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_RC20StatusMessage(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_RC20Time(uint8_t * data, uint8_t length);
|
||||||
|
bool _process_RC20Temperature(uint8_t * data, uint8_t length);
|
||||||
|
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] =
|
const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
||||||
{ {EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", 36, _process_UBAMonitorFast},
|
{ {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_UBAMonitorSlow, "UBAMonitorSlow", 28, _process_UBAMonitorSlow},
|
||||||
@@ -29,7 +62,8 @@ const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
|||||||
|
|
||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", 3, _process_RC20StatusMessage},
|
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", 3, _process_RC20StatusMessage},
|
||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", 20, _process_RC20Time},
|
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", 20, _process_RC20Time},
|
||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", 10, _process_RC20Temperature}
|
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", 10, _process_RC20Temperature},
|
||||||
|
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", 2, _process_Version}
|
||||||
};
|
};
|
||||||
|
|
||||||
// reserve space for the data we collect from the Boiler and Thermostat
|
// reserve space for the data we collect from the Boiler and Thermostat
|
||||||
@@ -168,7 +202,7 @@ void ems_setLogVerbose(bool b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate CRC checksum using lookup table
|
* Calculate CRC checksum using lookup table for speed
|
||||||
* len is length of data in bytes (including the CRC byte at end)
|
* len is length of data in bytes (including the CRC byte at end)
|
||||||
*/
|
*/
|
||||||
uint8_t _crcCalculator(uint8_t * data, uint8_t len) {
|
uint8_t _crcCalculator(uint8_t * data, uint8_t len) {
|
||||||
@@ -238,7 +272,7 @@ void _ems_sendTelegram() {
|
|||||||
* When we receive a Poll Request we need to send quickly
|
* When we receive a Poll Request we need to send quickly
|
||||||
*/
|
*/
|
||||||
void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
||||||
// if we're waiting on a reponse from a read and it hasn't come, try again
|
// if we're waiting on a response from a previous read and it hasn't come, try again
|
||||||
if ((EMS_Sys_Status.emsTxStatus != EMS_TX_PENDING)
|
if ((EMS_Sys_Status.emsTxStatus != EMS_TX_PENDING)
|
||||||
&& ((EMS_TxTelegram.action == EMS_TX_READ) || (EMS_TxTelegram.action == EMS_TX_VALIDATE))
|
&& ((EMS_TxTelegram.action == EMS_TX_READ) || (EMS_TxTelegram.action == EMS_TX_VALIDATE))
|
||||||
&& ((millis() - EMS_Sys_Status.emsLastTx) > RX_READ_TIMEOUT)) {
|
&& ((millis() - EMS_Sys_Status.emsLastTx) > RX_READ_TIMEOUT)) {
|
||||||
@@ -325,6 +359,7 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
|||||||
// if its an echo of ourselves from the master, ignore
|
// if its an echo of ourselves from the master, ignore
|
||||||
if (src == EMS_ID_ME) {
|
if (src == EMS_ID_ME) {
|
||||||
_debugPrintTelegram("Telegram echo:", telegram, length, COLOR_BLUE);
|
_debugPrintTelegram("Telegram echo:", telegram, length, COLOR_BLUE);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// header
|
// header
|
||||||
@@ -338,7 +373,8 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
|||||||
char src_s[20];
|
char src_s[20];
|
||||||
char dest_s[20];
|
char dest_s[20];
|
||||||
|
|
||||||
// scan through known types
|
// scan through known types we understand
|
||||||
|
// set typeFound if we found a match
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool typeFound = false;
|
bool typeFound = false;
|
||||||
while (i < MAX_TYPECALLBACK) {
|
while (i < MAX_TYPECALLBACK) {
|
||||||
@@ -370,7 +406,7 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
|||||||
|
|
||||||
// did we actually ask for it from an earlier read/write request?
|
// did we actually ask for it from an earlier read/write request?
|
||||||
// note when we issue a read command the responder (dest) has to return a telegram back immediately
|
// note when we issue a read command the responder (dest) has to return a telegram back immediately
|
||||||
if ((EMS_TxTelegram.action == EMS_TX_READ) && (EMS_TxTelegram.type == type) && typeFound) {
|
if ((EMS_TxTelegram.action == EMS_TX_READ) && (EMS_TxTelegram.type == type)) {
|
||||||
// yes we were expecting this one one
|
// yes we were expecting this one one
|
||||||
EMS_Sys_Status.emsRxPgks++; // increment rx counter
|
EMS_Sys_Status.emsRxPgks++; // increment rx counter
|
||||||
EMS_Sys_Status.emsLastRx = millis();
|
EMS_Sys_Status.emsLastRx = millis();
|
||||||
@@ -522,6 +558,18 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version - type 0x02 - get the version of the Thermostat
|
||||||
|
*/
|
||||||
|
bool _process_Version(uint8_t * data, uint8_t length) {
|
||||||
|
uint8_t major = data[1];
|
||||||
|
uint8_t minor = data[2];
|
||||||
|
|
||||||
|
// TODO: finish this
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* process_RC20Time - type 0x06 - date and time from the RC20 thermostat (0x17) - 14 bytes long
|
* process_RC20Time - type 0x06 - date and time from the RC20 thermostat (0x17) - 14 bytes long
|
||||||
*/
|
*/
|
||||||
|
|||||||
33
src/ems.h
33
src/ems.h
@@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Header file for EMS.cpp
|
* Header file for EMS.cpp
|
||||||
|
*
|
||||||
|
* You shouldn't need to change much in this file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __EMS_H
|
#ifndef __EMS_H
|
||||||
@@ -8,32 +10,13 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
// EMS IDs
|
// EMS IDs
|
||||||
#define EMS_ID_THERMOSTAT 0x17 // x17=RC20, x10=RC30 (Moduline 300)
|
|
||||||
|
|
||||||
#define EMS_ID_NONE 0x00 // Fixed - used as a dest in broadcast messages
|
#define EMS_ID_NONE 0x00 // Fixed - used as a dest in broadcast messages
|
||||||
#define EMS_ID_BOILER 0x08 // Fixed - also known as MC10.
|
#define EMS_ID_BOILER 0x08 // Fixed - also known as MC10.
|
||||||
#define EMS_ID_ME 0x0B // Fixed - our device, hardcoded as "Service Key"
|
#define EMS_ID_ME 0x0B // Fixed - our device, hardcoded as "Service Key"
|
||||||
|
|
||||||
// EMS Telegram Types
|
// Special EMS Telegram Types
|
||||||
#define EMS_TYPE_NONE 0x00 // none
|
#define EMS_TYPE_NONE 0x00 // none
|
||||||
|
|
||||||
#define EMS_TYPE_UBAMonitorFast 0x18 // is an automatic monitor broadcast
|
|
||||||
#define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast
|
|
||||||
#define EMS_TYPE_UBAMonitorWWMessage 0x34 // is an automatic monitor broadcast
|
|
||||||
#define EMS_TYPE_UBAMaintenanceStatusMessage 0x1c // is an automatic monitor broadcast
|
|
||||||
#define EMS_TYPE_UBAParameterWW 0x33
|
|
||||||
|
|
||||||
#define EMS_TYPE_UBATotalUptimeMessage 0x14
|
|
||||||
#define EMS_TYPE_UBAMaintenanceSettingsMessage 0x15
|
|
||||||
#define EMS_TYPE_UBAParametersMessage 0x16
|
|
||||||
|
|
||||||
// EMS Telegram types from Thermostat
|
|
||||||
// types 1A and 35 and used for errors from Thermostat
|
|
||||||
#define EMS_TYPE_RC20StatusMessage 0x91
|
|
||||||
#define EMS_TYPE_RC20Time 0x06 // is an automatic monitor broadcast
|
|
||||||
#define EMS_TYPE_RC20Temperature 0xA8
|
|
||||||
#define EMS_TYPE_RCOutdoorTempMessage 0xa3 // we can ignore
|
|
||||||
|
|
||||||
#define EMS_TX_MAXBUFFERSIZE 128 // max size of the buffer. packets are 32 bits
|
#define EMS_TX_MAXBUFFERSIZE 128 // max size of the buffer. packets are 32 bits
|
||||||
|
|
||||||
/* EMS UART transfer status */
|
/* EMS UART transfer status */
|
||||||
@@ -86,7 +69,6 @@ typedef struct {
|
|||||||
/*
|
/*
|
||||||
* Telegram package defintions
|
* Telegram package defintions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// UBAParameterWW
|
// UBAParameterWW
|
||||||
bool wWActivated; // Warm Water activated
|
bool wWActivated; // Warm Water activated
|
||||||
@@ -170,15 +152,6 @@ void _initTxBuffer();
|
|||||||
void _buildTxTelegram(uint8_t data_value);
|
void _buildTxTelegram(uint8_t data_value);
|
||||||
void _debugPrintPackage(const char * prefix, uint8_t * data, uint8_t len, const char * color);
|
void _debugPrintPackage(const char * prefix, uint8_t * data, uint8_t len, const char * color);
|
||||||
|
|
||||||
// callbacks per type
|
|
||||||
bool _process_UBAMonitorFast(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_UBAMonitorSlow(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_UBAMonitorWWMessage(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_UBAParameterWW(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_RC20StatusMessage(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_RC20Time(uint8_t * data, uint8_t length);
|
|
||||||
bool _process_RC20Temperature(uint8_t * data, uint8_t length);
|
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
float _toFloat(uint8_t i, uint8_t * data);
|
float _toFloat(uint8_t i, uint8_t * data);
|
||||||
uint16_t _toLong(uint8_t i, uint8_t * data);
|
uint16_t _toLong(uint8_t i, uint8_t * data);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* emsuart.cpp
|
* emsuart.cpp
|
||||||
|
*
|
||||||
* The low level UART code for ESP8266 to read and write to the EMS bus via uart
|
* The low level UART code for ESP8266 to read and write to the EMS bus via uart
|
||||||
* Paul Derbyshire - https://github.com/proddy/EMS-ESP-Boiler
|
* Paul Derbyshire - https://github.com/proddy/EMS-ESP-Boiler
|
||||||
*/
|
*/
|
||||||
@@ -157,7 +158,7 @@ void ICACHE_FLASH_ATTR emsuart_tx_brk() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send to Tx, ending with a BRK
|
* Send to Tx, ending with a <BRK>
|
||||||
*/
|
*/
|
||||||
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user