Skip to content

Commit

Permalink
Merge pull request rbroker#13 from limkinZero/main
Browse files Browse the repository at this point in the history
Add support to switch Off/On Ecodan system from HA
  • Loading branch information
rbroker committed Nov 14, 2023
2 parents fa59f02 + 0028dc1 commit 00cbd1c
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
ecodan-ha-local/build/
ecodan-ha-local/build/
.vscode
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
# ecodan-ha-local
ESP32 compatible program for local monitoring of Mitsubishi Ecodan Air to Water heat pumps with automatic discovery in HomeAssistant.

Uses the CN105 connector on the Cased Flow Temp Controller (FTC6 in my setup) to do very basic control (zone 1 temperature set point, DHW temperature set point, boost DHW) + retrieve basic sensor information from the heat pump.
Uses the CN105 connector on the Cased Flow Temp Controller (FTC6 in my setup) to do basic control.

## Controls implemented
- Manage Zone 1 climate. Temperature set point. Actual temperature.
- Heat pump mode selector. You can select the working mode (heat and cool): `Space room temperature`, `Flow temperature` or `Compensation curve`.
- Manage water boiler. Configure temperature set point and its modes (eco or normal).
- Control to boost DHW.
- Control to turn ON and turn OFF ecodan.

## Sensors information retreived
- Defrost mode
- Compressor frequency
- Pump flow rate
- Boost DHW mode
- Output power
- Legionella prevention temperature setting
- Zone 1 room temperature
- Zone 2 room temperature
- Dhw current temperature
- Dhw temperature target
- Dhw temperature drop
- Outside temperature
- Heat pump feed temperature
- Heat pump return temperature
- Boiler flow temperature
- Boiler return temperature
- Power mode
- Operation mode
- DHW mode
- Heating/Cooling working mode
- Heating consumed energy
- Heating delivered energy
- DHW consumed energy
- DHW delivered energy
- COP of space heating
- COP of DHW

<p float="left">
<img src="img/config_page.png" height="640" />
Expand All @@ -16,6 +51,10 @@ Uses the CN105 connector on the Cased Flow Temp Controller (FTC6 in my setup) to
- CN105 female connector + pigtails, as described [here](https://github.com/SwiCago/HeatPump#Demo-Circuit).
- Note: The software is configured to use Serial UART1 on the ESP32, explicitly labelled TX/RX pins on a pinout will usually be pre-assigned to UART0.

## ESP32 Boards tested
- LOLIN S2 Mini
- WROOM-32

## Library Dependencies
- ArduinoJson v6.21.2
- Seeed_Arduino_mbedtls v3.0.1
Expand Down
2 changes: 1 addition & 1 deletion ecodan-ha-local/ehal_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace ehal

String get_software_version()
{
return FPSTR("v0.1.2");
return FPSTR("v0.1.3");
}

} // namespace ehal
19 changes: 19 additions & 0 deletions ecodan-ha-local/ehal_hp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,25 @@ namespace ehal::hp
return true;
}

bool set_power_mode(bool on)
{
Message cmd{MsgType::SET_CMD, SetType::BASIC_SETTINGS};
cmd[1] = SET_SETTINGS_FLAG_MODE_TOGGLE;
cmd[3] = on ? 1 : 0;
{
std::lock_guard<std::mutex> lock{cmdQueueMutex};
cmdQueue.emplace(std::move(cmd));
}

if (!dispatch_next_cmd())
{
log_web(F("command dispatch failed for DHW force setting!"));
return false;
}

return true;
}

bool set_hp_mode(uint8_t mode)
{
Message cmd{MsgType::SET_CMD, SetType::BASIC_SETTINGS};
Expand Down
1 change: 1 addition & 0 deletions ecodan-ha-local/ehal_hp.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ namespace ehal::hp
bool set_dhw_target_temperature(float value);
bool set_dhw_mode(String mode);
bool set_dhw_force(bool on);
bool set_power_mode(bool on);
bool set_hp_mode(uint8_t mode);

bool begin_connect();
Expand Down
71 changes: 71 additions & 0 deletions ecodan-ha-local/ehal_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,30 @@ off
}
}

void on_turn_on_off_command(const String& payload)
{
bool turnON = payload == "ON";

if (!hp::set_power_mode(turnON))
{
log_web(F("Failed to set power mode!"));
}
else
{
auto& status = hp::get_status();
std::lock_guard<hp::Status> lock{status};
if (turnON)
{
status.Power = hp::Status::PowerMode::ON;
}
else
{
status.Power = hp::Status::PowerMode::STANDBY;
}
publish_sensor_status<String>(F("mode_power"), status.power_as_string());
}
}

void mqtt_callback(String& topic, String& payload)
{
try
Expand All @@ -252,6 +276,7 @@ off
String climateEntity = unique_entity_name(F("climate_control"));
String tempCmdTopic = config.MqttTopic + "/" + climateEntity + F("/temp_cmd");
String dhwForceCmdTopic = config.MqttTopic + "/" + unique_entity_name(F("force_dhw")) + F("/set");
String turnOnOffCmdTopic = config.MqttTopic + "/" + unique_entity_name(F("turn_on_off_hp")) + F("/set");
String dhwTempCmdTopic = config.MqttTopic + "/" + unique_entity_name(F("dhw_water_heater")) + F("/set");
String dhwModeCmdTopic = config.MqttTopic + "/" + unique_entity_name(F("dhw_mode")) + F("/set");
String shModeCmdTopic = config.MqttTopic + "/" + unique_entity_name(F("sh_mode")) + F("/set");
Expand All @@ -277,6 +302,10 @@ off
{
on_force_dhw_command(payload);
}
else if (turnOnOffCmdTopic == topic)
{
on_turn_on_off_command(payload);
}
}
catch (std::exception const& ex)
{
Expand Down Expand Up @@ -463,6 +492,39 @@ off
return true;
}

bool publish_ha_turn_on_off_auto_discover()
{
// https://www.home-assistant.io/integrations/switch.mqtt/
String uniqueName = unique_entity_name(F("turn_on_off_hp"));

const auto& config = config_instance();
String discoveryTopic = String(F("homeassistant/switch/")) + uniqueName + F("/config");
String stateTopic = config.MqttTopic + "/" + unique_entity_name(F("mode_power")) + F("/state");
String cmdTopic = config.MqttTopic + "/" + uniqueName + F("/set");

DynamicJsonDocument payloadJson(8192);
payloadJson[F("name")] = uniqueName;
payloadJson[F("unique_id")] = uniqueName;
payloadJson[F("icon")] = F("mdi:power");

add_discovery_device_object(payloadJson);

payloadJson[F("stat_t")] = stateTopic;
payloadJson[F("stat_t_tpl")] = F("{{ value }}");
payloadJson[F("stat_on")] = F("On");
payloadJson[F("stat_off")] = F("Standby");
payloadJson[F("cmd_t")] = cmdTopic;
payloadJson[F("cmd_tpl")] = F("{{ value }}");

if (!publish_mqtt(discoveryTopic, payloadJson, /* retain =*/true))
{
log_web(F("Failed to publish homeassistant turn On/Off HP entity auto-discover"));
return false;
}

return true;
}

bool publish_ha_set_dhw_temp_auto_discover()
{
// https://www.home-assistant.io/integrations/water_heater.mqtt/
Expand Down Expand Up @@ -679,6 +741,9 @@ off
if (!publish_ha_force_dhw_auto_discover())
anyFailed = true;

if (!publish_ha_turn_on_off_auto_discover())
anyFailed = true;

if (!publish_ha_set_dhw_temp_auto_discover())
anyFailed = true;

Expand Down Expand Up @@ -888,6 +953,12 @@ off
return false;
}

if (!mqttClient.subscribe(config.MqttTopic + "/" + unique_entity_name(F("turn_on_off_hp")) + F("/set")))
{
log_web(F("Failed to subscribe to turn ON/OFF command topic!"));
return false;
}

if (!mqttClient.subscribe(config.MqttTopic + "/" + unique_entity_name(F("dhw_water_heater")) + F("/set")))
{
log_web(F("Failed to subscribe to DHW temperature topic!"));
Expand Down

0 comments on commit 00cbd1c

Please sign in to comment.