Merge pull request #1 from ToniA/master

Merge main repository to this fork
This commit is contained in:
Frederic LESUR 2021-04-01 16:22:35 +09:00 committed by GitHub
commit 0773d6a437
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 841 additions and 119 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

198
ZHLT01HeatpumpIR.cpp Normal file
View File

@ -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);
}

161
ZHLT01HeatpumpIR.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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(;;)
;
}

View File

@ -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()

View File

@ -38,6 +38,7 @@ IVTHeatpumpIR KEYWORD1
HitachiHeatpumpIR KEYWORD1
BalluHeatpumpIR KEYWORD1
AUXHeatpumpIR KEYWORD1
ZHLT01HeatpumpIR KEYWORD1
IRSender KEYWORD1
IRSenderPWM KEYWORD1

View File

@ -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"]
}
]
}

View File

@ -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