mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 16:59:50 +03:00
mem optimizatons
This commit is contained in:
14
CHANGELOG.md
14
CHANGELOG.md
@@ -5,15 +5,17 @@ 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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [1.6.0 dev] 2019-03-19
|
## [1.6.0 dev] 2019-03-20
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- system command to show ESP stats
|
- system command to show ESP8266 stats
|
||||||
- crash command to see stack of last system crash, with .py files to track stack dump
|
- crash command to see stack of last system crash, with .py files to track stack dump (compile with -DCRASH)
|
||||||
- publish dallas external temp sensors to MQTT (Thanks @JewelZB)
|
- publish dallas external temp sensors to MQTT (thanks @JewelZB)
|
||||||
- shower timer and shower alert options available via set commands
|
- shower timer and shower alert options available via set commands
|
||||||
- Added support for warm water modes Hot, Comfort and Intelligent (https://github.com/proddy/EMS-ESP/issues/67)
|
- added support for warm water modes Hot, Comfort and Intelligent (https://github.com/proddy/EMS-ESP/issues/67)
|
||||||
|
- added 'set publish_time' to set how often to publish MQTT
|
||||||
|
- support for SM10 Solar Module
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -25,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- included various fixes and suggestions from @nomis
|
- included various fixes and suggestions from @nomis
|
||||||
- upgraded MyESP library
|
- upgraded MyESP library with many optimizations
|
||||||
- test_mode renamed to silent_mode
|
- test_mode renamed to silent_mode
|
||||||
- 'set wifi' replaced with 'set wifi_ssid and set wifi_password' to allow values with spaces
|
- 'set wifi' replaced with 'set wifi_ssid and set wifi_password' to allow values with spaces
|
||||||
|
|
||||||
|
|||||||
@@ -766,6 +766,7 @@ String MyESP::_getESPhostname() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns build time as a String - copied for espurna. see (c)
|
// returns build time as a String - copied for espurna. see (c)
|
||||||
|
// takes the time from the gcc during compilation
|
||||||
String MyESP::_buildTime() {
|
String MyESP::_buildTime() {
|
||||||
const char time_now[] = __TIME__; // hh:mm:ss
|
const char time_now[] = __TIME__; // hh:mm:ss
|
||||||
unsigned int hour = atoi(&time_now[0]);
|
unsigned int hour = atoi(&time_now[0]);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ platform = ${common.platform_def}
|
|||||||
flash_mode = dout
|
flash_mode = dout
|
||||||
|
|
||||||
; for production
|
; for production
|
||||||
build_flags = -Os -w
|
build_flags = -g -w
|
||||||
|
|
||||||
; for debug
|
; for debug
|
||||||
; build_flags = -g -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DCRASH
|
; build_flags = -g -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DCRASH
|
||||||
|
|||||||
@@ -110,10 +110,7 @@ command_t PROGMEM project_cmds[] = {
|
|||||||
{false, "boiler read <type ID>", "send read request to boiler"},
|
{false, "boiler read <type ID>", "send read request to boiler"},
|
||||||
{false, "boiler wwtemp <degrees>", "set boiler warm water temperature"},
|
{false, "boiler wwtemp <degrees>", "set boiler warm water temperature"},
|
||||||
{false, "boiler tapwater <on | off>", "set boiler warm tap water on/off"},
|
{false, "boiler tapwater <on | off>", "set boiler warm tap water on/off"},
|
||||||
{false, "boiler comfort <hot | eco | intelligent>", "set boiler warm water comfort setting"},
|
{false, "boiler comfort <hot | eco | intelligent>", "set boiler warm water comfort setting"}};
|
||||||
{false, "startup", "send startup sequence to bus master - still experimental"}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// store for overall system status
|
// store for overall system status
|
||||||
_EMSESP_Status EMSESP_Status;
|
_EMSESP_Status EMSESP_Status;
|
||||||
|
|||||||
213
src/ems.cpp
213
src/ems.cpp
@@ -24,40 +24,40 @@ CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO
|
|||||||
// callbacks per type
|
// callbacks per type
|
||||||
|
|
||||||
// generic
|
// generic
|
||||||
void _process_Version(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_Version(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// Boiler and Buderus devices
|
// Boiler and Buderus devices
|
||||||
void _process_UBAMonitorFast(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBAMonitorFast(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_UBAMonitorSlow(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBAMonitorSlow(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_UBAMonitorWWMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBAMonitorWWMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_UBAParameterWW(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBAParameterWW(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_UBATotalUptimeMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBATotalUptimeMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_UBAParametersMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_UBAParametersMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_SetPoints(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_SetPoints(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_SM10Monitor(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_SM10Monitor(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// Common for most thermostats
|
// Common for most thermostats
|
||||||
void _process_RCTime(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RCTime(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_RCOutdoorTempMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RCOutdoorTempMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// RC10
|
// RC10
|
||||||
void _process_RC10Set(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC10Set(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_RC10StatusMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC10StatusMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// RC20
|
// RC20
|
||||||
void _process_RC20Set(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC20Set(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_RC20StatusMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC20StatusMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// RC30
|
// RC30
|
||||||
void _process_RC30Set(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC30Set(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_RC30StatusMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC30StatusMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// RC35
|
// RC35
|
||||||
void _process_RC35Set(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC35Set(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
void _process_RC35StatusMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_RC35StatusMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// Easy
|
// Easy
|
||||||
void _process_EasyStatusMessage(uint8_t type, uint8_t * data, uint8_t length);
|
void _process_EasyStatusMessage(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recognized EMS types and the functions they call to process the telegrams
|
* Recognized EMS types and the functions they call to process the telegrams
|
||||||
@@ -424,24 +424,24 @@ char * _smallitoa3(uint16_t value, char * buffer) {
|
|||||||
* debug print a telegram to telnet/serial including the CRC
|
* debug print a telegram to telnet/serial including the CRC
|
||||||
* len is length in bytes including the CRC
|
* len is length in bytes including the CRC
|
||||||
*/
|
*/
|
||||||
void _debugPrintTelegram(const char * prefix, _EMS_RxTelegram EMS_RxTelegram, const char * color) {
|
void _debugPrintTelegram(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram, const char * color) {
|
||||||
if (EMS_Sys_Status.emsLogging <= EMS_SYS_LOGGING_BASIC)
|
if (EMS_Sys_Status.emsLogging <= EMS_SYS_LOGGING_BASIC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char output_str[200] = {0};
|
char output_str[200] = {0};
|
||||||
char buffer[16] = {0};
|
char buffer[16] = {0};
|
||||||
uint8_t len = EMS_RxTelegram.length;
|
uint8_t len = EMS_RxTelegram->length;
|
||||||
uint8_t * data = EMS_RxTelegram.telegram;
|
uint8_t * data = EMS_RxTelegram->telegram;
|
||||||
|
|
||||||
strlcpy(output_str, "(", sizeof(output_str));
|
strlcpy(output_str, "(", sizeof(output_str));
|
||||||
strlcat(output_str, COLOR_CYAN, sizeof(output_str));
|
strlcat(output_str, COLOR_CYAN, sizeof(output_str));
|
||||||
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram.timestamp / 3600000) % 24), buffer), sizeof(output_str));
|
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram->timestamp / 3600000) % 24), buffer), sizeof(output_str));
|
||||||
strlcat(output_str, ":", sizeof(output_str));
|
strlcat(output_str, ":", sizeof(output_str));
|
||||||
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram.timestamp / 60000) % 60), buffer), sizeof(output_str));
|
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram->timestamp / 60000) % 60), buffer), sizeof(output_str));
|
||||||
strlcat(output_str, ":", sizeof(output_str));
|
strlcat(output_str, ":", sizeof(output_str));
|
||||||
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram.timestamp / 1000) % 60), buffer), sizeof(output_str));
|
strlcat(output_str, _smallitoa((uint8_t)((EMS_RxTelegram->timestamp / 1000) % 60), buffer), sizeof(output_str));
|
||||||
strlcat(output_str, ".", sizeof(output_str));
|
strlcat(output_str, ".", sizeof(output_str));
|
||||||
strlcat(output_str, _smallitoa3(EMS_RxTelegram.timestamp % 1000, buffer), sizeof(output_str));
|
strlcat(output_str, _smallitoa3(EMS_RxTelegram->timestamp % 1000, buffer), sizeof(output_str));
|
||||||
strlcat(output_str, COLOR_RESET, sizeof(output_str));
|
strlcat(output_str, COLOR_RESET, sizeof(output_str));
|
||||||
strlcat(output_str, ") ", sizeof(output_str));
|
strlcat(output_str, ") ", sizeof(output_str));
|
||||||
|
|
||||||
@@ -483,6 +483,13 @@ void _ems_sendTelegram() {
|
|||||||
// we don't remove from the queue yet
|
// we don't remove from the queue yet
|
||||||
_EMS_TxTelegram EMS_TxTelegram = EMS_TxQueue.first();
|
_EMS_TxTelegram EMS_TxTelegram = EMS_TxQueue.first();
|
||||||
|
|
||||||
|
// if there is no destination, also delete it from the queue
|
||||||
|
if (EMS_TxTelegram.dest == EMS_ID_NONE) {
|
||||||
|
EMS_TxQueue.shift(); // remove from queue
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if we're in raw mode just fire and forget
|
// if we're in raw mode just fire and forget
|
||||||
if (EMS_TxTelegram.action == EMS_TX_TELEGRAM_RAW) {
|
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
|
EMS_TxTelegram.data[EMS_TxTelegram.length - 1] = _crcCalculator(EMS_TxTelegram.data, EMS_TxTelegram.length); // add the CRC
|
||||||
@@ -490,18 +497,12 @@ void _ems_sendTelegram() {
|
|||||||
EMS_RxTelegram.length = EMS_TxTelegram.length;
|
EMS_RxTelegram.length = EMS_TxTelegram.length;
|
||||||
EMS_RxTelegram.telegram = EMS_TxTelegram.data;
|
EMS_RxTelegram.telegram = EMS_TxTelegram.data;
|
||||||
EMS_RxTelegram.timestamp = millis(); // now
|
EMS_RxTelegram.timestamp = millis(); // now
|
||||||
_debugPrintTelegram("Sending raw", EMS_RxTelegram, COLOR_CYAN); // always show
|
_debugPrintTelegram("Sending raw", &EMS_RxTelegram, COLOR_CYAN); // always show
|
||||||
emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); // send the telegram to the UART Tx
|
emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); // send the telegram to the UART Tx
|
||||||
EMS_TxQueue.shift(); // remove from queue
|
EMS_TxQueue.shift(); // remove from queue
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is no destination, also delete it from the queue
|
|
||||||
if (EMS_TxTelegram.dest == EMS_ID_NONE) {
|
|
||||||
EMS_TxQueue.shift(); // remove from queue
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create header
|
// create header
|
||||||
EMS_TxTelegram.data[0] = EMS_ID_ME; // src
|
EMS_TxTelegram.data[0] = EMS_ID_ME; // src
|
||||||
// dest
|
// dest
|
||||||
@@ -540,7 +541,7 @@ void _ems_sendTelegram() {
|
|||||||
EMS_RxTelegram.length = EMS_TxTelegram.length;
|
EMS_RxTelegram.length = EMS_TxTelegram.length;
|
||||||
EMS_RxTelegram.telegram = EMS_TxTelegram.data;
|
EMS_RxTelegram.telegram = EMS_TxTelegram.data;
|
||||||
EMS_RxTelegram.timestamp = millis(); // now
|
EMS_RxTelegram.timestamp = millis(); // now
|
||||||
_debugPrintTelegram(s, EMS_RxTelegram, COLOR_CYAN);
|
_debugPrintTelegram(s, &EMS_RxTelegram, COLOR_CYAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the telegram to the UART Tx
|
// send the telegram to the UART Tx
|
||||||
@@ -605,7 +606,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
// or either a return code like 0x01 or 0x04 from the last Write command
|
// or either a return code like 0x01 or 0x04 from the last Write command
|
||||||
|
|
||||||
// create the Rx package
|
// create the Rx package
|
||||||
_EMS_RxTelegram EMS_RxTelegram;
|
static _EMS_RxTelegram EMS_RxTelegram;
|
||||||
EMS_RxTelegram.length = length;
|
EMS_RxTelegram.length = length;
|
||||||
EMS_RxTelegram.telegram = telegram;
|
EMS_RxTelegram.telegram = telegram;
|
||||||
EMS_RxTelegram.timestamp = millis();
|
EMS_RxTelegram.timestamp = millis();
|
||||||
@@ -651,7 +652,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
// ignore anything that doesn't resemble a proper telegram package
|
// ignore anything that doesn't resemble a proper telegram package
|
||||||
// minimal is 5 bytes, excluding CRC at the end
|
// minimal is 5 bytes, excluding CRC at the end
|
||||||
if (length <= 4) {
|
if (length <= 4) {
|
||||||
//_debugPrintTelegram("Noisy data:", telegram, length, COLOR_RED);
|
//_debugPrintTelegram("Noisy data:", &EMS_RxTelegram COLOR_RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +662,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
if (telegram[length - 1] != crc) {
|
if (telegram[length - 1] != crc) {
|
||||||
EMS_Sys_Status.emxCrcErr++;
|
EMS_Sys_Status.emxCrcErr++;
|
||||||
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
||||||
_debugPrintTelegram("Corrupt telegram:", EMS_RxTelegram, COLOR_RED);
|
_debugPrintTelegram("Corrupt telegram:", &EMS_RxTelegram, COLOR_RED);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -684,16 +685,16 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
EMS_Sys_Status.emsBusConnected = true;
|
EMS_Sys_Status.emsBusConnected = true;
|
||||||
|
|
||||||
// now lets process it and see what to do next
|
// now lets process it and see what to do next
|
||||||
_processType(EMS_RxTelegram);
|
_processType(&EMS_RxTelegram);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* print detailed telegram
|
* print detailed telegram
|
||||||
* and then call its callback if there is one defined
|
* and then call its callback if there is one defined
|
||||||
*/
|
*/
|
||||||
void _ems_processTelegram(_EMS_RxTelegram EMS_RxTelegram) {
|
void _ems_processTelegram(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
// header
|
// header
|
||||||
uint8_t * telegram = EMS_RxTelegram.telegram;
|
uint8_t * telegram = EMS_RxTelegram->telegram;
|
||||||
uint8_t src = telegram[0] & 0x7F;
|
uint8_t src = telegram[0] & 0x7F;
|
||||||
uint8_t dest = telegram[1] & 0x7F; // remove 8th bit to handle both reads and writes
|
uint8_t dest = telegram[1] & 0x7F; // remove 8th bit to handle both reads and writes
|
||||||
uint8_t type = telegram[2];
|
uint8_t type = telegram[2];
|
||||||
@@ -785,7 +786,7 @@ void _ems_processTelegram(_EMS_RxTelegram EMS_RxTelegram) {
|
|||||||
// call callback function to process it
|
// call callback function to process it
|
||||||
// as we only handle complete telegrams (not partial) check that the offset is 0
|
// as we only handle complete telegrams (not partial) check that the offset is 0
|
||||||
if (offset == EMS_ID_NONE) {
|
if (offset == EMS_ID_NONE) {
|
||||||
(void)EMS_Types[i].processType_cb(src, data, EMS_RxTelegram.length - 5);
|
(void)EMS_Types[i].processType_cb(src, data, EMS_RxTelegram->length - 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -806,9 +807,8 @@ void _removeTxQueue() {
|
|||||||
* length is only data bytes, excluding the BRK
|
* length is only data bytes, excluding the BRK
|
||||||
* We only remove from the Tx queue if the read or write was successful
|
* We only remove from the Tx queue if the read or write was successful
|
||||||
*/
|
*/
|
||||||
void _processType(_EMS_RxTelegram EMS_RxTelegram) {
|
void _processType(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
uint8_t * telegram = EMS_RxTelegram.telegram;
|
uint8_t * telegram = EMS_RxTelegram->telegram;
|
||||||
uint8_t length = EMS_RxTelegram.length;
|
|
||||||
|
|
||||||
// header
|
// header
|
||||||
uint8_t src = telegram[0] & 0x7F; // removing 8th bit as we deal with both reads and writes here
|
uint8_t src = telegram[0] & 0x7F; // removing 8th bit as we deal with both reads and writes here
|
||||||
@@ -944,7 +944,7 @@ void _checkActive() {
|
|||||||
* UBAParameterWW - type 0x33 - warm water parameters
|
* UBAParameterWW - type 0x33 - warm water parameters
|
||||||
* received only after requested (not broadcasted)
|
* received only after requested (not broadcasted)
|
||||||
*/
|
*/
|
||||||
void _process_UBAParameterWW(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBAParameterWW(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.wWActivated = (data[1] == 0xFF); // 0xFF means on
|
EMS_Boiler.wWActivated = (data[1] == 0xFF); // 0xFF means on
|
||||||
EMS_Boiler.wWSelTemp = data[2];
|
EMS_Boiler.wWSelTemp = data[2];
|
||||||
EMS_Boiler.wWCircPump = (data[6] == 0xFF); // 0xFF means on
|
EMS_Boiler.wWCircPump = (data[6] == 0xFF); // 0xFF means on
|
||||||
@@ -958,7 +958,7 @@ void _process_UBAParameterWW(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* UBATotalUptimeMessage - type 0x14 - total uptime
|
* UBATotalUptimeMessage - type 0x14 - total uptime
|
||||||
* received only after requested (not broadcasted)
|
* received only after requested (not broadcasted)
|
||||||
*/
|
*/
|
||||||
void _process_UBATotalUptimeMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBATotalUptimeMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.UBAuptime = _toLong(0, data);
|
EMS_Boiler.UBAuptime = _toLong(0, data);
|
||||||
EMS_Sys_Status.emsRefreshed = true; // when we receieve this, lets force an MQTT publish
|
EMS_Sys_Status.emsRefreshed = true; // when we receieve this, lets force an MQTT publish
|
||||||
}
|
}
|
||||||
@@ -966,7 +966,7 @@ void _process_UBATotalUptimeMessage(uint8_t type, uint8_t * data, uint8_t length
|
|||||||
/*
|
/*
|
||||||
* UBAParametersMessage - type 0x16
|
* UBAParametersMessage - type 0x16
|
||||||
*/
|
*/
|
||||||
void _process_UBAParametersMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBAParametersMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.heating_temp = data[1];
|
EMS_Boiler.heating_temp = data[1];
|
||||||
EMS_Boiler.pump_mod_max = data[9];
|
EMS_Boiler.pump_mod_max = data[9];
|
||||||
EMS_Boiler.pump_mod_min = data[10];
|
EMS_Boiler.pump_mod_min = data[10];
|
||||||
@@ -976,7 +976,7 @@ void _process_UBAParametersMessage(uint8_t type, uint8_t * data, uint8_t length)
|
|||||||
* UBAMonitorWWMessage - type 0x34 - warm water monitor. 19 bytes long
|
* UBAMonitorWWMessage - type 0x34 - warm water monitor. 19 bytes long
|
||||||
* received every 10 seconds
|
* received every 10 seconds
|
||||||
*/
|
*/
|
||||||
void _process_UBAMonitorWWMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBAMonitorWWMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.wWCurTmp = _toFloat(1, data);
|
EMS_Boiler.wWCurTmp = _toFloat(1, data);
|
||||||
EMS_Boiler.wWStarts = _toLong(13, data);
|
EMS_Boiler.wWStarts = _toLong(13, data);
|
||||||
EMS_Boiler.wWWorkM = _toLong(10, data);
|
EMS_Boiler.wWWorkM = _toLong(10, data);
|
||||||
@@ -988,7 +988,7 @@ void _process_UBAMonitorWWMessage(uint8_t type, uint8_t * data, uint8_t length)
|
|||||||
* UBAMonitorFast - type 0x18 - central heating monitor part 1 (25 bytes long)
|
* UBAMonitorFast - type 0x18 - central heating monitor part 1 (25 bytes long)
|
||||||
* received every 10 seconds
|
* received every 10 seconds
|
||||||
*/
|
*/
|
||||||
void _process_UBAMonitorFast(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBAMonitorFast(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.selFlowTemp = data[0];
|
EMS_Boiler.selFlowTemp = data[0];
|
||||||
EMS_Boiler.curFlowTemp = _toFloat(1, data);
|
EMS_Boiler.curFlowTemp = _toFloat(1, data);
|
||||||
EMS_Boiler.retTemp = _toFloat(13, data);
|
EMS_Boiler.retTemp = _toFloat(13, data);
|
||||||
@@ -1028,7 +1028,7 @@ void _process_UBAMonitorFast(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* UBAMonitorSlow - type 0x19 - central heating monitor part 2 (27 bytes long)
|
* UBAMonitorSlow - type 0x19 - central heating monitor part 2 (27 bytes long)
|
||||||
* received every 60 seconds
|
* received every 60 seconds
|
||||||
*/
|
*/
|
||||||
void _process_UBAMonitorSlow(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_UBAMonitorSlow(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Boiler.extTemp = _toFloat(0, data); // 0x8000 if not available
|
EMS_Boiler.extTemp = _toFloat(0, data); // 0x8000 if not available
|
||||||
EMS_Boiler.boilTemp = _toFloat(2, data); // 0x8000 if not available
|
EMS_Boiler.boilTemp = _toFloat(2, data); // 0x8000 if not available
|
||||||
EMS_Boiler.pumpMod = data[9];
|
EMS_Boiler.pumpMod = data[9];
|
||||||
@@ -1043,7 +1043,7 @@ void _process_UBAMonitorSlow(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* For reading the temp values only
|
* For reading the temp values only
|
||||||
* received every 60 seconds
|
* received every 60 seconds
|
||||||
*/
|
*/
|
||||||
void _process_RC10StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC10StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC10StatusMessage_setpoint]) / (float)2;
|
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC10StatusMessage_setpoint]) / (float)2;
|
||||||
EMS_Thermostat.curr_roomTemp = ((float)data[EMS_TYPE_RC10StatusMessage_curr]) / (float)10;
|
EMS_Thermostat.curr_roomTemp = ((float)data[EMS_TYPE_RC10StatusMessage_curr]) / (float)10;
|
||||||
|
|
||||||
@@ -1055,7 +1055,7 @@ void _process_RC10StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* For reading the temp values only
|
* For reading the temp values only
|
||||||
* received every 60 seconds
|
* received every 60 seconds
|
||||||
*/
|
*/
|
||||||
void _process_RC20StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC20StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC20StatusMessage_setpoint]) / (float)2;
|
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC20StatusMessage_setpoint]) / (float)2;
|
||||||
EMS_Thermostat.curr_roomTemp = _toFloat(EMS_TYPE_RC20StatusMessage_curr, data);
|
EMS_Thermostat.curr_roomTemp = _toFloat(EMS_TYPE_RC20StatusMessage_curr, data);
|
||||||
|
|
||||||
@@ -1067,7 +1067,7 @@ void _process_RC20StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* For reading the temp values only
|
* For reading the temp values only
|
||||||
* received every 60 seconds
|
* received every 60 seconds
|
||||||
*/
|
*/
|
||||||
void _process_RC30StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC30StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC30StatusMessage_setpoint]) / (float)2;
|
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC30StatusMessage_setpoint]) / (float)2;
|
||||||
EMS_Thermostat.curr_roomTemp = _toFloat(EMS_TYPE_RC30StatusMessage_curr, data);
|
EMS_Thermostat.curr_roomTemp = _toFloat(EMS_TYPE_RC30StatusMessage_curr, data);
|
||||||
|
|
||||||
@@ -1079,7 +1079,7 @@ void _process_RC30StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* For reading the temp values only
|
* For reading the temp values only
|
||||||
* received every 60 seconds
|
* received every 60 seconds
|
||||||
*/
|
*/
|
||||||
void _process_RC35StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC35StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC35StatusMessage_setpoint]) / (float)2;
|
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC35StatusMessage_setpoint]) / (float)2;
|
||||||
|
|
||||||
// check if temp sensor is unavailable
|
// check if temp sensor is unavailable
|
||||||
@@ -1096,7 +1096,7 @@ void _process_RC35StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* type 0x0A - data from the Nefit Easy/TC100 thermostat (0x18) - 31 bytes long
|
* type 0x0A - data from the Nefit Easy/TC100 thermostat (0x18) - 31 bytes long
|
||||||
* The Easy has a digital precision of its floats to 2 decimal places, so values is divided by 100
|
* The Easy has a digital precision of its floats to 2 decimal places, so values is divided by 100
|
||||||
*/
|
*/
|
||||||
void _process_EasyStatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_EasyStatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.curr_roomTemp = ((float)(((data[EMS_TYPE_EasyStatusMessage_curr] << 8) + data[9]))) / 100;
|
EMS_Thermostat.curr_roomTemp = ((float)(((data[EMS_TYPE_EasyStatusMessage_curr] << 8) + data[9]))) / 100;
|
||||||
EMS_Thermostat.setpoint_roomTemp = ((float)(((data[EMS_TYPE_EasyStatusMessage_setpoint] << 8) + data[11]))) / 100;
|
EMS_Thermostat.setpoint_roomTemp = ((float)(((data[EMS_TYPE_EasyStatusMessage_setpoint] << 8) + data[11]))) / 100;
|
||||||
|
|
||||||
@@ -1107,7 +1107,7 @@ void _process_EasyStatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* type 0xB0 - for reading the mode from the RC10 thermostat (0x17)
|
* type 0xB0 - for reading the mode from the RC10 thermostat (0x17)
|
||||||
* received only after requested
|
* received only after requested
|
||||||
*/
|
*/
|
||||||
void _process_RC10Set(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC10Set(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
// mode not implemented yet
|
// mode not implemented yet
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,7 +1115,7 @@ void _process_RC10Set(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* type 0xA8 - for reading the mode from the RC20 thermostat (0x17)
|
* type 0xA8 - for reading the mode from the RC20 thermostat (0x17)
|
||||||
* received only after requested
|
* received only after requested
|
||||||
*/
|
*/
|
||||||
void _process_RC20Set(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC20Set(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.mode = data[EMS_OFFSET_RC20Set_mode];
|
EMS_Thermostat.mode = data[EMS_OFFSET_RC20Set_mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1123,7 +1123,7 @@ void _process_RC20Set(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* type 0xA7 - for reading the mode from the RC30 thermostat (0x10)
|
* type 0xA7 - for reading the mode from the RC30 thermostat (0x10)
|
||||||
* received only after requested
|
* received only after requested
|
||||||
*/
|
*/
|
||||||
void _process_RC30Set(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC30Set(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.mode = data[EMS_OFFSET_RC30Set_mode];
|
EMS_Thermostat.mode = data[EMS_OFFSET_RC30Set_mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1132,14 +1132,14 @@ void _process_RC30Set(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
* Working Mode Heating Circuit 1 (HC1)
|
* Working Mode Heating Circuit 1 (HC1)
|
||||||
* received only after requested
|
* received only after requested
|
||||||
*/
|
*/
|
||||||
void _process_RC35Set(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RC35Set(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
EMS_Thermostat.mode = data[EMS_OFFSET_RC35Set_mode];
|
EMS_Thermostat.mode = data[EMS_OFFSET_RC35Set_mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type 0xA3 - for external temp settings from the the RC* thermostats
|
* type 0xA3 - for external temp settings from the the RC* thermostats
|
||||||
*/
|
*/
|
||||||
void _process_RCOutdoorTempMessage(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_RCOutdoorTempMessage(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
// add support here if you're reading external sensors
|
// add support here if you're reading external sensors
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1147,7 +1147,7 @@ void _process_RCOutdoorTempMessage(uint8_t type, uint8_t * data, uint8_t length)
|
|||||||
* type 0x02 - get the firmware version and type of an EMS device
|
* type 0x02 - get the firmware version and type of an EMS device
|
||||||
* look up known devices via the product id and setup if not already set
|
* look up known devices via the product id and setup if not already set
|
||||||
*/
|
*/
|
||||||
void _process_Version(uint8_t type, uint8_t * data, uint8_t length) {
|
void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
// ignore short messages that we can't interpret
|
// ignore short messages that we can't interpret
|
||||||
if (length < 3) {
|
if (length < 3) {
|
||||||
return;
|
return;
|
||||||
@@ -1265,10 +1265,53 @@ void _process_Version(uint8_t type, uint8_t * data, uint8_t length) {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
myDebug("Unrecognized device found. TypeID 0x%02X, Product ID %d, Version %s", type, product_id, version);
|
myDebug("Unrecognized device found. TypeID 0x%02X, Product ID %d, Version %s", src, product_id, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SM10Monitor - type 0x97
|
||||||
|
*/
|
||||||
|
void _process_SM10Monitor(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
|
// TODO: polish off
|
||||||
|
EMS_Other.SM10collectorTemp = _toFloat(2, data); // collector temp from SM10
|
||||||
|
EMS_Other.SM10bottomTemp = _toFloat(5, data); // bottom temp from SM10
|
||||||
|
EMS_Other.SM10pumpModulation = data[4]; // modulation solar pump
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UBASetPoint 0x1A
|
||||||
|
*/
|
||||||
|
void _process_SetPoints(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
|
/*
|
||||||
|
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
||||||
|
if (length != 0) {
|
||||||
|
uint8_t setpoint = data[0];
|
||||||
|
uint8_t hk_power = data[1];
|
||||||
|
uint8_t ww_power = data[2];
|
||||||
|
myDebug(" SetPoint=%d, hk_power=%d, ww_power=%d", setpoint, hk_power, ww_power);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
||||||
|
* common for all thermostats
|
||||||
|
*/
|
||||||
|
void _process_RCTime(uint8_t src, uint8_t * data, uint8_t length) {
|
||||||
|
if ((EMS_Thermostat.model_id == EMS_MODEL_EASY) || (EMS_Thermostat.model_id == EMS_MODEL_BOSCHEASY)) {
|
||||||
|
return; // not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
EMS_Thermostat.hour = data[2];
|
||||||
|
EMS_Thermostat.minute = data[4];
|
||||||
|
EMS_Thermostat.second = data[5];
|
||||||
|
EMS_Thermostat.day = data[3];
|
||||||
|
EMS_Thermostat.month = data[1];
|
||||||
|
EMS_Thermostat.year = data[0];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out the boiler and thermostat types
|
* Figure out the boiler and thermostat types
|
||||||
*/
|
*/
|
||||||
@@ -1328,50 +1371,6 @@ void _ems_setThermostatModel(uint8_t thermostat_modelid) {
|
|||||||
EMS_Thermostat.write_supported = thermostat_type->write_supported;
|
EMS_Thermostat.write_supported = thermostat_type->write_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* SM10Monitor - type 0x97
|
|
||||||
*/
|
|
||||||
void _process_SM10Monitor(uint8_t type, uint8_t * data, uint8_t length) {
|
|
||||||
// TODO: polish off
|
|
||||||
EMS_Other.SM10collectorTemp = _toFloat(2, data); // collector temp from SM10
|
|
||||||
EMS_Other.SM10bottomTemp = _toFloat(5, data); // bottom temp from SM10
|
|
||||||
EMS_Other.SM10pumpModulation = data[4]; // modulation solar pump
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UBASetPoint 0x1A
|
|
||||||
*/
|
|
||||||
void _process_SetPoints(uint8_t type, uint8_t * data, uint8_t length) {
|
|
||||||
/*
|
|
||||||
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
|
||||||
if (length != 0) {
|
|
||||||
uint8_t setpoint = data[0];
|
|
||||||
uint8_t hk_power = data[1];
|
|
||||||
uint8_t ww_power = data[2];
|
|
||||||
myDebug(" SetPoint=%d, hk_power=%d, ww_power=%d", setpoint, hk_power, ww_power);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
|
||||||
* common for all thermostats
|
|
||||||
*/
|
|
||||||
void _process_RCTime(uint8_t type, uint8_t * data, uint8_t length) {
|
|
||||||
if ((EMS_Thermostat.model_id == EMS_MODEL_EASY) || (EMS_Thermostat.model_id == EMS_MODEL_BOSCHEASY)) {
|
|
||||||
return; // not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
EMS_Thermostat.hour = data[2];
|
|
||||||
EMS_Thermostat.minute = data[4];
|
|
||||||
EMS_Thermostat.second = data[5];
|
|
||||||
EMS_Thermostat.day = data[3];
|
|
||||||
EMS_Thermostat.month = data[1];
|
|
||||||
EMS_Thermostat.year = data[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the Tx queue - for debugging
|
* Print the Tx queue - for debugging
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ typedef struct {
|
|||||||
} _EMS_Thermostat;
|
} _EMS_Thermostat;
|
||||||
|
|
||||||
// call back function signature for processing telegram types
|
// call back function signature for processing telegram types
|
||||||
typedef void (*EMS_processType_cb)(uint8_t type, uint8_t * data, uint8_t length);
|
typedef void (*EMS_processType_cb)(uint8_t src, uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
// Definition for each EMS type, including the relative callback function
|
// Definition for each EMS type, including the relative callback function
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -308,8 +308,8 @@ void ems_startupTelegrams();
|
|||||||
|
|
||||||
// private functions
|
// private functions
|
||||||
uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
||||||
void _processType(_EMS_RxTelegram EMS_RxTelegram);
|
void _processType(_EMS_RxTelegram *EMS_RxTelegram);
|
||||||
void _debugPrintPackage(const char * prefix, _EMS_RxTelegram EMS_RxTelegram, const char * color);
|
void _debugPrintPackage(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram, const char * color);
|
||||||
void _ems_clearTxData();
|
void _ems_clearTxData();
|
||||||
int _ems_findBoilerModel(uint8_t model_id);
|
int _ems_findBoilerModel(uint8_t model_id);
|
||||||
bool _ems_setModel(uint8_t model_id);
|
bool _ems_setModel(uint8_t model_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user