From 196ea2eb99a5c3340572812f5b16cb553d898826 Mon Sep 17 00:00:00 2001 From: Djordje <6750655+DjordjeMandic@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:08:49 +0100 Subject: [PATCH] [midea] [midea_ir] Add Fahrenheit support to follow me ir data class Bit 5 of idx 2 is used for Fahrenheit indication. There is no known actual max value for temp in Fahrenheit. see https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L117 Added min and max values for more readable code used for value clamping. --- esphome/components/midea/ir_transmitter.h | 39 ++++++++++++++++++++--- esphome/components/midea_ir/midea_data.h | 39 ++++++++++++++++++++--- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/esphome/components/midea/ir_transmitter.h b/esphome/components/midea/ir_transmitter.h index a8b89f9b7b..b0a889fa05 100644 --- a/esphome/components/midea/ir_transmitter.h +++ b/esphome/components/midea/ir_transmitter.h @@ -3,6 +3,7 @@ #ifdef USE_ARDUINO #ifdef USE_REMOTE_TRANSMITTER #include "esphome/components/remote_base/midea_protocol.h" +#include namespace esphome { namespace midea { @@ -16,22 +17,52 @@ class IrFollowMeData : public IrData { IrFollowMeData() : IrData({MIDEA_TYPE_FOLLOW_ME, 0x82, 0x48, 0x7F, 0x1F}) {} // Copy from Base IrFollowMeData(const IrData &data) : IrData(data) {} - // Direct from temperature and beeper values + // Direct from temperature in celsius and beeper values IrFollowMeData(uint8_t temp, bool beeper = false) : IrFollowMeData() { + this->set_fahrenheit(false); + this->set_temp(temp); + this->set_beeper(beeper); + } + // Direct from temperature, fahrenheit and beeper values + IrFollowMeData(uint8_t temp, bool fahrenheit, bool beeper) : IrFollowMeData() { + this->set_fahrenheit(fahrenheit); this->set_temp(temp); this->set_beeper(beeper); } /* TEMPERATURE */ - uint8_t temp() const { return this->get_value_(4) - 1; } - void set_temp(uint8_t val) { this->set_value_(4, std::min(MAX_TEMP, val) + 1); } + uint8_t temp() const { + if (this->fahrenheit()) { + return this->get_value_(4) + 31; + } + return this->get_value_(4) - 1; + } + void set_temp(uint8_t val) { + if (this->fahrenheit()) { + // see https://github.com/esphome/feature-requests/issues/1627#issuecomment-1365639966 + val = std::clamp(val, MIN_TEMP_F, MAX_TEMP_F) - 31; + } else { + val = std::clamp(val, MIN_TEMP_C, MAX_TEMP_C) + 1; + } + this->set_value_(4, val); + } /* BEEPER */ bool beeper() const { return this->get_value_(3, 128); } void set_beeper(bool val) { this->set_mask_(3, val, 128); } + /* FAHRENHEIT */ + bool fahrenheit() const { return this->get_value_(2, 32); } + void set_fahrenheit(bool val) { this->set_mask_(2, val, 32); } + protected: - static const uint8_t MAX_TEMP = 37; + static const uint8_t MIN_TEMP_C = 0; + static const uint8_t MAX_TEMP_C = 37; + + // see https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L116 + static const uint8_t MIN_TEMP_F = 32; + // see https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L117 + static const uint8_t MAX_TEMP_F = 99; }; class IrSpecialData : public IrData { diff --git a/esphome/components/midea_ir/midea_data.h b/esphome/components/midea_ir/midea_data.h index 0f7e24907d..c4685b3b0e 100644 --- a/esphome/components/midea_ir/midea_data.h +++ b/esphome/components/midea_ir/midea_data.h @@ -2,6 +2,7 @@ #include "esphome/components/remote_base/midea_protocol.h" #include "esphome/components/climate/climate_mode.h" +#include namespace esphome { namespace midea_ir { @@ -62,22 +63,52 @@ class FollowMeData : public MideaData { FollowMeData() : MideaData({MIDEA_TYPE_FOLLOW_ME, 0x82, 0x48, 0x7F, 0x1F}) {} // Copy from Base FollowMeData(const MideaData &data) : MideaData(data) {} - // Direct from temperature and beeper values + // Direct from temperature in celsius and beeper values FollowMeData(uint8_t temp, bool beeper = false) : FollowMeData() { + this->set_fahrenheit(false); + this->set_temp(temp); + this->set_beeper(beeper); + } + // Direct from temperature, fahrenheit and beeper values + FollowMeData(uint8_t temp, bool fahrenheit, bool beeper) : FollowMeData() { + this->set_fahrenheit(fahrenheit); this->set_temp(temp); this->set_beeper(beeper); } /* TEMPERATURE */ - uint8_t temp() const { return this->get_value_(4) - 1; } - void set_temp(uint8_t val) { this->set_value_(4, std::min(MAX_TEMP, val) + 1); } + uint8_t temp() const { + if (this->fahrenheit()) { + return this->get_value_(4) + 31; + } + return this->get_value_(4) - 1; + } + void set_temp(uint8_t val) { + if (this->fahrenheit()) { + // see https://github.com/esphome/feature-requests/issues/1627#issuecomment-1365639966 + val = std::clamp(val, MIN_TEMP_F, MAX_TEMP_F) - 31; + } else { + val = std::clamp(val, MIN_TEMP_C, MAX_TEMP_C) + 1; + } + this->set_value_(4, val); + } /* BEEPER */ bool beeper() const { return this->get_value_(3, 128); } void set_beeper(bool value) { this->set_mask_(3, value, 128); } + /* FAHRENHEIT */ + bool fahrenheit() const { return this->get_value_(2, 32); } + void set_fahrenheit(bool val) { this->set_mask_(2, val, 32); } + protected: - static const uint8_t MAX_TEMP = 37; + static const uint8_t MIN_TEMP_C = 0; + static const uint8_t MAX_TEMP_C = 37; + + // see https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L116 + static const uint8_t MIN_TEMP_F = 32; + // see https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L117 + static const uint8_t MAX_TEMP_F = 99; }; class SpecialData : public MideaData {