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 display_status_(true),
57 force_send_control_(false),
58 forced_request_status_(false),
59 reset_protocol_request_(false),
60 send_wifi_signal_(true),
114 static uint8_t wifi_status_data[4] = {0x00, 0x00, 0x00, 0x00};
116 wifi_status_data[1] = 0;
118 wifi_status_data[3] = uint8_t((128 + rssi) / 1.28f);
119 ESP_LOGD(TAG,
"WiFi signal is: %ddBm => %d%%", rssi, wifi_status_data[3]);
121 ESP_LOGD(TAG,
"WiFi is not connected");
122 wifi_status_data[1] = 1;
123 wifi_status_data[3] = 0;
125 return haier_protocol::HaierMessage(haier_protocol::FrameType::REPORT_NETWORK_STATUS, wifi_status_data,
126 sizeof(wifi_status_data));
179 if (!presets.empty())
194 haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type,
195 haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type,
197 haier_protocol::HandlerError result = haier_protocol::HandlerError::HANDLER_OK;
198 if ((expected_request_message_type != haier_protocol::FrameType::UNKNOWN_FRAME_TYPE) &&
199 (request_message_type != expected_request_message_type))
200 result = haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
201 if ((expected_answer_message_type != haier_protocol::FrameType::UNKNOWN_FRAME_TYPE) &&
202 (answer_message_type != expected_answer_message_type))
203 result = haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
206 result = haier_protocol::HandlerError::UNEXPECTED_MESSAGE;
207 if (answer_message_type == haier_protocol::FrameType::INVALID)
208 result = haier_protocol::HandlerError::INVALID_ANSWER;
213 haier_protocol::FrameType request_type, haier_protocol::FrameType message_type,
const uint8_t *data,
215 haier_protocol::HandlerError result =
216 this->
answer_preprocess_(request_type, haier_protocol::FrameType::REPORT_NETWORK_STATUS, message_type,
223 ESP_LOGW(TAG,
"Answer timeout for command %02X, phase %s", (uint8_t) request_type,
230 return haier_protocol::HandlerError::HANDLER_OK;
234 ESP_LOGI(TAG,
"Haier initialization...");
245 LOG_CLIMATE(
"",
"Haier Climate",
this);
246 ESP_LOGCONFIG(TAG,
" Device communication status: %s", this->
valid_connection() ?
"established" :
"none");
250 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
252 COMMUNICATION_TIMEOUT_MS) ||
260 ESP_LOGW(TAG,
"Protocol reset requested");
262 ESP_LOGW(TAG,
"Communication timeout, reseting protocol");
278 ESP_LOGV(TAG,
"Control packet is pending...");
322 ESP_LOGW(TAG,
"Unsupported action: %d", (uint8_t) this->
action_request_.value().action);
333 ESP_LOGD(
"Control",
"Control call");
335 ESP_LOGW(TAG,
"Can't send control packet, first poll answer not received");
339 ESP_LOGW(TAG,
"New settings come faster then processed!");
366 std::chrono::milliseconds interval) {
367 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.
The fan mode is set to Low.
constexpr size_t COMMUNICATION_TIMEOUT_MS
ClimateSwingMode swing_mode
The active swing mode of the climate device.
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
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, ...)
bool get_display_state() const
void add_supported_preset(ClimatePreset preset)
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.
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)
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.
const optional< ClimateFanMode > & get_fan_mode() const
virtual void process_protocol_reset()
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.
virtual void initialization()
The climate device only has the fan enabled, no heating or cooling is taking place.
bool is_control_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
CallbackManager< void(const char *, size_t)> status_message_callback_
void add_supported_mode(ClimateMode mode)
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