16static 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",
40 "Wrong phase_names array size. Please, make sure that this array is aligned with the enum ProtocolPhases");
41 int phase_index = (int) phase;
44 return phase_names[phase_index];
47bool 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;
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();
271 ESP_LOGW(TAG,
"Protocol reset requested");
273 ESP_LOGW(TAG,
"Communication timeout, reseting protocol");
286 if (this->
action_request_.has_value() && this->prepare_pending_action()) {
289 ESP_LOGV(TAG,
"Control packet is pending...");
341 ESP_LOGW(TAG,
"Unsupported action: %d", (uint8_t) this->
action_request_.value().action);
353 constexpr uint32_t restore_settings_version = 0xA77D21EF;
358 recovered = {
false,
true};
373 ESP_LOGD(
"Control",
"Control call");
375 ESP_LOGW(TAG,
"Can't send control packet, first poll answer not received");
379 ESP_LOGW(TAG,
"New settings come faster then processed!");
382 if (
call.get_mode().has_value())
384 if (
call.get_fan_mode().has_value())
386 if (
call.get_swing_mode().has_value())
388 if (
call.get_target_temperature().has_value())
390 if (
call.get_preset().has_value())
422 std::chrono::milliseconds interval) {
423 this->
haier_protocol_.send_message(command, use_crc, num_repeats, interval);
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t get_object_id_hash()
This class is used to encode all control actions on a climate device.
const optional< ClimateSwingMode > & get_swing_mode() const
const optional< float > & get_target_temperature() const
const optional< ClimatePreset > & get_preset() const
const optional< ClimateFanMode > & get_fan_mode() const
const optional< ClimateMode > & get_mode() const
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
float target_temperature
The target temperature of the climate device.
float current_temperature
The current temperature of the climate device, as reported from the integration.
void publish_state()
Publish the state of the climate device, to be called from integrations.
optional< ClimatePreset > preset
The active preset of the climate device.
This class contains all static data for climate devices.
void set_supported_modes(std::set< ClimateMode > modes)
void add_supported_preset(ClimatePreset preset)
void set_supported_swing_modes(std::set< ClimateSwingMode > modes)
void set_supported_presets(std::set< ClimatePreset > presets)
void add_supported_mode(ClimateMode mode)
void set_supported_fan_modes(std::set< ClimateFanMode > modes)
void set_supports_current_temperature(bool supports_current_temperature)
void add_supported_swing_mode(ClimateSwingMode mode)
bool reset_protocol_request_
virtual haier_protocol::HaierMessage get_power_message(bool state)=0
ProtocolPhases protocol_phase_
void add_status_message_callback(std::function< void(const char *, size_t)> &&callback)
SwitchState display_status_
esphome::climate::ClimateTraits traits_
bool get_health_mode() const
ESPPreferenceObject base_rtc_
void send_power_on_command()
bool is_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
void set_supported_swing_modes(const std::set< esphome::climate::ClimateSwingMode > &modes)
CallbackManager< void(const char *, size_t)> status_message_callback_
bool forced_request_status_
void set_supported_presets(const std::set< esphome::climate::ClimatePreset > &presets)
bool is_protocol_initialisation_interval_exceeded_(std::chrono::steady_clock::time_point now)
bool is_status_request_interval_exceeded_(std::chrono::steady_clock::time_point now)
esphome::climate::ClimateTraits traits() override
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)
virtual void initialization()
virtual void save_settings()
haier_protocol::ProtocolHandler haier_protocol_
void set_health_mode(bool state)
virtual void process_protocol_reset()
std::chrono::steady_clock::time_point last_request_timestamp_
const char * phase_to_string_(ProtocolPhases phase)
@ SENDING_UPDATE_SIGNAL_REQUEST
void send_message_(const haier_protocol::HaierMessage &command, bool use_crc, uint8_t num_repeats=0, std::chrono::milliseconds interval=std::chrono::milliseconds::zero())
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 control(const esphome::climate::ClimateCall &call) override
virtual void process_phase(std::chrono::steady_clock::time_point now)=0
virtual bool prepare_pending_action()
bool get_display_state() const
void set_health_mode_switch(switch_::Switch *sw)
std::chrono::steady_clock::time_point last_valid_status_timestamp_
haier_protocol::HaierMessage get_wifi_signal_message_()
haier_protocol::HandlerError timeout_default_handler_(haier_protocol::FrameType request_type)
bool is_control_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
switch_::Switch * health_mode_switch_
bool valid_connection() const
esphome::optional< PendingAction > action_request_
void set_answer_timeout(uint32_t timeout)
std::chrono::steady_clock::time_point last_status_request_
HvacSettings current_hvac_settings_
HvacSettings next_hvac_settings_
void set_display_switch(switch_::Switch *sw)
void dump_config() override
void set_display_state(bool state)
void send_power_off_command()
virtual void set_handlers()=0
void set_send_wifi(bool send_wifi)
virtual void set_phase(ProtocolPhases phase)
void send_custom_command(const haier_protocol::HaierMessage &message)
void set_supported_modes(const std::set< esphome::climate::ClimateMode > &modes)
switch_::Switch * display_switch_
Base class for all switches.
bool state
The current reported state of the binary sensor.
void publish_state(bool state)
Publish a state to the front-end from the back-end.
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_SWING_BOTH
The fan mode is set to Both.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
@ CLIMATE_FAN_MEDIUM
The fan mode is set to Medium.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
@ CLIMATE_FAN_LOW
The fan mode is set to Low.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
constexpr size_t STATUS_REQUEST_INTERVAL_MS
bool check_timeout(std::chrono::steady_clock::time_point now, std::chrono::steady_clock::time_point tpoint, size_t timeout)
constexpr size_t PROTOCOL_INITIALIZATION_INTERVAL
constexpr size_t DEFAULT_MESSAGES_INTERVAL_MS
constexpr size_t COMMUNICATION_TIMEOUT_MS
constexpr size_t CONTROL_MESSAGES_INTERVAL_MS
WiFiComponent * global_wifi_component
Providing packet encoding functions for exchanging data with a remote host.
ESPPreferences * global_preferences
esphome::optional< esphome::climate::ClimateFanMode > fan_mode
esphome::optional< esphome::climate::ClimateSwingMode > swing_mode
esphome::optional< esphome::climate::ClimateMode > mode
esphome::optional< esphome::climate::ClimatePreset > preset
esphome::optional< float > target_temperature