16 static const char *
const TAG =
"haier.climate";
24 static const char *phase_names[] = {
27 "SENDING_FIRST_STATUS_REQUEST",
28 "SENDING_FIRST_ALARM_STATUS_REQUEST",
30 "SENDING_STATUS_REQUEST",
31 "SENDING_UPDATE_SIGNAL_REQUEST",
32 "SENDING_SIGNAL_LEVEL",
34 "SENDING_ACTION_COMMAND",
35 "SENDING_ALARM_STATUS_REQUEST",
39 (
sizeof(phase_names) /
sizeof(
char *)) == (((
int) ProtocolPhases::NUM_PROTOCOL_PHASES) + 1),
40 "Wrong phase_names array size. Please, make sure that this array is aligned with the enum ProtocolPhases");
41 int phase_index = (int) phase;
42 if ((phase_index > (
int) ProtocolPhases::NUM_PROTOCOL_PHASES) || (phase_index < 0))
43 phase_index = (int) ProtocolPhases::NUM_PROTOCOL_PHASES;
44 return phase_names[phase_index];
47 bool check_timeout(std::chrono::steady_clock::time_point now, std::chrono::steady_clock::time_point tpoint,
49 return std::chrono::duration_cast<std::chrono::milliseconds>(now - tpoint).count() > timeout;
52 HaierClimateBase::HaierClimateBase()
53 : haier_protocol_(*this),
55 force_send_control_(false),
56 forced_request_status_(false),
57 reset_protocol_request_(false),
58 send_wifi_signal_(true),
112 static uint8_t wifi_status_data[4] = {0x00, 0x00, 0x00, 0x00};
114 wifi_status_data[1] = 0;
116 wifi_status_data[3] = uint8_t((128 + rssi) / 1.28f);
117 ESP_LOGD(TAG,
"WiFi signal is: %ddBm => %d%%", rssi, wifi_status_data[3]);
119 ESP_LOGD(TAG,
"WiFi is not connected");
120 wifi_status_data[1] = 1;
121 wifi_status_data[3] = 0;
123 return haier_protocol::HaierMessage(haier_protocol::FrameType::REPORT_NETWORK_STATUS, wifi_status_data,
124 sizeof(wifi_status_data));
131 ESP_LOGW(TAG,
"Failed to save settings");
190 if (!presets.empty())
205 haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type,
206 haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type,
208 haier_protocol::HandlerError result = haier_protocol::HandlerError::HANDLER_OK;
209 if ((expected_request_message_type != haier_protocol::FrameType::UNKNOWN_FRAME_TYPE) &&
210 (request_message_type != expected_request_message_type))
211 result = haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
212 if ((expected_answer_message_type != haier_protocol::FrameType::UNKNOWN_FRAME_TYPE) &&
213 (answer_message_type != expected_answer_message_type))
214 result = haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
217 result = haier_protocol::HandlerError::UNEXPECTED_MESSAGE;
218 if (answer_message_type == haier_protocol::FrameType::INVALID)
219 result = haier_protocol::HandlerError::INVALID_ANSWER;
224 haier_protocol::FrameType request_type, haier_protocol::FrameType message_type,
const uint8_t *data,
226 haier_protocol::HandlerError result =
227 this->
answer_preprocess_(request_type, haier_protocol::FrameType::REPORT_NETWORK_STATUS, message_type,
234 ESP_LOGW(TAG,
"Answer timeout for command %02X, phase %s", (uint8_t) request_type,
241 return haier_protocol::HandlerError::HANDLER_OK;
245 ESP_LOGI(TAG,
"Haier initialization...");
256 LOG_CLIMATE(
"",
"Haier Climate",
this);
257 ESP_LOGCONFIG(TAG,
" Device communication status: %s", this->
valid_connection() ?
"established" :
"none");
261 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
263 COMMUNICATION_TIMEOUT_MS) ||
271 ESP_LOGW(TAG,
"Protocol reset requested");
273 ESP_LOGW(TAG,
"Communication timeout, reseting protocol");
289 ESP_LOGV(TAG,
"Control packet is pending...");
341 ESP_LOGW(TAG,
"Unsupported action: %d", (uint8_t) this->
action_request_.value().action);
352 constexpr uint32_t restore_settings_version = 0xA77D21EF;
357 recovered = {
false,
true};
372 ESP_LOGD(
"Control",
"Control call");
374 ESP_LOGW(TAG,
"Can't send control packet, first poll answer not received");
378 ESP_LOGW(TAG,
"New settings come faster then processed!");
421 std::chrono::milliseconds interval) {
422 this->
haier_protocol_.send_message(command, use_crc, num_repeats, interval);
HvacSettings current_hvac_settings_
This class is used to encode all control actions on a climate device.
Base class for all switches.
The fan mode is set to Low.
constexpr size_t COMMUNICATION_TIMEOUT_MS
ClimateSwingMode swing_mode
The active swing mode of the climate device.
SwitchState display_status_
esphome::optional< float > target_temperature
The fan mode is set to Both.
esphome::optional< esphome::climate::ClimatePreset > preset
constexpr size_t PROTOCOL_INITIALIZATION_INTERVAL
float target_temperature
The target temperature of the climate device.
haier_protocol::HandlerError report_network_status_answer_handler_(haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data, size_t data_size)
void send_power_off_command()
const optional< ClimateMode > & get_mode() const
virtual void set_phase(ProtocolPhases phase)
This class contains all static data for climate devices.
void control(const esphome::climate::ClimateCall &call) override
void set_health_mode(bool state)
constexpr size_t DEFAULT_MESSAGES_INTERVAL_MS
bool reset_protocol_request_
std::chrono::steady_clock::time_point last_status_request_
The climate device is set to heat to reach the target temperature.
ClimateMode mode
The active mode of the climate device.
bool get_health_mode() const
ESPPreferenceObject base_rtc_
float current_temperature
The current temperature of the climate device, as reported from the integration.
void set_send_wifi(bool send_wifi)
haier_protocol::HandlerError answer_preprocess_(haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type, haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type, ProtocolPhases expected_phase)
The climate device is set to dry/humidity mode.
virtual bool prepare_pending_action()
void set_supported_presets(std::set< ClimatePreset > presets)
virtual void process_phase(std::chrono::steady_clock::time_point now)=0
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
void set_display_switch(switch_::Switch *sw)
bool get_display_state() const
void add_supported_preset(ClimatePreset preset)
virtual void save_settings()
esphome::climate::ClimateTraits traits() override
haier_protocol::ProtocolHandler haier_protocol_
void add_supported_swing_mode(ClimateSwingMode mode)
bool is_protocol_initialisation_interval_exceeded_(std::chrono::steady_clock::time_point now)
void set_display_state(bool state)
The fan mode is set to Horizontal.
The climate device is set to cool to reach the target temperature.
virtual void initialization()
const optional< ClimatePreset > & get_preset() const
void set_supported_fan_modes(std::set< ClimateFanMode > modes)
The fan mode is set to Auto.
void set_answer_timeout(uint32_t timeout)
void send_message_(const haier_protocol::HaierMessage &command, bool use_crc, uint8_t num_repeats=0, std::chrono::milliseconds interval=std::chrono::milliseconds::zero())
ProtocolPhases protocol_phase_
haier_protocol::HaierMessage get_wifi_signal_message_()
optional< ClimatePreset > preset
The active preset of the climate device.
const char * phase_to_string_(ProtocolPhases phase)
ESPPreferences * global_preferences
constexpr size_t STATUS_REQUEST_INTERVAL_MS
void set_supported_modes(std::set< ClimateMode > modes)
esphome::optional< PendingAction > action_request_
void set_supported_modes(const std::set< esphome::climate::ClimateMode > &modes)
esphome::optional< esphome::climate::ClimateFanMode > fan_mode
The climate device is set to heat/cool to reach the target temperature.
void set_supported_swing_modes(const std::set< esphome::climate::ClimateSwingMode > &modes)
The fan mode is set to Vertical.
void dump_config() override
constexpr size_t CONTROL_MESSAGES_INTERVAL_MS
WiFiComponent * global_wifi_component
virtual void set_handlers()=0
const optional< float > & get_target_temperature() const
void publish_state()
Publish the state of the climate device, to be called from integrations.
The fan mode is set to High.
virtual haier_protocol::HaierMessage get_power_message(bool state)=0
The swing mode is set to Off.
The climate device is off.
void add_status_message_callback(std::function< void(const char *, size_t)> &&callback)
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
switch_::Switch * health_mode_switch_
const optional< ClimateFanMode > & get_fan_mode() const
virtual void process_protocol_reset()
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
HvacSettings next_hvac_settings_
bool valid_connection() const
bool is_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
const optional< ClimateSwingMode > & get_swing_mode() const
bool is_status_request_interval_exceeded_(std::chrono::steady_clock::time_point now)
bool check_timeout(std::chrono::steady_clock::time_point now, std::chrono::steady_clock::time_point tpoint, size_t timeout)
Implementation of SPI Controller mode.
std::chrono::steady_clock::time_point last_request_timestamp_
void set_supported_swing_modes(std::set< ClimateSwingMode > modes)
haier_protocol::HandlerError timeout_default_handler_(haier_protocol::FrameType request_type)
void send_custom_command(const haier_protocol::HaierMessage &message)
void set_supported_presets(const std::set< esphome::climate::ClimatePreset > &presets)
void set_supports_current_temperature(bool supports_current_temperature)
The fan mode is set to Medium.
void set_health_mode_switch(switch_::Switch *sw)
switch_::Switch * display_switch_
The climate device only has the fan enabled, no heating or cooling is taking place.
void publish_state(bool state)
Publish a state to the front-end from the back-end.
bool is_control_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
CallbackManager< void(const char *, size_t)> status_message_callback_
bool state
The current reported state of the binary sensor.
void add_supported_mode(ClimateMode mode)
uint32_t get_object_id_hash()
void send_power_on_command()
esphome::climate::ClimateTraits traits_
bool forced_request_status_
esphome::optional< esphome::climate::ClimateSwingMode > swing_mode
std::chrono::steady_clock::time_point last_valid_status_timestamp_
esphome::optional< esphome::climate::ClimateMode > mode