Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/ir_Daikin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3878,9 +3878,15 @@ void IRDaikin312::stateReset(void) {
_.raw[2] = 0x27;
_.raw[3] = 0x00;
_.raw[4] = 0x02;
// CurrentTime lower byte (placeholder; set via setCurrentTime)
_.raw[5] = 0x58;
// CurrentTime upper nibble + Power2 (Power2 set by setPower)
_.raw[6] = 0x64;
_.raw[7] = 0x58;
// raw[7] bits 6-7 = EyeTimer (0x00=off, 0x40=1hr, 0x80=3hr).
_.raw[7] = 0x00;
// raw[8] bit5 (0x20) is always set by a ARC472A43 remote (meaning unknown).
// AC seems to accept commands regardless of the value set here.
// Value from the original PR (#2246) is kept.
_.raw[8] = 0x64;
_.raw[9] = 0x06;
_.raw[10] = 0x00;
Expand Down Expand Up @@ -4204,6 +4210,21 @@ void IRDaikin312::setEye(bool on) { _.Eye = on; }
/// @return true, the setting is on. false, the setting is off.
bool IRDaikin312::getEye(void) const { return _.Eye; }

/// Set the Eye (Sensor) timer duration of the A/C.
/// @param[in] duration kDaikin312EyeTimerOff, kDaikin312EyeTimer1Hr, or
/// kDaikin312EyeTimer3Hr.
void IRDaikin312::setEyeTimer(const uint8_t duration) {
if (duration > kDaikin312EyeTimer3Hr)
_.EyeTimer = kDaikin312EyeTimerOff;
else
_.EyeTimer = duration;
}

/// Get the Eye (Sensor) timer duration of the A/C.
/// @return kDaikin312EyeTimerOff, kDaikin312EyeTimer1Hr, or
/// kDaikin312EyeTimer3Hr.
uint8_t IRDaikin312::getEyeTimer(void) const { return _.EyeTimer; }

/// Set the Economy mode of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRDaikin312::setEcono(bool on) { _.Econo = on; }
Expand Down
23 changes: 16 additions & 7 deletions src/ir_Daikin.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,16 +709,17 @@ union Daikin312Protocol{
uint64_t CurrentTime :12;
uint64_t :3;
uint64_t Power2 :1;
// Byte 7
uint64_t :4;
uint64_t :2; // Light moved to byte 12
uint64_t Beep :2;
// Byte 7: Eye timer duration (bits 6–7); remaining bits unused.
// Observed remote encodings: 0x00 = off, 0x40 = 1 hr, 0x80 = 3 hr.
uint64_t :6;
uint64_t EyeTimer :2;
// Byte 8
uint64_t FreshAir :1;
uint64_t :2;
uint64_t Mold :1;
uint64_t :2;
uint64_t :1;
uint64_t :1; // HeatHigh indicator
uint64_t :1; // always 1 (0x20)
uint64_t :1; // unknown; always 0 in observed signals
uint64_t FreshAirHigh :1;
// Byte 9~10
// Byte 9: Always 0x06
Expand All @@ -728,7 +729,8 @@ union Daikin312Protocol{
uint64_t :8;
// Byte 12
uint64_t Light :2;
uint64_t :6;
uint64_t Beep :2;
uint64_t :4;

// Byte 13
uint64_t :8;
Expand Down Expand Up @@ -861,6 +863,11 @@ const uint8_t kDaikin312HumidityAuto = 0xFF;
// Min temp (in C) when in Cool mode.
const uint8_t kDaikin312MinCoolTemp = 18;

// Eye timer duration (byte 7, bits 6-7). @see setEyeTimer()
const uint8_t kDaikin312EyeTimerOff = 0; // 0x00
const uint8_t kDaikin312EyeTimer1Hr = 1; // 0x40
const uint8_t kDaikin312EyeTimer3Hr = 2; // 0x80

/// Class for handling detailed Daikin 312-bit A/C messages.
/// @note Code by crankyoldgit, Reverse engineering analysis by AntonWert
class IRDaikin312 {
Expand Down Expand Up @@ -901,6 +908,8 @@ class IRDaikin312 {
bool getEye(void) const;
void setEyeAuto(const bool on);
bool getEyeAuto(void) const;
void setEyeTimer(const uint8_t duration);
uint8_t getEyeTimer(void) const;
void setPurify(const bool on);
bool getPurify(void) const;
void setMold(const bool on);
Expand Down
18 changes: 18 additions & 0 deletions test/ir_Daikin_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4291,6 +4291,24 @@ TEST(TestDaikin312Class, EyeSetting) {
ASSERT_TRUE(ac.getEyeAuto());
}

TEST(TestDaikin312Class, EyeTimerSetting) {
IRDaikin312 ac(kGpioUnused);
ac.begin();

ac.setEyeTimer(kDaikin312EyeTimerOff);
EXPECT_EQ(kDaikin312EyeTimerOff, ac.getEyeTimer());

ac.setEyeTimer(kDaikin312EyeTimer1Hr);
EXPECT_EQ(kDaikin312EyeTimer1Hr, ac.getEyeTimer());

ac.setEyeTimer(kDaikin312EyeTimer3Hr);
EXPECT_EQ(kDaikin312EyeTimer3Hr, ac.getEyeTimer());

// Out-of-range values fall back to Off.
ac.setEyeTimer(3);
EXPECT_EQ(kDaikin312EyeTimerOff, ac.getEyeTimer());
}

TEST(TestDaikin312Class, PurifySetting) {
IRDaikin312 ac(kGpioUnused);
ac.begin();
Expand Down
Loading