Skip to content

Commit

Permalink
IRHitachiAc1: Add support for SwingH
Browse files Browse the repository at this point in the history
  • Loading branch information
crankyoldgit committed Apr 4, 2020
1 parent 7af6755 commit 2febeb8
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 38 deletions.
12 changes: 7 additions & 5 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,16 +706,17 @@ void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
const bool on, const bool power_toggle,
const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool swing_toggle,
const int16_t sleep) {
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool swing_toggle, const int16_t sleep) {
ac->begin();
ac->setModel(model);
ac->setPower(on);
ac->setPowerToggle(power_toggle);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwing(swingv != stdAc::swingv_t::kOff);
ac->setSwingV(swingv != stdAc::swingv_t::kOff);
ac->setSwingH(swingh != stdAc::swingh_t::kOff);
ac->setSwingToggle(swing_toggle);
ac->setSleep((sleep >= 0) ? kHitachiAc1Sleep2 : kHitachiAc1SleepOff);
// No Sleep setting available.
Expand Down Expand Up @@ -1532,11 +1533,12 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
bool swing_toggle = false;
if (prev != NULL) {
power_toggle = (send.power != prev->power);
swing_toggle = (send.swingv != prev->swingv);
swing_toggle = (send.swingv != prev->swingv) ||
(send.swingh != prev->swingh);
}
hitachi1(&ac, (hitachi_ac1_remote_model_t)send.model, send.power,
power_toggle, send.mode, degC, send.fanspeed, send.swingv,
swing_toggle, send.sleep);
send.swingh, swing_toggle, send.sleep);
break;
}
#endif // SEND_HITACHI_AC1
Expand Down
4 changes: 2 additions & 2 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ void electra(IRElectraAc *ac,
const bool on, const bool power_toggle,
const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool swing_toggle,
const int16_t sleep = -1);
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool swing_toggle, const int16_t sleep = -1);
#endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC424
void hitachi424(IRHitachiAc424 *ac,
Expand Down
28 changes: 19 additions & 9 deletions src/ir_Hitachi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,20 @@ void IRHitachiAc1::setSwingToggle(const bool toggle) {
toggle);
}

bool IRHitachiAc1::getSwing(void) {
return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingOffset);
bool IRHitachiAc1::getSwingV(void) {
return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset);
}

void IRHitachiAc1::setSwing(const bool on) {
setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingOffset, on);
void IRHitachiAc1::setSwingV(const bool on) {
setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset, on);
}

bool IRHitachiAc1::getSwingH(void) {
return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset);
}

void IRHitachiAc1::setSwingH(const bool on) {
setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset, on);
}

uint8_t IRHitachiAc1::getSleep(void) {
Expand Down Expand Up @@ -629,8 +637,10 @@ stdAc::state_t IRHitachiAc1::toCommon(void) {
result.celsius = true;
result.degrees = this->getTemp();
result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.swingv = this->getSwing() ? stdAc::swingv_t::kAuto :
stdAc::swingv_t::kOff;
result.swingv = this->getSwingV() ? stdAc::swingv_t::kAuto :
stdAc::swingv_t::kOff;
result.swingh = this->getSwingH() ? stdAc::swingh_t::kAuto :
stdAc::swingh_t::kOff;
result.sleep = this->getSleep() ? 0 : -1;
// Not supported.
result.quiet = false;
Expand All @@ -640,15 +650,14 @@ stdAc::state_t IRHitachiAc1::toCommon(void) {
result.filter = false;
result.light = false;
result.beep = false;
result.swingh = stdAc::swingh_t::kOff;
result.clock = -1;
return result;
}

// Convert the internal state into a human readable string.
String IRHitachiAc1::toString(void) {
String result = "";
result.reserve(160); // Reserve some heap for the string to reduce fragging.
result.reserve(170); // Reserve some heap for the string to reduce fragging.
result += addModelToString(decode_type_t::HITACHI_AC1, getModel(), false);
result += addBoolToString(getPower(), kPowerStr);
result += addBoolToString(getPowerToggle(), kPowerToggleStr);
Expand All @@ -659,7 +668,8 @@ String IRHitachiAc1::toString(void) {
kHitachiAc1FanAuto, kHitachiAc1FanAuto,
kHitachiAc1FanMed);
result += addBoolToString(getSwingToggle(), kSwingVToggleStr);
result += addBoolToString(getSwing(), kSwingVModeStr);
result += addBoolToString(getSwingV(), kSwingVStr);
result += addBoolToString(getSwingH(), kSwingHStr);
result += addLabeledString(getSleep() ? uint64ToString(getSleep()) : kOffStr,
kSleepStr);
result += addLabeledString(getOnTimer() ? minsToString(getOnTimer())
Expand Down
9 changes: 6 additions & 3 deletions src/ir_Hitachi.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ const uint8_t kHitachiAc1PowerByte = 11;
const uint8_t kHitachiAc1PowerOffset = 5; // Mask 0b00100000
const uint8_t kHitachiAc1PowerToggleOffset = 4; // Mask 0b00010000
const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte;
const uint8_t kHitachiAc1SwingOffset = 6; // Mask 0b01000000
const uint8_t kHitachiAc1SwingHOffset = 7; // Mask 0b10000000
const uint8_t kHitachiAc1SwingVOffset = 6; // Mask 0b01000000
const uint8_t kHitachiAc1SwingToggleOffset = 0; // Mask 0b00000001
const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte;
const uint8_t kHitachiAc1SleepOffset = 1; // Mask 0b00001110
Expand Down Expand Up @@ -215,8 +216,10 @@ class IRHitachiAc1 {
uint8_t getMode(void);
void setSwingToggle(const bool toggle);
bool getSwingToggle(void);
void setSwing(const bool on);
bool getSwing(void);
void setSwingV(const bool on);
bool getSwingV(void);
void setSwingH(const bool on);
bool getSwingH(void);
void setSleep(const uint8_t mode);
uint8_t getSleep(void);
void setOnTimer(const uint16_t mins);
Expand Down
5 changes: 3 additions & 2 deletions test/IRac_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ TEST(TestIRac, Hitachi1) {
char expected[] =
"Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: Off, "
"Mode: 15 (Auto), Temp: 19C, Fan: 4 (Medium), "
"Swing(V) Toggle: On, Swing(V) Mode: On, Sleep: 2, "
"Swing(V) Toggle: On, Swing(V): On, Swing(H): On, Sleep: 2, "
"On Timer: Off, Off Timer: Off";

ac.begin();
Expand All @@ -650,7 +650,8 @@ TEST(TestIRac, Hitachi1) {
19, // Celsius
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kAuto, // Vertical swing
true, // Swing(V) toggle
stdAc::swingh_t::kLeft, // Horizontal swing
true, // Swing toggle
5 * 60 + 37); // Sleep

ac._irsend.makeDecodeResult();
Expand Down
39 changes: 22 additions & 17 deletions test/ir_Hitachi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ TEST(TestDecodeHitachiAC1, NormalRealExample) {
EXPECT_EQ(
"Model: 2 (R-LT0541-HTA-B), Power: Off, Power Toggle: On, "
"Mode: 6 (Cool), Temp: 23C, Fan: 1 (Auto), "
"Swing(V) Toggle: Off, Swing(V) Mode: Off, Sleep: Off, "
"Swing(V) Toggle: Off, Swing(V): Off, Swing(H): Off, Sleep: Off, "
"On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
}
Expand Down Expand Up @@ -1601,11 +1601,12 @@ TEST(TestIRHitachiAc1Class, HumanReadable) {
ac.setRaw(cool_32_auto);
EXPECT_EQ(
"Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: On, Mode: 6 (Cool), "
"Temp: 32C, Fan: 1 (Auto), Swing(V) Toggle: Off, Swing(V) Mode: Off, "
"Temp: 32C, Fan: 1 (Auto), Swing(V) Toggle: Off, "
"Swing(V): Off, Swing(H): Off, "
"Sleep: Off, On Timer: Off, Off Timer: Off",
ac.toString());
ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);
ac.setSwing(true);
ac.setSwingV(true);
ac.setSwingToggle(true);
ac.setSleep(kHitachiAc1Sleep2);
ac.setPowerToggle(false);
Expand All @@ -1614,7 +1615,7 @@ TEST(TestIRHitachiAc1Class, HumanReadable) {
EXPECT_EQ(
"Model: 2 (R-LT0541-HTA-B), Power: On, Power Toggle: Off, "
"Mode: 6 (Cool), Temp: 32C, Fan: 1 (Auto), "
"Swing(V) Toggle: On, Swing(V) Mode: On, Sleep: 2, "
"Swing(V) Toggle: On, Swing(V): On, Swing(H): Off, Sleep: 2, "
"On Timer: 02:39, Off Timer: 10:17",
ac.toString());
}
Expand Down Expand Up @@ -1659,7 +1660,8 @@ TEST(TestIRHitachiAc1Class, toCommon) {
ac.setMode(kHitachiAc1Cool);
ac.setTemp(20);
ac.setFan(kHitachiAc1FanHigh);
ac.setSwing(false);
ac.setSwingV(false);
ac.setSwingH(true);
ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);
// Now test it.
ASSERT_EQ(decode_type_t::HITACHI_AC1, ac.toCommon().protocol);
Expand All @@ -1670,8 +1672,8 @@ TEST(TestIRHitachiAc1Class, toCommon) {
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
// Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().clean);
ASSERT_FALSE(ac.toCommon().light);
Expand All @@ -1694,49 +1696,52 @@ TEST(TestIRHitachiAc1Class, ReconstructKnownGood) {
ac.setMode(kHitachiAc1Cool);
ac.setTemp(23);
ac.setFan(kHitachiAc1FanAuto);
ac.setSwing(false);
ac.setSwingV(false);
ac.setSwingH(false);
ac.setSwingToggle(false);
ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);

EXPECT_STATE_EQ(known_good, ac.getRaw(), kHitachiAc1Bits);
EXPECT_EQ(
"Model: 2 (R-LT0541-HTA-B), Power: Off, Power Toggle: On, "
"Mode: 6 (Cool), Temp: 23C, Fan: 1 (Auto), "
"Swing(V) Toggle: Off, Swing(V) Mode: Off, Sleep: Off, "
"Swing(V) Toggle: Off, Swing(V): Off, Swing(H): Off, Sleep: Off, "
"On Timer: Off, Off Timer: Off",
ac.toString());
}

TEST(TestIRHitachiAc1Class, Swing) {
IRHitachiAc1 ac(kGpioUnused);
ac.setSwing(false);
EXPECT_FALSE(ac.getSwing());
ac.setSwingV(false);
EXPECT_FALSE(ac.getSwingV());
ac.setSwingToggle(false);
EXPECT_FALSE(ac.getSwingToggle());

ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
ac.setSwingV(true);
EXPECT_TRUE(ac.getSwingV());
EXPECT_FALSE(ac.getSwingToggle());
ac.setSwingToggle(true);
EXPECT_TRUE(ac.getSwing());
EXPECT_TRUE(ac.getSwingV());
EXPECT_TRUE(ac.getSwingToggle());

ac.setSwing(false);
EXPECT_FALSE(ac.getSwing());
ac.setSwingV(false);
EXPECT_FALSE(ac.getSwingV());
ac.setSwingToggle(false);
EXPECT_FALSE(ac.getSwingToggle());

const uint8_t swing_on_with_toggle[kHitachiAc1StateLength] = {
0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0xE1, 0xA4,
0x00, 0x00, 0x00, 0x00, 0x61, 0x24};
ac.setRaw(swing_on_with_toggle);
EXPECT_TRUE(ac.getSwing());
EXPECT_TRUE(ac.getSwingV());
EXPECT_FALSE(ac.getSwingH());
EXPECT_TRUE(ac.getSwingToggle());
const uint8_t swing_off_with_toggle[kHitachiAc1StateLength] = {
0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0xE1, 0xA4,
0x00, 0x00, 0x00, 0x00, 0x21, 0x44};
ac.setRaw(swing_off_with_toggle);
EXPECT_FALSE(ac.getSwing());
EXPECT_FALSE(ac.getSwingV());
EXPECT_FALSE(ac.getSwingH());
EXPECT_TRUE(ac.getSwingToggle());
ac.setSwingToggle(true);
EXPECT_STATE_EQ(swing_off_with_toggle, ac.getRaw(), kHitachiAc1Bits);
Expand Down

0 comments on commit 2febeb8

Please sign in to comment.