improvements to rendering floats

This commit is contained in:
proddy
2019-03-24 11:54:49 +01:00
parent 599171202c
commit c7c07eb1c4
6 changed files with 177 additions and 150 deletions

View File

@@ -30,7 +30,6 @@ There are 3 parts to this project, first the design of the circuit, secondly the
- [Home Assistant Configuration](#home-assistant-configuration) - [Home Assistant Configuration](#home-assistant-configuration)
- [Building The Firmware](#building-the-firmware) - [Building The Firmware](#building-the-firmware)
- [Using PlatformIO Standalone](#using-platformio-standalone) - [Using PlatformIO Standalone](#using-platformio-standalone)
- [Building Using Arduino IDE](#building-using-arduino-ide)
- [Using the Pre-built Firmware](#using-the-pre-built-firmware) - [Using the Pre-built Firmware](#using-the-pre-built-firmware)
- [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
- [Known Issues](#known-issues) - [Known Issues](#known-issues)
@@ -83,7 +82,7 @@ The code and circuit has been tested with a few ESP8266 development boards such
13. Connect the EMS lines to the ESP. This can be done via the two EMS wires or via the 3.5mm service jack if you have an bbqkees board. 13. Connect the EMS lines to the ESP. This can be done via the two EMS wires or via the 3.5mm service jack if you have an bbqkees board.
14. Reboot the ESP, either by the reset switch or pulling the power. 14. Reboot the ESP, either by the reset switch or pulling the power.
15. The ESP will first perform an autodetect to try and discover the EMS devices attached. If your boiler and thermostat are recognized it will set these types and store them for ever and ever. You can trace the output by telnet'ing to the board `telnet ems-esp.local`. Also use `info` to check the status. 15. The ESP will first perform an autodetect to try and discover the EMS devices attached. If your boiler and thermostat are recognized it will set these types and store them for ever and ever. You can trace the output by telnet'ing to the board `telnet ems-esp.local`. Also use `info` to check the status.
16. If your boiler/thermostat is not discovered create a GitHub issue stating the type and product ID. These will be added to the file `ems_devices.h` in a future release. 16. If your boiler/thermostat is not discovered create a GitHub issue stating the type and Product ID. These will be added to the file `ems_devices.h` in a future release.
17. If all is well and there is traffic on the EMS bus the onboard LED will stop blinking and be permanently on. If this is annoying you can disable with `set led off`. To see the EMS messages type `set log v` for verbose logging. 17. If all is well and there is traffic on the EMS bus the onboard LED will stop blinking and be permanently on. If this is annoying you can disable with `set led off`. To see the EMS messages type `set log v` for verbose logging.
18. And all is not well, check the wiring, make sure serial is off and look at the telnet session for errors. If in doubt, wipe the ESP with `pio run -t erase` and start again with step #3 18. And all is not well, check the wiring, make sure serial is off and look at the telnet session for errors. If in doubt, wipe the ESP with `pio run -t erase` and start again with step #3

View File

@@ -9,7 +9,7 @@
#ifndef MyEMS_h #ifndef MyEMS_h
#define MyEMS_h #define MyEMS_h
#define MYESP_VERSION "1.1.6b4" #define MYESP_VERSION "1.1.6"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>

View File

@@ -182,6 +182,7 @@ int16_t DS18::getRawValue(unsigned char index) {
} }
// return real value as a double // return real value as a double
// The raw temperature data is in units of sixteenths of a degree, so the value must be divided by 16 in order to convert it to degrees.
double DS18::getValue(unsigned char index) { double DS18::getValue(unsigned char index) {
double value = (float)getRawValue(index) / 16.0; double value = (float)getRawValue(index) / 16.0;
return value; return value;

View File

@@ -161,56 +161,42 @@ char * _bool_to_char(char * s, uint8_t value) {
// convert short (two bytes) to text value // convert short (two bytes) to text value
// negative values are assumed stored as 1-compliment (https://medium.com/@LeeJulija/how-integers-are-stored-in-memory-using-twos-complement-5ba04d61a56c) // negative values are assumed stored as 1-compliment (https://medium.com/@LeeJulija/how-integers-are-stored-in-memory-using-twos-complement-5ba04d61a56c)
char * _short_to_char(char * s, int16_t value, uint8_t div = 10) { char * _short_to_char(char * s, int16_t value, uint8_t decimals = 1) {
// remove errors on invalid values // remove errors on invalid values
if (abs(value) >= EMS_VALUE_SHORT_NOTSET) { if (abs(value) >= EMS_VALUE_SHORT_NOTSET) {
strlcpy(s, "?", sizeof(s)); strlcpy(s, "?", sizeof(s));
return (s); return (s);
} }
if (div != 0) { if (decimals == 0) {
char s2[5] = {0};
// check for negative values
if (value < 0) {
strlcpy(s, "-", 2);
strlcat(s, itoa(abs(value) / div, s2, 10), 5);
} else {
strlcpy(s, itoa(value / div, s2, 10), 5);
}
strlcat(s, ".", sizeof(s));
strlcat(s, itoa(abs(value) % div, s2, 10), 5);
} else {
itoa(value, s, 10); itoa(value, s, 10);
return (s);
} }
// floating point
char s2[5] = {0};
// check for negative values
if (value < 0) {
strlcpy(s, "-", 2);
value = abs(value);
}
strlcpy(s, itoa(value / (decimals * 10), s2, 10), 5);
strlcat(s, ".", sizeof(s));
strlcat(s, itoa(value % (decimals * 10), s2, 10), 5);
return s; return s;
} }
// convert int (single byte) to text value // takes a short value (2 bytes), converts to a fraction
char * _int_to_char(char * s, uint8_t value, uint8_t div = 0) { // most values stored a s short are either *10 or *100
if (value == EMS_VALUE_INT_NOTSET) { void _renderShortValue(const char * prefix, const char * postfix, int16_t value, uint8_t decimals = 1) {
strlcpy(s, "?", sizeof(s));
} else {
if (div != 0) {
char s2[5] = {0};
strlcpy(s, itoa(value / div, s2, 10), 5);
strlcat(s, ".", sizeof(s));
strlcat(s, itoa(value % div, s2, 10), 5);
} else {
itoa(value, s, 10);
}
}
return s;
}
// takes an int value (1 byte), converts to a fraction
void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, uint8_t div = 0) {
char buffer[200] = {0}; char buffer[200] = {0};
char s[20] = {0}; char s[20] = {0};
strlcpy(buffer, " ", sizeof(buffer)); strlcpy(buffer, " ", sizeof(buffer));
strlcat(buffer, prefix, sizeof(buffer)); strlcat(buffer, prefix, sizeof(buffer));
strlcat(buffer, ": ", sizeof(buffer)); strlcat(buffer, ": ", sizeof(buffer));
strlcat(buffer, _int_to_char(s, value, div), sizeof(buffer)); strlcat(buffer, _short_to_char(s, value, decimals), sizeof(buffer));
if (postfix != NULL) { if (postfix != NULL) {
strlcat(buffer, " ", sizeof(buffer)); strlcat(buffer, " ", sizeof(buffer));
@@ -220,15 +206,49 @@ void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, u
myDebug(buffer); myDebug(buffer);
} }
// takes a short value (2 bytes), converts to a fraction // convert int (single byte) to text value
void _renderShortValue(const char * prefix, const char * postfix, int16_t value, uint8_t div = 10) { char * _int_to_char(char * s, uint8_t value, uint8_t div = 1) {
if (value == EMS_VALUE_INT_NOTSET) {
strlcpy(s, "?", sizeof(s));
return (s);
}
char s2[5] = {0};
switch (div) {
case 1:
itoa(value, s, 10);
break;
case 2:
strlcpy(s, itoa(value >> 1, s2, 10), 5);
strlcat(s, ".", sizeof(s));
strlcat(s, ((value & 0x01) ? "5" : "0"), 5);
break;
case 10:
strlcpy(s, itoa(value / 10, s2, 10), 5);
strlcat(s, ".", sizeof(s));
strlcat(s, itoa(value % 10, s2, 10), 5);
break;
default:
itoa(value, s, 10);
break;
}
return s;
}
// takes an int value (1 byte), converts to a fraction
void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, uint8_t div = 1) {
char buffer[200] = {0}; char buffer[200] = {0};
char s[20] = {0}; char s[20] = {0};
strlcpy(buffer, " ", sizeof(buffer)); strlcpy(buffer, " ", sizeof(buffer));
strlcat(buffer, prefix, sizeof(buffer)); strlcat(buffer, prefix, sizeof(buffer));
strlcat(buffer, ": ", sizeof(buffer)); strlcat(buffer, ": ", sizeof(buffer));
strlcat(buffer, _short_to_char(s, value, div), sizeof(buffer)); strlcat(buffer, _int_to_char(s, value, div), sizeof(buffer));
if (postfix != NULL) { if (postfix != NULL) {
strlcat(buffer, " ", sizeof(buffer)); strlcat(buffer, " ", sizeof(buffer));
@@ -422,11 +442,16 @@ void showInfo() {
if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) { if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) {
// for easy temps are * 100 // for easy temps are * 100
// also we don't have the time or mode // also we don't have the time or mode
_renderShortValue("Setpoint room temperature", "C", EMS_Thermostat.setpoint_roomTemp, 100); _renderShortValue("Set room temperature", "C", EMS_Thermostat.setpoint_roomTemp, 10);
_renderShortValue("Current room temperature", "C", EMS_Thermostat.curr_roomTemp, 100);
} else {
_renderShortValue("Setpoint room temperature", "C", EMS_Thermostat.setpoint_roomTemp, 2);
_renderShortValue("Current room temperature", "C", EMS_Thermostat.curr_roomTemp, 10); _renderShortValue("Current room temperature", "C", EMS_Thermostat.curr_roomTemp, 10);
} else {
// because we store in 2 bytes short, when converting to a single byte we'll loose the negative value if its unset
if ((EMS_Thermostat.setpoint_roomTemp <= 0) || (EMS_Thermostat.curr_roomTemp <= 0)) {
EMS_Thermostat.setpoint_roomTemp = EMS_VALUE_INT_NOTSET;
EMS_Thermostat.curr_roomTemp = EMS_VALUE_INT_NOTSET;
}
_renderIntValue("Setpoint room temperature", "C", EMS_Thermostat.setpoint_roomTemp, 2); // convert to a single byte * 2
_renderIntValue("Current room temperature", "C", EMS_Thermostat.curr_roomTemp, 10); // is *10
myDebug(" Thermostat time is %02d:%02d:%02d %d/%d/%d", myDebug(" Thermostat time is %02d:%02d:%02d %d/%d/%d",
EMS_Thermostat.hour, EMS_Thermostat.hour,
@@ -451,12 +476,12 @@ void showInfo() {
// Dallas // Dallas
if (EMSESP_Status.dallas_sensors != 0) { if (EMSESP_Status.dallas_sensors != 0) {
char s[80] = {0}; //char s[80] = {0};
char buffer[128] = {0}; char buffer[128] = {0};
char valuestr[8] = {0}; // for formatting temp
myDebug("%sExternal temperature sensors:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); myDebug("%sExternal temperature sensors:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) { for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) {
snprintf(s, sizeof(s), "Sensor #%d %s", i + 1, ds18.getDeviceString(buffer, i)); myDebug(" Sensor #%d %s: %s C", i + 1, ds18.getDeviceString(buffer, i), _float_to_char(valuestr, ds18.getValue(i) ));
_renderShortValue(s, "C", ds18.getRawValue(i), 16); // divide by 16
} }
myDebug(""); // newline myDebug(""); // newline
} }
@@ -524,9 +549,8 @@ void publishValues(bool force) {
rootBoiler["wWComfort"] = "Intelligent"; rootBoiler["wWComfort"] = "Intelligent";
} }
rootBoiler["wWCurTmp"] = _short_to_char(s, EMS_Boiler.wWCurTmp); rootBoiler["wWCurTmp"] = _short_to_char(s, EMS_Boiler.wWCurTmp);
snprintf(s, sizeof(s), "%i.%i", EMS_Boiler.wWCurFlow / 10, EMS_Boiler.wWCurFlow % 10); rootBoiler["wWCurFlow"] = _int_to_char(s, EMS_Boiler.wWCurFlow, 10);
rootBoiler["wWCurFlow"] = s;
rootBoiler["wWHeat"] = _bool_to_char(s, EMS_Boiler.wWHeat); rootBoiler["wWHeat"] = _bool_to_char(s, EMS_Boiler.wWHeat);
rootBoiler["curFlowTemp"] = _short_to_char(s, EMS_Boiler.curFlowTemp); rootBoiler["curFlowTemp"] = _short_to_char(s, EMS_Boiler.curFlowTemp);
rootBoiler["retTemp"] = _short_to_char(s, EMS_Boiler.retTemp); rootBoiler["retTemp"] = _short_to_char(s, EMS_Boiler.retTemp);
@@ -571,7 +595,7 @@ void publishValues(bool force) {
// handle the thermostat values separately // handle the thermostat values separately
if (ems_getThermostatEnabled()) { if (ems_getThermostatEnabled()) {
// only send thermostat values if we actually have them // only send thermostat values if we actually have them
if ((EMS_Thermostat.curr_roomTemp == 0) || (EMS_Thermostat.setpoint_roomTemp == 0)) if ((EMS_Thermostat.curr_roomTemp <= 0) || (EMS_Thermostat.setpoint_roomTemp <= 0))
return; return;
// build new json object // build new json object
@@ -579,11 +603,11 @@ void publishValues(bool force) {
JsonObject rootThermostat = doc.to<JsonObject>(); JsonObject rootThermostat = doc.to<JsonObject>();
if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) { if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) {
rootThermostat[THERMOSTAT_CURRTEMP] = _short_to_char(s, EMS_Thermostat.curr_roomTemp, 100); rootThermostat[THERMOSTAT_SELTEMP] = _short_to_char(s, EMS_Thermostat.setpoint_roomTemp, 10);
rootThermostat[THERMOSTAT_SELTEMP] = _short_to_char(s, EMS_Thermostat.setpoint_roomTemp, 100);
} else {
rootThermostat[THERMOSTAT_CURRTEMP] = _short_to_char(s, EMS_Thermostat.curr_roomTemp, 10); rootThermostat[THERMOSTAT_CURRTEMP] = _short_to_char(s, EMS_Thermostat.curr_roomTemp, 10);
rootThermostat[THERMOSTAT_SELTEMP] = _short_to_char(s, EMS_Thermostat.setpoint_roomTemp, 2); } else {
rootThermostat[THERMOSTAT_SELTEMP] = _int_to_char(s, EMS_Thermostat.setpoint_roomTemp, 2);
rootThermostat[THERMOSTAT_CURRTEMP] = _int_to_char(s, EMS_Thermostat.curr_roomTemp, 10);
} }
// RC20 has different mode settings // RC20 has different mode settings
@@ -701,6 +725,61 @@ char * _readWord() {
return word; return word;
} }
// publish external dallas sensor temperature values to MQTT
void do_publishSensorValues() {
if (EMSESP_Status.dallas_sensors != 0) {
publishSensorValues();
}
}
// call PublishValues without forcing, so using CRC to see if we really need to publish
void do_publishValues() {
// don't publish if we're not connected to the EMS bus
if ((ems_getBusConnected()) && (!myESP.getUseSerial()) && myESP.isMQTTConnected()) {
publishValues(false);
}
}
// callback to light up the LED, called via Ticker every second
// fast way is to use WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + (state ? 4 : 8), (1 << EMSESP_Status.led_gpio)); // 4 is on, 8 is off
void do_ledcheck() {
if (EMSESP_Status.led) {
if (ems_getBusConnected()) {
digitalWrite(EMSESP_Status.led_gpio, (EMSESP_Status.led_gpio == LED_BUILTIN) ? LOW : HIGH); // light on. For onboard LED high=off
} else {
int state = digitalRead(EMSESP_Status.led_gpio);
digitalWrite(EMSESP_Status.led_gpio, !state);
}
}
}
// Thermostat scan
void do_scanThermostat() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebug("> Scanning thermostat message type #0x%02X...", scanThermostat_count);
ems_doReadCommand(scanThermostat_count, EMS_Thermostat.type_id);
scanThermostat_count++;
}
}
// do a system health check every now and then to see if we all connections
void do_systemCheck() {
if ((!ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebug("Error! Unable to read from EMS bus. Retrying in %d seconds...", SYSTEMCHECK_TIME);
}
}
// force calls to get data from EMS for the types that aren't sent as broadcasts
// only if we have a EMS connection
void do_regularUpdates() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebugLog("Calling scheduled data refresh from EMS devices...");
ems_getThermostatValues();
ems_getBoilerValues();
ems_getOtherValues();
}
}
// initiate a force scan by sending type read requests from 0 to FF to the thermostat // initiate a force scan by sending type read requests from 0 to FF to the thermostat
// used to analyze responses for debugging // used to analyze responses for debugging
void startThermostatScan(uint8_t start) { void startThermostatScan(uint8_t start) {
@@ -713,6 +792,27 @@ void startThermostatScan(uint8_t start) {
scanThermostat.attach(SCANTHERMOSTAT_TIME, do_scanThermostat); scanThermostat.attach(SCANTHERMOSTAT_TIME, do_scanThermostat);
} }
// turn back on the hot water for the shower
void _showerColdShotStop() {
if (EMSESP_Shower.doingColdShot) {
myDebugLog("[Shower] finished shot of cold. hot water back on");
ems_setWarmTapWaterActivated(true);
EMSESP_Shower.doingColdShot = false;
showerColdShotStopTimer.detach(); // disable the timer
}
}
// turn off hot water to send a shot of cold
void _showerColdShotStart() {
if (EMSESP_Status.shower_alert) {
myDebugLog("[Shower] doing a shot of cold water");
ems_setWarmTapWaterActivated(false);
EMSESP_Shower.doingColdShot = true;
// start the timer for n seconds which will reset the water back to hot
showerColdShotStopTimer.attach(SHOWER_COLDSHOT_DURATION, _showerColdShotStop);
}
}
// callback for loading/saving settings to the file system (SPIFFS) // callback for loading/saving settings to the file system (SPIFFS)
bool FSCallback(MYESP_FSACTION action, const JsonObject json) { bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
bool recreate_config = true; bool recreate_config = true;
@@ -1235,82 +1335,6 @@ void initEMSESP() {
EMSESP_Shower.doingColdShot = false; EMSESP_Shower.doingColdShot = false;
} }
// publish external dallas sensor temperature values to MQTT
void do_publishSensorValues() {
if (EMSESP_Status.dallas_sensors != 0) {
publishSensorValues();
}
}
// call PublishValues without forcing, so using CRC to see if we really need to publish
void do_publishValues() {
// don't publish if we're not connected to the EMS bus
if ((ems_getBusConnected()) && (!myESP.getUseSerial()) && myESP.isMQTTConnected()) {
publishValues(false);
}
}
// callback to light up the LED, called via Ticker every second
// fast way is to use WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + (state ? 4 : 8), (1 << EMSESP_Status.led_gpio)); // 4 is on, 8 is off
void do_ledcheck() {
if (EMSESP_Status.led) {
if (ems_getBusConnected()) {
digitalWrite(EMSESP_Status.led_gpio, (EMSESP_Status.led_gpio == LED_BUILTIN) ? LOW : HIGH); // light on. For onboard LED high=off
} else {
int state = digitalRead(EMSESP_Status.led_gpio);
digitalWrite(EMSESP_Status.led_gpio, !state);
}
}
}
// Thermostat scan
void do_scanThermostat() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebug("> Scanning thermostat message type #0x%02X...", scanThermostat_count);
ems_doReadCommand(scanThermostat_count, EMS_Thermostat.type_id);
scanThermostat_count++;
}
}
// do a system health check every now and then to see if we all connections
void do_systemCheck() {
if ((!ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebug("Error! Unable to read from EMS bus. Retrying in %d seconds...", SYSTEMCHECK_TIME);
}
}
// force calls to get data from EMS for the types that aren't sent as broadcasts
// only if we have a EMS connection
void do_regularUpdates() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebugLog("Calling scheduled data refresh from EMS devices...");
ems_getThermostatValues();
ems_getBoilerValues();
ems_getOtherValues();
}
}
// turn off hot water to send a shot of cold
void _showerColdShotStart() {
if (EMSESP_Status.shower_alert) {
myDebugLog("[Shower] doing a shot of cold water");
ems_setWarmTapWaterActivated(false);
EMSESP_Shower.doingColdShot = true;
// start the timer for n seconds which will reset the water back to hot
showerColdShotStopTimer.attach(SHOWER_COLDSHOT_DURATION, _showerColdShotStop);
}
}
// turn back on the hot water for the shower
void _showerColdShotStop() {
if (EMSESP_Shower.doingColdShot) {
myDebugLog("[Shower] finished shot of cold. hot water back on");
ems_setWarmTapWaterActivated(true);
EMSESP_Shower.doingColdShot = false;
showerColdShotStopTimer.detach(); // disable the timer
}
}
/* /*
* Shower Logic * Shower Logic
*/ */

View File

@@ -14,11 +14,6 @@
#include <MyESP.h> #include <MyESP.h>
#include <list> // std::list #include <list> // std::list
#define _toByte(i) (data[i])
#define _toShort(i) ((data[i] << 8) + data[i + 1])
#define _toLong(i) ((data[i] << 16) + (data[i + 1] << 8) + (data[i + 2]))
#define _bitRead(i, bit) (((data[i]) >> (bit)) & 0x01)
// myESP for logging to telnet and serial // myESP for logging to telnet and serial
#define myDebug(...) myESP.myDebug(__VA_ARGS__) #define myDebug(...) myESP.myDebug(__VA_ARGS__)
@@ -26,7 +21,15 @@ _EMS_Sys_Status EMS_Sys_Status; // EMS Status
CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer
// callbacks per type //
// process callbacks per type
//
// macros used in the _process* functions
#define _toByte(i) (data[i])
#define _toShort(i) ((data[i] << 8) + data[i + 1])
#define _toLong(i) ((data[i] << 16) + (data[i + 1] << 8) + (data[i + 2]))
#define _bitRead(i, bit) (((data[i]) >> (bit)) & 0x01)
// generic // generic
void _process_Version(uint8_t src, uint8_t * data, uint8_t length); void _process_Version(uint8_t src, uint8_t * data, uint8_t length);
@@ -1191,7 +1194,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
if (typeFound) { if (typeFound) {
// its a boiler // its a boiler
myDebug("Boiler found. Model %s with TypeID 0x%02X, Product ID %d, Version %s", myDebug("Boiler found. Model %s with TypeID 0x%02X, ProductID %d, Version %s",
Boiler_Types[i].model_string, Boiler_Types[i].model_string,
Boiler_Types[i].type_id, Boiler_Types[i].type_id,
product_id, product_id,
@@ -1200,7 +1203,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
// if its a boiler set it // if its a boiler set it
// it will take the first one found in the list // it will take the first one found in the list
if ((EMS_Boiler.type_id == EMS_ID_NONE) || (EMS_Boiler.type_id == Boiler_Types[i].type_id)) { if ((EMS_Boiler.type_id == EMS_ID_NONE) || (EMS_Boiler.type_id == Boiler_Types[i].type_id)) {
myDebug("* Setting Boiler type to Model %s, TypeID 0x%02X, Product ID %d, Version %s", myDebug("* Setting Boiler type to Model %s, TypeID 0x%02X, ProductID %d, Version %s",
Boiler_Types[i].model_string, Boiler_Types[i].model_string,
Boiler_Types[i].type_id, Boiler_Types[i].type_id,
product_id, product_id,
@@ -1230,7 +1233,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
if (typeFound) { if (typeFound) {
// its a known thermostat // its a known thermostat
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) { if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) {
myDebug("Thermostat found. Model %s with TypeID 0x%02X, Product ID %d, Version %s", myDebug("Thermostat found. Model %s with TypeID 0x%02X, ProductID %d, Version %s",
Thermostat_Types[i].model_string, Thermostat_Types[i].model_string,
Thermostat_Types[i].type_id, Thermostat_Types[i].type_id,
product_id, product_id,
@@ -1240,7 +1243,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
// if we don't have a thermostat set, use this one // if we don't have a thermostat set, use this one
if ((EMS_Thermostat.type_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE) if ((EMS_Thermostat.type_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE)
|| (EMS_Thermostat.type_id == Thermostat_Types[i].type_id)) { || (EMS_Thermostat.type_id == Thermostat_Types[i].type_id)) {
myDebug("* Setting Thermostat type to Model %s, TypeID 0x%02X, Product ID %d, Version %s", myDebug("* Setting Thermostat type to Model %s, TypeID 0x%02X, ProductID %d, Version %s",
Thermostat_Types[i].model_string, Thermostat_Types[i].model_string,
Thermostat_Types[i].type_id, Thermostat_Types[i].type_id,
product_id, product_id,
@@ -1272,7 +1275,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
} }
if (typeFound) { if (typeFound) {
myDebug("Device found. Model %s with TypeID 0x%02X, Product ID %d, Version %s", myDebug("Device found. Model %s with TypeID 0x%02X, ProductID %d, Version %s",
Other_Types[i].model_string, Other_Types[i].model_string,
Other_Types[i].type_id, Other_Types[i].type_id,
product_id, product_id,
@@ -1289,7 +1292,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
return; return;
} else { } else {
myDebug("Unrecognized device found. TypeID 0x%02X, Product ID %d, Version %s", src, product_id, version); myDebug("Unrecognized device found. TypeID 0x%02X, ProductID %d, Version %s", src, product_id, version);
} }
} }
@@ -1339,7 +1342,7 @@ void _ems_setThermostatModel(uint8_t thermostat_modelid) {
// set the thermostat // set the thermostat
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) { if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) {
myDebug("Setting Thermostat. Model %s with TypeID 0x%02X, Product ID %d", myDebug("Setting Thermostat. Model %s with TypeID 0x%02X, ProductID %d",
thermostat_type->model_string, thermostat_type->model_string,
thermostat_type->type_id, thermostat_type->type_id,
thermostat_type->product_id); thermostat_type->product_id);
@@ -1485,7 +1488,7 @@ char * ems_getThermostatDescription(char * buffer) {
strlcat(buffer, _hextoa(EMS_Thermostat.type_id, tmp), size); strlcat(buffer, _hextoa(EMS_Thermostat.type_id, tmp), size);
} }
strlcat(buffer, " (Product ID:", size); strlcat(buffer, " (ProductID:", size);
strlcat(buffer, itoa(EMS_Thermostat.product_id, tmp, 10), size); strlcat(buffer, itoa(EMS_Thermostat.product_id, tmp, 10), size);
strlcat(buffer, " Version:", size); strlcat(buffer, " Version:", size);
strlcat(buffer, EMS_Thermostat.version, size); strlcat(buffer, EMS_Thermostat.version, size);
@@ -1522,7 +1525,7 @@ char * ems_getBoilerDescription(char * buffer) {
strlcat(buffer, _hextoa(EMS_Boiler.type_id, tmp), size); strlcat(buffer, _hextoa(EMS_Boiler.type_id, tmp), size);
} }
strlcat(buffer, " (Product ID:", size); strlcat(buffer, " (ProductID:", size);
strlcat(buffer, itoa(EMS_Boiler.product_id, tmp, 10), size); strlcat(buffer, itoa(EMS_Boiler.product_id, tmp, 10), size);
strlcat(buffer, " Version:", size); strlcat(buffer, " Version:", size);
strlcat(buffer, EMS_Boiler.version, size); strlcat(buffer, EMS_Boiler.version, size);
@@ -1574,12 +1577,12 @@ void ems_printAllTypes() {
myDebug("\nThese %d boiler type devices are in the library:", _Boiler_Types_max); myDebug("\nThese %d boiler type devices are in the library:", _Boiler_Types_max);
for (i = 0; i < _Boiler_Types_max; i++) { for (i = 0; i < _Boiler_Types_max; i++) {
myDebug(" %s, type ID:0x%02X Product ID:%d", Boiler_Types[i].model_string, Boiler_Types[i].type_id, Boiler_Types[i].product_id); myDebug(" %s, type ID:0x%02X ProductID:%d", Boiler_Types[i].model_string, Boiler_Types[i].type_id, Boiler_Types[i].product_id);
} }
myDebug("\nThese %d EMS devices are in the library:", _Other_Types_max); myDebug("\nThese %d EMS devices are in the library:", _Other_Types_max);
for (i = 0; i < _Other_Types_max; i++) { for (i = 0; i < _Other_Types_max; i++) {
myDebug(" %s, type ID:0x%02X Product ID:%d", Other_Types[i].model_string, Other_Types[i].type_id, Other_Types[i].product_id); myDebug(" %s, type ID:0x%02X ProductID:%d", Other_Types[i].model_string, Other_Types[i].type_id, Other_Types[i].product_id);
} }
myDebug("\nThese telegram type IDs are recognized for the selected boiler:"); myDebug("\nThese telegram type IDs are recognized for the selected boiler:");
@@ -1591,7 +1594,7 @@ void ems_printAllTypes() {
myDebug("\nThese %d thermostats models are supported:", _Thermostat_Types_max); myDebug("\nThese %d thermostats models are supported:", _Thermostat_Types_max);
for (i = 0; i < _Thermostat_Types_max; i++) { for (i = 0; i < _Thermostat_Types_max; i++) {
myDebug(" %s, type ID:0x%02X Product ID:%d Read/Write support:%c%c", myDebug(" %s, type ID:0x%02X ProductID:%d Read/Write support:%c%c",
Thermostat_Types[i].model_string, Thermostat_Types[i].model_string,
Thermostat_Types[i].type_id, Thermostat_Types[i].type_id,
Thermostat_Types[i].product_id, Thermostat_Types[i].product_id,
@@ -1940,7 +1943,7 @@ void ems_setWarmTapWaterActivated(bool activated) {
} }
/* /*
* Start up sequence for UBA Master * Start up sequence for UBA Master, hopefully to initialize a handshake
* Still experimental * Still experimental
*/ */
void ems_startupTelegrams() { void ems_startupTelegrams() {

View File

@@ -6,5 +6,5 @@
#pragma once #pragma once
#define APP_NAME "EMS-ESP" #define APP_NAME "EMS-ESP"
#define APP_VERSION "1.6.0b5" #define APP_VERSION "1.6.0b6"
#define APP_HOSTNAME "ems-esp" #define APP_HOSTNAME "ems-esp"