Skip to content

Commit

Permalink
Detailed support for HITACHI_AC1 protocol. (#1072)
Browse files Browse the repository at this point in the history
* Add settings for `HITACHI_AC1` A/C protocol
  - Power, Fan, Mode, Temp, Swing, Sleep, On & Off Timers.
  - Kudos to @camilloaddis for working out the alg, & @soumaxetuirk for reverse engineering settings.
* Add support for it in the Common A/C api
* Add unit tests.

Fixes #1056
Fixes #1061
  • Loading branch information
crankyoldgit authored Apr 9, 2020
1 parent ae23f01 commit 23697d8
Show file tree
Hide file tree
Showing 8 changed files with 899 additions and 1 deletion.
71 changes: 71 additions & 0 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_HITACHI_AC
case decode_type_t::HITACHI_AC:
#endif
#if SEND_HITACHI_AC1
case decode_type_t::HITACHI_AC1:
#endif
#if SEND_HITACHI_AC424
case decode_type_t::HITACHI_AC424:
#endif
Expand Down Expand Up @@ -698,6 +701,37 @@ void IRac::hitachi(IRHitachiAc *ac,
}
#endif // SEND_HITACHI_AC

#if SEND_HITACHI_AC1
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 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->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.
// No Swing(H) setting available.
// No Quiet setting available.
// No Turbo setting available.
// No Light setting available.
// No Filter setting available.
// No Clean setting available.
// No Beep setting available.
// No Clock setting available.
ac->send();
}
#endif // SEND_HITACHI_AC1

#if SEND_HITACHI_AC424
void IRac::hitachi424(IRHitachiAc424 *ac,
const bool on, const stdAc::opmode_t mode,
Expand Down Expand Up @@ -1492,6 +1526,23 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_HITACHI_AC
#if SEND_HITACHI_AC1
case HITACHI_AC1:
{
IRHitachiAc1 ac(_pin, _inverted, _modulation);
bool power_toggle = false;
bool swing_toggle = false;
if (prev != NULL) {
power_toggle = (send.power != prev->power);
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,
send.swingh, swing_toggle, send.sleep);
break;
}
#endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC424
case HITACHI_AC424:
{
Expand Down Expand Up @@ -1833,6 +1884,11 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return gree_ac_remote_model_t::YAW1F;
} else if (!strcasecmp(str, "YBOFB")) {
return gree_ac_remote_model_t::YBOFB;
// HitachiAc1 models
} else if (!strcasecmp(str, "R-LT0541-HTA-A")) {
return hitachi_ac1_remote_model_t::R_LT0541_HTA_A;
} else if (!strcasecmp(str, "R-LT0541-HTA-B")) {
return hitachi_ac1_remote_model_t::R_LT0541_HTA_B;
// Fujitsu A/C models
} else if (!strcasecmp(str, "ARRAH2E")) {
return fujitsu_ac_remote_model_t::ARRAH2E;
Expand Down Expand Up @@ -2201,6 +2257,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_HITACHI_AC
#if DECODE_HITACHI_AC1
case decode_type_t::HITACHI_AC1: {
IRHitachiAc1 ac(kGpioUnused);
ac.setRaw(result->state);
return ac.toString();
}
#endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC424
case decode_type_t::HITACHI_AC424: {
IRHitachiAc424 ac(0);
Expand Down Expand Up @@ -2413,6 +2476,14 @@ namespace IRAcUtils {
break;
}
#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC2)
#if DECODE_HITACHI_AC1
case decode_type_t::HITACHI_AC1: {
IRHitachiAc1 ac(kGpioUnused);
ac.setRaw(decode->state);
*result = ac.toCommon();
break;
}
#endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC424
case decode_type_t::HITACHI_AC424: {
IRHitachiAc424 ac(kGpioUnused);
Expand Down
8 changes: 8 additions & 0 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ void electra(IRElectraAc *ac,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh);
#endif // SEND_HITACHI_AC
#if SEND_HITACHI_AC1
void 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 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,
const bool on, const stdAc::opmode_t mode,
Expand Down
5 changes: 5 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ enum gree_ac_remote_model_t {
YBOFB, // (2) Green, YBOFB2, YAPOF3
};

enum hitachi_ac1_remote_model_t {
R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default)
R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting.
};

enum panasonic_ac_remote_model_t {
kPanasonicUnknown = 0,
kPanasonicLke = 1,
Expand Down
9 changes: 9 additions & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,15 @@ namespace irutils {
default: return kUnknownStr;
}
break;
case decode_type_t::HITACHI_AC1:
switch (model) {
case hitachi_ac1_remote_model_t::R_LT0541_HTA_A:
return F("R-LT0541-HTA-A");
case hitachi_ac1_remote_model_t::R_LT0541_HTA_B:
return F("R-LT0541-HTA-B");
default: return kUnknownStr;
}
break;
case decode_type_t::LG:
case decode_type_t::LG2:
switch (model) {
Expand Down
Loading

0 comments on commit 23697d8

Please sign in to comment.