Skip to content

Commit

Permalink
LG: Add Swing Toggle support for Model LG6711A20083V
Browse files Browse the repository at this point in the history
* Detect swingv toggle messages and set appropriate model.
* Allow sending of swingv toggle messages.
* Update supported models info
* Various collateral updates.
* Minor code cleanup.
* Supporting unit tests.

* Needs testing on a real device.

Fixes #1770
  • Loading branch information
crankyoldgit committed Mar 7, 2022
1 parent 846daf5 commit dbe983f
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3458,6 +3458,8 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return lg_ac_remote_model_t::AKB74955603;
} else if (!STRCASECMP(str, kAkb73757604Str)) {
return lg_ac_remote_model_t::AKB73757604;
} else if (!STRCASECMP(str, kLg6711a20083vStr)) {
return lg_ac_remote_model_t::LG6711A20083V;
// Panasonic A/C families
} else if (!STRCASECMP(str, kLkeStr) ||
!STRCASECMP(str, kPanasonicLkeStr)) {
Expand Down
1 change: 1 addition & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ enum lg_ac_remote_model_t {
AKB75215403, // (2) LG2 28-bit Protocol
AKB74955603, // (3) LG2 28-bit Protocol variant
AKB73757604, // (4) LG2 Variant of AKB74955603
LG6711A20083V, // (5) Same as GE6711AR2853M, but only SwingV toggle.
};


Expand Down
2 changes: 2 additions & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ IRTEXT_CONST_STRING(kGe6711ar2853mStr, D_STR_GE6711AR2853M); ///<
IRTEXT_CONST_STRING(kAkb75215403Str, D_STR_AKB75215403); ///< "AKB75215403"
IRTEXT_CONST_STRING(kAkb74955603Str, D_STR_AKB74955603); ///< "AKB74955603"
IRTEXT_CONST_STRING(kAkb73757604Str, D_STR_AKB73757604); ///< "AKB73757604"
IRTEXT_CONST_STRING(kLg6711a20083vStr, D_STR_LG6711A20083V); ///<
///< "LG6711A20083V"
IRTEXT_CONST_STRING(kKkg9ac1Str, D_STR_KKG9AC1); ///< "KKG9AC1"
IRTEXT_CONST_STRING(kKkg29ac1Str, D_STR_KKG29AC1); ///< "KKG29AC1"
IRTEXT_CONST_STRING(kLkeStr, D_STR_LKE); ///< "LKE"
Expand Down
16 changes: 8 additions & 8 deletions src/IRtext.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2021 - David Conran (@crankyoldgit)
// Copyright 2019-2022 - David Conran (@crankyoldgit)
// This header file is to be included in files **other than** 'IRtext.cpp'.
//
// WARNING: Do not edit this file! This file is automatically generated by
Expand Down Expand Up @@ -33,6 +33,7 @@ extern IRTEXT_CONST_PTR(k8CHeatStr);
extern IRTEXT_CONST_PTR(kA705Str);
extern IRTEXT_CONST_PTR(kA903Str);
extern IRTEXT_CONST_PTR(kA907Str);
extern IRTEXT_CONST_PTR(kAbsenseDetectStr);
extern IRTEXT_CONST_PTR(kAirFlowStr);
extern IRTEXT_CONST_PTR(kAkb73757604Str);
extern IRTEXT_CONST_PTR(kAkb74955603Str);
Expand Down Expand Up @@ -74,6 +75,8 @@ extern IRTEXT_CONST_PTR(kDehumidifyStr);
extern IRTEXT_CONST_PTR(kDg11j104Str);
extern IRTEXT_CONST_PTR(kDg11j13aStr);
extern IRTEXT_CONST_PTR(kDg11j191Str);
extern IRTEXT_CONST_PTR(kDirectIndirectModeStr);
extern IRTEXT_CONST_PTR(kDirectStr);
extern IRTEXT_CONST_PTR(kDisplayTempStr);
extern IRTEXT_CONST_PTR(kDkeStr);
extern IRTEXT_CONST_PTR(kDownStr);
Expand Down Expand Up @@ -108,20 +111,23 @@ extern IRTEXT_CONST_PTR(kHourStr);
extern IRTEXT_CONST_PTR(kHumidStr);
extern IRTEXT_CONST_PTR(kIdStr);
extern IRTEXT_CONST_PTR(kIFeelStr);
extern IRTEXT_CONST_PTR(kIndirectStr);
extern IRTEXT_CONST_PTR(kInsideStr);
extern IRTEXT_CONST_PTR(kIonStr);
extern IRTEXT_CONST_PTR(kISeeStr);
extern IRTEXT_CONST_PTR(kJkeStr);
extern IRTEXT_CONST_PTR(kKkg29ac1Str);
extern IRTEXT_CONST_PTR(kKkg9ac1Str);
extern IRTEXT_CONST_PTR(kLastStr);
extern IRTEXT_CONST_PTR(kLeftMaxNoSpaceStr);
extern IRTEXT_CONST_PTR(kLeftMaxStr);
extern IRTEXT_CONST_PTR(kLeftStr);
extern IRTEXT_CONST_PTR(kLg6711a20083vStr);
extern IRTEXT_CONST_PTR(kLightStr);
extern IRTEXT_CONST_PTR(kLightToggleStr);
extern IRTEXT_CONST_PTR(kLkeStr);
extern IRTEXT_CONST_PTR(kLoStr);
extern IRTEXT_CONST_PTR(kLockStr);
extern IRTEXT_CONST_PTR(kLoStr);
extern IRTEXT_CONST_PTR(kLoudStr);
extern IRTEXT_CONST_PTR(kLowerStr);
extern IRTEXT_CONST_PTR(kLowestStr);
Expand Down Expand Up @@ -231,11 +237,5 @@ extern IRTEXT_CONST_PTR(kYbofbStr);
extern IRTEXT_CONST_PTR(kYesStr);
extern IRTEXT_CONST_PTR(kZoneFollowStr);
extern IRTEXT_CONST_PTR(kAllProtocolNamesStr);
extern IRTEXT_CONST_PTR(kISeeStr);
extern IRTEXT_CONST_PTR(kEcocoolStr);
extern IRTEXT_CONST_PTR(kAbsenseDetectStr);
extern IRTEXT_CONST_PTR(kDirectIndirectModeStr);
extern IRTEXT_CONST_PTR(kDirectStr);
extern IRTEXT_CONST_PTR(kIndirectStr);

#endif // IRTEXT_H_
1 change: 1 addition & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ namespace irutils {
case lg_ac_remote_model_t::AKB75215403: return kAkb75215403Str;
case lg_ac_remote_model_t::AKB74955603: return kAkb74955603Str;
case lg_ac_remote_model_t::AKB73757604: return kAkb73757604Str;
case lg_ac_remote_model_t::LG6711A20083V: return kLg6711a20083vStr;
default: return kUnknownStr;
}
break;
Expand Down
67 changes: 43 additions & 24 deletions src/ir_LG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ using irutils::addModeToString;
using irutils::addModelToString;
using irutils::addFanToString;
using irutils::addTempToString;
using irutils::addToggleToString;
using irutils::addSwingVToString;
using irutils::addIntToString;

Expand Down Expand Up @@ -255,6 +256,11 @@ void IRLgAc::send(const uint16_t repeat) {
_irsend.send(_protocol, getRaw(), kLgBits, repeat);
// Some models have extra/special settings & controls
switch (getModel()) {
case lg_ac_remote_model_t::LG6711A20083V:
// Only send the swing setting if we need to.
if (_swingv != _swingv_prev)
_irsend.send(_protocol, _swingv, kLgBits, repeat);
break;
case lg_ac_remote_model_t::AKB74955603:
// Only send the swing setting if we need to.
if (_swingv != _swingv_prev)
Expand Down Expand Up @@ -309,6 +315,7 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) {
_protocol = decode_type_t::LG2;
break;
case lg_ac_remote_model_t::GE6711AR2853M:
case lg_ac_remote_model_t::LG6711A20083V:
_protocol = decode_type_t::LG;
break;
default:
Expand All @@ -319,24 +326,25 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) {

/// Get the model of the A/C.
/// @return The enum of the compatible model.
lg_ac_remote_model_t IRLgAc::getModel(void) const {
return _model;
}
lg_ac_remote_model_t IRLgAc::getModel(void) const { return _model; }

/// Check if the stored code must belong to a AKB74955603 model.
/// @return true, if it is AKB74955603 message. Otherwise, false.
/// @note Internal use only.
bool IRLgAc::_isAKB74955603(void) const {
return ((_.raw & kLgAcAKB74955603DetectionMask) && _isNormal()) ||
isSwingV() || isLightToggle();
(isSwingV() && !isSwingVToggle()) || isLightToggle();
}

/// Check if the stored code must belong to a AKB73757604 model.
/// @return true, if it is AKB73757604 message. Otherwise, false.
/// @note Internal use only.
bool IRLgAc::_isAKB73757604(void) const {
return isSwingH() || isVaneSwingV();
}
bool IRLgAc::_isAKB73757604(void) const { return isSwingH() || isVaneSwingV(); }

/// Check if the stored code must belong to a LG6711A20083V model.
/// @return true, if it is LG6711A20083V message. Otherwise, false.
/// @note Internal use only.
bool IRLgAc::_isLG6711A20083V(void) const { return isSwingVToggle(); }

/// Get a copy of the internal state/code for this protocol.
/// @return The code for this protocol based on the current internal state.
Expand All @@ -353,7 +361,10 @@ void IRLgAc::setRaw(const uint32_t new_code, const decode_type_t protocol) {
// Set the default model for this protocol, if the protocol is supplied.
switch (protocol) {
case decode_type_t::LG:
setModel(lg_ac_remote_model_t::GE6711AR2853M);
if (isSwingVToggle()) // This model uses a swingv toggle message.
setModel(lg_ac_remote_model_t::LG6711A20083V);
else // Assume others are a different model.
setModel(lg_ac_remote_model_t::GE6711AR2853M);
break;
case decode_type_t::LG2:
setModel(lg_ac_remote_model_t::AKB75215403);
Expand Down Expand Up @@ -521,18 +532,22 @@ void IRLgAc::setMode(const uint8_t mode) {
}
}

/// Check if the stored code is a SwingV Toggle message.
/// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwingVToggle(void) const { return _.raw == kLgAcSwingVToggle; }

/// Check if the stored code is a Swing message.
/// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwing(void) const {
return (_.raw >> 12) == kLgAcSwingSignature;
return ((_.raw >> 12) == kLgAcSwingSignature) || isSwingVToggle();
}

/// Check if the stored code is a non-vane SwingV message.
/// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwingV(void) const {
const uint32_t code = _.raw >> kLgAcChecksumSize;
return code >= (kLgAcSwingVLowest >> kLgAcChecksumSize) &&
code < (kLgAcSwingHAuto >> kLgAcChecksumSize);
return (code >= (kLgAcSwingVLowest >> kLgAcChecksumSize) &&
code < (kLgAcSwingHAuto >> kLgAcChecksumSize)) || isSwingVToggle();
}

/// Check if the stored code is a SwingH message.
Expand Down Expand Up @@ -562,7 +577,7 @@ bool IRLgAc::isVaneSwingV(void) const {
/// @param[in] position The position/mode to set the vanes to.
void IRLgAc::setSwingV(const uint32_t position) {
// Is it a valid position code?
if (position == kLgAcSwingVOff ||
if (position == kLgAcSwingVOff || position == kLgAcSwingVToggle ||
toCommonSwingV(position) != stdAc::swingv_t::kOff) {
if (position <= 0xFF) { // It's a short code, convert it.
_swingv = (kLgAcSwingSignature << 8 | position) << kLgAcChecksumSize;
Expand Down Expand Up @@ -703,6 +718,7 @@ stdAc::swingv_t IRLgAc::toCommonSwingV(const uint32_t code) {
case kLgAcSwingVLow: return stdAc::swingv_t::kLow;
case kLgAcSwingVLowest_Short:
case kLgAcSwingVLowest: return stdAc::swingv_t::kLowest;
case kLgAcSwingVToggle:
case kLgAcSwingVSwing_Short:
case kLgAcSwingVSwing: return stdAc::swingv_t::kAuto;
default: return stdAc::swingv_t::kOff;
Expand Down Expand Up @@ -805,18 +821,21 @@ String IRLgAc::toString(void) const {
} else if (isSwingH()) {
result += addBoolToString(_swingh, kSwingHStr);
} else if (isSwingV()) {
result += addSwingVToString((uint8_t)(_swingv >> kLgAcChecksumSize),
0, // No Auto, See "swing". Unused
kLgAcSwingVHighest_Short,
kLgAcSwingVHigh_Short,
kLgAcSwingVUpperMiddle_Short,
kLgAcSwingVMiddle_Short,
0, // Unused
kLgAcSwingVLow_Short,
kLgAcSwingVLowest_Short,
kLgAcSwingVOff_Short,
kLgAcSwingVSwing_Short,
0, 0);
if (isSwingVToggle())
result += addToggleToString(isSwingVToggle(), kSwingVStr);
else
result += addSwingVToString((uint8_t)(_swingv >> kLgAcChecksumSize),
0, // No Auto, See "swing". Unused
kLgAcSwingVHighest_Short,
kLgAcSwingVHigh_Short,
kLgAcSwingVUpperMiddle_Short,
kLgAcSwingVMiddle_Short,
0, // Unused
kLgAcSwingVLow_Short,
kLgAcSwingVLowest_Short,
kLgAcSwingVOff_Short,
kLgAcSwingVSwing_Short,
0, 0);
} else if (isVaneSwingV()) {
const uint8_t vane = getVaneCode(_.raw) / kLgAcVaneSwingVSize;
result += addIntToString(vane, kVaneStr);
Expand Down
10 changes: 7 additions & 3 deletions src/ir_LG.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1513

// Supports:
// Brand: LG, Model: 6711A20083V remote (LG)
// Brand: LG, Model: 6711A20083V remote (LG - LG6711A20083V)
// Brand: LG, Model: TS-H122ERM1 remote (LG - LG6711A20083V)
// Brand: LG, Model: AKB74395308 remote (LG2)
// Brand: LG, Model: S4-W12JA3AA A/C (LG2)
// Brand: LG, Model: AKB75215403 remote (LG2)
Expand All @@ -17,8 +18,8 @@
// Brand: LG, Model: AKB73757604 remote (LG2 - AKB73757604)
// Brand: LG, Model: AKB73315611 remote (LG2 - AKB74955603)
// Brand: LG, Model: MS05SQ NW0 A/C (LG2 - AKB74955603)
// Brand: General Electric, Model: AG1BH09AW101 Split A/C (LG)
// Brand: General Electric, Model: 6711AR2853M A/C Remote (LG)
// Brand: General Electric, Model: AG1BH09AW101 A/C (LG - GE6711AR2853M)
// Brand: General Electric, Model: 6711AR2853M Remote (LG - GE6711AR2853M)

#ifndef IR_LG_H_
#define IR_LG_H_
Expand Down Expand Up @@ -83,6 +84,7 @@ const uint32_t kLgAcSwingVHighest = 0x881309D;
const uint32_t kLgAcSwingVSwing = 0x8813149;
const uint32_t kLgAcSwingVAuto = kLgAcSwingVSwing;
const uint32_t kLgAcSwingVOff = 0x881315A;
const uint32_t kLgAcSwingVToggle = 0x8810001;
const uint8_t kLgAcSwingVLowest_Short = 0x04;
const uint8_t kLgAcSwingVLow_Short = 0x05;
const uint8_t kLgAcSwingVMiddle_Short = 0x06;
Expand Down Expand Up @@ -144,6 +146,7 @@ class IRLgAc {
void setSwingH(const bool on);
bool getSwingH(void) const;
bool isSwingV(void) const;
bool isSwingVToggle(void) const;
bool isVaneSwingV(void) const;
void setSwingV(const uint32_t position);
uint32_t getSwingV(void) const;
Expand Down Expand Up @@ -192,6 +195,7 @@ class IRLgAc {
void _setTemp(const uint8_t value);
bool _isAKB74955603(void) const;
bool _isAKB73757604(void) const;
bool _isLG6711A20083V(void) const;
bool _isNormal(void) const;
};

Expand Down
3 changes: 3 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@ D_STR_INDIRECT " " D_STR_MODE
#ifndef D_STR_AKB73757604
#define D_STR_AKB73757604 "AKB73757604"
#endif // D_STR_AKB73757604
#ifndef D_STR_LG6711A20083V
#define D_STR_LG6711A20083V "LG6711A20083V"
#endif // D_STR_LG6711A20083V
#ifndef D_STR_KKG9AC1
#define D_STR_KKG9AC1 "KKG9AC1"
#endif // D_STR_KKG9AC1
Expand Down
21 changes: 21 additions & 0 deletions test/ir_LG_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,10 @@ TEST(TestUtils, Housekeeping) {
IRac::strToModel(irutils::modelToStr(
decode_type_t::LG2,
lg_ac_remote_model_t::AKB73757604).c_str()));
ASSERT_EQ(lg_ac_remote_model_t::LG6711A20083V,
IRac::strToModel(irutils::modelToStr(
decode_type_t::LG,
lg_ac_remote_model_t::LG6711A20083V).c_str()));
}

TEST(TestIRLgAcClass, KnownExamples) {
Expand Down Expand Up @@ -1163,3 +1167,20 @@ TEST(TestIRLgAcClass, Issue1737) {
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
EXPECT_TRUE(result.power);
}

TEST(TestIRLgAcClass, SwingVToggle) {
IRLgAc ac(kGpioUnused);
ac.begin();

ac.setModel(lg_ac_remote_model_t::GE6711AR2853M);
EXPECT_FALSE(ac.isSwingVToggle());
EXPECT_FALSE(ac._isLG6711A20083V());
EXPECT_EQ(lg_ac_remote_model_t::GE6711AR2853M, ac.getModel());

ac.setRaw(kLgAcSwingVToggle, decode_type_t::LG);
EXPECT_TRUE(ac.isSwingVToggle());
EXPECT_TRUE(ac._isLG6711A20083V());
EXPECT_EQ(lg_ac_remote_model_t::LG6711A20083V, ac.getModel());

EXPECT_EQ("Model: 5 (LG6711A20083V), Swing(V): Toggle", ac.toString());
}

0 comments on commit dbe983f

Please sign in to comment.