mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Merge pull request #8992 from s-hadinger/ir_pioneer_samsung
Change IRRemoteESP8266 IR lib to pre-2.7.9, fixing Samsung and Pioneer protocols (#8938)
This commit is contained in:
commit
d9427c5c5b
@ -38,7 +38,7 @@ void printState() {
|
||||
// Display the encoded IR sequence.
|
||||
unsigned char* ir_code = ac.getRaw();
|
||||
Serial.print("IR Code: 0x");
|
||||
for (uint8_t i = 0; i < kToshibaACStateLength; i++)
|
||||
for (uint8_t i = 0; i < ac.getStateLength(); i++)
|
||||
Serial.printf("%02X", ir_code[i]);
|
||||
Serial.println();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRtext.h"
|
||||
#include "IRutils.h"
|
||||
#include "ir_Airwell.h"
|
||||
#include "ir_Amcor.h"
|
||||
#include "ir_Argo.h"
|
||||
#include "ir_Carrier.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#include "ir_Neoclima.h"
|
||||
#include "ir_Panasonic.h"
|
||||
#include "ir_Samsung.h"
|
||||
#include "ir_Sanyo.h"
|
||||
#include "ir_Sharp.h"
|
||||
#include "ir_Tcl.h"
|
||||
#include "ir_Teco.h"
|
||||
@ -132,6 +134,9 @@ stdAc::state_t IRac::getStatePrev(void) { return _prev; }
|
||||
/// @return true if the protocol is supported by this class, otherwise false.
|
||||
bool IRac::isProtocolSupported(const decode_type_t protocol) {
|
||||
switch (protocol) {
|
||||
#if SEND_AIRWELL
|
||||
case decode_type_t::AIRWELL:
|
||||
#endif
|
||||
#if SEND_AMCOR
|
||||
case decode_type_t::AMCOR:
|
||||
#endif
|
||||
@ -236,6 +241,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
|
||||
#if SEND_SAMSUNG_AC
|
||||
case decode_type_t::SAMSUNG_AC:
|
||||
#endif
|
||||
#if SEND_SANYO_AC
|
||||
case decode_type_t::SANYO_AC:
|
||||
#endif
|
||||
#if SEND_SHARP_AC
|
||||
case decode_type_t::SHARP_AC:
|
||||
#endif
|
||||
@ -269,6 +277,34 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
|
||||
}
|
||||
}
|
||||
|
||||
#if SEND_AIRWELL
|
||||
/// Send an Airwell A/C message with the supplied settings.
|
||||
/// @param[in, out] ac A Ptr to an IRAirwellAc object to use.
|
||||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
void IRac::airwell(IRAirwellAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan) {
|
||||
ac->begin();
|
||||
ac->setPowerToggle(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
// No Swing setting available.
|
||||
// No Quiet setting available.
|
||||
// No Light setting available.
|
||||
// No Filter setting available.
|
||||
// No Turbo setting available.
|
||||
// No Economy setting available.
|
||||
// No Clean setting available.
|
||||
// No Beep setting available.
|
||||
// No Sleep setting available.
|
||||
ac->send();
|
||||
}
|
||||
#endif // SEND_AIRWELL
|
||||
|
||||
#if SEND_AMCOR
|
||||
/// Send an Amcor A/C message with the supplied settings.
|
||||
/// @param[in, out] ac A Ptr to an IRAmcorAc object to use.
|
||||
@ -1231,11 +1267,14 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model,
|
||||
/// @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] econo Run the device in economical mode.
|
||||
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
|
||||
/// @note On Danby A/C units, swingv controls the Ion Filter instead.
|
||||
void IRac::midea(IRMideaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const int16_t sleep) {
|
||||
const stdAc::swingv_t swingv, const bool econo,
|
||||
const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
@ -1246,6 +1285,7 @@ void IRac::midea(IRMideaAC *ac,
|
||||
// No Horizontal swing setting available.
|
||||
// No Quiet setting available.
|
||||
// No Turbo setting available.
|
||||
ac->setEconoToggle(econo);
|
||||
// No Light setting available.
|
||||
// No Filter setting available.
|
||||
// No Clean setting available.
|
||||
@ -1572,6 +1612,45 @@ void IRac::samsung(IRSamsungAc *ac,
|
||||
}
|
||||
#endif // SEND_SAMSUNG_AC
|
||||
|
||||
#if SEND_SANYO_AC
|
||||
/// Send a Toshiba A/C message with the supplied settings.
|
||||
/// @param[in, out] ac A Ptr to an IRSanyoAc object to use.
|
||||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @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] beep Enable/Disable beeps when receiving IR messages.
|
||||
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
|
||||
void IRac::sanyo(IRSanyoAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool beep,
|
||||
const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setSwingV(ac->convertSwingV(swingv));
|
||||
// No Horizontal swing setting available.
|
||||
// No Quiet setting available.
|
||||
// No Turbo setting available.
|
||||
// No Econo setting available.
|
||||
// No Light setting available.
|
||||
// No Filter setting available.
|
||||
// No Clean setting available.
|
||||
ac->setBeep(beep);
|
||||
ac->setSleep(sleep >= 0); // Sleep is either on/off, so convert to boolean.
|
||||
// No Clock setting available.
|
||||
|
||||
// Extra
|
||||
ac->setSensor(true); // Set the A/C to use the temp sensor in the Unit/Wall.
|
||||
ac->setSensorTemp(degrees); // Set the sensor temp to the desired temp.
|
||||
ac->send();
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
|
||||
#if SEND_SHARP_AC
|
||||
/// Send a Sharp A/C message with the supplied settings.
|
||||
/// @note Multiple IR messages may be generated & sent.
|
||||
@ -1703,18 +1782,26 @@ void IRac::teco(IRTecoAc *ac,
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @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] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] econo Run the device in economical mode.
|
||||
void IRac::toshiba(IRToshibaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan) {
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv,
|
||||
const bool turbo, const bool econo) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
// No Vertical swing setting available.
|
||||
// The API has no "step" option, so off is off, anything else is on.
|
||||
ac->setSwing((swingv == stdAc::swingv_t::kOff) ? kToshibaAcSwingOff
|
||||
: kToshibaAcSwingOn);
|
||||
// No Horizontal swing setting available.
|
||||
// No Quiet setting available.
|
||||
// No Turbo setting available.
|
||||
ac->setTurbo(turbo);
|
||||
ac->setEcono(econo);
|
||||
// No Light setting available.
|
||||
// No Filter setting available.
|
||||
// No Clean setting available.
|
||||
@ -1881,10 +1968,12 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
|
||||
case decode_type_t::ELECTRA_AC:
|
||||
result.light = desired.light ^ prev->light;
|
||||
break;
|
||||
case decode_type_t::MIDEA:
|
||||
result.econo = desired.econo ^ prev->econo;
|
||||
// FALL THRU
|
||||
case decode_type_t::CORONA_AC:
|
||||
case decode_type_t::HITACHI_AC344:
|
||||
case decode_type_t::HITACHI_AC424:
|
||||
case decode_type_t::MIDEA:
|
||||
case decode_type_t::SHARP_AC:
|
||||
if ((desired.swingv == stdAc::swingv_t::kOff) ^
|
||||
(prev->swingv == stdAc::swingv_t::kOff)) // It changed, so toggle.
|
||||
@ -1892,6 +1981,7 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
|
||||
else
|
||||
result.swingv = stdAc::swingv_t::kOff; // No change, so no toggle.
|
||||
break;
|
||||
case decode_type_t::AIRWELL:
|
||||
case decode_type_t::DAIKIN64:
|
||||
case decode_type_t::WHIRLPOOL_AC:
|
||||
result.power = desired.power ^ prev->power;
|
||||
@ -1959,6 +2049,14 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
||||
stdAc::state_t send = this->handleToggles(this->cleanState(desired), prev);
|
||||
// Per vendor settings & setup.
|
||||
switch (send.protocol) {
|
||||
#if SEND_AIRWELL
|
||||
case AIRWELL:
|
||||
{
|
||||
IRAirwellAc ac(_pin, _inverted, _modulation);
|
||||
airwell(&ac, send.power, send.mode, degC, send.fanspeed);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_AIRWELL
|
||||
#if SEND_AMCOR
|
||||
case AMCOR:
|
||||
{
|
||||
@ -2210,7 +2308,7 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
||||
{
|
||||
IRMideaAC ac(_pin, _inverted, _modulation);
|
||||
midea(&ac, send.power, send.mode, send.celsius, send.degrees,
|
||||
send.fanspeed, send.swingv, send.sleep);
|
||||
send.fanspeed, send.swingv, send.econo, send.sleep);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_MIDEA
|
||||
@ -2288,6 +2386,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
||||
break;
|
||||
}
|
||||
#endif // SEND_SAMSUNG_AC
|
||||
#if SEND_SANYO_AC
|
||||
case SANYO_AC:
|
||||
{
|
||||
IRSanyoAc ac(_pin, _inverted, _modulation);
|
||||
sanyo(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.beep, send.sleep);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
#if SEND_SHARP_AC
|
||||
case SHARP_AC:
|
||||
{
|
||||
@ -2321,7 +2428,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
||||
case TOSHIBA_AC:
|
||||
{
|
||||
IRToshibaAC ac(_pin, _inverted, _modulation);
|
||||
toshiba(&ac, send.power, send.mode, degC, send.fanspeed);
|
||||
toshiba(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.turbo, send.econo);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_TOSHIBA_AC
|
||||
@ -2715,16 +2823,23 @@ namespace IRAcUtils {
|
||||
/// An empty string if we can't.
|
||||
String resultAcToString(const decode_results * const result) {
|
||||
switch (result->decode_type) {
|
||||
#if DECODE_AIRWELL
|
||||
case decode_type_t::AIRWELL: {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // AIRWELL uses value instead of state.
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_AIRWELL
|
||||
#if DECODE_AMCOR
|
||||
case decode_type_t::AMCOR: {
|
||||
IRAmcorAc ac(0);
|
||||
IRAmcorAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_AMCOR
|
||||
#if DECODE_ARGO
|
||||
case decode_type_t::ARGO: {
|
||||
IRArgoAC ac(0);
|
||||
IRArgoAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
@ -2738,49 +2853,49 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_CARRIER_AC64
|
||||
#if DECODE_DAIKIN
|
||||
case decode_type_t::DAIKIN: {
|
||||
IRDaikinESP ac(0);
|
||||
IRDaikinESP ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN
|
||||
#if DECODE_DAIKIN128
|
||||
case decode_type_t::DAIKIN128: {
|
||||
IRDaikin128 ac(0);
|
||||
IRDaikin128 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN128
|
||||
#if DECODE_DAIKIN152
|
||||
case decode_type_t::DAIKIN152: {
|
||||
IRDaikin152 ac(0);
|
||||
IRDaikin152 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN152
|
||||
#if DECODE_DAIKIN160
|
||||
case decode_type_t::DAIKIN160: {
|
||||
IRDaikin160 ac(0);
|
||||
IRDaikin160 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN160
|
||||
#if DECODE_DAIKIN176
|
||||
case decode_type_t::DAIKIN176: {
|
||||
IRDaikin176 ac(0);
|
||||
IRDaikin176 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN160
|
||||
#if DECODE_DAIKIN2
|
||||
case decode_type_t::DAIKIN2: {
|
||||
IRDaikin2 ac(0);
|
||||
IRDaikin2 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_DAIKIN2
|
||||
#if DECODE_DAIKIN216
|
||||
case decode_type_t::DAIKIN216: {
|
||||
IRDaikin216 ac(0);
|
||||
IRDaikin216 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
@ -2801,131 +2916,138 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_DELONGHI_AC
|
||||
#if DECODE_ELECTRA_AC
|
||||
case decode_type_t::ELECTRA_AC: {
|
||||
IRElectraAc ac(0);
|
||||
IRElectraAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_ELECTRA_AC
|
||||
#if DECODE_FUJITSU_AC
|
||||
case decode_type_t::FUJITSU_AC: {
|
||||
IRFujitsuAC ac(0);
|
||||
IRFujitsuAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state, result->bits / 8);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_FUJITSU_AC
|
||||
#if DECODE_KELVINATOR
|
||||
case decode_type_t::KELVINATOR: {
|
||||
IRKelvinatorAC ac(0);
|
||||
IRKelvinatorAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_KELVINATOR
|
||||
#if DECODE_MITSUBISHI_AC
|
||||
case decode_type_t::MITSUBISHI_AC: {
|
||||
IRMitsubishiAC ac(0);
|
||||
IRMitsubishiAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_MITSUBISHI_AC
|
||||
#if DECODE_MITSUBISHI112
|
||||
case decode_type_t::MITSUBISHI112: {
|
||||
IRMitsubishi112 ac(0);
|
||||
IRMitsubishi112 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_MITSUBISHI112
|
||||
#if DECODE_MITSUBISHI136
|
||||
case decode_type_t::MITSUBISHI136: {
|
||||
IRMitsubishi136 ac(0);
|
||||
IRMitsubishi136 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_MITSUBISHI136
|
||||
#if DECODE_MITSUBISHIHEAVY
|
||||
case decode_type_t::MITSUBISHI_HEAVY_88: {
|
||||
IRMitsubishiHeavy88Ac ac(0);
|
||||
IRMitsubishiHeavy88Ac ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
case decode_type_t::MITSUBISHI_HEAVY_152: {
|
||||
IRMitsubishiHeavy152Ac ac(0);
|
||||
IRMitsubishiHeavy152Ac ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_MITSUBISHIHEAVY
|
||||
#if DECODE_NEOCLIMA
|
||||
case decode_type_t::NEOCLIMA: {
|
||||
IRNeoclimaAc ac(0);
|
||||
IRNeoclimaAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_NEOCLIMA
|
||||
#if DECODE_TOSHIBA_AC
|
||||
case decode_type_t::TOSHIBA_AC: {
|
||||
IRToshibaAC ac(0);
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_TOSHIBA_AC
|
||||
#if DECODE_TROTEC
|
||||
case decode_type_t::TROTEC: {
|
||||
IRTrotecESP ac(0);
|
||||
IRTrotecESP ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_TROTEC
|
||||
#if DECODE_GOODWEATHER
|
||||
case decode_type_t::GOODWEATHER: {
|
||||
IRGoodweatherAc ac(0);
|
||||
IRGoodweatherAc ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // Goodweather uses value instead of state.
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_GOODWEATHER
|
||||
#if DECODE_GREE
|
||||
case decode_type_t::GREE: {
|
||||
IRGreeAC ac(0);
|
||||
IRGreeAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_GREE
|
||||
#if DECODE_MIDEA
|
||||
case decode_type_t::MIDEA: {
|
||||
IRMideaAC ac(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // Midea uses value instead of state.
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_MIDEA
|
||||
#if DECODE_HAIER_AC
|
||||
case decode_type_t::HAIER_AC: {
|
||||
IRHaierAC ac(0);
|
||||
IRHaierAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_HAIER_AC
|
||||
#if DECODE_HAIER_AC_YRW02
|
||||
case decode_type_t::HAIER_AC_YRW02: {
|
||||
IRHaierACYRW02 ac(0);
|
||||
IRHaierACYRW02 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_HAIER_AC_YRW02
|
||||
#if DECODE_SAMSUNG_AC
|
||||
case decode_type_t::SAMSUNG_AC: {
|
||||
IRSamsungAc ac(0);
|
||||
IRSamsungAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state, result->bits / 8);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_SAMSUNG_AC
|
||||
#if DECODE_SANYO_AC
|
||||
case decode_type_t::SANYO_AC: {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_SANYO_AC
|
||||
#if DECODE_SHARP_AC
|
||||
case decode_type_t::SHARP_AC: {
|
||||
IRSharpAc ac(0);
|
||||
IRSharpAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_SHARP_AC
|
||||
#if DECODE_COOLIX
|
||||
case decode_type_t::COOLIX: {
|
||||
IRCoolixAC ac(0);
|
||||
IRCoolixAC ac(kGpioUnused);
|
||||
ac.on();
|
||||
ac.setRaw(result->value); // Coolix uses value instead of state.
|
||||
return ac.toString();
|
||||
@ -2941,7 +3063,7 @@ namespace IRAcUtils {
|
||||
#if DECODE_PANASONIC_AC
|
||||
case decode_type_t::PANASONIC_AC: {
|
||||
if (result->bits > kPanasonicAcShortBits) {
|
||||
IRPanasonicAc ac(0);
|
||||
IRPanasonicAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
@ -2950,7 +3072,7 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_PANASONIC_AC
|
||||
#if DECODE_HITACHI_AC
|
||||
case decode_type_t::HITACHI_AC: {
|
||||
IRHitachiAc ac(0);
|
||||
IRHitachiAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
@ -2971,35 +3093,35 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_HITACHI_AC344
|
||||
#if DECODE_HITACHI_AC424
|
||||
case decode_type_t::HITACHI_AC424: {
|
||||
IRHitachiAc424 ac(0);
|
||||
IRHitachiAc424 ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_HITACHI_AC424
|
||||
#if DECODE_WHIRLPOOL_AC
|
||||
case decode_type_t::WHIRLPOOL_AC: {
|
||||
IRWhirlpoolAc ac(0);
|
||||
IRWhirlpoolAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_WHIRLPOOL_AC
|
||||
#if DECODE_VESTEL_AC
|
||||
case decode_type_t::VESTEL_AC: {
|
||||
IRVestelAc ac(0);
|
||||
IRVestelAc ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // Like Coolix, use value instead of state.
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_VESTEL_AC
|
||||
#if DECODE_TECO
|
||||
case decode_type_t::TECO: {
|
||||
IRTecoAc ac(0);
|
||||
IRTecoAc ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // Like Coolix, use value instead of state.
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_TECO
|
||||
#if DECODE_TCL112AC
|
||||
case decode_type_t::TCL112AC: {
|
||||
IRTcl112Ac ac(0);
|
||||
IRTcl112Ac ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
@ -3007,7 +3129,7 @@ namespace IRAcUtils {
|
||||
#if DECODE_LG
|
||||
case decode_type_t::LG:
|
||||
case decode_type_t::LG2: {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setRaw(result->value); // Like Coolix, use value instead of state.
|
||||
switch (result->decode_type) {
|
||||
case decode_type_t::LG2:
|
||||
@ -3040,6 +3162,14 @@ namespace IRAcUtils {
|
||||
) {
|
||||
if (decode == NULL || result == NULL) return false; // Safety check.
|
||||
switch (decode->decode_type) {
|
||||
#if DECODE_AIRWELL
|
||||
case decode_type_t::AIRWELL: {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
ac.setRaw(decode->value); // Uses value instead of state.
|
||||
*result = ac.toCommon();
|
||||
break;
|
||||
}
|
||||
#endif // DECODE_AIRWELL
|
||||
#if DECODE_AMCOR
|
||||
case decode_type_t::AMCOR: {
|
||||
IRAmcorAc ac(kGpioUnused);
|
||||
@ -3090,7 +3220,7 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_DAIKIN
|
||||
#if DECODE_DAIKIN128
|
||||
case decode_type_t::DAIKIN128: {
|
||||
IRDaikin128 ac(0);
|
||||
IRDaikin128 ac(kGpioUnused);
|
||||
ac.setRaw(decode->state);
|
||||
*result = ac.toCommon();
|
||||
break;
|
||||
@ -3098,7 +3228,7 @@ namespace IRAcUtils {
|
||||
#endif // DECODE_DAIKIN128
|
||||
#if DECODE_DAIKIN152
|
||||
case decode_type_t::DAIKIN152: {
|
||||
IRDaikin152 ac(0);
|
||||
IRDaikin152 ac(kGpioUnused);
|
||||
ac.setRaw(decode->state);
|
||||
*result = ac.toCommon();
|
||||
break;
|
||||
@ -3327,6 +3457,14 @@ namespace IRAcUtils {
|
||||
break;
|
||||
}
|
||||
#endif // DECODE_SAMSUNG_AC
|
||||
#if DECODE_SANYO_AC
|
||||
case decode_type_t::SANYO_AC: {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.setRaw(decode->state);
|
||||
*result = ac.toCommon();
|
||||
break;
|
||||
}
|
||||
#endif // DECODE_SANYO_AC
|
||||
#if DECODE_SHARP_AC
|
||||
case decode_type_t::SHARP_AC: {
|
||||
IRSharpAc ac(kGpioUnused);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "ir_Airwell.h"
|
||||
#include "ir_Amcor.h"
|
||||
#include "ir_Argo.h"
|
||||
#include "ir_Carrier.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "ir_Neoclima.h"
|
||||
#include "ir_Panasonic.h"
|
||||
#include "ir_Samsung.h"
|
||||
#include "ir_Sanyo.h"
|
||||
#include "ir_Sharp.h"
|
||||
#include "ir_Tcl.h"
|
||||
#include "ir_Teco.h"
|
||||
@ -37,9 +39,10 @@
|
||||
#include "ir_Whirlpool.h"
|
||||
|
||||
// Constants
|
||||
const int8_t kGpioUnused = -1;
|
||||
const int8_t kGpioUnused = -1; ///< A placeholder for not using an actual GPIO.
|
||||
|
||||
// Class
|
||||
/// A universal/common/generic interface for controling supported A/Cs.
|
||||
class IRac {
|
||||
public:
|
||||
explicit IRac(const uint16_t pin, const bool inverted = false,
|
||||
@ -93,10 +96,15 @@ class IRac {
|
||||
|
||||
private:
|
||||
#endif
|
||||
uint16_t _pin;
|
||||
bool _inverted;
|
||||
bool _modulation;
|
||||
stdAc::state_t _prev; // The state we expect the device to currently be in.
|
||||
uint16_t _pin; ///< The GPIO to use to transmit messages from.
|
||||
bool _inverted; ///< IR LED is lit when GPIO is LOW (true) or HIGH (false)?
|
||||
bool _modulation; ///< Is frequency modulation to be used?
|
||||
stdAc::state_t _prev; ///< The state we expect the device to currently be in.
|
||||
#if SEND_AIRWELL
|
||||
void airwell(IRAirwellAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan);
|
||||
#endif // SEND_AIRWELL
|
||||
#if SEND_AMCOR
|
||||
void amcor(IRAmcorAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
@ -286,7 +294,8 @@ void electra(IRElectraAc *ac,
|
||||
void midea(IRMideaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const int16_t sleep = -1);
|
||||
const stdAc::swingv_t swingv, const bool econo,
|
||||
const int16_t sleep = -1);
|
||||
#endif // SEND_MIDEA
|
||||
#if SEND_MITSUBISHI_AC
|
||||
void mitsubishi(IRMitsubishiAC *ac,
|
||||
@ -350,6 +359,12 @@ void electra(IRElectraAc *ac,
|
||||
const bool beep, const bool prevpower = true,
|
||||
const bool forcepower = true);
|
||||
#endif // SEND_SAMSUNG_AC
|
||||
#if SEND_SANYO_AC
|
||||
void sanyo(IRSanyoAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool beep, const int16_t sleep = -1);
|
||||
#endif // SEND_SANYO_AC
|
||||
#if SEND_SHARP_AC
|
||||
void sharp(IRSharpAc *ac,
|
||||
const bool on, const bool prev_power, const stdAc::opmode_t mode,
|
||||
@ -374,7 +389,8 @@ void electra(IRElectraAc *ac,
|
||||
#if SEND_TOSHIBA_AC
|
||||
void toshiba(IRToshibaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan);
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool turbo, const bool econo);
|
||||
#endif // SEND_TOSHIBA_AC
|
||||
#if SEND_TROTEC
|
||||
void trotec(IRTrotecESP *ac,
|
||||
@ -401,6 +417,7 @@ static stdAc::state_t handleToggles(const stdAc::state_t desired,
|
||||
const stdAc::state_t *prev = NULL);
|
||||
}; // IRac class
|
||||
|
||||
/// Common functions for use with all A/Cs supported by the IRac class.
|
||||
namespace IRAcUtils {
|
||||
String resultAcToString(const decode_results * const results);
|
||||
bool decodeToState(const decode_results *decode, stdAc::state_t *result,
|
||||
|
@ -614,8 +614,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
||||
if (decodeDaikin216(results, offset)) return true;
|
||||
#endif
|
||||
#if DECODE_TOSHIBA_AC
|
||||
DPRINTLN("Attempting Toshiba AC decode");
|
||||
DPRINTLN("Attempting Toshiba AC 72bit decode");
|
||||
if (decodeToshibaAC(results, offset)) return true;
|
||||
DPRINTLN("Attempting Toshiba AC 80bit decode");
|
||||
if (decodeToshibaAC(results, offset, kToshibaACBitsLong)) return true;
|
||||
DPRINTLN("Attempting Toshiba AC 56bit decode");
|
||||
if (decodeToshibaAC(results, offset, kToshibaACBitsShort)) return true;
|
||||
#endif
|
||||
#if DECODE_MIDEA
|
||||
DPRINTLN("Attempting Midea decode");
|
||||
@ -852,6 +856,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
||||
DPRINTLN("Attempting Zepeal decode");
|
||||
if (decodeZepeal(results, offset)) return true;
|
||||
#endif // DECODE_ZEPEAL
|
||||
#if DECODE_SANYO_AC
|
||||
DPRINTLN("Attempting Sanyo AC decode");
|
||||
if (decodeSanyoAc(results, offset)) return true;
|
||||
#endif // DECODE_SANYO_AC
|
||||
// Typically new protocols are added above this line.
|
||||
}
|
||||
#if DECODE_HASH
|
||||
|
@ -283,8 +283,14 @@ class IRrecv {
|
||||
bool decodeSanyoLC7461(decode_results *results,
|
||||
uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kSanyoLC7461Bits,
|
||||
bool strict = true);
|
||||
const bool strict = true);
|
||||
#endif
|
||||
#if DECODE_SANYO_AC
|
||||
bool decodeSanyoAc(decode_results *results,
|
||||
uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kSanyoAcBits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_SANYO_AC
|
||||
#if DECODE_MITSUBISHI
|
||||
bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kMitsubishiBits,
|
||||
@ -469,7 +475,7 @@ class IRrecv {
|
||||
#endif
|
||||
#if DECODE_TOSHIBA_AC
|
||||
bool decodeToshibaAC(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbytes = kToshibaACBits,
|
||||
const uint16_t nbits = kToshibaACBits,
|
||||
const bool strict = true);
|
||||
#endif
|
||||
#if DECODE_TROTEC
|
||||
|
@ -201,6 +201,13 @@
|
||||
#define SEND_SANYO _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_SANYO
|
||||
|
||||
#ifndef DECODE_SANYO_AC
|
||||
#define DECODE_SANYO_AC _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_SANYO_AC
|
||||
#ifndef SEND_SANYO_AC
|
||||
#define SEND_SANYO_AC _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_SANYO_AC
|
||||
|
||||
#ifndef DECODE_MITSUBISHI
|
||||
#define DECODE_MITSUBISHI _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_MITSUBISHI
|
||||
@ -674,7 +681,7 @@
|
||||
DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \
|
||||
DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \
|
||||
DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \
|
||||
DECODE_HITACHI_AC344 || DECODE_CORONA_AC)
|
||||
DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC)
|
||||
// Add any DECODE to the above if it uses result->state (see kStateSizeMax)
|
||||
// you might also want to add the protocol to hasACState function
|
||||
#define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
|
||||
@ -802,8 +809,9 @@ enum decode_type_t {
|
||||
CORONA_AC,
|
||||
MIDEA24,
|
||||
ZEPEAL,
|
||||
SANYO_AC,
|
||||
// Add new entries before this one, and update it to point to the last entry.
|
||||
kLastDecodeType = ZEPEAL,
|
||||
kLastDecodeType = SANYO_AC,
|
||||
};
|
||||
|
||||
// Message lengths & required repeat values
|
||||
@ -971,6 +979,8 @@ const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8;
|
||||
const uint16_t kSamsungAcExtendedStateLength = 21;
|
||||
const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8;
|
||||
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat;
|
||||
const uint16_t kSanyoAcStateLength = 9;
|
||||
const uint16_t kSanyoAcBits = kSanyoAcStateLength * 8;
|
||||
const uint16_t kSanyoSA8650BBits = 12;
|
||||
const uint16_t kSanyoLC7461AddressBits = 13;
|
||||
const uint16_t kSanyoLC7461CommandBits = 8;
|
||||
@ -999,6 +1009,10 @@ const uint16_t kTecoDefaultRepeat = kNoRepeat;
|
||||
const uint16_t kToshibaACStateLength = 9;
|
||||
const uint16_t kToshibaACBits = kToshibaACStateLength * 8;
|
||||
const uint16_t kToshibaACMinRepeat = kSingleRepeat;
|
||||
const uint16_t kToshibaACStateLengthShort = kToshibaACStateLength - 2;
|
||||
const uint16_t kToshibaACBitsShort = kToshibaACStateLengthShort * 8;
|
||||
const uint16_t kToshibaACStateLengthLong = kToshibaACStateLength + 1;
|
||||
const uint16_t kToshibaACBitsLong = kToshibaACStateLengthLong * 8;
|
||||
const uint16_t kTrotecStateLength = 9;
|
||||
const uint16_t kTrotecBits = kTrotecStateLength * 8;
|
||||
const uint16_t kTrotecDefaultRepeat = kNoRepeat;
|
||||
|
@ -721,6 +721,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
|
||||
return kNeoclimaBits;
|
||||
case SAMSUNG_AC:
|
||||
return kSamsungAcBits;
|
||||
case SANYO_AC:
|
||||
return kSanyoAcBits;
|
||||
case SHARP_AC:
|
||||
return kSharpAcBits;
|
||||
case TCL112AC:
|
||||
@ -1152,6 +1154,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
|
||||
sendSamsungAC(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_SAMSUNG_AC
|
||||
#if SEND_SANYO_AC
|
||||
case SANYO_AC:
|
||||
sendSanyoAc(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_SANYO_AC
|
||||
#if SEND_SHARP_AC
|
||||
case SHARP_AC:
|
||||
sendSharpAc(state, nbytes);
|
||||
|
@ -294,6 +294,11 @@ class IRsend {
|
||||
const uint16_t nbits = kSanyoLC7461Bits,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif
|
||||
#if SEND_SANYO_AC
|
||||
void sendSanyoAc(const uint8_t *data,
|
||||
const uint16_t nbytes = kSanyoAcStateLength,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_SANYO_AC
|
||||
#if SEND_DISH
|
||||
// sendDISH() should typically be called with repeat=3 as DISH devices
|
||||
// expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
|
||||
@ -461,7 +466,7 @@ class IRsend {
|
||||
uint16_t repeat = kNoRepeat);
|
||||
#endif
|
||||
#if SEND_TOSHIBA_AC
|
||||
void sendToshibaAC(const unsigned char data[],
|
||||
void sendToshibaAC(const uint8_t data[],
|
||||
const uint16_t nbytes = kToshibaACStateLength,
|
||||
const uint16_t repeat = kToshibaACMinRepeat);
|
||||
#endif
|
||||
|
@ -130,6 +130,7 @@ const PROGMEM char* kTopStr = D_STR_TOP; ///< "Top"
|
||||
const PROGMEM char* kBottomStr = D_STR_BOTTOM; ///< "Bottom"
|
||||
|
||||
// Compound words/phrases/descriptions from pre-defined words.
|
||||
const PROGMEM char* kEconoToggleStr = D_STR_ECONOTOGGLE; ///< "Econo Toggle"
|
||||
const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; ///< "Eye Auto"
|
||||
const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; ///< "Light Toggle"
|
||||
const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; ///< "Outside Quiet"
|
||||
@ -264,5 +265,6 @@ const PROGMEM char *kAllProtocolNamesStr =
|
||||
D_STR_CORONA_AC "\x0"
|
||||
D_STR_MIDEA24 "\x0"
|
||||
D_STR_ZEPEAL "\x0"
|
||||
D_STR_SANYO_AC "\x0"
|
||||
///< New protocol strings should be added just above this line.
|
||||
"\x0"; ///< This string requires double null termination.
|
||||
|
@ -45,6 +45,7 @@ extern const char* kDisplayTempStr;
|
||||
extern const char* kDownStr;
|
||||
extern const char* kDryStr;
|
||||
extern const char* kEconoStr;
|
||||
extern const char* kEconoToggleStr;
|
||||
extern const char* kEyeAutoStr;
|
||||
extern const char* kEyeStr;
|
||||
extern const char* kFalseStr;
|
||||
@ -104,10 +105,10 @@ extern const char* kOnStr;
|
||||
extern const char* kOnTimerStr;
|
||||
extern const char* kOutsideQuietStr;
|
||||
extern const char* kOutsideStr;
|
||||
extern const char* kPowerButtonStr;
|
||||
extern const char* kPowerfulStr;
|
||||
extern const char* kPowerStr;
|
||||
extern const char* kPowerToggleStr;
|
||||
extern const char* kPowerButtonStr;
|
||||
extern const char* kPreviousPowerStr;
|
||||
extern const char* kProtocolStr;
|
||||
extern const char* kPurifyStr;
|
||||
|
@ -14,7 +14,7 @@ uint32_t _TimerMs_unittest_now = 0;
|
||||
/// Class constructor.
|
||||
IRtimer::IRtimer() { reset(); }
|
||||
|
||||
/// Resets the IRtimer object.
|
||||
/// Resets the IRtimer object. I.e. The counter starts again from now.
|
||||
void IRtimer::reset() {
|
||||
#ifndef UNIT_TEST
|
||||
start = micros();
|
||||
@ -47,7 +47,7 @@ void IRtimer::add(uint32_t usecs) { _IRtimer_unittest_now += usecs; }
|
||||
/// Class constructor.
|
||||
TimerMs::TimerMs() { reset(); }
|
||||
|
||||
/// Resets the TimerMs object.
|
||||
/// Resets the TimerMs object. I.e. The counter starts again from now.
|
||||
void TimerMs::reset() {
|
||||
#ifndef UNIT_TEST
|
||||
start = millis();
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
// Classes
|
||||
|
||||
/// This class performs a simple timer in useconds since instantiated.
|
||||
/// This class offers a simple counter in micro-seconds since instantiated.
|
||||
/// @note Handles when the system timer wraps around (once).
|
||||
class IRtimer {
|
||||
public:
|
||||
@ -20,10 +20,10 @@ class IRtimer {
|
||||
#endif // UNIT_TEST
|
||||
|
||||
private:
|
||||
uint32_t start;
|
||||
uint32_t start; ///< Time in uSeconds when the class was instantiated/reset.
|
||||
};
|
||||
|
||||
/// This class performs a simple timer in milli-seoncds since instantiated.
|
||||
/// This class offers a simple counter in milli-seconds since instantiated.
|
||||
/// @note Handles when the system timer wraps around (once).
|
||||
class TimerMs {
|
||||
public:
|
||||
@ -35,6 +35,6 @@ class TimerMs {
|
||||
#endif // UNIT_TEST
|
||||
|
||||
private:
|
||||
uint32_t start;
|
||||
uint32_t start; ///< Time in mSeconds when the class was instantiated/reset.
|
||||
};
|
||||
#endif // IRTIMER_H_
|
||||
|
@ -161,6 +161,7 @@ bool hasACState(const decode_type_t protocol) {
|
||||
case NEOCLIMA:
|
||||
case PANASONIC_AC:
|
||||
case SAMSUNG_AC:
|
||||
case SANYO_AC:
|
||||
case SHARP_AC:
|
||||
case TCL112AC:
|
||||
case TOSHIBA_AC:
|
||||
@ -915,4 +916,35 @@ namespace irutils {
|
||||
// Merge in the data.
|
||||
*dst |= ((data & mask) << offset);
|
||||
}
|
||||
|
||||
/// Create byte pairs where the second byte of the pair is a bit
|
||||
/// inverted/flipped copy of the first/previous byte of the pair.
|
||||
/// @param[in,out] ptr A pointer to the start of array to modify.
|
||||
/// @param[in] length The byte size of the array.
|
||||
/// @note A length of `<= 1` will do nothing.
|
||||
/// @return A ptr to the modified array.
|
||||
uint8_t * invertBytePairs(uint8_t *ptr, const uint16_t length) {
|
||||
for (uint16_t i = 1; i < length; i += 2) {
|
||||
// Code done this way to avoid a compiler warning bug.
|
||||
uint8_t inv = ~*(ptr + i - 1);
|
||||
*(ptr + i) = inv;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// Check an array to see if every second byte of a pair is a bit
|
||||
/// inverted/flipped copy of the first/previous byte of the pair.
|
||||
/// @param[in] ptr A pointer to the start of array to check.
|
||||
/// @param[in] length The byte size of the array.
|
||||
/// @note A length of `<= 1` will always return true.
|
||||
/// @return true, if every second byte is inverted. Otherwise false.
|
||||
bool checkInvertedBytePairs(const uint8_t * const ptr,
|
||||
const uint16_t length) {
|
||||
for (uint16_t i = 1; i < length; i += 2) {
|
||||
// Code done this way to avoid a compiler warning bug.
|
||||
uint8_t inv = ~*(ptr + i - 1);
|
||||
if (*(ptr + i) != inv) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace irutils
|
||||
|
@ -107,5 +107,7 @@ namespace irutils {
|
||||
const uint32_t data);
|
||||
void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits,
|
||||
const uint64_t data);
|
||||
uint8_t * invertBytePairs(uint8_t *ptr, const uint16_t length);
|
||||
bool checkInvertedBytePairs(const uint8_t * const ptr, const uint16_t length);
|
||||
} // namespace irutils
|
||||
#endif // IRUTILS_H_
|
||||
|
@ -1,23 +1,28 @@
|
||||
// Copyright 2020 David Conran
|
||||
|
||||
#include "ir_Airwell.h"
|
||||
#include <algorithm>
|
||||
#include "IRrecv.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRtext.h"
|
||||
#include "IRutils.h"
|
||||
|
||||
/// @file
|
||||
/// @brief Airwell "Manchester code" based protocol.
|
||||
/// Some other Airwell products use the COOLIX protocol.
|
||||
|
||||
// Supports:
|
||||
// Brand: Airwell, Model: RC08W remote
|
||||
// Brand: Airwell, Model: RC04 remote
|
||||
// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C
|
||||
|
||||
const uint8_t kAirwellOverhead = 4;
|
||||
const uint16_t kAirwellHalfClockPeriod = 950; // uSeconds
|
||||
const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod; // uSeconds
|
||||
const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod; // uSeconds
|
||||
const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod; // uSeconds
|
||||
|
||||
using irutils::addBoolToString;
|
||||
using irutils::addModeToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
|
||||
#if SEND_AIRWELL
|
||||
/// Send an Airwell Manchester Code formatted message.
|
||||
/// Status: BETA / Appears to be working.
|
||||
@ -74,3 +79,203 @@ bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset,
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Class constructor
|
||||
/// @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?
|
||||
IRAirwellAc::IRAirwellAc(const uint16_t pin, const bool inverted,
|
||||
const bool use_modulation)
|
||||
: _irsend(pin, inverted, use_modulation) { stateReset(); }
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
void IRAirwellAc::begin(void) { _irsend.begin(); }
|
||||
|
||||
/// Get the raw state of the object, suitable to be sent with the appropriate
|
||||
/// IRsend object method.
|
||||
/// @return A copy of the internal state.
|
||||
uint64_t IRAirwellAc::getRaw(void) {
|
||||
return remote_state;
|
||||
}
|
||||
|
||||
/// Set the raw state of the object.
|
||||
/// @param[in] state The raw state from the native IR message.
|
||||
void IRAirwellAc::setRaw(const uint64_t state) {
|
||||
remote_state = state;
|
||||
}
|
||||
|
||||
#if SEND_AIRWELL
|
||||
/// Send the current internal state as an IR message.
|
||||
/// @param[in] repeat Nr. of times the message will be repeated.
|
||||
void IRAirwellAc::send(const uint16_t repeat) {
|
||||
_irsend.sendAirwell(getRaw(), kAirwellBits, repeat);
|
||||
}
|
||||
#endif // SEND_AIRWELL
|
||||
|
||||
/// Reset the internals of the object to a known good state.
|
||||
void IRAirwellAc::stateReset(void) {
|
||||
remote_state = kAirwellKnownGoodState;
|
||||
}
|
||||
|
||||
/// Turn on/off the Power Airwell setting.
|
||||
/// @param[in] on The desired setting state.
|
||||
void IRAirwellAc::setPowerToggle(const bool on) {
|
||||
setBit(&remote_state, kAirwellPowerToggleBit, on);
|
||||
}
|
||||
|
||||
/// Get the power toggle setting from the internal state.
|
||||
/// @return A boolean indicating the setting.
|
||||
bool IRAirwellAc::getPowerToggle(void) {
|
||||
return GETBIT64(remote_state, kAirwellPowerToggleBit);
|
||||
}
|
||||
|
||||
/// Get the current operation mode setting.
|
||||
/// @return The current operation mode.
|
||||
uint8_t IRAirwellAc::getMode(void) {
|
||||
return GETBITS64(remote_state, kAirwellModeOffset, kAirwellModeSize);
|
||||
}
|
||||
|
||||
/// Set the desired operation mode.
|
||||
/// @param[in] mode The desired operation mode.
|
||||
void IRAirwellAc::setMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kAirwellFan:
|
||||
case kAirwellCool:
|
||||
case kAirwellHeat:
|
||||
case kAirwellDry:
|
||||
case kAirwellAuto:
|
||||
setBits(&remote_state, kAirwellModeOffset, kAirwellModeSize, mode);
|
||||
break;
|
||||
default:
|
||||
setMode(kAirwellAuto);
|
||||
}
|
||||
setFan(getFan()); // Ensure the fan is at the correct speed for the new mode.
|
||||
}
|
||||
|
||||
/// Convert a stdAc::opmode_t enum into its native mode.
|
||||
/// @param[in] mode The enum to be converted.
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRAirwellAc::convertMode(const stdAc::opmode_t mode) {
|
||||
switch (mode) {
|
||||
case stdAc::opmode_t::kCool: return kAirwellCool;
|
||||
case stdAc::opmode_t::kHeat: return kAirwellHeat;
|
||||
case stdAc::opmode_t::kDry: return kAirwellDry;
|
||||
case stdAc::opmode_t::kFan: return kAirwellFan;
|
||||
default: return kAirwellAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a native mode into its stdAc equivilant.
|
||||
/// @param[in] mode The native setting to be converted.
|
||||
/// @return The stdAc equivilant of the native setting.
|
||||
stdAc::opmode_t IRAirwellAc::toCommonMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kAirwellCool: return stdAc::opmode_t::kCool;
|
||||
case kAirwellHeat: return stdAc::opmode_t::kHeat;
|
||||
case kAirwellDry: return stdAc::opmode_t::kDry;
|
||||
case kAirwellFan: return stdAc::opmode_t::kFan;
|
||||
default: return stdAc::opmode_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the speed of the fan.
|
||||
/// @param[in] speed The desired setting.
|
||||
/// @note The speed is locked to Low when in Dry mode.
|
||||
void IRAirwellAc::setFan(const uint8_t speed) {
|
||||
setBits(&remote_state, kAirwellFanOffset, kAirwellFanSize,
|
||||
(getMode() == kAirwellDry) ? kAirwellFanLow
|
||||
: std::min(speed, kAirwellFanAuto));
|
||||
}
|
||||
|
||||
/// Get the current fan speed setting.
|
||||
/// @return The current fan speed.
|
||||
uint8_t IRAirwellAc::getFan(void) {
|
||||
return GETBITS64(remote_state, kAirwellFanOffset, kAirwellFanSize);
|
||||
}
|
||||
|
||||
/// Convert a stdAc::fanspeed_t enum into it's native speed.
|
||||
/// @param[in] speed The enum to be converted.
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRAirwellAc::convertFan(const stdAc::fanspeed_t speed) {
|
||||
switch (speed) {
|
||||
case stdAc::fanspeed_t::kMin:
|
||||
case stdAc::fanspeed_t::kLow:
|
||||
return kAirwellFanLow;
|
||||
case stdAc::fanspeed_t::kMedium:
|
||||
return kAirwellFanMedium;
|
||||
case stdAc::fanspeed_t::kHigh:
|
||||
case stdAc::fanspeed_t::kMax:
|
||||
return kAirwellFanHigh;
|
||||
default:
|
||||
return kAirwellFanAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a native fan speed into its stdAc equivilant.
|
||||
/// @param[in] speed The native setting to be converted.
|
||||
/// @return The stdAc equivilant of the native setting.
|
||||
stdAc::fanspeed_t IRAirwellAc::toCommonFanSpeed(const uint8_t speed) {
|
||||
switch (speed) {
|
||||
case kAirwellFanHigh: return stdAc::fanspeed_t::kMax;
|
||||
case kAirwellFanMedium: return stdAc::fanspeed_t::kMedium;
|
||||
case kAirwellFanLow: return stdAc::fanspeed_t::kMin;
|
||||
default: return stdAc::fanspeed_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the temperature.
|
||||
/// @param[in] degrees The temperature in degrees celsius.
|
||||
void IRAirwellAc::setTemp(const uint8_t degrees) {
|
||||
uint8_t temp = std::max(kAirwellMinTemp, degrees);
|
||||
temp = std::min(kAirwellMaxTemp, temp);
|
||||
setBits(&remote_state, kAirwellTempOffset, kAirwellTempSize,
|
||||
temp - kAirwellMinTemp + 1);
|
||||
}
|
||||
|
||||
/// Get the current temperature setting.
|
||||
/// @return Get current setting for temp. in degrees celsius.
|
||||
uint8_t IRAirwellAc::getTemp(void) {
|
||||
return GETBITS64(remote_state, kAirwellTempOffset,
|
||||
kAirwellTempSize) + kAirwellMinTemp - 1;
|
||||
}
|
||||
|
||||
/// Convert the current internal state into its stdAc::state_t equivilant.
|
||||
/// @return The stdAc equivilant of the native settings.
|
||||
stdAc::state_t IRAirwellAc::toCommon(void) {
|
||||
stdAc::state_t result;
|
||||
result.protocol = decode_type_t::AIRWELL;
|
||||
result.power = getPowerToggle();
|
||||
result.mode = toCommonMode(getMode());
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.fanspeed = toCommonFanSpeed(getFan());
|
||||
// Not supported.
|
||||
result.model = -1;
|
||||
result.turbo = false;
|
||||
result.swingv = stdAc::swingv_t::kOff;
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
result.light = false;
|
||||
result.filter = false;
|
||||
result.econo = false;
|
||||
result.quiet = false;
|
||||
result.clean = false;
|
||||
result.beep = false;
|
||||
result.sleep = -1;
|
||||
result.clock = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Convert the current internal state into a human readable string.
|
||||
/// @return A human readable string.
|
||||
String IRAirwellAc::toString(void) {
|
||||
String result = "";
|
||||
result.reserve(70); // Reserve some heap for the string to reduce fragging.
|
||||
result += addBoolToString(getPowerToggle(), kPowerToggleStr, false);
|
||||
result += addModeToString(getMode(), kAirwellAuto, kAirwellCool,
|
||||
kAirwellHeat, kAirwellDry, kAirwellFan);
|
||||
result += addFanToString(getFan(), kAirwellFanHigh, kAirwellFanLow,
|
||||
kAirwellFanAuto, kAirwellFanAuto,
|
||||
kAirwellFanMedium);
|
||||
result += addTempToString(getTemp());
|
||||
return result;
|
||||
}
|
||||
|
97
lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h
Normal file
97
lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright 2020 David Conran
|
||||
|
||||
/// @file
|
||||
/// @brief Airwell "Manchester code" based protocol.
|
||||
/// Some other Airwell products use the COOLIX protocol.
|
||||
|
||||
// Supports:
|
||||
// Brand: Airwell, Model: RC08W remote
|
||||
// Brand: Airwell, Model: RC04 remote
|
||||
// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C
|
||||
|
||||
#ifndef IR_AIRWELL_H_
|
||||
#define IR_AIRWELL_H_
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
#ifndef UNIT_TEST
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRsend.h"
|
||||
#ifdef UNIT_TEST
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Constants
|
||||
const uint64_t kAirwellKnownGoodState = 0x140500002; // Mode Fan, Speed 1, 25C
|
||||
// Temperature
|
||||
const uint8_t kAirwellMinTemp = 16; // Celsius
|
||||
const uint8_t kAirwellMaxTemp = 30; // Celsius
|
||||
const uint8_t kAirwellTempSize = 4; // Bits
|
||||
const uint8_t kAirwellTempOffset = 19; // 0b1111 << 19
|
||||
// Fan
|
||||
const uint8_t kAirwellFanSize = 2; // Bits
|
||||
const uint8_t kAirwellFanOffset = 28; // 0b11 << 28
|
||||
const uint8_t kAirwellFanLow = 0; // 0b00
|
||||
const uint8_t kAirwellFanMedium = 1; // 0b01
|
||||
const uint8_t kAirwellFanHigh = 2; // 0b10
|
||||
const uint8_t kAirwellFanAuto = 3; // 0b11
|
||||
// Modes
|
||||
const uint8_t kAirwellModeSize = 3; // Bits
|
||||
const uint8_t kAirwellModeOffset = 30; // 0b111 << 30
|
||||
const uint8_t kAirwellCool = 1; // 0b001
|
||||
const uint8_t kAirwellHeat = 2; // 0b010
|
||||
const uint8_t kAirwellAuto = 3; // 0b011
|
||||
const uint8_t kAirwellDry = 4; // 0b100
|
||||
const uint8_t kAirwellFan = 5; // 0b101
|
||||
// Power
|
||||
const uint8_t kAirwellPowerToggleBit = 33; // 0b1 << 33
|
||||
|
||||
|
||||
// Classes
|
||||
/// Class for handling detailed Airwell A/C messages.
|
||||
class IRAirwellAc {
|
||||
public:
|
||||
explicit IRAirwellAc(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
void stateReset();
|
||||
#if SEND_AIRWELL
|
||||
void send(const uint16_t repeat = kAirwellMinRepeats);
|
||||
/// Run the calibration to calculate uSec timing offsets for this platform.
|
||||
/// @return The uSec timing offset needed per modulation of the IR Led.
|
||||
/// @note This will produce a 65ms IR signal pulse at 38kHz.
|
||||
/// Only ever needs to be run once per object instantiation, if at all.
|
||||
int8_t calibrate(void) { return _irsend.calibrate(); }
|
||||
#endif // SEND_AIRWELL
|
||||
void begin();
|
||||
void setPowerToggle(const bool on);
|
||||
bool getPowerToggle();
|
||||
void setTemp(const uint8_t temp);
|
||||
uint8_t getTemp();
|
||||
void setFan(const uint8_t speed);
|
||||
uint8_t getFan();
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode();
|
||||
uint64_t getRaw();
|
||||
void setRaw(const uint64_t state);
|
||||
uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
stdAc::state_t toCommon(void);
|
||||
String toString();
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
IRsend _irsend; ///< Instance of the IR send class
|
||||
#else
|
||||
/// @cond IGNORE
|
||||
IRsendTest _irsend; ///< Instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif
|
||||
uint64_t remote_state; // The state of the IR remote in native IR code form.
|
||||
void checksum(void);
|
||||
};
|
||||
#endif // IR_AIRWELL_H_
|
@ -598,7 +598,7 @@ class IRDaikinESP {
|
||||
};
|
||||
|
||||
/// Class for handling detailed Daikin 312-bit A/C messages.
|
||||
/// Code by crankyoldgit, Reverse engineering analysis by sheppy99
|
||||
/// @note Code by crankyoldgit, Reverse engineering analysis by sheppy99
|
||||
class IRDaikin2 {
|
||||
public:
|
||||
explicit IRDaikin2(const uint16_t pin, const bool inverted = false,
|
||||
@ -859,8 +859,7 @@ class IRDaikin176 {
|
||||
};
|
||||
|
||||
/// Class for handling detailed Daikin 128-bit A/C messages.
|
||||
/// Code by crankyoldgit.
|
||||
/// Analysis by Daniel Vena
|
||||
/// @note Code by crankyoldgit. Analysis by Daniel Vena
|
||||
class IRDaikin128 {
|
||||
public:
|
||||
explicit IRDaikin128(const uint16_t pin, const bool inverted = false,
|
||||
|
@ -52,6 +52,8 @@ using irutils::addModeToString;
|
||||
using irutils::addModelToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::checkInvertedBytePairs;
|
||||
using irutils::invertBytePairs;
|
||||
using irutils::minsToString;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
@ -1047,8 +1049,7 @@ void IRHitachiAc424::stateReset(void) {
|
||||
|
||||
/// Update the internal consistency check for the protocol.
|
||||
void IRHitachiAc424::setInvertedStates(void) {
|
||||
for (uint8_t i = 3; i < kHitachiAc424StateLength - 1; i += 2)
|
||||
remote_state[i + 1] = ~remote_state[i];
|
||||
invertBytePairs(remote_state + 3, kHitachiAc424StateLength - 3);
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
@ -1402,8 +1403,7 @@ void IRHitachiAc3::stateReset(void) {
|
||||
/// @param[in] length The size of the state array.
|
||||
/// @note This is this protocols integrity check.
|
||||
void IRHitachiAc3::setInvertedStates(const uint16_t length) {
|
||||
for (uint8_t i = 3; i < length - 1; i += 2)
|
||||
remote_state[i + 1] = ~remote_state[i];
|
||||
if (length > 3) invertBytePairs(remote_state + 3, length - 3);
|
||||
}
|
||||
|
||||
/// Check if every second byte of the state, after the fixed header
|
||||
@ -1413,9 +1413,7 @@ void IRHitachiAc3::setInvertedStates(const uint16_t length) {
|
||||
/// @note This is this protocols integrity check.
|
||||
bool IRHitachiAc3::hasInvertedStates(const uint8_t state[],
|
||||
const uint16_t length) {
|
||||
for (uint8_t i = 3; i < length - 1; i += 2)
|
||||
if ((state[i + 1] ^ state[i]) != 0xFF) return false;
|
||||
return true;
|
||||
return (length <= 3 || checkInvertedBytePairs(state + 3, length - 3));
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
|
@ -400,6 +400,7 @@ uint8_t IRLgAc::getTemp(void) {
|
||||
void IRLgAc::setFan(const uint8_t speed) {
|
||||
switch (speed) {
|
||||
case kLgAcFanAuto:
|
||||
case kLgAcFanLowest:
|
||||
case kLgAcFanLow:
|
||||
case kLgAcFanMedium:
|
||||
case kLgAcFanHigh:
|
||||
@ -469,12 +470,12 @@ stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) {
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) {
|
||||
switch (speed) {
|
||||
case stdAc::fanspeed_t::kMin:
|
||||
case stdAc::fanspeed_t::kMin: return kLgAcFanLowest;
|
||||
case stdAc::fanspeed_t::kLow: return kLgAcFanLow;
|
||||
case stdAc::fanspeed_t::kMedium: return kLgAcFanMedium;
|
||||
case stdAc::fanspeed_t::kHigh:
|
||||
case stdAc::fanspeed_t::kMax: return kHitachiAcFanHigh;
|
||||
default: return kHitachiAcFanAuto;
|
||||
case stdAc::fanspeed_t::kMax: return kLgAcFanHigh;
|
||||
default: return kLgAcFanAuto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,6 +487,7 @@ stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) {
|
||||
case kLgAcFanHigh: return stdAc::fanspeed_t::kMax;
|
||||
case kLgAcFanMedium: return stdAc::fanspeed_t::kMedium;
|
||||
case kLgAcFanLow: return stdAc::fanspeed_t::kLow;
|
||||
case kLgAcFanLowest: return stdAc::fanspeed_t::kMin;
|
||||
default: return stdAc::fanspeed_t::kAuto;
|
||||
}
|
||||
}
|
||||
@ -528,7 +530,7 @@ String IRLgAc::toString(void) {
|
||||
kLgAcHeat, kLgAcDry, kLgAcFan);
|
||||
result += addTempToString(getTemp());
|
||||
result += addFanToString(getFan(), kLgAcFanHigh, kLgAcFanLow,
|
||||
kLgAcFanAuto, kLgAcFanAuto, kLgAcFanMedium);
|
||||
kLgAcFanAuto, kLgAcFanLowest, kLgAcFanMedium);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -32,7 +32,8 @@ const uint8_t kLgAcChecksumOffset = 0; // Nr. of bits
|
||||
const uint8_t kLgAcChecksumSize = kNibbleSize; // Nr. of bits
|
||||
const uint8_t kLgAcFanOffset = 4; // Nr. of bits
|
||||
const uint8_t kLgAcFanSize = 3; // Nr. of bits
|
||||
const uint8_t kLgAcFanLow = 0; // 0b000
|
||||
const uint8_t kLgAcFanLowest = 0; // 0b000
|
||||
const uint8_t kLgAcFanLow = 1; // 0b001
|
||||
const uint8_t kLgAcFanMedium = 2; // 0b010
|
||||
const uint8_t kLgAcFanHigh = 4; // 0b100
|
||||
const uint8_t kLgAcFanAuto = 5; // 0b101
|
||||
|
@ -3,7 +3,9 @@
|
||||
/// @brief Support for Midea protocols.
|
||||
/// Midea added by crankyoldgit & bwze.
|
||||
/// send: bwze/crankyoldgit, decode: crankyoldgit
|
||||
/// @note SwingV has the function of an Ion Filter on Danby A/C units.
|
||||
/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/1213
|
||||
|
||||
#include "ir_Midea.h"
|
||||
#include "ir_NEC.h"
|
||||
@ -99,6 +101,7 @@ void IRMideaAC::stateReset(void) {
|
||||
// Power On, Mode Auto, Fan Auto, Temp = 25C/77F
|
||||
remote_state = 0xA1826FFFFF62;
|
||||
_SwingVToggle = false;
|
||||
_EconoToggle = false;
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
@ -110,11 +113,14 @@ void IRMideaAC::begin(void) { _irsend.begin(); }
|
||||
void IRMideaAC::send(const uint16_t repeat) {
|
||||
this->checksum(); // Ensure correct checksum before sending.
|
||||
_irsend.sendMidea(remote_state, kMideaBits, repeat);
|
||||
// Handle toggling the swing if we need to.
|
||||
if (_SwingVToggle && !isSwingVToggle()) {
|
||||
// Handle toggling the swing & econo mode if we need to.
|
||||
if (_SwingVToggle && !isSwingVToggle())
|
||||
_irsend.sendMidea(kMideaACToggleSwingV, kMideaBits, repeat);
|
||||
}
|
||||
_SwingVToggle = false; // The toggle message has been sent, so reset.
|
||||
if (_EconoToggle && !isEconoToggle())
|
||||
_irsend.sendMidea(kMideaACToggleEcono, kMideaBits, repeat);
|
||||
// The toggle messages has been sent, so reset.
|
||||
_SwingVToggle = false;
|
||||
_EconoToggle = false;
|
||||
}
|
||||
#endif // SEND_MIDEA
|
||||
|
||||
@ -246,22 +252,42 @@ bool IRMideaAC::getSleep(void) {
|
||||
}
|
||||
|
||||
/// Set the A/C to toggle the vertical swing toggle for the next send.
|
||||
/// @note On Danby A/C units, this is associated with the Ion Filter instead.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRMideaAC::setSwingVToggle(const bool on) { _SwingVToggle = on; }
|
||||
|
||||
/// Is the current state a vertical swing toggle message?
|
||||
/// @note On Danby A/C units, this is associated with the Ion Filter instead.
|
||||
/// @return true, it is. false, it isn't.
|
||||
bool IRMideaAC::isSwingVToggle(void) {
|
||||
return remote_state == kMideaACToggleSwingV;
|
||||
}
|
||||
|
||||
// Get the vertical swing toggle state of the A/C.
|
||||
/// @note On Danby A/C units, this is associated with the Ion Filter instead.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRMideaAC::getSwingVToggle(void) {
|
||||
_SwingVToggle |= isSwingVToggle();
|
||||
return _SwingVToggle;
|
||||
}
|
||||
|
||||
/// Set the A/C to toggle the Econo (energy saver) mode for the next send.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRMideaAC::setEconoToggle(const bool on) { _EconoToggle = on; }
|
||||
|
||||
/// Is the current state an Econo (energy saver) toggle message?
|
||||
/// @return true, it is. false, it isn't.
|
||||
bool IRMideaAC::isEconoToggle(void) {
|
||||
return remote_state == kMideaACToggleEcono;
|
||||
}
|
||||
|
||||
// Get the Econo (energy saver) toggle state of the A/C.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRMideaAC::getEconoToggle(void) {
|
||||
_EconoToggle |= isEconoToggle();
|
||||
return _EconoToggle;
|
||||
}
|
||||
|
||||
/// Calculate the checksum for a given state.
|
||||
/// @param[in] state The value to calc the checksum of.
|
||||
/// @return The calculated checksum value.
|
||||
@ -376,6 +402,7 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
|
||||
result.degrees = this->getTemp(result.celsius);
|
||||
result.fanspeed = this->toCommonFanSpeed(this->getFan());
|
||||
result.sleep = this->getSleep() ? 0 : -1;
|
||||
result.econo = this->getEconoToggle();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -384,7 +411,8 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
|
||||
String IRMideaAC::toString(void) {
|
||||
String result = "";
|
||||
result.reserve(100); // Reserve some heap for the string to reduce fragging.
|
||||
if (!isSwingVToggle()) {
|
||||
bool needComma = false;
|
||||
if (!isSwingVToggle() && !isEconoToggle()) {
|
||||
result += addBoolToString(getPower(), kPowerStr, false);
|
||||
result += addModeToString(getMode(), kMideaACAuto, kMideaACCool,
|
||||
kMideaACHeat, kMideaACDry, kMideaACFan);
|
||||
@ -396,9 +424,10 @@ String IRMideaAC::toString(void) {
|
||||
result += addFanToString(getFan(), kMideaACFanHigh, kMideaACFanLow,
|
||||
kMideaACFanAuto, kMideaACFanAuto, kMideaACFanMed);
|
||||
result += addBoolToString(getSleep(), kSleepStr);
|
||||
needComma = true;
|
||||
}
|
||||
result += addBoolToString(getSwingVToggle(), kSwingVToggleStr,
|
||||
!isSwingVToggle());
|
||||
result += addBoolToString(getSwingVToggle(), kSwingVToggleStr, needComma);
|
||||
result += addBoolToString(getEconoToggle(), kEconoToggleStr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,10 @@
|
||||
// Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA)
|
||||
// Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA)
|
||||
// Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24)
|
||||
// Brand: Danby, Model: DAC080BGUWDB (MIDEA)
|
||||
// Brand: Danby, Model: DAC100BGUWDB (MIDEA)
|
||||
// Brand: Danby, Model: DAC120BGUWDB (MIDEA)
|
||||
// Brand: Danby, Model: R09C/BCGE remote (MIDEA)
|
||||
|
||||
#ifndef IR_MIDEA_H_
|
||||
#define IR_MIDEA_H_
|
||||
@ -26,6 +30,10 @@
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
|
||||
#if DANBY_DAC
|
||||
kSwingVToggleStr = kIonStr;
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
const uint8_t kMideaACTempOffset = 24;
|
||||
const uint8_t kMideaACTempSize = 5; // Bits
|
||||
@ -49,6 +57,9 @@ const uint8_t kMideaACFanHigh = 3; // 0b11
|
||||
const uint8_t kMideaACSleepOffset = 38;
|
||||
const uint8_t kMideaACPowerOffset = 39;
|
||||
const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C;
|
||||
// For Danby DAC unit, the Ionizer toggle is the same as ToggleSwingV
|
||||
// const uint64_t kMideaACToggleIonizer = 0x0000A201FFFFFF7C;
|
||||
const uint64_t kMideaACToggleEcono = 0x0000A202FFFFFF7E;
|
||||
|
||||
// Legacy defines. (Deprecated)
|
||||
#define MIDEA_AC_COOL kMideaACCool
|
||||
@ -104,6 +115,9 @@ class IRMideaAC {
|
||||
bool isSwingVToggle(void);
|
||||
void setSwingVToggle(const bool on);
|
||||
bool getSwingVToggle(void);
|
||||
bool isEconoToggle(void);
|
||||
void setEconoToggle(const bool on);
|
||||
bool getEconoToggle(void);
|
||||
uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
@ -121,6 +135,7 @@ class IRMideaAC {
|
||||
#endif // UNIT_TEST
|
||||
uint64_t remote_state; ///< The state of the IR remote in IR code form.
|
||||
bool _SwingVToggle;
|
||||
bool _EconoToggle;
|
||||
void checksum(void);
|
||||
static uint8_t calcChecksum(const uint64_t state);
|
||||
};
|
||||
|
@ -163,7 +163,7 @@ const uint8_t kMitsubishi112SwingHAuto = 0b1100;
|
||||
|
||||
|
||||
/// Class for handling detailed Mitsubishi 144-bit A/C messages.
|
||||
/// Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
|
||||
/// @note Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
|
||||
/// @warning Consider this very alpha code. Seems to work, but not validated.
|
||||
class IRMitsubishiAC {
|
||||
public:
|
||||
@ -282,7 +282,7 @@ class IRMitsubishi136 {
|
||||
void checksum(void);
|
||||
};
|
||||
|
||||
|
||||
/// Class for handling detailed Mitsubishi 122-bit A/C messages.
|
||||
class IRMitsubishi112 {
|
||||
public:
|
||||
explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false,
|
||||
|
@ -33,6 +33,8 @@ using irutils::addIntToString;
|
||||
using irutils::addLabeledString;
|
||||
using irutils::addModeToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::checkInvertedBytePairs;
|
||||
using irutils::invertBytePairs;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
|
||||
@ -321,32 +323,24 @@ bool IRMitsubishiHeavy152Ac::checkZmsSig(const uint8_t *state) {
|
||||
}
|
||||
|
||||
/// Calculate the checksum for the current internal state of the remote.
|
||||
/// Note: Technically it has no checksum, but does has inverted byte pairs.
|
||||
/// Note: Technically it has no checksum, but does have inverted byte pairs.
|
||||
void IRMitsubishiHeavy152Ac::checksum(void) {
|
||||
for (uint8_t i = kMitsubishiHeavySigLength - 2;
|
||||
i < kMitsubishiHeavy152StateLength;
|
||||
i += 2) {
|
||||
remote_state[i + 1] = ~remote_state[i];
|
||||
}
|
||||
const uint8_t kOffset = kMitsubishiHeavySigLength - 2;
|
||||
invertBytePairs(remote_state + kOffset,
|
||||
kMitsubishiHeavy152StateLength - kOffset);
|
||||
}
|
||||
|
||||
/// Verify the checksum is valid for a given state.
|
||||
/// @param[in] state The array to verify the checksum of.
|
||||
/// @param[in] length The length/size of the state array.
|
||||
/// @return true, if the state has a valid checksum. Otherwise, false.
|
||||
/// Note: Technically it has no checksum, but does has inverted byte pairs.
|
||||
/// Note: Technically it has no checksum, but does have inverted byte pairs.
|
||||
bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state,
|
||||
const uint16_t length) {
|
||||
// Assume anything too short is fine.
|
||||
if (length < kMitsubishiHeavySigLength) return true;
|
||||
// Check all the byte pairs.
|
||||
for (uint16_t i = kMitsubishiHeavySigLength - 2;
|
||||
i < length;
|
||||
i += 2) {
|
||||
// XOR of a byte and it's self inverted should be 0xFF;
|
||||
if ((state[i] ^ state[i + 1]) != 0xFF) return false;
|
||||
}
|
||||
return true;
|
||||
const uint8_t kOffset = kMitsubishiHeavySigLength - 2;
|
||||
return checkInvertedBytePairs(state + kOffset, length - kOffset);
|
||||
}
|
||||
|
||||
/// Convert a stdAc::opmode_t enum into its native mode.
|
||||
@ -856,20 +850,18 @@ bool IRMitsubishiHeavy88Ac::checkZjsSig(const uint8_t *state) {
|
||||
}
|
||||
|
||||
/// Calculate the checksum for the current internal state of the remote.
|
||||
/// Note: Technically it has no checksum, but does has inverted byte pairs.
|
||||
/// Note: Technically it has no checksum, but does have inverted byte pairs.
|
||||
void IRMitsubishiHeavy88Ac::checksum(void) {
|
||||
for (uint8_t i = kMitsubishiHeavySigLength - 2;
|
||||
i < kMitsubishiHeavy88StateLength;
|
||||
i += 2) {
|
||||
remote_state[i + 1] = ~remote_state[i];
|
||||
}
|
||||
const uint8_t kOffset = kMitsubishiHeavySigLength - 2;
|
||||
invertBytePairs(remote_state + kOffset,
|
||||
kMitsubishiHeavy88StateLength - kOffset);
|
||||
}
|
||||
|
||||
/// Verify the checksum is valid for a given state.
|
||||
/// @param[in] state The array to verify the checksum of.
|
||||
/// @param[in] length The length/size of the state array.
|
||||
/// @return true, if the state has a valid checksum. Otherwise, false.
|
||||
/// Note: Technically it has no checksum, but does has inverted byte pairs.
|
||||
/// Note: Technically it has no checksum, but does have inverted byte pairs.
|
||||
bool IRMitsubishiHeavy88Ac::validChecksum(const uint8_t *state,
|
||||
const uint16_t length) {
|
||||
return IRMitsubishiHeavy152Ac::validChecksum(state, length);
|
||||
|
@ -8,9 +8,12 @@
|
||||
/// @see http://www.adrian-kingston.com/IRFormatPioneer.htm
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547
|
||||
/// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1220
|
||||
|
||||
// Supports:
|
||||
// Brand: Pioneer, Model: AV Receivers
|
||||
// Brand: Pioneer, Model: VSX-324 AV Receiver
|
||||
// Brand: Pioneer, Model: AXD7690 Remote
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
@ -20,22 +23,15 @@
|
||||
#include "IRutils.h"
|
||||
|
||||
// Constants
|
||||
const uint16_t kPioneerTick = 534;
|
||||
const uint16_t kPioneerHdrMarkTicks = 16;
|
||||
const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick;
|
||||
const uint16_t kPioneerHdrSpaceTicks = 8;
|
||||
const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick;
|
||||
const uint16_t kPioneerBitMarkTicks = 1;
|
||||
const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick;
|
||||
const uint16_t kPioneerOneSpaceTicks = 3;
|
||||
const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick;
|
||||
const uint16_t kPioneerZeroSpaceTicks = 1;
|
||||
const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick;
|
||||
const uint16_t kPioneerMinCommandLengthTicks = 159;
|
||||
const uint32_t kPioneerMinCommandLength = kPioneerMinCommandLengthTicks *
|
||||
kPioneerTick;
|
||||
const uint16_t kPioneerMinGapTicks = 47;
|
||||
const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick;
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1220
|
||||
const uint16_t kPioneerTick = 534; ///< uSeconds.
|
||||
const uint16_t kPioneerHdrMark = 8506; ///< uSeconds.
|
||||
const uint16_t kPioneerHdrSpace = 4191; ///< uSeconds.
|
||||
const uint16_t kPioneerBitMark = 568; ///< uSeconds.
|
||||
const uint16_t kPioneerOneSpace = 1542; ///< uSeconds.
|
||||
const uint16_t kPioneerZeroSpace = 487; ///< uSeconds.
|
||||
const uint32_t kPioneerMinCommandLength = 84906; ///< uSeconds.
|
||||
const uint32_t kPioneerMinGap = 25181; ///< uSeconds.
|
||||
|
||||
#if SEND_PIONEER
|
||||
/// Send a raw Pioneer formatted message.
|
||||
|
@ -53,6 +53,14 @@ const uint16_t kSamsungAcBitMark = 586;
|
||||
const uint16_t kSamsungAcOneSpace = 1432;
|
||||
const uint16_t kSamsungAcZeroSpace = 436;
|
||||
|
||||
// Data from https://github.com/crankyoldgit/IRremoteESP8266/issues/1220
|
||||
// Values calculated based on the average of ten messages.
|
||||
const uint16_t kSamsung36HdrMark = 4515; /// < uSeconds
|
||||
const uint16_t kSamsung36HdrSpace = 4438; /// < uSeconds
|
||||
const uint16_t kSamsung36BitMark = 512; /// < uSeconds
|
||||
const uint16_t kSamsung36OneSpace = 1468; /// < uSeconds
|
||||
const uint16_t kSamsung36ZeroSpace = 490; /// < uSeconds
|
||||
|
||||
using irutils::addBoolToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::addIntToString;
|
||||
@ -146,7 +154,7 @@ bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset,
|
||||
|
||||
#if SEND_SAMSUNG36
|
||||
/// Send a Samsung 36-bit formatted message.
|
||||
/// Status: Alpha / Experimental.
|
||||
/// Status: STABLE / Works on real devices.
|
||||
/// @param[in] data The message to be sent.
|
||||
/// @param[in] nbits The number of bits of message to be sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
@ -156,16 +164,16 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits,
|
||||
if (nbits < 16) return; // To small to send.
|
||||
for (uint16_t r = 0; r <= repeat; r++) {
|
||||
// Block #1 (16 bits)
|
||||
sendGeneric(kSamsungHdrMark, kSamsungHdrSpace,
|
||||
kSamsungBitMark, kSamsungOneSpace,
|
||||
kSamsungBitMark, kSamsungZeroSpace,
|
||||
kSamsungBitMark, kSamsungHdrSpace,
|
||||
sendGeneric(kSamsung36HdrMark, kSamsung36HdrSpace,
|
||||
kSamsung36BitMark, kSamsung36OneSpace,
|
||||
kSamsung36BitMark, kSamsung36ZeroSpace,
|
||||
kSamsung36BitMark, kSamsung36HdrSpace,
|
||||
data >> (nbits - 16), 16, 38, true, 0, kDutyDefault);
|
||||
// Block #2 (The rest, typically 20 bits)
|
||||
sendGeneric(0, 0, // No header
|
||||
kSamsungBitMark, kSamsungOneSpace,
|
||||
kSamsungBitMark, kSamsungZeroSpace,
|
||||
kSamsungBitMark, kSamsungMinGap, // Gap is just a guess.
|
||||
kSamsung36BitMark, kSamsung36OneSpace,
|
||||
kSamsung36BitMark, kSamsung36ZeroSpace,
|
||||
kSamsung36BitMark, kSamsungMinGap, // Gap is just a guess.
|
||||
// Mask off the rest of the bits.
|
||||
data & ((1ULL << (nbits - 16)) - 1),
|
||||
nbits - 16, 38, true, 0, kDutyDefault);
|
||||
@ -175,7 +183,7 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits,
|
||||
|
||||
#if DECODE_SAMSUNG36
|
||||
/// Decode the supplied Samsung36 message.
|
||||
/// Status: Alpha / Experimental
|
||||
/// Status: STABLE / Expected to work.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the result
|
||||
/// @param[in] offset The starting index to use when attempting to decode the
|
||||
/// raw data. Typically/Defaults to kStartOffset.
|
||||
@ -198,10 +206,10 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset,
|
||||
uint16_t used;
|
||||
used = matchGeneric(results->rawbuf + offset, &data,
|
||||
results->rawlen - offset, 16,
|
||||
kSamsungHdrMark, kSamsungHdrSpace,
|
||||
kSamsungBitMark, kSamsungOneSpace,
|
||||
kSamsungBitMark, kSamsungZeroSpace,
|
||||
kSamsungBitMark, kSamsungHdrSpace, false);
|
||||
kSamsung36HdrMark, kSamsung36HdrSpace,
|
||||
kSamsung36BitMark, kSamsung36OneSpace,
|
||||
kSamsung36BitMark, kSamsung36ZeroSpace,
|
||||
kSamsung36BitMark, kSamsung36HdrSpace, false);
|
||||
if (!used) return false;
|
||||
offset += used;
|
||||
// Data (Block #2)
|
||||
@ -209,9 +217,9 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset,
|
||||
if (!matchGeneric(results->rawbuf + offset, &data2,
|
||||
results->rawlen - offset, nbits - 16,
|
||||
0, 0,
|
||||
kSamsungBitMark, kSamsungOneSpace,
|
||||
kSamsungBitMark, kSamsungZeroSpace,
|
||||
kSamsungBitMark, kSamsungMinGap, true)) return false;
|
||||
kSamsung36BitMark, kSamsung36OneSpace,
|
||||
kSamsung36BitMark, kSamsung36ZeroSpace,
|
||||
kSamsung36BitMark, kSamsungMinGap, true)) return false;
|
||||
data <<= (nbits - 16);
|
||||
data += data2;
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
// Brand: Samsung, Model: DB93-16761C remote
|
||||
// Brand: Samsung, Model: IEC-R03 remote
|
||||
// Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36)
|
||||
// Brand: Samsung, Model: AH59-02692E Soundbar remote (SAMSUNG36)
|
||||
// Brand: Samsung, Model: HW-J551 Soundbar (SAMSUNG36)
|
||||
// Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC)
|
||||
// Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC)
|
||||
// Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Copyright 2009 Ken Shirriff
|
||||
// Copyright 2016 marcosamarinho
|
||||
// Copyright 2017 David Conran
|
||||
// Copyright 2017-2020 David Conran
|
||||
|
||||
/// @file
|
||||
/// @brief Support for Sanyo protocols.
|
||||
@ -11,15 +11,27 @@
|
||||
/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
|
||||
/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
|
||||
/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
|
||||
/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing
|
||||
|
||||
// Supports:
|
||||
// Brand: Sanyo, Model: SA 8650B - disabled
|
||||
// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461)
|
||||
|
||||
#include "ir_Sanyo.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "IRrecv.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRtext.h"
|
||||
#include "IRutils.h"
|
||||
|
||||
using irutils::addBoolToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::addIntToString;
|
||||
using irutils::addLabeledString;
|
||||
using irutils::addModeToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::minsToString;
|
||||
using irutils::sumNibbles;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
|
||||
// Constants
|
||||
// Sanyo SA 8650B
|
||||
@ -48,6 +60,14 @@ const uint16_t kSanyoLc7461MinGap =
|
||||
(kSanyoLc7461OneSpace + kSanyoLc7461ZeroSpace) / 2) +
|
||||
kSanyoLc7461BitMark);
|
||||
|
||||
const uint16_t kSanyoAcHdrMark = 8500; ///< uSeconds
|
||||
const uint16_t kSanyoAcHdrSpace = 4200; ///< uSeconds
|
||||
const uint16_t kSanyoAcBitMark = 500; ///< uSeconds
|
||||
const uint16_t kSanyoAcOneSpace = 1600; ///< uSeconds
|
||||
const uint16_t kSanyoAcZeroSpace = 550; ///< uSeconds
|
||||
const uint32_t kSanyoAcGap = kDefaultMessageGap; ///< uSeconds (Guess only)
|
||||
const uint16_t kSanyoAcFreq = 38000; ///< Hz. (Guess only)
|
||||
|
||||
#if SEND_SANYO
|
||||
/// Construct a Sanyo LC7461 message.
|
||||
/// @param[in] address The 13 bit value of the address(Custom) portion of the
|
||||
@ -221,3 +241,453 @@ bool IRrecv::decodeSanyo(decode_results *results, uint16_t nbits, bool strict) {
|
||||
}
|
||||
*/
|
||||
#endif // DECODE_SANYO
|
||||
|
||||
|
||||
#if SEND_SANYO_AC
|
||||
/// Send a SanyoAc formatted message.
|
||||
/// Status: STABLE / Reported as working.
|
||||
/// @param[in] data An array of bytes containing the IR command.
|
||||
/// @param[in] nbytes Nr. of bytes of data in the array.
|
||||
/// @param[in] repeat Nr. of times the message is to be repeated.
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
|
||||
void IRsend::sendSanyoAc(const uint8_t data[], const uint16_t nbytes,
|
||||
const uint16_t repeat) {
|
||||
// Header + Data + Footer
|
||||
sendGeneric(kSanyoAcHdrMark, kSanyoAcHdrSpace,
|
||||
kSanyoAcBitMark, kSanyoAcOneSpace,
|
||||
kSanyoAcBitMark, kSanyoAcZeroSpace,
|
||||
kSanyoAcBitMark, kSanyoAcGap,
|
||||
data, nbytes, kSanyoAcFreq, false, repeat, kDutyDefault);
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
|
||||
#if DECODE_SANYO_AC
|
||||
/// Decode the supplied SanyoAc message.
|
||||
/// Status: STABLE / Reported as working.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the decode
|
||||
/// @param[in] offset The starting index to use when attempting to decode the
|
||||
/// raw data. Typically/Defaults to kStartOffset.
|
||||
/// @param[in] nbits The number of data bits to expect.
|
||||
/// @param[in] strict Flag indicating if we should perform strict matching.
|
||||
/// @return A boolean. True if it can decode it, false if it can't.
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
|
||||
bool IRrecv::decodeSanyoAc(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
if (strict && nbits != kSanyoAcBits)
|
||||
return false;
|
||||
|
||||
// Header + Data + Footer
|
||||
if (!matchGeneric(results->rawbuf + offset, results->state,
|
||||
results->rawlen - offset, nbits,
|
||||
kSanyoAcHdrMark, kSanyoAcHdrSpace,
|
||||
kSanyoAcBitMark, kSanyoAcOneSpace,
|
||||
kSanyoAcBitMark, kSanyoAcZeroSpace,
|
||||
kSanyoAcBitMark, kSanyoAcGap,
|
||||
true, kUseDefTol, kMarkExcess, false)) return false;
|
||||
// Compliance
|
||||
if (strict)
|
||||
if (!IRSanyoAc::validChecksum(results->state, nbits / 8)) return false;
|
||||
|
||||
// Success
|
||||
results->decode_type = decode_type_t::SANYO_AC;
|
||||
results->bits = nbits;
|
||||
// No need to record the state as we stored it as we decoded it.
|
||||
// As we use result->state, we don't record value, address, or command as it
|
||||
// is a union data type.
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_SANYO_AC
|
||||
|
||||
/// Class constructor
|
||||
/// @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?
|
||||
IRSanyoAc::IRSanyoAc(const uint16_t pin, const bool inverted,
|
||||
const bool use_modulation)
|
||||
: _irsend(pin, inverted, use_modulation) { stateReset(); }
|
||||
|
||||
/// Reset the state of the remote to a known good state/sequence.
|
||||
/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?ts=5f0190a5#gid=1050142776&range=A2:B2
|
||||
void IRSanyoAc::stateReset(void) {
|
||||
static const uint8_t kReset[kSanyoAcStateLength] = {
|
||||
0x6A, 0x6D, 0x51, 0x00, 0x10, 0x45, 0x00, 0x00, 0x33};
|
||||
memcpy(remote_state, kReset, kSanyoAcStateLength);
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
void IRSanyoAc::begin(void) { _irsend.begin(); }
|
||||
|
||||
#if SEND_SANYO_AC
|
||||
/// Send the current internal state as IR messages.
|
||||
/// @param[in] repeat Nr. of times the message will be repeated.
|
||||
void IRSanyoAc::send(const uint16_t repeat) {
|
||||
_irsend.sendSanyoAc(getRaw(), kSanyoAcStateLength, repeat);
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
|
||||
/// Get a PTR to the internal state/code for this protocol with all integrity
|
||||
/// checks passing.
|
||||
/// @return PTR to a code for this protocol based on the current internal state.
|
||||
uint8_t* IRSanyoAc::getRaw(void) {
|
||||
checksum();
|
||||
return remote_state;
|
||||
}
|
||||
|
||||
/// Set the internal state from a valid code for this protocol.
|
||||
/// @param[in] newState A valid code for this protocol.
|
||||
void IRSanyoAc::setRaw(const uint8_t newState[]) {
|
||||
memcpy(remote_state, newState, kSanyoAcStateLength);
|
||||
}
|
||||
|
||||
/// Calculate the checksum for a given state.
|
||||
/// @param[in] state The array to calc the checksum of.
|
||||
/// @param[in] length The length/size of the array.
|
||||
/// @return The calculated checksum value.
|
||||
uint8_t IRSanyoAc::calcChecksum(const uint8_t state[],
|
||||
const uint16_t length) {
|
||||
return length ? sumNibbles(state, length - 1) : 0;
|
||||
}
|
||||
|
||||
/// Verify the checksum is valid for a given state.
|
||||
/// @param[in] state The array to verify the checksum of.
|
||||
/// @param[in] length The length/size of the array.
|
||||
/// @return true, if the state has a valid checksum. Otherwise, false.
|
||||
bool IRSanyoAc::validChecksum(const uint8_t state[], const uint16_t length) {
|
||||
return length && state[length - 1] == IRSanyoAc::calcChecksum(state, length);
|
||||
}
|
||||
|
||||
/// Calculate & set the checksum for the current internal state of the remote.
|
||||
void IRSanyoAc::checksum(void) {
|
||||
// Stored the checksum value in the last byte.
|
||||
remote_state[kSanyoAcStateLength - 1] = calcChecksum(remote_state);
|
||||
}
|
||||
|
||||
|
||||
/// Set the requested power state of the A/C to on.
|
||||
void IRSanyoAc::on(void) { setPower(true); }
|
||||
|
||||
/// Set the requested power state of the A/C to off.
|
||||
void IRSanyoAc::off(void) { setPower(false); }
|
||||
|
||||
/// Change the power setting.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRSanyoAc::setPower(const bool on) {
|
||||
setBits(&remote_state[kSanyoAcPowerByte], kSanyoAcPowerOffset,
|
||||
kSanyoAcPowerSize, on ? kSanyoAcPowerOn : kSanyoAcPowerOff);
|
||||
}
|
||||
|
||||
/// Get the value of the current power setting.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRSanyoAc::getPower(void) {
|
||||
return GETBITS8(remote_state[kSanyoAcPowerByte], kSanyoAcPowerOffset,
|
||||
kSanyoAcPowerSize) == kSanyoAcPowerOn;
|
||||
}
|
||||
|
||||
/// Get the operating mode setting of the A/C.
|
||||
/// @return The current operating mode setting.
|
||||
uint8_t IRSanyoAc::getMode(void) {
|
||||
return GETBITS8(remote_state[kSanyoAcModeByte], kSanyoAcModeOffset,
|
||||
kSanyoAcModeSize);
|
||||
}
|
||||
|
||||
/// Set the operating mode of the A/C.
|
||||
/// @param[in] mode The desired operating mode.
|
||||
/// @note If we get an unexpected mode, default to AUTO.
|
||||
void IRSanyoAc::setMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kSanyoAcAuto:
|
||||
case kSanyoAcCool:
|
||||
case kSanyoAcDry:
|
||||
case kSanyoAcHeat:
|
||||
setBits(&remote_state[kSanyoAcModeByte], kSanyoAcModeOffset,
|
||||
kSanyoAcModeSize, mode);
|
||||
break;
|
||||
default: setMode(kSanyoAcAuto);
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a stdAc::opmode_t enum into its native mode.
|
||||
/// @param[in] mode The enum to be converted.
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRSanyoAc::convertMode(const stdAc::opmode_t mode) {
|
||||
switch (mode) {
|
||||
case stdAc::opmode_t::kCool: return kSanyoAcCool;
|
||||
case stdAc::opmode_t::kHeat: return kSanyoAcHeat;
|
||||
case stdAc::opmode_t::kDry: return kSanyoAcDry;
|
||||
default: return kSanyoAcAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a native mode into its stdAc equivilant.
|
||||
/// @param[in] mode The native setting to be converted.
|
||||
/// @return The stdAc equivilant of the native setting.
|
||||
stdAc::opmode_t IRSanyoAc::toCommonMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kSanyoAcCool: return stdAc::opmode_t::kCool;
|
||||
case kSanyoAcHeat: return stdAc::opmode_t::kHeat;
|
||||
case kSanyoAcDry: return stdAc::opmode_t::kDry;
|
||||
default: return stdAc::opmode_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the temperature at a given location.
|
||||
/// @param[out] ptr A pointer to a temperature byte.
|
||||
/// @param[in] degrees The temperature in degrees celsius.
|
||||
void IRSanyoAc::_setTemp(uint8_t *ptr, const uint8_t degrees) {
|
||||
uint8_t temp = std::max((uint8_t)kSanyoAcTempMin, degrees);
|
||||
temp = std::min((uint8_t)kSanyoAcTempMax, temp);
|
||||
setBits(ptr, kSanyoAcTempOffset, kSanyoAcTempSize, temp - kSanyoAcTempDelta);
|
||||
}
|
||||
|
||||
/// Get the temperature from a given location.
|
||||
/// @param[in] ptr A pointer to a temperature byte.
|
||||
/// @return The current setting for temp. in degrees celsius.
|
||||
uint8_t IRSanyoAc::_getTemp(uint8_t *ptr) {
|
||||
return GETBITS8(*ptr, kSanyoAcTempOffset, kSanyoAcTempSize) +
|
||||
kSanyoAcTempDelta;
|
||||
}
|
||||
|
||||
/// Set the desired temperature.
|
||||
/// @param[in] degrees The temperature in degrees celsius.
|
||||
void IRSanyoAc::setTemp(const uint8_t degrees) {
|
||||
_setTemp(&remote_state[kSanyoAcTempByte], degrees);
|
||||
}
|
||||
|
||||
/// Get the current desired temperature setting.
|
||||
/// @return The current setting for temp. in degrees celsius.
|
||||
uint8_t IRSanyoAc::getTemp(void) {
|
||||
return _getTemp(&remote_state[kSanyoAcTempByte]);
|
||||
}
|
||||
|
||||
/// Set the sensor temperature.
|
||||
/// @param[in] degrees The temperature in degrees celsius.
|
||||
void IRSanyoAc::setSensorTemp(const uint8_t degrees) {
|
||||
_setTemp(&remote_state[kSanyoAcSensorByte], degrees);
|
||||
}
|
||||
|
||||
/// Get the current sensor temperature setting.
|
||||
/// @return The current setting for temp. in degrees celsius.
|
||||
uint8_t IRSanyoAc::getSensorTemp(void) {
|
||||
return _getTemp(&remote_state[kSanyoAcSensorByte]);
|
||||
}
|
||||
|
||||
/// Set the speed of the fan.
|
||||
/// @param[in] speed The desired setting.
|
||||
void IRSanyoAc::setFan(const uint8_t speed) {
|
||||
setBits(&remote_state[kSanyoAcModeByte], kSanyoAcFanOffset, kSanyoAcFanSize,
|
||||
speed);
|
||||
}
|
||||
|
||||
/// Get the current fan speed setting.
|
||||
/// @return The current fan speed/mode.
|
||||
uint8_t IRSanyoAc::getFan(void) {
|
||||
return GETBITS8(remote_state[kSanyoAcModeByte], kSanyoAcFanOffset,
|
||||
kSanyoAcFanSize);
|
||||
}
|
||||
|
||||
/// Convert a stdAc::fanspeed_t enum into it's native speed.
|
||||
/// @param[in] speed The enum to be converted.
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRSanyoAc::convertFan(const stdAc::fanspeed_t speed) {
|
||||
switch (speed) {
|
||||
case stdAc::fanspeed_t::kMin:
|
||||
case stdAc::fanspeed_t::kLow: return kSanyoAcFanLow;
|
||||
case stdAc::fanspeed_t::kMedium: return kSanyoAcFanMedium;
|
||||
case stdAc::fanspeed_t::kHigh:
|
||||
case stdAc::fanspeed_t::kMax: return kSanyoAcFanHigh;
|
||||
default: return kSanyoAcFanAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a native fan speed into its stdAc equivilant.
|
||||
/// @param[in] spd The native setting to be converted.
|
||||
/// @return The stdAc equivilant of the native setting.
|
||||
stdAc::fanspeed_t IRSanyoAc::toCommonFanSpeed(const uint8_t spd) {
|
||||
switch (spd) {
|
||||
case kSanyoAcFanHigh: return stdAc::fanspeed_t::kHigh;
|
||||
case kSanyoAcFanMedium: return stdAc::fanspeed_t::kMedium;
|
||||
case kSanyoAcFanLow: return stdAc::fanspeed_t::kLow;
|
||||
default: return stdAc::fanspeed_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the vertical swing setting of the A/C.
|
||||
/// @return The current swing mode setting.
|
||||
uint8_t IRSanyoAc::getSwingV(void) {
|
||||
return GETBITS8(remote_state[kSanyoAcPowerByte], kSanyoAcSwingVOffset,
|
||||
kSanyoAcSwingVSize);
|
||||
}
|
||||
|
||||
/// Set the vertical swing setting of the A/C.
|
||||
/// @param[in] setting The value of the desired setting.
|
||||
void IRSanyoAc::setSwingV(const uint8_t setting) {
|
||||
if (setting == kSanyoAcSwingVAuto ||
|
||||
(setting >= kSanyoAcSwingVLowest && setting <= kSanyoAcSwingVHighest))
|
||||
setBits(&remote_state[kSanyoAcPowerByte], kSanyoAcSwingVOffset,
|
||||
kSanyoAcSwingVSize, setting);
|
||||
|
||||
else
|
||||
setSwingV(kSanyoAcSwingVAuto);
|
||||
}
|
||||
|
||||
/// Convert a stdAc::swingv_t enum into it's native setting.
|
||||
/// @param[in] position The enum to be converted.
|
||||
/// @return The native equivilant of the enum.
|
||||
uint8_t IRSanyoAc::convertSwingV(const stdAc::swingv_t position) {
|
||||
switch (position) {
|
||||
case stdAc::swingv_t::kHighest: return kSanyoAcSwingVHighest;
|
||||
case stdAc::swingv_t::kHigh: return kSanyoAcSwingVHigh;
|
||||
case stdAc::swingv_t::kMiddle: return kSanyoAcSwingVUpperMiddle;
|
||||
case stdAc::swingv_t::kLow: return kSanyoAcSwingVLow;
|
||||
case stdAc::swingv_t::kLowest: return kSanyoAcSwingVLowest;
|
||||
default: return kSanyoAcSwingVAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a native vertical swing postion to it's common equivalent.
|
||||
/// @param[in] setting A native position to convert.
|
||||
/// @return The common vertical swing position.
|
||||
stdAc::swingv_t IRSanyoAc::toCommonSwingV(const uint8_t setting) {
|
||||
switch (setting) {
|
||||
case kSanyoAcSwingVHighest: return stdAc::swingv_t::kHighest;
|
||||
case kSanyoAcSwingVHigh: return stdAc::swingv_t::kHigh;
|
||||
case kSanyoAcSwingVUpperMiddle:
|
||||
case kSanyoAcSwingVLowerMiddle: return stdAc::swingv_t::kMiddle;
|
||||
case kSanyoAcSwingVLow: return stdAc::swingv_t::kLow;
|
||||
case kSanyoAcSwingVLowest: return stdAc::swingv_t::kLowest;
|
||||
default: return stdAc::swingv_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the Sleep (Night Setback) setting of the A/C.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRSanyoAc::setSleep(const bool on) {
|
||||
setBit(&remote_state[kSanyoAcSleepByte], kSanyoAcSleepBit, on);
|
||||
}
|
||||
|
||||
/// Get the Sleep (Night Setback) setting of the A/C.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRSanyoAc::getSleep(void) {
|
||||
return GETBIT8(remote_state[kSanyoAcSleepByte], kSanyoAcSleepBit);
|
||||
}
|
||||
|
||||
/// Set the Sensor Location setting of the A/C.
|
||||
/// i.e. Where the ambient temperature is measured.
|
||||
/// @param[in] location true is Unit/Wall, false is Remote/Room.
|
||||
void IRSanyoAc::setSensor(const bool location) {
|
||||
setBit(&remote_state[kSanyoAcSensorByte], kSanyoAcSensorBit, location);
|
||||
}
|
||||
|
||||
/// Get the Sensor Location setting of the A/C.
|
||||
/// i.e. Where the ambient temperature is measured.
|
||||
/// @return true is Unit/Wall, false is Remote/Room.
|
||||
bool IRSanyoAc::getSensor(void) {
|
||||
return GETBIT8(remote_state[kSanyoAcSensorByte], kSanyoAcSensorBit);
|
||||
}
|
||||
|
||||
/// Set the Beep setting of the A/C.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRSanyoAc::setBeep(const bool on) {
|
||||
setBit(&remote_state[kSanyoAcSensorByte], kSanyoAcBeepBit, on);
|
||||
}
|
||||
|
||||
/// Get the Beep setting of the A/C.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRSanyoAc::getBeep(void) {
|
||||
return GETBIT8(remote_state[kSanyoAcSensorByte], kSanyoAcBeepBit);
|
||||
}
|
||||
|
||||
/// Get the nr of minutes the Off Timer is set to.
|
||||
/// @return The timer time expressed as the number of minutes.
|
||||
/// A value of 0 means the Off Timer is off/disabled.
|
||||
/// @note The internal precission has a resolution of 1 hour.
|
||||
uint16_t IRSanyoAc::getOffTimer(void) {
|
||||
if (GETBIT8(remote_state[kSanyoAcModeByte], kSanyoAcOffTimerEnableBit))
|
||||
return GETBITS8(remote_state[kSanyoAcOffHourByte], kSanyoAcOffHourOffset,
|
||||
kSanyoAcOffHourSize) * 60;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Set the nr of minutes for the Off Timer.
|
||||
/// @param[in] mins The timer time expressed as nr. of minutes.
|
||||
/// A value of 0 means the Off Timer is off/disabled.
|
||||
/// @note The internal precission has a resolution of 1 hour.
|
||||
void IRSanyoAc::setOffTimer(const uint16_t mins) {
|
||||
const uint8_t hours = std::min((uint8_t)(mins / 60), kSanyoAcHourMax);
|
||||
setBit(&remote_state[kSanyoAcModeByte], kSanyoAcOffTimerEnableBit, hours > 0);
|
||||
setBits(&remote_state[kSanyoAcOffHourByte], kSanyoAcOffHourOffset,
|
||||
kSanyoAcOffHourSize, hours);
|
||||
}
|
||||
|
||||
/// Convert the current internal state into its stdAc::state_t equivilant.
|
||||
/// @return The stdAc equivilant of the native settings.
|
||||
stdAc::state_t IRSanyoAc::toCommon(void) {
|
||||
stdAc::state_t result;
|
||||
result.protocol = decode_type_t::SANYO_AC;
|
||||
result.model = -1; // Not supported.
|
||||
result.power = getPower();
|
||||
result.mode = toCommonMode(getMode());
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.fanspeed = toCommonFanSpeed(getFan());
|
||||
result.sleep = getSleep() ? 0 : -1;
|
||||
result.swingv = toCommonSwingV(getSwingV());
|
||||
result.beep = getBeep();
|
||||
// Not supported.
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
result.turbo = false;
|
||||
result.econo = false;
|
||||
result.light = false;
|
||||
result.filter = false;
|
||||
result.quiet = false;
|
||||
result.clean = false;
|
||||
result.clock = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Convert the current internal state into a human readable string.
|
||||
/// @return A human readable string.
|
||||
String IRSanyoAc::toString(void) {
|
||||
String result = "";
|
||||
result.reserve(140);
|
||||
result += addBoolToString(getPower(), kPowerStr, false);
|
||||
result += addModeToString(getMode(), kSanyoAcAuto, kSanyoAcCool,
|
||||
kSanyoAcHeat, kSanyoAcDry, kSanyoAcAuto);
|
||||
result += addTempToString(getTemp());
|
||||
result += addFanToString(getFan(), kSanyoAcFanHigh, kSanyoAcFanLow,
|
||||
kSanyoAcFanAuto, kSanyoAcFanAuto,
|
||||
kSanyoAcFanMedium);
|
||||
result += addIntToString(getSwingV(), kSwingVStr);
|
||||
result += kSpaceLBraceStr;
|
||||
switch (getSwingV()) {
|
||||
case kSanyoAcSwingVHighest: result += kHighestStr; break;
|
||||
case kSanyoAcSwingVHigh: result += kHighStr; break;
|
||||
case kSanyoAcSwingVUpperMiddle:
|
||||
result += kUpperStr;
|
||||
result += ' ';
|
||||
result += kMiddleStr;
|
||||
break;
|
||||
case kSanyoAcSwingVLowerMiddle:
|
||||
result += kLowerStr;
|
||||
result += ' ';
|
||||
result += kMiddleStr;
|
||||
break;
|
||||
case kSanyoAcSwingVLow: result += kLowStr; break;
|
||||
case kSanyoAcSwingVLowest: result += kLowestStr; break;
|
||||
case kSanyoAcSwingVAuto: result += kAutoStr; break;
|
||||
default: result += kUnknownStr;
|
||||
}
|
||||
result += ')';
|
||||
result += addBoolToString(getSleep(), kSleepStr);
|
||||
result += addBoolToString(getBeep(), kBeepStr);
|
||||
result += addLabeledString(getSensor() ? kRoomStr : kWallStr, kSensorStr);
|
||||
result += kCommaSpaceStr;
|
||||
result += kSensorStr;
|
||||
result += ' ';
|
||||
result += addTempToString(getSensorTemp(), true, false);
|
||||
const uint16_t offtime = getOffTimer();
|
||||
result += addLabeledString(offtime ? minsToString(offtime) : kOffStr,
|
||||
kOffTimerStr);
|
||||
return result;
|
||||
}
|
||||
|
163
lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h
Normal file
163
lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h
Normal file
@ -0,0 +1,163 @@
|
||||
// Copyright 2020 David Conran
|
||||
|
||||
/// @file
|
||||
/// @brief Support for Sanyo protocols.
|
||||
/// Sanyo LC7461 support originally by marcosamarinho
|
||||
/// Sanyo SA 8650B originally added from
|
||||
/// https://github.com/shirriff/Arduino-IRremote/
|
||||
/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp
|
||||
/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
|
||||
/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
|
||||
/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211
|
||||
/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing
|
||||
|
||||
// Supports:
|
||||
// Brand: Sanyo, Model: SA 8650B - disabled
|
||||
// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461)
|
||||
// Brand: Sanyo, Model: SAP-K121AHA A/C (SANYO_AC)
|
||||
// Brand: Sanyo, Model: RCS-2HS4E remote (SANYO_AC)
|
||||
// Brand: Sanyo, Model: SAP-K242AH A/C (SANYO_AC)
|
||||
// Brand: Sanyo, Model: RCS-2S4E remote (SANYO_AC)
|
||||
|
||||
#ifndef IR_SANYO_H_
|
||||
#define IR_SANYO_H_
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRsend.h"
|
||||
#ifdef UNIT_TEST
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
|
||||
// Sanyo A/C
|
||||
// Ref: https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing
|
||||
// Byte[0] - 0x6A (Fixed?)
|
||||
// Byte[1] - Address + Temperature
|
||||
const uint8_t kSanyoAcTempByte = 1; ///< Index
|
||||
const uint8_t kSanyoAcTempOffset = 0; ///< Mask 0b000xxxxx
|
||||
const uint8_t kSanyoAcTempSize = 5; ///< Mask 0b000xxxxx
|
||||
const uint8_t kSanyoAcTempMin = 16; ///< Celsius
|
||||
const uint8_t kSanyoAcTempMax = 30; ///< Celsius
|
||||
const uint8_t kSanyoAcTempDelta = 4; ///< Celsius to Native Temp difference.
|
||||
// Byte[2] - Ambient Temp + Sensor
|
||||
const uint8_t kSanyoAcSensorByte = 2; ///< Index
|
||||
const uint8_t kSanyoAcSensorBit = 2; ///< Mask 0b00x00000
|
||||
// Ambient Temp Mask 0b000xxxxx
|
||||
const uint8_t kSanyoAcBeepBit = 6; ///< Mask 0b0x000000
|
||||
// Byte[3] - Off Hour
|
||||
const uint8_t kSanyoAcOffHourByte = 3; ///< Index
|
||||
const uint8_t kSanyoAcOffHourOffset = 0; ///< Mask 0b0000xxxx
|
||||
const uint8_t kSanyoAcOffHourSize = 4; ///< Mask 0b0000xxxx
|
||||
const uint8_t kSanyoAcHourMax = 15; ///< 0b1111
|
||||
// Byte[4] - Mode + Fan + Timer Enables
|
||||
const uint8_t kSanyoAcModeByte = 4; ///< Index
|
||||
const uint8_t kSanyoAcModeOffset = 4; ///< Mask 0b0xxx0000
|
||||
const uint8_t kSanyoAcModeSize = 3; ///< Mask 0b0xxx0000
|
||||
const uint8_t kSanyoAcHeat = 1; ///< 0b001
|
||||
const uint8_t kSanyoAcCool = 2; ///< 0b010
|
||||
const uint8_t kSanyoAcDry = 3; ///< 0b011
|
||||
const uint8_t kSanyoAcAuto = 4; ///< 0b100
|
||||
const uint8_t kSanyoAcOffTimerEnableBit = 2; ///< Mask 0b00000x00
|
||||
const uint8_t kSanyoAcFanOffset = 0; ///< Mask 0b000000xx
|
||||
const uint8_t kSanyoAcFanSize = 2; ///< Mask 0b000000xx
|
||||
const uint8_t kSanyoAcFanAuto = 0; ///< 0b00
|
||||
const uint8_t kSanyoAcFanHigh = 1; ///< 0b01
|
||||
const uint8_t kSanyoAcFanLow = 2; ///< 0b10
|
||||
const uint8_t kSanyoAcFanMedium = 3; ///< 0b11
|
||||
// Byte[5] - Power + SwingV
|
||||
const uint8_t kSanyoAcPowerByte = 5; ///< Index
|
||||
const uint8_t kSanyoAcPowerOffset = 6; ///< Mask 0bxx000000
|
||||
const uint8_t kSanyoAcPowerSize = 2; ///< Mask 0bxx000000
|
||||
// const uint8_t kSanyoAcPowerStandby = 0b00; ///< Standby?
|
||||
const uint8_t kSanyoAcPowerOff = 0b01; ///< Off
|
||||
const uint8_t kSanyoAcPowerOn = 0b10; ///< On
|
||||
const uint8_t kSanyoAcSwingVOffset = 0; ///< Mask 0b00000xxx
|
||||
const uint8_t kSanyoAcSwingVSize = 3; ///< Mask 0b00000xxx
|
||||
const uint8_t kSanyoAcSwingVAuto = 0; ///< 0b000
|
||||
const uint8_t kSanyoAcSwingVLowest = 2; ///< 0b010
|
||||
const uint8_t kSanyoAcSwingVLow = 3; ///< 0b011
|
||||
const uint8_t kSanyoAcSwingVLowerMiddle = 4; ///< 0b100
|
||||
const uint8_t kSanyoAcSwingVUpperMiddle = 5; ///< 0b101
|
||||
const uint8_t kSanyoAcSwingVHigh = 6; ///< 0b110
|
||||
const uint8_t kSanyoAcSwingVHighest = 7; ///< 0b111
|
||||
// Byte[6] - Sleep
|
||||
const uint8_t kSanyoAcSleepByte = 6; ///< Index
|
||||
const uint8_t kSanyoAcSleepBit = 3; ///< Mask 0b0000x000
|
||||
// Byte[8] - Checksum (8-bit Sum of all preceeding nibbles)
|
||||
|
||||
|
||||
// Classes
|
||||
/// Class for handling detailed Sanyo A/C messages.
|
||||
class IRSanyoAc {
|
||||
public:
|
||||
explicit IRSanyoAc(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
void stateReset(void);
|
||||
#if SEND_SANYO_AC
|
||||
void send(const uint16_t repeat = kNoRepeat);
|
||||
/// Run the calibration to calculate uSec timing offsets for this platform.
|
||||
/// @return The uSec timing offset needed per modulation of the IR Led.
|
||||
/// @note This will produce a 65ms IR signal pulse at 38kHz.
|
||||
/// Only ever needs to be run once per object instantiation, if at all.
|
||||
int8_t calibrate(void) { return _irsend.calibrate(); }
|
||||
#endif // SEND_SANYO_AC
|
||||
void begin(void);
|
||||
void on(void);
|
||||
void off(void);
|
||||
void setPower(const bool on);
|
||||
bool getPower(void);
|
||||
void setTemp(const uint8_t degrees);
|
||||
uint8_t getTemp(void);
|
||||
void setSensorTemp(const uint8_t degrees);
|
||||
uint8_t getSensorTemp(void);
|
||||
void setFan(const uint8_t speed);
|
||||
uint8_t getFan(void);
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode(void);
|
||||
void setSleep(const bool on);
|
||||
bool getSleep(void);
|
||||
void setSensor(const bool location);
|
||||
bool getSensor(void);
|
||||
void setBeep(const bool on);
|
||||
bool getBeep(void);
|
||||
void setSwingV(const uint8_t setting);
|
||||
uint8_t getSwingV(void);
|
||||
void setRaw(const uint8_t newState[]);
|
||||
uint8_t* getRaw(void);
|
||||
uint16_t getOffTimer(void);
|
||||
void setOffTimer(const uint16_t mins);
|
||||
static bool validChecksum(const uint8_t state[],
|
||||
const uint16_t length = kSanyoAcStateLength);
|
||||
uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
uint8_t convertSwingV(const stdAc::swingv_t position);
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
|
||||
stdAc::state_t toCommon(void);
|
||||
String toString(void);
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
IRsend _irsend; ///< Instance of the IR send class
|
||||
#else // UNIT_TEST
|
||||
/// @cond IGNORE
|
||||
IRsendTest _irsend; ///< Instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif // UNIT_TEST
|
||||
uint8_t remote_state[kSanyoAcStateLength]; ///< The state in IR code form.
|
||||
void checksum(void);
|
||||
static uint8_t calcChecksum(const uint8_t state[],
|
||||
const uint16_t length = kSanyoAcStateLength);
|
||||
void _setTemp(uint8_t *ptr, const uint8_t degrees);
|
||||
uint8_t _getTemp(uint8_t *ptr);
|
||||
};
|
||||
|
||||
#endif // IR_SANYO_H_
|
@ -4,6 +4,9 @@
|
||||
/// @brief Support for Toshiba protocols.
|
||||
/// @see https://github.com/r45635/HVAC-IR-Control
|
||||
/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205
|
||||
/// @see https://www.toshiba-carrier.co.jp/global/about/index.htm
|
||||
/// @see http://www.toshiba-carrier.co.th/AboutUs/Pages/CompanyProfile.aspx
|
||||
|
||||
#include "ir_Toshiba.h"
|
||||
#include <algorithm>
|
||||
@ -21,10 +24,10 @@
|
||||
// Toshiba A/C
|
||||
const uint16_t kToshibaAcHdrMark = 4400;
|
||||
const uint16_t kToshibaAcHdrSpace = 4300;
|
||||
const uint16_t kToshibaAcBitMark = 543;
|
||||
const uint16_t kToshibaAcOneSpace = 1623;
|
||||
const uint16_t kToshibaAcZeroSpace = 472;
|
||||
const uint16_t kToshibaAcMinGap = 7048;
|
||||
const uint16_t kToshibaAcBitMark = 580;
|
||||
const uint16_t kToshibaAcOneSpace = 1600;
|
||||
const uint16_t kToshibaAcZeroSpace = 490;
|
||||
const uint16_t kToshibaAcMinGap = 7400;
|
||||
|
||||
using irutils::addBoolToString;
|
||||
using irutils::addFanToString;
|
||||
@ -32,6 +35,8 @@ using irutils::addIntToString;
|
||||
using irutils::addLabeledString;
|
||||
using irutils::addModeToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::checkInvertedBytePairs;
|
||||
using irutils::invertBytePairs;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
|
||||
@ -41,10 +46,8 @@ using irutils::setBits;
|
||||
/// @param[in] data The message to be sent.
|
||||
/// @param[in] nbytes The number of bytes of message to be sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes,
|
||||
void IRsend::sendToshibaAC(const uint8_t data[], const uint16_t nbytes,
|
||||
const uint16_t repeat) {
|
||||
if (nbytes < kToshibaACStateLength)
|
||||
return; // Not enough bytes to send a proper message.
|
||||
sendGeneric(kToshibaAcHdrMark, kToshibaAcHdrSpace, kToshibaAcBitMark,
|
||||
kToshibaAcOneSpace, kToshibaAcBitMark, kToshibaAcZeroSpace,
|
||||
kToshibaAcBitMark, kToshibaAcMinGap, data, nbytes, 38, true,
|
||||
@ -58,7 +61,7 @@ void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes,
|
||||
/// @param[in] use_modulation Is frequency modulation to be used?
|
||||
IRToshibaAC::IRToshibaAC(const uint16_t pin, const bool inverted,
|
||||
const bool use_modulation)
|
||||
: _irsend(pin, inverted, use_modulation) { this->stateReset(); }
|
||||
: _irsend(pin, inverted, use_modulation) { stateReset(); }
|
||||
|
||||
/// Reset the state of the remote to a known good state/sequence.
|
||||
/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103
|
||||
@ -66,24 +69,72 @@ void IRToshibaAC::stateReset(void) {
|
||||
static const uint8_t kReset[kToshibaACStateLength] = {
|
||||
0xF2, 0x0D, 0x03, 0xFC, 0x01};
|
||||
memcpy(remote_state, kReset, kToshibaACStateLength);
|
||||
mode_state = getMode(true);
|
||||
setTemp(22); // Remote defaults to 22C after factory reset. So do the same.
|
||||
setSwing(kToshibaAcSwingOff);
|
||||
prev_mode = getMode();
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
void IRToshibaAC::begin(void) { _irsend.begin(); }
|
||||
|
||||
#if SEND_TOSHIBA_AC
|
||||
/// Send the current internal state as an IR message.
|
||||
/// Send the current internal state as IR messages.
|
||||
/// @param[in] repeat Nr. of times the message will be repeated.
|
||||
void IRToshibaAC::send(const uint16_t repeat) {
|
||||
_irsend.sendToshibaAC(getRaw(), kToshibaACStateLength, repeat);
|
||||
_backupState();
|
||||
_irsend.sendToshibaAC(getRaw(), getStateLength(), repeat);
|
||||
if (_send_swing && (getStateLength() != kToshibaACStateLengthShort)) {
|
||||
setStateLength(kToshibaACStateLengthShort);
|
||||
// Swing settings expect the min temp to be set.
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-653922374
|
||||
setTemp(kToshibaAcMinTemp);
|
||||
setSwing(_swing_mode);
|
||||
_irsend.sendToshibaAC(getRaw(), getStateLength(), repeat);
|
||||
_restoreState();
|
||||
}
|
||||
_send_swing = false;
|
||||
}
|
||||
#endif // SEND_TOSHIBA_AC
|
||||
|
||||
/// Get a PTR to the internal state/code for this protocol.
|
||||
/// Get the length of the supplied Toshiba state per it's protocol structure.
|
||||
/// @param[in] state The array to get the built-in length from.
|
||||
/// @param[in] size The physical size of the state array.
|
||||
/// @return Nr. of bytes in use for the provided state message.
|
||||
uint16_t IRToshibaAC::getInternalStateLength(const uint8_t state[],
|
||||
const uint16_t size) {
|
||||
if (size < kToshibaAcLengthByte) return 0;
|
||||
return std::min((uint16_t)(state[kToshibaAcLengthByte] + kToshibaAcMinLength),
|
||||
kToshibaACStateLengthLong);
|
||||
}
|
||||
|
||||
/// Get the length of the current internal state per the protocol structure.
|
||||
/// @return Nr. of bytes in use for the current internal state message.
|
||||
uint16_t IRToshibaAC::getStateLength(void) {
|
||||
return getInternalStateLength(remote_state, kToshibaACStateLengthLong);
|
||||
}
|
||||
|
||||
/// Set the internal length of the current internal state per the protocol.
|
||||
/// @param[in] size Nr. of bytes in use for the current internal state message.
|
||||
void IRToshibaAC::setStateLength(const uint16_t size) {
|
||||
if (size < kToshibaAcMinLength) return;
|
||||
remote_state[kToshibaAcLengthByte] = size - kToshibaAcMinLength;
|
||||
}
|
||||
|
||||
/// Make a copy of the internal code-form A/C state.
|
||||
void IRToshibaAC::_backupState(void) {
|
||||
memcpy(backup, remote_state, kToshibaACStateLengthLong);
|
||||
}
|
||||
|
||||
/// Recover the internal code-form A/C state from the backup.
|
||||
void IRToshibaAC::_restoreState(void) {
|
||||
memcpy(remote_state, backup, kToshibaACStateLengthLong);
|
||||
}
|
||||
|
||||
/// Get a PTR to the internal state/code for this protocol with all integrity
|
||||
/// checks passing.
|
||||
/// @return PTR to a code for this protocol based on the current internal state.
|
||||
uint8_t* IRToshibaAC::getRaw(void) {
|
||||
this->checksum();
|
||||
checksum(getStateLength());
|
||||
return remote_state;
|
||||
}
|
||||
|
||||
@ -91,7 +142,8 @@ uint8_t* IRToshibaAC::getRaw(void) {
|
||||
/// @param[in] newState A valid code for this protocol.
|
||||
void IRToshibaAC::setRaw(const uint8_t newState[]) {
|
||||
memcpy(remote_state, newState, kToshibaACStateLength);
|
||||
mode_state = this->getMode(true);
|
||||
prev_mode = getMode();
|
||||
_send_swing = true;
|
||||
}
|
||||
|
||||
/// Calculate the checksum for a given state.
|
||||
@ -100,13 +152,7 @@ void IRToshibaAC::setRaw(const uint8_t newState[]) {
|
||||
/// @return The calculated checksum value.
|
||||
uint8_t IRToshibaAC::calcChecksum(const uint8_t state[],
|
||||
const uint16_t length) {
|
||||
uint8_t checksum = 0;
|
||||
// Only calculate it for valid lengths.
|
||||
if (length > 1) {
|
||||
// Checksum is simple XOR of all bytes except the last one.
|
||||
for (uint8_t i = 0; i < length - 1; i++) checksum ^= state[i];
|
||||
}
|
||||
return checksum;
|
||||
return length ? xorBytes(state, length - 1) : 0;
|
||||
}
|
||||
|
||||
/// Verify the checksum is valid for a given state.
|
||||
@ -114,17 +160,27 @@ uint8_t IRToshibaAC::calcChecksum(const uint8_t state[],
|
||||
/// @param[in] length The length/size of the array.
|
||||
/// @return true, if the state has a valid checksum. Otherwise, false.
|
||||
bool IRToshibaAC::validChecksum(const uint8_t state[], const uint16_t length) {
|
||||
return (length > 1 && state[length - 1] == IRToshibaAC::calcChecksum(state,
|
||||
length));
|
||||
return length >= kToshibaAcMinLength &&
|
||||
state[length - 1] == IRToshibaAC::calcChecksum(state, length) &&
|
||||
checkInvertedBytePairs(state, kToshibaAcInvertedLength) &&
|
||||
IRToshibaAC::getInternalStateLength(state, length) == length;
|
||||
}
|
||||
|
||||
/// Calculate & set the checksum for the current internal state of the remote.
|
||||
/// @param[in] length The length/size of the internal array to checksum.
|
||||
|
||||
void IRToshibaAC::checksum(const uint16_t length) {
|
||||
// Stored the checksum value in the last byte.
|
||||
if (length > 1) remote_state[length - 1] = this->calcChecksum(remote_state,
|
||||
length);
|
||||
if (length >= kToshibaAcMinLength) {
|
||||
// Set/clear the short msg bit.
|
||||
setBit(&remote_state[4], kToshibaAcShortMsgBit,
|
||||
getStateLength() == kToshibaACStateLengthShort);
|
||||
// Set/clear the long msg bit.
|
||||
setBit(&remote_state[4], kToshibaAcLongMsgBit,
|
||||
getStateLength() == kToshibaACStateLengthLong);
|
||||
invertBytePairs(remote_state, kToshibaAcInvertedLength);
|
||||
// Always do the Xor checksum LAST!
|
||||
remote_state[length - 1] = calcChecksum(remote_state, length);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the requested power state of the A/C to on.
|
||||
@ -136,19 +192,18 @@ void IRToshibaAC::off(void) { setPower(false); }
|
||||
/// Change the power setting.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRToshibaAC::setPower(const bool on) {
|
||||
setBit(&remote_state[6], kToshibaAcPowerOffset, !on); // Cleared when on.
|
||||
if (on)
|
||||
setMode(mode_state);
|
||||
else
|
||||
setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize,
|
||||
kToshibaAcHeat);
|
||||
if (on) { // On
|
||||
// If not already on, pick the last non-off mode used
|
||||
if (!getPower()) setMode(prev_mode);
|
||||
} else { // Off
|
||||
setMode(kToshibaAcOff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Get the value of the current power setting.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRToshibaAC::getPower(void) {
|
||||
return !GETBIT8(remote_state[6], kToshibaAcPowerOffset);
|
||||
return getMode(true) != kToshibaAcOff;
|
||||
}
|
||||
|
||||
/// Set the temperature.
|
||||
@ -187,32 +242,104 @@ uint8_t IRToshibaAC::getFan(void) {
|
||||
return --fan;
|
||||
}
|
||||
|
||||
/// Get the swing setting of the A/C.
|
||||
/// @param[in] raw Calculate the answer from just the state data.
|
||||
/// @return The current swing mode setting.
|
||||
uint8_t IRToshibaAC::getSwing(const bool raw) {
|
||||
return raw ? GETBITS8(remote_state[5], kToshibaAcSwingOffset,
|
||||
kToshibaAcSwingSize) : _swing_mode;
|
||||
}
|
||||
|
||||
/// Set the swing setting of the A/C.
|
||||
/// @param[in] setting The value of the desired setting.
|
||||
void IRToshibaAC::setSwing(const uint8_t setting) {
|
||||
switch (setting) {
|
||||
case kToshibaAcSwingStep:
|
||||
case kToshibaAcSwingOn:
|
||||
case kToshibaAcSwingOff:
|
||||
_send_swing = true;
|
||||
_swing_mode = setting;
|
||||
if (getStateLength() == kToshibaACStateLengthShort)
|
||||
setBits(&remote_state[5], kToshibaAcSwingOffset, kToshibaAcSwingSize,
|
||||
setting);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the operating mode setting of the A/C.
|
||||
/// @param[in] useRaw Indicate to get the mode from the internal state array.
|
||||
/// @param[in] raw Get the value without any intelligent processing.
|
||||
/// @return The current operating mode setting.
|
||||
uint8_t IRToshibaAC::getMode(const bool useRaw) {
|
||||
if (useRaw)
|
||||
return GETBITS8(remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize);
|
||||
else
|
||||
return mode_state;
|
||||
uint8_t IRToshibaAC::getMode(const bool raw) {
|
||||
const uint8_t mode = GETBITS8(remote_state[6], kToshibaAcModeOffset,
|
||||
kToshibaAcModeSize);
|
||||
if (raw) return mode;
|
||||
switch (mode) {
|
||||
case kToshibaAcOff: return prev_mode;
|
||||
default: return mode;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the operating mode of the A/C.
|
||||
/// @param[in] mode The desired operating mode.
|
||||
/// @note If we get an unexpected mode, default to AUTO.
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-654446771
|
||||
void IRToshibaAC::setMode(const uint8_t mode) {
|
||||
if (mode != prev_mode)
|
||||
// Changing mode or power turns Econo & Turbo to off on a real remote.
|
||||
// Setting the internal message length to "normal" will do that.
|
||||
setStateLength(kToshibaACStateLength);
|
||||
switch (mode) {
|
||||
case kToshibaAcAuto:
|
||||
case kToshibaAcCool:
|
||||
case kToshibaAcDry:
|
||||
case kToshibaAcHeat:
|
||||
mode_state = mode;
|
||||
// Only adjust the remote_state if we have power set to on.
|
||||
if (getPower())
|
||||
setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize,
|
||||
mode_state);
|
||||
return;
|
||||
default: this->setMode(kToshibaAcAuto); // There is no Fan mode.
|
||||
case kToshibaAcFan:
|
||||
prev_mode = mode;
|
||||
// FALL-THRU
|
||||
case kToshibaAcOff:
|
||||
setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize,
|
||||
mode);
|
||||
break;
|
||||
default: setMode(kToshibaAcAuto);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the Turbo (Powerful) setting of the A/C.
|
||||
/// @return true, if the current setting is on. Otherwise, false.
|
||||
bool IRToshibaAC::getTurbo(void) {
|
||||
if (getStateLength() == kToshibaACStateLengthLong)
|
||||
return remote_state[8] == kToshibaAcTurboOn;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set the Turbo (Powerful) setting of the A/C.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
/// Note: Turbo mode is mutually exclusive with Economy mode.
|
||||
void IRToshibaAC::setTurbo(const bool on) {
|
||||
if (on) {
|
||||
remote_state[8] = kToshibaAcTurboOn;
|
||||
setStateLength(kToshibaACStateLengthLong);
|
||||
} else {
|
||||
if (!getEcono()) setStateLength(kToshibaACStateLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the Economy mode setting of the A/C.
|
||||
/// @return true, if the current setting is on. Otherwise, false.
|
||||
bool IRToshibaAC::getEcono(void) {
|
||||
if (getStateLength() == kToshibaACStateLengthLong)
|
||||
return remote_state[8] == kToshibaAcEconoOn;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set the Economy mode setting of the A/C.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
/// Note: Economy mode is mutually exclusive with Turbo mode.
|
||||
void IRToshibaAC::setEcono(const bool on) {
|
||||
if (on) {
|
||||
remote_state[8] = kToshibaAcEconoOn;
|
||||
setStateLength(kToshibaACStateLengthLong);
|
||||
} else {
|
||||
if (!getTurbo()) setStateLength(kToshibaACStateLength);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,7 +351,8 @@ uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) {
|
||||
case stdAc::opmode_t::kCool: return kToshibaAcCool;
|
||||
case stdAc::opmode_t::kHeat: return kToshibaAcHeat;
|
||||
case stdAc::opmode_t::kDry: return kToshibaAcDry;
|
||||
// No Fan mode.
|
||||
case stdAc::opmode_t::kFan: return kToshibaAcFan;
|
||||
case stdAc::opmode_t::kOff: return kToshibaAcOff;
|
||||
default: return kToshibaAcAuto;
|
||||
}
|
||||
}
|
||||
@ -251,6 +379,8 @@ stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) {
|
||||
case kToshibaAcCool: return stdAc::opmode_t::kCool;
|
||||
case kToshibaAcHeat: return stdAc::opmode_t::kHeat;
|
||||
case kToshibaAcDry: return stdAc::opmode_t::kDry;
|
||||
case kToshibaAcFan: return stdAc::opmode_t::kFan;
|
||||
case kToshibaAcOff: return stdAc::opmode_t::kOff;
|
||||
default: return stdAc::opmode_t::kAuto;
|
||||
}
|
||||
}
|
||||
@ -280,12 +410,13 @@ stdAc::state_t IRToshibaAC::toCommon(void) {
|
||||
result.celsius = true;
|
||||
result.degrees = this->getTemp();
|
||||
result.fanspeed = this->toCommonFanSpeed(this->getFan());
|
||||
result.swingv = (getSwing() == kToshibaAcSwingOn) ? stdAc::swingv_t::kAuto
|
||||
: stdAc::swingv_t::kOff;
|
||||
result.turbo = getTurbo();
|
||||
result.econo = getEcono();
|
||||
// Not supported.
|
||||
result.turbo = false;
|
||||
result.light = false;
|
||||
result.filter = false;
|
||||
result.econo = false;
|
||||
result.swingv = stdAc::swingv_t::kOff;
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
result.quiet = false;
|
||||
result.clean = false;
|
||||
@ -299,14 +430,33 @@ stdAc::state_t IRToshibaAC::toCommon(void) {
|
||||
/// @return A human readable string.
|
||||
String IRToshibaAC::toString(void) {
|
||||
String result = "";
|
||||
result.reserve(40);
|
||||
result += addBoolToString(getPower(), kPowerStr, false);
|
||||
result += addModeToString(getMode(), kToshibaAcAuto, kToshibaAcCool,
|
||||
kToshibaAcHeat, kToshibaAcDry, kToshibaAcAuto);
|
||||
result += addTempToString(getTemp());
|
||||
result += addFanToString(getFan(), kToshibaAcFanMax, kToshibaAcFanMin,
|
||||
kToshibaAcFanAuto, kToshibaAcFanAuto,
|
||||
kToshibaAcFanMed);
|
||||
result.reserve(80);
|
||||
result += addTempToString(getTemp(), true, false);
|
||||
switch (getStateLength()) {
|
||||
case kToshibaACStateLengthShort:
|
||||
result += addIntToString(getSwing(true), kSwingVStr);
|
||||
result += kSpaceLBraceStr;
|
||||
switch (getSwing(true)) {
|
||||
case kToshibaAcSwingOff: result += kOffStr; break;
|
||||
case kToshibaAcSwingOn: result += kOnStr; break;
|
||||
case kToshibaAcSwingStep: result += kStepStr; break;
|
||||
default: result += kUnknownStr;
|
||||
}
|
||||
result += ')';
|
||||
break;
|
||||
case kToshibaACStateLengthLong:
|
||||
case kToshibaACStateLength:
|
||||
default:
|
||||
result += addBoolToString(getPower(), kPowerStr);
|
||||
if (getPower())
|
||||
result += addModeToString(getMode(), kToshibaAcAuto, kToshibaAcCool,
|
||||
kToshibaAcHeat, kToshibaAcDry, kToshibaAcFan);
|
||||
result += addFanToString(getFan(), kToshibaAcFanMax, kToshibaAcFanMin,
|
||||
kToshibaAcFanAuto, kToshibaAcFanAuto,
|
||||
kToshibaAcFanMed);
|
||||
result += addBoolToString(getTurbo(), kTurboStr);
|
||||
result += addBoolToString(getEcono(), kEconoStr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -322,8 +472,16 @@ String IRToshibaAC::toString(void) {
|
||||
bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
// Compliance
|
||||
if (strict && nbits != kToshibaACBits)
|
||||
return false; // Must be called with the correct nr. of bytes.
|
||||
if (strict) {
|
||||
switch (nbits) { // Must be called with the correct nr. of bits.
|
||||
case kToshibaACBits:
|
||||
case kToshibaACBitsShort:
|
||||
case kToshibaACBitsLong:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Match Header + Data + Footer
|
||||
if (!matchGeneric(results->rawbuf + offset, results->state,
|
||||
@ -336,7 +494,7 @@ bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset,
|
||||
// Compliance
|
||||
if (strict) {
|
||||
// Check that the checksum of the message is correct.
|
||||
if (!IRToshibaAC::validChecksum(results->state)) return false;
|
||||
if (!IRToshibaAC::validChecksum(results->state, nbits / 8)) return false;
|
||||
}
|
||||
|
||||
// Success
|
||||
|
@ -4,6 +4,10 @@
|
||||
/// @brief Support for Toshiba protocols.
|
||||
/// @see https://github.com/r45635/HVAC-IR-Control
|
||||
/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205
|
||||
/// @see https://docs.google.com/spreadsheets/d/1yidE2fvaO9kpCHfKafIdH31q4uaskYR1OwwrkyOxbp0/edit?usp=drivesdk
|
||||
/// @see https://www.toshiba-carrier.co.jp/global/about/index.htm
|
||||
/// @see http://www.toshiba-carrier.co.th/AboutUs/Pages/CompanyProfile.aspx
|
||||
|
||||
// Supports:
|
||||
// Brand: Toshiba, Model: RAS-B13N3KV2
|
||||
@ -12,6 +16,10 @@
|
||||
// Brand: Toshiba, Model: RAS 18SKP-ES
|
||||
// Brand: Toshiba, Model: WH-TA04NE
|
||||
// Brand: Toshiba, Model: WC-L03SE
|
||||
// Brand: Carrier, Model: 42NQV060M2 / 38NYV060M2 A/C
|
||||
// Brand: Carrier, Model: 42NQV050M2 / 38NYV050M2 A/C
|
||||
// Brand: Carrier, Model: 42NQV035M2 / 38NYV035M2 A/C
|
||||
// Brand: Carrier, Model: 42NQV025M2 / 38NYV025M2 A/C
|
||||
|
||||
#ifndef IR_TOSHIBA_H_
|
||||
#define IR_TOSHIBA_H_
|
||||
@ -28,23 +36,53 @@
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
// Byte[0] - 0xF2
|
||||
// Byte[1] - 0x0D (inverted previous byte's value)
|
||||
// Byte[2] - The expected payload length (in bytes) past the Byte[4].
|
||||
const uint8_t kToshibaAcLengthByte = 2; ///< Byte pos of the "length" attribute
|
||||
const uint8_t kToshibaAcMinLength = 6; ///< Min Nr. of bytes in a message.
|
||||
///< Known lengths are:
|
||||
///< 1 (56 bit message)
|
||||
///< 3 (72 bit message)
|
||||
///< 4 (80 bit message)
|
||||
// Byte[3] - The bit-inverted value of the "length" byte.
|
||||
const uint16_t kToshibaAcInvertedLength = 4; ///< Nr. of leading bytes in
|
||||
///< inverted pairs.
|
||||
// Byte[4]
|
||||
const uint8_t kToshibaAcShortMsgBit = 5; ///< Mask 0b00x00000
|
||||
const uint8_t kToshibaAcLongMsgBit = 3; ///< Mask 0b00001000
|
||||
// Byte[5]
|
||||
const uint8_t kToshibaAcSwingOffset = 0; ///< Bit offset.
|
||||
const uint8_t kToshibaAcSwingSize = 2; ///< Mask 0b000000xx
|
||||
const uint8_t kToshibaAcSwingStep = 0; ///< 0b00
|
||||
const uint8_t kToshibaAcSwingOn = 1; ///< 0b01
|
||||
const uint8_t kToshibaAcSwingOff = 2; ///< 0b10
|
||||
|
||||
const uint8_t kToshibaAcTempOffset = 4; ///< Bit offset.
|
||||
const uint8_t kToshibaAcTempSize = 4; ///< Mask 0bxxxx0000
|
||||
const uint8_t kToshibaAcMinTemp = 17; ///< 17C
|
||||
const uint8_t kToshibaAcMaxTemp = 30; ///< 30C
|
||||
// Byte[6]
|
||||
const uint8_t kToshibaAcModeOffset = 0;
|
||||
const uint8_t kToshibaAcModeSize = 2; // Nr. of bits
|
||||
const uint8_t kToshibaAcAuto = 0;
|
||||
const uint8_t kToshibaAcCool = 1;
|
||||
const uint8_t kToshibaAcDry = 2;
|
||||
const uint8_t kToshibaAcHeat = 3;
|
||||
const uint8_t kToshibaAcPowerOffset = 2;
|
||||
const uint8_t kToshibaAcModeSize = 3; // Mask 0b00000xxx
|
||||
const uint8_t kToshibaAcAuto = 0; // 0b000
|
||||
const uint8_t kToshibaAcCool = 1; // 0b001
|
||||
const uint8_t kToshibaAcDry = 2; // 0b010
|
||||
const uint8_t kToshibaAcHeat = 3; // 0b011
|
||||
const uint8_t kToshibaAcFan = 4; // 0b100
|
||||
const uint8_t kToshibaAcOff = 7; // 0b111
|
||||
const uint8_t kToshibaAcFanOffset = 5;
|
||||
const uint8_t kToshibaAcFanSize = 3; // Nr. of bits
|
||||
const uint8_t kToshibaAcFanAuto = 0b000;
|
||||
const uint8_t kToshibaAcFanMin = 0b001;
|
||||
const uint8_t kToshibaAcFanMed = 0b011;
|
||||
const uint8_t kToshibaAcFanMax = 0b101;
|
||||
const uint8_t kToshibaAcTempOffset = 4;
|
||||
const uint8_t kToshibaAcTempSize = 4; // Nr. of bits
|
||||
const uint8_t kToshibaAcMinTemp = 17; // 17C
|
||||
const uint8_t kToshibaAcMaxTemp = 30; // 30C
|
||||
const uint8_t kToshibaAcFanSize = 3; // Mask 0bxxx00000
|
||||
const uint8_t kToshibaAcFanAuto = 0; // 0b000
|
||||
const uint8_t kToshibaAcFanMin = 1; // 0b001
|
||||
const uint8_t kToshibaAcFanMed = 3; // 0b011
|
||||
const uint8_t kToshibaAcFanMax = 5; // 0b101
|
||||
// Byte[8] (Checksum for 72 bit messages, Eco/Turbo for long 80 bit messages)
|
||||
const uint8_t kToshibaAcEcoTurboOffset = 0;
|
||||
const uint8_t kToshibaAcEcoTurboSize = 2; // Mask 0b000000xx
|
||||
const uint8_t kToshibaAcTurboOn = 1; // 0b01
|
||||
const uint8_t kToshibaAcEconoOn = 3; // 0b11
|
||||
// Byte[last] - Checksum (xor)
|
||||
|
||||
// Legacy defines. (Deperecated)
|
||||
#define TOSHIBA_AC_AUTO kToshibaAcAuto
|
||||
@ -81,12 +119,21 @@ class IRToshibaAC {
|
||||
uint8_t getTemp(void);
|
||||
void setFan(const uint8_t speed);
|
||||
uint8_t getFan(void);
|
||||
void setTurbo(const bool on);
|
||||
bool getTurbo(void);
|
||||
void setEcono(const bool on);
|
||||
bool getEcono(void);
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode(const bool useRaw = false);
|
||||
uint8_t getMode(const bool raw = false);
|
||||
void setRaw(const uint8_t newState[]);
|
||||
uint8_t* getRaw(void);
|
||||
static uint16_t getInternalStateLength(const uint8_t state[],
|
||||
const uint16_t size);
|
||||
uint16_t getStateLength(void);
|
||||
static bool validChecksum(const uint8_t state[],
|
||||
const uint16_t length = kToshibaACStateLength);
|
||||
uint8_t getSwing(const bool raw = true);
|
||||
void setSwing(const uint8_t setting);
|
||||
uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
@ -102,11 +149,17 @@ class IRToshibaAC {
|
||||
IRsendTest _irsend; ///< Instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif // UNIT_TEST
|
||||
uint8_t remote_state[kToshibaACStateLength]; ///< The state in IR code form.
|
||||
uint8_t remote_state[kToshibaACStateLengthLong]; ///< The state in code form.
|
||||
uint8_t backup[kToshibaACStateLengthLong]; ///< A backup copy of the state.
|
||||
uint8_t prev_mode; ///< Store of the previously set mode.
|
||||
bool _send_swing; ///< Flag indicating if we need to send a swing message.
|
||||
uint8_t _swing_mode; ///< The saved swing state/mode/command.
|
||||
void checksum(const uint16_t length = kToshibaACStateLength);
|
||||
static uint8_t calcChecksum(const uint8_t state[],
|
||||
const uint16_t length = kToshibaACStateLength);
|
||||
uint8_t mode_state;
|
||||
void setStateLength(const uint16_t size);
|
||||
void _backupState(void);
|
||||
void _restoreState(void);
|
||||
};
|
||||
|
||||
#endif // IR_TOSHIBA_H_
|
||||
|
@ -360,6 +360,9 @@
|
||||
|
||||
// Compound words/phrases/descriptions from pre-defined words.
|
||||
// Note: Obviously these need to be defined *after* their component words.
|
||||
#ifndef D_STR_ECONOTOGGLE
|
||||
#define D_STR_ECONOTOGGLE D_STR_ECONO " " D_STR_TOGGLE
|
||||
#endif // D_STR_ECONOTOGGLE
|
||||
#ifndef D_STR_EYEAUTO
|
||||
#define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
|
||||
#endif // D_STR_EYEAUTO
|
||||
@ -685,6 +688,9 @@
|
||||
#ifndef D_STR_SANYO
|
||||
#define D_STR_SANYO "SANYO"
|
||||
#endif // D_STR_SANYO
|
||||
#ifndef D_STR_SANYO_AC
|
||||
#define D_STR_SANYO_AC "SANYO_AC"
|
||||
#endif // D_STR_SANYO_AC
|
||||
#ifndef D_STR_SANYO_LC7461
|
||||
#define D_STR_SANYO_LC7461 "SANYO_LC7461"
|
||||
#endif // D_STR_SANYO_LC7461
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2019 David Conran
|
||||
|
||||
#include <string>
|
||||
#include "ir_Airwell.h"
|
||||
#include "ir_Amcor.h"
|
||||
#include "ir_Argo.h"
|
||||
#include "ir_Carrier.h"
|
||||
@ -39,10 +40,33 @@
|
||||
|
||||
// Tests for IRac class.
|
||||
|
||||
TEST(TestIRac, Airwell) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power Toggle: On, Mode: 3 (Auto), Fan: 1 (Medium), Temp: 18C";
|
||||
|
||||
ac.begin();
|
||||
irac.airwell(&ac,
|
||||
true, // Power
|
||||
stdAc::opmode_t::kAuto, // Mode
|
||||
18, // Celsius
|
||||
stdAc::fanspeed_t::kMedium); // Fan speed
|
||||
ASSERT_EQ(expected, ac.toString());
|
||||
ac._irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
|
||||
ASSERT_EQ(AIRWELL, ac._irsend.capture.decode_type);
|
||||
ASSERT_EQ(kAirwellBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestIRac, Amcor) {
|
||||
IRAmcorAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRAmcorAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 5 (Auto), Fan: 3 (High), Temp: 19C, Max: Off";
|
||||
|
||||
@ -63,8 +87,8 @@ TEST(TestIRac, Amcor) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Argo) {
|
||||
IRArgoAC ac(0);
|
||||
IRac irac(0);
|
||||
IRArgoAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
|
||||
ac.begin();
|
||||
irac.argo(&ac,
|
||||
@ -118,9 +142,9 @@ TEST(TestIRac, Carrier64) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Coolix) {
|
||||
IRCoolixAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRCoolixAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Heat), Fan: 1 (Max), Temp: 21C, Zone Follow: Off, "
|
||||
"Sensor Temp: Off";
|
||||
@ -221,9 +245,9 @@ TEST(TestIRac, Corona) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin) {
|
||||
IRDaikinESP ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikinESP ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Cool), Temp: 19C, Fan: 5 (High), Powerful: Off, "
|
||||
"Quiet: Off, Sensor: Off, Mould: On, Comfort: Off, "
|
||||
@ -254,9 +278,9 @@ TEST(TestIRac, Daikin) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin128) {
|
||||
IRDaikin128 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin128 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power Toggle: On, Mode: 8 (Heat), Temp: 27C, Fan: 9 (Quiet), "
|
||||
"Powerful: Off, Quiet: On, Swing(V): On, Sleep: On, "
|
||||
@ -287,9 +311,9 @@ TEST(TestIRac, Daikin128) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin152) {
|
||||
IRDaikin152 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin152 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Cool), Temp: 27C, Fan: 3 (Medium), Swing(V): On, "
|
||||
"Powerful: Off, Quiet: Off, Econo: On, Sensor: Off, Comfort: Off";
|
||||
@ -315,9 +339,9 @@ TEST(TestIRac, Daikin152) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin160) {
|
||||
IRDaikin160 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin160 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 2 (Dry), Temp: 23C, Fan: 1 (Low), "
|
||||
"Swing(V): 3 (Middle)";
|
||||
@ -340,9 +364,9 @@ TEST(TestIRac, Daikin160) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin176) {
|
||||
IRDaikin176 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin176 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 1 (Low), Swing(H): 5 (Auto)";
|
||||
|
||||
@ -364,9 +388,9 @@ TEST(TestIRac, Daikin176) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin2) {
|
||||
IRDaikin2 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin2 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Cool), Temp: 19C, Fan: 1 (Low), "
|
||||
"Swing(V): 14 (Auto), Swing(H): 170 (UNKNOWN), Clock: 00:00, "
|
||||
@ -402,9 +426,9 @@ TEST(TestIRac, Daikin2) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin216) {
|
||||
IRDaikin216 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRDaikin216 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 4 (Heat), Temp: 31C, Fan: 11 (Quiet), "
|
||||
"Swing(H): On, Swing(V): On, Quiet: On, Powerful: Off";
|
||||
@ -511,9 +535,9 @@ TEST(TestIRac, Electra) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Fujitsu) {
|
||||
IRFujitsuAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRFujitsuAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
std::string ardb1_expected =
|
||||
"Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 19C, "
|
||||
"Fan: 2 (Medium), Command: N/A";
|
||||
@ -591,9 +615,9 @@ TEST(TestIRac, Fujitsu) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Goodweather) {
|
||||
IRGoodweatherAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRGoodweatherAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 19C, Fan: 2 (Medium), Turbo: Toggle, "
|
||||
"Light: Toggle, Sleep: Toggle, Swing: 1 (Slow), Command: 0 (Power)";
|
||||
@ -619,9 +643,9 @@ TEST(TestIRac, Goodweather) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Gree) {
|
||||
IRGreeAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRGreeAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, "
|
||||
"Fan: 2 (Medium), Turbo: Off, IFeel: Off, WiFi: Off, XFan: On, "
|
||||
@ -652,9 +676,9 @@ TEST(TestIRac, Gree) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Haier) {
|
||||
IRHaierAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRHaierAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Command: 1 (On), Mode: 1 (Cool), Temp: 24C, Fan: 2 (Medium), "
|
||||
"Swing: 1 (Up), Sleep: On, Health: On, Clock: 13:45, "
|
||||
@ -682,9 +706,9 @@ TEST(TestIRac, Haier) {
|
||||
|
||||
|
||||
TEST(TestIRac, HaierYrwo2) {
|
||||
IRHaierACYRW02 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRHaierACYRW02 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 23C, "
|
||||
"Fan: 2 (Medium), Turbo: 1 (High), Swing: 1 (Highest), Sleep: On, "
|
||||
@ -711,9 +735,9 @@ TEST(TestIRac, HaierYrwo2) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Hitachi) {
|
||||
IRHitachiAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRHitachiAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 2 (Auto), Temp: 22C, Fan: 3 (Medium), "
|
||||
"Swing(V): Off, Swing(H): On";
|
||||
@ -821,9 +845,9 @@ TEST(TestIRac, Hitachi344) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Hitachi424) {
|
||||
IRHitachiAc424 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRHitachiAc424 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), "
|
||||
"Button: 19 (Power/Mode), Swing(V) Toggle: Off";
|
||||
@ -866,9 +890,9 @@ TEST(TestIRac, Hitachi424) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Kelvinator) {
|
||||
IRKelvinatorAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRKelvinatorAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 19C, Fan: 3 (Medium), Turbo: Off, "
|
||||
"Quiet: Off, XFan: On, Ion: On, Light: On, "
|
||||
@ -899,9 +923,9 @@ TEST(TestIRac, Kelvinator) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, LG) {
|
||||
IRLgAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 1 (Dry), Temp: 27C, Fan: 2 (Medium)";
|
||||
@ -925,12 +949,12 @@ TEST(TestIRac, LG) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Midea) {
|
||||
IRMideaAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Dry), Celsius: On, Temp: 27C/80F, Fan: 2 (Medium), "
|
||||
"Sleep: On, Swing(V) Toggle: Off";
|
||||
"Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off";
|
||||
|
||||
ac.begin();
|
||||
irac.midea(&ac,
|
||||
@ -940,6 +964,7 @@ TEST(TestIRac, Midea) {
|
||||
27, // Degrees
|
||||
stdAc::fanspeed_t::kMedium, // Fan speed
|
||||
stdAc::swingv_t::kOff, // Swing(V)
|
||||
false, // Econo
|
||||
8 * 60 + 0); // Sleep time
|
||||
|
||||
ASSERT_EQ(expected, ac.toString());
|
||||
@ -953,9 +978,9 @@ TEST(TestIRac, Midea) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Mitsubishi) {
|
||||
IRMitsubishiAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRMitsubishiAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 2 (Medium), "
|
||||
"Swing(V): 0 (Auto), Swing(H): 3 (UNKNOWN), "
|
||||
@ -982,9 +1007,9 @@ TEST(TestIRac, Mitsubishi) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Mitsubishi136) {
|
||||
IRMitsubishi136 ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRMitsubishi136 ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 5 (Dry), Temp: 22C, Fan: 3 (High), "
|
||||
"Swing(V): 3 (Highest), Quiet: Off";
|
||||
@ -1008,9 +1033,9 @@ TEST(TestIRac, Mitsubishi136) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, MitsubishiHeavy88) {
|
||||
IRMitsubishiHeavy88Ac ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRMitsubishiHeavy88Ac ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 3 (Med), "
|
||||
"Swing(V): 4 (Auto), Swing(H): 0 (Off), Turbo: Off, Econo: Off, "
|
||||
@ -1038,9 +1063,9 @@ TEST(TestIRac, MitsubishiHeavy88) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, MitsubishiHeavy152) {
|
||||
IRMitsubishiHeavy152Ac ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRMitsubishiHeavy152Ac ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 6 (Econo), "
|
||||
"Swing(V): 6 (Off), Swing(H): 0 (Auto), Silent: On, Turbo: Off, "
|
||||
@ -1071,9 +1096,9 @@ TEST(TestIRac, MitsubishiHeavy152) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Neoclima) {
|
||||
IRNeoclimaAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRNeoclimaAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 3 (Low), "
|
||||
"Swing(V): Off, Swing(H): On, Sleep: On, Turbo: Off, Hold: Off, Ion: On, "
|
||||
@ -1103,9 +1128,9 @@ TEST(TestIRac, Neoclima) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Panasonic) {
|
||||
IRPanasonicAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRPanasonicAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected_nke[] =
|
||||
"Model: 2 (NKE), Power: On, Mode: 4 (Heat), Temp: 28C, Fan: 2 (Medium), "
|
||||
"Swing(V): 15 (Auto), Swing(H): 6 (Middle), Quiet: On, "
|
||||
@ -1161,9 +1186,9 @@ TEST(TestIRac, Panasonic) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Samsung) {
|
||||
IRSamsungAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRSamsungAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), Swing: On, "
|
||||
"Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, "
|
||||
@ -1223,10 +1248,38 @@ TEST(TestIRac, Samsung) {
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestIRac, Sanyo) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), "
|
||||
"Swing(V): 7 (Highest), Sleep: On, Beep: On, "
|
||||
"Sensor: Wall, Sensor Temp: 28C, Off Timer: Off";
|
||||
|
||||
ac.begin();
|
||||
irac.sanyo(&ac,
|
||||
true, // Power
|
||||
stdAc::opmode_t::kCool, // Mode
|
||||
28, // Celsius
|
||||
stdAc::fanspeed_t::kMedium, // Fan speed
|
||||
stdAc::swingv_t::kHighest, // Vertical Swing
|
||||
true, // Beep
|
||||
17); // Sleep
|
||||
ASSERT_EQ(expected, ac.toString());
|
||||
ac._irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
|
||||
ASSERT_EQ(SANYO_AC, ac._irsend.capture.decode_type);
|
||||
ASSERT_EQ(kSanyoAcBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestIRac, Sharp) {
|
||||
IRSharpAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRSharpAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), "
|
||||
"Turbo: Off, Swing(V) Toggle: On, Ion: On, Econo: -, Clean: Off";
|
||||
@ -1253,9 +1306,9 @@ TEST(TestIRac, Sharp) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Tcl112) {
|
||||
IRTcl112Ac ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRTcl112Ac ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 3 (Medium), Econo: On, "
|
||||
"Health: On, Light: On, Turbo: Off, Swing(H): On, Swing(V): Off";
|
||||
@ -1283,9 +1336,9 @@ TEST(TestIRac, Tcl112) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Teco) {
|
||||
IRTecoAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRTecoAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 0 (Auto), Temp: 21C, Fan: 2 (Medium), Sleep: On, "
|
||||
"Swing: On, Light: On, Humid: Off, Save: Off, Timer: Off";
|
||||
@ -1310,31 +1363,82 @@ TEST(TestIRac, Teco) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Toshiba) {
|
||||
IRToshibaAC ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
char expected[] = "Power: On, Mode: 2 (Dry), Temp: 29C, Fan: 2 (UNKNOWN)";
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Temp: 29C, Power: On, Mode: 2 (Dry), Fan: 2 (UNKNOWN), "
|
||||
"Turbo: Off, Econo: On";
|
||||
|
||||
ac.begin();
|
||||
irac.toshiba(&ac,
|
||||
true, // Power
|
||||
stdAc::opmode_t::kDry, // Mode
|
||||
29, // Celsius
|
||||
stdAc::fanspeed_t::kLow); // Fan speed
|
||||
stdAc::fanspeed_t::kLow, // Fan speed
|
||||
stdAc::swingv_t::kOff, // Vertical Swing
|
||||
false, // Turbo
|
||||
true); // Econo
|
||||
ASSERT_EQ(expected, ac.toString());
|
||||
ASSERT_EQ(kToshibaACStateLengthLong, ac.getStateLength());
|
||||
ac._irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
|
||||
ASSERT_EQ(TOSHIBA_AC, ac._irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(kToshibaACBitsLong, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600"
|
||||
"m580s1600m580s1600m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s1600m580s1600m580s490m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600"
|
||||
"m580s1600m580s1600m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s1600m580s1600m580s490m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490"
|
||||
"m580s490m580s490m580s1600m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s1600m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490"
|
||||
"m580s490m580s490m580s1600m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s1600m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s7400",
|
||||
ac._irsend.outputStr());
|
||||
}
|
||||
|
||||
TEST(TestIRac, Trotec) {
|
||||
IRTrotecESP ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRTrotecESP ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 18C, Fan: 3 (High), Sleep: On";
|
||||
|
||||
@ -1361,9 +1465,9 @@ TEST(TestIRac, Trotec) {
|
||||
}
|
||||
|
||||
TEST(TestIRac, Vestel) {
|
||||
IRVestelAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRVestelAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 0 (Auto), Temp: 22C, Fan: 5 (Low), Sleep: On, "
|
||||
"Turbo: Off, Ion: On, Swing: On";
|
||||
@ -1452,9 +1556,9 @@ TEST(TestIRac, Vestel) {
|
||||
|
||||
|
||||
TEST(TestIRac, Whirlpool) {
|
||||
IRWhirlpoolAc ac(0);
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRWhirlpoolAc ac(kGpioUnused);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Model: 1 (DG11J13A), Power Toggle: On, Mode: 1 (Auto), Temp: 21C, "
|
||||
"Fan: 3 (Low), Swing: On, Light: On, Clock: 23:58, On Timer: Off, "
|
||||
@ -1755,9 +1859,9 @@ TEST(TestIRac, Issue821) {
|
||||
next = prev;
|
||||
next.light = true;
|
||||
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRCoolixAC ac(0);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
IRCoolixAC ac(kGpioUnused);
|
||||
|
||||
ac.begin();
|
||||
result = irac.handleToggles(next, &prev);
|
||||
@ -1844,9 +1948,9 @@ TEST(TestIRac, Issue1001) {
|
||||
desired = prev;
|
||||
desired.power = false;
|
||||
|
||||
IRac irac(0);
|
||||
IRrecv capture(0);
|
||||
IRWhirlpoolAc ac(0);
|
||||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
IRWhirlpoolAc ac(kGpioUnused);
|
||||
|
||||
ac.begin();
|
||||
ASSERT_TRUE(prev.power);
|
||||
|
@ -220,32 +220,32 @@ TEST(TestResultToSourceCode, ComplexProtocols) {
|
||||
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"uint16_t rawData[296] = {4400, 4300, 542, 1622, 542, 1622, "
|
||||
"542, 1622, 542, 1622, 542, 472, 542, 472, 542, 1622, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, "
|
||||
"542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 1622, 542, 1622, 542, 1622, 542, 1622, "
|
||||
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 1622, 542, 7048, 4400, 4300, "
|
||||
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, "
|
||||
"542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 1622, 542, 1622, 542, 472, 542, 1622, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, "
|
||||
"542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 1622, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, "
|
||||
"542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, "
|
||||
"542, 7048 }; // TOSHIBA_AC\n"
|
||||
"uint16_t rawData[296] = {4400, 4300, 580, 1600, 580, 1600, "
|
||||
"580, 1600, 580, 1600, 580, 490, 580, 490, 580, 1600, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, 580, 1600, "
|
||||
"580, 490, 580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 1600, 580, 1600, 580, 1600, 580, 1600, "
|
||||
"580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 1600, 580, 7400, 4400, 4300, "
|
||||
"580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 490, 580, 490, "
|
||||
"580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 1600, 580, 1600, 580, 490, 580, 1600, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, 580, 1600, "
|
||||
"580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 1600, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 1600, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, "
|
||||
"580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, "
|
||||
"580, 7400 }; // TOSHIBA_AC\n"
|
||||
"uint8_t state[9] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, "
|
||||
"0x01};\n",
|
||||
resultToSourceCode(&irsend.capture));
|
||||
@ -744,3 +744,35 @@ TEST(TestUtils, setBits64Bit) {
|
||||
irutils::setBits(&data, 32, 4, 0b1001);
|
||||
EXPECT_EQ(0x4000000900000013, data);
|
||||
}
|
||||
|
||||
TEST(TestUtils, InvertedBytePairs) {
|
||||
const uint8_t correct[] = {0x00, 0xFF, 0x01, 0xFE, 0xAA, 0x55};
|
||||
uint8_t wrong[] = {0x00, 0xFF, 0x01, 0xFD, 0xAA, 0x55};
|
||||
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 6));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 5));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 4));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 3));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 2));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 1));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 0));
|
||||
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6));
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 5));
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 4));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 3));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 2));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 1));
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 0));
|
||||
|
||||
irutils::invertBytePairs(wrong, 0);
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6));
|
||||
irutils::invertBytePairs(wrong, 1);
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6));
|
||||
irutils::invertBytePairs(wrong, 2);
|
||||
ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6));
|
||||
|
||||
irutils::invertBytePairs(wrong, 6);
|
||||
ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 6));
|
||||
EXPECT_STATE_EQ(correct, wrong, 6 * 8);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Copyright 2020 David Conran
|
||||
|
||||
#include "ir_Airwell.h"
|
||||
#include "IRac.h"
|
||||
#include "IRrecv.h"
|
||||
#include "IRrecv_test.h"
|
||||
@ -44,6 +45,9 @@ TEST(TestDecodeAirwell, RealExample) {
|
||||
EXPECT_EQ(0x2B0D0181B, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: On, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 25C",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
|
||||
const uint16_t rawData_2[175] = {
|
||||
2862, 3892,
|
||||
@ -76,6 +80,9 @@ TEST(TestDecodeAirwell, RealExample) {
|
||||
EXPECT_EQ(0x270F8181B, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: On, Mode: 1 (Cool), Fan: 3 (Auto), Temp: 30C",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
}
|
||||
|
||||
TEST(TestDecodeAirwell, SyntheticExample) {
|
||||
@ -192,6 +199,9 @@ TEST(TestDecodeAirwell, RealExample2) {
|
||||
EXPECT_EQ(0xB0C0181B, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: Off, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 23C",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
|
||||
// Resend it as a synthetic to see if it decodes to the same value.
|
||||
irsend.reset();
|
||||
@ -210,7 +220,7 @@ TEST(TestUtils, Housekeeping) {
|
||||
ASSERT_EQ("AIRWELL", typeToString(decode_type_t::AIRWELL));
|
||||
ASSERT_EQ(decode_type_t::AIRWELL, strToDecodeType("AIRWELL"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::AIRWELL));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::AIRWELL));
|
||||
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::AIRWELL));
|
||||
ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL));
|
||||
ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL));
|
||||
}
|
||||
@ -250,4 +260,142 @@ TEST(TestDecodeAirwell, RealExample3) {
|
||||
EXPECT_EQ(0x60080002, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: Off, Mode: 1 (Cool), Fan: 2 (High), Temp: 16C",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
}
|
||||
|
||||
// Tests for IRAirwellAc class.
|
||||
|
||||
TEST(TestAirwellAcClass, PowerToggle) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setPowerToggle(true);
|
||||
EXPECT_TRUE(ac.getPowerToggle());
|
||||
ac.setPowerToggle(false);
|
||||
EXPECT_FALSE(ac.getPowerToggle());
|
||||
ac.setPowerToggle(true);
|
||||
EXPECT_TRUE(ac.getPowerToggle());
|
||||
}
|
||||
|
||||
TEST(TestAirwellAcClass, Temperature) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setTemp(0);
|
||||
EXPECT_EQ(kAirwellMinTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(255);
|
||||
EXPECT_EQ(kAirwellMaxTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(kAirwellMinTemp);
|
||||
EXPECT_EQ(kAirwellMinTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(kAirwellMaxTemp);
|
||||
EXPECT_EQ(kAirwellMaxTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(kAirwellMinTemp - 1);
|
||||
EXPECT_EQ(kAirwellMinTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(kAirwellMaxTemp + 1);
|
||||
EXPECT_EQ(kAirwellMaxTemp, ac.getTemp());
|
||||
|
||||
ac.setTemp(17);
|
||||
EXPECT_EQ(17, ac.getTemp());
|
||||
|
||||
ac.setTemp(21);
|
||||
EXPECT_EQ(21, ac.getTemp());
|
||||
|
||||
ac.setTemp(25);
|
||||
EXPECT_EQ(25, ac.getTemp());
|
||||
|
||||
ac.setTemp(29);
|
||||
EXPECT_EQ(29, ac.getTemp());
|
||||
}
|
||||
|
||||
TEST(TestAirwellAcClass, OperatingMode) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setMode(kAirwellAuto);
|
||||
EXPECT_EQ(kAirwellAuto, ac.getMode());
|
||||
|
||||
ac.setMode(kAirwellCool);
|
||||
EXPECT_EQ(kAirwellCool, ac.getMode());
|
||||
|
||||
ac.setMode(kAirwellHeat);
|
||||
EXPECT_EQ(kAirwellHeat, ac.getMode());
|
||||
|
||||
ac.setMode(kAirwellDry);
|
||||
EXPECT_EQ(kAirwellDry, ac.getMode());
|
||||
|
||||
ac.setMode(kAirwellFan);
|
||||
EXPECT_EQ(kAirwellFan, ac.getMode());
|
||||
|
||||
ac.setMode(kAirwellFan + 1);
|
||||
EXPECT_EQ(kAirwellAuto, ac.getMode());
|
||||
|
||||
ac.setMode(255);
|
||||
EXPECT_EQ(kAirwellAuto, ac.getMode());
|
||||
}
|
||||
|
||||
TEST(TestAirwellAcClass, FanSpeed) {
|
||||
IRAirwellAc ac(0);
|
||||
ac.begin();
|
||||
|
||||
ac.setFan(0);
|
||||
EXPECT_EQ(kAirwellFanLow, ac.getFan());
|
||||
|
||||
ac.setFan(255);
|
||||
EXPECT_EQ(kAirwellFanAuto, ac.getFan());
|
||||
|
||||
ac.setFan(kAirwellFanHigh);
|
||||
EXPECT_EQ(kAirwellFanHigh, ac.getFan());
|
||||
|
||||
ac.setFan(kAirwellFanHigh + 2);
|
||||
EXPECT_EQ(kAirwellFanAuto, ac.getFan());
|
||||
|
||||
ac.setFan(kAirwellFanHigh - 1);
|
||||
EXPECT_EQ(kAirwellFanHigh - 1, ac.getFan());
|
||||
|
||||
ac.setFan(1);
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
|
||||
ac.setFan(1);
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
|
||||
ac.setFan(3);
|
||||
EXPECT_EQ(3, ac.getFan());
|
||||
}
|
||||
|
||||
// Test human readable output.
|
||||
TEST(TestAirwellAcClass, HumanReadable) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: Off, Mode: 5 (Fan), Fan: 0 (Low), Temp: 25C",
|
||||
ac.toString());
|
||||
ac.setPowerToggle(true);
|
||||
ac.setMode(kAirwellHeat);
|
||||
ac.setTemp(30);
|
||||
ac.setFan(kAirwellFanAuto);
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: On, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 30C",
|
||||
ac.toString());
|
||||
}
|
||||
|
||||
TEST(TestAirwellAcClass, ReconstructKnownState) {
|
||||
IRAirwellAc ac(kGpioUnused);
|
||||
const uint64_t expected = 0x240380002;
|
||||
ac.begin();
|
||||
ac.stateReset();
|
||||
ASSERT_NE(expected, ac.getRaw());
|
||||
ac.setPowerToggle(true);
|
||||
ac.setMode(kAirwellCool);
|
||||
ac.setTemp(22);
|
||||
ac.setFan(kAirwellFanLow);
|
||||
EXPECT_EQ(expected, ac.getRaw());
|
||||
EXPECT_EQ(
|
||||
"Power Toggle: On, Mode: 1 (Cool), Fan: 0 (Low), Temp: 22C",
|
||||
ac.toString());
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ TEST(TestDecodeLG, Issue620) {
|
||||
|
||||
// Resend the same code as the report is a sent code doesn't decode
|
||||
// to the same message code.
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
irsend.sendLG(0x8808721);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
@ -477,7 +477,7 @@ TEST(TestDecodeLG, Issue620) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, SetAndGetPower) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.on();
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
ac.off();
|
||||
@ -489,7 +489,7 @@ TEST(TestIRLgAcClass, SetAndGetPower) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, SetAndGetTemp) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setTemp(25);
|
||||
EXPECT_EQ(25, ac.getTemp());
|
||||
ac.setTemp(kLgAcMinTemp);
|
||||
@ -503,7 +503,7 @@ TEST(TestIRLgAcClass, SetAndGetTemp) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, SetAndGetMode) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setMode(kLgAcCool);
|
||||
ac.setFan(kLgAcFanAuto);
|
||||
ac.setTemp(25);
|
||||
@ -517,22 +517,22 @@ TEST(TestIRLgAcClass, SetAndGetMode) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, SetAndGetFan) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setMode(kLgAcCool);
|
||||
ac.setFan(kLgAcFanAuto);
|
||||
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
|
||||
ac.setFan(kLgAcFanLow);
|
||||
EXPECT_EQ(kLgAcFanLow, ac.getFan());
|
||||
ac.setFan(kLgAcFanLowest);
|
||||
EXPECT_EQ(kLgAcFanLowest, ac.getFan());
|
||||
ac.setFan(kLgAcFanHigh);
|
||||
EXPECT_EQ(kLgAcFanHigh, ac.getFan());
|
||||
ac.setFan(kLgAcFanAuto + 1);
|
||||
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
|
||||
ac.setFan(kLgAcFanLow - 1);
|
||||
ac.setFan(kLgAcFanLowest - 1);
|
||||
EXPECT_EQ(kLgAcFanAuto, ac.getFan());
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, toCommon) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setPower(true);
|
||||
ac.setMode(kLgAcCool);
|
||||
ac.setTemp(20);
|
||||
@ -564,7 +564,7 @@ TEST(TestIRLgAcClass, toCommon) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, HumanReadable) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
@ -583,17 +583,17 @@ TEST(TestIRLgAcClass, HumanReadable) {
|
||||
ac.setTemp(kLgAcMinTemp);
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)",
|
||||
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 1 (Low)",
|
||||
ac.toString());
|
||||
ac.setTemp(ac.getTemp() + 1);
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 0 (Cool), Temp: 17C, Fan: 0 (Low)",
|
||||
"Power: On, Mode: 0 (Cool), Temp: 17C, Fan: 1 (Low)",
|
||||
ac.toString());
|
||||
ac.setTemp(ac.getTemp() - 1);
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)",
|
||||
"Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 1 (Low)",
|
||||
ac.toString());
|
||||
ac.setPower(false);
|
||||
EXPECT_EQ(
|
||||
@ -603,7 +603,7 @@ TEST(TestIRLgAcClass, HumanReadable) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, SetAndGetRaw) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
|
||||
ac.setRaw(0x8800A4E);
|
||||
ASSERT_EQ(0x8800A4E, ac.getRaw());
|
||||
@ -621,7 +621,7 @@ TEST(TestIRLgAcClass, SetAndGetRaw) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, MessageConstruction) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
|
||||
ac.on();
|
||||
ac.setMode(kLgAcCool);
|
||||
@ -635,7 +635,7 @@ TEST(TestIRLgAcClass, MessageConstruction) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, isValidLgAc) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
|
||||
ac.setRaw(0x8800A4E);
|
||||
ASSERT_TRUE(ac.isValidLgAc());
|
||||
@ -670,7 +670,7 @@ TEST(TestUtils, Housekeeping) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, KnownExamples) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
// Ref:
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1008#issuecomment-570646648
|
||||
|
||||
@ -694,7 +694,7 @@ TEST(TestIRLgAcClass, KnownExamples) {
|
||||
ASSERT_TRUE(ac.isValidLgAc());
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 1 (Dry), Temp: 21C, Fan: 0 (Low)",
|
||||
"Power: On, Mode: 1 (Dry), Temp: 21C, Fan: 0 (Quiet)",
|
||||
ac.toString());
|
||||
|
||||
ac.setRaw(0x880C758);
|
||||
@ -716,7 +716,7 @@ TEST(TestIRLgAcClass, KnownExamples) {
|
||||
ASSERT_TRUE(ac.isValidLgAc());
|
||||
EXPECT_EQ(
|
||||
"Model: 1 (GE6711AR2853M), "
|
||||
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 0 (Low)",
|
||||
"Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 0 (Quiet)",
|
||||
ac.toString());
|
||||
|
||||
ac.setRaw(0x8808721);
|
||||
@ -816,7 +816,7 @@ TEST(TestDecodeLG2, Issue1008) {
|
||||
EXPECT_EQ(0x8800347, irsend.capture.value);
|
||||
|
||||
irsend.reset();
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
ac.setRaw(0x8800347);
|
||||
ac.setModel(lg_ac_remote_model_t::AKB75215403); // aka. 2
|
||||
ac.send();
|
||||
@ -835,7 +835,7 @@ TEST(TestDecodeLG2, Issue1008) {
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, DifferentModels) {
|
||||
IRLgAc ac(0);
|
||||
IRLgAc ac(kGpioUnused);
|
||||
IRrecv capture(0);
|
||||
|
||||
ac.setRaw(0x8800347);
|
||||
@ -872,3 +872,12 @@ TEST(TestIRLgAcClass, DifferentModels) {
|
||||
ASSERT_EQ(expected2, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestIRLgAcClass, FanSpeedIssue1214) {
|
||||
EXPECT_EQ(kLgAcFanLowest, IRLgAc::convertFan(stdAc::fanspeed_t::kMin));
|
||||
EXPECT_EQ(kLgAcFanLow, IRLgAc::convertFan(stdAc::fanspeed_t::kLow));
|
||||
EXPECT_EQ(kLgAcFanMedium, IRLgAc::convertFan(stdAc::fanspeed_t::kMedium));
|
||||
EXPECT_EQ(kLgAcFanHigh, IRLgAc::convertFan(stdAc::fanspeed_t::kHigh));
|
||||
EXPECT_EQ(kLgAcFanHigh, IRLgAc::convertFan(stdAc::fanspeed_t::kMax));
|
||||
EXPECT_EQ(kLgAcFanAuto, IRLgAc::convertFan(stdAc::fanspeed_t::kAuto));
|
||||
}
|
||||
|
@ -441,13 +441,13 @@ TEST(TestMideaACClass, Sleep) {
|
||||
}
|
||||
|
||||
TEST(TestMideaACClass, HumanReadableOutput) {
|
||||
IRMideaAC ac(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setRaw(0xA1826FFFFF62);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.off();
|
||||
ac.setTemp(25, true);
|
||||
ac.setFan(kMideaACFanHigh);
|
||||
@ -455,16 +455,16 @@ TEST(TestMideaACClass, HumanReadableOutput) {
|
||||
ac.setSleep(true);
|
||||
EXPECT_EQ(
|
||||
"Power: Off, Mode: 1 (Dry), Celsius: Off, Temp: 25C/77F, Fan: 3 (High), "
|
||||
"Sleep: On, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.setUseCelsius(true);
|
||||
EXPECT_EQ(
|
||||
"Power: Off, Mode: 1 (Dry), Celsius: On, Temp: 25C/77F, Fan: 3 (High), "
|
||||
"Sleep: On, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
|
||||
ac.setRaw(0xA19867FFFF7E);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 0 (Cool), Celsius: Off, Temp: 21C/69F, Fan: 3 (High), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
}
|
||||
|
||||
// Tests for decodeMidea().
|
||||
@ -672,14 +672,14 @@ TEST(TestDecodeMidea, DecodeRealExample) {
|
||||
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 18C/65F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off",
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
TEST(TestMideaACClass, toCommon) {
|
||||
IRMideaAC ac(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
ac.setPower(true);
|
||||
ac.setMode(kMideaACCool);
|
||||
ac.setUseCelsius(true);
|
||||
@ -709,7 +709,7 @@ TEST(TestMideaACClass, toCommon) {
|
||||
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/819
|
||||
TEST(TestMideaACClass, CelsiusRemoteTemp) {
|
||||
IRMideaAC ac(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
uint64_t on_cool_low_17c = 0xA18840FFFF56;
|
||||
uint64_t on_cool_low_30c = 0xA1884DFFFF5D;
|
||||
ac.on();
|
||||
@ -722,13 +722,13 @@ TEST(TestMideaACClass, CelsiusRemoteTemp) {
|
||||
EXPECT_EQ(on_cool_low_17c, ac.getRaw());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.setRaw(on_cool_low_17c);
|
||||
EXPECT_EQ(17, ac.getTemp(true));
|
||||
EXPECT_EQ(62, ac.getTemp(false));
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.setTemp(17, true);
|
||||
EXPECT_EQ(17, ac.getTemp(true));
|
||||
EXPECT_EQ(62, ac.getTemp(false));
|
||||
@ -737,26 +737,45 @@ TEST(TestMideaACClass, CelsiusRemoteTemp) {
|
||||
ac.setRaw(on_cool_low_30c);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 0 (Cool), Celsius: On, Temp: 30C/86F, Fan: 1 (Low), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
}
|
||||
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/819
|
||||
TEST(TestMideaACClass, SwingV) {
|
||||
IRMideaAC ac(0);
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
ac.setSwingVToggle(false);
|
||||
ASSERT_FALSE(ac.getSwingVToggle());
|
||||
ac.setSwingVToggle(true);
|
||||
ASSERT_TRUE(ac.getSwingVToggle());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: On", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: On, Econo Toggle: Off", ac.toString());
|
||||
ac.setSwingVToggle(false);
|
||||
ASSERT_FALSE(ac.getSwingVToggle());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off", ac.toString());
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.setRaw(kMideaACToggleSwingV);
|
||||
EXPECT_EQ("Swing(V) Toggle: On", ac.toString());
|
||||
EXPECT_EQ("Swing(V) Toggle: On, Econo Toggle: Off", ac.toString());
|
||||
}
|
||||
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/pull/1213
|
||||
TEST(TestMideaACClass, Econo) {
|
||||
IRMideaAC ac(kGpioUnused);
|
||||
ac.setEconoToggle(false);
|
||||
ASSERT_FALSE(ac.getEconoToggle());
|
||||
ac.setEconoToggle(true);
|
||||
ASSERT_TRUE(ac.getEconoToggle());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: On", ac.toString());
|
||||
ac.setEconoToggle(false);
|
||||
ASSERT_FALSE(ac.getEconoToggle());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), "
|
||||
"Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString());
|
||||
ac.setRaw(kMideaACToggleEcono);
|
||||
EXPECT_EQ("Swing(V) Toggle: Off, Econo Toggle: On", ac.toString());
|
||||
}
|
||||
|
||||
// Test abusing the protocol for sending 6 arbitary bytes.
|
||||
|
@ -14,34 +14,34 @@ TEST(TestSendPioneer, SendDataOnly) {
|
||||
irsend.sendPioneer(0);
|
||||
EXPECT_EQ(
|
||||
"f40000d33"
|
||||
"m8544s4272"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s37380"
|
||||
"m8544s4272"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s37380",
|
||||
"m8506s4191"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s37881"
|
||||
"m8506s4191"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s37881",
|
||||
irsend.outputStr());
|
||||
irsend.sendPioneer(0x55FF00AAAA00FF55);
|
||||
EXPECT_EQ(
|
||||
"f40000d33"
|
||||
"m8544s4272"
|
||||
"m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602"
|
||||
"m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534"
|
||||
"m534s25098"
|
||||
"m8544s4272"
|
||||
"m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534"
|
||||
"m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534"
|
||||
"m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602"
|
||||
"m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602"
|
||||
"m534s25098",
|
||||
"m8506s4191"
|
||||
"m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542"
|
||||
"m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487"
|
||||
"m568s25181"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487"
|
||||
"m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542"
|
||||
"m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542"
|
||||
"m568s25181",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
@ -139,17 +139,91 @@ TEST(TestDecodePioneer, SyntheticPioneerMessage) {
|
||||
irsend.sendPioneer(0x659A857AF50A3DC2, 64, 0);
|
||||
EXPECT_EQ(
|
||||
"f40000d33"
|
||||
"m8544s4272"
|
||||
"m534s534m534s1602m534s1602m534s534m534s534m534s1602m534s534m534s1602"
|
||||
"m534s1602m534s534m534s534m534s1602m534s1602m534s534m534s1602m534s534"
|
||||
"m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602"
|
||||
"m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534"
|
||||
"m534s25098"
|
||||
"m8544s4272"
|
||||
"m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534m534s1602"
|
||||
"m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602m534s534"
|
||||
"m534s534m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602"
|
||||
"m534s1602m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534"
|
||||
"m534s25098",
|
||||
"m8506s4191"
|
||||
"m568s487m568s1542m568s1542m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s1542m568s487m568s487m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s1542m568s487m568s487m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s1542m568s1542m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s25181"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s1542m568s1542m568s1542m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s487m568s487m568s487m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s1542m568s1542m568s1542m568s1542m568s487m568s1542"
|
||||
"m568s1542m568s1542m568s487m568s487m568s487m568s487m568s1542m568s487"
|
||||
"m568s25181",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1220#issuecomment-661598412
|
||||
TEST(TestDecodePioneer, Issue1220) {
|
||||
IRsendTest irsend(0);
|
||||
IRrecv irrecv(0);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Pwr Toggle {"IrReceived":{"Protocol":"PIONEER","Bits":64,
|
||||
// "Data":"0xA55A38C7A55A38C7"}}
|
||||
const uint16_t rawPowerToggle[203] = {
|
||||
8510, 4188, 580, 1544, 556, 470, 582, 1566, 556, 494, 560, 488, 556, 1542,
|
||||
580, 470, 584, 1540, 582, 492, 552, 1522, 578, 496, 558, 1564, 558, 1542,
|
||||
580, 470, 586, 1564, 536, 512, 532, 494, 560, 464, 582, 1542, 580, 1544,
|
||||
578, 1544, 578, 498, 558, 492, 562, 488, 556, 1518, 582, 1542, 582, 492,
|
||||
552, 498, 556, 494, 550, 1572, 560, 1538, 562, 1536, 586, 25188,
|
||||
8512, 4186, 584, 1540, 584, 468, 576, 1572, 528, 522, 532, 492, 552, 1546,
|
||||
584, 492, 550, 1548, 582, 494, 560, 1538, 580, 468, 586, 1514, 586, 1538,
|
||||
584, 490, 554, 1546, 586, 488, 554, 470, 584, 490, 556, 1542, 556, 1542,
|
||||
580, 1544, 578, 496, 560, 466, 578, 496, 560, 1538, 584, 1516, 584, 490,
|
||||
554, 472, 582, 492, 552, 1546, 586, 1536, 586, 1538, 586, 25162,
|
||||
8514, 4184, 582, 1542, 580, 496, 562, 1536, 584, 490, 554, 496, 560, 1538,
|
||||
562, 514, 530, 1542, 580, 496, 560, 1538, 584, 466, 578, 1546, 576, 1524,
|
||||
578, 496, 558, 1542, 586, 488, 554, 496, 558, 466, 576, 1546, 576, 1548,
|
||||
586, 1512, 578, 498, 558, 492, 552, 496, 558, 1540, 580, 1542, 578, 498,
|
||||
556, 494, 550, 498, 556, 1516, 584, 1540, 584, 1540, 580};
|
||||
irsend.sendRaw(rawPowerToggle, 203, 40); // Pioneer uses 40kHz
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0xA55A38C7A55A38C7, irsend.capture.value);
|
||||
EXPECT_EQ(0xA51C, irsend.capture.address);
|
||||
EXPECT_EQ(0xA51C, irsend.capture.command);
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendPioneer(0xA55A38C7A55A38C7, 64, 1);
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(PIONEER, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kPioneerBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0xA55A38C7A55A38C7, irsend.capture.value);
|
||||
EXPECT_EQ(0xA51C, irsend.capture.address);
|
||||
EXPECT_EQ(0xA51C, irsend.capture.command);
|
||||
EXPECT_EQ(
|
||||
"f40000d33"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487"
|
||||
"m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542"
|
||||
"m568s25181"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487"
|
||||
"m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542"
|
||||
"m568s25181"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487"
|
||||
"m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542"
|
||||
"m568s25181"
|
||||
"m8506s4191"
|
||||
"m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542"
|
||||
"m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487"
|
||||
"m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487"
|
||||
"m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542"
|
||||
"m568s25181",
|
||||
irsend.outputStr());
|
||||
|
||||
EXPECT_EQ(0xA55A38C7A55A38C7, irsend.encodePioneer(0xA51C, 0xA51C));
|
||||
}
|
||||
|
@ -12,8 +12,10 @@
|
||||
|
||||
// General housekeeping
|
||||
TEST(TestSamsung, Housekeeping) {
|
||||
ASSERT_EQ("SAMSUNG", typeToString(SAMSUNG));
|
||||
ASSERT_FALSE(hasACState(SAMSUNG));
|
||||
ASSERT_EQ("SAMSUNG", typeToString(decode_type_t::SAMSUNG));
|
||||
ASSERT_EQ(decode_type_t::SAMSUNG, strToDecodeType("SAMSUNG"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::SAMSUNG));
|
||||
ASSERT_EQ(kSamsungBits, IRsend::defaultBits(decode_type_t::SAMSUNG));
|
||||
}
|
||||
|
||||
// Tests for sendSAMSUNG().
|
||||
@ -307,8 +309,12 @@ TEST(TestDecodeSamsung, FailToDecodeNonSamsungExample) {
|
||||
|
||||
// General housekeeping
|
||||
TEST(TestSamsungAC, Housekeeping) {
|
||||
ASSERT_EQ("SAMSUNG_AC", typeToString(SAMSUNG_AC));
|
||||
ASSERT_TRUE(hasACState(SAMSUNG_AC));
|
||||
ASSERT_EQ("SAMSUNG_AC", typeToString(decode_type_t::SAMSUNG_AC));
|
||||
ASSERT_EQ(decode_type_t::SAMSUNG_AC, strToDecodeType("SAMSUNG_AC"));
|
||||
ASSERT_TRUE(hasACState(decode_type_t::SAMSUNG_AC));
|
||||
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::SAMSUNG_AC));
|
||||
ASSERT_EQ(kSamsungAcBits, IRsend::defaultBits(decode_type_t::SAMSUNG_AC));
|
||||
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SAMSUNG_AC));
|
||||
}
|
||||
|
||||
// Tests for sendSamsungAC().
|
||||
@ -1143,34 +1149,36 @@ TEST(TestSendSamsung36, SendDataOnly) {
|
||||
irsend.sendSamsung36(0);
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560"
|
||||
"m560s26880",
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490"
|
||||
"m512s26880",
|
||||
irsend.outputStr());
|
||||
irsend.sendSamsung36(0x400E00FF);
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880",
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880",
|
||||
irsend.outputStr());
|
||||
irsend.reset();
|
||||
}
|
||||
|
||||
// General housekeeping
|
||||
TEST(TestSamsung36, Housekeeping) {
|
||||
ASSERT_EQ("SAMSUNG36", typeToString(SAMSUNG36));
|
||||
ASSERT_FALSE(hasACState(SAMSUNG36));
|
||||
ASSERT_EQ("SAMSUNG36", typeToString(decode_type_t::SAMSUNG36));
|
||||
ASSERT_EQ(decode_type_t::SAMSUNG36, strToDecodeType("SAMSUNG36"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::SAMSUNG36));
|
||||
ASSERT_EQ(kSamsung36Bits, IRsend::defaultBits(decode_type_t::SAMSUNG36));
|
||||
}
|
||||
|
||||
// Test sending with different repeats.
|
||||
@ -1182,50 +1190,50 @@ TEST(TestSendSamsung36, SendWithRepeats) {
|
||||
irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 1); // 1 repeat.
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880",
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880"
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880",
|
||||
irsend.outputStr());
|
||||
irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 2); // 2 repeats.
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880"
|
||||
"m4480s4480"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s4480"
|
||||
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
|
||||
"m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s1680m560s1680m560s1680m560s1680"
|
||||
"m560s26880",
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880"
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880"
|
||||
"m4515s4438"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s4438"
|
||||
"m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490"
|
||||
"m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s1468m512s1468m512s1468m512s1468"
|
||||
"m512s26880",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
// Copyright 2017 David Conran
|
||||
// Copyright 2017-2020 David Conran
|
||||
|
||||
#include "ir_Sanyo.h"
|
||||
#include "IRac.h"
|
||||
#include "IRrecv.h"
|
||||
#include "IRrecv_test.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRsend_test.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -257,3 +261,272 @@ TEST(TestDecodeSanyoLC7461, FailToDecodeNonSanyoLC7461Example) {
|
||||
irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits,
|
||||
false));
|
||||
}
|
||||
|
||||
TEST(TestUtils, Housekeeping) {
|
||||
// Sanyo LC7461
|
||||
ASSERT_EQ("SANYO_LC7461", typeToString(decode_type_t::SANYO_LC7461));
|
||||
ASSERT_EQ(decode_type_t::SANYO_LC7461, strToDecodeType("SANYO_LC7461"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::SANYO_LC7461));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::SANYO_LC7461));
|
||||
ASSERT_EQ(kSanyoLC7461Bits, IRsend::defaultBits(decode_type_t::SANYO_LC7461));
|
||||
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SANYO_LC7461));
|
||||
// Sanyo A/C
|
||||
ASSERT_EQ("SANYO_AC", typeToString(decode_type_t::SANYO_AC));
|
||||
ASSERT_EQ(decode_type_t::SANYO_AC, strToDecodeType("SANYO_AC"));
|
||||
ASSERT_TRUE(hasACState(decode_type_t::SANYO_AC));
|
||||
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::SANYO_AC));
|
||||
ASSERT_EQ(kSanyoAcBits, IRsend::defaultBits(decode_type_t::SANYO_AC));
|
||||
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SANYO_AC));
|
||||
}
|
||||
|
||||
TEST(TestDecodeSanyoAc, DecodeRealExamples) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
// Ref: "On" from https://github.com/crankyoldgit/IRremoteESP8266/issues/1211#issue-650997449
|
||||
const uint16_t rawData[148] = {
|
||||
8456, 4192,
|
||||
624, 448, 584, 1508, 608, 452, 580, 1512, 628, 452, 604, 1468, 560, 1552,
|
||||
600, 472, 584, 1532, 580, 472, 528, 516, 512, 540, 576, 1516, 628, 1472,
|
||||
612, 1508, 612, 452, 580, 1512, 628, 1468, 612, 1496, 632, 444, 580, 480,
|
||||
580, 476, 580, 1496, 564, 508, 576, 480, 576, 480, 580, 476, 584, 472,
|
||||
584, 468, 584, 480, 520, 512, 580, 480, 576, 480, 580, 476, 584, 472,
|
||||
584, 472, 528, 508, 524, 1568, 600, 480, 576, 480, 584, 1492, 560, 512,
|
||||
580, 1536, 576, 480, 580, 476, 580, 476, 528, 528, 524, 1568, 580, 476,
|
||||
584, 476, 580, 476, 580, 472, 528, 512, 520, 536, 576, 480, 580, 480,
|
||||
576, 480, 576, 476, 532, 528, 520, 512, 576, 480, 584, 476, 580, 476,
|
||||
580, 480, 576, 472, 528, 1548, 600, 480, 576, 480, 576, 1520, 592, 1496,
|
||||
600, 476, 580, 480, 576};
|
||||
const uint8_t expectedState[kSanyoAcStateLength] = {
|
||||
0x6A, 0x71, 0x47, 0x00, 0x20, 0x85, 0x00, 0x00, 0x32};
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
irsend.sendRaw(rawData, 148, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(SANYO_AC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kSanyoAcBits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Cool), Temp: 21C, Fan: 0 (Auto), "
|
||||
"Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, Sensor: Room, "
|
||||
"Sensor Temp: 11C, Off Timer: Off",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
}
|
||||
|
||||
TEST(TestDecodeSanyoAc, SyntheticSelfDecode) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
const uint8_t expectedState[kSanyoAcStateLength] = {
|
||||
0x6A, 0x71, 0x47, 0x00, 0x20, 0x85, 0x00, 0x00, 0x32};
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
irsend.sendSanyoAc(expectedState);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(SANYO_AC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kSanyoAcBits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 2 (Cool), Temp: 21C, Fan: 0 (Auto), "
|
||||
"Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, Sensor: Room, "
|
||||
"Sensor Temp: 11C, Off Timer: Off",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m8500s4200"
|
||||
"m500s550m500s1600m500s550m500s1600m500s550m500s1600m500s1600m500s550"
|
||||
"m500s1600m500s550m500s550m500s550m500s1600m500s1600m500s1600m500s550"
|
||||
"m500s1600m500s1600m500s1600m500s550m500s550m500s550m500s1600m500s550"
|
||||
"m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550"
|
||||
"m500s550m500s550m500s550m500s550m500s1600m500s550m500s550m500s1600"
|
||||
"m500s550m500s1600m500s550m500s550m500s550m500s550m500s1600m500s550"
|
||||
"m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550"
|
||||
"m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s1600"
|
||||
"m500s550m500s550m500s1600m500s1600m500s550m500s550"
|
||||
"m500s100000",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Tests for IRSanyoAc class.
|
||||
|
||||
TEST(TestSanyoAcClass, Power) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.on();
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
|
||||
ac.off();
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
|
||||
ac.setPower(true);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
|
||||
ac.setPower(false);
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, Temperature) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setTemp(0);
|
||||
EXPECT_EQ(kSanyoAcTempMin, ac.getTemp());
|
||||
|
||||
ac.setTemp(255);
|
||||
EXPECT_EQ(kSanyoAcTempMax, ac.getTemp());
|
||||
|
||||
ac.setTemp(kSanyoAcTempMin);
|
||||
EXPECT_EQ(kSanyoAcTempMin, ac.getTemp());
|
||||
|
||||
ac.setTemp(kSanyoAcTempMax);
|
||||
EXPECT_EQ(kSanyoAcTempMax, ac.getTemp());
|
||||
|
||||
ac.setTemp(kSanyoAcTempMin - 1);
|
||||
EXPECT_EQ(kSanyoAcTempMin, ac.getTemp());
|
||||
|
||||
ac.setTemp(kSanyoAcTempMax + 1);
|
||||
EXPECT_EQ(kSanyoAcTempMax, ac.getTemp());
|
||||
|
||||
ac.setTemp(17);
|
||||
EXPECT_EQ(17, ac.getTemp());
|
||||
|
||||
ac.setTemp(21);
|
||||
EXPECT_EQ(21, ac.getTemp());
|
||||
|
||||
ac.setTemp(25);
|
||||
EXPECT_EQ(25, ac.getTemp());
|
||||
|
||||
ac.setTemp(30);
|
||||
EXPECT_EQ(30, ac.getTemp());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, OperatingMode) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setMode(kSanyoAcAuto);
|
||||
EXPECT_EQ(kSanyoAcAuto, ac.getMode());
|
||||
|
||||
ac.setMode(kSanyoAcCool);
|
||||
EXPECT_EQ(kSanyoAcCool, ac.getMode());
|
||||
|
||||
ac.setMode(kSanyoAcHeat);
|
||||
EXPECT_EQ(kSanyoAcHeat, ac.getMode());
|
||||
|
||||
ac.setMode(kSanyoAcDry);
|
||||
EXPECT_EQ(kSanyoAcDry, ac.getMode());
|
||||
|
||||
ac.setMode(kSanyoAcAuto + 1);
|
||||
EXPECT_EQ(kSanyoAcAuto, ac.getMode());
|
||||
|
||||
ac.setMode(0);
|
||||
EXPECT_EQ(kSanyoAcAuto, ac.getMode());
|
||||
|
||||
ac.setMode(255);
|
||||
EXPECT_EQ(kSanyoAcAuto, ac.getMode());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, FanSpeed) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setFan(kSanyoAcFanAuto);
|
||||
EXPECT_EQ(kSanyoAcFanAuto, ac.getFan());
|
||||
|
||||
ac.setFan(kSanyoAcFanHigh);
|
||||
EXPECT_EQ(kSanyoAcFanHigh, ac.getFan());
|
||||
|
||||
ac.setFan(kSanyoAcFanLow);
|
||||
EXPECT_EQ(kSanyoAcFanLow, ac.getFan());
|
||||
|
||||
ac.setFan(kSanyoAcFanMedium);
|
||||
EXPECT_EQ(kSanyoAcFanMedium, ac.getFan());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, Sleep) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setSleep(true);
|
||||
EXPECT_TRUE(ac.getSleep());
|
||||
ac.setSleep(false);
|
||||
EXPECT_FALSE(ac.getSleep());
|
||||
ac.setSleep(true);
|
||||
EXPECT_TRUE(ac.getSleep());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, SwingV) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setSwingV(kSanyoAcSwingVAuto);
|
||||
EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV());
|
||||
|
||||
ac.setSwingV(kSanyoAcSwingVHigh);
|
||||
EXPECT_EQ(kSanyoAcSwingVHigh, ac.getSwingV());
|
||||
|
||||
ac.setSwingV(kSanyoAcSwingVLow);
|
||||
EXPECT_EQ(kSanyoAcSwingVLow, ac.getSwingV());
|
||||
|
||||
ac.setSwingV(kSanyoAcSwingVUpperMiddle);
|
||||
EXPECT_EQ(kSanyoAcSwingVUpperMiddle, ac.getSwingV());
|
||||
|
||||
ac.setSwingV(0);
|
||||
EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV());
|
||||
ac.setSwingV(255);
|
||||
EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, Timers) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setOffTimer(0);
|
||||
EXPECT_EQ(0, ac.getOffTimer());
|
||||
ac.setOffTimer(59);
|
||||
EXPECT_EQ(0, ac.getOffTimer());
|
||||
ac.setOffTimer(60);
|
||||
EXPECT_EQ(60, ac.getOffTimer());
|
||||
ac.setOffTimer(61);
|
||||
EXPECT_EQ(60, ac.getOffTimer());
|
||||
ac.setOffTimer(15 * 60 + 59);
|
||||
EXPECT_EQ(15 * 60, ac.getOffTimer());
|
||||
ac.setOffTimer(16 * 60);
|
||||
EXPECT_EQ(15 * 60, ac.getOffTimer());
|
||||
|
||||
const uint8_t offTimer2Hr[kSanyoAcStateLength] = {
|
||||
0x6A, 0x6D, 0x4F, 0x02, 0x14, 0x85, 0x00, 0x00, 0x4A};
|
||||
ac.setRaw(offTimer2Hr);
|
||||
EXPECT_EQ(2 * 60, ac.getOffTimer());
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 1 (Heat), Temp: 17C, Fan: 0 (Auto), "
|
||||
"Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, "
|
||||
"Sensor: Room, Sensor Temp: 19C, Off Timer: 02:00",
|
||||
ac.toString());
|
||||
}
|
||||
|
||||
TEST(TestSanyoAcClass, Beep) {
|
||||
IRSanyoAc ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
ac.setBeep(true);
|
||||
EXPECT_TRUE(ac.getBeep());
|
||||
ac.setBeep(false);
|
||||
EXPECT_FALSE(ac.getBeep());
|
||||
ac.setBeep(true);
|
||||
EXPECT_TRUE(ac.getBeep());
|
||||
|
||||
const uint8_t beep_off[kSanyoAcStateLength] = {
|
||||
0x6A, 0x6D, 0x11, 0x00, 0x10, 0x85, 0x00, 0x00, 0x33};
|
||||
ac.setRaw(beep_off);
|
||||
EXPECT_FALSE(ac.getBeep());
|
||||
const uint8_t beep_on[kSanyoAcStateLength] = {
|
||||
0x6A, 0x6E, 0x54, 0x00, 0x10, 0x83, 0x00, 0x00, 0x39};
|
||||
ac.setRaw(beep_on);
|
||||
EXPECT_TRUE(ac.getBeep());
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
// Test sending typical data only.
|
||||
TEST(TestSendToshibaAC, SendDataOnly) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
uint8_t toshiba_code[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
@ -21,33 +21,33 @@ TEST(TestSendToshibaAC, SendDataOnly) {
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048",
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Test sending with repeats.
|
||||
TEST(TestSendToshibaAC, SendWithRepeats) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
@ -58,16 +58,16 @@ TEST(TestSendToshibaAC, SendWithRepeats) {
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048",
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400",
|
||||
irsend.outputStr());
|
||||
|
||||
irsend.reset();
|
||||
@ -75,242 +75,200 @@ TEST(TestSendToshibaAC, SendWithRepeats) {
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Test sending atypical sizes.
|
||||
TEST(TestSendToshibaAC, SendUnexpectedSizes) {
|
||||
IRsendTest irsend(4);
|
||||
irsend.begin();
|
||||
|
||||
uint8_t toshiba_short_code[8] = {0x01, 0x02, 0x03, 0x04,
|
||||
0x05, 0x06, 0x07, 0x08};
|
||||
uint8_t toshiba_long_code[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x09, 0x0A};
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(toshiba_short_code, kToshibaACStateLength - 1);
|
||||
ASSERT_EQ("", irsend.outputStr());
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(toshiba_long_code, kToshibaACStateLength + 1);
|
||||
ASSERT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472"
|
||||
"m543s7048"
|
||||
"m4400s4300"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472"
|
||||
"m543s7048",
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s7400",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Tests for IRToshibaAC class.
|
||||
|
||||
TEST(TestToshibaACClass, Power) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
toshiba.on();
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
ac.on();
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
|
||||
toshiba.off();
|
||||
EXPECT_FALSE(toshiba.getPower());
|
||||
ac.off();
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
|
||||
toshiba.setPower(true);
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
ac.setPower(true);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
|
||||
toshiba.setPower(false);
|
||||
EXPECT_FALSE(toshiba.getPower());
|
||||
ac.setPower(false);
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, Temperature) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
toshiba.setTemp(0);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
|
||||
ac.setTemp(0);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(255);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
|
||||
ac.setTemp(255);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(kToshibaAcMinTemp);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
|
||||
ac.setTemp(kToshibaAcMinTemp);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(kToshibaAcMaxTemp);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
|
||||
ac.setTemp(kToshibaAcMaxTemp);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(kToshibaAcMinTemp - 1);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
|
||||
ac.setTemp(kToshibaAcMinTemp - 1);
|
||||
EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(kToshibaAcMaxTemp + 1);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp());
|
||||
ac.setTemp(kToshibaAcMaxTemp + 1);
|
||||
EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(17);
|
||||
EXPECT_EQ(17, toshiba.getTemp());
|
||||
ac.setTemp(17);
|
||||
EXPECT_EQ(17, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(21);
|
||||
EXPECT_EQ(21, toshiba.getTemp());
|
||||
ac.setTemp(21);
|
||||
EXPECT_EQ(21, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(25);
|
||||
EXPECT_EQ(25, toshiba.getTemp());
|
||||
ac.setTemp(25);
|
||||
EXPECT_EQ(25, ac.getTemp());
|
||||
|
||||
toshiba.setTemp(30);
|
||||
EXPECT_EQ(30, toshiba.getTemp());
|
||||
ac.setTemp(30);
|
||||
EXPECT_EQ(30, ac.getTemp());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, OperatingMode) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
toshiba.setMode(kToshibaAcAuto);
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcAuto);
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
|
||||
toshiba.setMode(kToshibaAcCool);
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcCool);
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
|
||||
toshiba.setMode(kToshibaAcHeat);
|
||||
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcHeat);
|
||||
EXPECT_EQ(kToshibaAcHeat, ac.getMode());
|
||||
|
||||
toshiba.setMode(kToshibaAcDry);
|
||||
EXPECT_EQ(kToshibaAcDry, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcDry);
|
||||
EXPECT_EQ(kToshibaAcDry, ac.getMode());
|
||||
|
||||
toshiba.setMode(kToshibaAcHeat + 1);
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcFan);
|
||||
EXPECT_EQ(kToshibaAcFan, ac.getMode());
|
||||
|
||||
toshiba.setMode(255);
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
ac.setMode(kToshibaAcFan + 1);
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
|
||||
// Setting the power off changes the underlying mode in the state to heat.
|
||||
toshiba.setPower(true);
|
||||
toshiba.setMode(kToshibaAcCool);
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode(true));
|
||||
toshiba.setPower(false);
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode(true));
|
||||
ac.setMode(255);
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
|
||||
// Setting the power off changes the underlying mode in the state to a special
|
||||
// off mode.
|
||||
ac.setPower(true);
|
||||
ac.setMode(kToshibaAcCool);
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
ac.setPower(false);
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, FanSpeed) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
toshiba.setFan(kToshibaAcFanAuto);
|
||||
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
|
||||
ac.setFan(kToshibaAcFanAuto);
|
||||
EXPECT_EQ(kToshibaAcFanAuto, ac.getFan());
|
||||
|
||||
toshiba.setFan(255);
|
||||
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
|
||||
ac.setFan(255);
|
||||
EXPECT_EQ(kToshibaAcFanMax, ac.getFan());
|
||||
|
||||
toshiba.setFan(kToshibaAcFanMax);
|
||||
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
|
||||
ac.setFan(kToshibaAcFanMax);
|
||||
EXPECT_EQ(kToshibaAcFanMax, ac.getFan());
|
||||
|
||||
toshiba.setFan(kToshibaAcFanMax - 1);
|
||||
EXPECT_EQ(kToshibaAcFanMax - 1, toshiba.getFan());
|
||||
ac.setFan(kToshibaAcFanMax - 1);
|
||||
EXPECT_EQ(kToshibaAcFanMax - 1, ac.getFan());
|
||||
|
||||
toshiba.setFan(1);
|
||||
EXPECT_EQ(1, toshiba.getFan());
|
||||
ac.setFan(1);
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
|
||||
toshiba.setFan(2);
|
||||
EXPECT_EQ(2, toshiba.getFan());
|
||||
ac.setFan(2);
|
||||
EXPECT_EQ(2, ac.getFan());
|
||||
|
||||
toshiba.setFan(3);
|
||||
EXPECT_EQ(3, toshiba.getFan());
|
||||
ac.setFan(3);
|
||||
EXPECT_EQ(3, ac.getFan());
|
||||
|
||||
toshiba.setFan(4);
|
||||
EXPECT_EQ(4, toshiba.getFan());
|
||||
ac.setFan(4);
|
||||
EXPECT_EQ(4, ac.getFan());
|
||||
|
||||
toshiba.setFan(kToshibaAcFanMax + 1);
|
||||
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
|
||||
ac.setFan(kToshibaAcFanMax + 1);
|
||||
EXPECT_EQ(kToshibaAcFanMax, ac.getFan());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, RawState) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
0x50, 0x00, 0x00, 0x51};
|
||||
uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0xC1, 0x00, 0xC0};
|
||||
|
||||
// Verify the starting state.
|
||||
EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits);
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
|
||||
EXPECT_STATE_EQ(initial_state, ac.getRaw(), kToshibaACBits);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, ac.getFan());
|
||||
|
||||
// Change some settings.
|
||||
toshiba.setMode(kToshibaAcCool);
|
||||
toshiba.setFan(kToshibaAcFanMax);
|
||||
toshiba.setTemp(kToshibaAcMinTemp);
|
||||
ac.setMode(kToshibaAcCool);
|
||||
ac.setFan(kToshibaAcFanMax);
|
||||
ac.setTemp(kToshibaAcMinTemp);
|
||||
// Verify those were set.
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp());
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanMax, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp());
|
||||
// Retrieve the modified state.
|
||||
EXPECT_STATE_EQ(modified_state, toshiba.getRaw(), kToshibaACBits);
|
||||
EXPECT_STATE_EQ(modified_state, ac.getRaw(), kToshibaACBits);
|
||||
|
||||
// Set it back to the initial state.
|
||||
toshiba.setRaw(initial_state);
|
||||
ac.setRaw(initial_state);
|
||||
|
||||
// Check the new state was set correctly.
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
|
||||
EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, ac.getFan());
|
||||
EXPECT_STATE_EQ(initial_state, ac.getRaw(), kToshibaACBits);
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, Checksums) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
@ -319,8 +277,8 @@ TEST(TestToshibaACClass, Checksums) {
|
||||
uint8_t invalid_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
EXPECT_EQ(0x01, toshiba.calcChecksum(initial_state));
|
||||
EXPECT_EQ(0xC0, toshiba.calcChecksum(modified_state));
|
||||
EXPECT_EQ(0x01, ac.calcChecksum(initial_state));
|
||||
EXPECT_EQ(0xC0, ac.calcChecksum(modified_state));
|
||||
// Check we can call it without instantiating the object.
|
||||
EXPECT_EQ(0x01, IRToshibaAC::calcChecksum(initial_state));
|
||||
// Use different lengths.
|
||||
@ -344,150 +302,69 @@ TEST(TestToshibaACClass, Checksums) {
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, HumanReadableOutput) {
|
||||
IRToshibaAC toshiba(0);
|
||||
toshiba.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01};
|
||||
uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
0x00, 0xC1, 0x00, 0xC0};
|
||||
|
||||
toshiba.setRaw(initial_state);
|
||||
EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)",
|
||||
toshiba.toString());
|
||||
toshiba.setRaw(modified_state);
|
||||
EXPECT_EQ("Power: On, Mode: 1 (Cool), Temp: 17C, Fan: 5 (High)",
|
||||
toshiba.toString());
|
||||
toshiba.off();
|
||||
toshiba.setTemp(25);
|
||||
toshiba.setFan(3);
|
||||
toshiba.setMode(kToshibaAcDry);
|
||||
EXPECT_EQ("Power: Off, Mode: 2 (Dry), Temp: 25C, Fan: 3 (Medium)",
|
||||
toshiba.toString());
|
||||
ac.setRaw(initial_state);
|
||||
EXPECT_EQ("Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), "
|
||||
"Turbo: Off, Econo: Off",
|
||||
ac.toString());
|
||||
ac.setRaw(modified_state);
|
||||
EXPECT_EQ("Temp: 17C, Power: On, Mode: 1 (Cool), Fan: 5 (High), "
|
||||
"Turbo: Off, Econo: Off",
|
||||
ac.toString());
|
||||
ac.setTemp(25);
|
||||
ac.setFan(3);
|
||||
ac.setMode(kToshibaAcDry);
|
||||
EXPECT_EQ("Temp: 25C, Power: On, Mode: 2 (Dry), Fan: 3 (Medium), "
|
||||
"Turbo: Off, Econo: Off",
|
||||
ac.toString());
|
||||
ac.off();
|
||||
EXPECT_EQ("Temp: 25C, Power: Off, Fan: 3 (Medium), Turbo: Off, Econo: Off",
|
||||
ac.toString());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, MessageConstuction) {
|
||||
IRToshibaAC toshiba(0);
|
||||
IRsendTest irsend(4);
|
||||
toshiba.begin();
|
||||
irsend.begin();
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.begin();
|
||||
|
||||
toshiba.setFan(1);
|
||||
toshiba.setMode(kToshibaAcCool);
|
||||
toshiba.setTemp(27);
|
||||
toshiba.on();
|
||||
ac.on();
|
||||
ac.setFan(1);
|
||||
ac.setMode(kToshibaAcCool);
|
||||
ac.setTemp(27);
|
||||
|
||||
// Check everything for kicks.
|
||||
EXPECT_EQ(1, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(27, toshiba.getTemp());
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(toshiba.getRaw());
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048",
|
||||
irsend.outputStr());
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
EXPECT_EQ(27, ac.getTemp());
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
|
||||
// Turn off the power and re-check.
|
||||
toshiba.setPower(false);
|
||||
ac.setPower(false);
|
||||
// Check everything for kicks.
|
||||
EXPECT_EQ(1, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(27, toshiba.getTemp());
|
||||
EXPECT_FALSE(toshiba.getPower());
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(toshiba.getRaw());
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472"
|
||||
"m543s7048"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472"
|
||||
"m543s7048",
|
||||
irsend.outputStr());
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
EXPECT_EQ(27, ac.getTemp());
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
|
||||
// Turn the power back on, and check nothing changed.
|
||||
toshiba.on();
|
||||
ac.on();
|
||||
|
||||
EXPECT_EQ(1, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
EXPECT_EQ(27, toshiba.getTemp());
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(toshiba.getRaw());
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048"
|
||||
"m4400s4300"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623"
|
||||
"m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623"
|
||||
"m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472"
|
||||
"m543s7048",
|
||||
irsend.outputStr());
|
||||
EXPECT_EQ(1, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
EXPECT_EQ(27, ac.getTemp());
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
}
|
||||
|
||||
// Decoding a message we entirely constructed based solely on a given state.
|
||||
TEST(TestDecodeToshibaAC, SyntheticExample) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
uint8_t expectedState[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01,
|
||||
@ -501,7 +378,8 @@ TEST(TestDecodeToshibaAC, SyntheticExample) {
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)",
|
||||
"Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: Off, "
|
||||
"Econo: Off",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
@ -510,9 +388,9 @@ TEST(TestDecodeToshibaAC, SyntheticExample) {
|
||||
// Test decoding against captures from a real Toshiba A/C remote.
|
||||
// Recorded by @mwildbolz
|
||||
TEST(TestDecodeToshibaAC, RealExamples) {
|
||||
IRToshibaAC toshiba(0);
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
uint16_t rawData1[295] = {
|
||||
@ -548,11 +426,11 @@ TEST(TestDecodeToshibaAC, RealExamples) {
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
toshiba.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
EXPECT_EQ(23, toshiba.getTemp());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcAuto, toshiba.getMode());
|
||||
ac.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(23, ac.getTemp());
|
||||
EXPECT_EQ(kToshibaAcFanAuto, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcAuto, ac.getMode());
|
||||
|
||||
uint16_t rawData2[295] = {
|
||||
4500, 4236, 636, 1520, 642, 1520, 640, 1520, 664, 1492, 642, 440,
|
||||
@ -587,11 +465,11 @@ TEST(TestDecodeToshibaAC, RealExamples) {
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
toshiba.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
EXPECT_EQ(17, toshiba.getTemp());
|
||||
EXPECT_EQ(3, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, toshiba.getMode());
|
||||
ac.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(17, ac.getTemp());
|
||||
EXPECT_EQ(3, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcCool, ac.getMode());
|
||||
|
||||
uint16_t rawData3[295] = {
|
||||
4474, 4262, 642, 1514, 642, 1520, 642, 1520, 642, 1514, 642, 438,
|
||||
@ -626,11 +504,11 @@ TEST(TestDecodeToshibaAC, RealExamples) {
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
toshiba.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(toshiba.getPower());
|
||||
EXPECT_EQ(24, toshiba.getTemp());
|
||||
EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan());
|
||||
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
|
||||
ac.setRaw(irsend.capture.state);
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(24, ac.getTemp());
|
||||
EXPECT_EQ(kToshibaAcFanMax, ac.getFan());
|
||||
EXPECT_EQ(kToshibaAcHeat, ac.getMode());
|
||||
|
||||
uint16_t rawData4[295] = {
|
||||
4474, 4262, 636, 1520, 640, 1520, 640, 1520, 638, 1518, 642, 438,
|
||||
@ -665,16 +543,10 @@ TEST(TestDecodeToshibaAC, RealExamples) {
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
|
||||
toshiba.setRaw(irsend.capture.state);
|
||||
EXPECT_FALSE(toshiba.getPower());
|
||||
EXPECT_EQ(22, toshiba.getTemp());
|
||||
EXPECT_EQ(4, toshiba.getFan());
|
||||
|
||||
// Confirming the quirky behaviour that the 'Power OFF' signal
|
||||
// sets the mode to heat.
|
||||
// The previous state the remote was in was 'AUTO' just prior to
|
||||
// sending the power off message.
|
||||
EXPECT_EQ(kToshibaAcHeat, toshiba.getMode());
|
||||
ac.setRaw(irsend.capture.state);
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
EXPECT_EQ(22, ac.getTemp());
|
||||
EXPECT_EQ(4, ac.getFan());
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, toCommon) {
|
||||
@ -704,3 +576,166 @@ TEST(TestToshibaACClass, toCommon) {
|
||||
ASSERT_EQ(-1, ac.toCommon().sleep);
|
||||
ASSERT_EQ(-1, ac.toCommon().clock);
|
||||
}
|
||||
|
||||
// Tests for CarrierAc2
|
||||
/// Decode a "real" long example message.
|
||||
TEST(TestDecodeToshibaAC, RealLongExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Data from:
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-650475434
|
||||
const uint16_t high_power_on[327] = {
|
||||
4424, 4320,
|
||||
582, 1574, 588, 1578, 582, 1574, 586, 1578, 586, 496, 582, 492, 586, 1576,
|
||||
586, 492, 586, 492, 588, 496, 584, 496, 584, 496, 584, 1626, 534, 1626,
|
||||
534, 494, 586, 1578, 582, 494, 586, 494, 586, 494, 588, 492, 586, 492,
|
||||
586, 1576, 586, 494, 588, 492, 588, 1574, 588, 1576, 584, 1578, 584, 1574,
|
||||
588, 1574, 588, 492, 588, 1572, 590, 1570, 590, 492, 588, 492, 590, 488,
|
||||
590, 494, 584, 1570, 592, 492, 586, 490, 590, 1572, 590, 490, 590, 1570,
|
||||
590, 490, 590, 1570, 590, 492, 588, 490, 588, 492, 588, 492, 590, 490,
|
||||
590, 494, 586, 490, 590, 490, 588, 490, 590, 490, 588, 492, 590, 490,
|
||||
588, 492, 590, 490, 590, 490, 590, 494, 584, 490, 590, 490, 590, 490,
|
||||
590, 490, 588, 490, 588, 492, 588, 492, 586, 492, 588, 490, 588, 492,
|
||||
588, 490, 590, 1572, 588, 494, 586, 1574, 588, 492, 588, 1572, 590, 1572,
|
||||
588, 492, 588, 492, 586, 494, 588,
|
||||
7422,
|
||||
4424, 4320,
|
||||
586, 1572, 588, 1572, 588, 1576, 584, 1574, 588, 494, 586, 492, 588, 1572,
|
||||
588, 492, 588, 492, 588, 492, 588, 494, 586, 496, 584, 1574, 586, 1578,
|
||||
582, 494, 586, 1578, 584, 494, 586, 492, 588, 492, 586, 496, 584, 494,
|
||||
586, 1578, 584, 494, 586, 494, 584, 1574, 588, 1572, 586, 1574, 588, 1574,
|
||||
588, 1572, 588, 494, 590, 1572, 588, 1574, 588, 492, 588, 492, 588, 492,
|
||||
586, 492, 588, 1572, 588, 498, 582, 492, 588, 1576, 586, 492, 588, 1572,
|
||||
588, 494, 588, 1572, 588, 492, 586, 492, 588, 492, 590, 490, 588, 492,
|
||||
586, 492, 588, 492, 590, 490, 588, 490, 588, 492, 590, 490, 588, 492,
|
||||
590, 490, 588, 490, 590, 490, 590, 490, 592, 488, 592, 494, 584, 494,
|
||||
586, 490, 590, 494, 586, 494, 588, 488, 592, 490, 588, 492, 586, 490,
|
||||
592, 490, 588, 1576, 584, 494, 586, 1570, 590, 494, 586, 1576, 582, 1572,
|
||||
590, 490, 590, 490, 588, 490, 590}; // UNKNOWN 54926187
|
||||
|
||||
const uint8_t expectedState[kToshibaACStateLengthLong] = {
|
||||
0xF2, 0x0D, 0x04, 0xFB, 0x09, 0x50, 0x00, 0x00, 0x01, 0x58};
|
||||
irsend.sendRaw(high_power_on, 327, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kToshibaACBitsLong, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"Temp: 22C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: On, "
|
||||
"Econo: Off",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
}
|
||||
|
||||
|
||||
/// Decode a synthetic long message.
|
||||
TEST(TestDecodeToshibaAC, SyntheticLongExample) {
|
||||
IRsendTest irsend(0);
|
||||
IRrecv irrecv(0);
|
||||
|
||||
const uint8_t expectedState[kToshibaACStateLengthLong] = {
|
||||
0xF2, 0x0D, 0x04, 0xFB, 0x09, 0x50, 0x00, 0x00, 0x01, 0x58};
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
irsend.sendToshibaAC(expectedState, kToshibaACStateLengthLong);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kToshibaACBitsLong, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
// 4424 4320
|
||||
"m4400s4300"
|
||||
// 582 1574 588 1578 582 1574 586 1578 586 496 582 492 586 1576 586 492
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
// 586 492 588 496 584 496 584 496 584 1626 534 1626 534 494 586 1578
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
// 582 494 586 494 586 494 588 492 586 492 586 1576 586 494 588 492
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490"
|
||||
// 588 1574 588 1576 584 1578 584 1574 588 1574 588 492 588 1572 590 1570
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600"
|
||||
// 590 492 588 492 590 488 590 494 584 1570 592 492 586 490 590 1572
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600"
|
||||
// 590 490 590 1570 590 490 590 1570 590 492 588 490 588 492 588 492
|
||||
"m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490m580s490"
|
||||
// 590 490 590 494 586 490 590 490 588 490 590 490 588 492 590 490
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
// 588 492 590 490 590 490 590 494 584 490 590 490 590 490 590 490
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
// 588 490 588 492 588 492 586 492 588 490 588 492 588 490 590 1572
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
// 588 494 586 1574 588 492 588 1572 590 1572 588 492 588 492 586 494
|
||||
"m580s490m580s1600m580s490m580s1600m580s1600m580s490m580s490m580s490"
|
||||
// 588 7422
|
||||
"m580s7400"
|
||||
"m4400s4300"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490"
|
||||
"m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600"
|
||||
"m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600"
|
||||
"m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490"
|
||||
"m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600"
|
||||
"m580s490m580s1600m580s490m580s1600m580s1600m580s490m580s490m580s490"
|
||||
"m580s7400",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
/// Decode a "real" short example message.
|
||||
TEST(TestDecodeToshibaAC, RealShortExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Data from:
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-650475096
|
||||
const uint16_t air_direction[115] = {
|
||||
4424, 4318,
|
||||
588, 1574, 588, 1572, 588, 1574, 586, 1572, 590, 490, 586, 494, 586, 1574,
|
||||
588, 492, 586, 494, 586, 494, 586, 496, 584, 492, 588, 1572, 588, 1572,
|
||||
590, 492, 588, 1572, 590, 490, 588, 492, 586, 494, 588, 492, 588, 492,
|
||||
588, 494, 584, 492, 588, 1572, 588, 1574, 588, 1574, 588, 1572, 588, 1572,
|
||||
588, 1572, 588, 1574, 590, 1570, 588, 494, 586, 496, 584, 494, 588, 1572,
|
||||
588, 492, 588, 492, 588, 490, 588, 492, 590, 1572, 588, 492, 588, 496,
|
||||
586, 492, 588, 492, 586, 492, 588, 492, 588, 490, 590, 490, 588, 492,
|
||||
588, 490, 588, 1572, 588, 492, 588, 492, 588, 490, 588, 492, 588, 1572,
|
||||
586}; // UNKNOWN DEB8845C
|
||||
const uint8_t expectedState[kToshibaACStateLengthShort] = {
|
||||
0xF2, 0x0D, 0x01, 0xFE, 0x21, 0x00, 0x21};
|
||||
irsend.sendRaw(air_direction, 115, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kToshibaACBitsShort, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"Temp: 17C, Swing(V): 0 (Step)",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
}
|
||||
|
||||
TEST(TestToshibaACClass, ConstructLongState) {
|
||||
IRToshibaAC ac(kGpioUnused);
|
||||
ac.setPower(true);
|
||||
ac.setMode(kToshibaAcDry);
|
||||
ac.setTemp(29);
|
||||
ac.setFan(2);
|
||||
ac.setSwing(false);
|
||||
ac.setTurbo(false);
|
||||
ac.setEcono(true);
|
||||
EXPECT_EQ(
|
||||
"Temp: 29C, Power: On, Mode: 2 (Dry), Fan: 2 (UNKNOWN), "
|
||||
"Turbo: Off, Econo: On",
|
||||
ac.toString());
|
||||
EXPECT_EQ(kToshibaACStateLengthLong, ac.getStateLength());
|
||||
const uint8_t expectedState[kToshibaACStateLengthLong] = {
|
||||
0xF2, 0x0D, 0x04, 0xFB, 0x09, 0xC0, 0x62, 0x00, 0x03, 0xA8};
|
||||
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kToshibaACBitsLong);
|
||||
EXPECT_EQ(kToshibaACStateLengthLong, ac.getStateLength());
|
||||
}
|
||||
|
0
lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/mkkeywords
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/mkkeywords
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py
Normal file → Executable file
0
lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py
Normal file → Executable file
@ -13,6 +13,7 @@
|
||||
- Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3
|
||||
- Add command (``S``)``SerialSend6`` \<comma seperated values\> (#8937)
|
||||
- Add support for Sonoff Zigbee Bridge as module 75 (#8583)
|
||||
- Change IRRemoteESP8266 IR lib to pre-2.7.9, fixing Samsung and Pioneer protocols (#8938)
|
||||
|
||||
### 8.3.1.6 20200617
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user