|
|
|
|
@@ -32,10 +32,8 @@ DS18 ds18;
|
|
|
|
|
#define myDebug_P(...) myESP.myDebug_P(__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
// timers, all values are in seconds
|
|
|
|
|
#define PUBLISHVALUES_TIME 120 // every 2 minutes publish MQTT values
|
|
|
|
|
#define DEFAULT_PUBLISHVALUES_TIME 120 // every 2 minutes publish MQTT values, including Dallas sensors
|
|
|
|
|
Ticker publishValuesTimer;
|
|
|
|
|
|
|
|
|
|
#define PUBLISHSENSORVALUES_TIME 180 // every 3 minutes publish MQTT sensor values
|
|
|
|
|
Ticker publishSensorValuesTimer;
|
|
|
|
|
|
|
|
|
|
#define SYSTEMCHECK_TIME 20 // every 20 seconds check if Boiler is online
|
|
|
|
|
@@ -70,6 +68,7 @@ typedef struct {
|
|
|
|
|
bool shower_alert; // true if we want the alert of cold water
|
|
|
|
|
bool led_enabled; // LED on/off
|
|
|
|
|
bool test_mode; // test mode to stop automatic Tx on/off
|
|
|
|
|
uint16_t publish_time; // frequency of MQTT publish in seconds
|
|
|
|
|
uint8_t led_gpio;
|
|
|
|
|
uint8_t dallas_gpio;
|
|
|
|
|
uint8_t dallas_parasite;
|
|
|
|
|
@@ -91,12 +90,13 @@ command_t PROGMEM project_cmds[] = {
|
|
|
|
|
{true, "dallas_parasite <on | off>", "set to on if powering Dallas via parasite"},
|
|
|
|
|
{true, "thermostat_type <type ID>", "set the thermostat type id (e.g. 10 for 0x10)"},
|
|
|
|
|
{true, "boiler_type <type ID>", "set the boiler type id (e.g. 8 for 0x08)"},
|
|
|
|
|
{true, "test_mode <on | off>", "test_mode turns off all automatic reads"},
|
|
|
|
|
{true, "shower_timer <on | off>", "notify on shower durations"},
|
|
|
|
|
{true, "test_mode <on | off>", "test_mode turns on/off all automatic reads"},
|
|
|
|
|
{true, "shower_timer <on | off>", "notify via MQTT all shower durations"},
|
|
|
|
|
{true, "shower_alert <on | off>", "send a warning of cold water after shower time is exceeded"},
|
|
|
|
|
{false, "info", "show data captured on the EMS bus"},
|
|
|
|
|
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
|
|
|
|
{false, "publish", "publish all values to MQTT"},
|
|
|
|
|
{false, "publish_time <seconds>", "set frequency for MQTT publishing of values"},
|
|
|
|
|
{false, "types", "list supported EMS telegram type IDs"},
|
|
|
|
|
{false, "queue", "show current Tx queue"},
|
|
|
|
|
{false, "autodetect", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
|
|
|
|
|
@@ -108,7 +108,8 @@ command_t PROGMEM project_cmds[] = {
|
|
|
|
|
{false, "thermostat scan <type ID>", "do a read on all type IDs"},
|
|
|
|
|
{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 tapwater <on | off>", "set boiler warm tap water on/off"},
|
|
|
|
|
{false, "boiler comfort <hot | eco | intelligent>", "set boiler warm water comfort setting"}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -262,7 +263,7 @@ void showInfo() {
|
|
|
|
|
|
|
|
|
|
char buffer_type[128] = {0};
|
|
|
|
|
|
|
|
|
|
myDebug("%sEMS-ESP System stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
|
|
|
|
myDebug("%sEMS-ESP system stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
|
|
|
|
_EMS_SYS_LOGGING sysLog = ems_getLogging();
|
|
|
|
|
if (sysLog == EMS_SYS_LOGGING_BASIC) {
|
|
|
|
|
myDebug(" System logging set to Basic");
|
|
|
|
|
@@ -283,7 +284,7 @@ void showInfo() {
|
|
|
|
|
((EMSESP_Status.shower_timer) ? "enabled" : "disabled"),
|
|
|
|
|
((EMSESP_Status.shower_alert) ? "enabled" : "disabled"));
|
|
|
|
|
|
|
|
|
|
myDebug("\n%sEMS Bus Stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
|
|
|
|
myDebug("\n%sEMS Bus stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
|
|
|
|
myDebug(" Bus Connected=%s, # Rx telegrams=%d, # Tx telegrams=%d, # Crc Errors=%d",
|
|
|
|
|
(ems_getBusConnected() ? "yes" : "no"),
|
|
|
|
|
EMS_Sys_Status.emsRxPgks,
|
|
|
|
|
@@ -300,11 +301,11 @@ void showInfo() {
|
|
|
|
|
// active stats
|
|
|
|
|
if (ems_getBusConnected()) {
|
|
|
|
|
if (EMS_Boiler.tapwaterActive != EMS_VALUE_INT_NOTSET) {
|
|
|
|
|
myDebug(" Hot tap water is %s", EMS_Boiler.tapwaterActive ? "running" : "off");
|
|
|
|
|
myDebug(" Hot tap water: %s", EMS_Boiler.tapwaterActive ? "running" : "off");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (EMS_Boiler.heatingActive != EMS_VALUE_INT_NOTSET) {
|
|
|
|
|
myDebug(" Central Heating is %s", EMS_Boiler.heatingActive ? "active" : "off");
|
|
|
|
|
myDebug(" Central Heating: %s", EMS_Boiler.heatingActive ? "active" : "off");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -312,11 +313,11 @@ void showInfo() {
|
|
|
|
|
_renderBoolValue("Warm Water activated", EMS_Boiler.wWActivated);
|
|
|
|
|
_renderBoolValue("Warm Water circulation pump available", EMS_Boiler.wWCircPump);
|
|
|
|
|
if (EMS_Boiler.wWComfort == EMS_VALUE_UBAParameterWW_wwComfort_Hot) {
|
|
|
|
|
myDebug(" Warm Water comfort is set to Hot");
|
|
|
|
|
myDebug(" Warm Water comfort setting: Hot");
|
|
|
|
|
} else if (EMS_Boiler.wWComfort == EMS_VALUE_UBAParameterWW_wwComfort_Eco) {
|
|
|
|
|
myDebug(" Warm Water comfort is set to Eco");
|
|
|
|
|
myDebug(" Warm Water comfort setting: Eco");
|
|
|
|
|
} else if (EMS_Boiler.wWComfort == EMS_VALUE_UBAParameterWW_wwComfort_Intelligent) {
|
|
|
|
|
myDebug(" Warm Water comfort is set to Intelligent");
|
|
|
|
|
myDebug(" Warm Water comfort setting: Intelligent");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_renderIntValue("Warm Water selected temperature", "C", EMS_Boiler.wWSelTemp);
|
|
|
|
|
@@ -701,6 +702,12 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
|
|
|
|
|
recreate_config = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// publish_time
|
|
|
|
|
if (!(EMSESP_Status.publish_time = json["publish_time"])) {
|
|
|
|
|
EMSESP_Status.publish_time = DEFAULT_PUBLISHVALUES_TIME; // default value
|
|
|
|
|
recreate_config = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return recreate_config; // return false if some settings are missing and we need to rebuild the file
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -714,6 +721,7 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
|
|
|
|
|
json["test_mode"] = EMSESP_Status.test_mode;
|
|
|
|
|
json["shower_timer"] = EMSESP_Status.shower_timer;
|
|
|
|
|
json["shower_alert"] = EMSESP_Status.shower_alert;
|
|
|
|
|
json["publish_time"] = EMSESP_Status.publish_time;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@@ -823,6 +831,12 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
|
|
|
|
|
myDebug("Error. Usage: set shower_alert <on | off>");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// publish_time
|
|
|
|
|
if ((strcmp(setting, "publish_time") == 0) && (wc == 2)) {
|
|
|
|
|
EMSESP_Status.publish_time = atoi(value);
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (action == MYESP_FSACTION_LIST) {
|
|
|
|
|
@@ -848,6 +862,7 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
|
|
|
|
|
myDebug(" test_mode=%s", EMSESP_Status.test_mode ? "on" : "off");
|
|
|
|
|
myDebug(" shower_timer=%s", EMSESP_Status.shower_timer ? "on" : "off");
|
|
|
|
|
myDebug(" shower_alert=%s", EMSESP_Status.shower_alert ? "on" : "off");
|
|
|
|
|
myDebug(" publish_time=%d", EMSESP_Status.publish_time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
@@ -896,8 +911,7 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shower settings
|
|
|
|
|
if (strcmp(first_cmd, "shower") == 0) {
|
|
|
|
|
if (wc == 2) {
|
|
|
|
|
if ((strcmp(first_cmd, "shower") == 0) && (wc == 2)) {
|
|
|
|
|
char * second_cmd = _readWord();
|
|
|
|
|
if (strcmp(second_cmd, "timer") == 0) {
|
|
|
|
|
EMSESP_Status.shower_timer = !EMSESP_Status.shower_timer;
|
|
|
|
|
@@ -909,11 +923,9 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// logging
|
|
|
|
|
if (strcmp(first_cmd, "log") == 0) {
|
|
|
|
|
if (wc == 2) {
|
|
|
|
|
if ((strcmp(first_cmd, "log") == 0) && (wc == 2)) {
|
|
|
|
|
char * second_cmd = _readWord();
|
|
|
|
|
if (strcmp(second_cmd, "v") == 0) {
|
|
|
|
|
ems_setLogging(EMS_SYS_LOGGING_VERBOSE);
|
|
|
|
|
@@ -932,11 +944,9 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// thermostat commands
|
|
|
|
|
if (strcmp(first_cmd, "thermostat") == 0) {
|
|
|
|
|
if (wc == 3) {
|
|
|
|
|
if ((strcmp(first_cmd, "thermostat") == 0) && (wc == 3)) {
|
|
|
|
|
char * second_cmd = _readWord();
|
|
|
|
|
if (strcmp(second_cmd, "temp") == 0) {
|
|
|
|
|
ems_setThermostatTemp(_readFloatNumber());
|
|
|
|
|
@@ -952,15 +962,25 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// boiler commands
|
|
|
|
|
if (strcmp(first_cmd, "boiler") == 0) {
|
|
|
|
|
if (wc == 3) {
|
|
|
|
|
if ((strcmp(first_cmd, "boiler") == 0) && (wc == 3)) {
|
|
|
|
|
char * second_cmd = _readWord();
|
|
|
|
|
if (strcmp(second_cmd, "wwtemp") == 0) {
|
|
|
|
|
ems_setWarmWaterTemp(_readIntNumber());
|
|
|
|
|
ok = true;
|
|
|
|
|
} else if (strcmp(second_cmd, "comfort") == 0) {
|
|
|
|
|
char * third_cmd = _readWord();
|
|
|
|
|
if (strcmp(third_cmd, "hot") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(1);
|
|
|
|
|
ok = true;
|
|
|
|
|
} else if (strcmp(third_cmd, "eco") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(2);
|
|
|
|
|
ok = true;
|
|
|
|
|
} else if (strcmp(third_cmd, "intelligent") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(3);
|
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (strcmp(second_cmd, "read") == 0) {
|
|
|
|
|
ems_doReadCommand(_readHexNumber(), EMS_Boiler.type_id);
|
|
|
|
|
ok = true;
|
|
|
|
|
@@ -975,7 +995,6 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send raw
|
|
|
|
|
if (strcmp(first_cmd, "send") == 0) {
|
|
|
|
|
@@ -1009,6 +1028,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_MODE);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_BOILER_WWACTIVATED);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_BOILER_CMD_WWTEMP);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_BOILER_CMD_COMFORT);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_SHOWER_TIMER);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_SHOWER_ALERT);
|
|
|
|
|
myESP.mqttSubscribe(TOPIC_SHOWER_COLDSHOT);
|
|
|
|
|
@@ -1070,6 +1090,19 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
|
|
|
|
publishValues(true); // publish back immediately
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// boiler ww comfort setting
|
|
|
|
|
if (strcmp(topic, TOPIC_BOILER_CMD_COMFORT) == 0) {
|
|
|
|
|
myDebug("MQTT topic: boiler warm water comfort value is %s", message);
|
|
|
|
|
if (strcmp((char *)message, "hot") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(1);
|
|
|
|
|
} else if (strcmp((char *)message, "comfort") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(2);
|
|
|
|
|
} else if (strcmp((char *)message, "intelligent") == 0) {
|
|
|
|
|
ems_setWarmWaterModeComfort(3);
|
|
|
|
|
}
|
|
|
|
|
// publishValues(true); // publish back immediately
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shower timer
|
|
|
|
|
if (strcmp(topic, TOPIC_SHOWER_TIMER) == 0) {
|
|
|
|
|
if (message[0] == '1') {
|
|
|
|
|
@@ -1113,12 +1146,14 @@ void WIFICallback() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize the boiler settings and shower settings
|
|
|
|
|
// Most of these will be overwritten after the SPIFFS config file is loaded
|
|
|
|
|
void initEMSESP() {
|
|
|
|
|
// general settings
|
|
|
|
|
EMSESP_Status.shower_timer = false;
|
|
|
|
|
EMSESP_Status.shower_alert = false;
|
|
|
|
|
EMSESP_Status.led_enabled = true; // LED is on by default
|
|
|
|
|
EMSESP_Status.test_mode = false;
|
|
|
|
|
EMSESP_Status.publish_time = DEFAULT_PUBLISHVALUES_TIME;
|
|
|
|
|
|
|
|
|
|
EMSESP_Status.timestamp = millis();
|
|
|
|
|
EMSESP_Status.dallas_sensors = 0;
|
|
|
|
|
@@ -1316,11 +1351,13 @@ void setup() {
|
|
|
|
|
// start up all the services
|
|
|
|
|
myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION);
|
|
|
|
|
|
|
|
|
|
// at this point we have the settings from our internall SPIFFS config file
|
|
|
|
|
|
|
|
|
|
// enable regular checks if not in test mode
|
|
|
|
|
if (!EMSESP_Status.test_mode) {
|
|
|
|
|
publishValuesTimer.attach(PUBLISHVALUES_TIME, do_publishValues); // post MQTT values
|
|
|
|
|
publishValuesTimer.attach(EMSESP_Status.publish_time, do_publishValues); // post MQTT EMS values
|
|
|
|
|
publishSensorValuesTimer.attach(EMSESP_Status.publish_time, do_publishSensorValues); // post MQTT sensor values
|
|
|
|
|
regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS
|
|
|
|
|
publishSensorValuesTimer.attach(PUBLISHSENSORVALUES_TIME, do_publishSensorValues); // post MQTT sensor values
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set pin for LED
|
|
|
|
|
@@ -1360,5 +1397,5 @@ void loop() {
|
|
|
|
|
showerCheck();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delay(1); // some time to WiFi and everything else to catch up
|
|
|
|
|
delay(1); // some time to WiFi and everything else to catch up, and prevent overheating
|
|
|
|
|
}
|
|
|
|
|
|