@@ -1723,10 +1723,15 @@ void IRsend::sendHitachiAc296(const unsigned char data[],
17231723}
17241724#endif // SEND_HITACHIAC296
17251725
1726+ // Class constructor for handling detailed Hitachi_AC296 37 byte A/C messages.
1727+ // / @param[in] pin GPIO to be used when sending.
1728+ // / @param[in] inverted Is the output signal to be inverted?
1729+ // / @param[in] use_modulation Is frequency modulation to be used?
17261730IRHitachiAc296::IRHitachiAc296 (const uint16_t pin, const bool inverted,
17271731 const bool use_modulation)
17281732 : _irsend(pin, inverted, use_modulation) { stateReset (); }
17291733
1734+ // / Reset the internal state to auto fan, heating, & 24° Celsius
17301735void IRHitachiAc296::stateReset (void ) {
17311736 // Header
17321737 _.raw [0 ] = 0x01 ;
@@ -1785,18 +1790,13 @@ void IRHitachiAc296::send(const uint16_t repeat) {
17851790}
17861791#endif // SEND_HITACHI_AC296
17871792
1788-
17891793// / Get the value of the current power setting.
17901794// / @return true, the setting is on. false, the setting is off.
1791- bool IRHitachiAc296::getPower (void ) const {
1792- return _.Power ;
1793- }
1795+ bool IRHitachiAc296::getPower (void ) const { return _.Power ; }
17941796
17951797// / Change the power setting.
17961798// / @param[in] on true, the setting is on. false, the setting is off.
1797- void IRHitachiAc296::setPower (const bool on) {
1798- _.Power = on;
1799- }
1799+ void IRHitachiAc296::setPower (const bool on) { _.Power = on; }
18001800
18011801// / Change the power setting to On.
18021802void IRHitachiAc296::on (void ) { setPower (true ); }
@@ -1806,52 +1806,106 @@ void IRHitachiAc296::off(void) { setPower(false); }
18061806
18071807// / Get the operating mode setting of the A/C.
18081808// / @return The current operating mode setting.
1809- uint8_t IRHitachiAc296::getMode (void ) const {
1810- return _.Mode ;
1811- }
1809+ uint8_t IRHitachiAc296::getMode (void ) const { return _.Mode ; }
18121810
18131811// / Set the operating mode of the A/C.
18141812// / @param[in] mode The desired operating mode.
18151813void IRHitachiAc296::setMode (const uint8_t mode) {
1816- uint8_t newMode = mode;
18171814 switch (mode) {
18181815 case kHitachiAc296Heat :
18191816 case kHitachiAc296Cool :
1820- case kHitachiAc296Auto : break ;
1821- default : newMode = kHitachiAc296Auto ;
1817+ case kHitachiAc296Dehumidify :
1818+ case kHitachiAc296AutoDehumidifying :
1819+ case kHitachiAc296Auto :
1820+ _.Mode = mode;
1821+ setTemp (getTemp ()); // Reset the temp to handle "Auto"'s special temp.
1822+ break ;
1823+ default :
1824+ setMode (kHitachiAc296Auto );
18221825 }
1826+ }
18231827
1824- _.Mode = newMode;
1828+ // / Convert a stdAc::opmode_t enum into its native mode.
1829+ // / @param[in] mode The enum to be converted.
1830+ // / @return The native equivalent of the enum.
1831+ uint8_t IRHitachiAc296::convertMode (const stdAc::opmode_t mode) {
1832+ switch (mode) {
1833+ case stdAc::opmode_t ::kCool : return kHitachiAc296Cool ;
1834+ case stdAc::opmode_t ::kHeat : return kHitachiAc296Heat ;
1835+ case stdAc::opmode_t ::kDry : return kHitachiAc296Dehumidify ;
1836+ default : return kHitachiAc296Auto ;
1837+ }
1838+ }
1839+
1840+ // / Convert a native mode into its stdAc equivalent.
1841+ // / @param[in] mode The native setting to be converted.
1842+ // / @return The stdAc equivalent of the native setting.
1843+ stdAc::opmode_t IRHitachiAc296::toCommonMode (const uint8_t mode) {
1844+ switch (mode) {
1845+ case kHitachiAc296DryCool :
1846+ case kHitachiAc296Cool : return stdAc::opmode_t ::kCool ;
1847+ case kHitachiAc296Heat : return stdAc::opmode_t ::kHeat ;
1848+ case kHitachiAc296AutoDehumidifying :
1849+ case kHitachiAc296Dehumidify : return stdAc::opmode_t ::kDry ;
1850+ default : return stdAc::opmode_t ::kAuto ;
1851+ }
18251852}
18261853
18271854// / Get the current temperature setting.
18281855// / @return The current setting for temp. in degrees celsius.
1829- uint8_t IRHitachiAc296::getTemp (void ) const {
1830- return _.Temp ;
1831- }
1856+ uint8_t IRHitachiAc296::getTemp (void ) const { return _.Temp ; }
18321857
18331858// / Set the temperature.
18341859// / @param[in] celsius The temperature in degrees celsius.
18351860void IRHitachiAc296::setTemp (const uint8_t celsius) {
1836- uint8_t temp;
1837- temp = std::min (celsius, kHitachiAc296MaxTemp );
1838- _.Temp = std::max (temp, kHitachiAc296MinTemp );
1861+ uint8_t temp = celsius;
1862+ if (getMode () == kHitachiAc296Auto ) { // Special temp for auto mode
1863+ temp = kHitachiAc296TempAuto ;
1864+ } else { // Normal temp setting.
1865+ temp = std::min (temp, kHitachiAc296MaxTemp );
1866+ temp = std::max (temp, kHitachiAc296MinTemp );
1867+ }
1868+ _.Temp = temp;
18391869}
18401870
18411871// / Get the current fan speed setting.
18421872// / @return The current fan speed.
1843- uint8_t IRHitachiAc296::getFan (void ) const {
1844- return _.Fan ;
1845- }
1873+ uint8_t IRHitachiAc296::getFan (void ) const { return _.Fan ; }
18461874
18471875// / Set the speed of the fan.
18481876// / @param[in] speed The desired setting.
18491877void IRHitachiAc296::setFan (const uint8_t speed) {
1850- uint8_t newSpeed = speed;
1851- newSpeed = std::max (newSpeed, kHitachiAc296FanSilent );
1878+ uint8_t newSpeed = std::max (speed, kHitachiAc296FanSilent );
18521879 _.Fan = std::min (newSpeed, kHitachiAc296FanAuto );
18531880}
18541881
1882+ // / Convert a stdAc::fanspeed_t enum into it's native speed.
1883+ // / @param[in] speed The enum to be converted.
1884+ // / @return The native equivalent of the enum.
1885+ uint8_t IRHitachiAc296::convertFan (const stdAc::fanspeed_t speed) {
1886+ switch (speed) {
1887+ case stdAc::fanspeed_t ::kMin : return kHitachiAc296FanSilent ;
1888+ case stdAc::fanspeed_t ::kLow : return kHitachiAc296FanLow ;
1889+ case stdAc::fanspeed_t ::kMedium : return kHitachiAc296FanMedium ;
1890+ case stdAc::fanspeed_t ::kHigh :
1891+ case stdAc::fanspeed_t ::kMax : return kHitachiAc296FanHigh ;
1892+ default : return kHitachiAc296FanAuto ;
1893+ }
1894+ }
1895+
1896+ // / Convert a native fan speed into its stdAc equivalent.
1897+ // / @param[in] speed The native setting to be converted.
1898+ // / @return The stdAc equivalent of the native setting.
1899+ stdAc::fanspeed_t IRHitachiAc296::toCommonFanSpeed (const uint8_t speed) {
1900+ switch (speed) {
1901+ case kHitachiAc296FanHigh : return stdAc::fanspeed_t ::kHigh ;
1902+ case kHitachiAc296FanMedium : return stdAc::fanspeed_t ::kMedium ;
1903+ case kHitachiAc296FanLow : return stdAc::fanspeed_t ::kLow ;
1904+ case kHitachiAc296FanSilent : return stdAc::fanspeed_t ::kMin ;
1905+ default : return stdAc::fanspeed_t ::kAuto ;
1906+ }
1907+ }
1908+
18551909// / Get a PTR to the internal state/code for this protocol.
18561910// / @return PTR to a code for this protocol based on the current internal state.
18571911uint8_t *IRHitachiAc296::getRaw (void ) {
@@ -1866,6 +1920,49 @@ void IRHitachiAc296::setRaw(const uint8_t new_code[], const uint16_t length) {
18661920 memcpy (_.raw , new_code, std::min (length, kHitachiAc296StateLength ));
18671921}
18681922
1923+
1924+ // / Convert the current internal state into its stdAc::state_t equivalent.
1925+ // / @return The stdAc equivalent of the native settings.
1926+ stdAc::state_t IRHitachiAc296::toCommon (void ) const {
1927+ stdAc::state_t result{};
1928+ result.protocol = decode_type_t ::HITACHI_AC296;
1929+ result.model = -1 ; // No models used.
1930+ result.power = getPower ();
1931+ result.mode = toCommonMode (_.Mode );
1932+ result.celsius = true ;
1933+ result.degrees = _.Temp ;
1934+ result.fanspeed = toCommonFanSpeed (_.Fan );
1935+ result.quiet = _.Fan == kHitachiAc296FanSilent ;
1936+ // Not supported.
1937+ result.swingv = stdAc::swingv_t ::kOff ;
1938+ result.swingh = stdAc::swingh_t ::kOff ;
1939+ result.turbo = false ;
1940+ result.clean = false ;
1941+ result.econo = false ;
1942+ result.filter = false ;
1943+ result.light = false ;
1944+ result.beep = false ;
1945+ result.sleep = -1 ;
1946+ result.clock = -1 ;
1947+ return result;
1948+ }
1949+
1950+ // / Convert the current internal state into a human readable string.
1951+ // / @return A human readable string.
1952+ String IRHitachiAc296::toString (void ) const {
1953+ String result = " " ;
1954+ result.reserve (70 ); // Reserve some heap for the string to reduce fragging.
1955+ result += addBoolToString (_.Power , kPowerStr , false );
1956+ result += addModeToString (_.Mode , kHitachiAc296Auto , kHitachiAc296Cool ,
1957+ kHitachiAc296Heat , kHitachiAc1Dry ,
1958+ kHitachiAc296Auto );
1959+ result += addTempToString (getTemp ());
1960+ result += addFanToString (_.Fan , kHitachiAc296FanHigh , kHitachiAc296FanLow ,
1961+ kHitachiAc296FanAuto , kHitachiAc296FanSilent ,
1962+ kHitachiAc296FanMedium );
1963+ return result;
1964+ }
1965+
18691966#if DECODE_HITACHI_AC296
18701967// / Decode the supplied Hitachi 37-byte A/C message.
18711968// / Status: STABLE / Working on a real device.
@@ -1879,14 +1976,13 @@ void IRHitachiAc296::setRaw(const uint8_t new_code[], const uint16_t length) {
18791976bool IRrecv::decodeHitachiAc296 (decode_results *results, uint16_t offset,
18801977 const uint16_t nbits,
18811978 const bool strict) {
1882- uint16_t used = matchGeneric (results->rawbuf + offset, results->state ,
1883- results->rawlen - offset, nbits,
1884- kHitachiAcHdrMark , kHitachiAcHdrSpace ,
1885- kHitachiAcBitMark , kHitachiAcOneSpace ,
1886- kHitachiAcBitMark , kHitachiAcZeroSpace ,
1887- kHitachiAcBitMark , kHitachiAcMinGap , true ,
1888- kUseDefTol , 0 , false );
1889- if (used == 0 ) return false ;
1979+ if (!matchGeneric (results->rawbuf + offset, results->state ,
1980+ results->rawlen - offset, nbits,
1981+ kHitachiAcHdrMark , kHitachiAcHdrSpace ,
1982+ kHitachiAcBitMark , kHitachiAcOneSpace ,
1983+ kHitachiAcBitMark , kHitachiAcZeroSpace ,
1984+ kHitachiAcBitMark , kHitachiAcMinGap , true ,
1985+ kUseDefTol , 0 , false )) return false ;
18901986
18911987 // Compliance
18921988 if (strict && !IRHitachiAc296::hasInvertedStates (results->state , nbits / 8 ))
0 commit comments