Skip to content

Commit

Permalink
[HAIER_AC176] Basic support for HAIER_AC176 176 bit protocol. (#1481)
Browse files Browse the repository at this point in the history
* Add `sendHaierAC176()` & `decodeHaierAC176()`
* Additional changes to support the new protocol.
* Unit test coverage for send and decode.
* Add housekeeping tests for Haier family
* Minor code clean-up in the unit tests.

For #1480
  • Loading branch information
crankyoldgit authored May 20, 2021
1 parent 4655462 commit bf84a00
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 46 deletions.
4 changes: 4 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Haier AC YR-W02 decode");
if (decodeHaierACYRW02(results, offset)) return true;
#endif
#if DECODE_HAIER_AC176
DPRINTLN("Attempting Haier AC 176 bit decode");
if (decodeHaierAC176(results, offset)) return true;
#endif // DECODE_HAIER_AC176
#if DECODE_HITACHI_AC424
// HitachiAc424 should be checked before HitachiAC, HitachiAC2,
// & HitachiAC184
Expand Down
6 changes: 6 additions & 0 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,12 @@ class IRrecv {
const uint16_t nbits = kHaierACYRW02Bits,
const bool strict = true);
#endif
#if DECODE_HAIER_AC176
bool decodeHaierAC176(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierAC176Bits,
const bool strict = true);
#endif // DECODE_HAIER_AC176
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344)
bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAcBits,
Expand Down
15 changes: 13 additions & 2 deletions src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,13 @@
#define SEND_TRUMA _IR_ENABLE_DEFAULT_
#endif // SEND_TRUMA

#ifndef DECODE_HAIER_AC176
#define DECODE_HAIER_AC176 _IR_ENABLE_DEFAULT_
#endif // DECODE_HAIER_AC176
#ifndef SEND_HAIER_AC176
#define SEND_HAIER_AC176 _IR_ENABLE_DEFAULT_
#endif // SEND_HAIER_AC176

#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 @@ -759,7 +766,7 @@
DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \
DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \
DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \
DECODE_VOLTAS || DECODE_MIRAGE)
DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176)
// 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.
Expand Down Expand Up @@ -899,8 +906,9 @@ enum decode_type_t {
ECOCLIM,
XMP,
TRUMA, // 100
HAIER_AC176,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = TRUMA,
kLastDecodeType = HAIER_AC176,
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -992,6 +1000,9 @@ const uint16_t kHaierAcDefaultRepeat = kNoRepeat;
const uint16_t kHaierACYRW02StateLength = 14;
const uint16_t kHaierACYRW02Bits = kHaierACYRW02StateLength * 8;
const uint16_t kHaierAcYrw02DefaultRepeat = kNoRepeat;
const uint16_t kHaierAC176StateLength = 22;
const uint16_t kHaierAC176Bits = kHaierAC176StateLength * 8;
const uint16_t kHaierAc176DefaultRepeat = kNoRepeat;
const uint16_t kHitachiAcStateLength = 28;
const uint16_t kHitachiAcBits = kHitachiAcStateLength * 8;
const uint16_t kHitachiAcDefaultRepeat = kNoRepeat;
Expand Down
7 changes: 7 additions & 0 deletions src/IRsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kHaierACBits;
case HAIER_AC_YRW02:
return kHaierACYRW02Bits;
case HAIER_AC176:
return kHaierAC176Bits;
case HITACHI_AC:
return kHitachiAcBits;
case HITACHI_AC1:
Expand Down Expand Up @@ -1143,6 +1145,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendHaierACYRW02(state, nbytes);
break;
#endif // SEND_HAIER_AC_YRW02
#if SEND_HAIER_AC176
case HAIER_AC176:
sendHaierAC176(state, nbytes);
break;
#endif // SEND_HAIER_AC176
#if SEND_HITACHI_AC
case HITACHI_AC:
sendHitachiAC(state, nbytes);
Expand Down
11 changes: 8 additions & 3 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,16 +522,21 @@ class IRsend {
void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits,
uint16_t repeat = kCarrierAc64MinRepeat);
#endif
#if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02)
#if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02 || SEND_HAIER_AC176)
void sendHaierAC(const unsigned char data[],
const uint16_t nbytes = kHaierACStateLength,
const uint16_t repeat = kHaierAcDefaultRepeat);
#endif
#endif // (SEND_HAIER_AC || SEND_HAIER_AC_YRW02 || SEND_HAIER_AC176)
#if SEND_HAIER_AC_YRW02
void sendHaierACYRW02(const unsigned char data[],
const uint16_t nbytes = kHaierACYRW02StateLength,
const uint16_t repeat = kHaierAcYrw02DefaultRepeat);
#endif
#endif // SEND_HAIER_AC_YRW02
#if SEND_HAIER_AC176
void sendHaierAC176(const unsigned char data[],
const uint16_t nbytes = kHaierAC176StateLength,
const uint16_t repeat = kHaierAc176DefaultRepeat);
#endif // SEND_HAIER_AC176
#if SEND_HITACHI_AC
void sendHitachiAC(const unsigned char data[],
const uint16_t nbytes = kHitachiAcStateLength,
Expand Down
1 change: 1 addition & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,5 +285,6 @@ const PROGMEM char *kAllProtocolNamesStr =
D_STR_ECOCLIM "\x0"
D_STR_XMP "\x0"
D_STR_TRUMA "\x0"
D_STR_HAIER_AC176 "\x0"
///< New protocol strings should be added just above this line.
"\x0"; ///< This string requires double null termination.
1 change: 1 addition & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ bool hasACState(const decode_type_t protocol) {
case GREE:
case HAIER_AC:
case HAIER_AC_YRW02:
case HAIER_AC176:
case HITACHI_AC:
case HITACHI_AC1:
case HITACHI_AC2:
Expand Down
53 changes: 49 additions & 4 deletions src/ir_Haier.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018 crankyoldgit
// Copyright 2018-2021 crankyoldgit
/// @file
/// @brief Support for Haier A/C protocols.
/// The specifics of reverse engineering the protocols details:
Expand All @@ -8,6 +8,7 @@
/// @see https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/485
/// @see https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1480

#include "ir_Haier.h"
#include <cstring>
Expand Down Expand Up @@ -42,7 +43,7 @@ using irutils::minsToString;
_.x##Mins = mins % 60;\
} while (0)

#if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02)
#if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02 || SEND_HAIER_AC176)
/// Send a Haier A/C formatted message. (HSU07-HEA03 remote)
/// Status: STABLE / Known to be working.
/// @param[in] data The message to be sent.
Expand All @@ -63,11 +64,11 @@ void IRsend::sendHaierAC(const unsigned char data[], const uint16_t nbytes,
50);
}
}
#endif // (SEND_HAIER_AC || SEND_HAIER_AC_YRW02)
#endif // (SEND_HAIER_AC || SEND_HAIER_AC_YRW02 || SEND_HAIER_AC176)

#if SEND_HAIER_AC_YRW02
/// Send a Haier YR-W02 remote A/C formatted message.
/// Status: Alpha / Untested on a real device.
/// Status: STABLE / Known to be working.
/// @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.
Expand All @@ -77,6 +78,18 @@ void IRsend::sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes,
}
#endif // SEND_HAIER_AC_YRW02

#if SEND_HAIER_AC176
/// Send a Haier 176 bit remote A/C formatted message.
/// Status: STABLE / Known to be working.
/// @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::sendHaierAC176(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes >= kHaierAC176StateLength) sendHaierAC(data, nbytes, repeat);
}
#endif // SEND_HAIER_AC176

/// Class constructor
/// @param[in] pin GPIO to be used when sending.
/// @param[in] inverted Is the output signal to be inverted?
Expand Down Expand Up @@ -1039,3 +1052,35 @@ bool IRrecv::decodeHaierACYRW02(decode_results* results, uint16_t offset,
return true;
}
#endif // DECODE_HAIER_AC_YRW02

#if DECODE_HAIER_AC176
/// Decode the supplied Haier 176 bit remote A/C message.
/// Status: STABLE / Known to be working.
/// @param[in,out] results Ptr to the data to decode & where to store the decode
/// result.
/// @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.
bool IRrecv::decodeHaierAC176(decode_results* results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (strict) {
if (nbits != kHaierAC176Bits)
return false; // Not strictly a HAIER_AC176 message.
}

// The protocol is almost exactly the same as HAIER_AC
if (!decodeHaierAC(results, offset, nbits, false)) return false;

// Compliance
if (strict) {
if (results->state[0] != kHaierAcYrw02Prefix) return false;
}

// Success
// It looks correct, but we haven't check the checksum etc.
results->decode_type = HAIER_AC176;
return true;
}
#endif // DECODE_HAIER_AC176
2 changes: 2 additions & 0 deletions src/ir_Haier.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC)
// Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02)
// Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02)
// Brand: Mabe, Model: MMI18HDBWCA6MI8 A/C (HAIER_AC176)
// Brand: Mabe, Model: V12843 HJ200223 remote (HAIER_AC176)

#ifndef IR_HAIER_H_
#define IR_HAIER_H_
Expand Down
3 changes: 3 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@
#ifndef D_STR_HAIER_AC_YRW02
#define D_STR_HAIER_AC_YRW02 "HAIER_AC_YRW02"
#endif // D_STR_HAIER_AC_YRW02
#ifndef D_STR_HAIER_AC176
#define D_STR_HAIER_AC176 "HAIER_AC176"
#endif // D_STR_HAIER_AC176
#ifndef D_STR_HITACHI_AC
#define D_STR_HITACHI_AC "HITACHI_AC"
#endif // D_STR_HITACHI_AC
Expand Down
Loading

0 comments on commit bf84a00

Please sign in to comment.