mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 06:33:51 +00:00 
			
		
		
		
	Format files with clang-format
This commit is contained in:
		| @@ -11,9 +11,7 @@ samsung_ns = cg.esphome_ns.namespace("climate_ir_samsung") | ||||
| SamsungClimateIR = samsung_ns.class_("SamsungClimateIR", climate_ir.ClimateIR) | ||||
|  | ||||
| CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( | ||||
|     { | ||||
|         cv.GenerateID(): cv.declare_id(SamsungClimateIR) | ||||
|     } | ||||
|     {cv.GenerateID(): cv.declare_id(SamsungClimateIR)} | ||||
| ) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,235 +3,233 @@ | ||||
| namespace esphome { | ||||
| namespace climate_ir_samsung { | ||||
|  | ||||
|     void SamsungClimateIR::transmit_state() { | ||||
|         if(current_climate_mode != climate::ClimateMode::CLIMATE_MODE_OFF && this->mode == climate::ClimateMode::CLIMATE_MODE_OFF) { | ||||
|             setAndSendPowerState(false); | ||||
|             return; | ||||
|         } | ||||
| void SamsungClimateIR::transmit_state() { | ||||
|   if (current_climate_mode != climate::ClimateMode::CLIMATE_MODE_OFF && | ||||
|       this->mode == climate::ClimateMode::CLIMATE_MODE_OFF) { | ||||
|     setAndSendPowerState(false); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|         if(current_climate_mode == climate::ClimateMode::CLIMATE_MODE_OFF && this->mode != climate::ClimateMode::CLIMATE_MODE_OFF) { | ||||
|             setAndSendPowerState(true); | ||||
|         } | ||||
|   if (current_climate_mode == climate::ClimateMode::CLIMATE_MODE_OFF && | ||||
|       this->mode != climate::ClimateMode::CLIMATE_MODE_OFF) { | ||||
|     setAndSendPowerState(true); | ||||
|   } | ||||
|  | ||||
|         current_climate_mode = this->mode; | ||||
|   current_climate_mode = this->mode; | ||||
|  | ||||
|         setMode(this->mode); | ||||
|         setTemp(this->target_temperature); | ||||
|         setSwing(this->swing_mode); | ||||
|         setFan(this->fan_mode.has_value() ? this->fan_mode.value() : climate::CLIMATE_FAN_AUTO); | ||||
|   setMode(this->mode); | ||||
|   setTemp(this->target_temperature); | ||||
|   setSwing(this->swing_mode); | ||||
|   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. | ||||
|     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; | ||||
|             } | ||||
|         } | ||||
|     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(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. | ||||
|     void SamsungClimateIR::setSwing(const climate::ClimateSwingMode swingMode) { | ||||
|         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; | ||||
|         } | ||||
|     } | ||||
|   data->mark(SAMSUNG_AIRCON1_BIT_MARK); | ||||
|   data->space(0); | ||||
|  | ||||
|     /// Set the operating mode of the A/C. | ||||
|     /// @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; | ||||
|         } | ||||
|     } | ||||
|   transmit.perform(); | ||||
| } | ||||
|  | ||||
|     /// Set the temperature. | ||||
|     /// @param[in] temp The temperature in degrees celsius. | ||||
|     void SamsungClimateIR::setTemp(const uint8_t temp) { | ||||
|         uint8_t newtemp = std::max(kSamsungAcMinTemp, temp); | ||||
|         newtemp = std::min(kSamsungAcMaxTemp, newtemp); | ||||
|         protocol.Temp = newtemp - kSamsungAcMinTemp; | ||||
|     } | ||||
| /// Set the vertical swing setting of the A/C. | ||||
| void SamsungClimateIR::setSwing(const climate::ClimateSwingMode swingMode) { | ||||
|   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; | ||||
|   } | ||||
| } | ||||
|  | ||||
|     /// Change the AC power state. | ||||
|     /// @param[in] on true, the AC is on. false, the AC is off. | ||||
|     void SamsungClimateIR::setAndSendPowerState(const bool on) { | ||||
| /// Set the operating mode of the A/C. | ||||
| /// @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; | ||||
|   } | ||||
| } | ||||
|  | ||||
|         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}; | ||||
| /// Set the temperature. | ||||
| /// @param[in] temp The temperature in degrees celsius. | ||||
| void SamsungClimateIR::setTemp(const uint8_t temp) { | ||||
|   uint8_t newtemp = std::max(kSamsungAcMinTemp, temp); | ||||
|   newtemp = std::min(kSamsungAcMaxTemp, newtemp); | ||||
|   protocol.Temp = newtemp - kSamsungAcMinTemp; | ||||
| } | ||||
|  | ||||
|         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}; | ||||
| /// Change the AC power state. | ||||
| /// @param[in] on true, the AC is on. false, the AC is off. | ||||
| void SamsungClimateIR::setAndSendPowerState(const bool on) { | ||||
|   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. | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
|   std::memcpy(protocol.raw, kReset, kSamsungAcExtendedStateLength); | ||||
| } | ||||
|  | ||||
|     /// Calculate the checksum for a given state section. | ||||
|     /// @param[in] section The array to calc the checksum of. | ||||
|     /// @return The calculated checksum value. | ||||
|     /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1538#issuecomment-894645947 | ||||
|     uint8_t SamsungClimateIR::calcSectionChecksum(const uint8_t *section) { | ||||
|         uint8_t sum = 0; | ||||
| /// Set the fan speed. | ||||
| 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; | ||||
|   } | ||||
| } | ||||
|  | ||||
|         sum += countBits(*section, 8);  // Include the entire first byte | ||||
|         // The lower half of the second byte. | ||||
|         sum += countBits(GETBITS8(*(section + 1), kLowNibble, kNibbleSize), 8); | ||||
|         // The upper half of the third byte. | ||||
|         sum += countBits(GETBITS8(*(section + 2), kHighNibble, kNibbleSize), 8); | ||||
|         // The next 4 bytes. | ||||
|         sum += countBits(section + 3, 4); | ||||
|         // Bitwise invert the result. | ||||
|         return sum ^ UINT8_MAX; | ||||
|     } | ||||
| /// Calculate the checksum for a given state section. | ||||
| /// @param[in] section The array to calc the checksum of. | ||||
| /// @return The calculated checksum value. | ||||
| /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1538#issuecomment-894645947 | ||||
| uint8_t SamsungClimateIR::calcSectionChecksum(const uint8_t *section) { | ||||
|   uint8_t sum = 0; | ||||
|  | ||||
|     /// Update the checksum for the internal state. | ||||
|     void SamsungClimateIR::checksum(void) { | ||||
|         uint8_t sectionsum = calcSectionChecksum(protocol.raw); | ||||
|         protocol.Sum1Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); | ||||
|         protocol.Sum1Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); | ||||
|         sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength); | ||||
|         protocol.Sum2Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); | ||||
|         protocol.Sum2Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); | ||||
|         sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength * 2); | ||||
|         protocol.Sum3Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); | ||||
|         protocol.Sum3Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); | ||||
|     } | ||||
|   sum += countBits(*section, 8);  // Include the entire first byte | ||||
|   // The lower half of the second byte. | ||||
|   sum += countBits(GETBITS8(*(section + 1), kLowNibble, kNibbleSize), 8); | ||||
|   // The upper half of the third byte. | ||||
|   sum += countBits(GETBITS8(*(section + 2), kHighNibble, kNibbleSize), 8); | ||||
|   // The next 4 bytes. | ||||
|   sum += countBits(section + 3, 4); | ||||
|   // Bitwise invert the result. | ||||
|   return sum ^ UINT8_MAX; | ||||
| } | ||||
|  | ||||
|     /// Count the number of bits of a certain type in an array. | ||||
|     /// @param[in] start A ptr to the start of the byte array to calculate over. | ||||
|     /// @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; | ||||
| /// Update the checksum for the internal state. | ||||
| void SamsungClimateIR::checksum(void) { | ||||
|   uint8_t sectionsum = calcSectionChecksum(protocol.raw); | ||||
|   protocol.Sum1Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); | ||||
|   protocol.Sum1Lower = GETBITS8(sectionsum, kLowNibble, kNibbleSize); | ||||
|   sectionsum = calcSectionChecksum(protocol.raw + kSamsungAcSectionLength); | ||||
|   protocol.Sum2Upper = GETBITS8(sectionsum, kHighNibble, kNibbleSize); | ||||
|   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++) | ||||
|             for (uint8_t currentbyte = *(start + offset); currentbyte; currentbyte >>= 1) | ||||
|                 if (currentbyte & 1) count++; | ||||
| /// Count the number of bits of a certain type in an array. | ||||
| /// @param[in] start A ptr to the start of the byte array to calculate over. | ||||
| /// @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) | ||||
|             return count; | ||||
|         else | ||||
|             return (length * 8) - count; | ||||
|     } | ||||
|   for (uint16_t offset = 0; offset < length; offset++) | ||||
|     for (uint8_t currentbyte = *(start + offset); currentbyte; currentbyte >>= 1) | ||||
|       if (currentbyte & 1) | ||||
|         count++; | ||||
|  | ||||
|     /// Count the number of bits of a certain type in an Integer. | ||||
|     /// @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) | ||||
|     return count; | ||||
|   else | ||||
|     return (length * 8) - count; | ||||
| } | ||||
|  | ||||
|         for (uint64_t remainder = data; remainder && bitsSoFar; remainder >>= 1, bitsSoFar--) | ||||
|             if (remainder & 1) count++; | ||||
| /// Count the number of bits of a certain type in an Integer. | ||||
| /// @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) | ||||
|             return count; | ||||
|         else | ||||
|             return length - count; | ||||
|     } | ||||
| }} | ||||
|   for (uint64_t remainder = data; remainder && bitsSoFar; remainder >>= 1, bitsSoFar--) | ||||
|     if (remainder & 1) | ||||
|       count++; | ||||
|  | ||||
|   if (ones || length == 0) | ||||
|     return count; | ||||
|   else | ||||
|     return length - count; | ||||
| } | ||||
| }  // namespace climate_ir_samsung | ||||
| }  // namespace esphome | ||||
|   | ||||
| @@ -3,207 +3,208 @@ | ||||
| #include "esphome/components/climate/climate_mode.h" | ||||
| #include "esphome/components/climate_ir/climate_ir.h" | ||||
|  | ||||
|  | ||||
| namespace esphome { | ||||
| namespace climate_ir_samsung { | ||||
|  | ||||
| #define GETBITS8(data, offset, size) \ | ||||
|     (((data) & (((uint8_t)UINT8_MAX >> (8 - (size))) << (offset))) >> (offset)) | ||||
| #define GETBITS8(data, offset, size) (((data) & (((uint8_t) UINT8_MAX >> (8 - (size))) << (offset))) >> (offset)) | ||||
|  | ||||
|     static const char *const TAG = "samsung.climate"; | ||||
|     static const uint32_t SAMSUNG_IR_FREQUENCY = 38000; | ||||
|     static const int SAMSUNG_AIRCON1_HDR_MARK = 3000; | ||||
|     static const int SAMSUNG_AIRCON1_HDR_SPACE = 9000; | ||||
|     static const int SAMSUNG_AIRCON1_BIT_MARK = 500; | ||||
|     static const int SAMSUNG_AIRCON1_ONE_SPACE = 1500; | ||||
|     static const int SAMSUNG_AIRCON1_ZERO_SPACE = 500; | ||||
|     static const int SAMSUNG_AIRCON1_MSG_SPACE = 2000; | ||||
| static const char *const TAG = "samsung.climate"; | ||||
| static const uint32_t SAMSUNG_IR_FREQUENCY = 38000; | ||||
| static const int SAMSUNG_AIRCON1_HDR_MARK = 3000; | ||||
| static const int SAMSUNG_AIRCON1_HDR_SPACE = 9000; | ||||
| static const int SAMSUNG_AIRCON1_BIT_MARK = 500; | ||||
| static const int SAMSUNG_AIRCON1_ONE_SPACE = 1500; | ||||
| static const int SAMSUNG_AIRCON1_ZERO_SPACE = 500; | ||||
| static const int SAMSUNG_AIRCON1_MSG_SPACE = 2000; | ||||
|  | ||||
|     const uint16_t kSamsungAcExtendedStateLength = 21; | ||||
|     const uint16_t kSamsungAcSectionLength = 7; | ||||
| const uint16_t kSamsungAcExtendedStateLength = 21; | ||||
| const uint16_t kSamsungAcSectionLength = 7; | ||||
|  | ||||
|     // Temperature | ||||
|     const uint8_t kSamsungAcMinTemp  = 16;  // C   Mask 0b11110000 | ||||
|     const uint8_t kSamsungAcMaxTemp  = 30;  // C   Mask 0b11110000 | ||||
|     const uint8_t kSamsungAcAutoTemp = 25;  // C   Mask 0b11110000 | ||||
| // Temperature | ||||
| const uint8_t kSamsungAcMinTemp = 16;   // C   Mask 0b11110000 | ||||
| const uint8_t kSamsungAcMaxTemp = 30;   // C   Mask 0b11110000 | ||||
| const uint8_t kSamsungAcAutoTemp = 25;  // C   Mask 0b11110000 | ||||
|  | ||||
|     // Mode | ||||
|     const uint8_t kSamsungAcAuto = 0; | ||||
|     const uint8_t kSamsungAcCool = 1; | ||||
|     const uint8_t kSamsungAcDry = 2; | ||||
|     const uint8_t kSamsungAcFan = 3; | ||||
|     const uint8_t kSamsungAcHeat = 4; | ||||
| // Mode | ||||
| const uint8_t kSamsungAcAuto = 0; | ||||
| const uint8_t kSamsungAcCool = 1; | ||||
| const uint8_t kSamsungAcDry = 2; | ||||
| const uint8_t kSamsungAcFan = 3; | ||||
| const uint8_t kSamsungAcHeat = 4; | ||||
|  | ||||
|     // Fan | ||||
|     const uint8_t kSamsungAcFanAuto = 0; | ||||
|     const uint8_t kSamsungAcFanLow = 2; | ||||
|     const uint8_t kSamsungAcFanMed = 4; | ||||
|     const uint8_t kSamsungAcFanHigh = 5; | ||||
|     const uint8_t kSamsungAcFanAuto2 = 6; | ||||
|     const uint8_t kSamsungAcFanTurbo = 7; | ||||
| // Fan | ||||
| const uint8_t kSamsungAcFanAuto = 0; | ||||
| const uint8_t kSamsungAcFanLow = 2; | ||||
| const uint8_t kSamsungAcFanMed = 4; | ||||
| const uint8_t kSamsungAcFanHigh = 5; | ||||
| const uint8_t kSamsungAcFanAuto2 = 6; | ||||
| const uint8_t kSamsungAcFanTurbo = 7; | ||||
|  | ||||
|     // Swing | ||||
|     const uint8_t kSamsungAcSwingV =        0b010; | ||||
|     const uint8_t kSamsungAcSwingH =        0b011; | ||||
|     const uint8_t kSamsungAcSwingBoth =     0b100; | ||||
|     const uint8_t kSamsungAcSwingOff =      0b111; | ||||
| // Swing | ||||
| const uint8_t kSamsungAcSwingV = 0b010; | ||||
| const uint8_t kSamsungAcSwingH = 0b011; | ||||
| const uint8_t kSamsungAcSwingBoth = 0b100; | ||||
| const uint8_t kSamsungAcSwingOff = 0b111; | ||||
|  | ||||
|     // Power | ||||
|     const uint8_t kNibbleSize = 4; | ||||
|     const uint8_t kLowNibble = 0; | ||||
|     const uint8_t kHighNibble = 4; | ||||
|     const uint8_t kModeBitsSize = 3; | ||||
| // Power | ||||
| const uint8_t kNibbleSize = 4; | ||||
| const uint8_t kLowNibble = 0; | ||||
| const uint8_t kHighNibble = 4; | ||||
| 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, 0xAE, 0x71, 0x00, 0x15, 0xF0}; | ||||
| // 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, 0xAE, 0x71, 0x00, 0x15, 0xF0}; | ||||
|  | ||||
|     /// Native representation of a Samsung A/C message. | ||||
|     union SamsungProtocol { | ||||
|         uint8_t raw[kSamsungAcExtendedStateLength];  ///< State in code form. | ||||
|         struct {  // Standard message map | ||||
|             // Byte 0 | ||||
|             uint8_t         :8; | ||||
|             // Byte 1 | ||||
|             uint8_t         :4; | ||||
|             uint8_t         :4;  // Sum1Lower | ||||
|             // Byte 2 | ||||
|             uint8_t         :4;  // Sum1Upper | ||||
|             uint8_t         :4; | ||||
|             // Byte 3 | ||||
|             uint8_t         :8; | ||||
|             // Byte 4 | ||||
|             uint8_t         :8; | ||||
|             // Byte 5 | ||||
|             uint8_t         :4; | ||||
|             uint8_t Sleep5  :1; | ||||
|             uint8_t Quiet   :1; | ||||
|             uint8_t         :2; | ||||
|             // Byte 6 | ||||
|             uint8_t         :4; | ||||
|             uint8_t Power1  :2; | ||||
|             uint8_t         :2; | ||||
|             // Byte 7 | ||||
|             uint8_t         :8; | ||||
|             // Byte 8 | ||||
|             uint8_t         :4; | ||||
|             uint8_t         :4;  // Sum2Lower | ||||
|             // Byte 9 | ||||
|             uint8_t         :4;  // Sum1Upper | ||||
|             uint8_t Swing   :3; | ||||
|             uint8_t         :1; | ||||
|             // Byte 10 | ||||
|             uint8_t               :1; | ||||
|             uint8_t FanSpecial    :3;  // Powerful, Breeze/WindFree, Econo | ||||
|             uint8_t Display       :1; | ||||
|             uint8_t               :2; | ||||
|             uint8_t CleanToggle10 :1; | ||||
|             // Byte 11 | ||||
|             uint8_t Ion           :1; | ||||
|             uint8_t CleanToggle11 :1; | ||||
|             uint8_t               :2; | ||||
|             uint8_t Temp          :4; | ||||
|             // Byte 12 | ||||
|             uint8_t       :1; | ||||
|             uint8_t Fan   :3; | ||||
|             uint8_t Mode  :3; | ||||
|             uint8_t       :1; | ||||
|             // Byte 13 | ||||
|             uint8_t            :2; | ||||
|             uint8_t BeepToggle :1; | ||||
|             uint8_t            :1; | ||||
|             uint8_t Power2     :2; | ||||
|             uint8_t            :2; | ||||
|         }; | ||||
|         struct {  // Extended message map | ||||
|             // 1st Section | ||||
|             // Byte 0 | ||||
|             uint8_t                :8; | ||||
|             // Byte 1 | ||||
|             uint8_t                :4; | ||||
|             uint8_t Sum1Lower      :4; | ||||
|             // Byte 2 | ||||
|             uint8_t Sum1Upper      :4; | ||||
|             uint8_t                :4; | ||||
|             // Byte 3 | ||||
|             uint8_t                :8; | ||||
|             // Byte 4 | ||||
|             uint8_t                :8; | ||||
|             // Byte 5 | ||||
|             uint8_t                :8; | ||||
|             // Byte 6 | ||||
|             uint8_t                :8; | ||||
|             // 2nd Section | ||||
|             // Byte 7 | ||||
|             uint8_t                :8; | ||||
|             // Byte 8 | ||||
|             uint8_t                :4; | ||||
|             uint8_t Sum2Lower      :4; | ||||
|             // Byte 9 | ||||
|             uint8_t Sum2Upper      :4; | ||||
|             uint8_t OffTimeMins    :3;  // In units of 10's of mins | ||||
|             uint8_t OffTimeHrs1    :1;  // LSB of the number of hours. | ||||
|             // Byte 10 | ||||
|             uint8_t OffTimeHrs2    :4;  // MSBs of the number of hours. | ||||
|             uint8_t OnTimeMins     :3;  // In units of 10's of mins | ||||
|             uint8_t OnTimeHrs1     :1;  // LSB of the number of hours. | ||||
|             // Byte 11 | ||||
|             uint8_t OnTimeHrs2     :4;  // MSBs of the number of hours. | ||||
|             uint8_t                :4; | ||||
|             // Byte 12 | ||||
|             uint8_t OffTimeDay     :1; | ||||
|             uint8_t OnTimerEnable  :1; | ||||
|             uint8_t OffTimerEnable :1; | ||||
|             uint8_t Sleep12        :1; | ||||
|             uint8_t OnTimeDay      :1; | ||||
|             uint8_t                :3; | ||||
|             // Byte 13 | ||||
|             uint8_t                :8; | ||||
|             // 3rd Section | ||||
|             // Byte 14 | ||||
|             uint8_t                :8; | ||||
|             // Byte 15 | ||||
|             uint8_t                :4; | ||||
|             uint8_t Sum3Lower      :4; | ||||
|             // Byte 16 | ||||
|             uint8_t Sum3Upper      :4; | ||||
|             uint8_t                :4; | ||||
|             // Byte 17 | ||||
|             uint8_t                :8; | ||||
|             // Byte 18 | ||||
|             uint8_t                :8; | ||||
|             // Byte 19 | ||||
|             uint8_t                :8; | ||||
|             // Byte 20 | ||||
|             uint8_t                :8; | ||||
|         }; | ||||
|     }; | ||||
| /// Native representation of a Samsung A/C message. | ||||
| union SamsungProtocol { | ||||
|   uint8_t raw[kSamsungAcExtendedStateLength];  ///< State in code form. | ||||
|   struct {                                     // Standard message map | ||||
|     // Byte 0 | ||||
|     uint8_t : 8; | ||||
|     // Byte 1 | ||||
|     uint8_t : 4; | ||||
|     uint8_t : 4;  // Sum1Lower | ||||
|     // Byte 2 | ||||
|     uint8_t : 4;  // Sum1Upper | ||||
|     uint8_t : 4; | ||||
|     // Byte 3 | ||||
|     uint8_t : 8; | ||||
|     // Byte 4 | ||||
|     uint8_t : 8; | ||||
|     // Byte 5 | ||||
|     uint8_t : 4; | ||||
|     uint8_t Sleep5 : 1; | ||||
|     uint8_t Quiet : 1; | ||||
|     uint8_t : 2; | ||||
|     // Byte 6 | ||||
|     uint8_t : 4; | ||||
|     uint8_t Power1 : 2; | ||||
|     uint8_t : 2; | ||||
|     // Byte 7 | ||||
|     uint8_t : 8; | ||||
|     // Byte 8 | ||||
|     uint8_t : 4; | ||||
|     uint8_t : 4;  // Sum2Lower | ||||
|     // Byte 9 | ||||
|     uint8_t : 4;  // Sum1Upper | ||||
|     uint8_t Swing : 3; | ||||
|     uint8_t : 1; | ||||
|     // Byte 10 | ||||
|     uint8_t : 1; | ||||
|     uint8_t FanSpecial : 3;  // Powerful, Breeze/WindFree, Econo | ||||
|     uint8_t Display : 1; | ||||
|     uint8_t : 2; | ||||
|     uint8_t CleanToggle10 : 1; | ||||
|     // Byte 11 | ||||
|     uint8_t Ion : 1; | ||||
|     uint8_t CleanToggle11 : 1; | ||||
|     uint8_t : 2; | ||||
|     uint8_t Temp : 4; | ||||
|     // Byte 12 | ||||
|     uint8_t : 1; | ||||
|     uint8_t Fan : 3; | ||||
|     uint8_t Mode : 3; | ||||
|     uint8_t : 1; | ||||
|     // Byte 13 | ||||
|     uint8_t : 2; | ||||
|     uint8_t BeepToggle : 1; | ||||
|     uint8_t : 1; | ||||
|     uint8_t Power2 : 2; | ||||
|     uint8_t : 2; | ||||
|   }; | ||||
|   struct {  // Extended message map | ||||
|     // 1st Section | ||||
|     // Byte 0 | ||||
|     uint8_t : 8; | ||||
|     // Byte 1 | ||||
|     uint8_t : 4; | ||||
|     uint8_t Sum1Lower : 4; | ||||
|     // Byte 2 | ||||
|     uint8_t Sum1Upper : 4; | ||||
|     uint8_t : 4; | ||||
|     // Byte 3 | ||||
|     uint8_t : 8; | ||||
|     // Byte 4 | ||||
|     uint8_t : 8; | ||||
|     // Byte 5 | ||||
|     uint8_t : 8; | ||||
|     // Byte 6 | ||||
|     uint8_t : 8; | ||||
|     // 2nd Section | ||||
|     // Byte 7 | ||||
|     uint8_t : 8; | ||||
|     // Byte 8 | ||||
|     uint8_t : 4; | ||||
|     uint8_t Sum2Lower : 4; | ||||
|     // Byte 9 | ||||
|     uint8_t Sum2Upper : 4; | ||||
|     uint8_t OffTimeMins : 3;  // In units of 10's of mins | ||||
|     uint8_t OffTimeHrs1 : 1;  // LSB of the number of hours. | ||||
|     // Byte 10 | ||||
|     uint8_t OffTimeHrs2 : 4;  // MSBs of the number of hours. | ||||
|     uint8_t OnTimeMins : 3;   // In units of 10's of mins | ||||
|     uint8_t OnTimeHrs1 : 1;   // LSB of the number of hours. | ||||
|     // Byte 11 | ||||
|     uint8_t OnTimeHrs2 : 4;  // MSBs of the number of hours. | ||||
|     uint8_t : 4; | ||||
|     // Byte 12 | ||||
|     uint8_t OffTimeDay : 1; | ||||
|     uint8_t OnTimerEnable : 1; | ||||
|     uint8_t OffTimerEnable : 1; | ||||
|     uint8_t Sleep12 : 1; | ||||
|     uint8_t OnTimeDay : 1; | ||||
|     uint8_t : 3; | ||||
|     // Byte 13 | ||||
|     uint8_t : 8; | ||||
|     // 3rd Section | ||||
|     // Byte 14 | ||||
|     uint8_t : 8; | ||||
|     // Byte 15 | ||||
|     uint8_t : 4; | ||||
|     uint8_t Sum3Lower : 4; | ||||
|     // Byte 16 | ||||
|     uint8_t Sum3Upper : 4; | ||||
|     uint8_t : 4; | ||||
|     // Byte 17 | ||||
|     uint8_t : 8; | ||||
|     // Byte 18 | ||||
|     uint8_t : 8; | ||||
|     // Byte 19 | ||||
|     uint8_t : 8; | ||||
|     // Byte 20 | ||||
|     uint8_t : 8; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
|     class SamsungClimateIR : public climate_ir::ClimateIR { | ||||
| class SamsungClimateIR : public climate_ir::ClimateIR { | ||||
|   SamsungProtocol protocol; | ||||
|   climate::ClimateMode current_climate_mode; | ||||
|  | ||||
|         SamsungProtocol protocol; | ||||
|         climate::ClimateMode current_climate_mode; | ||||
|  public: | ||||
|   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() : | ||||
|             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}) { } | ||||
|  protected: | ||||
|   void transmit_state() override; | ||||
|  | ||||
|         protected: | ||||
|             void transmit_state() override; | ||||
|   void send(); | ||||
|   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 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 checksum(void); | ||||
|             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); | ||||
|     }; | ||||
| }} | ||||
|   void checksum(void); | ||||
|   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); | ||||
| }; | ||||
| }  // namespace climate_ir_samsung | ||||
| }  // namespace esphome | ||||
|   | ||||
		Reference in New Issue
	
	Block a user