From 019da61a0f2efedf9d873da973f507b3064b0fb2 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 01:39:46 +0800 Subject: [PATCH 1/8] Add support of Toshiba Remote Control B --- src/ir_Toshiba.cpp | 20 +++++++++++++++++++- src/ir_Toshiba.h | 11 ++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index c9672bcab..0f421da49 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -104,7 +104,8 @@ void IRToshibaAC::send(const uint16_t repeat) { uint16_t IRToshibaAC::getInternalStateLength(const uint8_t state[], const uint16_t size) { if (size < kToshibaAcLengthByte) return 0; - return std::min((uint16_t)(state[kToshibaAcLengthByte] + kToshibaAcMinLength), + // Fix: Extract the last 4 bits instead + return std::min((uint16_t)((state[kToshibaAcLengthByte] & 0xF) + kToshibaAcMinLength), kToshibaACStateLengthLong); } @@ -493,6 +494,23 @@ String IRToshibaAC::toString(void) const { return result; } +void IRToshibaAC::setRemoteControl(const uint8_t remote_type) { + switch (remote_type) + { + case kToshibaAcRemoteA: + case kToshibaAcRemoteB: + _.Remote = remote_type; + break; + default: + _.Remote = kToshibaAcRemoteA; + break; + } +} + +uint8_t IRToshibaAC::getRemoteControl() const { + return _.Remote; +} + #if DECODE_TOSHIBA_AC /// Decode the supplied Toshiba A/C message. /// Status: STABLE / Working. diff --git a/src/ir_Toshiba.h b/src/ir_Toshiba.h index 1314cf54d..eba644213 100644 --- a/src/ir_Toshiba.h +++ b/src/ir_Toshiba.h @@ -53,7 +53,11 @@ union ToshibaProtocol{ ///< 1 (56 bit message) ///< 3 (72 bit message) ///< 4 (80 bit message) - uint8_t Length :8; + uint8_t Length :4; + // Toshiba remote type + // 0 - Remote control A + // 1 - Remote control B + uint8_t Remote :4; // Byte[3] - The bit-inverted value of the "length" byte. uint8_t :8; // Byte[4] @@ -111,6 +115,9 @@ const uint8_t kToshibaAcFanMax = 5; // 0b101 const uint8_t kToshibaAcTurboOn = 1; // 0b01 const uint8_t kToshibaAcEconoOn = 3; // 0b11 +const uint8_t kToshibaAcRemoteA = 0; // 0b0000 +const uint8_t kToshibaAcRemoteB = 1; // 0b0001 + // Legacy defines. (Deprecated) #define TOSHIBA_AC_AUTO kToshibaAcAuto #define TOSHIBA_AC_COOL kToshibaAcCool @@ -140,6 +147,8 @@ class IRToshibaAC { void begin(void); void on(void); void off(void); + void setRemoteControl(const uint8_t remote_type); + uint8_t getRemoteControl() const; void setPower(const bool on); bool getPower(void) const; void setTemp(const uint8_t degrees); From 5a0844cca3d8b0788e8a6eca48dfa3d9b65f0ddf Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 01:59:09 +0800 Subject: [PATCH 2/8] Fix linting issues --- src/ir_Toshiba.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index 0f421da49..1e8ffc492 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -105,8 +105,8 @@ uint16_t IRToshibaAC::getInternalStateLength(const uint8_t state[], const uint16_t size) { if (size < kToshibaAcLengthByte) return 0; // Fix: Extract the last 4 bits instead - return std::min((uint16_t)((state[kToshibaAcLengthByte] & 0xF) + kToshibaAcMinLength), - kToshibaACStateLengthLong); + return std::min((uint16_t)((state[kToshibaAcLengthByte] & 0xF) + + kToshibaAcMinLength), kToshibaACStateLengthLong); } /// Get the length of the current internal state per the protocol structure. @@ -495,8 +495,7 @@ String IRToshibaAC::toString(void) const { } void IRToshibaAC::setRemoteControl(const uint8_t remote_type) { - switch (remote_type) - { + switch (remote_type) { case kToshibaAcRemoteA: case kToshibaAcRemoteB: _.Remote = remote_type; From c74689df5546906cac2e166906ee6211901df9f4 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 02:00:52 +0800 Subject: [PATCH 3/8] Fix linting issues --- src/ir_Toshiba.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index 1e8ffc492..bff423b6e 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -105,7 +105,7 @@ uint16_t IRToshibaAC::getInternalStateLength(const uint8_t state[], const uint16_t size) { if (size < kToshibaAcLengthByte) return 0; // Fix: Extract the last 4 bits instead - return std::min((uint16_t)((state[kToshibaAcLengthByte] & 0xF) + return std::min((uint16_t)((state[kToshibaAcLengthByte] & 0xF) + kToshibaAcMinLength), kToshibaACStateLengthLong); } From 747df8231f180d54048ad66a4e11ed7de41163e6 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 21:55:46 +0800 Subject: [PATCH 4/8] Add remote control type in toString() function --- src/IRtext.cpp | 7 +++++++ src/IRtext.h | 3 +++ src/ir_Toshiba.cpp | 10 ++++++++++ src/locale/defaults.h | 9 +++++++++ 4 files changed, 29 insertions(+) diff --git a/src/IRtext.cpp b/src/IRtext.cpp index 9cb39b772..d0bbd796f 100644 --- a/src/IRtext.cpp +++ b/src/IRtext.cpp @@ -217,6 +217,13 @@ IRTEXT_CONST_STRING(kTimerActiveDaysStr, D_STR_TIMER_ACTIVE_DAYS); ///< "TimerActiveDays" IRTEXT_CONST_STRING(kKeyStr, D_STR_KEY); ///< "Key" IRTEXT_CONST_STRING(kValueStr, D_STR_VALUE); ///< "Value" +///< "Remote Control Types" +IRTEXT_CONST_STRING(kRemoteControlType, D_STR_REMOTECONTROLTYPE); ///< + ///< "Remote Control Type" +IRTEXT_CONST_STRING(kToshibaRemoteControlTypeA, D_STR_TOSHIBAREMOTETYPEA); + ///< "A" +IRTEXT_CONST_STRING(kToshibaRemoteControlTypeB, D_STR_TOSHIBAREMOTETYPEB); + ///< "B" // Separators & Punctuation const char kTimeSep = D_CHR_TIME_SEP; ///< ':' diff --git a/src/IRtext.h b/src/IRtext.h index 15d2690b7..c57fc2af3 100644 --- a/src/IRtext.h +++ b/src/IRtext.h @@ -238,6 +238,9 @@ extern IRTEXT_CONST_PTR(kUpStr); extern IRTEXT_CONST_PTR(kUpperStr); extern IRTEXT_CONST_PTR(kUpperMiddleStr); extern IRTEXT_CONST_PTR(kValueStr); +extern IRTEXT_CONST_PTR(kRemoteControlType); +extern IRTEXT_CONST_PTR(kToshibaRemoteControlTypeA); +extern IRTEXT_CONST_PTR(kToshibaRemoteControlTypeB); extern IRTEXT_CONST_PTR(kV9014557AStr); extern IRTEXT_CONST_PTR(kV9014557BStr); extern IRTEXT_CONST_PTR(kVaneStr); diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index bff423b6e..daf993982 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -491,6 +491,16 @@ String IRToshibaAC::toString(void) const { result += addBoolToString(getEcono(), kEconoStr); result += addBoolToString(getFilter(), kFilterStr); } + switch (getRemoteControl()) { + case kToshibaAcRemoteA: + result += addLabeledString(kToshibaRemoteControlTypeA, kRemoteControlType); + break; + case kToshibaAcRemoteB: + result += addLabeledString(kToshibaRemoteControlTypeB, kRemoteControlType); + break; + default: + break; + } return result; } diff --git a/src/locale/defaults.h b/src/locale/defaults.h index 438cc5da3..bb9dc03e9 100644 --- a/src/locale/defaults.h +++ b/src/locale/defaults.h @@ -478,6 +478,15 @@ D_STR_INDIRECT " " D_STR_MODE #ifndef D_STR_VALUE #define D_STR_VALUE "Value" #endif // D_STR_VALUE +#ifndef D_STR_REMOTECONTROLTYPE +#define D_STR_REMOTECONTROLTYPE "Remote Control Type" +#endif // D_STR_REMOTECONTROLTYPE +#ifndef D_STR_TOSHIBAREMOTETYPEA +#define D_STR_TOSHIBAREMOTETYPEA "A" +#endif // D_STR_TOSHIBAREMOTETYPEA +#ifndef D_STR_TOSHIBAREMOTETYPEB +#define D_STR_TOSHIBAREMOTETYPEB "B" +#endif // D_STR_TOSHIBAREMOTETYPEB // Compound words/phrases/descriptions from pre-defined words. // Note: Obviously these need to be defined *after* their component words. From 4bb15247fbbf4f33e24c31acbbefc69e05568d29 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 21:57:58 +0800 Subject: [PATCH 5/8] Fix linting issues --- src/ir_Toshiba.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index daf993982..9f9c4751c 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -493,10 +493,12 @@ String IRToshibaAC::toString(void) const { } switch (getRemoteControl()) { case kToshibaAcRemoteA: - result += addLabeledString(kToshibaRemoteControlTypeA, kRemoteControlType); + result += addLabeledString(kToshibaRemoteControlTypeA, + kRemoteControlType); break; case kToshibaAcRemoteB: - result += addLabeledString(kToshibaRemoteControlTypeB, kRemoteControlType); + result += addLabeledString(kToshibaRemoteControlTypeB, + kRemoteControlType); break; default: break; From 05250b09d4890a4039b5abcc8442ce886747feb6 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 22:04:21 +0800 Subject: [PATCH 6/8] Fix unit tests --- test/ir_Toshiba_test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/ir_Toshiba_test.cpp b/test/ir_Toshiba_test.cpp index 4a63780d5..95566a200 100644 --- a/test/ir_Toshiba_test.cpp +++ b/test/ir_Toshiba_test.cpp @@ -380,7 +380,7 @@ TEST(TestDecodeToshibaAC, SyntheticExample) { EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( "Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: Off, " - "Econo: Off, Filter: Off", + "Econo: Off, Filter: Off, Remote Control Type: A", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -628,7 +628,7 @@ TEST(TestDecodeToshibaAC, RealLongExample) { EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( "Temp: 22C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: On, " - "Econo: Off, Filter: Off", + "Econo: Off, Filter: Off, Remote Control Type: A", IRAcUtils::resultAcToString(&irsend.capture)); } @@ -718,7 +718,7 @@ TEST(TestDecodeToshibaAC, RealShortExample) { EXPECT_EQ(kToshibaACBitsShort, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( - "Temp: 17C, Swing(V): 0 (Step)", + "Temp: 17C, Swing(V): 0 (Step), Remote Control Type: A", IRAcUtils::resultAcToString(&irsend.capture)); } @@ -733,7 +733,7 @@ TEST(TestToshibaACClass, ConstructLongState) { ac.setEcono(true); EXPECT_EQ( "Temp: 29C, Power: On, Mode: 2 (Dry), Fan: 2 (UNKNOWN), " - "Turbo: Off, Econo: On, Filter: Off", + "Turbo: Off, Econo: On, Filter: Off, Remote Control Type: A", ac.toString()); EXPECT_EQ(kToshibaACStateLengthLong, ac.getStateLength()); const uint8_t expectedState[kToshibaACStateLengthLong] = { @@ -784,7 +784,7 @@ TEST(TestDecodeToshibaAC, RealExample_WHUB03NJ) { EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( "Temp: 20C, Power: Off, Fan: 0 (Auto), Turbo: Off, Econo: Off, " - "Filter: Off", + "Filter: Off, Remote Control Type: A", IRAcUtils::resultAcToString(&irsend.capture)); } @@ -805,7 +805,7 @@ TEST(TestToshibaACClass, SwingCodes) { ac.setSwing(kToshibaAcSwingOn); EXPECT_EQ( - "Temp: 17C, Swing(V): 1 (On)", + "Temp: 17C, Swing(V): 1 (On), Remote Control Type: A", ac.toString()); EXPECT_EQ(kToshibaACStateLengthShort, ac.getStateLength()); const uint8_t swingOnState[kToshibaACStateLengthShort] = { @@ -815,7 +815,7 @@ TEST(TestToshibaACClass, SwingCodes) { ac.setSwing(kToshibaAcSwingOff); EXPECT_EQ( - "Temp: 17C, Swing(V): 2 (Off)", + "Temp: 17C, Swing(V): 2 (Off), Remote Control Type: A", ac.toString()); EXPECT_EQ(kToshibaACStateLengthShort, ac.getStateLength()); const uint8_t swingOffState[kToshibaACStateLengthShort] = { @@ -828,7 +828,7 @@ TEST(TestToshibaACClass, SwingCodes) { ac.setRaw(swingToggleState, kToshibaACStateLengthShort); EXPECT_EQ(kToshibaAcSwingToggle, ac.getSwing()); EXPECT_EQ( - "Temp: 17C, Swing(V): 4 (Toggle)", + "Temp: 17C, Swing(V): 4 (Toggle), Remote Control Type: A", ac.toString()); } From 04e174b1823064b42ba205d3582ee0e430c8ccc6 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 22:13:12 +0800 Subject: [PATCH 7/8] Fix unit tests --- test/ir_Toshiba_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/ir_Toshiba_test.cpp b/test/ir_Toshiba_test.cpp index 95566a200..1f53b03f0 100644 --- a/test/ir_Toshiba_test.cpp +++ b/test/ir_Toshiba_test.cpp @@ -312,21 +312,21 @@ TEST(TestToshibaACClass, HumanReadableOutput) { ac.setRaw(initial_state); EXPECT_EQ("Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), " - "Turbo: Off, Econo: Off, Filter: Off", + "Turbo: Off, Econo: Off, Filter: Off, Remote Control Type: A", ac.toString()); ac.setRaw(modified_state); EXPECT_EQ("Temp: 17C, Power: On, Mode: 1 (Cool), Fan: 5 (High), " - "Turbo: Off, Econo: Off, Filter: Off", + "Turbo: Off, Econo: Off, Filter: Off, Remote Control Type: A", ac.toString()); ac.setTemp(25); ac.setFan(3); ac.setMode(kToshibaAcDry); EXPECT_EQ("Temp: 25C, Power: On, Mode: 2 (Dry), Fan: 3 (Medium), " - "Turbo: Off, Econo: Off, Filter: Off", + "Turbo: Off, Econo: Off, Filter: Off, Remote Control Type: A", ac.toString()); ac.off(); EXPECT_EQ("Temp: 25C, Power: Off, Fan: 3 (Medium), Turbo: Off, Econo: Off, " - "Filter: Off", + "Filter: Off, Remote Control Type: A", ac.toString()); } From ae89b4bb828062a9d6ddcd0a6e9cbbe5440f4d51 Mon Sep 17 00:00:00 2001 From: Jacky Sze Date: Mon, 13 May 2024 22:34:52 +0800 Subject: [PATCH 8/8] Fix unit tests --- src/ir_Toshiba.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ir_Toshiba.cpp b/src/ir_Toshiba.cpp index 9f9c4751c..250800b01 100644 --- a/src/ir_Toshiba.cpp +++ b/src/ir_Toshiba.cpp @@ -492,15 +492,13 @@ String IRToshibaAC::toString(void) const { result += addBoolToString(getFilter(), kFilterStr); } switch (getRemoteControl()) { - case kToshibaAcRemoteA: - result += addLabeledString(kToshibaRemoteControlTypeA, - kRemoteControlType); - break; case kToshibaAcRemoteB: result += addLabeledString(kToshibaRemoteControlTypeB, kRemoteControlType); break; default: + result += addLabeledString(kToshibaRemoteControlTypeA, + kRemoteControlType); break; } return result;