Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hitachi344: Add Swing(H) and improve Swing(V) #1148

Merged
merged 9 commits into from
May 31, 2020
13 changes: 8 additions & 5 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,15 +785,14 @@ void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
void IRac::hitachi344(IRHitachiAc344 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv) {
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh) {
ac->begin();
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwingH(ac->convertSwingH(swingh));
ac->setPower(on);
// SwingVToggle is special. Needs to be last method called.
ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
// No Swing(H) setting available.
// No Quiet setting available.
// No Turbo setting available.
// No Light setting available.
Expand All @@ -802,6 +801,9 @@ void IRac::hitachi344(IRHitachiAc344 *ac,
// No Beep setting available.
// No Sleep setting available.
// No Clock setting available.

// SwingVToggle is special. Needs to be last method called.
ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
ac->send();
}
#endif // SEND_HITACHI_AC344
Expand Down Expand Up @@ -1654,7 +1656,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
case HITACHI_AC344:
{
IRHitachiAc344 ac(_pin, _inverted, _modulation);
hitachi344(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv);
hitachi344(&ac, send.power, send.mode, degC, send.fanspeed,
send.swingv, send.swingh);
break;
}
#endif // SEND_HITACHI_AC344
Expand Down
3 changes: 2 additions & 1 deletion src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ void electra(IRElectraAc *ac,
void hitachi344(IRHitachiAc344 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv);
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh);
#endif // SEND_HITACHI_AC344
#if SEND_HITACHI_AC424
void hitachi424(IRHitachiAc424 *ac,
Expand Down
97 changes: 94 additions & 3 deletions src/ir_Hitachi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1156,8 +1156,10 @@ stdAc::state_t IRHitachiAc424::toCommon(void) {
return result;
}

// Convert the internal state into a human readable string.
String IRHitachiAc424::toString(void) {
/// Convert the internal state into a human readable string for the settings
/// that are common to protocols of this nature.
/// @return A string containing the common settings in human-readable form.
String IRHitachiAc424::_toString(void) {
String result = "";
result.reserve(100); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
Expand All @@ -1177,7 +1179,6 @@ String IRHitachiAc424::toString(void) {
default: result += kUnknownStr;
}
result += ')';
result += addBoolToString(getSwingVToggle(), kSwingVToggleStr);
result += addIntToString(getButton(), kButtonStr);
result += kSpaceLBraceStr;
switch (getButton()) {
Expand All @@ -1188,6 +1189,7 @@ String IRHitachiAc424::toString(void) {
break;
case kHitachiAc424ButtonFan: result += kFanStr; break;
case kHitachiAc424ButtonSwingV: result += kSwingVStr; break;
case kHitachiAc344ButtonSwingH: result += kSwingHStr; break;
case kHitachiAc424ButtonTempDown: result += kTempDownStr; break;
case kHitachiAc424ButtonTempUp: result += kTempUpStr; break;
default: result += kUnknownStr;
Expand All @@ -1196,6 +1198,12 @@ String IRHitachiAc424::toString(void) {
return result;
}

/// Convert the internal state into a human readable string.
/// @return A string containing the settings in human-readable form.
String IRHitachiAc424::toString(void) {
return _toString() + addBoolToString(getSwingVToggle(), kSwingVToggleStr);
}


#if SEND_HITACHI_AC3
// Send HITACHI_AC3 messages
Expand Down Expand Up @@ -1366,10 +1374,93 @@ void IRHitachiAc344::setRaw(const uint8_t new_code[], const uint16_t length) {
memcpy(remote_state, new_code, std::min(length, kHitachiAc344StateLength));
}

/// Control the vertical swing setting.
/// @param[in] on True, turns on the feature. False, turns off the feature.
void IRHitachiAc344::setSwingV(const bool on) {
setSwingVToggle(on); // Set the button value.
setBit(&remote_state[kHitachiAc344SwingVByte], kHitachiAc344SwingVOffset, on);
}

/// Get the current vertical swing setting.
/// @return True, if the setting is on. False, it is off.
bool IRHitachiAc344::getSwingV(void) {
return GETBIT8(remote_state[kHitachiAc344SwingVByte],
kHitachiAc344SwingVOffset);
}

/// Control the horizontal swing setting.
/// @param[in] position The position to set the horizontal swing to.
void IRHitachiAc344::setSwingH(const uint8_t position) {
if (position > kHitachiAc344SwingHLeftMax)
return setSwingH(kHitachiAc344SwingHMiddle);
setBits(&remote_state[kHitachiAc344SwingHByte], kHitachiAc344SwingHOffset,
kHitachiAc344SwingHSize, position);
setButton(kHitachiAc344ButtonSwingH);
}

/// Get the current horizontal swing setting.
/// @return The current position horizontal swing is set to.
uint8_t IRHitachiAc344::getSwingH(void) {
return GETBITS8(remote_state[kHitachiAc344SwingHByte],
kHitachiAc344SwingHOffset, kHitachiAc344SwingHSize);
}

/// Convert a standard A/C horizontal swing into its native setting.
/// @param[in] position A stdAc::swingh_t position to convert.
/// @return The equivilent native horizontal swing position.
uint8_t IRHitachiAc344::convertSwingH(const stdAc::swingh_t position) {
switch (position) {
case stdAc::swingh_t::kAuto: return kHitachiAc344SwingHAuto;
case stdAc::swingh_t::kLeftMax: return kHitachiAc344SwingHLeftMax;
case stdAc::swingh_t::kLeft: return kHitachiAc344SwingHLeft;
case stdAc::swingh_t::kRight: return kHitachiAc344SwingHRight;
case stdAc::swingh_t::kRightMax: return kHitachiAc344SwingHRightMax;
default: return kHitachiAc344SwingHMiddle;
}
}

/// Convert a native horizontal swing postion to it's common equivalent.
/// @param[in] pos A native position to convert.
/// @return The common horizontal swing position.
stdAc::swingh_t IRHitachiAc344::toCommonSwingH(const uint8_t pos) {
switch (pos) {
case kHitachiAc344SwingHLeftMax: return stdAc::swingh_t::kLeftMax;
case kHitachiAc344SwingHLeft: return stdAc::swingh_t::kLeft;
case kHitachiAc344SwingHRight: return stdAc::swingh_t::kRight;
case kHitachiAc344SwingHRightMax: return stdAc::swingh_t::kRightMax;
case kHitachiAc344SwingHAuto: return stdAc::swingh_t::kAuto;
default: return stdAc::swingh_t::kOff;
}
}

/// Convert the current A/C state to its common stdAc::state_t equivalent.
/// @return A stdAc::state_t state.
stdAc::state_t IRHitachiAc344::toCommon(void) {
stdAc::state_t result = IRHitachiAc424::toCommon();
result.protocol = decode_type_t::HITACHI_AC344;
result.swingv = getSwingV() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
result.swingh = toCommonSwingH(getSwingH());
return result;
}

/// Convert the internal state into a human readable string.
/// @return A string containing the settings in human-readable form.
String IRHitachiAc344::toString(void) {
String result;
result.reserve(120); // Reserve some heap for the string to reduce fragging.
result += _toString();
result += addBoolToString(getSwingV(), kSwingVStr);
result += addIntToString(getSwingH(), kSwingHStr);
result += kSpaceLBraceStr;
switch (getSwingH()) {
case kHitachiAc344SwingHLeftMax: result += kLeftMaxStr; break;
case kHitachiAc344SwingHLeft: result += kLeftStr; break;
case kHitachiAc344SwingHMiddle: result += kMiddleStr; break;
case kHitachiAc344SwingHRight: result += kRightStr; break;
case kHitachiAc344SwingHRightMax: result += kRightMaxStr; break;
case kHitachiAc344SwingHAuto: result += kAutoStr; break;
default: result += kUnknownStr;
}
result += ')';
return result;
}
28 changes: 27 additions & 1 deletion src/ir_Hitachi.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
// Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3)
// Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1)
// Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
// Brand: Hitachi, Model: RAS-22NK remote (HITACHI_AC344)
// Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344)
// Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344)
NiKiZe marked this conversation as resolved.
Show resolved Hide resolved

#ifndef IR_HITACHI_H_
#define IR_HITACHI_H_
Expand Down Expand Up @@ -52,11 +53,13 @@ const uint8_t kHitachiAc424ButtonFan = 0x42;
const uint8_t kHitachiAc424ButtonTempDown = 0x43;
const uint8_t kHitachiAc424ButtonTempUp = 0x44;
const uint8_t kHitachiAc424ButtonSwingV = 0x81;
const uint8_t kHitachiAc424ButtonSwingH = 0x8C;
const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode;
const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan;
const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown;
const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp;
const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV;
const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH;

// Byte[13]
const uint8_t kHitachiAc424TempByte = 13;
Expand Down Expand Up @@ -99,6 +102,21 @@ const uint8_t kHitachiAc424PowerByte = 27;
const uint8_t kHitachiAc424PowerOn = 0xF1;
const uint8_t kHitachiAc424PowerOff = 0xE1;

// Byte[35]
const uint8_t kHitachiAc344SwingHByte = 35;
const uint8_t kHitachiAc344SwingHOffset = 0; // Mask 0b00000xxx
const uint8_t kHitachiAc344SwingHSize = 3; // Mask 0b00000xxx
const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000
const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001
const uint8_t kHitachiAc344SwingHRight = 2; // 0b010
const uint8_t kHitachiAc344SwingHMiddle = 3; // 0b011
const uint8_t kHitachiAc344SwingHLeft = 4; // 0b100
const uint8_t kHitachiAc344SwingHLeftMax = 5; // 0b101

// Byte[37]
const uint8_t kHitachiAc344SwingVByte = 37;
const uint8_t kHitachiAc344SwingVOffset = 5; // Mask 0b00x00000

// HitachiAc1
// Byte[3] (Model)
const uint8_t kHitachiAc1ModelByte = 3;
Expand Down Expand Up @@ -317,6 +335,7 @@ class IRHitachiAc424 {
// The state of the IR remote in IR code form.
uint8_t remote_state[kHitachiAc424StateLength];
void setInvertedStates(void);
String _toString(void);
uint8_t _previoustemp;
};

Expand Down Expand Up @@ -359,6 +378,13 @@ class IRHitachiAc344: public IRHitachiAc424 {
#if SEND_HITACHI_AC344
void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif // SEND_HITACHI_AC344
void setSwingV(const bool on);
bool getSwingV(void);
void setSwingH(const uint8_t position);
uint8_t getSwingH(void);
static uint8_t convertSwingH(const stdAc::swingh_t position);
static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
String toString(void);
};

#endif // IR_HITACHI_H_
2 changes: 1 addition & 1 deletion src/ir_MitsubishiHeavy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed(const uint8_t spd) {
}
}

// Convert a native vertical swing to it's common equivalent.
// Convert a native horizontal swing to it's common equivalent.
stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH(const uint8_t pos) {
switch (pos) {
case kMitsubishiHeavy152SwingHLeftMax: return stdAc::swingh_t::kLeftMax;
Expand Down
38 changes: 20 additions & 18 deletions test/IRac_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,49 +730,51 @@ TEST(TestIRac, Hitachi344) {
IRHitachiAc344 ac(kGpioUnused);
IRac irac(kGpioUnused);
IRrecv capture(kGpioUnused);
char expected[] =
char expected_swingon[] =
"Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), "
"Swing(V) Toggle: Off, Button: 19 (Power/Mode)";
char expected_swingv[] =
"Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), "
"Swing(V) Toggle: On, Button: 129 (Swing(V))";
"Button: 129 (Swing(V)), Swing(V): Off, Swing(H): 2 (Right)";

ac.begin();
irac.hitachi344(&ac,
true, // Power
stdAc::opmode_t::kHeat, // Mode
25, // Celsius
stdAc::fanspeed_t::kMax, // Fan speed
stdAc::swingv_t::kOff); // Swing(V)
stdAc::swingv_t::kAuto, // Swing(V)
stdAc::swingh_t::kRight); // Swing(H)

ASSERT_EQ(expected, ac.toString());
ASSERT_EQ(expected_swingon, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type);
ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_EQ(expected_swingon, IRAcUtils::resultAcToString(&ac._irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
EXPECT_EQ(decode_type_t::HITACHI_AC344, r.protocol);
EXPECT_TRUE(r.power);
EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode);
EXPECT_EQ(25, r.degrees);

char expected_swingoff[] =
"Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), "
"Button: 19 (Power/Mode), Swing(V): Off, Swing(H): 2 (Right)";

ac._irsend.reset();
irac.hitachi344(&ac,
true, // Power
stdAc::opmode_t::kCool, // Mode
26, // Celsius
stdAc::fanspeed_t::kMin, // Fan speed
stdAc::swingv_t::kAuto); // Swing(V)

ASSERT_EQ(expected_swingv, ac.toString());
stdAc::opmode_t::kHeat, // Mode
25, // Celsius
stdAc::fanspeed_t::kMax, // Fan speed
stdAc::swingv_t::kOff, // Swing(V)
stdAc::swingh_t::kRight); // Swing(H)
ASSERT_EQ(expected_swingoff, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type);
ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected_swingv, IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ASSERT_EQ(expected_swingoff,
IRAcUtils::resultAcToString(&ac._irsend.capture));
}

TEST(TestIRac, Hitachi424) {
Expand All @@ -781,10 +783,10 @@ TEST(TestIRac, Hitachi424) {
IRrecv capture(0);
char expected[] =
"Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), "
"Swing(V) Toggle: Off, Button: 19 (Power/Mode)";
"Button: 19 (Power/Mode), Swing(V) Toggle: Off";
char expected_swingv[] =
"Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), "
"Swing(V) Toggle: On, Button: 129 (Swing(V))";
"Button: 129 (Swing(V)), Swing(V) Toggle: On";

ac.begin();
irac.hitachi424(&ac,
Expand Down
Loading