Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update sharp to match my AC (Sharp AH-A5SAY) #1074

Merged
merged 9 commits into from
Apr 5, 2020
2 changes: 1 addition & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2871,7 +2871,7 @@ kSharpAcBitPowerOffset LITERAL1
kSharpAcBitTempManualOffset LITERAL1
kSharpAcBits LITERAL1
kSharpAcByteFan LITERAL1
kSharpAcByteManual LITERAL1
kSharpAcByteButton LITERAL1
kSharpAcByteMode LITERAL1
kSharpAcBytePower LITERAL1
kSharpAcByteTemp LITERAL1
Expand Down
9 changes: 6 additions & 3 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,10 +1023,11 @@ void IRac::samsung(IRSamsungAc *ac,

#if SEND_SHARP_AC
void IRac::sharp(IRSharpAc *ac,
const bool on, const stdAc::opmode_t mode,
const bool on, const bool prev_power,
const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan) {
ac->begin();
ac->setPower(on);
ac->setPower(on, prev_power);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
Expand Down Expand Up @@ -1606,7 +1607,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
case SHARP_AC:
{
IRSharpAc ac(_pin, _inverted, _modulation);
sharp(&ac, send.power, send.mode, degC, send.fanspeed);
bool prev_power = !send.power;
if (prev != NULL) prev_power = prev->power;
sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed);
break;
}
#endif // SEND_SHARP_AC
Expand Down
2 changes: 1 addition & 1 deletion src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ void electra(IRElectraAc *ac,
#endif // SEND_SAMSUNG_AC
#if SEND_SHARP_AC
void sharp(IRSharpAc *ac,
const bool on, const stdAc::opmode_t mode,
const bool on, const bool prev_power, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan);
#endif // SEND_SHARP_AC
#if SEND_TCL112AC
Expand Down
1 change: 1 addition & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO;
const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE;
const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET;
const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE;
const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER;
const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP;
const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER;
const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE;
Expand Down
1 change: 1 addition & 0 deletions src/IRtext.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern const char* kOutsideStr;
extern const char* kPowerfulStr;
extern const char* kPowerStr;
extern const char* kPowerToggleStr;
extern const char* kPreviousPowerStr;
extern const char* kProtocolStr;
extern const char* kPurifyStr;
extern const char* kQuietStr;
Expand Down
47 changes: 40 additions & 7 deletions src/ir_Sharp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

// Equipment it seems compatible with:
// * Sharp LC-52D62U
// * Sharp AH-AxSAY A/C (Remote CRMC-A907 JBEZ)
// * <Add models (devices & remotes) you've gotten it working with here>
//

Expand Down Expand Up @@ -334,35 +335,67 @@ void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) {
memcpy(remote, new_code, std::min(length, kSharpAcStateLength));
}

void IRSharpAc::setPreviousPower(const bool on) {
setBit(&remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset, on);
}

bool IRSharpAc::getPreviousPower(void) {
return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset);
}

void IRSharpAc::on(void) { setPower(true); }

void IRSharpAc::off(void) { setPower(false); }

void IRSharpAc::setPower(const bool on) {
setPreviousPower(getPower());
setBit(&remote[kSharpAcBytePower], kSharpAcBitPowerOffset, on);
setButton(kSharpAcButtonPowerMode);
}

void IRSharpAc::setPower(const bool on, const bool prev) {
setPower(on);
setPreviousPower(prev);
}

bool IRSharpAc::getPower(void) {
return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPowerOffset);
}

void IRSharpAc::setButton(const uint8_t button) {
switch (button) {
case kSharpAcButtonPowerMode:
case kSharpAcButtonTemp:
case kSharpAcButtonFan:
setBits(&remote[kSharpAcByteButton], kSharpAcButtonOffset,
kSharpAcButtonSize, button);
break;
default:
setButton(kSharpAcButtonPowerMode);
}
}

uint8_t IRSharpAc::getButton(void) {
return GETBITS8(remote[kSharpAcByteButton], kSharpAcButtonOffset,
kSharpAcButtonSize);
}

// Set the temp in deg C
void IRSharpAc::setTemp(const uint8_t temp) {
switch (this->getMode()) {
// Auto & Dry don't allow temp changes and have a special temp.
case kSharpAcAuto:
case kSharpAcDry:
remote[kSharpAcByteTemp] = 0;
remote[kSharpAcByteManual] = 0; // When in Dry/Auto this byte is 0.
return;
default:
remote[kSharpAcByteTemp] = 0xC0;
setBit(&remote[kSharpAcByteManual], kSharpAcBitTempManualOffset);
}
uint8_t degrees = std::max(temp, kSharpAcMinTemp);
degrees = std::min(degrees, kSharpAcMaxTemp);
setBits(&remote[kSharpAcByteTemp], kLowNibble, kNibbleSize,
degrees - kSharpAcMinTemp);
setButton(kSharpAcButtonTemp);
}

uint8_t IRSharpAc::getTemp(void) {
Expand All @@ -375,11 +408,10 @@ uint8_t IRSharpAc::getMode(void) {
}

void IRSharpAc::setMode(const uint8_t mode) {
setBit(&remote[kSharpAcBytePower], kSharpAcBitModeNonAutoOffset,
mode != kSharpAcAuto);
switch (mode) {
case kSharpAcAuto:
case kSharpAcDry:
this->setFan(2); // When Dry or Auto, Fan always 2(Auto)
this->setTemp(0); // Dry/Auto have no temp setting.
// FALLTHRU
case kSharpAcCool:
Expand All @@ -389,6 +421,7 @@ void IRSharpAc::setMode(const uint8_t mode) {
default:
this->setMode(kSharpAcAuto);
}
setButton(kSharpAcButtonPowerMode);
}

// Set the speed of the fan
Expand All @@ -399,14 +432,13 @@ void IRSharpAc::setFan(const uint8_t speed) {
case kSharpAcFanMed:
case kSharpAcFanHigh:
case kSharpAcFanMax:
setBit(&remote[kSharpAcByteManual], kSharpAcBitFanManualOffset,
speed != kSharpAcFanAuto);
setBits(&remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize,
speed);
break;
default:
this->setFan(kSharpAcFanAuto);
}
setButton(kSharpAcButtonFan);
}

uint8_t IRSharpAc::getFan(void) {
Expand Down Expand Up @@ -485,8 +517,9 @@ stdAc::state_t IRSharpAc::toCommon(void) {
// Convert the internal state into a human readable string.
String IRSharpAc::toString(void) {
String result = "";
result.reserve(60); // Reserve some heap for the string to reduce fragging.
result.reserve(80); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
result += addBoolToString(getPreviousPower(), kPreviousPowerStr);
result += addModeToString(getMode(), kSharpAcAuto, kSharpAcCool, kSharpAcHeat,
kSharpAcDry, kSharpAcAuto);
result += addTempToString(getTemp());
Expand Down
20 changes: 14 additions & 6 deletions src/ir_Sharp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Supports:
// Brand: Sharp, Model: LC-52D62U TV
// Brand: Sharp, Model: AY-ZP40KR A/C
// Brand: Sharp, Model: AH-AxSAY A/C

#ifndef IR_SHARP_H_
#define IR_SHARP_H_
Expand Down Expand Up @@ -38,17 +39,19 @@ const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3)
const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4)
const uint8_t kSharpAcByteTemp = 4;
const uint8_t kSharpAcBytePower = 5;
const uint8_t kSharpAcBitPowerOffset = 4;
const uint8_t kSharpAcBitModeNonAutoOffset = 5; // 0b00100000
const uint8_t kSharpAcBitPowerOffset = 4; // 0b000x0000
const uint8_t kSharpAcBitPreviousPowerOffset = 5; // 0b00x00000
const uint8_t kSharpAcByteMode = 6;
const uint8_t kSharpAcModeSize = 2; // Mask 0b00000011;
const uint8_t kSharpAcByteFan = kSharpAcByteMode;
const uint8_t kSharpAcFanOffset = 4; // Mask 0b01110000
const uint8_t kSharpAcFanSize = 3; // Nr. of Bits
const uint8_t kSharpAcByteManual = 10;
const uint8_t kSharpAcBitFanManualOffset = 0; // 0b00000001
const uint8_t kSharpAcBitTempManualOffset = 2; // 0b00000100

const uint8_t kSharpAcByteButton = 10;
const uint8_t kSharpAcButtonOffset = 0;
const uint8_t kSharpAcButtonSize = 3; // Mask 0b00000xxx
const uint8_t kSharpAcButtonPowerMode = 0b000; // 0
const uint8_t kSharpAcButtonTemp = 0b100; // 4
const uint8_t kSharpAcButtonFan = 0b101; // 5

class IRSharpAc {
public:
Expand All @@ -63,13 +66,18 @@ class IRSharpAc {
void on(void);
void off(void);
void setPower(const bool on);
void setPower(const bool on, const bool prev);
bool getPower(void);
void setPreviousPower(const bool on);
bool getPreviousPower(void);
void setTemp(const uint8_t temp);
uint8_t getTemp(void);
void setFan(const uint8_t fan);
uint8_t getFan(void);
void setMode(const uint8_t mode);
uint8_t getMode(void);
void setButton(const uint8_t button);
uint8_t getButton(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kSharpAcStateLength);
Expand Down
6 changes: 6 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#ifndef D_STR_POWER
#define D_STR_POWER "Power"
#endif // D_STR_POWER
#ifndef D_STR_PREVIOUS
#define D_STR_PREVIOUS "Previous"
#endif // D_STR_PREVIOUS
#ifndef D_STR_ON
#define D_STR_ON "On"
#endif // D_STR_ON
Expand Down Expand Up @@ -363,6 +366,9 @@
#ifndef D_STR_POWERTOGGLE
#define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
#endif // D_STR_POWERTOGGLE
#ifndef D_STR_PREVIOUSPOWER
#define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
#endif // D_STR_PREVIOUSPOWER
#ifndef D_STR_SENSORTEMP
#define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
#endif // D_STR_SENSORTEMP
Expand Down
2 changes: 2 additions & 0 deletions src/locale/es-ES.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#define D_STR_UNKNOWN "DESCONOCIDO"
#define D_STR_PROTOCOL "Protocolo"
#define D_STR_POWER "Poder"
#define D_STR_PREVIOUS "Anterior"
#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_ON "Encendido"
#define D_STR_OFF "Apagado"
#define D_STR_MODE "Modo"
Expand Down
2 changes: 2 additions & 0 deletions src/locale/fr-FR.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define D_STR_SLEEP "Pause"
#define D_STR_LIGHT "Lumière"
#define D_STR_POWERFUL "Puissance"
#define D_STR_PREVIOUS "Precedente"
#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_QUIET "Silence"
#define D_STR_ECONO "Economie"
#define D_STR_BEEP "Bip"
Expand Down
2 changes: 2 additions & 0 deletions src/locale/it-IT.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#define D_STR_UNKNOWN "SCONOSCIUTO"
#define D_STR_PROTOCOL "Protocollo"
#define D_STR_POWER "Accensione"
#define D_STR_PREVIOUS "Precedente"
#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_ON "Acceso"
#define D_STR_OFF "Spento"
#define D_STR_MODE "Modalità"
Expand Down
4 changes: 3 additions & 1 deletion test/IRac_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,11 +1039,13 @@ TEST(TestIRac, Sharp) {
IRac irac(0);
IRrecv capture(0);
char expected[] =
"Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium)";
"Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
"Fan: 3 (Medium)";

ac.begin();
irac.sharp(&ac,
true, // Power
true, // Previous Power
stdAc::opmode_t::kCool, // Mode
28, // Celsius
stdAc::fanspeed_t::kMedium); // Fan speed
Expand Down
Loading