more ems+ optimizations

This commit is contained in:
proddy
2019-04-19 17:11:36 +02:00
parent 584192344c
commit 8814c2a504
7 changed files with 171 additions and 90 deletions

View File

@@ -2,7 +2,7 @@ Language: Cpp
BasedOnStyle: LLVM
UseTab: Never
IndentWidth: 4
ColumnLimit: 140
ColumnLimit: 160
TabWidth: 4
#BreakBeforeBraces: Custom
BraceWrapping:

View File

@@ -9,20 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Buderus Logamax plus
- EMS+ support (thanks @GlennArens, @gl3nni3)
- Buderus Logamax plus boiler added
- EMS+ support (thanks too @gl3nni3 for making the first implementation)
- MQTT 'restart' topic to reboot ESP (thanks @balk77)
- Support for multiple thermostat heating circuits like the HC1/HC2 on a RC35, also via MQTT (thanks @lobocobra)
- `boiler flowtemp` command to set the flow temperature [(issue 59)](https://github.com/proddy/EMS-ESP/issues/59)
- `tx_delay` setting for circuits where we needed to slow down Tx transmission
- nefit proline hrc 24 cw4 thermostat
- support for Buderus RC300 and RC310 thermostats [(issue 37)](https://github.com/proddy/EMS-ESP/issues/37)
- added a test harness to try out response to various telegrams
### Changed
- `types` renamed to `devices` to also show all detected devices
- EMS Plus logic optimized
## [1.6.0] 2019-03-24
### Added

View File

@@ -929,6 +929,17 @@ void _showerColdShotStart() {
}
}
// run tests to validate handling of telegrams by injecting fake telegrams
void runUnitTest(uint8_t test_num) {
ems_setLogging(EMS_SYS_LOGGING_VERBOSE);
publishValuesTimer.detach();
systemCheckTimer.detach();
regularUpdatesTimer.detach();
if (test_num >= 1 && test_num <= 10) {
ems_testTelegram(test_num);
}
}
// callback for loading/saving settings to the file system (SPIFFS)
bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
if (action == MYESP_FSACTION_LOAD) {
@@ -1331,6 +1342,12 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
ok = true;
}
// test commands
if ((strcmp(first_cmd, "test") == 0) && (wc == 2)) {
runUnitTest(_readIntNumber());
ok = true;
}
// check for invalid command
if (!ok) {
myDebug("Unknown command. Use ? for help.");

View File

@@ -46,6 +46,7 @@ void _process_UBATotalUptimeMessage(_EMS_RxTelegram * EMS_RxTelegram);
void _process_UBAParametersMessage(_EMS_RxTelegram * EMS_RxTelegram);
void _process_SetPoints(_EMS_RxTelegram * EMS_RxTelegram);
void _process_SM10Monitor(_EMS_RxTelegram * EMS_RxTelegram);
void _process_SM100Monitor(_EMS_RxTelegram * EMS_RxTelegram);
// Common for most thermostats
void _process_RCTime(_EMS_RxTelegram * EMS_RxTelegram);
@@ -70,9 +71,9 @@ void _process_RC35StatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
// Easy
void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
//RC1010
void _process_RC1010StatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
void _process_RC1010SetMessage(_EMS_RxTelegram * EMS_RxTelegram);
// RC1010, RC300, RC310
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram);
/*
* Recognized EMS types and the functions they call to process the telegrams
@@ -95,6 +96,7 @@ const _EMS_Type EMS_Types[] = {
// Other devices
{EMS_MODEL_OTHER, EMS_TYPE_SM10Monitor, "SM10Monitor", _process_SM10Monitor},
{EMS_MODEL_OTHER, EMS_TYPE_SM100Monitor, "SM100Monitor", _process_SM100Monitor},
// RC10
{EMS_MODEL_RC10, EMS_TYPE_RCTime, "RCTime", _process_RCTime},
@@ -136,9 +138,9 @@ const _EMS_Type EMS_Types[] = {
{EMS_MODEL_EASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage},
{EMS_MODEL_BOSCHEASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage},
// Nefit 1010
{EMS_MODEL_RC1010, EMS_TYPE_RC1010StatusMessage, "RC1010StatusMessage", _process_RC1010StatusMessage},
{EMS_MODEL_RC1010, EMS_TYPE_RC1010Set, "RC1010SetMessage", _process_RC1010SetMessage}
// Nefit 1010, RC300, RC310 (EMS Plus)
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusMessage, "RCPLUSStatusMessage", _process_RCPLUSStatusMessage},
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSSet, "RCPLUSSetMessage", _process_RCPLUSSetMessage}
};
@@ -205,7 +207,6 @@ void ems_init() {
EMS_Thermostat.mode = 255; // dummy value
EMS_Thermostat.day_mode = 255; // dummy value
EMS_Thermostat.device_id = EMS_ID_NONE;
EMS_Thermostat.read_supported = false;
EMS_Thermostat.write_supported = false;
EMS_Thermostat.hc = 1; // default heating circuit is 1
EMS_Thermostat.daytemp = EMS_VALUE_INT_NOTSET; // 0x47 byte
@@ -377,7 +378,7 @@ void ems_setLogging(_EMS_SYS_LOGGING loglevel) {
/**
* Calculate CRC checksum using lookup table for speed
* len is length of data in bytes (including the CRC byte at end)
* So its the complete telegram with the header
* So its the complete telegram with the header. CRC is calculated only over the data bytes
*/
uint8_t _crcCalculator(uint8_t * data, uint8_t len) {
uint8_t crc = 0;
@@ -450,8 +451,9 @@ void _debugPrintTelegram(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram,
char output_str[200] = {0};
char buffer[16] = {0};
uint8_t len = EMS_RxTelegram->length;
uint8_t * data = EMS_RxTelegram->telegram;
uint8_t len = EMS_RxTelegram->length; // length of data block
uint8_t full_len = EMS_RxTelegram->full_length - 1; // no CRC
strlcpy(output_str, "(", sizeof(output_str));
strlcat(output_str, COLOR_CYAN, sizeof(output_str));
@@ -469,19 +471,19 @@ void _debugPrintTelegram(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram,
strlcat(output_str, prefix, sizeof(output_str));
strlcat(output_str, " telegram: ", sizeof(output_str));
for (int i = 0; i < len - 1; i++) {
for (int i = 0; i < full_len; i++) {
strlcat(output_str, _hextoa(data[i], buffer), sizeof(output_str));
strlcat(output_str, " ", sizeof(output_str)); // add space
}
strlcat(output_str, "(CRC=", sizeof(output_str));
strlcat(output_str, _hextoa(data[len - 1], buffer), sizeof(output_str));
strlcat(output_str, _hextoa(data[full_len], buffer), sizeof(output_str));
strlcat(output_str, ")", sizeof(output_str));
// print number of data bytes only if its a valid telegram
if (len > 5) {
strlcat(output_str, ", #data=", sizeof(output_str));
strlcat(output_str, itoa(len - 5, buffer, 10), sizeof(output_str));
strlcat(output_str, itoa(len, buffer, 10), sizeof(output_str));
}
strlcat(output_str, COLOR_RESET, sizeof(output_str));
@@ -509,7 +511,6 @@ void _ems_sendTelegram() {
return;
}
// if we're in raw mode just fire and forget
if (EMS_TxTelegram.action == EMS_TX_TELEGRAM_RAW) {
EMS_TxTelegram.data[EMS_TxTelegram.length - 1] = _crcCalculator(EMS_TxTelegram.data, EMS_TxTelegram.length); // add the CRC
@@ -616,7 +617,7 @@ void _createValidate() {
/*
* Entry point triggered by an interrupt in emsuart.cpp
* length is only data bytes, excluding the BRK
* length is size of all the data bytes with CRC, excluding the BRK at the end
* Read commands are asynchronous as they're handled by the interrupt
* When a telegram is processed we forcefully erase it from the stack to prevent overflow
*/
@@ -632,6 +633,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
/**
* the main logic that parses the telegram message
* When we receive a Poll Request we need to send any Tx packages quickly within a 200ms window
* length is total number of bytes of the telegram excluding the CRC byte at the end
*/
void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
// create the Rx package
@@ -639,6 +641,7 @@ void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
static uint32_t _last_emsPollFrequency = 0;
EMS_RxTelegram.telegram = telegram;
EMS_RxTelegram.timestamp = millis();
EMS_RxTelegram.full_length = length;
// check if we just received a single byte
// it could well be a Poll request from the boiler for us, which will have a value of 0x8B (0x0B | 0x80)
@@ -690,6 +693,25 @@ void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
return;
}
// fill in the rest of the Telegram
EMS_RxTelegram.src = telegram[0] & 0x7F; // removing 8th bit as we deal with both reads and writes here
EMS_RxTelegram.dest = telegram[1] & 0x7F; // remove 8th bit (don't care if read or write)
EMS_RxTelegram.offset = telegram[3]; // offset is always 4th byte
// determing if its normal ems or ems plus
if (telegram[2] >= 0xF0) {
// its EMS plus
EMS_RxTelegram.emsplus = true;
EMS_RxTelegram.type = (telegram[4] << 8) + telegram[5]; // is a long in bytes 5 & 6
EMS_RxTelegram.data = telegram + 6;
EMS_RxTelegram.length = length - 8; // remove 5 bytes header plus CRC + length byte + 0x00 at end
} else {
EMS_RxTelegram.emsplus = false;
EMS_RxTelegram.type = telegram[2]; // 3rd byte
EMS_RxTelegram.data = telegram + 4;
EMS_RxTelegram.length = length - 5; // remove 4 bytes header plus CRC
}
// Assume at this point we have something that vaguely resembles a telegram in the format [src] [dest] [type] [offset] [data] [crc]
// validate the CRC, if its bad ignore it
if (telegram[length - 1] != _crcCalculator(telegram, length)) {
@@ -717,25 +739,6 @@ void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
EMS_Sys_Status.emsRxTimestamp = EMS_RxTelegram.timestamp; // timestamp of last read
EMS_Sys_Status.emsBusConnected = true;
// fill in the rest of the Telegram
EMS_RxTelegram.src = telegram[0] & 0x7F; // removing 8th bit as we deal with both reads and writes here
EMS_RxTelegram.dest = telegram[1] & 0x7F; // remove 8th bit (don't care if read or write)
EMS_RxTelegram.offset = telegram[3]; // offset is always 4th byte
// determing if its normal ems or ems plus
if (telegram[2] >= 0xF0) {
// its EMS plus
EMS_RxTelegram.emsplus = true;
EMS_RxTelegram.type = (telegram[4] << 8) + telegram[5]; // is a long in bytes 5 & 6
EMS_RxTelegram.data = telegram + 6;
EMS_RxTelegram.length = length - 8; // remove 5 bytes header plus CRC + length byte + 0x00 at end
} else {
EMS_RxTelegram.emsplus = false;
EMS_RxTelegram.type = telegram[2]; // 3rd byte
EMS_RxTelegram.data = telegram + 4;
EMS_RxTelegram.length = length - 5; // remove 4 bytes header plus CRC
}
// now lets process it and see what to do next
_processType(&EMS_RxTelegram);
}
@@ -1167,21 +1170,19 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
}
/**
* type 0x01A5 - data from the Nefit RC1010 thermostat (0x18)
* type 0x01A5 - data from the Nefit RC1010 thermostat (0x18) and RC300/310s on 0x10
* EMS+ messages may come in with different offsets so handle them here
*/
void _process_RC1010StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0) {
// the whole telegram
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00 (CRC=CC), #data=27
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RC1010StatusMessage_curr); // value is * 10
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC1010StatusMessage_setpoint); // value is * 2
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RCPLUSStatusMessage_setpoint); // value is * 2
// room night setpoint is _toByte(2) (value is *2)
// boiler set temp is _toByte(4) (value is *2)
// day night is byte(8), 0x01 for night, 0x00 for day
}
// this is a temp value but not sure which one
@@ -1200,7 +1201,7 @@ void _process_RC1010StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
/*
* to complete....
*/
void _process_RC1010SetMessage(_EMS_RxTelegram * EMS_RxTelegram) {
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram) {
// to complete
}
@@ -1263,6 +1264,21 @@ void _process_SM10Monitor(_EMS_RxTelegram * EMS_RxTelegram) {
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
/*
* SM100Monitor - type 0x0262 EMS+
*/
void _process_SM100Monitor(_EMS_RxTelegram * EMS_RxTelegram) {
// to be completed
// need help to decyper telegram, e.g. 30 00 FF 00 02 62 00 A1 01 3F 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00
//EMS_Other.SMcollectorTemp = _toShort(2); // collector temp from SM10/SM100, is *10
//EMS_Other.SMbottomTemp = _toShort(5); // bottom temp from SM10/SM100, is *10
//EMS_Other.SMpumpModulation = _toByte(4); // modulation solar pump
//EMS_Other.SMpump = _bitRead(7, 1); // active if bit 1 is set
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
/**
* UBASetPoint 0x1A
*/
@@ -1272,7 +1288,7 @@ void _process_SetPoints(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t setpoint = EMS_RxTelegram->data[0]; // flow temp
//uint8_t ww_power = data[2]; // power in %
/* this logic if the value is *2
/* use this logic if the value is *2
char s[5];
char s2[5];
strlcpy(s, itoa(setpoint >> 1, s2, 10), 5);
@@ -1418,7 +1434,6 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
EMS_Thermostat.model_id = Thermostat_Types[i].model_id;
EMS_Thermostat.device_id = Thermostat_Types[i].device_id;
EMS_Thermostat.read_supported = Thermostat_Types[i].read_supported;
EMS_Thermostat.write_supported = Thermostat_Types[i].write_supported;
EMS_Thermostat.product_id = product_id;
strlcpy(EMS_Thermostat.version, version, sizeof(EMS_Thermostat.version));
@@ -1552,11 +1567,6 @@ void ems_getThermostatValues() {
return;
}
if (!EMS_Thermostat.read_supported) {
myDebug("Read operations not yet supported for this model thermostat");
return;
}
uint8_t model_id = EMS_Thermostat.model_id;
uint8_t type = EMS_Thermostat.device_id;
uint8_t hc = EMS_Thermostat.hc;
@@ -1746,13 +1756,12 @@ void ems_printAllDevices() {
myDebug("\nThese %d thermostat devices are supported:", _Thermostat_Types_max);
for (i = 0; i < _Thermostat_Types_max; i++) {
myDebug(" %s%s%s (DeviceID:0x%02X ProductID:%d) Read:%c Write:%c",
myDebug(" %s%s%s (DeviceID:0x%02X ProductID:%d) can write:%c",
COLOR_BOLD_ON,
Thermostat_Types[i].model_string,
COLOR_BOLD_OFF,
Thermostat_Types[i].device_id,
Thermostat_Types[i].product_id,
(Thermostat_Types[i].read_supported) ? 'y' : 'n',
(Thermostat_Types[i].write_supported) ? 'y' : 'n');
}
@@ -1778,8 +1787,8 @@ void ems_printDevices() {
(it)->version);
}
myDebug("\nNote: if any devices are marked as 'unknown?', please report this as a GitHub issue so we can update the EMS devices "
"database.\n");
myDebug("\nNote: if any devices are marked as 'unknown?' please report this as a GitHub issue so the EMS devices list can be "
"updated.\n");
}
}
@@ -2194,3 +2203,60 @@ void ems_startupTelegrams() {
snprintf(s, sizeof(s), "%02X %02X 01 00 1B", EMS_ID_ME, EMS_Boiler.device_id | 0x80);
ems_sendRawTelegram(s);
}
/*
* Test parsing of telgrams by injecting fake telegrams and simulating the response
*/
void ems_testTelegram(uint8_t test_num) {
if (test_num == 0)
return;
static const char tests[5][200] = {
"08 00 34 00 3E 02 1D 80 00 31 00 00 01 00 01 0B AE 02", // test 1
"10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00", // test 2 - RC310 ems+
"10 00 FF 19 01 A5 06 04 00 00 00 00 FF 64 37 00 3C 01 FF 01", // test 3 - RC310 ems+
"30 00 FF 00 02 62 00 A1 01 3F 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00", // test 4 - SM100
"10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00" // test 5 - RC1010
"18 00 FF 00 01 A5 00 DD 21 23 00 00 23 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00" // test 6 - RC300
};
// stop all Tx
if (!EMS_TxQueue.isEmpty()) {
EMS_TxQueue.clear();
EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE;
}
static uint8_t * telegram = (uint8_t *)malloc(EMS_MAX_TELEGRAM_LENGTH); // warning, memory is not free'd so use only for debugging
char telegram_string[200];
strlcpy(telegram_string, tests[test_num - 1], sizeof(telegram_string));
uint8_t length = 0;
char * p;
char value[10] = {0};
// get first value, which should be the src
if ((p = strtok(telegram_string, " ,"))) {
strlcpy(value, p, sizeof(value));
telegram[0] = (uint8_t)strtol(value, 0, 16);
}
// and interate until end
while (p != 0) {
if ((p = strtok(NULL, " ,"))) {
strlcpy(value, p, sizeof(value));
uint8_t val = (uint8_t)strtol(value, 0, 16);
telegram[++length] = val;
}
}
length++; // this is the total amount of bytes
telegram[length] = _crcCalculator(telegram, length + 1); // add the CRC
myDebug("[TEST %d] Injecting telegram %s (length %d)", test_num, tests[test_num - 1], length);
// go an parse it
_ems_readTelegram(telegram, length + 1); // include CRC in length
}

View File

@@ -31,8 +31,6 @@
#define EMS_VALUE_SHORT_NOTSET 0x8000 // for 2-byte shorts
#define EMS_VALUE_LONG_NOTSET 0xFFFFFF // for 3-byte longs
#define EMS_THERMOSTAT_READ_YES true
#define EMS_THERMOSTAT_READ_NO false
#define EMS_THERMOSTAT_WRITE_YES true
#define EMS_THERMOSTAT_WRITE_NO false
@@ -117,15 +115,16 @@ typedef struct {
// The Rx receive package
typedef struct {
uint32_t timestamp; // timestamp from millis()
uint8_t * telegram; // the full data package
uint8_t length; // length in bytes
uint8_t src; // source ID
uint8_t dest; // destination ID
uint16_t type; // type ID as a double byte to support EMS+
uint8_t offset; // offset
uint8_t * data; // pointer to where telegram data starts
bool emsplus; // true if ems+/ems 2.0
uint32_t timestamp; // timestamp from millis()
uint8_t * telegram; // the full data package
uint8_t length; // length in bytes of the data
uint8_t full_length; // full length of the complete telegram
uint8_t src; // source ID
uint8_t dest; // destination ID
uint16_t type; // type ID as a double byte to support EMS+
uint8_t offset; // offset
uint8_t * data; // pointer to where telegram data starts
bool emsplus; // true if ems+/ems 2.0
} _EMS_RxTelegram;
// default empty Tx
@@ -165,7 +164,6 @@ typedef struct {
uint8_t product_id;
uint8_t device_id;
char model_string[50];
bool read_supported;
bool write_supported;
} _Thermostat_Type;
@@ -253,7 +251,6 @@ typedef struct {
uint8_t device_id; // the device ID of the thermostat
uint8_t model_id; // thermostat model
uint8_t product_id;
bool read_supported;
bool write_supported;
uint8_t hc; // heating circuit 1 or 2
char version[10];
@@ -280,7 +277,7 @@ typedef void (*EMS_processType_cb)(_EMS_RxTelegram * EMS_RxTelegram);
// Definition for each EMS type, including the relative callback function
typedef struct {
uint8_t model_id;
uint16_t type; // long to support EMS+
uint16_t type; // long to support EMS+ types
const char typeString[50];
EMS_processType_cb processType_cb;
} _EMS_Type;
@@ -329,8 +326,8 @@ void ems_printDevices();
char * ems_getThermostatDescription(char * buffer);
void ems_printTxQueue();
char * ems_getBoilerDescription(char * buffer);
void ems_startupTelegrams();
void ems_testTelegram(uint8_t test_num);
void ems_startupTelegrams();
// private functions
uint8_t _crcCalculator(uint8_t * data, uint8_t len);

View File

@@ -41,7 +41,8 @@
#define EMS_OFFSET_UBASetPoints_flowtemp 0 // flow temp
// Other
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
#define EMS_TYPE_SM100Monitor 0x0262 // SM100Monitor
/*
* Thermostats...
@@ -94,11 +95,11 @@
#define EMS_OFFSET_EasyStatusMessage_setpoint 10 // setpoint temp
#define EMS_OFFSET_EasyStatusMessage_curr 8 // current temp
// RC1010 specific
#define EMS_TYPE_RC1010StatusMessage 0x01A5 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC1010Set 0x03 // setpoint temp message
#define EMS_OFFSET_RC1010StatusMessage_setpoint 3 // setpoint temp
#define EMS_OFFSET_RC1010StatusMessage_curr 1 // current temp
// RC1010,RC310 and RC300 specific (EMS Plus)
#define EMS_TYPE_RCPLUSStatusMessage 0x01A5 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RCPLUSSet 0x03 // setpoint temp message - this is incorrect!
#define EMS_OFFSET_RCPLUSStatusMessage_setpoint 2 // setpoint temp
#define EMS_OFFSET_RCPLUSStatusMessage_curr 0 // current temp
// Known EMS types
typedef enum {
@@ -168,17 +169,16 @@ const _Other_Type Other_Types[] = {
*/
const _Thermostat_Type Thermostat_Types[] = {
{EMS_MODEL_ES73, 76, 0x10, "Sieger ES73", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC10, 79, 0x17, "RC10/Nefit Moduline 100", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20, 77, 0x17, "RC20/Nefit Moduline 300", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{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_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}
{EMS_MODEL_ES73, 76, 0x10, "Sieger ES73", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC10, 79, 0x17, "RC10/Nefit Moduline 100", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20, 77, 0x17, "RC20/Nefit Moduline 300", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_EASY, 202, 0x18, "TC100/Nefit Easy", EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_BOSCHEASY, 206, 0x02, "Bosch Easy", EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_RC310, 158, 0x10, "RC300/RC310", EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010", EMS_THERMOSTAT_WRITE_NO}
};

View File

@@ -72,7 +72,7 @@ static void emsuart_rx_intr_handler(void * para) {
*/
static void ICACHE_FLASH_ATTR emsuart_recvTask(os_event_t * events) {
_EMSRxBuf * pCurrent = pEMSRxBuf;
ems_parseTelegram((uint8_t *)pCurrent->buffer, (pCurrent->writePtr) - 1); // transmit EMS buffer, excluding the BRK
ems_parseTelegram((uint8_t *)pCurrent->buffer, (pCurrent->writePtr) - 1); // transmit EMS buffer, excluding the BRK
pEMSRxBuf = paEMSRxBuf[++emsRxBufIdx % EMS_MAXBUFFERS]; // next free EMS Receive buffer
}