Skip to content

Commit

Permalink
Kelon: Fix minor lint issues
Browse files Browse the repository at this point in the history
  • Loading branch information
depau committed Jun 14, 2021
1 parent d501c8d commit b9451cc
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ namespace irutils {
/// @param[in] precomma Should the output string start with ", " or not?
/// @return The resulting String.
String addSignedIntToString(const int16_t value, const String label,
const bool precomma) {
const bool precomma) {
return addLabeledString(int64ToString(value), label, precomma);
}

Expand Down
62 changes: 43 additions & 19 deletions src/ir_Kelon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

/// @file
/// @brief Support for Kelan AC protocol.
/// Both sending and decoding should be functional for models of series KELON ON/OFF 9000-12000.
/// Both sending and decoding should be functional for models of series
/// KELON ON/OFF 9000-12000.
/// All features of the standard remote are implemented.
///
/// @note Unsupported:
/// - Explicit on/off due to AC unit limitations
/// - Explicit swing position due to AC unit limitations
/// - Fahrenheit.

#include <algorithm>

#include "ir_Kelon.h"

#include "IRrecv.h"
Expand Down Expand Up @@ -43,7 +46,8 @@ const uint16_t kKelonFreq = 38000;
/// @param[in] data The data to be transmitted.
/// @param[in] nbits Nr. of bits of data to be sent.
/// @param[in] repeat The number of times the command is to be repeated.
void IRsend::sendKelon(const uint64_t data, const uint16_t nbits, const uint16_t repeat) {
void IRsend::sendKelon(const uint64_t data, const uint16_t nbits,
const uint16_t repeat) {
sendGeneric(kKelonHdrMark, kKelonHdrSpace,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
Expand Down Expand Up @@ -90,7 +94,8 @@ bool IRrecv::decodeKelon(decode_results *results, uint16_t offset,
/// @param[in] pin GPIO to be used when sending.
/// @param[in] inverted Is the output signal to be inverted?
/// @param[in] use_modulation Is frequency modulation to be used?
IRKelonAc::IRKelonAc(const uint16_t pin, const bool inverted, const bool use_modulation)
IRKelonAc::IRKelonAc(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend{pin, inverted, use_modulation}, _{} { stateReset(); }

/// Reset the internals of the object to a known good state.
Expand Down Expand Up @@ -181,7 +186,8 @@ void IRKelonAc::setFan(const uint8_t speed) {
uint8_t fan = std::min(speed, kKelonFanMax);

_previousFan = _.Fan;
// Note: Kelon fan speeds are backwards! This code maps the range 0,1:3 to 0,3:1 to save the API's user's sanity.
// Note: Kelon fan speeds are backwards! This code maps the range 0,1:3 to
// 0,3:1 to save the API's user's sanity.
_.Fan = ((static_cast<int16_t>(fan) - 4) * -1) % 4;
}

Expand All @@ -207,16 +213,19 @@ void IRKelonAc::setDryGrade(const int8_t grade) {
_.DehumidifierGrade = outval;
}

/// Get the current dehumidification intensity setting. In smart mode, this controls the temperature adjustment.
/// Get the current dehumidification intensity setting. In smart mode, this
/// controls the temperature adjustment.
/// @return The current dehumidification intensity.
int8_t IRKelonAc::getDryGrade() const {
return (_.DehumidifierGrade & 0b011) * ((_.DehumidifierGrade & 0b100) ? -1 : 1); // NOLINT(cppcoreguidelines-narrowing-conversions)
return static_cast<int8_t>(_.DehumidifierGrade & 0b011) *
((_.DehumidifierGrade & 0b100) ? -1 : 1);
}

/// Set the desired operation mode.
/// @param[in] mode The desired operation mode.
void IRKelonAc::setMode(const uint8_t mode) {
if (_.Mode == kKelonModeSmart || _.Mode == kKelonModeFan || _.Mode == kKelonModeDry) {
if (_.Mode == kKelonModeSmart || _.Mode == kKelonModeFan ||
_.Mode == kKelonModeDry) {
_.Temperature = _previousTemp;
}
if (_.SuperCoolEnabled1) {
Expand Down Expand Up @@ -298,8 +307,10 @@ bool IRKelonAc::getSupercool() const {
return _.SuperCoolEnabled1;
}

/// Set the timer time and enable it. Timer is an off timer if the unit is on, it is an on timer if the unit is off.
/// @param[in] mins Nr. of minutes (only multiples of 30m are supported for < 10h, then only multiples of 60m)
/// Set the timer time and enable it. Timer is an off timer if the unit is on,
/// it is an on timer if the unit is off.
/// Only multiples of 30m are supported for < 10h, then only multiples of 60m
/// @param[in] mins Nr. of minutes
void IRKelonAc::setTimer(uint16_t mins) {
const uint16_t minutes = std::min(static_cast<int>(mins), 24 * 60);

Expand All @@ -315,8 +326,10 @@ void IRKelonAc::setTimer(uint16_t mins) {
setTimerEnabled(true);
}

/// Get the set timer. Timer set time is deleted once the command is sent, so calling this after send() will return 0.
/// The AC unit will continue keeping track of the remaining time unless it is later disabled.
/// Get the set timer. Timer set time is deleted once the command is sent, so
/// calling this after send() will return 0.
/// The AC unit will continue keeping track of the remaining time unless it is
/// later disabled.
/// @return The timer set minutes
uint16_t IRKelonAc::getTimer() const {
if (_.TimerHours >= 10) {
Expand All @@ -325,7 +338,8 @@ uint16_t IRKelonAc::getTimer() const {
return (((uint16_t) _.TimerHours) * 60) + (_.TimerHalfHour ? 30 : 0);
}

/// Enable or disable the timer. Note that in order to enable the timer the minutes must be set with setTimer().
/// Enable or disable the timer. Note that in order to enable the timer the
/// minutes must be set with setTimer().
/// @param[in] on Whether to enable or disable the timer
void IRKelonAc::setTimerEnabled(bool on) {
_.TimerEnabled = on;
Expand Down Expand Up @@ -436,7 +450,8 @@ stdAc::state_t IRKelonAc::toCommon() const {
// Not supported.
result.power = true; // N/A, AC only supports toggling it
result.swingv = stdAc::swingv_t::kAuto; // N/A, AC only supports toggling it
result.swingh = stdAc::swingh_t::kOff; // N/A, horizontal air direction can only be set by manually adjusting the flaps
// N/A, horizontal air direction can only be set by manually adjusting it
result.swingh = stdAc::swingh_t::kOff;
result.light = true;
result.beep = true;
result.quiet = false;
Expand All @@ -451,15 +466,24 @@ stdAc::state_t IRKelonAc::toCommon() const {
/// @return A String.
String IRKelonAc::toString() const {
String result = "";
result.reserve(160); // Reserve some heap for the string to reduce fragging.
// Reserve some heap for the string to reduce fragging.
result.reserve(160);
result += addTempToString(getTemp(), true, false);
result += addModeToString(_.Mode, kKelonModeSmart, kKelonModeCool, kKelonModeHeat, kKelonModeDry, kKelonModeFan);
result += addFanToString(_.Fan, kKelonFanMax, kKelonFanMin, kKelonFanAuto, -1, kKelonFanMedium, kKelonFanMax);
result += addModeToString(_.Mode, kKelonModeSmart, kKelonModeCool,
kKelonModeHeat, kKelonModeDry, kKelonModeFan);
result += addFanToString(_.Fan, kKelonFanMax, kKelonFanMin, kKelonFanAuto,
-1, kKelonFanMedium, kKelonFanMax);
result += addBoolToString(_.SleepEnabled, kSleepStr);
result += addSignedIntToString(getDryGrade(), kDryStr);
result += addLabeledString(getTimerEnabled()
? (getTimer() > 0 ? minsToString(getTimer()) : kOnStr)
: kOffStr,kTimerStr);
result += addLabeledString(
getTimerEnabled()
? (
getTimer() > 0
? minsToString(getTimer())
: kOnStr
)
: kOffStr,
kTimerStr);
result += addBoolToString(getSupercool(), kTurboStr);
if (getTogglePower()) {
result += addBoolToString(true, kPowerToggleStr);
Expand Down
68 changes: 34 additions & 34 deletions test/ir_Kelon_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ TEST(TestSendKelon, SendDataOnly) {
IRsendTest irsend(kGpioUnused);
irsend.begin();

// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off, Turbo: Off
// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off,
// Turbo: Off
irsend.reset();
irsend.sendKelon(0x82000683);
EXPECT_EQ(
Expand All @@ -26,10 +27,10 @@ TEST(TestSendKelon, SendDataOnly) {
"m560s600m560s1680m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s100000",
irsend.outputStr()
);
irsend.outputStr());

// Temp: 18C, Mode: 2 (Cool), Fan: 1 (Low), Sleep: Off, Dry: 0, Timer: Off, Turbo: On
// Temp: 18C, Mode: 2 (Cool), Fan: 1 (Low), Sleep: Off, Dry: 0, Timer: Off,
// Turbo: On
irsend.reset();
irsend.sendKelon(0x900002010683);
EXPECT_EQ(
Expand All @@ -41,10 +42,10 @@ TEST(TestSendKelon, SendDataOnly) {
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s1680m560s600m560s600m560s1680m560s100000",
irsend.outputStr()
);
irsend.outputStr());

// Temp: 23C, Mode: 0 (Heat), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off, Turbo: Off, Power Toggle: On
// Temp: 23C, Mode: 0 (Heat), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off,
// Turbo: Off, Power Toggle: On
irsend.reset();
irsend.sendKelon(0x50040683);
EXPECT_EQ(
Expand All @@ -56,10 +57,10 @@ TEST(TestSendKelon, SendDataOnly) {
"m560s600m560s1680m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s100000",
irsend.outputStr()
);
irsend.outputStr());

// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: On (9.5h), Turbo:
// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer:
// On (9.5h), Turbo:
irsend.reset();
irsend.sendKelon(0x138A000683);
EXPECT_EQ(
Expand All @@ -72,10 +73,10 @@ TEST(TestSendKelon, SendDataOnly) {
"m560s1680m560s600m560s600m560s1680m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s100000",
irsend.outputStr()
);
irsend.outputStr());

// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: On (15h), Turbo: Off:
// Temp: 26C, Mode: 2 (Cool), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer:
// On (15h), Turbo: Off:
irsend.reset();
irsend.sendKelon(0x198A000683);
EXPECT_EQ(
Expand All @@ -88,8 +89,7 @@ TEST(TestSendKelon, SendDataOnly) {
"m560s1680m560s600m560s600m560s1680m560s1680m560s600"
"m560s600m560s600m560s600m560s600m560s600m560s600m560s600"
"m560s600m560s600m560s600m560s100000",
irsend.outputStr()
);
irsend.outputStr());
}

// Tests for decodeKelon().
Expand All @@ -106,9 +106,9 @@ TEST(TestDecodeKelon, Timer12HSmartMode) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 25C, Mode: 1 (Auto), Fan: 3 (High), Sleep: Off, Dry: 0, Timer: 12:00, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 25C, Mode: 1 (Auto), Fan: 3 (High), Sleep: Off, Dry: 0, "
"Timer: 12:00, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand All @@ -125,9 +125,9 @@ TEST(TestDecodeKelon, Timer5_5hSuperCoolMode) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 18C, Mode: 2 (Cool), Fan: 1 (Low), Sleep: Off, Dry: 0, Timer: 05:30, Turbo: On",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 18C, Mode: 2 (Cool), Fan: 1 (Low), Sleep: Off, Dry: 0, "
"Timer: 05:30, Turbo: On",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand All @@ -144,9 +144,9 @@ TEST(TestDecodeKelon, ChangeSettingsWithTimerSetHeatMode) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 23C, Mode: 0 (Heat), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: On, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 23C, Mode: 0 (Heat), Fan: 0 (Auto), Sleep: Off, Dry: 0, "
"Timer: On, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand All @@ -163,9 +163,9 @@ TEST(TestDecodeKelon, TestPowerToggleDryMode) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off, Turbo: Off, Power Toggle: On",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer:"
" Off, Turbo: Off, Power Toggle: On",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand All @@ -182,9 +182,9 @@ TEST(TestDecodeKelon, TestSwingToggleDryMode) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer: Off, Turbo: Off, Swing(V) Toggle: On",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: 0, Timer:"
" Off, Turbo: Off, Swing(V) Toggle: On",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand All @@ -201,9 +201,9 @@ TEST(TestDecodeKelon, TestDryGradeNegativeValue) {
EXPECT_EQ(KELON, irsend.capture.decode_type);
EXPECT_EQ(kKelonBits, irsend.capture.bits);
EXPECT_EQ(
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: -2, Timer: Off, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture)
);
"Temp: 26C, Mode: 3 (Dry), Fan: 0 (Auto), Sleep: Off, Dry: -2,"
" Timer: Off, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
Expand Down Expand Up @@ -398,4 +398,4 @@ TEST(TestUtils, Housekeeping) {
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::KELON));
ASSERT_EQ(kKelonBits, IRsend::defaultBits(decode_type_t::KELON));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::KELON));
}
}

0 comments on commit b9451cc

Please sign in to comment.