mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
Added retrieving settings (0xA5) (validated on RC30N), and MQTT cmd to set display, building type and language.
This commit is contained in:
206
src/ems-esp.cpp
206
src/ems-esp.cpp
@@ -45,6 +45,9 @@ Ticker systemCheckTimer;
|
||||
#define REGULARUPDATES_TIME 60 // every minute a call is made to fetch data from EMS devices manually
|
||||
Ticker regularUpdatesTimer;
|
||||
|
||||
#define DAILYUPDATES_TIME 86400 // every day a call is made to fetch data from EMS devices manually
|
||||
Ticker dailyUpdatesTimer;
|
||||
|
||||
#define LEDCHECK_TIME 500 // every 1/2 second blink the heartbeat LED
|
||||
Ticker ledcheckTimer;
|
||||
|
||||
@@ -433,6 +436,58 @@ void showInfo() {
|
||||
myDebug_P(PSTR(" Thermostat time is %s"), EMS_Thermostat.datetime);
|
||||
}
|
||||
|
||||
// settings parameters
|
||||
if (EMS_Thermostat.ibaMainDisplay != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_INTTEMP) {
|
||||
myDebug_P(PSTR(" Display: internal temperature"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_INTSETPOINT) {
|
||||
myDebug_P(PSTR(" Display: internal setpoint"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_EXTTEMP) {
|
||||
myDebug_P(PSTR(" Display: external temperature"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_BURNERTEMP) {
|
||||
myDebug_P(PSTR(" Display: burner temperature"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_WWTEMP) {
|
||||
myDebug_P(PSTR(" Display: WW temperature"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_FUNCMODE) {
|
||||
myDebug_P(PSTR(" Display: functioning mode"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_TIME) {
|
||||
myDebug_P(PSTR(" Display: time"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_DATE) {
|
||||
myDebug_P(PSTR(" Display: date"));
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_SMOKETEMP) {
|
||||
myDebug_P(PSTR(" Display: smoke temperature"));
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaLanguage != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_GERMAN) {
|
||||
myDebug_P(PSTR(" Language: German"));
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_DUTCH) {
|
||||
myDebug_P(PSTR(" Language: Dutch"));
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_FRENCH) {
|
||||
myDebug_P(PSTR(" Language: French"));
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_ITALIAN) {
|
||||
myDebug_P(PSTR(" Language: Italian"));
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) {
|
||||
_renderIntValue("Offset int. temperature", "K", EMS_Thermostat.ibaCalIntTemperature, 10); // offset int. temperature sensor, by * 0.1 Kelvin
|
||||
}
|
||||
if (EMS_Thermostat.ibaMinExtTemperature != EMS_VALUE_SHORT_NOTSET) {
|
||||
_renderShortValue("Min ext. temperature", "C", EMS_Thermostat.ibaMinExtTemperature, 0); // min ext temp for heating curve, in deg.
|
||||
}
|
||||
if (EMS_Thermostat.ibaBuildingType != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_LIGHT) {
|
||||
myDebug_P(PSTR(" Building: light"));
|
||||
} else if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_MEDIUM) {
|
||||
myDebug_P(PSTR(" Building: medium"));
|
||||
} else if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_HEAVY) {
|
||||
myDebug_P(PSTR(" Building: heavy"));
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaClockOffset != EMS_VALUE_INT_NOTSET) {
|
||||
_renderIntValue("Offset clock", "s", EMS_Thermostat.ibaClockOffset); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||
}
|
||||
|
||||
uint8_t _m_setpoint, _m_curr;
|
||||
switch (model) {
|
||||
case EMS_DEVICE_FLAG_EASY:
|
||||
@@ -580,7 +635,7 @@ void scanDallas() {
|
||||
|
||||
// send all dallas sensor values as a JSON package to MQTT
|
||||
bool publishSensorValues() {
|
||||
// don't send if MQTT is connected
|
||||
// don't send if MQTT is not connected
|
||||
if (!myESP.isMQTTConnected() || (EMSESP_Settings.publish_time == -1)) {
|
||||
return false;
|
||||
}
|
||||
@@ -914,6 +969,65 @@ bool publishEMSValues_thermostat() {
|
||||
return (has_data);
|
||||
}
|
||||
|
||||
// publish Settings parameters via MQTT
|
||||
bool publishEMSValues_settings() {
|
||||
const size_t capacity = JSON_OBJECT_SIZE(5); // must recalculate if more objects added https://arduinojson.org/v6/assistant/
|
||||
DynamicJsonDocument doc(capacity);
|
||||
JsonObject rootSettings = doc.to<JsonObject>();
|
||||
|
||||
if (EMS_Thermostat.ibaMainDisplay != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_INTTEMP) {
|
||||
rootSettings["display"] = "int. temperature";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_INTSETPOINT) {
|
||||
rootSettings["display"] = "int. setpoint";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_EXTTEMP) {
|
||||
rootSettings["display"] = "ext. temperature";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_BURNERTEMP) {
|
||||
rootSettings["display"] = "burner temperature";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_WWTEMP) {
|
||||
rootSettings["display"] = "WW temperature";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_FUNCMODE) {
|
||||
rootSettings["display"] = "functioning mode";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_TIME) {
|
||||
rootSettings["display"] = "time";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_DATE) {
|
||||
rootSettings["display"] = "date";
|
||||
} else if (EMS_Thermostat.ibaMainDisplay == EMS_VALUE_IBASettings_DISPLAY_SMOKETEMP) {
|
||||
rootSettings["display"] = "smoke temperature";
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaLanguage != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_GERMAN) {
|
||||
rootSettings["language"] = "German";
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_DUTCH) {
|
||||
rootSettings["language"] = "Dutch";
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_FRENCH) {
|
||||
rootSettings["language"] = "French";
|
||||
} else if (EMS_Thermostat.ibaLanguage == EMS_VALUE_IBASettings_LANG_ITALIAN) {
|
||||
rootSettings["language"] = "Italian";
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) {
|
||||
rootSettings["CalIntTemperature"] = (float)EMS_Thermostat.ibaCalIntTemperature / 10; // offset int. temperature sensor, by * 0.1 Kelvin
|
||||
}
|
||||
if (EMS_Thermostat.ibaMinExtTemperature != EMS_VALUE_SHORT_NOTSET) {
|
||||
rootSettings["MinExtTemperature"] = EMS_Thermostat.ibaMinExtTemperature; // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
||||
}
|
||||
if (EMS_Thermostat.ibaBuildingType != EMS_VALUE_INT_NOTSET) {
|
||||
if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_LIGHT) {
|
||||
rootSettings["building"] = "light";
|
||||
} else if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_MEDIUM) {
|
||||
rootSettings["building"] = "medium";
|
||||
} else if (EMS_Thermostat.ibaBuildingType == EMS_VALUE_IBASettings_BUILDING_HEAVY) {
|
||||
rootSettings["building"] = "heavy";
|
||||
}
|
||||
}
|
||||
if (EMS_Thermostat.ibaClockOffset != EMS_VALUE_INT_NOTSET) {
|
||||
rootSettings["clockOffset"] = EMS_Thermostat.ibaClockOffset; // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||
}
|
||||
return (myESP.mqttPublish(TOPIC_SETTINGS_DATA, doc));
|
||||
}
|
||||
|
||||
// publish mixing data
|
||||
// only sending if we have an active hc
|
||||
bool publishEMSValues_mixing() {
|
||||
@@ -1059,6 +1173,7 @@ bool publishEMSValues(bool force) {
|
||||
|
||||
bool thermo = false;
|
||||
bool boiler = false;
|
||||
bool settings = false;
|
||||
bool mixing = false;
|
||||
bool solar = false;
|
||||
bool heatpump = false;
|
||||
@@ -1073,6 +1188,12 @@ bool publishEMSValues(bool force) {
|
||||
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_BOILER); // unset flag
|
||||
}
|
||||
|
||||
if (ems_getBoilerEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_SETTINGS))) {
|
||||
// never force publication of settings
|
||||
settings = publishEMSValues_settings();
|
||||
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_SETTINGS); // unset flag
|
||||
}
|
||||
|
||||
if (ems_getMixingModuleEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_MIXING) || force)) {
|
||||
mixing = publishEMSValues_mixing();
|
||||
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_MIXING); // unset flag
|
||||
@@ -1093,7 +1214,7 @@ bool publishEMSValues(bool force) {
|
||||
}
|
||||
|
||||
// print
|
||||
char log_s[50];
|
||||
char log_s[60];
|
||||
strlcpy(log_s, "Publishing MQTT data for:", sizeof(log_s));
|
||||
if (thermo) {
|
||||
strlcat(log_s, " thermostat", sizeof(log_s));
|
||||
@@ -1101,6 +1222,9 @@ bool publishEMSValues(bool force) {
|
||||
if (boiler) {
|
||||
strlcat(log_s, " boiler", sizeof(log_s));
|
||||
}
|
||||
if (settings) {
|
||||
strlcat(log_s, " settings", sizeof(log_s));
|
||||
}
|
||||
if (mixing) {
|
||||
strlcat(log_s, " mixing", sizeof(log_s));
|
||||
}
|
||||
@@ -1167,6 +1291,16 @@ void do_regularUpdates() {
|
||||
}
|
||||
}
|
||||
|
||||
// force low-frequency (daily) calls to get data from EMS for the types that aren't sent as broadcasts
|
||||
// only if we have a EMS connection
|
||||
// which will cause the values to get published
|
||||
void do_dailyUpdates() {
|
||||
if (ems_getBusConnected() && !ems_getTxDisabled()) {
|
||||
myDebugLog("Fetching settings data");
|
||||
ems_getSettingsValues();
|
||||
}
|
||||
}
|
||||
|
||||
// turn back on the hot water for the shower
|
||||
void _showerColdShotStop() {
|
||||
if (EMSESP_Shower.doingColdShot) {
|
||||
@@ -1194,6 +1328,7 @@ void runUnitTest(uint8_t test_num) {
|
||||
publishValuesTimer.detach();
|
||||
systemCheckTimer.detach();
|
||||
regularUpdatesTimer.detach();
|
||||
dailyUpdatesTimer.detach();
|
||||
// EMSESP_Settings.listen_mode = true; // temporary go into listen mode to disable Tx
|
||||
ems_testTelegram(test_num);
|
||||
}
|
||||
@@ -1527,6 +1662,7 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
||||
|
||||
if (strcmp(first_cmd, "refresh") == 0) {
|
||||
do_regularUpdates();
|
||||
do_dailyUpdates();
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -1775,12 +1911,15 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
||||
// this is used for example for comfort, flowtemp
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_CMD);
|
||||
|
||||
// these three need to be unique topics
|
||||
// these need to be unique topics
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_CMD_WWACTIVATED);
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_CMD_WWONETIME);
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_CMD_WWCIRCULATION);
|
||||
myESP.mqttSubscribe(TOPIC_BOILER_CMD_WWTEMP);
|
||||
|
||||
// generic incoming MQTT command for Settings
|
||||
myESP.mqttSubscribe(TOPIC_SETTINGS_CMD);
|
||||
|
||||
// generic incoming MQTT command for EMS-ESP
|
||||
// this is used for example for shower_coldshot
|
||||
myESP.mqttSubscribe(TOPIC_GENERIC_CMD);
|
||||
@@ -1936,6 +2075,66 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for settings commands
|
||||
if (strcmp(topic, TOPIC_SETTINGS_CMD) == 0) {
|
||||
// convert JSON and get the command
|
||||
StaticJsonDocument<100> doc;
|
||||
DeserializationError error = deserializeJson(doc, message); // Deserialize the JSON document
|
||||
if (error) {
|
||||
myDebug_P(PSTR("[MQTT] Invalid command from topic %s, payload %s, error %s"), topic, message, error.c_str());
|
||||
return;
|
||||
}
|
||||
const char * command = doc["cmd"];
|
||||
if (command == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// language setting
|
||||
if (strcmp(command, TOPIC_SETTINGS_CMD_LANGUAGE) == 0) {
|
||||
const char * data = doc["data"];
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (strcasecmp((char *)data, "french") == 0) {
|
||||
ems_setSettingsLanguage(EMS_VALUE_IBASettings_LANG_FRENCH);
|
||||
} else if (strcasecmp((char *)data, "german") == 0) {
|
||||
ems_setSettingsLanguage(EMS_VALUE_IBASettings_LANG_GERMAN);
|
||||
} else if (strcasecmp((char *)data, "italian") == 0) {
|
||||
ems_setSettingsLanguage(EMS_VALUE_IBASettings_LANG_ITALIAN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// building setting
|
||||
if (strcmp(command, TOPIC_SETTINGS_CMD_BUILDING) == 0) {
|
||||
const char * data = doc["data"];
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (strcasecmp((char *)data, "light") == 0) {
|
||||
ems_setSettingsBuilding(EMS_VALUE_IBASettings_BUILDING_LIGHT);
|
||||
} else if (strcasecmp((char *)data, "medium") == 0) {
|
||||
ems_setSettingsBuilding(EMS_VALUE_IBASettings_BUILDING_MEDIUM);
|
||||
} else if (strcasecmp((char *)data, "heavy") == 0) {
|
||||
ems_setSettingsBuilding(EMS_VALUE_IBASettings_BUILDING_HEAVY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// display setting
|
||||
if (strcmp(command, TOPIC_SETTINGS_CMD_DISPLAY) == 0) {
|
||||
const char * data = doc["data"];
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
uint8_t t = atoi((char *)data);
|
||||
if (t) {
|
||||
ems_setSettingsDisplay(t-1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return; // unknown settings command
|
||||
}
|
||||
|
||||
|
||||
uint8_t hc;
|
||||
// thermostat temp changes
|
||||
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_TEMP_HA, topic);
|
||||
@@ -2427,6 +2626,7 @@ void setup() {
|
||||
// enable regular checks to fetch data and publish using Tx (unless listen_mode is enabled)
|
||||
if (!EMSESP_Settings.listen_mode) {
|
||||
regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS
|
||||
dailyUpdatesTimer.attach(DAILYUPDATES_TIME, do_dailyUpdates); // daily reads from the EMS
|
||||
}
|
||||
|
||||
// set timers for MQTT publish
|
||||
|
||||
152
src/ems.cpp
152
src/ems.cpp
@@ -103,6 +103,13 @@ void ems_init() {
|
||||
strlcpy(EMS_Thermostat.datetime, "?", sizeof(EMS_Thermostat.datetime));
|
||||
EMS_Thermostat.write_supported = false;
|
||||
EMS_Thermostat.device_id = EMS_ID_NONE;
|
||||
// settings
|
||||
EMS_Thermostat.ibaMainDisplay = EMS_VALUE_INT_NOTSET; // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 boiler temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||
EMS_Thermostat.ibaLanguage = EMS_VALUE_INT_NOTSET; // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
||||
EMS_Thermostat.ibaCalIntTemperature = EMS_VALUE_INT_NOTSET; // offset int. temperature sensor, by * 0.1 Kelvin
|
||||
EMS_Thermostat.ibaMinExtTemperature = EMS_VALUE_SHORT_NOTSET; // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
||||
EMS_Thermostat.ibaBuildingType = EMS_VALUE_INT_NOTSET; // building type: 0 = light, 1 = medium, 2 = heavy
|
||||
EMS_Thermostat.ibaClockOffset = EMS_VALUE_INT_NOTSET; // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||
|
||||
// init all heating circuits
|
||||
for (uint8_t i = 0; i < EMS_THERMOSTAT_MAXHC; i++) {
|
||||
@@ -1286,6 +1293,33 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_EasyStatusMessage_setpoint); // is * 100
|
||||
}
|
||||
|
||||
// Settings Parameters - 0xA5
|
||||
void _process_IBASettingsMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
// thermostat compatible with this settings message, checked by in ems_getSettingsValues()
|
||||
|
||||
// at init, and every 24h, send read request for settings parameters message, done with Ticker on do_dailyUpdates()
|
||||
// send 0B 90 A5 00 20:
|
||||
// 10 0B A5 00 00 02 00 00 FF F6 01 06 00 01 0D 03 03
|
||||
// 00 01 02 03 04 05 06 07 08 09 10 11 12
|
||||
|
||||
// values validated for RC30N
|
||||
uint8_t extTemp = 100; // Min. ext temperature is coded as int8, 0xF6=-10, 0x0 = 0, 0xFF=-1. 100 is out of permissible range
|
||||
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.ibaMainDisplay, EMS_OFFSET_IBASettings_Display); // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.ibaLanguage, EMS_OFFSET_IBASettings_Language); // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.ibaBuildingType, EMS_OFFSET_IBASettings_Building); // building type: 0 = light, 1 = medium, 2 = heavy
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.ibaCalIntTemperature, EMS_OFFSET_IBASettings_CalIntTemp); // offset int. temperature sensor, by * 0.1 Kelvin
|
||||
_setValue(EMS_RxTelegram, &extTemp, EMS_OFFSET_IBASettings_MinExtTemp); // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
||||
if (extTemp != 100) {
|
||||
// code as signed short, to benefit from negative value rendering
|
||||
EMS_Thermostat.ibaMinExtTemperature = (int16_t)(extTemp > 127) ? (extTemp-256) : extTemp;
|
||||
}
|
||||
_setValue(EMS_RxTelegram, &EMS_Thermostat.ibaClockOffset, EMS_OFFSET_IBASettings_ClockOffset); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||
|
||||
// publish settings to mqtt (assuming this is a very low frequency message), done in publishEMSValues_settings()
|
||||
ems_Device_add_flags(EMS_DEVICE_UPDATE_FLAG_SETTINGS);
|
||||
}
|
||||
|
||||
// Mixing module - 0x01D7, 0x01D8
|
||||
void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_MMPLUSStatusMessage_HC1); // 0 to 3
|
||||
@@ -2075,6 +2109,24 @@ void ems_getBoilerValues() {
|
||||
ems_doReadCommand(EMS_TYPE_UBATotalUptimeMessage, EMS_Boiler.device_id); // get uptime from boiler
|
||||
}
|
||||
|
||||
void ems_getSettingsValues() {
|
||||
if (!ems_getThermostatEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t device_flags = EMS_Thermostat.device_flags;
|
||||
uint8_t device_id = EMS_Thermostat.device_id;
|
||||
|
||||
// for the moment, only validated on RC30
|
||||
switch (device_flags) {
|
||||
case EMS_DEVICE_FLAG_RC30N:
|
||||
ems_doReadCommand(EMS_TYPE_IBASettingsMessage, device_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get solar values from EMS devices
|
||||
*/
|
||||
@@ -2753,6 +2805,103 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc) {
|
||||
EMS_TxQueue.push(EMS_TxTelegram);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the language settings
|
||||
* to 0xA5
|
||||
*/
|
||||
void ems_setSettingsLanguage(uint8_t lg) {
|
||||
_EMS_TxTelegram EMS_TxTelegram = EMS_TX_TELEGRAM_NEW; // create new Tx
|
||||
EMS_TxTelegram.timestamp = millis(); // set timestamp
|
||||
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
||||
|
||||
switch(lg) {
|
||||
case EMS_VALUE_IBASettings_LANG_FRENCH:
|
||||
case EMS_VALUE_IBASettings_LANG_GERMAN:
|
||||
case EMS_VALUE_IBASettings_LANG_DUTCH:
|
||||
case EMS_VALUE_IBASettings_LANG_ITALIAN:
|
||||
myDebug_P(PSTR("Setting language to %d"),lg);
|
||||
EMS_TxTelegram.dataValue = lg;
|
||||
break;
|
||||
default:
|
||||
return; // invalid value
|
||||
}
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_Thermostat.device_id;
|
||||
EMS_TxTelegram.type = EMS_TYPE_IBASettingsMessage;
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_IBASettings_Language;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate
|
||||
|
||||
EMS_TxQueue.push(EMS_TxTelegram);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the building settings
|
||||
* to 0xA5
|
||||
*/
|
||||
void ems_setSettingsBuilding(uint8_t bg) {
|
||||
_EMS_TxTelegram EMS_TxTelegram = EMS_TX_TELEGRAM_NEW; // create new Tx
|
||||
EMS_TxTelegram.timestamp = millis(); // set timestamp
|
||||
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
||||
|
||||
switch(bg) {
|
||||
case EMS_VALUE_IBASettings_BUILDING_LIGHT:
|
||||
case EMS_VALUE_IBASettings_BUILDING_MEDIUM:
|
||||
case EMS_VALUE_IBASettings_BUILDING_HEAVY:
|
||||
myDebug_P(PSTR("Setting building to %d"),bg);
|
||||
EMS_TxTelegram.dataValue = bg;
|
||||
break;
|
||||
default:
|
||||
return; // invalid value
|
||||
}
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_Thermostat.device_id;
|
||||
EMS_TxTelegram.type = EMS_TYPE_IBASettingsMessage;
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_IBASettings_Building;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate
|
||||
|
||||
EMS_TxQueue.push(EMS_TxTelegram);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display settings
|
||||
* to 0xA5
|
||||
*/
|
||||
void ems_setSettingsDisplay(uint8_t ds) {
|
||||
_EMS_TxTelegram EMS_TxTelegram = EMS_TX_TELEGRAM_NEW; // create new Tx
|
||||
EMS_TxTelegram.timestamp = millis(); // set timestamp
|
||||
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
||||
|
||||
switch(ds) {
|
||||
case EMS_VALUE_IBASettings_DISPLAY_INTTEMP:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_INTSETPOINT:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_EXTTEMP:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_BURNERTEMP:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_WWTEMP:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_FUNCMODE:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_TIME:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_DATE:
|
||||
case EMS_VALUE_IBASettings_DISPLAY_SMOKETEMP:
|
||||
myDebug_P(PSTR("Setting display to %d"),ds);
|
||||
EMS_TxTelegram.dataValue = ds;
|
||||
break;
|
||||
default:
|
||||
return; // invalid value
|
||||
}
|
||||
|
||||
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
||||
EMS_TxTelegram.dest = EMS_Thermostat.device_id;
|
||||
EMS_TxTelegram.type = EMS_TYPE_IBASettingsMessage;
|
||||
EMS_TxTelegram.offset = EMS_OFFSET_IBASettings_Display;
|
||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate
|
||||
|
||||
EMS_TxQueue.push(EMS_TxTelegram);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the warm water temperature 0x33
|
||||
*/
|
||||
@@ -3083,6 +3232,9 @@ const _EMS_Type EMS_Types[] = {
|
||||
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_JunkersStatusMessage_HC3, "JunkersStatusMessage_HC3", _process_JunkersStatusMessage},
|
||||
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_JunkersStatusMessage_HC4, "JunkersStatusMessage_HC4", _process_JunkersStatusMessage},
|
||||
|
||||
// settings
|
||||
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_IBASettingsMessage, "IBASettingsMessage", _process_IBASettingsMessage},
|
||||
|
||||
// Mixing devices MM10 - MM400
|
||||
{EMS_DEVICE_UPDATE_FLAG_MIXING, EMS_TYPE_MMPLUSStatusMessage_HC1, "MMPLUSStatusMessage_HC1", _process_MMPLUSStatusMessage},
|
||||
{EMS_DEVICE_UPDATE_FLAG_MIXING, EMS_TYPE_MMPLUSStatusMessage_HC2, "MMPLUSStatusMessage_HC2", _process_MMPLUSStatusMessage},
|
||||
|
||||
17
src/ems.h
17
src/ems.h
@@ -204,7 +204,8 @@ typedef enum : uint8_t {
|
||||
EMS_DEVICE_UPDATE_FLAG_THERMOSTAT = (1 << 1),
|
||||
EMS_DEVICE_UPDATE_FLAG_MIXING = (1 << 2),
|
||||
EMS_DEVICE_UPDATE_FLAG_SOLAR = (1 << 3),
|
||||
EMS_DEVICE_UPDATE_FLAG_HEATPUMP = (1 << 4)
|
||||
EMS_DEVICE_UPDATE_FLAG_HEATPUMP = (1 << 4),
|
||||
EMS_DEVICE_UPDATE_FLAG_SETTINGS = (1 << 5)
|
||||
} _EMS_DEVICE_UPDATE_FLAG;
|
||||
|
||||
typedef enum : uint8_t {
|
||||
@@ -430,6 +431,15 @@ typedef struct {
|
||||
char version[10];
|
||||
char datetime[25]; // HH:MM:SS DD/MM/YYYY
|
||||
bool write_supported;
|
||||
|
||||
// Installation parameters (tested on RC30)
|
||||
uint8_t ibaMainDisplay; // 00, display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||
uint8_t ibaLanguage; // 01, language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
||||
uint8_t ibaCalIntTemperature; // 02, offset int. temperature sensor, by * 0.1 Kelvin
|
||||
int16_t ibaMinExtTemperature; // 05, min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1 (actually a int8_t, coded as int16_t to benefit from negative value rendering)
|
||||
uint8_t ibaBuildingType; // 06, building type: 0 = light, 1 = medium, 2 = heavy
|
||||
uint8_t ibaClockOffset; // 12, offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||
|
||||
_EMS_Thermostat_HC hc[EMS_THERMOSTAT_MAXHC]; // array for the 4 heating circuits
|
||||
} _EMS_Thermostat;
|
||||
|
||||
@@ -483,6 +493,10 @@ void ems_testTelegram(uint8_t test_num);
|
||||
void ems_startupTelegrams();
|
||||
bool ems_checkEMSBUSAlive();
|
||||
|
||||
void ems_setSettingsLanguage(uint8_t lg);
|
||||
void ems_setSettingsBuilding(uint8_t bg);
|
||||
void ems_setSettingsDisplay(uint8_t ds);
|
||||
|
||||
void ems_setThermostatTemp(float temperature, uint8_t hc, _EMS_THERMOSTAT_MODE temptype);
|
||||
void ems_setThermostatTemp(float temperature, uint8_t hc, const char * mode_s);
|
||||
void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc);
|
||||
@@ -509,6 +523,7 @@ char * ems_getDeviceTypeName(_EMS_DEVICE_TYPE device_type, char *
|
||||
_EMS_THERMOSTAT_MODE ems_getThermostatMode(const char * mode_s);
|
||||
void ems_getThermostatValues();
|
||||
void ems_getBoilerValues();
|
||||
void ems_getSettingsValues();
|
||||
void ems_getSolarModuleValues();
|
||||
void ems_getMixingModuleValues();
|
||||
char * ems_getThermostatModeString(_EMS_THERMOSTAT_MODE mode, char * mode_str);
|
||||
|
||||
@@ -52,6 +52,34 @@
|
||||
|
||||
#define EMS_OFFSET_UBASetPoints_flowtemp 0 // flow temp
|
||||
|
||||
// Installation settings
|
||||
#define EMS_TYPE_IBASettingsMessage 0xA5 // installation settings
|
||||
#define EMS_OFFSET_IBASettings_Display 0 // display
|
||||
#define EMS_OFFSET_IBASettings_Language 1 // language
|
||||
#define EMS_OFFSET_IBASettings_MinExtTemp 5 // min. ext. temperature
|
||||
#define EMS_OFFSET_IBASettings_Building 6 // building
|
||||
#define EMS_OFFSET_IBASettings_CalIntTemp 2 // cal. int. temperature
|
||||
#define EMS_OFFSET_IBASettings_ClockOffset 12 // clock offset
|
||||
|
||||
#define EMS_VALUE_IBASettings_LANG_GERMAN 0
|
||||
#define EMS_VALUE_IBASettings_LANG_DUTCH 1
|
||||
#define EMS_VALUE_IBASettings_LANG_FRENCH 2
|
||||
#define EMS_VALUE_IBASettings_LANG_ITALIAN 3
|
||||
|
||||
#define EMS_VALUE_IBASettings_BUILDING_LIGHT 0
|
||||
#define EMS_VALUE_IBASettings_BUILDING_MEDIUM 1
|
||||
#define EMS_VALUE_IBASettings_BUILDING_HEAVY 2
|
||||
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_INTTEMP 0
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_INTSETPOINT 1
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_EXTTEMP 2
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_BURNERTEMP 3
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_WWTEMP 4
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_FUNCMODE 5
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_TIME 6
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_DATE 7
|
||||
#define EMS_VALUE_IBASettings_DISPLAY_SMOKETEMP 9
|
||||
|
||||
// Mixing Modules
|
||||
// MM100/MM200 (EMS Plus)
|
||||
#define EMS_TYPE_MMPLUSStatusMessage_HC1 0x01D7 // mixing status HC1
|
||||
@@ -66,6 +94,7 @@
|
||||
#define EMS_OFFSET_MMPLUSStatusMessage_WW_flow_temp 0 // flow temperature
|
||||
#define EMS_OFFSET_MMPLUSStatusMessage_WW_pump_mod 2 // pump on 6, off 0
|
||||
#define EMS_OFFSET_MMPLUSStatusMessage_WW_temp_status 11 // 0,1,2
|
||||
|
||||
// MM10
|
||||
#define EMS_TYPE_MMStatusMessage 0xAB // mixing status
|
||||
#define EMS_OFFSET_MMStatusMessage_flow_set 0 // flow setpoint
|
||||
|
||||
@@ -59,6 +59,14 @@
|
||||
#define TOPIC_BOILER_CMD_COMFORT "comfort" // ww comfort setting via MQTT
|
||||
#define TOPIC_BOILER_CMD_FLOWTEMP "flowtemp" // flowtemp value via MQTT
|
||||
|
||||
// MQTT for settings
|
||||
#define TOPIC_SETTINGS_DATA "settings_data" // for sending settings values to MQTT
|
||||
#define TOPIC_SETTINGS_CMD "settings_cmd" // for receiving settings commands via MQTT
|
||||
#define TOPIC_SETTINGS_CMD_DISPLAY "display" // change display
|
||||
#define TOPIC_SETTINGS_CMD_LANGUAGE "language" // change language
|
||||
#define TOPIC_SETTINGS_CMD_BUILDING "building" // change building
|
||||
#define TOPIC_SETTINGS_CMD_MINEXTTEMP "minextTemp" // change min. ext. temp.
|
||||
|
||||
// MQTT for mixing device
|
||||
#define TOPIC_MIXING_DATA "mixing_data" // for sending mixing device values to MQTT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user