Merge pull request #1 from ToniA/master
Merge main repository to this fork
This commit is contained in:
commit
0773d6a437
|
@ -10,16 +10,16 @@ BalluHeatpumpIR::BalluHeatpumpIR()
|
|||
}
|
||||
|
||||
|
||||
void BalluHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd)
|
||||
void BalluHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
|
||||
{
|
||||
// Sensible defaults for the heat pump mode
|
||||
|
||||
|
||||
uint8_t operatingMode = BALLU_AIRCON_MODE_COOL;
|
||||
uint8_t fanSpeed = BALLU_AIRCON_FAN_AUTO;
|
||||
uint8_t temperature = 21;
|
||||
uint8_t powerMode = 00;
|
||||
|
||||
|
||||
|
||||
|
||||
if (powerModeCmd == POWER_OFF)
|
||||
{
|
||||
powerMode = BALLU_AIRCON_MODE_OFF;
|
||||
|
@ -43,7 +43,7 @@ void BalluHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operating
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (fanSpeedCmd)
|
||||
{
|
||||
case FAN_AUTO:
|
||||
|
@ -59,12 +59,11 @@ void BalluHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operating
|
|||
fanSpeed = BALLU_AIRCON_FAN3;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (temperatureCmd > 15 && temperatureCmd < 31)
|
||||
{
|
||||
temperature = temperatureCmd;
|
||||
}
|
||||
|
||||
sendBallu(IR, powerMode, operatingMode, fanSpeed, temperature);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class BalluHeatpumpIR : public HeatpumpIR
|
|||
{
|
||||
public:
|
||||
BalluHeatpumpIR();
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
|
||||
|
||||
private:
|
||||
void sendBallu(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature);
|
||||
|
|
|
@ -10,6 +10,12 @@ DaikinHeatpumpARC480A14IR::DaikinHeatpumpARC480A14IR() : HeatpumpIR()
|
|||
}
|
||||
|
||||
|
||||
void DaikinHeatpumpARC480A14IR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
|
||||
{
|
||||
send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd,
|
||||
DAIKIN_AIRCON_COMFORT_OFF, DAIKIN_AIRCON_ECONO_OFF, DAIKIN_AIRCON_SENSOR_OFF, DAIKIN_AIRCON_QUIET_OFF, DAIKIN_AIRCON_POWERFUL_OFF);
|
||||
}
|
||||
|
||||
// Daikin numeric values to command bytes
|
||||
void DaikinHeatpumpARC480A14IR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, uint8_t comfortModeCmd, uint8_t econoCmd, uint8_t sensorCmd, uint8_t quietCmd, uint8_t powerfulCmd)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@ class DaikinHeatpumpARC480A14IR : public HeatpumpIR
|
|||
{
|
||||
public:
|
||||
DaikinHeatpumpARC480A14IR();
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, uint8_t comfortMode, uint8_t econo, uint8_t sensor, uint8_t quiet, uint8_t powerful);
|
||||
private:
|
||||
void sendDaikin(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH, uint8_t comfortMode, uint8_t econo, uint8_t sensor, uint8_t quiet, uint8_t powerful);
|
||||
|
|
|
@ -36,12 +36,28 @@ GreeYAAHeatpumpIR::GreeYAAHeatpumpIR() : GreeHeatpumpIR()
|
|||
greeModel = GREE_YAA;
|
||||
}
|
||||
|
||||
// Support for YAC1FBF remote
|
||||
GreeYACHeatpumpIR::GreeYACHeatpumpIR() : GreeHeatpumpIR()
|
||||
{
|
||||
static const char model[] PROGMEM = "greeyac";
|
||||
static const char info[] PROGMEM = "{\"mdl\":\"greeyac\",\"dn\":\"Gree YAC\",\"mT\":16,\"xT\":30,\"fs\":3}";
|
||||
|
||||
_model = model;
|
||||
_info = info;
|
||||
greeModel = GREE_YAC;
|
||||
}
|
||||
|
||||
void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
|
||||
{
|
||||
send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd, false);
|
||||
}
|
||||
|
||||
void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode)
|
||||
{
|
||||
send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd, false, turboMode);
|
||||
}
|
||||
|
||||
void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode, bool iFeelMode)
|
||||
{
|
||||
(void)swingVCmd;
|
||||
(void)swingHCmd;
|
||||
|
@ -55,6 +71,7 @@ void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingM
|
|||
uint8_t swingV = GREE_VDIR_AUTO;
|
||||
uint8_t swingH = GREE_HDIR_AUTO;
|
||||
|
||||
|
||||
if (powerModeCmd == POWER_OFF)
|
||||
{
|
||||
powerMode = GREE_AIRCON1_POWER_OFF;
|
||||
|
@ -126,7 +143,7 @@ void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingM
|
|||
}
|
||||
}
|
||||
|
||||
if (greeModel == GREE_YAA)
|
||||
if (greeModel == GREE_YAA || greeModel == GREE_YAC)
|
||||
{
|
||||
switch (swingVCmd)
|
||||
{
|
||||
|
@ -152,6 +169,32 @@ void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingM
|
|||
swingV = GREE_VDIR_DOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (greeModel == GREE_YAC)
|
||||
{
|
||||
switch (swingHCmd)
|
||||
{
|
||||
case HDIR_AUTO:
|
||||
case HDIR_SWING:
|
||||
swingH = GREE_HDIR_SWING;
|
||||
break;
|
||||
case HDIR_LEFT:
|
||||
swingH = GREE_HDIR_LEFT;
|
||||
break;
|
||||
case HDIR_MLEFT:
|
||||
swingH = GREE_HDIR_MLEFT;
|
||||
break;
|
||||
case HDIR_MIDDLE:
|
||||
swingH = GREE_HDIR_MIDDLE;
|
||||
break;
|
||||
case HDIR_MRIGHT:
|
||||
swingH = GREE_HDIR_MRIGHT;
|
||||
break;
|
||||
case HDIR_RIGHT:
|
||||
swingH = GREE_HDIR_RIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,11 +203,11 @@ void GreeHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingM
|
|||
temperature = temperatureCmd - 16;
|
||||
}
|
||||
|
||||
sendGree(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH, false);
|
||||
sendGree(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH, turboMode, iFeelMode);
|
||||
}
|
||||
|
||||
// Send the Gree code
|
||||
void GreeHeatpumpIR::sendGree(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH, bool turboMode)
|
||||
void GreeHeatpumpIR::sendGree(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH, bool turboMode, bool iFeelMode)
|
||||
{
|
||||
(void)swingH;
|
||||
|
||||
|
@ -191,7 +234,15 @@ void GreeHeatpumpIR::sendGree(IRSender& IR, uint8_t powerMode, uint8_t operating
|
|||
|
||||
GreeTemplate[4] = swingV;
|
||||
}
|
||||
if (greeModel == GREE_YAA)
|
||||
if (greeModel == GREE_YAC)
|
||||
{
|
||||
GreeTemplate[4] |= (swingH << 4);
|
||||
if (iFeelMode)
|
||||
{
|
||||
GreeTemplate[5] |= (1 << 3);
|
||||
}
|
||||
}
|
||||
if (greeModel == GREE_YAA || greeModel == GREE_YAC)
|
||||
{
|
||||
// GreeTemplate[2] = 0xE0; // bits 0..3 always 0000, bits 4..7 TURBO,LIGHT,HEALTH,X-FAN
|
||||
GreeTemplate[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO,LIGHT,HEALTH,X-FAN
|
||||
|
@ -261,6 +312,30 @@ void GreeHeatpumpIR::sendGree(IRSender& IR, uint8_t powerMode, uint8_t operating
|
|||
IR.sendIRbyte(GreeTemplate[i], GREE_AIRCON1_BIT_MARK, GREE_AIRCON1_ZERO_SPACE, GREE_AIRCON1_ONE_SPACE);
|
||||
}
|
||||
|
||||
// End mark
|
||||
IR.mark(GREE_AIRCON1_BIT_MARK);
|
||||
IR.space(0);
|
||||
}
|
||||
|
||||
// Sends current sensed temperatures, YAC remotes/supporting units only
|
||||
void GreeYACHeatpumpIR::send(IRSender& IR, uint8_t currentTemperature)
|
||||
{
|
||||
uint8_t GreeTemplate[] = { 0x00, 0x00 };
|
||||
|
||||
GreeTemplate[0] = currentTemperature;
|
||||
GreeTemplate[1] = 0xA5;
|
||||
|
||||
// 38 kHz PWM frequency
|
||||
IR.setFrequency(38);
|
||||
|
||||
// Send Header mark
|
||||
IR.mark(GREE_AIRCON1_HDR_MARK);
|
||||
IR.space(GREE_AIRCON1_HDR_SPACE);
|
||||
|
||||
// send payload
|
||||
IR.sendIRbyte(GreeTemplate[0], GREE_AIRCON1_BIT_MARK, GREE_AIRCON1_ZERO_SPACE, GREE_AIRCON1_ONE_SPACE);
|
||||
IR.sendIRbyte(GreeTemplate[1], GREE_AIRCON1_BIT_MARK, GREE_AIRCON1_ZERO_SPACE, GREE_AIRCON1_ONE_SPACE);
|
||||
|
||||
// End mark
|
||||
IR.mark(GREE_AIRCON1_BIT_MARK);
|
||||
IR.space(0);
|
||||
|
|
|
@ -44,21 +44,22 @@
|
|||
#define GREE_VDIR_MDOWN 0x05
|
||||
#define GREE_VDIR_DOWN 0x06
|
||||
|
||||
// Not available in this model.
|
||||
// Only available on YAC
|
||||
// Horizontal air directions. Note that these cannot be set on all heat pumps
|
||||
#define GREE_HDIR_AUTO 0
|
||||
#define GREE_HDIR_MANUAL 0
|
||||
#define GREE_HDIR_SWING 0
|
||||
#define GREE_HDIR_MIDDLE 0
|
||||
#define GREE_HDIR_LEFT 0
|
||||
#define GREE_HDIR_MLEFT 0
|
||||
#define GREE_HDIR_MRIGHT 0
|
||||
#define GREE_HDIR_RIGHT 0
|
||||
#define GREE_HDIR_AUTO 0x00
|
||||
#define GREE_HDIR_MANUAL 0x00
|
||||
#define GREE_HDIR_SWING 0x01
|
||||
#define GREE_HDIR_LEFT 0x02
|
||||
#define GREE_HDIR_MLEFT 0x03
|
||||
#define GREE_HDIR_MIDDLE 0x04
|
||||
#define GREE_HDIR_MRIGHT 0x05
|
||||
#define GREE_HDIR_RIGHT 0x06
|
||||
|
||||
// Gree model codes
|
||||
#define GREE_GENERIC 0
|
||||
#define GREE_YAN 1
|
||||
#define GREE_YAA 2
|
||||
#define GREE_YAC 3
|
||||
|
||||
|
||||
class GreeHeatpumpIR : public HeatpumpIR
|
||||
|
@ -70,9 +71,10 @@ class GreeHeatpumpIR : public HeatpumpIR
|
|||
public:
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd , uint8_t fanSpeedCmd , uint8_t temperatureCmd , uint8_t swingVCmd , uint8_t swingHCmd, bool turboMode);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd , uint8_t fanSpeedCmd , uint8_t temperatureCmd , uint8_t swingVCmd , uint8_t swingHCmd, bool turboMode, bool iFeelMode);
|
||||
|
||||
private:
|
||||
void sendGree(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH, bool turboMode);
|
||||
void sendGree(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, uint8_t swingH, bool turboMode, bool iFeelMode);
|
||||
};
|
||||
|
||||
class GreeGenericHeatpumpIR : public GreeHeatpumpIR
|
||||
|
@ -87,7 +89,10 @@ class GreeYANHeatpumpIR : public GreeHeatpumpIR
|
|||
GreeYANHeatpumpIR();
|
||||
|
||||
public:
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode)
|
||||
{
|
||||
GreeHeatpumpIR::send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd, turboMode);
|
||||
}
|
||||
};
|
||||
|
||||
class GreeYAAHeatpumpIR : public GreeHeatpumpIR
|
||||
|
@ -96,7 +101,23 @@ class GreeYAAHeatpumpIR : public GreeHeatpumpIR
|
|||
GreeYAAHeatpumpIR();
|
||||
|
||||
public:
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode);
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode)
|
||||
{
|
||||
GreeHeatpumpIR::send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd, turboMode);
|
||||
}
|
||||
};
|
||||
|
||||
class GreeYACHeatpumpIR : public GreeHeatpumpIR
|
||||
{
|
||||
public:
|
||||
GreeYACHeatpumpIR();
|
||||
|
||||
public:
|
||||
void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd, bool turboMode, bool iFeelMode)
|
||||
{
|
||||
GreeHeatpumpIR::send(IR, powerModeCmd, operatingModeCmd, fanSpeedCmd, temperatureCmd, swingVCmd, swingHCmd, turboMode, iFeelMode);
|
||||
}
|
||||
void send(IRSender& IR, uint8_t currentTemperature);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,12 @@ HeatpumpIR* HeatpumpIRFactory::create(const char *modelName) {
|
|||
return new CarrierMCAHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("carrier_nqv")) == 0) {
|
||||
return new CarrierNQVHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("daikin_arc417")) == 0) {
|
||||
return new DaikinHeatpumpARC417IR();
|
||||
} else if (strcmp_P(modelName, PSTR("daikin_arc480")) == 0) {
|
||||
return new DaikinHeatpumpARC480A14IR();
|
||||
} else if (strcmp_P(modelName, PSTR("daikin")) == 0) {
|
||||
return new DaikinHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("fuego")) == 0) {
|
||||
return new FuegoHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("fujitsu_awyz")) == 0) {
|
||||
|
@ -71,7 +77,9 @@ HeatpumpIR* HeatpumpIRFactory::create(const char *modelName) {
|
|||
return new ToshibaDaiseikaiHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("toshiba")) == 0) {
|
||||
return new ToshibaHeatpumpIR();
|
||||
} else if (strcmp_P(modelName, PSTR("ZHLT01")) == 0) {
|
||||
return new ZHLT01HeatpumpIR();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <BalluHeatpumpIR.h>
|
||||
#include <CarrierHeatpumpIR.h>
|
||||
#include <DaikinHeatpumpIR.h>
|
||||
#include <DaikinHeatpumpARC417IR.h>
|
||||
#include <DaikinHeatpumpARC480A14IR.h>
|
||||
#include <FuegoHeatpumpIR.h>
|
||||
#include <FujitsuHeatpumpIR.h>
|
||||
#include <GreeHeatpumpIR.h>
|
||||
|
@ -24,7 +26,7 @@
|
|||
#include <SharpHeatpumpIR.h>
|
||||
#include <ToshibaDaiseikaiHeatpumpIR.h>
|
||||
#include <ToshibaHeatpumpIR.h>
|
||||
|
||||
#include <ZHLT01HeatpumpIR.h>
|
||||
|
||||
class HeatpumpIRFactory
|
||||
{
|
||||
|
@ -35,4 +37,4 @@ class HeatpumpIRFactory
|
|||
static HeatpumpIR* create(const char *modelName);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -93,9 +93,48 @@ void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
|
|||
powerMode = MITSUBISHI_AIRCON1_MODE_OFF;
|
||||
}
|
||||
|
||||
if (_mitsubishiModel != MITSUBISHI_MSY)
|
||||
if (_mitsubishiModel == MITSUBISHI_FA) // set operating model for FA
|
||||
{
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_AUTO;
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_HEAT;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_DRY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_mitsubishiModel == MITSUBISHI_MSY)
|
||||
{
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_COOL;
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_IFEEL;
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = MITSUBISHI_AIRCON1_MODE_HEAT;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = MITSUBISHI_AIRCON1_MODE_DRY;
|
||||
break;
|
||||
case MODE_FAN:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_FAN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("Mode=%d\n",operatingModeCmd);
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
|
@ -129,43 +168,6 @@ void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (_mitsubishiModel == MITSUBISHI_FA) // set operating model for FA
|
||||
{
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_AUTO;
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_HEAT;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = MITSUBISHI_AIRCON3_MODE_DRY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_COOL;
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_IFEEL;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_DRY;
|
||||
break;
|
||||
case MODE_FAN:
|
||||
operatingMode = MITSUBISHI_AIRCON2_MODE_FAN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (fanSpeedCmd)
|
||||
{
|
||||
|
@ -282,8 +284,8 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8
|
|||
// KJ has a bit different template
|
||||
if (_mitsubishiModel == MITSUBISHI_KJ) {
|
||||
MitsubishiTemplate[15] = 0x00;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Set the operatingmode on the template message
|
||||
MitsubishiTemplate[5] = powerMode;
|
||||
MitsubishiTemplate[6] = operatingMode;
|
||||
|
@ -303,12 +305,12 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8
|
|||
// Set the fan speed and vertical air direction on the template message
|
||||
MitsubishiTemplate[9] = fanSpeed | swingV;
|
||||
|
||||
|
||||
|
||||
|
||||
if (_mitsubishiModel == MITSUBISHI_KJ) {
|
||||
MitsubishiTemplate[8] = 0;
|
||||
if ( operatingMode == MITSUBISHI_AIRCON1_MODE_AUTO || operatingMode == MITSUBISHI_AIRCON1_MODE_COOL )
|
||||
MitsubishiTemplate[8] = 0x6;
|
||||
MitsubishiTemplate[8] = 0x6;
|
||||
if ( operatingMode == MITSUBISHI_AIRCON1_MODE_DRY )
|
||||
MitsubishiTemplate[8] = 0x2;
|
||||
|
||||
|
@ -319,20 +321,24 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8
|
|||
|
||||
#ifdef USE_TIME_H
|
||||
time(&now);
|
||||
timeinfo = localtime(&now);
|
||||
|
||||
timeinfo = localtime(&now);
|
||||
|
||||
MitsubishiTemplate[10] = (uint8_t)(timeinfo->tm_hour * 60 + timeinfo->tm_min)/6;
|
||||
#endif
|
||||
|
||||
#ifdef IR_SEND_TIME
|
||||
if (_mitsubishiModel == MITSUBISHI_KJ) {
|
||||
#ifdef DEBUG
|
||||
Serial.printf("Send time %02d:%02d day %d --> %x\n", sendHour, sendMinute, sendWeekday, (sendHour * 60 + sendMinute)/10);
|
||||
#endif
|
||||
MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/10);
|
||||
// Sunday is start if week , value 1
|
||||
MitsubishiTemplate[14] = TempTranslate[( sendWeekday - 1 ) % 7];
|
||||
MitsubishiTemplate[14] = TempTranslate[( sendWeekday - 1 ) % 7];
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
Serial.printf("Send time %02d:%02d --> %x\n", sendHour, sendMinute, (sendHour * 60 + sendMinute)/6);
|
||||
#endif
|
||||
MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/6);
|
||||
}
|
||||
#endif
|
||||
|
@ -385,5 +391,3 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8
|
|||
IR.mark(MITSUBISHI_AIRCON1_BIT_MARK);
|
||||
IR.space(0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,14 +28,13 @@
|
|||
#define MITSUBISHI_AIRCON2_MODE_COOL 0x18 // MSY cool mode
|
||||
#define MITSUBISHI_AIRCON3_MODE_COOL 0x58 // FA cool mode
|
||||
#define MITSUBISHI_AIRCON1_MODE_DRY 0x10
|
||||
#define MITSUBISHI_AIRCON2_MODE_DRY 0x18 // MSY DRY mode
|
||||
#define MITSUBISHI_AIRCON3_MODE_DRY 0x50 // FA dry mode
|
||||
#define MITSUBISHI_AIRCON1_MODE_FAN 0x38 // EF 'FAN' mode
|
||||
#define MITSUBISHI_AIRCON2_MODE_FAN 0x38 // MSY fan mode
|
||||
#define MITSUBISHI_AIRCON1_MODE_ISEE 0x40 // Isee
|
||||
#define MITSUBISHI_AIRCON2_MODE_IFEEL 0x00 // MSY
|
||||
|
||||
#define MITSUBISHI_AIRCON1_MODE_OFF 0x00 // Power FFi
|
||||
#define MITSUBISHI_AIRCON1_MODE_OFF 0x00 // Power OFF
|
||||
#define MITSUBISHI_AIRCON1_MODE_ON 0x20 // Power ON
|
||||
|
||||
// Mitsubishi fan codes
|
||||
|
|
10
README.md
10
README.md
|
@ -4,7 +4,7 @@ Original location: https://github.com/ToniA/arduino-heatpumpir
|
|||
|
||||
For concrete examples, see the MySensors (Arduino + nRF24 radio) and ESPEasy (ESP8266 modules) integrations:
|
||||
* https://github.com/mysensors/MySensorsArduinoExamples/tree/master/examples/HeatpumpIRController
|
||||
* https://github.com/ToniA/ESPEasy/blob/master/ESPEasy/_P115_HeatpumpIR.ino
|
||||
* https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/src/_P088_HeatpumpIR.ino
|
||||
|
||||
An Arduino library to control pump/split unit air conditioner. Currently supporting at least these models:
|
||||
|
||||
|
@ -14,7 +14,7 @@ An Arduino library to control pump/split unit air conditioner. Currently support
|
|||
* Hisense AUD (remote control Y-H1-01, Y-H1-02(E), Y-J1, Y-E4-07) probably AUC model
|
||||
* Hyundai (remote control P/N Y512F2)
|
||||
* This is probably a generic Gree model
|
||||
* Model H-AR21-07H (remote control P/N YKR-P/002E) confirmed as AUX
|
||||
* Models H-AR21-07H / H-AR16-09H (remote control P/N YKR-P/002E) confirmed as AUX
|
||||
* Fujitsu Nocria AWYZ14 (remote control P/N AR-PZ2)
|
||||
* Also Fujitsu remote controls RY3-AR and AR-RCE1E
|
||||
* IVT AY-XP12FR-N (remote control CRMC-A673JBEZ)
|
||||
|
@ -33,6 +33,7 @@ An Arduino library to control pump/split unit air conditioner. Currently support
|
|||
* Panasonic E9/E12-JKE and E9/E12-NKE
|
||||
* Samsung
|
||||
* AQV12PSBN / AQV09ASA
|
||||
* AQV12MSAN, Remote Control ARH-1362
|
||||
* Samsung FJM (RJ040F2HXEA / 2XMH026FNEA), Remote Control P/N ARH-465
|
||||
* Sharp AY-ZP40KR (remote control P/N CRMC-A788JBEZ), possibly also IVT
|
||||
* Toshiba Daiseikai (Toshiba remote control P/N WH-TA01EE).
|
||||
|
@ -40,7 +41,10 @@ An Arduino library to control pump/split unit air conditioner. Currently support
|
|||
* Tested with: RAS-10G2KVP-E RAS-10G2AVP-E and RAS-13G2KVP-E RAS-13G2AVP-E
|
||||
* Tosot T18H-SN/I (remote control P/N YAA1FB) as GreeYAA variant
|
||||
* Also marketed as Tadiran brand
|
||||
|
||||
* ZH/LT-01 remote control
|
||||
* Brands: Eurom, Chigo, Tristar, Tecnomaster, Elgin, Geant, Tekno, Topair,
|
||||
Proma, Sumikura, JBS, Turbo Air, Nakatomy, Celestial Air, Ager,
|
||||
Blueway, Airlux, etc.
|
||||
|
||||
|
||||
## Instructions
|
||||
|
|
|
@ -20,6 +20,16 @@ SamsungAQVHeatpumpIR::SamsungAQVHeatpumpIR() : SamsungHeatpumpIR()
|
|||
_info = info;
|
||||
}
|
||||
|
||||
SamsungAQV12MSANHeatpumpIR::SamsungAQV12MSANHeatpumpIR() : SamsungAQVHeatpumpIR()
|
||||
{
|
||||
static const char model[] PROGMEM = "samsung_aqv12msan";
|
||||
static const char info[] PROGMEM = "{\"mdl\":\"samsung_aqv12msan\",\"dn\":\"Samsung AQV12MSAN\",\"mT\":16,\"xT\":27,\"fs\":4}";
|
||||
|
||||
_model = model;
|
||||
_info = info;
|
||||
_samsungAQVModel = MODEL_AQV12_MSAN;
|
||||
}
|
||||
|
||||
SamsungFJMHeatpumpIR::SamsungFJMHeatpumpIR() : SamsungHeatpumpIR()
|
||||
{
|
||||
static const char model[] PROGMEM = "samsung_fjm";
|
||||
|
@ -44,41 +54,29 @@ void SamsungAQVHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
|
|||
uint8_t temperature = 23;
|
||||
uint8_t swingV = SAMSUNG_AIRCON1_VS_AUTO;
|
||||
|
||||
if (powerModeCmd == POWER_OFF)
|
||||
{
|
||||
powerMode = SAMSUNG_AIRCON1_MODE_OFF;
|
||||
|
||||
if (operatingModeCmd == MODE_COOL) // Cooling-only models need to have COOL as the operating mode in power off
|
||||
{
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_COOL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_AUTO;
|
||||
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in AUTO mode
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_HEAT;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_DRY;
|
||||
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in DRY mode
|
||||
break;
|
||||
case MODE_FAN:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_FAN;
|
||||
if ( fanSpeedCmd == FAN_AUTO ) {
|
||||
fanSpeedCmd = FAN_1; // Fan speed cannot be 'AUTO' in FAN mode
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_AUTO:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_AUTO;
|
||||
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in AUTO mode
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_HEAT;
|
||||
break;
|
||||
case MODE_COOL:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_COOL;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_DRY;
|
||||
fanSpeedCmd = FAN_AUTO; // Fan speed is always 'AUTO' in DRY mode
|
||||
break;
|
||||
case MODE_FAN:
|
||||
operatingMode = SAMSUNG_AIRCON1_MODE_FAN;
|
||||
if ( fanSpeedCmd == FAN_AUTO ) {
|
||||
fanSpeedCmd = FAN_1; // Fan speed cannot be 'AUTO' in FAN mode
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fanSpeedCmd)
|
||||
{
|
||||
|
@ -108,6 +106,23 @@ void SamsungAQVHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
|
|||
break;
|
||||
}
|
||||
|
||||
// power offmode is something special, so set it latest to treat
|
||||
if (powerModeCmd == POWER_OFF)
|
||||
{
|
||||
powerMode = SAMSUNG_AIRCON1_MODE_OFF;
|
||||
if (_samsungAQVModel == MODEL_AQV12_MSAN)
|
||||
{
|
||||
if (operatingModeCmd != MODE_AUTO)
|
||||
{
|
||||
swingV = 0xFF;
|
||||
}
|
||||
if (operatingModeCmd == MODE_AUTO)
|
||||
{
|
||||
fanSpeed = 0x0D; // reverse enginering remote
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendSamsung(IR, powerMode, operatingMode, fanSpeed, temperature, swingV);
|
||||
}
|
||||
|
||||
|
@ -157,7 +172,17 @@ void SamsungAQVHeatpumpIR::sendSamsung(IRSender& IR, uint8_t powerMode, uint8_t
|
|||
SamsungChecksum <<= 4;
|
||||
SamsungChecksum += 0x02;
|
||||
|
||||
SamsungTemplate[15] = SamsungChecksum;
|
||||
// for some unknown reason the checksum is different when powering off for the model Samsung AQV12MSAN
|
||||
if (_samsungAQVModel == MODEL_AQV12_MSAN
|
||||
&& powerMode == SAMSUNG_AIRCON1_MODE_OFF
|
||||
&& (operatingMode == SAMSUNG_AIRCON1_MODE_HEAT || operatingMode == SAMSUNG_AIRCON1_MODE_COOL))
|
||||
{
|
||||
SamsungTemplate[15] = 0x02; // reverse enginering remote
|
||||
}
|
||||
else
|
||||
{
|
||||
SamsungTemplate[15] = SamsungChecksum;
|
||||
}
|
||||
|
||||
// 38 kHz PWM frequency
|
||||
IR.setFrequency(38);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Samsung AQV12PSBN / AQV09ASA heatpump control (remote control P/N zzz)
|
||||
Samsung AQV12MSAN (remote control ARH-1362)
|
||||
Samsung FJM (RJ040F2HXEA / MH026FNEA) heatpump control (remote control P/N ARH-465)
|
||||
*/
|
||||
#ifndef SamsungHeatpumpIR_h
|
||||
|
@ -47,11 +48,13 @@
|
|||
#define SAMSUNG_AIRCON2_VS_AUTO 0xF0
|
||||
#define SAMSUNG_AIRCON2_TURBO 0x06 // 30 minutes of full power
|
||||
|
||||
#define MODEL_AQV12_MSAN 1
|
||||
|
||||
class SamsungHeatpumpIR : public HeatpumpIR
|
||||
{
|
||||
protected:
|
||||
SamsungHeatpumpIR();
|
||||
uint8_t _samsungAQVModel;
|
||||
|
||||
public:
|
||||
virtual void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);
|
||||
|
@ -82,4 +85,10 @@ class SamsungFJMHeatpumpIR : public SamsungHeatpumpIR
|
|||
void sendSamsung(IRSender& IR, uint8_t powerMode, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingV, bool turboMode);
|
||||
};
|
||||
|
||||
class SamsungAQV12MSANHeatpumpIR : public SamsungAQVHeatpumpIR
|
||||
{
|
||||
public:
|
||||
SamsungAQV12MSANHeatpumpIR();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
#include <ZHLT01HeatpumpIR.h>
|
||||
|
||||
ZHLT01HeatpumpIR::ZHLT01HeatpumpIR() : HeatpumpIR()
|
||||
{
|
||||
static const char model[] PROGMEM = "ZHLT01";
|
||||
static const char info[] PROGMEM = "{\"mdl\":\"ZHLT01\",\"dn\":\"ZHLT01\",\"mT\":18,\"xT\":32,\"fs\":3,\"maint\":[10]}}";
|
||||
|
||||
_model = model;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
void ZHLT01HeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd,
|
||||
uint8_t operatingModeCmd,
|
||||
uint8_t fanSpeedCmd,
|
||||
uint8_t temperatureCmd,
|
||||
uint8_t swingVCmd,
|
||||
uint8_t swingHCmd)
|
||||
{
|
||||
|
||||
// Sensible defaults for the heat pump mode
|
||||
|
||||
uint8_t powerMode = AC1_POWER_ON;
|
||||
uint8_t operatingMode = AC1_MODE_AUTO;
|
||||
uint8_t fanSpeed = AC1_FAN_AUTO;
|
||||
uint8_t temperature = 25;
|
||||
uint8_t swingV = AC1_VDIR_FIXED;
|
||||
uint8_t swingH = AC1_HDIR_FIXED;
|
||||
|
||||
if (powerModeCmd == 0)
|
||||
{
|
||||
powerMode = AC1_POWER_OFF;
|
||||
}
|
||||
|
||||
switch (operatingModeCmd)
|
||||
{
|
||||
case MODE_COOL:
|
||||
operatingMode = AC1_MODE_COOL;
|
||||
break;
|
||||
case MODE_FAN:
|
||||
operatingMode = AC1_MODE_FAN;
|
||||
break;
|
||||
case MODE_DRY:
|
||||
operatingMode = AC1_MODE_DRY;
|
||||
temperatureCmd = 25;
|
||||
break;
|
||||
case MODE_HEAT:
|
||||
operatingMode = AC1_MODE_HEAT;
|
||||
break;
|
||||
case MODE_MAINT:
|
||||
operatingMode = AC1_MODE_DRY; // MODE_MAINT not supported
|
||||
temperatureCmd = 30; // Simlulated as DRY at 30°C
|
||||
break;
|
||||
default:
|
||||
operatingMode = AC1_MODE_AUTO;
|
||||
temperatureCmd = 25; // "Auto" = 25°C
|
||||
}
|
||||
|
||||
switch (fanSpeedCmd)
|
||||
{
|
||||
case FAN_AUTO:
|
||||
fanSpeed = AC1_FAN_AUTO;
|
||||
break;
|
||||
case FAN_SILENT:
|
||||
fanSpeed = AC1_FAN_SILENT;
|
||||
break;
|
||||
case FAN_1:
|
||||
fanSpeed = AC1_FAN1;
|
||||
break;
|
||||
case FAN_2:
|
||||
fanSpeed = AC1_FAN2;
|
||||
break;
|
||||
case FAN_3:
|
||||
fanSpeed = AC1_FAN3;
|
||||
break;
|
||||
case FAN_4:
|
||||
if ( operatingMode == AC1_MODE_COOL || operatingMode == AC1_MODE_HEAT )
|
||||
{ fanSpeed = AC1_FAN_TURBO; }
|
||||
else
|
||||
{ fanSpeed = AC1_FAN3; }
|
||||
break;
|
||||
case FAN_5:
|
||||
if ( operatingMode == AC1_MODE_COOL || operatingMode == AC1_MODE_HEAT )
|
||||
{ fanSpeed = AC1_FAN_TURBO; }
|
||||
else
|
||||
{ fanSpeed = AC1_FAN3; }
|
||||
break;
|
||||
}
|
||||
|
||||
switch (swingVCmd)
|
||||
{
|
||||
case VDIR_AUTO:
|
||||
swingV = AC1_VDIR_WIND;
|
||||
break;
|
||||
case VDIR_SWING:
|
||||
swingV = AC1_VDIR_SWING;
|
||||
break;
|
||||
default:
|
||||
swingV = AC1_VDIR_FIXED;
|
||||
}
|
||||
|
||||
switch (swingHCmd)
|
||||
{
|
||||
case HDIR_SWING:
|
||||
swingH = AC1_HDIR_SWING;
|
||||
break;
|
||||
default:
|
||||
swingH = AC1_HDIR_FIXED;
|
||||
}
|
||||
|
||||
// temperature must be between 16 and 32 degrees
|
||||
|
||||
temperature = temperatureCmd;
|
||||
|
||||
if ( temperatureCmd < 16)
|
||||
{
|
||||
temperature = 16;
|
||||
}
|
||||
|
||||
if (temperatureCmd > 32)
|
||||
{
|
||||
temperature = 32;
|
||||
}
|
||||
|
||||
|
||||
sendZHLT01(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH);
|
||||
}
|
||||
|
||||
void ZHLT01HeatpumpIR::sendZHLT01(IRSender& IR, uint8_t powerMode,
|
||||
uint8_t operatingMode,
|
||||
uint8_t fanSpeed,
|
||||
uint8_t temperature,
|
||||
uint8_t swingV,
|
||||
uint8_t swingH)
|
||||
{
|
||||
uint8_t ZHLT01Template[] = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x2A, 0xD5 };
|
||||
// Bytenumbers: 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
|
||||
/********************************************************************************
|
||||
* Byte[03]: Button TURBO used for fanspeed 4 and 5
|
||||
* TURBO ON: Bxxxx1xxx (bit3)
|
||||
* TURBO ON: Bxxxx0xxx
|
||||
*******************************************************************************/
|
||||
if (fanSpeed == AC1_FAN_TURBO)
|
||||
{
|
||||
ZHLT01Template[3] = AC1_FAN_TURBO;
|
||||
ZHLT01Template[2] = ~ ZHLT01Template[3];
|
||||
fanSpeed = AC1_FAN_AUTO;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Byte[07]: POWER, FAN, SLEEP, HORIZONTAL, VERTICAL
|
||||
* POWER ON: B0xxxxx1x
|
||||
* POWER OFF: B0xxxxx0x
|
||||
* VERTICAL SWING: B0xxx01xx
|
||||
* VERTICAL WIND: B0xxx00xx
|
||||
* VERTICAL FIXED: B0xxx10xx
|
||||
* HORIZONTAL SWING: B0xx0xxxx
|
||||
* HORIZONTAL OFF: B0xx1xxxx
|
||||
* FAN AUTO: B000xxxx0
|
||||
* FAN SILENT: B000xxxx1
|
||||
* FAN3: B001xxxx0
|
||||
* FAN2: B010xxxx0
|
||||
* FAN1: B011xxxx0
|
||||
*******************************************************************************/
|
||||
ZHLT01Template[7] = fanSpeed | powerMode | swingV | swingH;
|
||||
ZHLT01Template[6] = ~ ZHLT01Template[7];
|
||||
|
||||
/********************************************************************************
|
||||
* Byte[09]: Mode, Temperature
|
||||
* MODE AUTO: B000xxxxx
|
||||
* MODE COOL: B001xxxxx
|
||||
* MODE VENT: B011xxxxx
|
||||
* MODE DRY: B010xxxxx
|
||||
* MODE HEAT: B100xxxxx
|
||||
* Temperature is determined by bit0-4:
|
||||
* 0x00 = 16C
|
||||
* 0x10 = 32C
|
||||
*******************************************************************************/
|
||||
|
||||
ZHLT01Template[9] = operatingMode | (temperature - 16);
|
||||
ZHLT01Template[8] = ~ ZHLT01Template[9];
|
||||
|
||||
// 38 kHz PWM frequency
|
||||
IR.setFrequency(38);
|
||||
|
||||
// Header
|
||||
IR.mark(AC1_HDR_MARK);
|
||||
IR.space(AC1_HDR_SPACE);
|
||||
|
||||
// Data
|
||||
for (unsigned int i=0; i<sizeof(ZHLT01Template); i++) {
|
||||
IR.sendIRbyte(ZHLT01Template[i], AC1_BIT_MARK, AC1_ZERO_SPACE, AC1_ONE_SPACE);
|
||||
}
|
||||
|
||||
// End mark
|
||||
IR.mark(AC1_BIT_MARK);
|
||||
IR.space(0);
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/********************************************************************************
|
||||
* Airconditional remote control encoder for:
|
||||
*
|
||||
* ZH/LT-01 Remote control https://www.google.com/search?q=zh/lt-01
|
||||
*
|
||||
* The ZH/LT-01 remote control is used for many locally branded Split
|
||||
* airconditioners, so it is better to name this protocol by the name of the
|
||||
* REMOTE rather then the name of the Airconditioner. For this project I used
|
||||
* a 2014 model Eurom-airconditioner, which is Dutch-branded and sold in
|
||||
* the Netherlands at Hornbach.
|
||||
*
|
||||
* For airco-brands:
|
||||
* Eurom
|
||||
* Chigo
|
||||
* Tristar
|
||||
* Tecnomaster
|
||||
* Elgin
|
||||
* Geant
|
||||
* Tekno
|
||||
* Topair
|
||||
* Proma
|
||||
* Sumikura
|
||||
* JBS
|
||||
* Turbo Air
|
||||
* Nakatomy
|
||||
* Celestial Air
|
||||
* Ager
|
||||
* Blueway
|
||||
* Airlux
|
||||
* Etc.
|
||||
*
|
||||
***********************************************************************************
|
||||
* SUMMARY FUNCTIONAL DESCRIPTION
|
||||
**********************************************************************************
|
||||
* The remote sends a 12 Byte message which contains all possible settings every
|
||||
* time.
|
||||
*
|
||||
* Byte 11 (and 10) contain the remote control identifier and are always 0xD5 and
|
||||
* 0x2A respectively for the ZH/LT-01 remote control.
|
||||
* Every UNeven Byte (01,03,05,07 and 09) holds command data
|
||||
* Every EVEN Byte (00,02,04,06,08 and 10) holds a checksum of the corresponding
|
||||
* command-, or identifier-byte by _inverting_ the bits, for example:
|
||||
*
|
||||
* The identifier byte[11] = 0xD5 = B1101 0101
|
||||
* The checksum byte[10] = 0x2A = B0010 1010
|
||||
*
|
||||
* So, you can check the message by:
|
||||
* - inverting the bits of the checksum byte with the corresponding command-, or
|
||||
* identifier byte, they should me the same, or
|
||||
* - Summing up the checksum byte and the corresponding command-, or identifier byte,
|
||||
* they should always add up to 0xFF = B11111111 = 255
|
||||
*
|
||||
* Control bytes:
|
||||
* [01] - Timer (1-24 hours, Off)
|
||||
* Time is hardcoded to OFF
|
||||
*
|
||||
* [03] - LAMP ON/OFF, TURBO ON/OFF, HOLD ON/OFF
|
||||
* Lamp and Hold are hardcoded to OFF
|
||||
* Turbo is used for Cool and Heat is case of FAN_4 or FAN_5
|
||||
*
|
||||
* [05] - Indicates which button the user _pressed_ on the remote control
|
||||
* Hardcoded to POWER-button
|
||||
*
|
||||
* [07] - POWER ON/OFF, FAN AUTO/3/2/1, SLEEP ON/OFF, AIRFLOW ON/OFF,
|
||||
* VERTICAL SWING/WIND/FIXED
|
||||
* SLEEP is used for FAN_SILENT
|
||||
* FAN_4 and FAN_5 are not supported, coded to FAN_3 or Turbo (byte [3])
|
||||
* Vertical Swing supports Fixed, Swing and "Wind"
|
||||
* VDIR_AUTO = Wind
|
||||
* VDIR_SWING = Swing
|
||||
* All others = Fixed
|
||||
*
|
||||
* [09] - MODE AUTO/COOL/VENT/DRY/HEAT, TEMPERATURE (16 - 32°C)
|
||||
* MODE_MAINT is not supported, but implemented as MODE_DRY at 30°C
|
||||
*
|
||||
* ******************************************************************************
|
||||
* Written by: Marcel van der Kooij
|
||||
* Date: 2020-10-29
|
||||
* Version: 1.0
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef ZHLT01HeatpumpIR_h
|
||||
#define ZHLT01HeatpumpIR_h
|
||||
|
||||
#include <HeatpumpIR.h>
|
||||
|
||||
/********************************************************************************
|
||||
* TIMINGS
|
||||
* Space: Not used
|
||||
* Header Mark: 6200 us
|
||||
* Header Space: 7500 us
|
||||
* Bit Mark: 475 us
|
||||
* Zero Space: 525 us
|
||||
* One Space: 1650 us
|
||||
*******************************************************************************/
|
||||
#define AC1_HDR_MARK 6200
|
||||
#define AC1_HDR_SPACE 7500
|
||||
#define AC1_BIT_MARK 475
|
||||
#define AC1_ZERO_SPACE 525
|
||||
#define AC1_ONE_SPACE 1650
|
||||
|
||||
/********************************************************************************
|
||||
*
|
||||
* ZHLT01 codes
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
// Power
|
||||
#define AC1_POWER_OFF 0x00
|
||||
#define AC1_POWER_ON 0x02
|
||||
|
||||
// Operating Modes
|
||||
#define AC1_MODE_AUTO 0x00
|
||||
#define AC1_MODE_COOL 0x20
|
||||
#define AC1_MODE_DRY 0x40
|
||||
#define AC1_MODE_FAN 0x60
|
||||
#define AC1_MODE_HEAT 0x80
|
||||
// MODE_MAINT is not supported, but implemented as DRY at 30°C.
|
||||
|
||||
//Fan control
|
||||
#define AC1_FAN_AUTO 0x00
|
||||
#define AC1_FAN_SILENT 0x01
|
||||
#define AC1_FAN1 0x60
|
||||
#define AC1_FAN2 0x40
|
||||
#define AC1_FAN3 0x20
|
||||
#define AC1_FAN_TURBO 0x08
|
||||
// FAN_4 and FAN_5 are not supported, but are implemented as button "TURBO"
|
||||
// This only works for HEAT and COOL. Otherwise FAN_3 is used.
|
||||
|
||||
// Vertical Swing
|
||||
#define AC1_VDIR_WIND 0x00 // "Natural Wind", implemented on VDIR_AUTO
|
||||
#define AC1_VDIR_SWING 0x04 // Swing
|
||||
#define AC1_VDIR_FIXED 0x08 // All others are not supported
|
||||
// and implemented as Fixed
|
||||
|
||||
// Horizontal Swing
|
||||
#define AC1_HDIR_SWING 0x00 // HDIR_SWING
|
||||
#define AC1_HDIR_FIXED 0x10 // All others are not supported
|
||||
// and implemented as Fixed
|
||||
|
||||
class ZHLT01HeatpumpIR : public HeatpumpIR
|
||||
{
|
||||
public:
|
||||
ZHLT01HeatpumpIR();
|
||||
void send(IRSender& IR, uint8_t powerModeCmd,
|
||||
uint8_t operatingModeCmd,
|
||||
uint8_t fanSpeedCmd,
|
||||
uint8_t temperatureCmd,
|
||||
uint8_t swingVCmd,
|
||||
uint8_t swingHCmd);
|
||||
|
||||
protected:
|
||||
void sendZHLT01(IRSender& IR, uint8_t powerMode,
|
||||
uint8_t operatingMode,
|
||||
uint8_t fanSpeed,
|
||||
uint8_t temperature,
|
||||
uint8_t swingV,
|
||||
uint8_t swingH);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <AUXHeatpumpIR.h>
|
||||
|
||||
// This example based on DaikinTest_MQTT example. Thanks for @nick1802 for sample
|
||||
|
||||
IRSenderESP8266 irSender(4); // Set GPIO pin number here. I use D2 pin on my Wemos D1 mini. See image in this example path
|
||||
AUXHeatpumpIR *heatpumpIR; // This class also works with Hyundai H-AR16-09H model (rc YKR-P/002E)
|
||||
|
||||
// TODO: Make next params manually configurable on first launch
|
||||
|
||||
const char* ssid = "SSID";// your wifi name
|
||||
const char* password = "SSIDPASS"; // your wifi password
|
||||
|
||||
IPAddress ip(192, 168, 1, 100); //ESP static ip
|
||||
IPAddress gateway(192, 168, 1, 1); //Set Gateway
|
||||
IPAddress subnet(255, 255, 255, 0); //Subnet mask
|
||||
const char* mqtt_server = "192.168.1.101"; // MQTT Server address
|
||||
const int mqtt_port = 1883; // MQTT Server port (default: 1883)
|
||||
|
||||
String client_id = "ESP-" + String(ESP.getChipId(), HEX);
|
||||
String power_topic = "homeassistant/ac/" + client_id + "/switch";
|
||||
String mode_topic = "homeassistant/ac/" + client_id + "/mode/set";
|
||||
String fan_topic = "homeassistant/ac/" + client_id + "/fan_speed/set";
|
||||
String temperature_topic = "homeassistant/ac/" + client_id + "/temperature/set";
|
||||
String swing_topic = "homeassistant/ac/" + client_id + "/swing/set";
|
||||
|
||||
int power;
|
||||
int acmode;
|
||||
int fan;
|
||||
int temp;
|
||||
int swing;
|
||||
|
||||
WiFiClient espClient;
|
||||
PubSubClient client(espClient);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(74880);
|
||||
|
||||
setup_wifi();
|
||||
|
||||
heatpumpIR = new AUXHeatpumpIR(); // Initiate IR receiver object
|
||||
|
||||
client.setServer(mqtt_server, mqtt_port);
|
||||
client.setCallback(callback); // Set callback to MQTT client which calls everytime in main loop function
|
||||
|
||||
Serial.println("Topics:");
|
||||
Serial.println(power_topic);
|
||||
Serial.println(mode_topic);
|
||||
Serial.println(fan_topic);
|
||||
Serial.println(temperature_topic);
|
||||
Serial.println(swing_topic);
|
||||
|
||||
// Set default AC settings
|
||||
power = POWER_OFF;
|
||||
acmode = MODE_AUTO;
|
||||
fan = FAN_AUTO;
|
||||
temp = 25;
|
||||
swing = VDIR_SWING;
|
||||
}
|
||||
|
||||
void setup_wifi() {
|
||||
delay(10);
|
||||
WiFi.mode(WIFI_STA); //set wifi to connect to your wifi and not start a AP
|
||||
WiFi.config(ip, gateway, subnet);
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) { // waits for WIFI to connect
|
||||
delay(500);
|
||||
}
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.print("RSSI : ");
|
||||
Serial.println(WiFi.RSSI()); // wifi signal strength
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void reconnect() {
|
||||
while (!client.connected()) {
|
||||
client.loop();
|
||||
if (client.connect(client_id.c_str())) {
|
||||
client.subscribe(power_topic.c_str());
|
||||
client.subscribe(mode_topic.c_str());
|
||||
client.subscribe(fan_topic.c_str());
|
||||
client.subscribe(temperature_topic.c_str());
|
||||
client.subscribe(swing_topic.c_str());
|
||||
} else {
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callback(char* topic, byte* payload, unsigned int length) {
|
||||
String Payload = "";
|
||||
for (int i = 0; i < length; i++) Payload += (char)payload[i];
|
||||
|
||||
if (String(topic) == power_topic) {
|
||||
if (Payload == "ON") power = POWER_ON;
|
||||
else if (Payload == "OFF") power = POWER_OFF;
|
||||
}
|
||||
if (String(topic) == mode_topic) {
|
||||
if (Payload == "heat") acmode = MODE_HEAT;
|
||||
else if (Payload == "cool") acmode = MODE_COOL;
|
||||
else if (Payload == "dry") acmode = MODE_DRY;
|
||||
else if (Payload == "fan_only") acmode = MODE_FAN;
|
||||
else if (Payload == "auto") acmode = MODE_AUTO;
|
||||
}
|
||||
if (String(topic) == fan_topic) {
|
||||
if (Payload == "auto") fan = FAN_AUTO;
|
||||
else if (Payload == "low") fan = FAN_1;
|
||||
else if (Payload == "medium") fan = FAN_2;
|
||||
else if (Payload == "high") fan = FAN_3;
|
||||
}
|
||||
if (String(topic) == temperature_topic) {
|
||||
temp = Payload.toInt();
|
||||
}
|
||||
if (String(topic) == swing_topic) {
|
||||
if (Payload == "on") swing = VDIR_AUTO;
|
||||
else if (Payload == "off") swing = VDIR_SWING;
|
||||
}
|
||||
|
||||
heatpumpIR->send(irSender, power, acmode, fan, temp, swing, 0); // Last zero because my AC doesn't have horizontal swing function
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!client.connected()) reconnect();
|
||||
client.loop();
|
||||
delay(50);
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -0,0 +1,10 @@
|
|||
climate:
|
||||
- platform: mqtt
|
||||
min_temp: 16
|
||||
max_temp: 30
|
||||
precision: 1.0
|
||||
power_command_topic: "homeassistant/ac/{GET IT FROM SERIAL OUTPUT}/switch"
|
||||
mode_command_topic: "homeassistant/ac/{GET IT FROM SERIAL OUTPUT}/mode/set"
|
||||
temperature_command_topic: "homeassistant/ac/{GET IT FROM SERIAL OUTPUT}/temperature/set"
|
||||
fan_mode_command_topic: "homeassistant/ac/{GET IT FROM SERIAL OUTPUT}/fan_speed/set"
|
||||
swing_mode_command_topic: "homeassistant/ac/{GET IT FROM SERIAL OUTPUT}/swing/set"
|
|
@ -0,0 +1,62 @@
|
|||
#include <Arduino.h>
|
||||
#include <GreeHeatpumpIR.h>
|
||||
|
||||
IRSenderPWM irSender(9); // IR led on Duemilanove digital pin 3, using Arduino PWM
|
||||
//IRSenderBlaster irSender(3); // IR led on Duemilanove digital pin 3, using IR Blaster (generates the 38 kHz carrier)
|
||||
|
||||
GreeYACHeatpumpIR *heatpumpIR;
|
||||
|
||||
int redLED = 6;
|
||||
int orangeLED = 5;
|
||||
int greenLED = 4;
|
||||
int blueLED = 3;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
pinMode(redLED, OUTPUT);
|
||||
pinMode(orangeLED, OUTPUT);
|
||||
pinMode(greenLED, OUTPUT);
|
||||
pinMode(blueLED, OUTPUT);
|
||||
delay(500);
|
||||
heatpumpIR = new GreeYACHeatpumpIR();
|
||||
Serial.println(F("Starting"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
const char* buf;
|
||||
|
||||
Serial.print(F("Sending IR to "));
|
||||
// Print the model
|
||||
buf = heatpumpIR->model();
|
||||
// 'model' is a PROGMEM pointer, so need to write a byte at a time
|
||||
while (char modelChar = pgm_read_byte(buf++))
|
||||
{
|
||||
Serial.print(modelChar);
|
||||
}
|
||||
Serial.print(F(", info: "));
|
||||
// Print the info
|
||||
buf = heatpumpIR->info();
|
||||
// 'info' is a PROGMEM pointer, so need to write a byte at a time
|
||||
while (char infoChar = pgm_read_byte(buf++))
|
||||
{
|
||||
Serial.print(infoChar);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
digitalWrite(orangeLED,HIGH);
|
||||
delay(4000);
|
||||
heatpumpIR->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 24, VDIR_AUTO, HDIR_AUTO, false, true);
|
||||
|
||||
delay(4000);
|
||||
heatpumpIR->send(irSender, 24);
|
||||
|
||||
digitalWrite(orangeLED,LOW);
|
||||
|
||||
digitalWrite(redLED, HIGH);
|
||||
|
||||
// don't loop()
|
||||
for(;;)
|
||||
;
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
#include <HitachiHeatpumpIR.h>
|
||||
#include <BalluHeatpumpIR.h>
|
||||
#include <AUXHeatpumpIR.h>
|
||||
#include <ZHLT01HeatpumpIR.h>
|
||||
|
||||
|
||||
#ifndef ESP8266
|
||||
|
@ -44,7 +45,7 @@ HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpu
|
|||
new GreeGenericHeatpumpIR(), new GreeYANHeatpumpIR(), new GreeYAAHeatpumpIR(),
|
||||
new FuegoHeatpumpIR(), new ToshibaHeatpumpIR(), new ToshibaDaiseikaiHeatpumpIR(),
|
||||
new IVTHeatpumpIR(), new HitachiHeatpumpIR(),
|
||||
new BalluHeatpumpIR(), new AUXHeatpumpIR(),
|
||||
new BalluHeatpumpIR(), new AUXHeatpumpIR(), new ZHLT01HeatpumpIR(),
|
||||
NULL};
|
||||
|
||||
void setup()
|
||||
|
|
|
@ -38,6 +38,7 @@ IVTHeatpumpIR KEYWORD1
|
|||
HitachiHeatpumpIR KEYWORD1
|
||||
BalluHeatpumpIR KEYWORD1
|
||||
AUXHeatpumpIR KEYWORD1
|
||||
ZHLT01HeatpumpIR KEYWORD1
|
||||
|
||||
IRSender KEYWORD1
|
||||
IRSenderPWM KEYWORD1
|
||||
|
|
11
library.json
11
library.json
|
@ -12,5 +12,14 @@
|
|||
"url": "https://github.com/ToniA/arduino-heatpumpir.git"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "atmelavr"
|
||||
"platforms": ["atmelavr", "espressif32", "espressif8266"],
|
||||
"version": "1.0.15",
|
||||
"dependencies": [
|
||||
{
|
||||
"owner": "crankyoldgit",
|
||||
"name": "IRremoteESP8266",
|
||||
"version": "~2.7.12",
|
||||
"platforms": ["espressif8266"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name=HeatpumpIR
|
||||
version=1.0.12
|
||||
version=1.0.15
|
||||
author=Toni Arte<toni.arte@iki.fi>
|
||||
maintainer=Toni Arte<toni.arte@iki.fi>
|
||||
sentence=Heatpump / Air Conditioner infrared control
|
||||
|
|
Loading…
Reference in New Issue