ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
pd_pioneer_data.cpp
Go to the documentation of this file.
1#include "pd_pioneer_data.h"
2#include "esphome/core/hal.h"
4
6
7// Default frames stay in flash; the constructor copies them with progmem_memcpy. Even byte 5 is PWR_ON, byte 6
8// MODE_COOL
9static const uint8_t DEFAULT_ODD[] PROGMEM = {0x23, 0xCB, 0x26, 0x02, 0x00, 0x40, 0xC0,
10 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00};
11static const uint8_t DEFAULT_EVEN[] PROGMEM = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
12 0x0B, 0x05, 0x00, 0x00, 0x00, 0x80};
13
14// Odd positions 5 and 6 and the even position 8 fan code, indexed from CLIMATE_FAN_AUTO to CLIMATE_FAN_HIGH
15static const uint8_t FAN_CODES[][3] PROGMEM = {
16 {0x40, 0x20, 0x00}, {0x60, 0x40, 0x02}, {0x40, 0x60, 0x03}, {0x40, 0xC0, 0x05}};
17static constexpr size_t FAN_CODE_COUNT = sizeof(FAN_CODES) / sizeof(FAN_CODES[0]);
18
19ControlData::ControlData() : odd_(DEFAULT_ODD, sizeof(DEFAULT_ODD)), even_(DEFAULT_EVEN, sizeof(DEFAULT_EVEN)) {}
20
21void ControlData::set_temp(float temp_c) {
22 // The temperature travels as 31 - C in whole degrees at position 7, with bit 2 of position 12 adding a half
23 temp_c = clamp(temp_c, static_cast<float>(PDPIONEER_TEMPC_MIN), static_cast<float>(PDPIONEER_TEMPC_MAX));
24 // Round to a quarter, then down to a half, so Fahrenheit set points encode as before
25 const int halves = static_cast<int>(lroundf(temp_c * 4)) / 2;
26 this->even_[7] = static_cast<uint8_t>(31 - halves / 2);
27 this->even_[12] = static_cast<uint8_t>(0x80 | ((halves & 1) ? 0x04 : 0x00));
28}
29
31 switch (mode) {
33 this->even_[5] = PWR_OFF;
34 this->even_[6] = MODE_HEAT;
35 this->even_[7] = 0x0C;
36 this->even_[12] = 0x80;
37 return;
39 this->even_[6] = MODE_COOL;
40 break;
42 this->even_[6] = MODE_DRY;
43 break;
45 this->even_[6] = MODE_FAN_ONLY;
46 break;
48 this->even_[6] = MODE_HEAT;
49 break;
50 default:
51 this->even_[6] = MODE_AUTO;
52 break;
53 }
54 this->even_[5] = PWR_ON;
55}
56
57optional<ClimateMode> ControlData::get_mode(const PDPioneerData &even) {
58 if (even[5] == PWR_OFF)
60 switch (even[6]) {
61 case MODE_COOL:
63 case MODE_DRY:
65 case MODE_FAN_ONLY:
67 case MODE_HEAT:
69 case MODE_AUTO:
71 default:
72 return {};
73 }
74}
75
77 const size_t idx = this->fan_ >= climate::CLIMATE_FAN_AUTO && this->fan_ <= climate::CLIMATE_FAN_HIGH
78 ? this->fan_ - climate::CLIMATE_FAN_AUTO
79 : FAN_CODE_COUNT - 1;
80 this->odd_[5] = progmem_read_byte(&FAN_CODES[idx][0]);
81 this->odd_[6] = progmem_read_byte(&FAN_CODES[idx][1]);
82 this->odd_[7] = this->swing_;
83 this->even_[8] = static_cast<uint8_t>(progmem_read_byte(&FAN_CODES[idx][2]) |
85 this->odd_.finalize();
86 this->even_.finalize();
87}
88
90 const uint8_t code = even[8] & ~SWING_VERTICAL_EVEN_MASK;
91 for (size_t idx = 0; idx < FAN_CODE_COUNT; idx++) {
92 if (progmem_read_byte(&FAN_CODES[idx][2]) == code)
93 return static_cast<ClimateFanMode>(climate::CLIMATE_FAN_AUTO + idx);
94 }
96}
97
101 this->swing_ = static_cast<uint8_t>((vertical ? SWING_VERTICAL : 0) | (horizontal ? SWING_HORIZONTAL : 0));
102}
103
110
111} // namespace esphome::pd_pioneer_ir
BedjetMode mode
BedJet operating mode.
static constexpr uint8_t MODE_HEAT
static constexpr uint8_t MODE_AUTO
static optional< ClimateMode > get_mode(const PDPioneerData &even)
Empty for a mode byte this remote does not use.
static constexpr uint8_t MODE_DRY
void set_swing_mode(climate::ClimateSwingMode mode)
static ClimateFanMode get_fan_mode(const PDPioneerData &even)
static constexpr uint8_t SWING_VERTICAL_EVEN_MASK
Vertical swing also sets this mask on even frame position 8 (fan sub-code).
void finalize()
Write the fan and swing positions, which share bytes, then the checksums.
static constexpr uint8_t MODE_FAN_ONLY
static constexpr uint8_t MODE_COOL
uint8_t swing_
Odd-burst position 7: SWING_VERTICAL and SWING_HORIZONTAL flags.
static constexpr uint8_t SWING_VERTICAL
static constexpr uint8_t PWR_OFF
const PDPioneerData & even() const
static constexpr uint8_t PWR_ON
static climate::ClimateSwingMode get_swing_mode(const PDPioneerData &even, bool horizontal)
static constexpr uint8_t SWING_HORIZONTAL
ClimateSwingMode
Enum for all modes a climate swing can be in NOTE: If adding values, update ClimateSwingModeMask in c...
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_SWING_BOTH
The fan mode is set to Both.
ClimateMode
Enum for all modes a climate device can be in.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
constexpr uint8_t PDPIONEER_TEMPC_MAX
constexpr uint8_t PDPIONEER_TEMPC_MIN
uint8_t progmem_read_byte(const uint8_t *addr)
Definition hal.h:51