mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
add hanlding for thermostat mode
This commit is contained in:
11
README.md
11
README.md
@@ -76,22 +76,23 @@ I've tested the code and circuit with a few ESP8266 development boards such as t
|
||||
|
||||
Use the telnet client to inform you of all activity and errors real-time. This is an example of the telnet output:
|
||||
|
||||

|
||||

|
||||
|
||||
If you hit 'q' and Enter, it will toggle verbose logging showing you more detailed messages. I use ANSI colors with white text for info messages, green for well formatted telegram packages (which have validated CRC checks), red for corrupt packages and yellow for send responses.
|
||||
|
||||

|
||||

|
||||
|
||||
To see the current values of the Boiler and its parameters type 's' and hit Enter. Watch out for unsuccessful telegram packets in the #CrcErrors line.
|
||||
|
||||

|
||||

|
||||
|
||||
Commands can be issued directly to the EMS bus typing in a letter followed by an optional parameter and pressing Enter. Supported commands are:
|
||||
* **r** to send a read command to all devices to fetch values. The 2nd parameter is the type. For example 'r 33' will request type UBAParameterWW and bring back the Warm Water temperatures (not the heating) from the Boiler
|
||||
* **t** set the thermostat temperature to the given value
|
||||
* **w** to adjust the temperature of the warm water from the boiler
|
||||
* **a** to turn the warm water on and off
|
||||
* **p** to toggle the Polling response on/off. It's not necessary to have Polling enabled to work
|
||||
* **p** to toggle the Polling response on/off. It's not necessary to have Polling enabled to work. I use this for debugging purposes.
|
||||
* **m** to set the thermostat mode from low, manual and clock/auto.
|
||||
* **T** to toggle thermostat reading on/off
|
||||
* **S** to toggle the Shower Timer functionality on/off
|
||||
|
||||
@@ -187,7 +188,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:
|
||||
|
||||
| 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 |undefined |undefined |undefined |undefined |undefined |undefined |undefined |undefined |
|
||||
| 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.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 86 KiB |
BIN
doc/telnet/telnet_example.PNG
Normal file
BIN
doc/telnet/telnet_example.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB |
BIN
doc/telnet/telnet_stats.PNG
Normal file
BIN
doc/telnet/telnet_stats.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 214 KiB |
BIN
doc/telnet/telnet_verbose.PNG
Normal file
BIN
doc/telnet/telnet_verbose.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
@@ -46,14 +46,15 @@ Ticker showerResetTimer;
|
||||
#define PROJECT_CMDS \
|
||||
"s=show statistics\n\r" \
|
||||
"* q=toggle Verbose telegram logging\n\r" \
|
||||
"* m=publish stats to MQTT\n\r" \
|
||||
"* p=toggle Poll response\n\r" \
|
||||
"* P=publish stats to MQTT\n\r" \
|
||||
"* p=toggle Poll response (for debugging)\n\r" \
|
||||
"* T=toggle Thermostat suport on/off\n\r" \
|
||||
"* S=toggle Shower Timer on/off\n\r" \
|
||||
"* r [n] to request for data from EMS " \
|
||||
"(33=UBAParameterWW, 18=UBAMonitorFast, 19=UBAMonitorSlow, " \
|
||||
"34=UBAMonitorWWMessage, 91=RC20StatusMessage, 6=RC20Time, 2=Version)\n\r" \
|
||||
"* r [n] to request for data from EMS, some examples:\n\r" \
|
||||
"* from Boiler: 33=UBAParameterWW, 18=UBAMonitorFast, 19=UBAMonitorSlow, 34=UBAMonitorWWMessage\n\r" \
|
||||
"* from Thermostat: 91=RC20StatusMessage, A8=RC20Temperature, 6=RC20Time, 2=Version\n\r" \
|
||||
"* t [n] set thermostat temperature to n\n\r" \
|
||||
"* m [n] set thermostat mode (0=low, 1=manual, 2=clock)\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)"
|
||||
|
||||
@@ -106,7 +107,8 @@ netInfo homeNet = {.mqttHost = MQTT_IP,
|
||||
.mqttPass = MQTT_PASS,
|
||||
.mqttPort = 1883, // this is the default, change if using another port
|
||||
.ssid = WIFI_SSID,
|
||||
.pass = WIFI_PASSWORD};
|
||||
.pass = WIFI_PASSWORD
|
||||
};
|
||||
|
||||
ESPHelper myESP(&homeNet);
|
||||
|
||||
@@ -236,6 +238,16 @@ void showInfo() {
|
||||
|
||||
myDebug(" Setpoint room temperature is %s C\n", _float_to_char(s, EMS_Thermostat.setpoint_roomTemp));
|
||||
myDebug(" Current room temperature is %s C\n", _float_to_char(s, EMS_Thermostat.curr_roomTemp));
|
||||
myDebug(" Mode is set to ");
|
||||
if (EMS_Thermostat.mode == 0) {
|
||||
myDebug("low\n");
|
||||
} else if (EMS_Thermostat.mode == 1) {
|
||||
myDebug("manual\n");
|
||||
} else if (EMS_Thermostat.mode == 2) {
|
||||
myDebug("clock/auto\n");
|
||||
} else {
|
||||
myDebug("<unknown>\n");
|
||||
}
|
||||
}
|
||||
|
||||
// show the Shower Info
|
||||
@@ -303,7 +315,7 @@ void myDebugCallback() {
|
||||
b = !ems_getPoll();
|
||||
ems_setPoll(b);
|
||||
break;
|
||||
case 'm':
|
||||
case 'P':
|
||||
publishValues();
|
||||
break;
|
||||
case 'r': // read command for Boiler or Thermostat
|
||||
@@ -312,6 +324,9 @@ void myDebugCallback() {
|
||||
case 't': // set thermostat temp
|
||||
ems_setThermostatTemp(strtof(&cmd[2], 0));
|
||||
break;
|
||||
case 'm': // set thermostat mode
|
||||
ems_setThermostatMode(cmd[2] - '0');
|
||||
break;
|
||||
case 'w': // set warm water temp
|
||||
ems_setWarmWaterTemp((uint8_t)strtol(&cmd[2], 0, 10));
|
||||
break;
|
||||
|
||||
149
src/ems.cpp
149
src/ems.cpp
@@ -37,6 +37,12 @@ _EMS_TxTelegram EMS_TxTelegram; // Empty buffer for sending telegrams
|
||||
#define EMS_TYPE_RCOutdoorTempMessage 0xa3 // we can ignore
|
||||
#define EMS_TYPE_Version 0x02 // version of the controller
|
||||
|
||||
// Offsets for specific values in a telegram, per type, used for validation
|
||||
#define EMS_OFFSET_RC20Temperature_temp 0x1C // thermostat set temp
|
||||
#define EMS_OFFSET_RC20Temperature_mode 0x17 // thermostat mode
|
||||
#define EMS_OFFSET_UBAParameterWW_wwtemp 0x02 // WW Temperature
|
||||
#define EMS_OFFSET_UBAParameterWW_wwactivated 0x01 // WW Activated
|
||||
|
||||
// and call backs
|
||||
#define MAX_TYPECALLBACK 12 // make sure it matches the #types you have
|
||||
// callbacks per type
|
||||
@@ -47,7 +53,6 @@ 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] =
|
||||
@@ -62,9 +67,8 @@ const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
||||
|
||||
{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_RC20Temperature, "RC20Temperature", 10, _process_RC20Temperature},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", 2, _process_Version}
|
||||
};
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", 27, _process_RC20Temperature},
|
||||
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", 2, _process_Version}};
|
||||
|
||||
// reserve space for the data we collect from the Boiler and Thermostat
|
||||
_EMS_Boiler EMS_Boiler;
|
||||
@@ -85,8 +89,7 @@ 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__);
|
||||
@@ -95,9 +98,10 @@ extern ESPHelper myESP; // needed for the DEBUG statements below
|
||||
const uint64_t RX_READ_TIMEOUT = 5000; // in ms. 5 seconds timeout for read replies
|
||||
const uint8_t RX_READ_TIMEOUT_COUNT = 4; // 4 retries before timeout
|
||||
|
||||
uint8_t emsLastRxCount = 0;
|
||||
uint8_t emsLastRxCount; // used for retries when sending failed
|
||||
|
||||
// init stats and counters and buffers
|
||||
// uses -1 or 255 for values that haven't been set yet
|
||||
void ems_init() {
|
||||
// overall status
|
||||
EMS_Sys_Status.emsRxPgks = 0;
|
||||
@@ -120,6 +124,7 @@ void ems_init() {
|
||||
EMS_Thermostat.day = 0;
|
||||
EMS_Thermostat.month = 0;
|
||||
EMS_Thermostat.year = 0;
|
||||
EMS_Thermostat.mode = 255; // dummy value
|
||||
|
||||
// UBAParameterWW
|
||||
EMS_Boiler.wWActivated = false; // Warm Water activated
|
||||
@@ -460,6 +465,18 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Report back true if there is a package pending a write in the queue
|
||||
*/
|
||||
bool _checkWriteQueueFull() {
|
||||
if (EMS_Sys_Status.emsTxStatus == EMS_TX_PENDING) { // send is already pending
|
||||
myDebug("Cannot write - already a telegram pending send.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // nothing queue, we can do a write command
|
||||
}
|
||||
|
||||
/*
|
||||
* UBAParameterWW - type 0x33 - warm water parameters
|
||||
*/
|
||||
@@ -544,28 +561,38 @@ bool _process_RC20StatusMessage(uint8_t * data, uint8_t length) {
|
||||
}
|
||||
|
||||
/*
|
||||
* RC20Temperature - type 0xa8 - set temp value from the RC20 thermostat (0x17)
|
||||
* Special case as we only want to store the value after a write command
|
||||
* RC20Temperature - type 0xa8 - for set temp value and mode from the RC20 thermostat (0x17)
|
||||
*/
|
||||
bool _process_RC20Temperature(uint8_t * data, uint8_t length) {
|
||||
// only interested in the single byte response we send to validate a temp change
|
||||
if (length == 6) {
|
||||
// check if this was called specifically to validate a single value
|
||||
// which is always stored in data[0] because we request only 1 byte
|
||||
if (length == EMS_MIN_TELEGRAM_LENGTH) {
|
||||
if (EMS_TxTelegram.type_validate == EMS_OFFSET_RC20Temperature_temp) {
|
||||
// validate the set temp
|
||||
EMS_Thermostat.setpoint_roomTemp = ((float)data[0]) / (float)2;
|
||||
} else if (EMS_TxTelegram.type_validate == EMS_OFFSET_RC20Temperature_mode) {
|
||||
// validate the mode
|
||||
EMS_Thermostat.mode = data[0];
|
||||
}
|
||||
|
||||
EMS_Sys_Status.emsRefreshed = true; // set the updated flag to trigger a send back to HA
|
||||
// and send the values back to HA (Home Assistant MQTT)
|
||||
EMS_Sys_Status.emsRefreshed = true;
|
||||
} else {
|
||||
// Process the whole telegram package
|
||||
EMS_Thermostat.mode = data[EMS_OFFSET_RC20Temperature_mode]; // get the mode
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version - type 0x02 - get the version of the Thermostat
|
||||
* Version - type 0x02 - get the version of the Thermostat firmware
|
||||
*/
|
||||
bool _process_Version(uint8_t * data, uint8_t length) {
|
||||
uint8_t major = data[1];
|
||||
uint8_t minor = data[2];
|
||||
|
||||
// TODO: finish this
|
||||
myDebug("Version %d.%d\n", major, minor); // TODO: finish this
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -581,7 +608,7 @@ bool _process_RC20Time(uint8_t * data, uint8_t length) {
|
||||
EMS_Thermostat.month = data[1];
|
||||
EMS_Thermostat.year = data[0];
|
||||
|
||||
// we can optional set the time based on the Thermostat's time if we want
|
||||
// we can optional set the time based on the thermostat's time if we want
|
||||
setTime(EMS_Thermostat.hour,
|
||||
EMS_Thermostat.minute,
|
||||
EMS_Thermostat.second,
|
||||
@@ -621,11 +648,8 @@ void ems_doReadCommand(uint8_t type) {
|
||||
if (type == EMS_TYPE_NONE)
|
||||
return; // not a valid type, quit
|
||||
|
||||
// check if there is already something in the queue
|
||||
if (EMS_Sys_Status.emsTxStatus == EMS_TX_PENDING) { // send is already pending
|
||||
myDebug("Cannot write - already a telegram pending send.\n");
|
||||
return;
|
||||
}
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
uint8_t dest, size;
|
||||
|
||||
@@ -655,7 +679,7 @@ void ems_doReadCommand(uint8_t type) {
|
||||
EMS_TxTelegram.action = EMS_TX_READ; // read command
|
||||
EMS_TxTelegram.dest = dest | 0x80; // set 7th bit to indicate a read
|
||||
EMS_TxTelegram.offset = 0; // 0 for all data
|
||||
EMS_TxTelegram.length = 6; // is always 6 bytes long (including CRC at end)
|
||||
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
|
||||
@@ -665,24 +689,42 @@ void ems_doReadCommand(uint8_t type) {
|
||||
* Set the temperature of the thermostat
|
||||
*/
|
||||
void ems_setThermostatTemp(float temperature) {
|
||||
// check if there is already something in the queue
|
||||
if (EMS_Sys_Status.emsTxStatus == EMS_TX_PENDING) { // send is already pending
|
||||
myDebug("Cannot write - already a telegram pending send.\n");
|
||||
return;
|
||||
}
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
char s[10];
|
||||
myDebug("Setting thermostat temperature to %s C\n", _float_to_char(s, temperature));
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE; // write command
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_ID_THERMOSTAT;
|
||||
EMS_TxTelegram.type = EMS_TYPE_RC20Temperature;
|
||||
EMS_TxTelegram.offset = 0x1C; // manual setpoint temperature
|
||||
EMS_TxTelegram.length = 6; // includes CRC
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_RC20Temperature_temp;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.checkValue = (uint8_t)((float)temperature * (float)2); // value to compare against. must be a single int
|
||||
|
||||
// post call is RC20StatusMessage to fetch temps and send to HA
|
||||
EMS_TxTelegram.type_validate = EMS_TYPE_RC20Temperature;
|
||||
// post call is back to EMS_TYPE_RC20Temperature to fetch temps and send to HA
|
||||
EMS_TxTelegram.type_validate = EMS_OFFSET_RC20Temperature_temp;
|
||||
_buildTxTelegram(EMS_TxTelegram.checkValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the thermostat working mode (0=low, 1=manual, 2=clock/auto)
|
||||
*/
|
||||
void ems_setThermostatMode(uint8_t mode) {
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
myDebug("Setting thermostat mode to %d\n", mode);
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_ID_THERMOSTAT;
|
||||
EMS_TxTelegram.type = EMS_TYPE_RC20Temperature;
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_RC20Temperature_mode;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.checkValue = mode; // value to compare against. must be a single int
|
||||
|
||||
// post call is back to EMS_TYPE_RC20Temperature to fetch temps and send to HA
|
||||
EMS_TxTelegram.type_validate = EMS_OFFSET_RC20Temperature_mode;
|
||||
_buildTxTelegram(EMS_TxTelegram.checkValue);
|
||||
}
|
||||
|
||||
@@ -690,22 +732,18 @@ void ems_setThermostatTemp(float temperature) {
|
||||
* Set the warm water temperature
|
||||
*/
|
||||
void ems_setWarmWaterTemp(uint8_t temperature) {
|
||||
// check if there is already something in the queue
|
||||
if (EMS_Sys_Status.emsTxStatus == EMS_TX_PENDING) { // send is already pending
|
||||
myDebug("Cannot write - already a telegram pending send.\n");
|
||||
return;
|
||||
}
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
myDebug("Setting boiler warm water temperature to %d C\n", temperature);
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE; // write command
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_ID_BOILER;
|
||||
EMS_TxTelegram.type = EMS_TYPE_UBAParameterWW;
|
||||
EMS_TxTelegram.offset = 0x02; // Temperature
|
||||
EMS_TxTelegram.length = 6; // includes CRC
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_UBAParameterWW_wwtemp;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.checkValue = temperature; // value to compare against. must be a single int
|
||||
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // this means don't send and we'll pick up the data from the next broadcast
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't force a send to check the value but do it during next broadcast
|
||||
|
||||
_buildTxTelegram(temperature);
|
||||
}
|
||||
@@ -715,28 +753,21 @@ void ems_setWarmWaterTemp(uint8_t temperature) {
|
||||
* true = on, false = off
|
||||
*/
|
||||
void ems_setWarmWaterActivated(bool activated) {
|
||||
// check if there is already something in the queue
|
||||
if (EMS_Sys_Status.emsTxStatus == EMS_TX_PENDING) { // send is already pending
|
||||
myDebug("Cannot write - already a telegram pending send.\n");
|
||||
return;
|
||||
}
|
||||
if (_checkWriteQueueFull())
|
||||
return; // check if there is already something in the queue
|
||||
|
||||
myDebug("Setting boiler warm water to %s\n", activated ? "on" : "off");
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE; // write command
|
||||
EMS_TxTelegram.action = EMS_TX_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_ID_BOILER;
|
||||
EMS_TxTelegram.type = EMS_TYPE_UBAParameterWW;
|
||||
EMS_TxTelegram.offset = 0x01; // WW activation
|
||||
EMS_TxTelegram.length = 6; // includes CRC
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // this means don't send and we'll pick up the data from the next broadcast
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_UBAParameterWW_wwactivated;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't force a send to check the value but do it during next broadcast
|
||||
|
||||
if (activated) {
|
||||
EMS_TxTelegram.checkValue = 0xFF; // the EMS value for on
|
||||
_buildTxTelegram(0xFF);
|
||||
} else {
|
||||
EMS_TxTelegram.checkValue = 0x00; // the EMS value for off
|
||||
_buildTxTelegram(0x00);
|
||||
}
|
||||
// 0xFF is on, 0x00 is off
|
||||
EMS_TxTelegram.checkValue = (activated ? 0xFF : 0x00);
|
||||
_buildTxTelegram(EMS_TxTelegram.checkValue);
|
||||
}
|
||||
|
||||
|
||||
@@ -747,7 +778,7 @@ void ems_setWarmWaterActivated(bool activated) {
|
||||
// function to turn a telegram int (2 bytes) to a float
|
||||
float _toFloat(uint8_t i, uint8_t * data) {
|
||||
if ((data[i] == 0x80) && (data[i + 1] == 0)) // 0x8000 is used when sensor is missing
|
||||
return (float)-1;
|
||||
return (float)-1; // return -1 to indicate that is unknown
|
||||
|
||||
return ((float)(((data[i] << 8) + data[i + 1]))) / 10;
|
||||
}
|
||||
@@ -762,7 +793,7 @@ char * _float_to_char(char * a, float f, uint8_t precision) {
|
||||
long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
||||
|
||||
char * ret = a;
|
||||
// check for 0x8000 (sensor missing)
|
||||
// check for 0x8000 (sensor missing), which has a -1 value
|
||||
if (f == -1) {
|
||||
strcpy(ret, "<n/a>");
|
||||
} else {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
// Special EMS Telegram Types
|
||||
#define EMS_TYPE_NONE 0x00 // none
|
||||
|
||||
#define EMS_MIN_TELEGRAM_LENGTH 6 // minimal length for a validation telegram, including CRC
|
||||
|
||||
#define EMS_TX_MAXBUFFERSIZE 128 // max size of the buffer. packets are 32 bits
|
||||
|
||||
/* EMS UART transfer status */
|
||||
@@ -108,8 +110,9 @@ typedef struct {
|
||||
|
||||
// RC20 data
|
||||
typedef struct {
|
||||
float setpoint_roomTemp;
|
||||
float curr_roomTemp;
|
||||
float setpoint_roomTemp; // current set temp
|
||||
float curr_roomTemp; // current room temp
|
||||
uint8_t mode; // 0=low, 1=manual, 2=clock/auto
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
@@ -135,6 +138,7 @@ extern void ems_parseTelegram(uint8_t * telegram, uint8_t len);
|
||||
void ems_init();
|
||||
void ems_doReadCommand(uint8_t type);
|
||||
void ems_setThermostatTemp(float temp);
|
||||
void ems_setThermostatMode(uint8_t mode);
|
||||
void ems_setWarmWaterTemp(uint8_t temperature);
|
||||
void ems_setWarmWaterActivated(bool activated);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user