Skip to content

Commit

Permalink
FUJITSU: Improve handling of 10C Heat mode. (#1788)
Browse files Browse the repository at this point in the history
* Better detect 10C heat mode.
* Report the temp as 10C when we detect it.
* Allow 10C heat mode to be activated via `IRac` interface.
  - Requires the following settings to activtate:
    - Suitable model (e.g. ARRAH2E or ARREW4E)
    - Mode: Fan
    - Fan Speed: Auto
    - Clean: True
    - SwingV: Off
    - SwingH: Off

* Update supported fujitsu models.
* Unit tests adjusted and added.

For #1780
  • Loading branch information
crankyoldgit authored May 6, 2022
1 parent 8b35396 commit 452a502
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ struct state_t {

/// Fujitsu A/C model numbers
enum fujitsu_ac_remote_model_t {
ARRAH2E = 1, ///< (1) AR-RAH2E, AR-RAC1E, AR-RAE1E, AR-RCE1E (Default)
ARRAH2E = 1, ///< (1) AR-RAH2E, AR-RAC1E, AR-RAE1E, AR-RCE1E, AR-RAH2U,
///< AR-REG1U (Default)
///< Warning: Use on incorrect models can cause the A/C to lock
///< up, requring the A/C to be physically powered off to fix.
///< e.g. AR-RAH1U may lock up with a Swing command.
Expand Down
40 changes: 32 additions & 8 deletions src/ir_Fujitsu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,13 @@ void IRFujitsuAC::checkSum(void) {
}
}
if (_model != fujitsu_ac_remote_model_t::ARRY4) {
if (_model != fujitsu_ac_remote_model_t::ARREW4E) _.Clean = false;
switch (_model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
break;
default:
_.Clean = false;
}
_.Filter = false;
}
// Set the On/Off/Sleep timer Nr of mins.
Expand Down Expand Up @@ -290,7 +296,8 @@ void IRFujitsuAC::buildFromState(const uint16_t length) {
setCmd(kFujitsuAcCmdStayOn);
// Currently the only way we know how to tell ARRAH2E & ARRY4 apart is if
// either the raw Filter or Clean setting is on.
if (_model == fujitsu_ac_remote_model_t::ARRAH2E && (_.Filter || _.Clean))
if (_model == fujitsu_ac_remote_model_t::ARRAH2E && (_.Filter || _.Clean) &&
!get10CHeat())
setModel(fujitsu_ac_remote_model_t::ARRY4);
if (_state_length == kFujitsuAcStateLength && _.OutsideQuiet)
setModel(fujitsu_ac_remote_model_t::ARREB1E);
Expand Down Expand Up @@ -578,7 +585,7 @@ void IRFujitsuAC::setFilter(const bool on) {
bool IRFujitsuAC::getFilter(void) const {
switch (_model) {
case fujitsu_ac_remote_model_t::ARRY4: return _.Filter;
default: return false;
default: return false;
}
}

Expand All @@ -587,6 +594,7 @@ bool IRFujitsuAC::getFilter(void) const {
void IRFujitsuAC::set10CHeat(const bool on) {
switch (_model) {
// Only selected models support this.
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
setClean(on); // 10C Heat uses the same bit as Clean
if (on) {
Expand All @@ -605,6 +613,7 @@ void IRFujitsuAC::set10CHeat(const bool on) {
/// @return true, the setting is on. false, the setting is off.
bool IRFujitsuAC::get10CHeat(void) const {
switch (_model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
return (_.Clean && _.Power && _.Mode == kFujitsuAcModeFan &&
_.Fan == kFujitsuAcFanAuto && _.Swing == kFujitsuAcSwingOff);
Expand Down Expand Up @@ -810,7 +819,11 @@ stdAc::state_t IRFujitsuAC::toCommon(const stdAc::state_t *prev) {
if (isLongCode() || prev == NULL) {
result.mode = toCommonMode(_.Mode);
result.celsius = getCelsius();
result.degrees = getTemp();
{
const float minHeat = result.celsius ? kFujitsuAcMinHeat
: kFujitsuAcMinHeatF;
result.degrees = get10CHeat() ? minHeat : getTemp();
}
result.fanspeed = toCommonFanSpeed(_.Fan);
uint8_t swing = _.Swing;
switch (result.model) {
Expand Down Expand Up @@ -848,7 +861,7 @@ stdAc::state_t IRFujitsuAC::toCommon(const stdAc::state_t *prev) {
/// @return A human readable string.
String IRFujitsuAC::toString(void) const {
String result = "";
result.reserve(100); // Reserve some heap for the string to reduce fragging.
result.reserve(180); // Reserve some heap for the string to reduce fragging.
fujitsu_ac_remote_model_t model = _model;
result += addModelToString(decode_type_t::FUJITSU_AC, model, false);
result += addIntToString(_.Id, kIdStr);
Expand All @@ -857,7 +870,12 @@ String IRFujitsuAC::toString(void) const {
result += addModeToString(_.Mode, kFujitsuAcModeAuto, kFujitsuAcModeCool,
kFujitsuAcModeHeat, kFujitsuAcModeDry,
kFujitsuAcModeFan);
result += addTempFloatToString(getTemp(), getCelsius());
{
const bool isCelsius = getCelsius();
const float minHeat = isCelsius ? kFujitsuAcMinHeat : kFujitsuAcMinHeatF;
result += addTempFloatToString(get10CHeat() ? minHeat : getTemp(),
isCelsius);
}
result += addFanToString(_.Fan, kFujitsuAcFanHigh, kFujitsuAcFanLow,
kFujitsuAcFanAuto, kFujitsuAcFanQuiet,
kFujitsuAcFanMed);
Expand All @@ -874,8 +892,14 @@ String IRFujitsuAC::toString(void) const {
result += addBoolToString(getFilter(), kFilterStr);
// FALL THRU
default: // e.g. ARREW4E
if (model == fujitsu_ac_remote_model_t::ARREW4E)
result += addBoolToString(get10CHeat(), k10CHeatStr);
switch (model) {
case fujitsu_ac_remote_model_t::ARRAH2E:
case fujitsu_ac_remote_model_t::ARREW4E:
result += addBoolToString(get10CHeat(), k10CHeatStr);
break;
default:
break;
}
result += addIntToString(_.Swing, kSwingStr);
result += kSpaceLBraceStr;
switch (_.Swing) {
Expand Down
4 changes: 4 additions & 0 deletions src/ir_Fujitsu.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
// Brand: Fujitsu, Model: AR-DL10 remote (ARDB1)
// Brand: Fujitsu, Model: ASU30C1 A/C (ARDB1)
// Brand: Fujitsu, Model: AR-RAH1U remote (ARREB1E)
// Brand: Fujitsu, Model: AR-RAH2U remote (ARRAH2E)
// Brand: Fujitsu, Model: ASU12RLF A/C (ARREB1E)
// Brand: Fujitsu, Model: AR-REW4E remote (ARREW4E)
// Brand: Fujitsu, Model: ASYG09KETA-B A/C (ARREW4E)
// Brand: Fujitsu, Model: AR-REB4E remote (ARREB1E)
// Brand: Fujitsu, Model: ASTG09K A/C (ARREW4E)
// Brand: Fujitsu, Model: ASTG18K A/C (ARREW4E)
// Brand: Fujitsu, Model: AR-REW1E remote (ARREW4E)
// Brand: Fujitsu, Model: AR-REG1U remote (ARRAH2E)

#ifndef IR_FUJITSU_H_
#define IR_FUJITSU_H_
Expand Down Expand Up @@ -128,9 +130,11 @@ const uint8_t kFujitsuAcFanMed = 0x02;
const uint8_t kFujitsuAcFanLow = 0x03;
const uint8_t kFujitsuAcFanQuiet = 0x04;

const float kFujitsuAcMinHeat = 10; // 10C
const float kFujitsuAcMinTemp = 16; // 16C
const float kFujitsuAcMaxTemp = 30; // 30C
const uint8_t kFujitsuAcTempOffsetC = kFujitsuAcMinTemp;
const float kFujitsuAcMinHeatF = 50; // 50F
const float kFujitsuAcMinTempF = 60; // 60F
const float kFujitsuAcMaxTempF = 88; // 88F
const uint8_t kFujitsuAcTempOffsetF = 44;
Expand Down
19 changes: 10 additions & 9 deletions test/IRac_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,9 +623,9 @@ TEST(TestIRac, Fujitsu) {
"Model: 2 (ARDB1), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Command: N/A";
std::string arrah2e_expected =
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A, "
"Sleep Timer: 03:00";
"Model: 1 (ARRAH2E), Id: 0, Power: On, Mode: 3 (Fan), Temp: 10C, "
"Fan: 0 (Auto), Clean: Off, Filter: Off, 10C Heat: On, "
"Swing: 0 (Off), Command: N/A, Sleep Timer: 03:00";
std::string arry4_expected =
"Model: 5 (ARRY4), Id: 0, Power: On, Mode: 1 (Cool), Temp: 19C, "
"Fan: 2 (Medium), Clean: On, Filter: On, Swing: 0 (Off), Command: N/A";
Expand Down Expand Up @@ -658,20 +658,21 @@ TEST(TestIRac, Fujitsu) {
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));

ac._irsend.reset();
// Try to set the device to 10C Heat mode.
irac.fujitsu(&ac,
ARRAH2E, // Model
true, // Power
stdAc::opmode_t::kCool, // Mode
stdAc::opmode_t::kFan, // Mode (Fan needed for 10C Heat)
true, // Celsius
19, // Degrees
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kOff, // Vertical swing
stdAc::swingh_t::kOff, // Horizontal swing
19, // Degrees (Ignored in 10C Heat)
stdAc::fanspeed_t::kAuto, // Fan speed (Auto needed for 10C)
stdAc::swingv_t::kOff, // Vertical swing (Ditto)
stdAc::swingh_t::kOff, // Horizontal swing (Ditto)
false, // Quiet
false, // Turbo (Powerful)
false, // Econo
true, // Filter
true, // Clean
true, // Clean (Needed for 10C Heat)
3 * 60); // Sleep
ASSERT_EQ(arrah2e_expected, ac.toString());
ac._irsend.makeDecodeResult();
Expand Down
Loading

0 comments on commit 452a502

Please sign in to comment.