diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 173526104..316dfc149 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -1185,6 +1185,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, DPRINTLN("Attempting York decode"); if (decodeYork(results, offset, kYorkBits)) return true; #endif // DECODE_YORK +#if DECODE_BLUESTARHEAVY + DPRINTLN("Attempting BluestarHeavy decode"); + if (decodeBluestarHeavy(results, offset, kBluestarHeavyBits)) return true; +#endif // DECODE_BLUESTARHEAVY // Typically new protocols are added above this line. } #if DECODE_HASH diff --git a/src/IRrecv.h b/src/IRrecv.h index 6d12d98a7..a9cbce610 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -883,6 +883,12 @@ class IRrecv { const uint16_t nbits = kYorkBits, const bool strict = true); #endif // DECODE_YORK +#if DECODE_BLUESTARHEAVY + bool decodeBluestarHeavy(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kBluestarHeavyBits, + const bool strict = true); +#endif // DECODE_BLUESTARHEAVY }; #endif // IRRECV_H_ diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 949de1ecf..b5daffaf8 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -952,6 +952,13 @@ #define SEND_YORK _IR_ENABLE_DEFAULT_ #endif // SEND_YORK +#ifndef DECODE_BLUESTARHEAVY +#define DECODE_BLUESTARHEAVY _IR_ENABLE_DEFAULT_ +#endif // DECODE_BLUESTARHEAVY +#ifndef SEND_BLUESTARHEAVY +#define SEND_BLUESTARHEAVY _IR_ENABLE_DEFAULT_ +#endif // SEND_BLUESTARHEAVY + #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 || \ @@ -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_BLUESTARHEAVY || \ 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 @@ -1137,8 +1144,9 @@ enum decode_type_t { WOWWEE, CARRIER_AC84, // 125 YORK, + BLUESTARHEAVY, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = YORK, + kLastDecodeType = BLUESTARHEAVY, }; // Message lengths & required repeat values @@ -1165,6 +1173,8 @@ const uint16_t kArgo3TimerStateLength = 9; // Bytes const uint16_t kArgo3ConfigStateLength = 4; // Bytes const uint16_t kArgoDefaultRepeat = kNoRepeat; const uint16_t kArrisBits = 32; +const uint16_t kBluestarHeavyStateLength = 13; +const uint16_t kBluestarHeavyBits = kBluestarHeavyStateLength * 8; const uint16_t kBosch144StateLength = 18; const uint16_t kBosch144Bits = kBosch144StateLength * 8; const uint16_t kCoolixBits = 24; @@ -1436,7 +1446,6 @@ const uint16_t kClimaButlerBits = 52; const uint16_t kYorkBits = 136; const uint16_t kYorkStateLength = 17; - // Legacy defines. (Deprecated) #define AIWA_RC_T501_BITS kAiwaRcT501Bits #define ARGO_COMMAND_LENGTH kArgoStateLength diff --git a/src/IRsend.cpp b/src/IRsend.cpp index 10e440b32..1864ee2a3 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -798,6 +798,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kXmpBits; case YORK: return kYorkBits; + case BLUESTARHEAVY: + return kBluestarHeavyBits; // No default amount of bits. case FUJITSU_AC: case MWM: @@ -1434,6 +1436,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state, sendYork(state, nbytes); break; #endif // SEND_YORK +#if SEND_BLUESTARHEAVY + case BLUESTARHEAVY: + sendBluestarHeavy(state, nbytes); + break; +#endif // SEND_BLUESTARHEAVY default: return false; } diff --git a/src/IRsend.h b/src/IRsend.h index 1af988cc9..56e9a3d35 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -892,6 +892,11 @@ class IRsend { const uint16_t nbytes = kYorkStateLength, const uint16_t repeat = kNoRepeat); #endif // SEND_YORK +#if SEND_BLUESTARHEAVY + void sendBluestarHeavy(const unsigned char data[], + const uint16_t nbytes = kBluestarHeavyStateLength, + const uint16_t repeat = kNoRepeat); +#endif // SEND_BLUESTARHEAVY protected: #ifdef UNIT_TEST diff --git a/src/IRtext.cpp b/src/IRtext.cpp index 8fd27b955..f8a3290bb 100644 --- a/src/IRtext.cpp +++ b/src/IRtext.cpp @@ -559,6 +559,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_BLUESTARHEAVY || SEND_BLUESTARHEAVY, + D_STR_BLUESTARHEAVY, D_STR_UNSUPPORTED) "\x0" ///< New protocol (macro) strings should be added just above this line. "\x0" ///< This string requires double null termination. }; diff --git a/src/IRutils.cpp b/src/IRutils.cpp index ab4a08dbf..d8cabaff4 100644 --- a/src/IRutils.cpp +++ b/src/IRutils.cpp @@ -169,6 +169,7 @@ bool hasACState(const decode_type_t protocol) { // This is kept sorted by name case AMCOR: case ARGO: + case BLUESTARHEAVY: case BOSCH144: case CARRIER_AC84: case CARRIER_AC128: diff --git a/src/ir_BluestarHeavy.cpp b/src/ir_BluestarHeavy.cpp new file mode 100644 index 000000000..5d6452767 --- /dev/null +++ b/src/ir_BluestarHeavy.cpp @@ -0,0 +1,72 @@ +// Copyright 2024 Harsh Bhosale (harshbhosale01) +/// @file +/// @brief Support for BluestarHeavy protocol + +// Supports: +// Brand: Bluestar, Model: D716LXM0535A2400313 (Remote) + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +const uint16_t kBluestarHeavyHdrMark = 4912; +const uint16_t kBluestarHeavyBitMark = 465; +const uint16_t kBluestarHeavyHdrSpace = 5058; +const uint16_t kBluestarHeavyOneSpace = 572; +const uint16_t kBluestarHeavyZeroSpace = 1548; +const uint16_t kBluestarHeavyFreq = 38000; +const uint16_t kBluestarHeavyOverhead = 3; + +#if SEND_BLUESTARHEAVY +/// Send a BluestarHeavy formatted message. +/// Status: BETA / Tested. +/// @param[in] data An array of bytes containing the IR command. +/// It is assumed to be in MSB order for this code. +/// e.g. +/// @code +/// uint8_t data[kBluestarHeavyStateLength] = +/// {0x2A,0x00,0x20,0xD0,0x05,0xA0,0x05,0xA0,0x00,0x80,0xBA,0x02,0x23}; +/// @endcode +/// @param[in] nbytes Nr. of bytes of data in the array. +/// @param[in] repeat Nr. of times the message is to be repeated. +void IRsend::sendBluestarHeavy(const uint8_t data[], const uint16_t nbytes, + const uint16_t repeat) { + sendGeneric(kBluestarHeavyHdrMark, kBluestarHeavyHdrSpace, + kBluestarHeavyBitMark, kBluestarHeavyOneSpace, + kBluestarHeavyBitMark, kBluestarHeavyZeroSpace, + kBluestarHeavyHdrMark, kDefaultMessageGap, + data, nbytes, // Bytes + kBluestarHeavyFreq, true, repeat, kDutyDefault); +} +#endif // SEND_BLUESTARHEAVY + +#if DECODE_BLUESTARHEAVY +/// Decode the supplied BluestarHeavy message. +/// Status: BETA / Tested. +/// @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. +bool IRrecv::decodeBluestarHeavy(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (strict && nbits != kBluestarHeavyBits) + return false; + + uint16_t used = 0; + + used = matchGeneric(results->rawbuf + offset, results->state, + results->rawlen - offset, nbits, + kBluestarHeavyHdrMark, kBluestarHeavyHdrSpace, + kBluestarHeavyBitMark, kBluestarHeavyOneSpace, + kBluestarHeavyBitMark, kBluestarHeavyZeroSpace, + kBluestarHeavyHdrMark, kDefaultMessageGap, true); + if (used == 0) return false; // We failed to find any data. + + // Success + results->decode_type = decode_type_t::BLUESTARHEAVY; + results->bits = nbits; + return true; +} +#endif // DECODE_BLUESTARHEAVY diff --git a/src/locale/defaults.h b/src/locale/defaults.h index ea20686cf..a1329a97c 100644 --- a/src/locale/defaults.h +++ b/src/locale/defaults.h @@ -751,6 +751,9 @@ D_STR_INDIRECT " " D_STR_MODE #ifndef D_STR_ARRIS #define D_STR_ARRIS "ARRIS" #endif // D_STR_ARRIS +#ifndef D_STR_BLUESTARHEACY +#define D_STR_BLUESTARHEAVY "BLUESTARHEAVY" +#endif // D_STR_TESTEXAMPLE #ifndef D_STR_BOSCH #define D_STR_BOSCH "BOSCH" #endif // D_STR_BOSCH