I have an ESP8266 and an EcoSmart27 Hot water heater that I would love to control but I am not understanding the repo and how to implement it with my HomeAssistant setup. I have the ESPHome addon and have successfully got a relay working but I am less familiar with MQTT.
I am hoping someone here could offer guidance in order to help get me going.
I updated the repo with ESPHome-specific instructions; it should be a bit easier to integrate now.
As always, I make no warranties as to whether this will work for you - but it did work for me on my particular model. And watch out connecting those control wires! I fried a controller just looking at it funny.
One thing I didn’t mention is that the metal enclosure of the EcoSmart was really a hindrance to the nodemcu wifi signal. I had to place an AP pretty close to it to get it to work. I also could have brought the control wires through the case and placed the nodemcu on the outside.
I attempted an install but got stuck a bit. First error I got was with the status pin declaration. I changed D0 to 0 and the error went away.
Then I got an error when compiling where I get an error about BinarySensor.
src/ecosmart.h:234:61: error: no matching function for call to 'esphome::binary_sensor::BinarySensor::BinarySensor(const char [12])'
234 | BinarySensor *flow_sensor = new BinarySensor("Flow Sensor");
| ^
In file included from src/esphome/core/controller.h:5,
from src/esphome/components/api/api_server.h:4,
from src/esphome/components/api/api_connection.h:6,
from src/esphome.h:3,
from src/main.cpp:3:
src/esphome/components/binary_sensor/binary_sensor.h:28:12: note: candidate: 'esphome::binary_sensor::BinarySensor::BinarySensor()'
28 | explicit BinarySensor();
| ^~~~~~~~~~~~
src/esphome/components/binary_sensor/binary_sensor.h:28:12: note: candidate expects 0 arguments, 1 provided
src/esphome/components/binary_sensor/binary_sensor.h:26:7: note: candidate: 'esphome::binary_sensor::BinarySensor::BinarySensor(const esphome::binary_sensor::BinarySensor&)'
26 | class BinarySensor : public EntityBase {
| ^~~~~~~~~~~~
src/esphome/components/binary_sensor/binary_sensor.h:26:7: note: no known conversion for argument 1 from 'const char [12]' to 'const esphome::binary_sensor::BinarySensor&'
src/esphome/components/binary_sensor/binary_sensor.h:26:7: note: candidate: 'esphome::binary_sensor::BinarySensor::BinarySensor(esphome::binary_sensor::BinarySensor&&)'
src/esphome/components/binary_sensor/binary_sensor.h:26:7: note: no known conversion for argument 1 from 'const char [12]' to 'esphome::binary_sensor::BinarySensor&&'
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/lib84c/IRremoteESP8266/ir_Sherwood.cpp.o
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/lib84c/IRremoteESP8266/ir_Sony.cpp.o
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/lib84c/IRremoteESP8266/ir_Symphony.cpp.o
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/lib84c/IRremoteESP8266/ir_Tcl.cpp.o
*** [/data/esp3-ecosmart/.pioenvs/esp3-ecosmart/src/main.cpp.o] Error 1
I went ahead and commented out the binary_sensor and the climate sections of the yaml and attempted to recompile. I then got new errors (several) this time with regard to ecosmart.h
In file included from src/main.cpp:28:
src/ecosmart.h:57:1: error: expected class-name before '{' token
57 | {
| ^
src/ecosmart.h:91:3: error: 'ClimateTraits' does not name a type
91 | ClimateTraits traits() override
| ^~~~~~~~~~~~~
src/ecosmart.h:108:22: error: 'ClimateCall' does not name a type
108 | void control(const ClimateCall &call) override
| ^~~~~~~~~~~
src/ecosmart.h:108:8: error: 'void EcoSmartClimate::control(const int&)' marked 'override', but does not override
108 | void control(const ClimateCall &call) override
| ^~~~~~~
src/ecosmart.h: In member function 'virtual void EcoSmartClimate::setup()':
src/ecosmart.h:74:26: error: 'class EcoSmartClimate' has no member named 'restore_state_'
74 | auto restore = this->restore_state_();
| ^~~~~~~~~~~~~~
src/ecosmart.h:81:13: error: 'class EcoSmartClimate' has no member named 'mode'
81 | this->mode = climate::CLIMATE_MODE_HEAT;
| ^~~~
src/ecosmart.h:81:20: error: 'climate' has not been declared
81 | this->mode = climate::CLIMATE_MODE_HEAT;
| ^~~~~~~
src/ecosmart.h:82:13: error: 'class EcoSmartClimate' has no member named 'current_temperature'
82 | this->current_temperature = NAN;
| ^~~~~~~~~~~~~~~~~~~
src/ecosmart.h:84:21: error: 'class EcoSmartClimate' has no member named 'target_temperature'
84 | if (isnan(this->target_temperature))
| ^~~~~~~~~~~~~~~~~~
src/ecosmart.h:86:13: error: 'class EcoSmartClimate' has no member named 'target_temperature'
86 | this->target_temperature = ECOSMART_TEMP_MIN;
| ^~~~~~~~~~~~~~~~~~
src/ecosmart.h:88:11: error: 'class EcoSmartClimate' has no member named 'publish_state'
88 | this->publish_state();
| ^~~~~~~~~~~~~
src/ecosmart.h: In member function 'void EcoSmartClimate::control(const int&)':
src/ecosmart.h:112:14: error: request for member 'get_mode' in 'call', which is of non-class type 'const int'
112 | if (call.get_mode().has_value())
| ^~~~~~~~
src/ecosmart.h:115:7: error: 'ClimateMode' was not declared in this scope; did you mean 'esphome::api::enums::ClimateMode'?
115 | ClimateMode mode = *call.get_mode();
| ^~~~~~~~~~~
| esphome::api::enums::ClimateMode
In file included from src/esphome/components/api/api_connection.h:4,
from src/esphome.h:3,
from src/main.cpp:3:
src/esphome/components/api/api_pb2.h:83:6: note: 'esphome::api::enums::ClimateMode' declared here
83 | enum ClimateMode : uint32_t {
| ^~~~~~~~~~~
In file included from src/main.cpp:28:
src/ecosmart.h:117:15: error: 'mode' was not declared in this scope; did you mean 'modf'?
117 | switch (mode)
| ^~~~
| modf
src/ecosmart.h:119:12: error: 'climate' has not been declared
119 | case climate::CLIMATE_MODE_OFF:
| ^~~~~~~
src/ecosmart.h:122:12: error: 'climate' has not been declared
122 | case climate::CLIMATE_MODE_HEAT:
| ^~~~~~~
In file included from src/esphome/components/api/proto.h:4,
from src/esphome/components/api/api_pb2.h:5,
from src/esphome/components/api/api_connection.h:4,
from src/esphome.h:3,
from src/main.cpp:3:
src/ecosmart.h:126:86: error: 'class EcoSmartClimate' has no member named 'mode'
126 | ESP_LOGE(TAG, "Climate mode not supported: %s", climate_mode_to_string(this->mode));
| ^~~~
src/esphome/core/log.h:123:89: note: in definition of macro 'esph_log_e'
123 | esp_log_printf_(ESPHOME_LOG_LEVEL_ERROR, tag, __LINE__, ESPHOME_LOG_FORMAT(format), ##__VA_ARGS__)
| ^~~~~~~~~~~
src/ecosmart.h:126:9: note: in expansion of macro 'ESP_LOGE'
126 | ESP_LOGE(TAG, "Climate mode not supported: %s", climate_mode_to_string(this->mode));
| ^~~~~~~~
src/ecosmart.h:126:57: error: 'climate_mode_to_string' was not declared in this scope
126 | ESP_LOGE(TAG, "Climate mode not supported: %s", climate_mode_to_string(this->mode));
| ^~~~~~~~~~~~~~~~~~~~~~
src/esphome/core/log.h:123:89: note: in definition of macro 'esph_log_e'
123 | esp_log_printf_(ESPHOME_LOG_LEVEL_ERROR, tag, __LINE__, ESPHOME_LOG_FORMAT(format), ##__VA_ARGS__)
| ^~~~~~~~~~~
src/ecosmart.h:126:9: note: in expansion of macro 'ESP_LOGE'
126 | ESP_LOGE(TAG, "Climate mode not supported: %s", climate_mode_to_string(this->mode));
| ^~~~~~~~
In file included from src/main.cpp:28:
src/ecosmart.h:131:13: error: 'class EcoSmartClimate' has no member named 'mode'
131 | this->mode = mode;
| ^~~~
src/ecosmart.h:131:20: error: 'mode' was not declared in this scope; did you mean 'modf'?
131 | this->mode = mode;
| ^~~~
| modf
src/ecosmart.h:138:14: error: request for member 'get_target_temperature' in 'call', which is of non-class type 'const int'
138 | if (call.get_target_temperature().has_value())
| ^~~~~~~~~~~~~~~~~~~~~~
src/ecosmart.h:141:41: error: request for member 'get_target_temperature' in 'call', which is of non-class type 'const int'
141 | float temp_c = clamp<float>(*call.get_target_temperature(), ECOSMART_TEMP_MIN, ECOSMART_TEMP_MAX);
| ^~~~~~~~~~~~~~~~~~~~~~
src/ecosmart.h:145:13: error: 'class EcoSmartClimate' has no member named 'target_temperature'
145 | this->target_temperature = temp_c;
| ^~~~~~~~~~~~~~~~~~
src/ecosmart.h: In member function 'void EcoSmartClimate::sendCommand()':
src/ecosmart.h:227:11: error: 'class EcoSmartClimate' has no member named 'publish_state'
227 | this->publish_state();
| ^~~~~~~~~~~~~
src/ecosmart.h: At global scope:
src/ecosmart.h:234:3: error: 'BinarySensor' does not name a type
234 | BinarySensor *flow_sensor = new BinarySensor("Flow Sensor");
| ^~~~~~~~~~~~
src/ecosmart.h: In member function 'void EcoSmart::processData(uint64_t)':
src/ecosmart.h:391:14: error: 'class EcoSmartClimate' has no member named 'target_temperature'
391 | climate->target_temperature = lroundf(use_c ? getTempC() : getTempF());
| ^~~~~~~~~~~~~~~~~~
src/ecosmart.h:392:14: error: 'class EcoSmartClimate' has no member named 'mode'
392 | climate->mode = stateOn ? climate::CLIMATE_MODE_HEAT : climate::CLIMATE_MODE_OFF;
| ^~~~
src/ecosmart.h:392:31: error: 'climate' is not a class, namespace, or enumeration
392 | climate->mode = stateOn ? climate::CLIMATE_MODE_HEAT : climate::CLIMATE_MODE_OFF;
| ^~~~~~~
src/ecosmart.h:392:60: error: 'climate' is not a class, namespace, or enumeration
392 | climate->mode = stateOn ? climate::CLIMATE_MODE_HEAT : climate::CLIMATE_MODE_OFF;
| ^~~~~~~
src/ecosmart.h:393:14: error: 'class EcoSmartClimate' has no member named 'publish_state'
393 | climate->publish_state();
| ^~~~~~~~~~~~~
src/ecosmart.h:395:5: error: 'flow_sensor' was not declared in this scope
395 | flow_sensor->publish_state(stateFlow);
| ^~~~~~~~~~~
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/FrameworkArduino/core_esp8266_spi_utils.cpp.o
Compiling /data/esp3-ecosmart/.pioenvs/esp3-ecosmart/FrameworkArduino/core_esp8266_timer.cpp.o
*** [/data/esp3-ecosmart/.pioenvs/esp3-ecosmart/src/main.cpp.o] Error 1
Unfortunately I lost my EcoSmart heater in a wildfire (not caused by the heater), so maintenance is not my priority at this point, but when I re-implement it I will try to work out the bugs. Are you using the ecosmart.h file from the ecosmart directory?