Skip to content

Commit

Permalink
Support more features of TCL A/C
Browse files Browse the repository at this point in the history
Add support for:
- Turbo
- Economy
- Fan speed
- Light/Display
- Health
- Vane Swing

* Improve some function interactions.
* Unit tests for the above.

Ref: #619
  • Loading branch information
crankyoldgit committed Mar 22, 2019
1 parent 2cfc2d7 commit f20bd5f
Show file tree
Hide file tree
Showing 3 changed files with 312 additions and 15 deletions.
135 changes: 134 additions & 1 deletion src/ir_Tcl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,18 @@ uint8_t IRTcl112Ac::getMode() {
}

// Set the requested climate operation mode of the a/c unit.
// Note: Fan/Ventilation mode sets the fan speed to high.
// Unknown values default to Auto.
void IRTcl112Ac::setMode(const uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
switch (mode) {
case kTcl112AcFan:
this->setFan(kTcl112AcFanHigh);
// FALLTHRU
case kTcl112AcAuto:
case kTcl112AcCool:
case kTcl112AcHeat:
case kTcl112AcDry:
case kTcl112AcFan:
remote_state[6] &= 0xF0;
remote_state[6] |= mode;
break;
Expand Down Expand Up @@ -153,6 +157,108 @@ float IRTcl112Ac::getTemp() {
return result;
}

// Set the speed of the fan.
// Unknown speeds will default to Auto.
void IRTcl112Ac::setFan(const uint8_t speed) {
switch (speed) {
case kTcl112AcFanAuto:
case kTcl112AcFanLow:
case kTcl112AcFanMed:
case kTcl112AcFanHigh:
remote_state[8] &= ~kTcl112AcFanMask;
remote_state[8] |= speed;
break;
default:
this->setFan(kTcl112AcFanAuto);
}
}

// Return the currect fan speed.
uint8_t IRTcl112Ac::getFan() {
return remote_state[8] & kTcl112AcFanMask;
}

// Control economy mode.
void IRTcl112Ac::setEcono(const bool on) {
if (on)
remote_state[5] |= kTcl112AcBitEcono;
else
remote_state[5] &= ~kTcl112AcBitEcono;
}

// Return the economy state of the A/C.
bool IRTcl112Ac::getEcono(void) {
return remote_state[5] & kTcl112AcBitEcono;
}

// Control Health mode.
void IRTcl112Ac::setHealth(const bool on) {
if (on)
remote_state[6] |= kTcl112AcBitHealth;
else
remote_state[6] &= ~kTcl112AcBitHealth;
}

// Return the Health mode state of the A/C.
bool IRTcl112Ac::getHealth(void) {
return remote_state[6] & kTcl112AcBitHealth;
}

// Control Light/Display mode.
void IRTcl112Ac::setLight(const bool on) {
if (on)
remote_state[5] &= ~kTcl112AcBitLight;
else
remote_state[5] |= kTcl112AcBitLight;
}

// Return the Light/Display mode state of the A/C.
bool IRTcl112Ac::getLight(void) {
return !(remote_state[5] & kTcl112AcBitLight);
}

// Control Horizontal Swing.
void IRTcl112Ac::setSwingHorizontal(const bool on) {
if (on)
remote_state[12] |= kTcl112AcBitSwingH;
else
remote_state[12] &= ~kTcl112AcBitSwingH;
}

// Return the Horizontal Swing state of the A/C.
bool IRTcl112Ac::getSwingHorizontal(void) {
return remote_state[12] & kTcl112AcBitSwingH;
}

// Control Vertical Swing.
void IRTcl112Ac::setSwingVertical(const bool on) {
if (on)
remote_state[8] |= kTcl112AcBitSwingV;
else
remote_state[8] &= ~kTcl112AcBitSwingV;
}

// Return the Vertical Swing state of the A/C.
bool IRTcl112Ac::getSwingVertical(void) {
return remote_state[8] & kTcl112AcBitSwingV;
}

// Control the Turbo setting.
void IRTcl112Ac::setTurbo(const bool on) {
if (on) {
remote_state[6] |= kTcl112AcBitTurbo;
this->setFan(kTcl112AcFanHigh);
this->setSwingVertical(true);
} else {
remote_state[6] &= ~kTcl112AcBitTurbo;
}
}

// Return the Turbo setting state of the A/C.
bool IRTcl112Ac::getTurbo(void) {
return remote_state[6] & kTcl112AcBitTurbo;
}

// Convert the internal state into a human readable string.
#ifdef ARDUINO
String IRTcl112Ac::toString() {
Expand Down Expand Up @@ -187,6 +293,33 @@ std::string IRTcl112Ac::toString() {
result += ", Temp: " + uint64ToString(nrHalfDegrees / 2);
if (nrHalfDegrees & 1) result += ".5";
result += "C";
result += ", Fan: " + uint64ToString(getFan());
switch (getFan()) {
case kTcl112AcFanAuto:
result += " (Auto)";
break;
case kTcl112AcFanLow:
result += " (Low)";
break;
case kTcl112AcFanMed:
result += " (Med)";
break;
case kTcl112AcFanHigh:
result += " (High)";
break;
}
result += ", Econo: ";
result += (this->getEcono() ? "On" : "Off");
result += ", Health: ";
result += (this->getHealth() ? "On" : "Off");
result += ", Light: ";
result += (this->getLight() ? "On" : "Off");
result += ", Turbo: ";
result += (this->getTurbo() ? "On" : "Off");
result += ", Swing (H): ";
result += (this->getSwingHorizontal() ? "On" : "Off");
result += ", Swing (V): ";
result += (this->getSwingVertical() ? "On" : "Off");
return result;
}

Expand Down
33 changes: 30 additions & 3 deletions src/ir_Tcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,24 @@ const uint8_t kTcl112AcDry = 2;
const uint8_t kTcl112AcCool = 3;
const uint8_t kTcl112AcFan = 7;
const uint8_t kTcl112AcAuto = 8;
const uint8_t kTcl112AcFanMask = 0b00000111;
const uint8_t kTcl112AcFanAuto = 0b00000000;
const uint8_t kTcl112AcFanLow = 0b00000010;
const uint8_t kTcl112AcFanMed = 0b00000011;
const uint8_t kTcl112AcFanHigh = 0b00000101;

const uint8_t kTcl112AcHalfDegree = 0b00100000;
const float kTcl112AcTempMax = 31.0;
const float kTcl112AcTempMin = 16.0;
const uint8_t kTcl112AcPowerMask = 0x04;
const float kTcl112AcTempMax = 31.0;
const float kTcl112AcTempMin = 16.0;

const uint8_t kTcl112AcPowerMask = 0b00000100;
const uint8_t kTcl112AcBitEcono = 0b10000000;
const uint8_t kTcl112AcBitLight = 0b01000000;
const uint8_t kTcl112AcBitHealth = 0b00010000;
const uint8_t kTcl112AcBitSwingH = 0b00001000;
const uint8_t kTcl112AcBitSwingV = 0b00111000;
const uint8_t kTcl112AcBitTurbo = 0b01000000;


class IRTcl112Ac {
public:
Expand All @@ -53,6 +66,20 @@ class IRTcl112Ac {
const uint16_t length = kTcl112AcStateLength);
static bool validChecksum(uint8_t state[],
const uint16_t length = kTcl112AcStateLength);
void setFan(const uint8_t speed);
uint8_t getFan(void);
void setEcono(const bool on);
bool getEcono(void);
void setHealth(const bool on);
bool getHealth(void);
void setLight(const bool on);
bool getLight(void);
void setSwingHorizontal(const bool on);
bool getSwingHorizontal(void);
void setSwingVertical(const bool on);
bool getSwingVertical(void);
void setTurbo(const bool on);
bool getTurbo(void);
#ifdef ARDUINO
String toString();
#else
Expand Down
Loading

0 comments on commit f20bd5f

Please sign in to comment.