Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Added support for Fujitsu 264 bit A/C remote protocol #2030

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_FUJITSU_AC
case decode_type_t::FUJITSU_AC:
#endif
#if SEND_FUJITSU_AC264
case decode_type_t::FUJITSU_AC264:
#endif
#if SEND_GOODWEATHER
case decode_type_t::GOODWEATHER:
#endif
Expand Down Expand Up @@ -1273,6 +1276,59 @@ void IRac::fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model,
}
#endif // SEND_FUJITSU_AC

#if SEND_FUJITSU_AC264
/// Send a Fujitsu A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRFujitsuAC264 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] quiet Run the device in quiet/silent mode.
/// @param[in] turbo Toggle the device's turbo/powerful mode.
/// @param[in] econo Run the device in economical mode.
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
/// @param[in] sleep Nr. of minutes for sleep mode. <= 0 is Off, > 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignored.
void IRac::fujitsu264(IRFujitsuAC264 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool econo,
const bool clean, const int16_t sleep,
const int16_t clock) {
ac->begin();
if (on) {
// Do all special messages (except "Off") first,
// These need to be sent separately.
// Some functions are only available on some models.
if (turbo) {
ac->togglePowerful();
// Powerful is a separate command.
ac->send();
}
// Normal operation.
ac->setMode(ac->convertMode(mode));
if (mode == stdAc::opmode_t::kAuto)
ac->setTempAuto(degrees);
else
ac->setTemp(degrees);
ac->setFanSpeed(ac->convertFanSpeed(fan));
ac->setSwing(swingv != stdAc::swingv_t::kOff);
if (quiet) ac->setFanSpeed(kFujitsuAc264FanSpeedQuiet);
ac->setEconomy(econo);
ac->setClean(clean);
ac->setSleepTimer(sleep > 0 ? sleep : 0);
if (clock >= 0) ac->setClock(clock);
ac->on();
} else {
// Off is special case/message. We don't need to send other messages.
ac->off();
}
ac->send();
}
#endif // SEND_FUJITSU_AC264

#if SEND_GOODWEATHER
/// Send a Goodweather A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRGoodweatherAc object to use.
Expand Down Expand Up @@ -3242,6 +3298,16 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_FUJITSU_AC
#if SEND_FUJITSU_AC264
case FUJITSU_AC264:
{
IRFujitsuAC264 ac(_pin, _inverted, _modulation);
fujitsu264(&ac, send.power, send.mode, send.degrees, send.fanspeed,
send.swingv, send.quiet, send.turbo, send.econo,
send.clean, send.sleep);
break;
}
#endif // SEND_FUJITSU_AC264
#if SEND_GOODWEATHER
case GOODWEATHER:
{
Expand Down Expand Up @@ -4212,6 +4278,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_FUJITSU_AC
#if DECODE_FUJITSU_AC264
case decode_type_t::FUJITSU_AC264: {
IRFujitsuAC264 ac(kGpioUnused);
ac.setRaw(result->state, result->bits / 8);
return ac.toString();
}
#endif // DECODE_FUJITSU_AC264
#if DECODE_GOODWEATHER
case decode_type_t::GOODWEATHER: {
IRGoodweatherAc ac(kGpioUnused);
Expand Down Expand Up @@ -4713,6 +4786,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_FUJITSU_AC
#if DECODE_FUJITSU_AC264
case decode_type_t::FUJITSU_AC264: {
IRFujitsuAC264 ac(kGpioUnused);
ac.setRaw(decode->state, decode->bits / 8);
*result = ac.toCommon(prev);
break;
}
#endif // DECODE_FUJITSU_AC264
#if DECODE_GOODWEATHER
case decode_type_t::GOODWEATHER: {
IRGoodweatherAc ac(kGpioUnused);
Expand Down
10 changes: 10 additions & 0 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,16 @@ void electra(IRElectraAc *ac,
const bool quiet, const bool turbo, const bool econo,
const bool filter, const bool clean, const int16_t sleep = -1);
#endif // SEND_FUJITSU_AC
#if SEND_FUJITSU_AC264
void fujitsu264(IRFujitsuAC264 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool econo,
const bool clean, const int16_t sleep = -1,
const int16_t clock = -1);
#endif // SEND_FUJITSU_AC264
#if SEND_GOODWEATHER
void goodweather(IRGoodweatherAc *ac,
const bool on, const stdAc::opmode_t mode,
Expand Down
10 changes: 10 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,16 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Fujitsu A/C decode");
if (decodeFujitsuAC(results, offset)) return true;
#endif
#if DECODE_FUJITSU_AC264
// FujitsuAC264 should be checked before FujitsuAC
// Fujitsu A/C needs to precede Panasonic and Denon as it has a short
// message which looks exactly the same as a Panasonic/Denon message.
DPRINTLN("Attempting Fujitsu A/C264 decode");
if (decodeFujitsuAC264(results, offset, kFujitsuAc264Bits) ||
decodeFujitsuAC264(results, offset, kFujitsuAc264BitsMiddle) ||
decodeFujitsuAC264(results, offset, kFujitsuAc264BitsShort))
return true;
#endif
#if DECODE_DENON
// Denon needs to precede Panasonic as it is a special case of Panasonic.
DPRINTLN("Attempting Denon decode");
Expand Down
6 changes: 6 additions & 0 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,12 @@ class IRrecv {
const uint16_t nbits = kFujitsuAcBits,
const bool strict = false);
#endif
#if DECODE_FUJITSU_AC264
bool decodeFujitsuAC264(decode_results* results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kFujitsuAc264Bits,
const bool strict = true);
#endif // DECODE_FUJITSU_AC264
#if DECODE_LASERTAG
bool decodeLasertag(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kLasertagBits,
Expand Down
19 changes: 17 additions & 2 deletions src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,13 @@
#define SEND_YORK _IR_ENABLE_DEFAULT_
#endif // SEND_YORK

#ifndef DECODE_FUJITSU_AC264
#define DECODE_FUJITSU_AC264 _IR_ENABLE_DEFAULT_
#endif // DECODE_FUJITSU_AC264
#ifndef SEND_FUJITSU_AC264
#define SEND_FUJITSU_AC264 _IR_ENABLE_DEFAULT_
#endif // SEND_FUJITSU_AC264

#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
Expand All @@ -970,7 +977,7 @@
DECODE_KELON168 || DECODE_HITACHI_AC296 || DECODE_CARRIER_AC128 || \
DECODE_DAIKIN200 || DECODE_HAIER_AC160 || DECODE_TCL96AC || \
DECODE_BOSCH144 || DECODE_SANYO_AC152 || DECODE_DAIKIN312 || \
DECODE_CARRIER_AC84 || DECODE_YORK || \
DECODE_CARRIER_AC84 || DECODE_YORK || DECODE_FUJITSU_AC264 || \
false)
// Add any DECODE to the above if it uses result->state (see kStateSizeMax)
// you might also want to add the protocol to hasACState function
Expand Down Expand Up @@ -1137,8 +1144,9 @@ enum decode_type_t {
WOWWEE,
CARRIER_AC84, // 125
YORK,
FUJITSU_AC264,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = YORK,
kLastDecodeType = FUJITSU_AC264,
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -1241,6 +1249,13 @@ const uint16_t kFujitsuAcStateLength = 16;
const uint16_t kFujitsuAcStateLengthShort = 7;
const uint16_t kFujitsuAcBits = kFujitsuAcStateLength * 8;
const uint16_t kFujitsuAcMinBits = (kFujitsuAcStateLengthShort - 1) * 8;
const uint16_t kFujitsuAc264DefaultRepeat = kNoRepeat;
const uint16_t kFujitsuAc264StateLength = 33;
const uint16_t kFujitsuAc264StateLengthMiddle = 16;
const uint16_t kFujitsuAc264StateLengthShort = 7;
const uint16_t kFujitsuAc264Bits = kFujitsuAc264StateLength * 8;
const uint16_t kFujitsuAc264BitsMiddle = kFujitsuAc264StateLengthMiddle * 8;
const uint16_t kFujitsuAc264BitsShort = kFujitsuAc264StateLengthShort * 8;
const uint16_t kGicableBits = 16;
const uint16_t kGicableMinRepeat = kSingleRepeat;
const uint16_t kGoodweatherBits = 48;
Expand Down
7 changes: 7 additions & 0 deletions src/IRsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kXmpBits;
case YORK:
return kYorkBits;
case FUJITSU_AC264:
return kFujitsuAc264Bits;
// No default amount of bits.
case FUJITSU_AC:
case MWM:
Expand Down Expand Up @@ -1246,6 +1248,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendFujitsuAC(state, nbytes);
break;
#endif // SEND_FUJITSU_AC
#if SEND_FUJITSU_AC264
case FUJITSU_AC264:
sendFujitsuAC264(state, nbytes);
break;
#endif
#if SEND_GREE
case GREE:
sendGree(state, nbytes);
Expand Down
5 changes: 5 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,11 @@ class IRsend {
void sendFujitsuAC(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat = kFujitsuAcMinRepeat);
#endif
#if SEND_FUJITSU_AC264
void sendFujitsuAC264(const unsigned char data[],
const uint16_t nbytes = kFujitsuAc264StateLength,
const uint16_t repeat = kNoRepeat);
#endif // SEND_FUJITSU_AC264
#if SEND_INAX
void sendInax(const uint64_t data, const uint16_t nbits = kInaxBits,
const uint16_t repeat = kInaxMinRepeat);
Expand Down
2 changes: 2 additions & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
D_STR_CARRIER_AC84, D_STR_UNSUPPORTED) "\x0"
COND(DECODE_YORK || SEND_YORK,
D_STR_YORK, D_STR_UNSUPPORTED) "\x0"
COND(DECODE_FUJITSU_AC264 || SEND_FUJITSU_AC264,
D_STR_FUJITSU_AC264, D_STR_UNSUPPORTED) "\x0"
///< New protocol (macro) strings should be added just above this line.
"\x0" ///< This string requires double null termination.
};
Expand Down
1 change: 1 addition & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ bool hasACState(const decode_type_t protocol) {
case DAIKIN312:
case ELECTRA_AC:
case FUJITSU_AC:
case FUJITSU_AC264:
case GREE:
case HAIER_AC:
case HAIER_AC_YRW02:
Expand Down
Loading
Loading