#pragma once #include "esphome/core/component.h" #include "esphome/components/climate/climate.h" #include "esphome/components/remote_transmitter/remote_transmitter.h" namespace esphome { namespace gree_ir { class GreeIR : public climate::Climate, public Component { public: void set_transmitter(remote_transmitter::RemoteTransmitterComponent *tx) { this->transmitter_ = tx; } void setup() override { this->mode = climate::CLIMATE_MODE_OFF; this->target_temperature = 24; this->publish_state(); } climate::ClimateTraits traits() override { auto traits = climate::ClimateTraits(); traits.set_supported_modes({ climate::CLIMATE_MODE_OFF, climate::CLIMATE_MODE_COOL, climate::CLIMATE_MODE_HEAT, climate::CLIMATE_MODE_FAN_ONLY, }); traits.set_visual_min_temperature(16); traits.set_visual_max_temperature(30); traits.set_visual_temperature_step(1); return traits; } void control(const climate::ClimateCall &call) override { if (call.get_mode().has_value()) this->mode = *call.get_mode(); if (call.get_target_temperature().has_value()) this->target_temperature = *call.get_target_temperature(); this->transmit_state_(); this->publish_state(); } protected: remote_transmitter::RemoteTransmitterComponent *transmitter_{nullptr}; void transmit_state_() { uint8_t b[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t mode_byte, b2, b1_0; switch (this->mode) { case climate::CLIMATE_MODE_COOL: mode_byte = 0x19; b2 = 0x60; b1_0 = 0x06; break; case climate::CLIMATE_MODE_HEAT: mode_byte = 0x4C; b2 = 0x40; b1_0 = 0x01; break; case climate::CLIMATE_MODE_FAN_ONLY: mode_byte = 0x1B; b2 = 0x60; b1_0 = 0x02; break; default: mode_byte = 0x44; b2 = 0x00; b1_0 = 0x01; break; } int temp = (int) this->target_temperature; if (temp < 16) temp = 16; if (temp > 30) temp = 30; uint8_t t = (this->mode == climate::CLIMATE_MODE_OFF) ? 0x0A : (uint8_t)(temp - 16); b[0] = mode_byte; b[1] = t; b[2] = b2; b[3] = 0x50; b[4] = b1_0; b[5] = 0x00; b[6] = 0x00; uint8_t cs = ((b[0] & 0xF) + (b[1] & 0xF) + (b[2] & 0xF) + (b[3] & 0xF) + ((b[4] >> 4) & 0xF) + ((b[5] >> 4) & 0xF) + ((b[6] >> 4) & 0xF) + 0x0A) & 0xF; b[7] = (cs << 4) & 0xF0; auto transmit = this->transmitter_->transmit(); auto *data = transmit.get_data(); data->set_carrier_frequency(38000); const int MK = 677, S0 = 553, S1 = 1630, GAP = 19960; data->mark(9030); data->space(4460); for (int by = 0; by < 4; by++) for (int bit = 0; bit < 8; bit++) { data->mark(MK); data->space(((b[by] >> bit) & 1) ? S1 : S0); } const int foot[3] = {0, 1, 0}; for (int i = 0; i < 3; i++) { data->mark(MK); data->space(foot[i] ? S1 : S0); } data->mark(MK); data->space(GAP); for (int by = 4; by < 8; by++) for (int bit = 0; bit < 8; bit++) { data->mark(MK); data->space(((b[by] >> bit) & 1) ? S1 : S0); } data->mark(MK); transmit.perform(); } }; } // namespace gree_ir } // namespace