1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-01 00:08:15 +00:00

Format files with clang-format

This commit is contained in:
Georgi Filipov 2024-12-24 02:12:12 +02:00
parent ccb754c56a
commit 534d4822a0
3 changed files with 390 additions and 393 deletions

View File

@ -11,9 +11,7 @@ samsung_ns = cg.esphome_ns.namespace("climate_ir_samsung")
SamsungClimateIR = samsung_ns.class_("SamsungClimateIR", climate_ir.ClimateIR) SamsungClimateIR = samsung_ns.class_("SamsungClimateIR", climate_ir.ClimateIR)
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
{ {cv.GenerateID(): cv.declare_id(SamsungClimateIR)}
cv.GenerateID(): cv.declare_id(SamsungClimateIR)
}
) )

View File

@ -3,235 +3,233 @@
namespace esphome { namespace esphome {
namespace climate_ir_samsung { namespace climate_ir_samsung {
void SamsungClimateIR::transmit_state() { void SamsungClimateIR::transmit_state() {
if(current_climate_mode != climate::ClimateMode::CLIMATE_MODE_OFF && this->mode == climate::ClimateMode::CLIMATE_MODE_OFF) { if (current_climate_mode != climate::ClimateMode::CLIMATE_MODE_OFF &&
setAndSendPowerState(false); this->mode == climate::ClimateMode::CLIMATE_MODE_OFF) {
return; setAndSendPowerState(false);
} return;
}
if(current_climate_mode == climate::ClimateMode::CLIMATE_MODE_OFF && this->mode != climate::ClimateMode::CLIMATE_MODE_OFF) { if (current_climate_mode == climate::ClimateMode::CLIMATE_MODE_OFF &&
setAndSendPowerState(true); this->mode != climate::ClimateMode::CLIMATE_MODE_OFF) {
} setAndSendPowerState(true);
}
current_climate_mode = this->mode; current_climate_mode = this->mode;
setMode(this->mode); setMode(this->mode);
setTemp(this->target_temperature); setTemp(this->target_temperature);
setSwing(this->swing_mode); setSwing(this->swing_mode);
setFan(this->fan_mode.has_value() ? this->fan_mode.value() : climate::CLIMATE_FAN_AUTO); setFan(this->fan_mode.has_value() ? this->fan_mode.value() : climate::CLIMATE_FAN_AUTO);
send(); send();
}
/// Send the current state of the climate object.
void SamsungClimateIR::send() {
checksum();
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
data->set_carrier_frequency(SAMSUNG_IR_FREQUENCY);
// Header
data->mark(SAMSUNG_AIRCON1_HDR_MARK);
data->space(SAMSUNG_AIRCON1_HDR_SPACE);
for (int i = 0; i < 21; i++) {
if (i == 7 || i == 14) {
data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(SAMSUNG_AIRCON1_MSG_SPACE);
data->mark(SAMSUNG_AIRCON1_HDR_MARK);
data->space(SAMSUNG_AIRCON1_HDR_SPACE);
} }
/// Send the current state of the climate object. uint8_t sendByte = protocol.raw[i];
void SamsungClimateIR::send() {
checksum();
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
data->set_carrier_frequency(SAMSUNG_IR_FREQUENCY);
// Header
data->mark(SAMSUNG_AIRCON1_HDR_MARK);
data->space(SAMSUNG_AIRCON1_HDR_SPACE);
for (int i = 0; i < 21; i++)
{
if (i == 7 || i == 14)
{
data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(SAMSUNG_AIRCON1_MSG_SPACE);
data->mark(SAMSUNG_AIRCON1_HDR_MARK);
data->space(SAMSUNG_AIRCON1_HDR_SPACE);
}
uint8_t sendByte = protocol.raw[i];
for (int y = 0; y < 8; y++)
{
if (sendByte & 0x01)
{
// ESP_LOGI(TAG, "For Y %d 1", y);
data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(SAMSUNG_AIRCON1_ONE_SPACE);
}
else
{
// ESP_LOGI(TAG, "For Y %d 0", y);
data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(SAMSUNG_AIRCON1_ZERO_SPACE);
}
sendByte >>= 1;
}
}
for (int y = 0; y < 8; y++) {
if (sendByte & 0x01) {
// ESP_LOGI(TAG, "For Y %d 1", y);
data->mark(SAMSUNG_AIRCON1_BIT_MARK); data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(0); data->space(SAMSUNG_AIRCON1_ONE_SPACE);
} else {
// ESP_LOGI(TAG, "For Y %d 0", y);
data->mark(SAMSUNG_AIRCON1_BIT_MARK);
data->space(SAMSUNG_AIRCON1_ZERO_SPACE);
}
transmit.perform(); sendByte >>= 1;
} }
}
/// Set the vertical swing setting of the A/C. data->mark(SAMSUNG_AIRCON1_BIT_MARK);
void SamsungClimateIR::setSwing(const climate::ClimateSwingMode swingMode) { data->space(0);
switch (swingMode) {
case climate::ClimateSwingMode::CLIMATE_SWING_BOTH:
protocol.Swing = kSamsungAcSwingBoth;
break;
case climate::ClimateSwingMode::CLIMATE_SWING_HORIZONTAL:
protocol.Swing = kSamsungAcSwingH;;
break;
case climate::ClimateSwingMode::CLIMATE_SWING_VERTICAL:
protocol.Swing = kSamsungAcSwingV;;
break;
case climate::ClimateSwingMode::CLIMATE_SWING_OFF:
default:
protocol.Swing = kSamsungAcSwingOff;;
break;
}
}
/// Set the operating mode of the A/C. transmit.perform();
/// @param[in] climateMode The desired operating mode. }
void SamsungClimateIR::setMode(const climate::ClimateMode climateMode) {
switch (climateMode) {
case climate::ClimateMode::CLIMATE_MODE_HEAT:
protocol.Mode = kSamsungAcHeat;
break;
case climate::ClimateMode::CLIMATE_MODE_DRY:
protocol.Mode = kSamsungAcDry;
break;
case climate::ClimateMode::CLIMATE_MODE_COOL:
protocol.Mode = kSamsungAcCool;
break;
case climate::ClimateMode::CLIMATE_MODE_FAN_ONLY:
protocol.Mode = kSamsungAcFan;
break;
case climate::ClimateMode::CLIMATE_MODE_HEAT_COOL:
case climate::ClimateMode::CLIMATE_MODE_AUTO:
default:
protocol.Mode = kSamsungAcAuto;
break;
}
}
/// Set the temperature. /// Set the vertical swing setting of the A/C.
/// @param[in] temp The temperature in degrees celsius. void SamsungClimateIR::setSwing(const climate::ClimateSwingMode swingMode) {
void SamsungClimateIR::setTemp(const uint8_t temp) { switch (swingMode) {
uint8_t newtemp = std::max(kSamsungAcMinTemp, temp); case climate::ClimateSwingMode::CLIMATE_SWING_BOTH:
newtemp = std::min(kSamsungAcMaxTemp, newtemp); protocol.Swing = kSamsungAcSwingBoth;
protocol.Temp = newtemp - kSamsungAcMinTemp; break;
} case climate::ClimateSwingMode::CLIMATE_SWING_HORIZONTAL:
protocol.Swing = kSamsungAcSwingH;
;
break;
case climate::ClimateSwingMode::CLIMATE_SWING_VERTICAL:
protocol.Swing = kSamsungAcSwingV;
;
break;
case climate::ClimateSwingMode::CLIMATE_SWING_OFF:
default:
protocol.Swing = kSamsungAcSwingOff;
;
break;
}
}
/// Change the AC power state. /// Set the operating mode of the A/C.
/// @param[in] on true, the AC is on. false, the AC is off. /// @param[in] climateMode The desired operating mode.
void SamsungClimateIR::setAndSendPowerState(const bool on) { void SamsungClimateIR::setMode(const climate::ClimateMode climateMode) {
switch (climateMode) {
case climate::ClimateMode::CLIMATE_MODE_HEAT:
protocol.Mode = kSamsungAcHeat;
break;
case climate::ClimateMode::CLIMATE_MODE_DRY:
protocol.Mode = kSamsungAcDry;
break;
case climate::ClimateMode::CLIMATE_MODE_COOL:
protocol.Mode = kSamsungAcCool;
break;
case climate::ClimateMode::CLIMATE_MODE_FAN_ONLY:
protocol.Mode = kSamsungAcFan;
break;
case climate::ClimateMode::CLIMATE_MODE_HEAT_COOL:
case climate::ClimateMode::CLIMATE_MODE_AUTO:
default:
protocol.Mode = kSamsungAcAuto;
break;
}
}
static const uint8_t kOn[kSamsungAcExtendedStateLength] = { /// Set the temperature.
0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, /// @param[in] temp The temperature in degrees celsius.
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00, void SamsungClimateIR::setTemp(const uint8_t temp) {
0x01, 0xE2, 0xFE, 0x71, 0x80, 0x11, 0xF0}; uint8_t newtemp = std::max(kSamsungAcMinTemp, temp);
newtemp = std::min(kSamsungAcMaxTemp, newtemp);
protocol.Temp = newtemp - kSamsungAcMinTemp;
}
static const uint8_t kOff[kSamsungAcExtendedStateLength] = { /// Change the AC power state.
0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0, /// @param[in] on true, the AC is on. false, the AC is off.
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00, void SamsungClimateIR::setAndSendPowerState(const bool on) {
0x01, 0x02, 0xFF, 0x71, 0x80, 0x11, 0xC0}; static const uint8_t kOn[kSamsungAcExtendedStateLength] = {0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x01, 0xE2, 0xFE, 0x71, 0x80, 0x11, 0xF0};
std::memcpy(protocol.raw, on ? kOn : kOff, kSamsungAcExtendedStateLength); static const uint8_t kOff[kSamsungAcExtendedStateLength] = {0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0xFF, 0x71, 0x80, 0x11, 0xC0};
send(); std::memcpy(protocol.raw, on ? kOn : kOff, kSamsungAcExtendedStateLength);
std::memcpy(protocol.raw, kReset, kSamsungAcExtendedStateLength); send();
}
/// Set the fan speed. std::memcpy(protocol.raw, kReset, kSamsungAcExtendedStateLength);
void SamsungClimateIR::setFan(const climate::ClimateFanMode fanMode) { }
switch (fanMode) {
case climate::ClimateFanMode::CLIMATE_FAN_LOW:
protocol.Fan = kSamsungAcFanAuto;
break;
case climate::ClimateFanMode::CLIMATE_FAN_MEDIUM:
protocol.Fan = kSamsungAcFanMed;
break;
case climate::ClimateFanMode::CLIMATE_FAN_HIGH:
protocol.Fan = kSamsungAcFanHigh;
break;
case climate::ClimateFanMode::CLIMATE_FAN_AUTO:
default:
protocol.Fan = kSamsungAcFanAuto;
break;
}
}
/// Calculate the checksum for a given state section. /// Set the fan speed.
/// @param[in] section The array to calc the checksum of. void SamsungClimateIR::setFan(const climate::ClimateFanMode fanMode) {
/// @return The calculated checksum value. switch (fanMode) {
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1538#issuecomment-894645947 case climate::ClimateFanMode::CLIMATE_FAN_LOW:
uint8_t SamsungClimateIR::calcSectionChecksum(const uint8_t *section) { protocol.Fan = kSamsungAcFanAuto;
uint8_t sum = 0; break;
case climate::ClimateFanMode::CLIMATE_FAN_MEDIUM:
protocol.Fan = kSamsungAcFanMed;
break;
case climate::ClimateFanMode::CLIMATE_FAN_HIGH:
protocol.Fan = kSamsungAcFanHigh;
break;
case climate::ClimateFanMode::CLIMATE_FAN_AUTO:
default:
protocol.Fan = kSamsungAcFanAuto;
break;
}
}
sum += countBits(*section, 8); // Include the entire first byte /// Calculate the checksum for a given state section.
// The lower half of the second byte. /// @param[in] section The array to calc the checksum of.
sum += countBits(GETBITS8(*(section + 1), kLowNibble, kNibbleSize), 8); /// @return The calculated checksum value.
// The upper half of the third byte. /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1538#issuecomment-894645947
sum += countBits(GETBITS8(*(section + 2), kHighNibble, kNibbleSize), 8); uint8_t SamsungClimateIR::calcSectionChecksum(const uint8_t *section) {
// The next 4 bytes. uint8_t sum = 0;
sum += countBits(section + 3, 4);
// Bitwise invert the result.
return sum ^ UINT8_MAX;
}
/// Update the checksum for the internal state. sum += countBits(*section, 8); // Include the entire first byte
void SamsungClimateIR::checksum(void) { // The lower half of the second byte.
uint8_t sectionsum = calcSectionChecksum(protocol.raw); sum += countBits(GETBITS8(*(section + 1), kLowNibble, kNibbleSize), 8);
protocol.Sum1Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); // The upper half of the third byte.
protocol.Sum1Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); sum += countBits(GETBITS8(*(section + 2), kHighNibble, kNibbleSize), 8);
sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength); // The next 4 bytes.
protocol.Sum2Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); sum += countBits(section + 3, 4);
protocol.Sum2Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); // Bitwise invert the result.
sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength * 2); return sum ^ UINT8_MAX;
protocol.Sum3Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); }
protocol.Sum3Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize);
}
/// Count the number of bits of a certain type in an array. /// Update the checksum for the internal state.
/// @param[in] start A ptr to the start of the byte array to calculate over. void SamsungClimateIR::checksum(void) {
/// @param[in] length How many bytes to use in the calculation. uint8_t sectionsum = calcSectionChecksum(protocol.raw);
/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. protocol.Sum1Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize);
/// @param[in] init Starting value of the calculation to use. (Default is 0) protocol.Sum1Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize);
/// @return The nr. of bits found of the given type found in the array. sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength);
uint16_t SamsungClimateIR::countBits(const uint8_t * const start, const uint16_t length, const bool ones, const uint16_t init) { protocol.Sum2Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize);
uint16_t count = init; protocol.Sum2Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize);
sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength * 2);
protocol.Sum3Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize);
protocol.Sum3Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize);
}
for (uint16_t offset = 0; offset < length; offset++) /// Count the number of bits of a certain type in an array.
for (uint8_t currentbyte = *(start + offset); currentbyte; currentbyte >>= 1) /// @param[in] start A ptr to the start of the byte array to calculate over.
if (currentbyte & 1) count++; /// @param[in] length How many bytes to use in the calculation.
/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s.
/// @param[in] init Starting value of the calculation to use. (Default is 0)
/// @return The nr. of bits found of the given type found in the array.
uint16_t SamsungClimateIR::countBits(const uint8_t *const start, const uint16_t length, const bool ones,
const uint16_t init) {
uint16_t count = init;
if (ones || length == 0) for (uint16_t offset = 0; offset < length; offset++)
return count; for (uint8_t currentbyte = *(start + offset); currentbyte; currentbyte >>= 1)
else if (currentbyte & 1)
return (length * 8) - count; count++;
}
/// Count the number of bits of a certain type in an Integer. if (ones || length == 0)
/// @param[in] data The value you want bits counted for. Starting from the LSB. return count;
/// @param[in] length How many bits to use in the calculation? Starts at the LSB else
/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. return (length * 8) - count;
/// @param[in] init Starting value of the calculation to use. (Default is 0) }
/// @return The nr. of bits found of the given type found in the Integer.
uint16_t SamsungClimateIR::countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init) {
uint16_t count = init;
uint8_t bitsSoFar = length;
for (uint64_t remainder = data; remainder && bitsSoFar; remainder >>= 1, bitsSoFar--) /// Count the number of bits of a certain type in an Integer.
if (remainder & 1) count++; /// @param[in] data The value you want bits counted for. Starting from the LSB.
/// @param[in] length How many bits to use in the calculation? Starts at the LSB
/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s.
/// @param[in] init Starting value of the calculation to use. (Default is 0)
/// @return The nr. of bits found of the given type found in the Integer.
uint16_t SamsungClimateIR::countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init) {
uint16_t count = init;
uint8_t bitsSoFar = length;
if (ones || length == 0) for (uint64_t remainder = data; remainder && bitsSoFar; remainder >>= 1, bitsSoFar--)
return count; if (remainder & 1)
else count++;
return length - count;
} if (ones || length == 0)
}} return count;
else
return length - count;
}
} // namespace climate_ir_samsung
} // namespace esphome

View File

@ -3,207 +3,208 @@
#include "esphome/components/climate/climate_mode.h" #include "esphome/components/climate/climate_mode.h"
#include "esphome/components/climate_ir/climate_ir.h" #include "esphome/components/climate_ir/climate_ir.h"
namespace esphome { namespace esphome {
namespace climate_ir_samsung { namespace climate_ir_samsung {
#define GETBITS8(data, offset, size) \ #define GETBITS8(data, offset, size) (((data) & (((uint8_t) UINT8_MAX >> (8 - (size))) << (offset))) >> (offset))
(((data) & (((uint8_t)UINT8_MAX >> (8 - (size))) << (offset))) >> (offset))
static const char *const TAG = "samsung.climate"; static const char *const TAG = "samsung.climate";
static const uint32_t SAMSUNG_IR_FREQUENCY = 38000; static const uint32_t SAMSUNG_IR_FREQUENCY = 38000;
static const int SAMSUNG_AIRCON1_HDR_MARK = 3000; static const int SAMSUNG_AIRCON1_HDR_MARK = 3000;
static const int SAMSUNG_AIRCON1_HDR_SPACE = 9000; static const int SAMSUNG_AIRCON1_HDR_SPACE = 9000;
static const int SAMSUNG_AIRCON1_BIT_MARK = 500; static const int SAMSUNG_AIRCON1_BIT_MARK = 500;
static const int SAMSUNG_AIRCON1_ONE_SPACE = 1500; static const int SAMSUNG_AIRCON1_ONE_SPACE = 1500;
static const int SAMSUNG_AIRCON1_ZERO_SPACE = 500; static const int SAMSUNG_AIRCON1_ZERO_SPACE = 500;
static const int SAMSUNG_AIRCON1_MSG_SPACE = 2000; static const int SAMSUNG_AIRCON1_MSG_SPACE = 2000;
const uint16_t kSamsungAcExtendedStateLength = 21; const uint16_t kSamsungAcExtendedStateLength = 21;
const uint16_t kSamsungAcSectionLength = 7; const uint16_t kSamsungAcSectionLength = 7;
// Temperature // Temperature
const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000 const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000 const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000 const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
// Mode // Mode
const uint8_t kSamsungAcAuto = 0; const uint8_t kSamsungAcAuto = 0;
const uint8_t kSamsungAcCool = 1; const uint8_t kSamsungAcCool = 1;
const uint8_t kSamsungAcDry = 2; const uint8_t kSamsungAcDry = 2;
const uint8_t kSamsungAcFan = 3; const uint8_t kSamsungAcFan = 3;
const uint8_t kSamsungAcHeat = 4; const uint8_t kSamsungAcHeat = 4;
// Fan // Fan
const uint8_t kSamsungAcFanAuto = 0; const uint8_t kSamsungAcFanAuto = 0;
const uint8_t kSamsungAcFanLow = 2; const uint8_t kSamsungAcFanLow = 2;
const uint8_t kSamsungAcFanMed = 4; const uint8_t kSamsungAcFanMed = 4;
const uint8_t kSamsungAcFanHigh = 5; const uint8_t kSamsungAcFanHigh = 5;
const uint8_t kSamsungAcFanAuto2 = 6; const uint8_t kSamsungAcFanAuto2 = 6;
const uint8_t kSamsungAcFanTurbo = 7; const uint8_t kSamsungAcFanTurbo = 7;
// Swing // Swing
const uint8_t kSamsungAcSwingV = 0b010; const uint8_t kSamsungAcSwingV = 0b010;
const uint8_t kSamsungAcSwingH = 0b011; const uint8_t kSamsungAcSwingH = 0b011;
const uint8_t kSamsungAcSwingBoth = 0b100; const uint8_t kSamsungAcSwingBoth = 0b100;
const uint8_t kSamsungAcSwingOff = 0b111; const uint8_t kSamsungAcSwingOff = 0b111;
// Power // Power
const uint8_t kNibbleSize = 4; const uint8_t kNibbleSize = 4;
const uint8_t kLowNibble = 0; const uint8_t kLowNibble = 0;
const uint8_t kHighNibble = 4; const uint8_t kHighNibble = 4;
const uint8_t kModeBitsSize = 3; const uint8_t kModeBitsSize = 3;
// static const uint8_t kReset[kSamsungAcExtendedStateLength] = {0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x02, 0xAE, 0x71, 0x00, 0x15, 0xF0}; // static const uint8_t kReset[kSamsungAcExtendedStateLength] = {0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x02,
static const uint8_t kReset[kSamsungAcExtendedStateLength] = { // 0xAE, 0x71, 0x00, 0x15, 0xF0};
0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, static const uint8_t kReset[kSamsungAcExtendedStateLength] = {0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
0x01, 0x02, 0xAE, 0x71, 0x00, 0x15, 0xF0}; 0x01, 0x02, 0xAE, 0x71, 0x00, 0x15, 0xF0};
/// Native representation of a Samsung A/C message. /// Native representation of a Samsung A/C message.
union SamsungProtocol { union SamsungProtocol {
uint8_t raw[kSamsungAcExtendedStateLength]; ///< State in code form. uint8_t raw[kSamsungAcExtendedStateLength]; ///< State in code form.
struct { // Standard message map struct { // Standard message map
// Byte 0 // Byte 0
uint8_t :8; uint8_t : 8;
// Byte 1 // Byte 1
uint8_t :4; uint8_t : 4;
uint8_t :4; // Sum1Lower uint8_t : 4; // Sum1Lower
// Byte 2 // Byte 2
uint8_t :4; // Sum1Upper uint8_t : 4; // Sum1Upper
uint8_t :4; uint8_t : 4;
// Byte 3 // Byte 3
uint8_t :8; uint8_t : 8;
// Byte 4 // Byte 4
uint8_t :8; uint8_t : 8;
// Byte 5 // Byte 5
uint8_t :4; uint8_t : 4;
uint8_t Sleep5 :1; uint8_t Sleep5 : 1;
uint8_t Quiet :1; uint8_t Quiet : 1;
uint8_t :2; uint8_t : 2;
// Byte 6 // Byte 6
uint8_t :4; uint8_t : 4;
uint8_t Power1 :2; uint8_t Power1 : 2;
uint8_t :2; uint8_t : 2;
// Byte 7 // Byte 7
uint8_t :8; uint8_t : 8;
// Byte 8 // Byte 8
uint8_t :4; uint8_t : 4;
uint8_t :4; // Sum2Lower uint8_t : 4; // Sum2Lower
// Byte 9 // Byte 9
uint8_t :4; // Sum1Upper uint8_t : 4; // Sum1Upper
uint8_t Swing :3; uint8_t Swing : 3;
uint8_t :1; uint8_t : 1;
// Byte 10 // Byte 10
uint8_t :1; uint8_t : 1;
uint8_t FanSpecial :3; // Powerful, Breeze/WindFree, Econo uint8_t FanSpecial : 3; // Powerful, Breeze/WindFree, Econo
uint8_t Display :1; uint8_t Display : 1;
uint8_t :2; uint8_t : 2;
uint8_t CleanToggle10 :1; uint8_t CleanToggle10 : 1;
// Byte 11 // Byte 11
uint8_t Ion :1; uint8_t Ion : 1;
uint8_t CleanToggle11 :1; uint8_t CleanToggle11 : 1;
uint8_t :2; uint8_t : 2;
uint8_t Temp :4; uint8_t Temp : 4;
// Byte 12 // Byte 12
uint8_t :1; uint8_t : 1;
uint8_t Fan :3; uint8_t Fan : 3;
uint8_t Mode :3; uint8_t Mode : 3;
uint8_t :1; uint8_t : 1;
// Byte 13 // Byte 13
uint8_t :2; uint8_t : 2;
uint8_t BeepToggle :1; uint8_t BeepToggle : 1;
uint8_t :1; uint8_t : 1;
uint8_t Power2 :2; uint8_t Power2 : 2;
uint8_t :2; uint8_t : 2;
}; };
struct { // Extended message map struct { // Extended message map
// 1st Section // 1st Section
// Byte 0 // Byte 0
uint8_t :8; uint8_t : 8;
// Byte 1 // Byte 1
uint8_t :4; uint8_t : 4;
uint8_t Sum1Lower :4; uint8_t Sum1Lower : 4;
// Byte 2 // Byte 2
uint8_t Sum1Upper :4; uint8_t Sum1Upper : 4;
uint8_t :4; uint8_t : 4;
// Byte 3 // Byte 3
uint8_t :8; uint8_t : 8;
// Byte 4 // Byte 4
uint8_t :8; uint8_t : 8;
// Byte 5 // Byte 5
uint8_t :8; uint8_t : 8;
// Byte 6 // Byte 6
uint8_t :8; uint8_t : 8;
// 2nd Section // 2nd Section
// Byte 7 // Byte 7
uint8_t :8; uint8_t : 8;
// Byte 8 // Byte 8
uint8_t :4; uint8_t : 4;
uint8_t Sum2Lower :4; uint8_t Sum2Lower : 4;
// Byte 9 // Byte 9
uint8_t Sum2Upper :4; uint8_t Sum2Upper : 4;
uint8_t OffTimeMins :3; // In units of 10's of mins uint8_t OffTimeMins : 3; // In units of 10's of mins
uint8_t OffTimeHrs1 :1; // LSB of the number of hours. uint8_t OffTimeHrs1 : 1; // LSB of the number of hours.
// Byte 10 // Byte 10
uint8_t OffTimeHrs2 :4; // MSBs of the number of hours. uint8_t OffTimeHrs2 : 4; // MSBs of the number of hours.
uint8_t OnTimeMins :3; // In units of 10's of mins uint8_t OnTimeMins : 3; // In units of 10's of mins
uint8_t OnTimeHrs1 :1; // LSB of the number of hours. uint8_t OnTimeHrs1 : 1; // LSB of the number of hours.
// Byte 11 // Byte 11
uint8_t OnTimeHrs2 :4; // MSBs of the number of hours. uint8_t OnTimeHrs2 : 4; // MSBs of the number of hours.
uint8_t :4; uint8_t : 4;
// Byte 12 // Byte 12
uint8_t OffTimeDay :1; uint8_t OffTimeDay : 1;
uint8_t OnTimerEnable :1; uint8_t OnTimerEnable : 1;
uint8_t OffTimerEnable :1; uint8_t OffTimerEnable : 1;
uint8_t Sleep12 :1; uint8_t Sleep12 : 1;
uint8_t OnTimeDay :1; uint8_t OnTimeDay : 1;
uint8_t :3; uint8_t : 3;
// Byte 13 // Byte 13
uint8_t :8; uint8_t : 8;
// 3rd Section // 3rd Section
// Byte 14 // Byte 14
uint8_t :8; uint8_t : 8;
// Byte 15 // Byte 15
uint8_t :4; uint8_t : 4;
uint8_t Sum3Lower :4; uint8_t Sum3Lower : 4;
// Byte 16 // Byte 16
uint8_t Sum3Upper :4; uint8_t Sum3Upper : 4;
uint8_t :4; uint8_t : 4;
// Byte 17 // Byte 17
uint8_t :8; uint8_t : 8;
// Byte 18 // Byte 18
uint8_t :8; uint8_t : 8;
// Byte 19 // Byte 19
uint8_t :8; uint8_t : 8;
// Byte 20 // Byte 20
uint8_t :8; uint8_t : 8;
}; };
}; };
class SamsungClimateIR : public climate_ir::ClimateIR { class SamsungClimateIR : public climate_ir::ClimateIR {
SamsungProtocol protocol;
climate::ClimateMode current_climate_mode;
SamsungProtocol protocol; public:
climate::ClimateMode current_climate_mode; SamsungClimateIR()
: climate_ir::ClimateIR(kSamsungAcMinTemp, kSamsungAcMaxTemp, 1.0f, true, true,
{climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM,
climate::CLIMATE_FAN_HIGH},
{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL,
climate::CLIMATE_SWING_HORIZONTAL, climate::CLIMATE_SWING_BOTH}) {}
public: SamsungClimateIR() : protected:
climate_ir::ClimateIR( void transmit_state() override;
kSamsungAcMinTemp, kSamsungAcMaxTemp, 1.0f, true, true,
{climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH},
{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_HORIZONTAL, climate::CLIMATE_SWING_BOTH}) { }
protected: void send();
void transmit_state() override; void setSwing(const climate::ClimateSwingMode swingMode);
void setMode(const climate::ClimateMode mode);
void setTemp(const uint8_t temp);
void setAndSendPowerState(const bool on);
void setFan(const climate::ClimateFanMode fanMode);
void send(); void checksum(void);
void setSwing(const climate::ClimateSwingMode swingMode); static uint8_t calcSectionChecksum(const uint8_t *section);
void setMode(const climate::ClimateMode mode); static uint16_t countBits(const uint8_t *const start, const uint16_t length, const bool ones = true,
void setTemp(const uint8_t temp); const uint16_t init = 0);
void setAndSendPowerState(const bool on); static uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones = true, const uint16_t init = 0);
void setFan(const climate::ClimateFanMode fanMode); };
} // namespace climate_ir_samsung
void checksum(void); } // namespace esphome
static uint8_t calcSectionChecksum(const uint8_t *section);
static uint16_t countBits(const uint8_t * const start, const uint16_t length, const bool ones = true, const uint16_t init = 0);
static uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones = true, const uint16_t init = 0);
};
}}