ems+ merges

This commit is contained in:
proddy
2019-04-05 17:59:24 +02:00
parent 7d8d6dea24
commit d4037fdc34
8 changed files with 138 additions and 988 deletions

View File

@@ -114,7 +114,9 @@ command_t PROGMEM project_cmds[] = {
{false, "boiler read <type ID>", "send read request to boiler"},
{false, "boiler wwtemp <degrees>", "set boiler warm water temperature"},
{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"}
};
// store for overall system status
_EMSESP_Status EMSESP_Status;
@@ -313,7 +315,7 @@ void showInfo() {
myDebug(" LED is %s, Silent mode is %s", EMSESP_Status.led ? "on" : "off", EMSESP_Status.silent_mode ? "on" : "off");
if (EMSESP_Status.dallas_sensors > 0) {
myDebug(" %d external temperature sensor%s connected", EMSESP_Status.dallas_sensors, (EMSESP_Status.dallas_sensors == 1) ? "" : "s");
myDebug(" %d external temperature sensor%s found", EMSESP_Status.dallas_sensors, (EMSESP_Status.dallas_sensors == 1) ? "" : "s");
}
myDebug(" Thermostat is %s, Boiler is %s, Shower Timer is %s, Shower Alert is %s",
@@ -481,8 +483,6 @@ void showInfo() {
myDebug(" Mode is set to ?");
}
}
myDebug(""); // newline
}
// Dallas
@@ -502,6 +502,8 @@ void showInfo() {
myDebug("%sShower stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
myDebug(" Shower is %s", (EMSESP_Shower.showerOn ? "running" : "off"));
}
myDebug(""); // newline
}
// send all dallas sensor values as a JSON package to MQTT
@@ -776,7 +778,7 @@ void do_scanThermostat() {
// 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);
myDebug("Error! Unable to read the EMS bus. Retrying in %d seconds...", SYSTEMCHECK_TIME);
}
}
@@ -784,7 +786,7 @@ void do_systemCheck() {
// only if we have a EMS connection
void do_regularUpdates() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebugLog("Calling scheduled data refresh from EMS devices...");
myDebugLog("Requesting scheduled EMS device data");
ems_getThermostatValues();
ems_getBoilerValues();
ems_getOtherValues();
@@ -1210,10 +1212,6 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
myESP.mqttSubscribe(TOPIC_SHOWER_ALERT);
myESP.mqttSubscribe(TOPIC_SHOWER_COLDSHOT);
// subscribe to a start message and send the first publish
myESP.mqttSubscribe(MQTT_TOPIC_START);
myESP.mqttPublish(MQTT_TOPIC_START, MQTT_TOPIC_START_PAYLOAD);
// publish the status of the Shower parameters
myESP.mqttPublish(TOPIC_SHOWER_TIMER, EMSESP_Status.shower_timer ? "1" : "0");
myESP.mqttPublish(TOPIC_SHOWER_ALERT, EMSESP_Status.shower_alert ? "1" : "0");
@@ -1221,13 +1219,6 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
// handle incoming MQTT publish events
if (type == MQTT_MESSAGE_EVENT) {
// handle response from a start message
// for example with HA it sends the system time from the server
if (strcmp(topic, MQTT_TOPIC_START) == 0) {
myDebug("Received boottime: %s", message);
myESP.setBoottime(message);
}
// thermostat temp changes
if (strcmp(topic, TOPIC_THERMOSTAT_CMD_TEMP) == 0) {
float f = strtof((char *)message, 0);
@@ -1276,7 +1267,6 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
} else if (strcmp((char *)message, "intelligent") == 0) {
ems_setWarmWaterModeComfort(3);
}
// publishValues(true); // publish back immediately
}
// shower timer
@@ -1346,77 +1336,6 @@ void initEMSESP() {
EMSESP_Shower.doingColdShot = false;
}
<<<<<<< HEAD:src/ems-esp.ino
// 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_enabled) {
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();
}
}
// 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
}
}
=======
>>>>>>> upstream/dev:src/ems-esp.cpp
/*
* Shower Logic
*/

View File

@@ -21,23 +21,20 @@ _EMS_Sys_Status EMS_Sys_Status; // EMS Status
CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer
//
// 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)
void _printMessage(_EMS_RxTelegram * EMS_RxTelegram);
//
// process callbacks per type
//
// generic
<<<<<<< HEAD
void _process_Version(uint8_t type, uint8_t * data, uint8_t length);
void _printMessage(uint8_t * telegram, uint8_t length);
=======
void _process_Version(uint8_t src, uint8_t * data, uint8_t length);
>>>>>>> upstream/dev
// Boiler and Buderus devices
void _process_UBAMonitorFast(uint8_t src, uint8_t * data, uint8_t length);
@@ -70,18 +67,15 @@ void _process_RC35Set(uint8_t src, uint8_t * data, uint8_t length);
void _process_RC35StatusMessage(uint8_t src, uint8_t * data, uint8_t length);
// Easy
<<<<<<< HEAD
void _process_EasyStatusMessage(uint8_t type, uint8_t * data, uint8_t length);
//RC1010
void _process_RC1010StatusMessage(uint8_t type, uint8_t * data, uint8_t length);
void _process_RC1010SetMessage(uint8_t type, uint8_t * data, uint8_t length);
=======
void _process_EasyStatusMessage(uint8_t src, uint8_t * data, uint8_t length);
>>>>>>> upstream/dev
/*
* Recognized EMS types and the functions they call to process the telegrams
* Format: MODEL ID, TYPE ID, Description, function
* Format: MODEL ID, TYPE ID, Description, function, emsplus
*/
const _EMS_Type EMS_Types[] = {
@@ -136,19 +130,15 @@ const _EMS_Type EMS_Types[] = {
{EMS_MODEL_ES73, EMS_TYPE_RC35StatusMessage, "RC35StatusMessage", _process_RC35StatusMessage, false},
// Easy
<<<<<<< HEAD
{EMS_MODEL_EASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage, false},
{EMS_MODEL_BOSCHEASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage, false},
//Ems plus
//Nefit 1010
{EMS_MODEL_RC1010, EMS_TYPE_RC1010StatusMessage, "RC1010StatusMessage", _process_RC1010StatusMessage, true},
{EMS_MODEL_RC1010, EMS_TYPE_RC1010Set, "RC1010SetMessage", _process_RC1010SetMessage, true}};
=======
{EMS_MODEL_EASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage},
{EMS_MODEL_BOSCHEASY, EMS_TYPE_EasyStatusMessage, "EasyStatusMessage", _process_EasyStatusMessage},
{EMS_MODEL_RC1010, EMS_TYPE_RC1010Set, "RC1010SetMessage", _process_RC1010SetMessage, true}
};
>>>>>>> upstream/dev
// calculate sizes of arrays at compile
uint8_t _EMS_Types_max = ArraySize(EMS_Types); // number of defined types
@@ -274,12 +264,12 @@ void ems_init() {
EMS_Boiler.heatingActive = EMS_VALUE_INT_NOTSET; // Central heating is on/off
// set boiler type
EMS_Boiler.product_id = 0;
EMS_Boiler.product_id = EMS_ID_NONE;
strlcpy(EMS_Boiler.version, "?", sizeof(EMS_Boiler.version));
// set thermostat model
EMS_Thermostat.model_id = EMS_MODEL_NONE;
EMS_Thermostat.product_id = 0;
EMS_Thermostat.product_id = EMS_ID_NONE;
strlcpy(EMS_Thermostat.version, "?", sizeof(EMS_Thermostat.version));
// set other types
@@ -717,16 +707,19 @@ void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
*/
void _ems_processTelegram(_EMS_RxTelegram * EMS_RxTelegram) {
// header
<<<<<<< HEAD
uint8_t src = telegram[0] & 0x7F;
uint8_t dest = telegram[1] & 0x7F; // remove 8th bit to handle both reads and writes
uint8_t type = telegram[2];
uint8_t offset = telegram[3];
uint8_t * data = &telegram[4]; // data block starts at position 4
uint8_t * telegram = EMS_RxTelegram->telegram;
uint8_t length = EMS_RxTelegram->length;
uint8_t src = telegram[0] & 0x7F;
uint8_t type = telegram[2];
uint8_t offset = telegram[3];
uint8_t * data = &telegram[4]; // data block starts at position 4
// EMS Plus support
uint8_t ptype = telegram[3];
uint8_t poffset = telegram[4];
uint8_t * pdata = &telegram[5 + poffset]; // data block starts at position 5 plus the offset
_printMessage(telegram, length);
_printMessage(EMS_RxTelegram);
// see if we recognize the type first by scanning our known EMS types list
// trying to match the type ID
@@ -766,28 +759,27 @@ void _ems_processTelegram(_EMS_RxTelegram * EMS_RxTelegram) {
}
}
}
void _printMessage(uint8_t * telegram, uint8_t length) {
/*
* print the telegram
*/
void _printMessage(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t * telegram = EMS_RxTelegram->telegram;
bool emsp = false;
uint8_t src = telegram[0] & 0x7F;
uint8_t dest = telegram[1] & 0x7F; // remove 8th bit to handle both reads and writes
uint8_t type = telegram[2];
uint8_t offset = telegram[3];
uint8_t * data = &telegram[4]; // data block starts at position 5
if (type >= 240) {
if (type >= 0xF0) {
type = telegram[3];
offset = telegram[4];
data = &telegram[5 + offset];
emsp = true;
}
=======
uint8_t * telegram = EMS_RxTelegram->telegram;
uint8_t src = telegram[0] & 0x7F;
uint8_t dest = telegram[1] & 0x7F; // remove 8th bit to handle both reads and writes
uint8_t type = telegram[2];
uint8_t offset = telegram[3];
uint8_t * data = telegram + 4; // data block starts at position 5
>>>>>>> upstream/dev
// print detailed telegram data
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_THERMOSTAT) {
char output_str[200] = {0};
@@ -798,16 +790,10 @@ void _printMessage(uint8_t * telegram, uint8_t length) {
if (src == EMS_Boiler.type_id) {
strlcpy(output_str, "Boiler", sizeof(output_str));
} else if (src == EMS_Thermostat.type_id) {
<<<<<<< HEAD
if (emsp)
strlcpy(output_str, "Thermostat+", sizeof(output_str));
else
strlcpy(output_str, "Thermostat", sizeof(output_str));
=======
strlcpy(output_str, "Thermostat", sizeof(output_str));
} else if (src == EMS_ID_SM10) {
strlcpy(output_str, "SM10", sizeof(output_str));
>>>>>>> upstream/dev
} else {
strlcpy(output_str, "0x", sizeof(output_str));
strlcat(output_str, _hextoa(src, buffer), sizeof(output_str));
@@ -833,24 +819,19 @@ void _printMessage(uint8_t * telegram, uint8_t length) {
strlcpy(color_s, COLOR_GREEN, sizeof(color_s));
}
} else if (dest == EMS_Boiler.type_id) {
<<<<<<< HEAD
if (emsp) {
strlcat(output_str, "Boiler", sizeof(output_str));
strlcat(output_str, "Boiler+", sizeof(output_str));
strlcpy(color_s, COLOR_BRIGHT_MAGENTA, sizeof(color_s));
} else {
strlcat(output_str, "Boiler", sizeof(output_str));
strlcpy(color_s, COLOR_MAGENTA, sizeof(color_s));
}
=======
strlcat(output_str, "Boiler", sizeof(output_str));
strlcpy(color_s, COLOR_MAGENTA, sizeof(color_s));
} else if (dest == EMS_ID_SM10) {
strlcat(output_str, "SM10", sizeof(output_str));
strlcpy(color_s, COLOR_MAGENTA, sizeof(color_s));
>>>>>>> upstream/dev
} else if (dest == EMS_Thermostat.type_id) {
if (emsp) {
strlcat(output_str, "Thermostat", sizeof(output_str));
strlcat(output_str, "Thermostat+", sizeof(output_str));
strlcpy(color_s, COLOR_BRIGHT_MAGENTA, sizeof(color_s));
} else {
strlcat(output_str, "Thermostat", sizeof(output_str));
@@ -1166,8 +1147,8 @@ void _process_UBAMonitorSlow(uint8_t src, uint8_t * data, uint8_t length) {
* e.g. 17 0B 91 00 80 1E 00 CB 27 00 00 00 00 05 01 00 CB 00 (CRC=47), #data=14
*/
void _process_RC10StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_TYPE_RC10StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toByte(EMS_TYPE_RC10StatusMessage_curr); // is * 10
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC10StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toByte(EMS_OFFSET_RC10StatusMessage_curr); // is * 10
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
@@ -1178,28 +1159,19 @@ void _process_RC10StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
* received every 60 seconds
*/
void _process_RC20StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_TYPE_RC20StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toShort(EMS_TYPE_RC20StatusMessage_curr); // is * 10
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC20StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RC20StatusMessage_curr); // is * 10
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
/**
<<<<<<< HEAD
*type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long * For reading the temp values only * received every 60 seconds
* type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
* For reading the temp values only * received every 60 seconds
*/
void _process_RC30StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC30StatusMessage_setpoint]) / (float)2;
EMS_Thermostat.curr_roomTemp = _toFloat(EMS_TYPE_RC30StatusMessage_curr, data);
=======
* type 0x41 - data from the RC30 thermostat (0x10) - 14 bytes long
* For reading the temp values only
* received every 60 seconds
*/
void _process_RC30StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_TYPE_RC30StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toShort(EMS_TYPE_RC30StatusMessage_curr); // note, its 2 bytes here
>>>>>>> upstream/dev
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC30StatusMessage_setpoint); // is * 2
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RC30StatusMessage_curr); // note, its 2 bytes here
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
@@ -1210,15 +1182,15 @@ void _process_RC30StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
* received every 60 seconds
*/
void _process_RC35StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_TYPE_RC35StatusMessage_setpoint); // is * 2
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC35StatusMessage_setpoint); // is * 2
// check if temp sensor is unavailable
if ((data[0] == 0x7D) && (data[1] = 0x00)) {
EMS_Thermostat.curr_roomTemp = EMS_VALUE_SHORT_NOTSET;
} else {
EMS_Thermostat.curr_roomTemp = _toShort(EMS_TYPE_RC35StatusMessage_curr);
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RC35StatusMessage_curr);
}
EMS_Thermostat.day_mode = bitRead(data[EMS_OFFSET_RC35Get_mode_day], 1); //get day mode flag
EMS_Thermostat.day_mode = bitRead(data[EMS_OFFSET_RC35Get_mode_day], 1); // get day mode flag
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
@@ -1226,32 +1198,27 @@ void _process_RC35StatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
* 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 must be divided by 100
*/
<<<<<<< HEAD
void _process_EasyStatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
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_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
void _process_EasyStatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_EasyStatusMessage_curr); // is *100
EMS_Thermostat.setpoint_roomTemp = _toShort(EMS_OFFSET_EasyStatusMessage_setpoint); // is *100
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
/**
* type 0x00 - data from the Nefit RC1010 thermostat (0x18) - 24 bytes long
* The 1010 has a digital precision of its floats to 1 decimal places for the current temperature, so values is divided by 10
* The 1010 has a digital precision of its floats to 1 decimal places for the set temperature, so values is divided by 2
*/
void _process_RC1010StatusMessage(uint8_t type, uint8_t * data, uint8_t length) {
EMS_Thermostat.curr_roomTemp = ((float)data[EMS_TYPE_RC1010StatusMessage_curr]) / (float)10;
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC1010StatusMessage_set]) / (float)2;
=======
void _process_EasyStatusMessage(uint8_t src, uint8_t * data, uint8_t length) {
EMS_Thermostat.curr_roomTemp = _toShort(EMS_TYPE_EasyStatusMessage_curr); // is *100
EMS_Thermostat.setpoint_roomTemp = _toShort(EMS_TYPE_EasyStatusMessage_setpoint); // is *100
>>>>>>> upstream/dev
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RC1010StatusMessage_curr);
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RC1010StatusMessage_setpoint); // is * 2
}
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
}
void _process_RC1010SetMessage(uint8_t type, uint8_t * data, uint8_t length) {
EMS_Thermostat.setpoint_roomTemp = ((float)data[EMS_TYPE_RC1010Set]) / (float)2;
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
// to complete
}
/**
* type 0xB0 - for reading the mode from the RC10 thermostat (0x17)
* received only after requested
@@ -1364,16 +1331,16 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
if (typeFound) {
// its a boiler
myDebug("Boiler found. Model %s with TypeID 0x%02X, ProductID %d, Version %s",
myDebug("Boiler found. Model %s (TypeID:0x%02X ProductID:%d Version:%s)",
Boiler_Types[i].model_string,
Boiler_Types[i].type_id,
product_id,
version);
// if its a boiler set it
// if its a boiler set it, unless it already has been set by checking for a productID
// 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)) {
myDebug("* Setting Boiler type to Model %s, TypeID 0x%02X, ProductID %d, Version %s",
if (((EMS_Boiler.type_id == EMS_ID_NONE) || (EMS_Boiler.type_id == Boiler_Types[i].type_id)) && EMS_Boiler.product_id == EMS_ID_NONE) {
myDebug("* Setting Boiler to model %s (TypeID:0x%02X ProductID:%d Version:%s)",
Boiler_Types[i].model_string,
Boiler_Types[i].type_id,
product_id,
@@ -1403,7 +1370,7 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
if (typeFound) {
// its a known thermostat
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) {
myDebug("Thermostat found. Model %s with TypeID 0x%02X, ProductID %d, Version %s",
myDebug("Thermostat found. Model %s (TypeID:0x%02X ProductID:%d Version:%s)",
Thermostat_Types[i].model_string,
Thermostat_Types[i].type_id,
product_id,
@@ -1411,9 +1378,10 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
}
// 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)
|| (EMS_Thermostat.type_id == Thermostat_Types[i].type_id)) {
myDebug("* Setting Thermostat type to Model %s, TypeID 0x%02X, ProductID %d, Version %s",
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.product_id == EMS_ID_NONE) {
myDebug("* Setting Thermostat model to %s (TypeID:0x%02X ProductID:%d Version:%s)",
Thermostat_Types[i].model_string,
Thermostat_Types[i].type_id,
product_id,
@@ -1470,6 +1438,8 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
* Figure out the boiler and thermostat types
*/
void ems_discoverModels() {
myDebug("Starting auto discover of EMS devices...");
// boiler
ems_doReadCommand(EMS_TYPE_Version, EMS_Boiler.type_id); // get version details of boiler
@@ -1526,43 +1496,6 @@ void _ems_setThermostatModel(uint8_t thermostat_modelid) {
}
/**
<<<<<<< HEAD
* 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
}
if (length > 5) {
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];
}
}
/**
=======
>>>>>>> upstream/dev
* Print the Tx queue - for debugging
*/
void ems_printTxQueue() {
@@ -1570,7 +1503,7 @@ void ems_printTxQueue() {
char sType[20] = {0};
if (EMS_TxQueue.size() == 0) {
myDebug("Tx queue is empty.");
myDebug("Tx queue is empty");
return;
}
@@ -1782,17 +1715,27 @@ void ems_scanDevices() {
void ems_printAllTypes() {
uint8_t i;
myDebug("\nThese %d boiler type devices are in the library:", _Boiler_Types_max);
myDebug("\nThese %d devices are defined as boiler units:", _Boiler_Types_max);
for (i = 0; i < _Boiler_Types_max; i++) {
myDebug(" %s, type ID:0x%02X ProductID:%d", Boiler_Types[i].model_string, Boiler_Types[i].type_id, Boiler_Types[i].product_id);
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
COLOR_BOLD_ON,
Boiler_Types[i].model_string,
COLOR_BOLD_OFF,
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 devices are defined as other EMS devices:", _Other_Types_max);
for (i = 0; i < _Other_Types_max; i++) {
myDebug(" %s, type ID:0x%02X ProductID:%d", Other_Types[i].model_string, Other_Types[i].type_id, Other_Types[i].product_id);
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
COLOR_BOLD_ON,
Other_Types[i].model_string,
COLOR_BOLD_OFF,
Other_Types[i].type_id,
Other_Types[i].product_id);
}
myDebug("\nThese telegram type IDs are recognized for the selected boiler:");
myDebug("\nThe following telegram type IDs are recognized:");
for (i = 0; i < _EMS_Types_max; i++) {
if ((EMS_Types[i].model_id == EMS_MODEL_ALL) || (EMS_Types[i].model_id == EMS_MODEL_UBA)) {
myDebug(" type %02X (%s)", EMS_Types[i].type, EMS_Types[i].typeString);
@@ -1801,12 +1744,14 @@ void ems_printAllTypes() {
myDebug("\nThese %d thermostats models are supported:", _Thermostat_Types_max);
for (i = 0; i < _Thermostat_Types_max; i++) {
myDebug(" %s, type ID:0x%02X ProductID:%d Read/Write support:%c%c",
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d) Read:%c Write:%c",
COLOR_BOLD_ON,
Thermostat_Types[i].model_string,
COLOR_BOLD_OFF,
Thermostat_Types[i].type_id,
Thermostat_Types[i].product_id,
(Thermostat_Types[i].read_supported) ? 'r' : ' ',
(Thermostat_Types[i].write_supported) ? 'w' : ' ');
(Thermostat_Types[i].read_supported) ? 'y' : 'n',
(Thermostat_Types[i].write_supported) ? 'y' : 'n');
}
}
@@ -1817,15 +1762,12 @@ void ems_printAllTypes() {
void ems_doReadCommand(uint8_t type, uint8_t dest, bool forceRefresh) {
// if not a valid type of boiler is not accessible then quits
if ((type == EMS_ID_NONE) || (dest == EMS_ID_NONE)) {
<<<<<<< HEAD
=======
return;
}
// if we're preventing all outbound traffic, quit
if (EMS_Sys_Status.emsTxDisabled) {
myDebug("in Silent Mode. All Tx is disabled.");
>>>>>>> upstream/dev
return;
}

View File

@@ -51,48 +51,49 @@
#define EMS_TYPE_RCOutdoorTempMessage 0xA3 // is an automatic thermostat broadcast, outdoor external temp
// RC10 specific
#define EMS_TYPE_RC10StatusMessage 0xB1 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC10Set 0xB0 // for setting values like temp and mode
#define EMS_OFFSET_RC10Set_temp 4 // position of thermostat setpoint temperature
#define EMS_TYPE_RC10StatusMessage_setpoint 1 // setpoint temp
#define EMS_TYPE_RC10StatusMessage_curr 3 // current temp
#define EMS_TYPE_RC10StatusMessage 0xB1 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC10Set 0xB0 // for setting values like temp and mode
#define EMS_OFFSET_RC10Set_temp 4 // position of thermostat setpoint temperature
#define EMS_OFFSET_RC10StatusMessage_setpoint 1 // setpoint temp
#define EMS_OFFSET_RC10StatusMessage_curr 3 // current temp
// RC20 specific
#define EMS_TYPE_RC20StatusMessage 0x91 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC20Set 0xA8 // for setting values like temp and mode
#define EMS_OFFSET_RC20Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC20Set_temp 28 // position of thermostat setpoint temperature
#define EMS_TYPE_RC20StatusMessage_setpoint 1 // setpoint temp
#define EMS_TYPE_RC20StatusMessage_curr 2 // current temp
#define EMS_TYPE_RC20StatusMessage 0x91 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC20Set 0xA8 // for setting values like temp and mode
#define EMS_OFFSET_RC20Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC20Set_temp 28 // position of thermostat setpoint temperature
#define EMS_OFFSET_RC20StatusMessage_setpoint 1 // setpoint temp
#define EMS_OFFSET_RC20StatusMessage_curr 2 // current temp
// RC30 specific
#define EMS_TYPE_RC30StatusMessage 0x41 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC30Set 0xA7 // for setting values like temp and mode
#define EMS_OFFSET_RC30Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC30Set_temp 28 // position of thermostat setpoint temperature
#define EMS_TYPE_RC30StatusMessage_setpoint 1 // setpoint temp
#define EMS_TYPE_RC30StatusMessage_curr 2 // current temp
#define EMS_TYPE_RC30StatusMessage 0x41 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC30Set 0xA7 // for setting values like temp and mode
#define EMS_OFFSET_RC30Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC30Set_temp 28 // position of thermostat setpoint temperature
#define EMS_OFFSET_RC30StatusMessage_setpoint 1 // setpoint temp
#define EMS_OFFSET_RC30StatusMessage_curr 2 // current temp
// RC35 specific
#define EMS_TYPE_RC35StatusMessage 0x3E // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC35StatusMessage_setpoint 2 // desired temp
#define EMS_TYPE_RC35StatusMessage_curr 3 // current temp
#define EMS_TYPE_RC35Set 0x3D // for setting values like temp and mode (Working mode HC1)
#define EMS_OFFSET_RC35Set_mode 7 // position of thermostat mode
#define EMS_OFFSET_RC35Set_temp_day 2 // position of thermostat setpoint temperature for day time
#define EMS_OFFSET_RC35Set_temp_night 1 // position of thermostat setpoint temperature for night time
#define EMS_OFFSET_RC35Get_mode_day 1 // position of thermostat day mode
#define EMS_TYPE_RC35StatusMessage 0x3E // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC35Set 0x3D // for setting values like temp and mode (Working mode HC1)
#define EMS_OFFSET_RC35StatusMessage_setpoint 2 // desired temp
#define EMS_OFFSET_RC35StatusMessage_curr 3 // current temp
#define EMS_OFFSET_RC35Set_mode 7 // position of thermostat mode
#define EMS_OFFSET_RC35Set_temp_day 2 // position of thermostat setpoint temperature for day time
#define EMS_OFFSET_RC35Set_temp_night 1 // position of thermostat setpoint temperature for night time
#define EMS_OFFSET_RC35Get_mode_day 1 // position of thermostat day mode
// Easy specific
#define EMS_TYPE_EasyStatusMessage 0x0A // reading values on an Easy Thermostat
#define EMS_TYPE_EasyStatusMessage_setpoint 10 // setpoint temp
#define EMS_TYPE_EasyStatusMessage_curr 8 // current temp
#define EMS_TYPE_EasyStatusMessage 0x0A // reading values on an Easy Thermostat
#define EMS_OFFSET_EasyStatusMessage_setpoint 10 // setpoint temp
#define EMS_OFFSET_EasyStatusMessage_curr 8 // current temp
// RC1010 specific
#define EMS_TYPE_RC1010StatusMessage 0x00 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC1010StatusMessage_curr 1 // current temp
#define EMS_TYPE_RC1010StatusMessage_set 3 // setpoint temp
#define EMS_TYPE_RC1010Set 0x03 // setpoint temp message
#define EMS_TYPE_RC1010Set_set 0 // setpoint temp
#define EMS_TYPE_RC1010StatusMessage 0x00 // 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
// Known EMS types
typedef enum {
EMS_MODEL_NONE,
@@ -130,16 +131,6 @@ const _Boiler_Type Boiler_Types[] = {
{EMS_MODEL_UBA, 203, 0x08, "Buderus Logamax U122"},
{EMS_MODEL_UBA, 208, 0x08, "Buderus Logamax plus"},
{EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler/Nefit Smartline"},
<<<<<<< HEAD
{EMS_MODEL_UBA, 190, 0x09, "BC10 Base Controller"},
{EMS_MODEL_UBA, 114, 0x09, "BC10 Base Controller"},
{EMS_MODEL_UBA, 125, 0x09, "BC25 Base Controller"},
{EMS_MODEL_UBA, 68, 0x09, "RFM20 Receiver"},
{EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500"},
{EMS_MODEL_UBA, 205, 0x08, "Nefit Moduline Easy Connect"},
{EMS_MODEL_UBA, 251, 0x21, "MM10 Mixer Module"}, // warning, fake product id!
{EMS_MODEL_UBA, 250, 0x11, "WM10 Switch Module"}, // warning, fake product id!
=======
{EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500"}
};
@@ -154,9 +145,9 @@ const _Other_Type Other_Types[] = {
{EMS_MODEL_OTHER, 114, 0x09, "BC10 Base Controller"},
{EMS_MODEL_OTHER, 125, 0x09, "BC25 Base Controller"},
{EMS_MODEL_OTHER, 205, 0x02, "Nefit Moduline Easy Connect"},
{EMS_MODEL_OTHER, 73, EMS_ID_SM10, "SM10 Solar Module"}
{EMS_MODEL_OTHER, 73, EMS_ID_SM10, "SM10 Solar Module"},
{EMS_MODEL_OTHER, 171, 0x02, "EMS-OT OpenTherm converter"}
>>>>>>> upstream/dev
};
/*
@@ -174,12 +165,7 @@ const _Thermostat_Type Thermostat_Types[] = {
{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},
<<<<<<< HEAD
{EMS_MODEL_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010)", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_OT, 171, 0x02, "EMS-OT OpenTherm converter", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
=======
{EMS_MODEL_OT, 171, 0x02, "EMS-OT OpenTherm converter", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC10, 165, 0x02, "RC10/Nefit Moduline 1010", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES}
{EMS_MODEL_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}
>>>>>>> upstream/dev
};

View File

@@ -14,8 +14,6 @@
#define MQTT_BASE "home" // all MQTT topics are prefix with this string, in the format <MQTT_BASE>/<app name>/<topic>
// MQTT general settings
#define MQTT_TOPIC_START "start"
#define MQTT_TOPIC_START_PAYLOAD "start"
#define MQTT_WILL_TOPIC "status" // for last will & testament topic name
#define MQTT_WILL_ONLINE_PAYLOAD "online" // for last will & testament payload
#define MQTT_WILL_OFFLINE_PAYLOAD "offline" // for last will & testament payload
@@ -53,17 +51,10 @@
#define TOPIC_SHOWER_ALERT "shower_alert" // toggle switch for enabling the shower alarm logic
#define TOPIC_SHOWER_COLDSHOT "shower_coldshot" // used to trigger a coldshot from an MQTT command
<<<<<<< HEAD
// default values for shower logic on/off
#define BOILER_SHOWER_TIMER 0 // enable (1) to monitor shower time
#define BOILER_SHOWER_ALERT 0 // enable (1) to send alert of cold water when shower time limit has exceeded
#define SHOWER_MAX_DURATION 420000 // in ms. 7 minutes, before trigger a shot of cold water
=======
// MQTT for EXTERNAL SENSORS
#define TOPIC_EXTERNAL_SENSORS "sensors" // for sending sensor values to MQTT
#define PAYLOAD_EXTERNAL_SENSORS "temp_%d" // for formatting the payload for each external dallas sensor
>>>>>>> upstream/dev
////////////////////////////////////////////////////////////////////////////////////////////////////
// THESE DEFAULT VALUES CAN ALSO BE SET AND STORED WITHTIN THE APPLICATION (see 'set' command) //

View File

@@ -5,12 +5,6 @@
#pragma once
<<<<<<< HEAD
#define APP_NAME "EMS-HEERENVEEN-1"
#define APP_VERSION "1.5.7b"
#define APP_HOSTNAME "ems-heerenveen-1"
=======
#define APP_NAME "EMS-ESP"
#define APP_VERSION "1.6.1b1"
#define APP_VERSION "1.7.0b2"
#define APP_HOSTNAME "ems-esp"
>>>>>>> upstream/dev