Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,8 +1841,10 @@ void IRac::panasonic32(IRPanasonicAc32 *ac,
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
/// @param[in] swingh The horizontal swing setting.
/// @param[in] quiet Run the device in quiet/silent mode.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] econo Run the device in economical mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
Expand All @@ -1854,8 +1856,10 @@ void IRac::panasonic32(IRPanasonicAc32 *ac,
void IRac::samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool light,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool quiet, const bool turbo, const bool econo,
const bool light,
const bool filter, const bool clean,
const bool beep, const int16_t sleep,
const bool prevpower, const int16_t prevsleep,
Expand All @@ -1867,11 +1871,11 @@ void IRac::samsung(IRSamsungAc *ac,
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwing(swingv != stdAc::swingv_t::kOff);
// No Horizontal swing setting available.
ac->setSwingH(swingh != stdAc::swingh_t::kOff);
ac->setQuiet(quiet);
ac->setPowerful(turbo);
ac->setPowerful(turbo); // FYI, `setEcono(true)` will override this.
ac->setDisplay(light);
// No Econo setting available.
ac->setEcono(econo);
ac->setIon(filter);
ac->setClean(clean);
ac->setBeep(beep);
Expand Down Expand Up @@ -3003,8 +3007,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
{
IRSamsungAc ac(_pin, _inverted, _modulation);
samsung(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
send.quiet, send.turbo, send.light, send.filter, send.clean,
send.beep, send.sleep, prev_power, prev_sleep);
send.swingh, send.quiet, send.turbo, send.econo, send.light,
send.filter, send.clean, send.beep, send.sleep,
prev_power, prev_sleep);
break;
}
#endif // SEND_SAMSUNG_AC
Expand Down
7 changes: 4 additions & 3 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,10 @@ void electra(IRElectraAc *ac,
#if SEND_SAMSUNG_AC
void samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool light,
const bool filter, const bool clean,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool quiet, const bool turbo, const bool econo,
const bool light, const bool filter, const bool clean,
const bool beep, const int16_t sleep = -1,
const bool prevpower = true, const int16_t prevsleep = -1,
const bool forceextended = true);
Expand Down
103 changes: 86 additions & 17 deletions src/ir_Samsung.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017, 2018, 2019 David Conran
// Copyright 2017-2021 David Conran
/// @file
/// @brief Support for Samsung protocols.
/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/
Expand Down Expand Up @@ -62,6 +62,17 @@ const uint16_t kSamsung36BitMark = 512; /// < uSeconds
const uint16_t kSamsung36OneSpace = 1468; /// < uSeconds
const uint16_t kSamsung36ZeroSpace = 490; /// < uSeconds

// _.Swing
const uint8_t kSamsungAcSwingV = 0b010;
const uint8_t kSamsungAcSwingH = 0b011;
const uint8_t kSamsungAcSwingBoth = 0b100;
const uint8_t kSamsungAcSwingOff = 0b111;
// _.FanSpecial
const uint8_t kSamsungAcFanSpecialOff = 0b000;
const uint8_t kSamsungAcPowerfulOn = 0b011;
const uint8_t kSamsungAcBreezeOn = 0b101;
const uint8_t kSamsungAcEconoOn = 0b111;

using irutils::addBoolToString;
using irutils::addFanToString;
using irutils::addIntToString;
Expand Down Expand Up @@ -443,7 +454,7 @@ void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) {
if (length > kSamsungAcStateLength) {
_OnTimerEnable = _.OnTimerEnable;
_OffTimerEnable = _.OffTimerEnable;
_Sleep = _.Sleep;
_Sleep = _.Sleep5 && _.Sleep12;
_OnTimer = _getOnTimer();
_OffTimer = _getOffTimer();
for (uint8_t i = kSamsungAcStateLength; i < length; i++)
Expand Down Expand Up @@ -535,18 +546,48 @@ uint8_t IRSamsungAc::getFan(void) const {

/// Get the vertical swing setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1.
/// e.g. 0xAE or 0XAF for swing move.
bool IRSamsungAc::getSwing(void) const {
return _.Swing == kSamsungAcSwingMove;
switch (_.Swing) {
case kSamsungAcSwingV:
case kSamsungAcSwingBoth: return true;
default: return false;
}
}

/// Set the vertical swing setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1.
/// e.g. 0xAE or 0XAF for swing move.
void IRSamsungAc::setSwing(const bool on) {
_.Swing = (on ? kSamsungAcSwingMove : kSamsungAcSwingStop);
switch (_.Swing) {
case kSamsungAcSwingBoth:
case kSamsungAcSwingH:
_.Swing = on ? kSamsungAcSwingBoth : kSamsungAcSwingH;
break;
default:
_.Swing = on ? kSamsungAcSwingV : kSamsungAcSwingOff;
}
}

/// Get the horizontal swing setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getSwingH(void) const {
switch (_.Swing) {
case kSamsungAcSwingH:
case kSamsungAcSwingBoth: return true;
default: return false;
}
}

/// Set the horizontal swing setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setSwingH(const bool on) {
switch (_.Swing) {
case kSamsungAcSwingV:
case kSamsungAcSwingBoth:
_.Swing = on ? kSamsungAcSwingBoth : kSamsungAcSwingV;
break;
default:
_.Swing = on ? kSamsungAcSwingH : kSamsungAcSwingOff;
}
}

/// Get the Beep setting of the A/C.
Expand Down Expand Up @@ -599,7 +640,8 @@ bool IRSamsungAc::getPowerful(void) const {
/// Set the Powerful (Turbo) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setPowerful(const bool on) {
uint8_t off_value = getBreeze() ? kSamsungAcBreezeOn : 0b000;
uint8_t off_value = (getBreeze() || getEcono()) ? _.FanSpecial
: kSamsungAcFanSpecialOff;
_.FanSpecial = (on ? kSamsungAcPowerfulOn : off_value);
if (on) {
// Powerful mode sets fan speed to Turbo.
Expand All @@ -623,14 +665,36 @@ bool IRSamsungAc::getBreeze(void) const {
/// @param[in] on true, the setting is on. false, the setting is off.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
void IRSamsungAc::setBreeze(const bool on) {
const uint8_t off_value = getPowerful() ? kSamsungAcPowerfulOn : 0b000;
const uint8_t off_value = (getPowerful() ||
getEcono()) ? _.FanSpecial
: kSamsungAcFanSpecialOff;
_.FanSpecial = (on ? kSamsungAcBreezeOn : off_value);
if (on) {
setFan(kSamsungAcFanAuto);
setSwing(false);
}
}

/// Get the current Economy (Eco) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getEcono(void) const {
return (_.FanSpecial == kSamsungAcEconoOn) &&
(_.Fan == kSamsungAcFanAuto && getSwing());
}

/// Set the current Economy (Eco) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setEcono(const bool on) {
const uint8_t off_value = (getBreeze() ||
getPowerful()) ? _.FanSpecial
: kSamsungAcFanSpecialOff;
_.FanSpecial = (on ? kSamsungAcEconoOn : off_value);
if (on) {
setFan(kSamsungAcFanAuto);
setSwing(true);
}
}

/// Get the Display (Light/LED) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getDisplay(void) const { return _.Display; }
Expand Down Expand Up @@ -693,7 +757,8 @@ void IRSamsungAc::_setOffTimer(void) {
void IRSamsungAc::_setSleepTimer(void) {
_setOffTimer();
// The Sleep mode/timer should only be engaged if an off time has been set.
_.Sleep = _Sleep && _OffTimerEnable;
_.Sleep5 = _Sleep && _OffTimerEnable;
_.Sleep12 = _.Sleep5;
}

/// Get the On Timer setting of the A/C.
Expand Down Expand Up @@ -724,6 +789,7 @@ uint16_t IRSamsungAc::getSleepTimer(void) const {
void IRSamsungAc::setOnTimer(const uint16_t nr_of_mins) {
// Limit to one day, and round down to nearest 10 min increment.
_OnTimer = TIMER_RESOLUTION(nr_of_mins);
_OnTimerEnable = _OnTimer > 0;
if (_OnTimer) _Sleep = false;
}

Expand All @@ -734,6 +800,7 @@ void IRSamsungAc::setOnTimer(const uint16_t nr_of_mins) {
void IRSamsungAc::setOffTimer(const uint16_t nr_of_mins) {
// Limit to one day, and round down to nearest 10 min increment.
_OffTimer = TIMER_RESOLUTION(nr_of_mins);
_OffTimerEnable = _OffTimer > 0;
if (_OffTimer) _Sleep = false;
}

Expand All @@ -746,6 +813,7 @@ void IRSamsungAc::setSleepTimer(const uint16_t nr_of_mins) {
_OffTimer = TIMER_RESOLUTION(nr_of_mins);
if (_OffTimer) setOnTimer(0); // Clear the on timer if set.
_Sleep = _OffTimer > 0;
_OffTimerEnable = _Sleep;
}

/// Convert a stdAc::opmode_t enum into its native mode.
Expand Down Expand Up @@ -812,18 +880,17 @@ stdAc::state_t IRSamsungAc::toCommon(void) const {
result.celsius = true;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
result.swingv = getSwing() ? stdAc::swingv_t::kAuto :
stdAc::swingv_t::kOff;
result.swingv = getSwing() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
result.swingh = getSwingH() ? stdAc::swingh_t::kAuto : stdAc::swingh_t::kOff;
result.quiet = getQuiet();
result.turbo = getPowerful();
result.econo = getEcono();
result.clean = getClean();
result.beep = _.Beep;
result.light = _.Display;
result.filter = _.Ion;
result.sleep = _Sleep ? getSleepTimer() : -1;
// Not supported.
result.swingh = stdAc::swingh_t::kOff;
result.econo = false;
result.clock = -1;
return result;
}
Expand All @@ -832,7 +899,7 @@ stdAc::state_t IRSamsungAc::toCommon(void) const {
/// @return A human readable string.
String IRSamsungAc::toString(void) const {
String result = "";
result.reserve(115); // Reserve some heap for the string to reduce fragging.
result.reserve(230); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
result += addModeToString(_.Mode, kSamsungAcAuto, kSamsungAcCool,
kSamsungAcHeat, kSamsungAcDry,
Expand Down Expand Up @@ -862,11 +929,13 @@ String IRSamsungAc::toString(void) const {
break;
}
result += ')';
result += addBoolToString(getSwing(), kSwingStr);
result += addBoolToString(getSwing(), kSwingVStr);
result += addBoolToString(getSwingH(), kSwingHStr);
result += addBoolToString(_.Beep, kBeepStr);
result += addBoolToString(getClean(), kCleanStr);
result += addBoolToString(getQuiet(), kQuietStr);
result += addBoolToString(getPowerful(), kPowerfulStr);
result += addBoolToString(getEcono(), kEconoStr);
result += addBoolToString(getBreeze(), kBreezeStr);
result += addBoolToString(_.Display, kLightStr);
result += addBoolToString(_.Ion, kIonStr);
Expand Down
17 changes: 9 additions & 8 deletions src/ir_Samsung.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018 David Conran
// Copyright 2018-2021 David Conran
/// @file
/// @brief Support for Samsung protocols.
/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/
Expand Down Expand Up @@ -58,7 +58,8 @@ union SamsungProtocol{
// Byte 4
uint8_t :8;
// Byte 5
uint8_t :5;
uint8_t :4;
uint8_t Sleep5 :1;
uint8_t Quiet :1;
uint8_t :2;
// Byte 6
Expand All @@ -76,7 +77,7 @@ union SamsungProtocol{
uint8_t :1;
// Byte 10
uint8_t :1;
uint8_t FanSpecial :3; // Powerful, Breeze/WindFree
uint8_t FanSpecial :3; // Powerful, Breeze/WindFree, Econo
uint8_t Display :1;
uint8_t :2;
uint8_t Clean10 :1;
Expand Down Expand Up @@ -136,7 +137,7 @@ union SamsungProtocol{
uint8_t OffTimeDay :1;
uint8_t OnTimerEnable :1;
uint8_t OffTimerEnable :1;
uint8_t Sleep :1;
uint8_t Sleep12 :1;
uint8_t OnTimeDay :1;
uint8_t :3;
// Byte 13
Expand All @@ -162,10 +163,6 @@ union SamsungProtocol{
};

// Constants
const uint8_t kSamsungAcSwingMove = 0b010;
const uint8_t kSamsungAcSwingStop = 0b111;
const uint8_t kSamsungAcPowerfulOn = 0b011;
const uint8_t kSamsungAcBreezeOn = 0b101;
const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
Expand Down Expand Up @@ -214,6 +211,8 @@ class IRSamsungAc {
uint8_t getMode(void) const;
void setSwing(const bool on);
bool getSwing(void) const;
void setSwingH(const bool on);
bool getSwingH(void) const;
void setBeep(const bool on);
bool getBeep(void) const;
void setClean(const bool on);
Expand All @@ -224,6 +223,8 @@ class IRSamsungAc {
bool getPowerful(void) const;
void setBreeze(const bool on);
bool getBreeze(void) const;
void setEcono(const bool on);
bool getEcono(void) const;
void setDisplay(const bool on);
bool getDisplay(void) const;
void setIon(const bool on);
Expand Down
Loading