Skip to content

Commit

Permalink
Voltas: Add detailed support for Voltas A/Cs (#1248)
Browse files Browse the repository at this point in the history
* Add `IRVoltas` class to handle detailed setting support.
  - Model
  - Power
  - Mode
  - Fan Speed
  - Temperature
  - Turbo (Cool Mode only)
  - Econo (Cool Mode only)
  - Sleep (Cool Mode only)
  - Wifi
  - Light/Lamp
  - SwingV
  - SwingH (Unavailable for Model 122LZF)
  - Off Timer
  - On Timer
* Add support for `VOLTAS` to Common A/C API (`IRac`)
* Unit tests.
* Tested against real received messages, and sending messages to a real device.

Fixes #1238
  • Loading branch information
crankyoldgit authored Aug 28, 2020
1 parent d0e2d83 commit ea79247
Show file tree
Hide file tree
Showing 8 changed files with 1,160 additions and 16 deletions.
99 changes: 89 additions & 10 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "ir_Toshiba.h"
#include "ir_Trotec.h"
#include "ir_Vestel.h"
#include "ir_Voltas.h"
#include "ir_Whirlpool.h"

/// Class constructor
Expand Down Expand Up @@ -262,6 +263,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_VESTEL_AC
case decode_type_t::VESTEL_AC:
#endif
#if SEND_VOLTAS
case decode_type_t::VOLTAS:
#endif
#if SEND_WHIRLPOOL_AC
case decode_type_t::WHIRLPOOL_AC:
#endif
Expand Down Expand Up @@ -547,7 +551,7 @@ void IRac::daikin(IRDaikinESP *ac,
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] econo Run the device in economical mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
void IRac::daikin128(IRDaikin128 *ac,
const bool on, const stdAc::opmode_t mode,
Expand Down Expand Up @@ -671,7 +675,7 @@ void IRac::daikin176(IRDaikin176 *ac,
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
/// @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.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
void IRac::daikin2(IRDaikin2 *ac,
const bool on, const stdAc::opmode_t mode,
Expand Down Expand Up @@ -740,7 +744,7 @@ void IRac::daikin216(IRDaikin216 *ac,
/// @param[in] swingv The vertical swing setting.
/// @param[in] quiet Run the device in quiet/silent mode.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
void IRac::daikin64(IRDaikin64 *ac,
const bool on, const stdAc::opmode_t mode,
Expand Down Expand Up @@ -1454,7 +1458,7 @@ void IRac::mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac,
/// @param[in] econo Run the device in economical mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter 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. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
Expand Down Expand Up @@ -1496,7 +1500,7 @@ void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac,
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::neoclima(IRNeoclimaAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
Expand Down Expand Up @@ -1621,7 +1625,7 @@ void IRac::samsung(IRSamsungAc *ac,
/// @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.
/// @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,
Expand Down Expand Up @@ -1751,7 +1755,7 @@ void IRac::tcl112(IRTcl112Ac *ac,
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::teco(IRTecoAc *ac,
const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
Expand Down Expand Up @@ -1820,7 +1824,7 @@ void IRac::toshiba(IRToshibaAC *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] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::trotec(IRTrotecESP *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
Expand Down Expand Up @@ -1854,7 +1858,7 @@ void IRac::trotec(IRTrotecESP *ac,
/// @param[in] swingv The vertical swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
/// @param[in] sendNormal Do we send a Normal settings message at all?
/// i.e In addition to the clock/time/timer message
Expand Down Expand Up @@ -1886,6 +1890,48 @@ void IRac::vestel(IRVestelAc *ac,
}
#endif // SEND_VESTEL_AC

#if SEND_VOLTAS
/// Send a Voltas A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRVoltas object to use.
/// @param[in] model The A/C model 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] swingh The horizontal swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] econo Run the device in economical mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::voltas(IRVoltas *ac,
const voltas_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool turbo, const bool econo, const bool light,
const int16_t sleep) {
ac->begin();
ac->setModel(model);
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwingV(swingv != stdAc::swingv_t::kOff);
ac->setSwingH(swingh != stdAc::swingh_t::kOff);
// No Quiet setting available.
ac->setTurbo(turbo);
ac->setEcono(econo);
ac->setLight(light);
// No Filter setting available.
// No Clean setting available.
// No Beep setting available.
ac->setSleep(sleep >= 0); // Sleep is either on/off, so convert to boolean.
// No Clock setting available.
ac->send();
}
#endif // SEND_VOLTAS

#if SEND_WHIRLPOOL_AC
/// Send a Whirlpool A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRWhirlpoolAc object to use.
Expand All @@ -1897,7 +1943,7 @@ void IRac::vestel(IRVestelAc *ac,
/// @param[in] swingv The vertical swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
void IRac::whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode,
Expand Down Expand Up @@ -2451,6 +2497,16 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_VESTEL_AC
#if SEND_VOLTAS
case VOLTAS:
{
IRVoltas ac(_pin, _inverted, _modulation);
voltas(&ac, (voltas_ac_remote_model_t)send.model, send.power, send.mode,
degC, send.fanspeed, send.swingv, send.swingh, send.turbo,
send.econo, send.light, send.sleep);
break;
}
#endif // SEND_VOLTAS
#if SEND_WHIRLPOOL_AC
case WHIRLPOOL_AC:
{
Expand Down Expand Up @@ -2667,6 +2723,11 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return fujitsu_ac_remote_model_t::ARJW2;
} else if (!strcasecmp(str, "ARRY4")) {
return fujitsu_ac_remote_model_t::ARRY4;
// LG A/C models
} else if (!strcasecmp(str, "GE6711AR2853M")) {
return lg_ac_remote_model_t::GE6711AR2853M;
} else if (!strcasecmp(str, "AKB75215403")) {
return lg_ac_remote_model_t::AKB75215403;
// Panasonic A/C families
} else if (!strcasecmp(str, "LKE") || !strcasecmp(str, "PANASONICLKE")) {
return panasonic_ac_remote_model_t::kPanasonicLke;
Expand All @@ -2681,6 +2742,9 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return panasonic_ac_remote_model_t::kPanasonicCkp;
} else if (!strcasecmp(str, "RKR") || !strcasecmp(str, "PANASONICRKR")) {
return panasonic_ac_remote_model_t::kPanasonicRkr;
// Voltas A/C models
} else if (!strcasecmp(str, "122LZF")) {
return voltas_ac_remote_model_t::kVoltas122LZF;
// Whirlpool A/C models
} else if (!strcasecmp(str, "DG11J13A") || !strcasecmp(str, "DG11J104") ||
!strcasecmp(str, "DG11J1-04")) {
Expand Down Expand Up @@ -3113,6 +3177,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_VESTEL_AC
#if DECODE_VOLTAS
case decode_type_t::VOLTAS: {
IRVoltas ac(kGpioUnused);
ac.setRaw(result->state);
return ac.toString();
}
#endif // DECODE_VOLTAS
#if DECODE_TECO
case decode_type_t::TECO: {
IRTecoAc ac(kGpioUnused);
Expand Down Expand Up @@ -3514,6 +3585,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_VESTEL_AC
#if DECODE_VOLTAS
case decode_type_t::VOLTAS: {
IRVoltas ac(kGpioUnused);
ac.setRaw(decode->state);
*result = ac.toCommon(prev);
break;
}
#endif // DECODE_VOLTAS
#if DECODE_WHIRLPOOL_AC
case decode_type_t::WHIRLPOOL_AC: {
IRWhirlpoolAc ac(kGpioUnused);
Expand Down
9 changes: 9 additions & 0 deletions src/IRac.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ir_Toshiba.h"
#include "ir_Trotec.h"
#include "ir_Vestel.h"
#include "ir_Voltas.h"
#include "ir_Whirlpool.h"

// Constants
Expand Down Expand Up @@ -405,6 +406,14 @@ void electra(IRElectraAc *ac,
const int16_t sleep = -1, const int16_t clock = -1,
const bool sendNormal = true);
#endif // SEND_VESTEL_AC
#if SEND_VOLTAS
void voltas(IRVoltas *ac, const voltas_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool turbo, const bool econo, const bool light,
const int16_t sleep = -1);
#endif // SEND_VOLTAS
#if SEND_WHIRLPOOL_AC
void whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const float degrees,
Expand Down
6 changes: 6 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ enum panasonic_ac_remote_model_t {
kPanasonicRkr = 6,
};

/// Voltas A/C model numbers
enum voltas_ac_remote_model_t {
kVoltasUnknown = 0, // Full Function
kVoltas122LZF = 1, // (1) 122LZF (No SwingH support) (Default)
};

/// Whirlpool A/C model numbers
enum whirlpool_ac_remote_model_t {
DG11J13A = 1, // DG11J1-04 too
Expand Down
6 changes: 6 additions & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,12 @@ namespace irutils {
default: return kUnknownStr;
}
break;
case decode_type_t::VOLTAS:
switch (model) {
case voltas_ac_remote_model_t::kVoltas122LZF: return F("122LZF");
default: return kUnknownStr;
}
break;
case decode_type_t::WHIRLPOOL_AC:
switch (model) {
case whirlpool_ac_remote_model_t::DG11J13A: return F("DG11J13A");
Expand Down
Loading

0 comments on commit ea79247

Please sign in to comment.