Support for MITSUBISHI KJ heatpumps (SG 161 0927 remote)

Added support for MITSUBISHI KJ series heatpumps / remote control type SG161.
Also added a IR_DEBUG_PACKET define to be able to feedback and debug the IR packet as added text output to a browser, curl or other http request tool.
This commit is contained in:
Hans-Rune Bue
2019-09-12 21:48:22 +02:00
parent 2610ade3f7
commit 684ae2e8db
4 changed files with 685 additions and 59 deletions
+147 -54
View File
@@ -1,5 +1,19 @@
#include <MitsubishiHeatpumpIR.h>
#ifdef USE_TIME_H
#include <time.h>
#endif
#ifdef IR_SEND_TIME
int sendHour = 16;
int sendMinute = 10;
int sendWeekday = 3;
#endif
#ifdef IR_DEBUG_PACKET
char IRPacket[180];
#endif
// These are protected methods, i.e. generic Mitsubishi instances cannot be created directly
MitsubishiHeatpumpIR::MitsubishiHeatpumpIR() : HeatpumpIR()
{
@@ -52,6 +66,16 @@ MitsubishiFAHeatpumpIR::MitsubishiFAHeatpumpIR() : MitsubishiHeatpumpIR()
_mitsubishiModel = MITSUBISHI_FA;
}
MitsubishiKJHeatpumpIR::MitsubishiKJHeatpumpIR() : MitsubishiHeatpumpIR()
{
static const char model[] PROGMEM = "mitsubishi_kj";
static const char info[] PROGMEM = "{\"mdl\":\"mitsubishi_kj\",\"dn\":\"Mitsubishi KJ\",\"mT\":16,\"xT\":31,\"fs\":5,\"maint\":[10]}";
_model = model;
_info = info;
_mitsubishiModel = MITSUBISHI_KJ;
}
void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
{
@@ -71,6 +95,7 @@ void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
if (_mitsubishiModel != MITSUBISHI_MSY)
{
Serial.printf("Mode=%d\n",operatingModeCmd);
switch (operatingModeCmd)
{
case MODE_AUTO:
@@ -96,7 +121,7 @@ void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
}
break;
case MODE_MAINT: // Maintenance mode is just the heat mode at +10, FAN5
if (_mitsubishiModel == MITSUBISHI_FE) {
if (_mitsubishiModel == MITSUBISHI_FE || _mitsubishiModel == MITSUBISHI_KJ) {
operatingMode |= MITSUBISHI_AIRCON1_MODE_HEAT;
temperature = 10; // Default to +10 degrees
fanSpeedCmd = FAN_AUTO;
@@ -159,59 +184,69 @@ void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t oper
case FAN_4:
fanSpeed = MITSUBISHI_AIRCON1_FAN4;
break;
case FAN_5:
fanSpeed = MITSUBISHI_AIRCON1_FAN5; // Quiet mode on KJ
break;
}
if ( temperatureCmd > 16 && temperatureCmd < 32)
if ( temperature != 10 && temperatureCmd > 16 && temperatureCmd < 32)
{
temperature = temperatureCmd;
}
switch (swingVCmd)
{
case VDIR_AUTO:
swingV = MITSUBISHI_AIRCON1_VS_AUTO;
break;
case VDIR_SWING:
swingV = MITSUBISHI_AIRCON1_VS_SWING;
break;
case VDIR_UP:
swingV = MITSUBISHI_AIRCON1_VS_UP;
break;
case VDIR_MUP:
swingV = MITSUBISHI_AIRCON1_VS_MUP;
break;
case VDIR_MIDDLE:
swingV = MITSUBISHI_AIRCON1_VS_MIDDLE;
break;
case VDIR_MDOWN:
swingV = MITSUBISHI_AIRCON1_VS_MDOWN;
break;
case VDIR_DOWN:
swingV = MITSUBISHI_AIRCON1_VS_DOWN;
break;
case VDIR_AUTO:
swingV = MITSUBISHI_AIRCON1_VS_AUTO;
break;
case VDIR_SWING:
swingV = MITSUBISHI_AIRCON1_VS_SWING;
break;
case VDIR_UP:
swingV = MITSUBISHI_AIRCON1_VS_UP;
break;
case VDIR_MUP:
swingV = MITSUBISHI_AIRCON1_VS_MUP;
break;
case VDIR_MIDDLE:
swingV = MITSUBISHI_AIRCON1_VS_MIDDLE;
break;
case VDIR_MDOWN:
swingV = MITSUBISHI_AIRCON1_VS_MDOWN;
break;
case VDIR_DOWN:
swingV = MITSUBISHI_AIRCON1_VS_DOWN;
break;
}
switch (swingHCmd)
{
case HDIR_AUTO:
case HDIR_SWING:
swingH = MITSUBISHI_AIRCON1_HS_SWING;
break;
case HDIR_MIDDLE:
swingH = MITSUBISHI_AIRCON1_HS_MIDDLE;
break;
case HDIR_LEFT:
swingH = MITSUBISHI_AIRCON1_HS_LEFT;
break;
case HDIR_MLEFT:
swingH = MITSUBISHI_AIRCON1_HS_MLEFT;
break;
case HDIR_RIGHT:
swingH = MITSUBISHI_AIRCON1_HS_RIGHT;
break;
case HDIR_MRIGHT:
swingH = MITSUBISHI_AIRCON1_HS_MRIGHT;
break;
// KJ has no horizontal swing. Instead 0 means 2flow, else 1flow operation
if (_mitsubishiModel == MITSUBISHI_KJ) {
swingH = swingHCmd; // We pass the value unmodified
}
else {
switch (swingHCmd)
{
case HDIR_AUTO:
case HDIR_SWING:
swingH = MITSUBISHI_AIRCON1_HS_SWING;
break;
case HDIR_MIDDLE:
swingH = MITSUBISHI_AIRCON1_HS_MIDDLE;
break;
case HDIR_LEFT:
swingH = MITSUBISHI_AIRCON1_HS_LEFT;
break;
case HDIR_MLEFT:
swingH = MITSUBISHI_AIRCON1_HS_MLEFT;
break;
case HDIR_RIGHT:
swingH = MITSUBISHI_AIRCON1_HS_RIGHT;
break;
case HDIR_MRIGHT:
swingH = MITSUBISHI_AIRCON1_HS_MRIGHT;
break;
}
}
sendMitsubishi(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH);
@@ -221,15 +256,41 @@ void MitsubishiHeatpumpIR::sendMitsubishi(IRSender& IR, uint8_t powerMode, uint8
{
uint8_t MitsubishiTemplate[] = { 0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00 };
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
uint8_t TempTranslate[] = { 0x82, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81 };
// Sun Mon Tue Wed Thu Fri Sat
uint8_t checksum = 0x00;
#ifdef USE_TIME_H
time_t now;
struct tm * timeinfo;
#endif
char pbyte[16];
// MSY has a bit different template
if (_mitsubishiModel == MITSUBISHI_MSY) {
MitsubishiTemplate[14] = 0x00;
MitsubishiTemplate[15] = 0x00;
}
// FA also has a bit different template
if (_mitsubishiModel == MITSUBISHI_FA)
{
MitsubishiTemplate[10] = 0x00;
MitsubishiTemplate[15] = 0x00;
}
// 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;
// Set the temperature on the template message
if (temperature == 10) {
Serial.println(F("Temp=10 maintenance mode"));
MitsubishiTemplate[7] = 0x00; // Maintenance mode
MitsubishiTemplate[15] = 0x20; // This seems to be set to 0x20 on maintenance mode
} else {
@@ -242,23 +303,55 @@ 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;
// MSY has a bit different template
if (_mitsubishiModel == MITSUBISHI_MSY) {
MitsubishiTemplate[14] = 0x00;
MitsubishiTemplate[15] = 0x00;
if (_mitsubishiModel == MITSUBISHI_KJ) {
MitsubishiTemplate[8] = 0;
if ( operatingMode == MITSUBISHI_AIRCON1_MODE_AUTO || operatingMode == MITSUBISHI_AIRCON1_MODE_COOL )
MitsubishiTemplate[8] = 0x6;
if ( operatingMode == MITSUBISHI_AIRCON1_MODE_DRY )
MitsubishiTemplate[8] = 0x2;
if ( swingH != 0 ) {
MitsubishiTemplate[16] = 0x02;
}
}
// FA also has a bit different template
if (_mitsubishiModel == MITSUBISHI_FA)
{
MitsubishiTemplate[10] = 0x00;
MitsubishiTemplate[15] = 0x00;
}
#ifdef USE_TIME_H
time(&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) {
Serial.printf("Send time %02d:%02d day %d --> %x\n", sendHour, sendMinute, sendWeekday, (sendHour * 60 + sendMinute)/10);
MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/10);
// Sunday is start if week , value 1
MitsubishiTemplate[14] = TempTranslate[( sendWeekday - 1 ) % 7];
}
else {
Serial.printf("Send time %02d:%02d --> %x\n", sendHour, sendMinute, (sendHour * 60 + sendMinute)/6);
MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/6);
}
#endif
#ifdef IR_DEBUG_PACKET
IRPacket[0] = (char) 0;
// Calculate the checksum
for (int i=0; i<17; i++) {
checksum += MitsubishiTemplate[i];
sprintf_P(pbyte, PSTR("[%02d]=%02x "), i, (int) MitsubishiTemplate[i]);
strcat(IRPacket, pbyte);
}
Serial.println(IRPacket);
#else
// Calculate the checksum
for (int i=0; i<17; i++) {
checksum += MitsubishiTemplate[i];
}
#endif
MitsubishiTemplate[17] = checksum;
+28 -3
View File
@@ -4,6 +4,10 @@
#ifndef MitsubishiHeatpumpIR_h
#define MitsubishiHeatpumpIR_h
// #define USE_TIME_H
#define IR_SEND_TIME
#define IR_DEBUG_PACKET
#include <HeatpumpIR.h>
@@ -15,8 +19,8 @@
#define MITSUBISHI_AIRCON1_ZERO_SPACE 390
#define MITSUBISHI_AIRCON1_MSG_SPACE 17500
// Mitsubishi mode codes
#define MITSUBISHI_AIRCON1_MODE_AUTO 0x20
// Mitsubishi codes
#define MITSUBISHI_AIRCON1_MODE_AUTO 0x20 // Operating mode
#define MITSUBISHI_AIRCON3_MODE_AUTO 0x60 // FA auto mode
#define MITSUBISHI_AIRCON1_MODE_HEAT 0x08
#define MITSUBISHI_AIRCON3_MODE_HEAT 0x48 // FA heat mode
@@ -31,7 +35,7 @@
#define MITSUBISHI_AIRCON1_MODE_ISEE 0x40 // Isee
#define MITSUBISHI_AIRCON2_MODE_IFEEL 0x00 // MSY
#define MITSUBISHI_AIRCON1_MODE_OFF 0x00 // Power OFF
#define MITSUBISHI_AIRCON1_MODE_OFF 0x00 // Power FFi
#define MITSUBISHI_AIRCON1_MODE_ON 0x20 // Power ON
// Mitsubishi fan codes
@@ -40,10 +44,15 @@
#define MITSUBISHI_AIRCON1_FAN2 0x02
#define MITSUBISHI_AIRCON1_FAN3 0x03
#define MITSUBISHI_AIRCON1_FAN4 0x04
#define MITSUBISHI_AIRCON1_FAN5 0x05 // KJ
#define MITSUBISHI_AIRCON1_QUIET 0x05 // KJ
// Mitsubishi vertical swing codes
#define MITSUBISHI_AIRCON1_VS_SWING 0x78
#define MITSUBISHI_AIRCON1_VS_AUTO 0x40
#define MITSUBISHI_AIRCON1_ECONOCOOL 0x20 // KJ byte 14 + 0x03
#define MITSUBISHI_AIRCON1_ISAVE 0x20 // KJ byte 15 w temperature=0
#define MITSUBISHI_AIRCON1_1FLOW 0x02 // KJ byte 16
#define MITSUBISHI_AIRCON1_VS_UP 0x48
#define MITSUBISHI_AIRCON1_VS_MUP 0x50
#define MITSUBISHI_AIRCON1_VS_MIDDLE 0x58
@@ -70,6 +79,7 @@
#define MITSUBISHI_FE 1
#define MITSUBISHI_MSY 2
#define MITSUBISHI_FA 3
#define MITSUBISHI_KJ 4
class MitsubishiHeatpumpIR : public HeatpumpIR
{
@@ -108,4 +118,19 @@ class MitsubishiFAHeatpumpIR : public MitsubishiHeatpumpIR
MitsubishiFAHeatpumpIR();
};
class MitsubishiKJHeatpumpIR : public MitsubishiHeatpumpIR
{
public:
MitsubishiKJHeatpumpIR();
};
#ifdef IR_SEND_TIME
extern int sendHour;
extern int sendMinute;
extern int sendWeekday;
#endif
#ifdef IR_DEBUG_PACKET
extern char IRPacket[180];
#endif
#endif
+495
View File
@@ -0,0 +1,495 @@
*** a/_P088_HeatpumpIR.ino 2019-08-27 19:41:29.601146400 +0200
--- b/_P088_HeatpumpIR.ino 2019-09-01 19:16:48.231090300 +0200
*************** HeatpumpIR *heatpumpIR[] = {new Panasoni
*** 71,76 ****
--- 71,77 ----
new CarrierNQVHeatpumpIR(), new CarrierMCAHeatpumpIR(),
new MideaHeatpumpIR(), new FujitsuHeatpumpIR(),
new MitsubishiFDHeatpumpIR(), new MitsubishiFEHeatpumpIR(), new MitsubishiMSYHeatpumpIR(), new MitsubishiFAHeatpumpIR(),
+ new MitsubishiKJHeatpumpIR(),
new SamsungAQVHeatpumpIR(), new SamsungFJMHeatpumpIR(),new SharpHeatpumpIR(), new DaikinHeatpumpIR(),
new MitsubishiHeavyZJHeatpumpIR(), new MitsubishiHeavyZMHeatpumpIR(),
new MitsubishiSEZKDXXHeatpumpIR(),
*************** boolean Plugin_088(byte function, struct
*** 202,208 ****
if (GetArgv(command, TmpStr1, 6)) temperature = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 7)) vDir = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 8)) hDir = str2int(TmpStr1.c_str());
!
int i = 0;
do
{
--- 203,213 ----
if (GetArgv(command, TmpStr1, 6)) temperature = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 7)) vDir = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 8)) hDir = str2int(TmpStr1.c_str());
! #ifdef IR_SEND_TIME
! sendHour = hour();
! sendMinute = minute();
! sendWeekday = weekday();
! #endif
int i = 0;
do
{
*************** boolean Plugin_088(byte function, struct
*** 220,228 ****
--- 225,241 ----
irReceiver->enableIRIn(); // Start the receiver
#endif
addLog(LOG_LEVEL_INFO, F("P088: Heatpump IR code transmitted"));
+ #ifdef IR_DEBUG_PACKET
+ addLog(LOG_LEVEL_DEBUG, IRPacket);
+ #endif
if (printToWeb)
{
printWebString += F("P088: Heatpump IR code transmitted");
+ #ifdef IR_DEBUG_PACKET
+ printWebString += F(" <BR>\n"); // do both <BR> and \n to break line both in browser and curl -s
+ printWebString += IRPacket;
+ printWebString += F("\n");
+ #endif
}
// Panasonic CKP can only be turned ON/OFF by using the timer,
*************** boolean Plugin_088(byte function, struct
*** 288,291 ****
return success;
}
! #endif // USES_P088
\ No newline at end of file
--- 301,304 ----
return success;
}
! #endif // USES_P088
*** a/MitsubishiHeatpumpIR.cpp 2019-08-27 19:41:17.497615900 +0200
--- b/MitsubishiHeatpumpIR.cpp 2019-09-01 19:16:35.373395300 +0200
***************
*** 1,5 ****
--- 1,19 ----
#include <MitsubishiHeatpumpIR.h>
+ #ifdef USE_TIME_H
+ #include <time.h>
+ #endif
+
+ #ifdef IR_SEND_TIME
+ int sendHour = 16;
+ int sendMinute = 10;
+ int sendWeekday = 3;
+ #endif
+ #ifdef IR_DEBUG_PACKET
+ char IRPacket[180];
+ #endif
+
+
// These are protected methods, i.e. generic Mitsubishi instances cannot be created directly
MitsubishiHeatpumpIR::MitsubishiHeatpumpIR() : HeatpumpIR()
{
*************** MitsubishiFAHeatpumpIR::MitsubishiFAHeat
*** 52,57 ****
--- 66,81 ----
_mitsubishiModel = MITSUBISHI_FA;
}
+ MitsubishiKJHeatpumpIR::MitsubishiKJHeatpumpIR() : MitsubishiHeatpumpIR()
+ {
+ static const char model[] PROGMEM = "mitsubishi_kj";
+ static const char info[] PROGMEM = "{\"mdl\":\"mitsubishi_kj\",\"dn\":\"Mitsubishi KJ\",\"mT\":16,\"xT\":31,\"fs\":5,\"maint\":[10]}";
+
+ _model = model;
+ _info = info;
+
+ _mitsubishiModel = MITSUBISHI_KJ;
+ }
void MitsubishiHeatpumpIR::send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd)
{
*************** void MitsubishiHeatpumpIR::send(IRSender
*** 71,76 ****
--- 95,101 ----
if (_mitsubishiModel != MITSUBISHI_MSY)
{
+ Serial.printf("Mode=%d\n",operatingModeCmd);
switch (operatingModeCmd)
{
case MODE_AUTO:
*************** void MitsubishiHeatpumpIR::send(IRSender
*** 96,102 ****
}
break;
case MODE_MAINT: // Maintenance mode is just the heat mode at +10, FAN5
! if (_mitsubishiModel == MITSUBISHI_FE) {
operatingMode |= MITSUBISHI_AIRCON1_MODE_HEAT;
temperature = 10; // Default to +10 degrees
fanSpeedCmd = FAN_AUTO;
--- 121,127 ----
}
break;
case MODE_MAINT: // Maintenance mode is just the heat mode at +10, FAN5
! if (_mitsubishiModel == MITSUBISHI_FE || _mitsubishiModel == MITSUBISHI_KJ) {
operatingMode |= MITSUBISHI_AIRCON1_MODE_HEAT;
temperature = 10; // Default to +10 degrees
fanSpeedCmd = FAN_AUTO;
*************** void MitsubishiHeatpumpIR::send(IRSender
*** 159,217 ****
case FAN_4:
fanSpeed = MITSUBISHI_AIRCON1_FAN4;
break;
}
! if ( temperatureCmd > 16 && temperatureCmd < 32)
{
temperature = temperatureCmd;
}
switch (swingVCmd)
{
! case VDIR_AUTO:
! swingV = MITSUBISHI_AIRCON1_VS_AUTO;
! break;
! case VDIR_SWING:
! swingV = MITSUBISHI_AIRCON1_VS_SWING;
! break;
! case VDIR_UP:
! swingV = MITSUBISHI_AIRCON1_VS_UP;
! break;
! case VDIR_MUP:
! swingV = MITSUBISHI_AIRCON1_VS_MUP;
! break;
! case VDIR_MIDDLE:
! swingV = MITSUBISHI_AIRCON1_VS_MIDDLE;
! break;
! case VDIR_MDOWN:
! swingV = MITSUBISHI_AIRCON1_VS_MDOWN;
! break;
! case VDIR_DOWN:
! swingV = MITSUBISHI_AIRCON1_VS_DOWN;
! break;
! }
!
! switch (swingHCmd)
! {
! case HDIR_AUTO:
! case HDIR_SWING:
! swingH = MITSUBISHI_AIRCON1_HS_SWING;
break;
! case HDIR_MIDDLE:
! swingH = MITSUBISHI_AIRCON1_HS_MIDDLE;
break;
! case HDIR_LEFT:
! swingH = MITSUBISHI_AIRCON1_HS_LEFT;
break;
! case HDIR_MLEFT:
! swingH = MITSUBISHI_AIRCON1_HS_MLEFT;
break;
! case HDIR_RIGHT:
! swingH = MITSUBISHI_AIRCON1_HS_RIGHT;
break;
! case HDIR_MRIGHT:
! swingH = MITSUBISHI_AIRCON1_HS_MRIGHT;
break;
}
sendMitsubishi(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH);
--- 184,252 ----
case FAN_4:
fanSpeed = MITSUBISHI_AIRCON1_FAN4;
break;
+ case FAN_5:
+ fanSpeed = MITSUBISHI_AIRCON1_FAN5; // Quiet mode on KJ
+ break;
+
}
! if ( temperature != 10 && temperatureCmd > 16 && temperatureCmd < 32)
{
temperature = temperatureCmd;
}
switch (swingVCmd)
{
! case VDIR_AUTO:
! swingV = MITSUBISHI_AIRCON1_VS_AUTO;
break;
! case VDIR_SWING:
! swingV = MITSUBISHI_AIRCON1_VS_SWING;
break;
! case VDIR_UP:
! swingV = MITSUBISHI_AIRCON1_VS_UP;
break;
! case VDIR_MUP:
! swingV = MITSUBISHI_AIRCON1_VS_MUP;
break;
! case VDIR_MIDDLE:
! swingV = MITSUBISHI_AIRCON1_VS_MIDDLE;
break;
! case VDIR_MDOWN:
! swingV = MITSUBISHI_AIRCON1_VS_MDOWN;
break;
+ case VDIR_DOWN:
+ swingV = MITSUBISHI_AIRCON1_VS_DOWN;
+ break;
+ }
+
+ // KJ has no horizontal swing. Instead 0 means 2flow, else 1flow operation
+ if (_mitsubishiModel == MITSUBISHI_KJ) {
+ swingH = swingHCmd; // We pass the value unmodified
+ }
+ else {
+ switch (swingHCmd)
+ {
+ case HDIR_AUTO:
+ case HDIR_SWING:
+ swingH = MITSUBISHI_AIRCON1_HS_SWING;
+ break;
+ case HDIR_MIDDLE:
+ swingH = MITSUBISHI_AIRCON1_HS_MIDDLE;
+ break;
+ case HDIR_LEFT:
+ swingH = MITSUBISHI_AIRCON1_HS_LEFT;
+ break;
+ case HDIR_MLEFT:
+ swingH = MITSUBISHI_AIRCON1_HS_MLEFT;
+ break;
+ case HDIR_RIGHT:
+ swingH = MITSUBISHI_AIRCON1_HS_RIGHT;
+ break;
+ case HDIR_MRIGHT:
+ swingH = MITSUBISHI_AIRCON1_HS_MRIGHT;
+ break;
+ }
}
sendMitsubishi(IR, powerMode, operatingMode, fanSpeed, temperature, swingV, swingH);
*************** void MitsubishiHeatpumpIR::sendMitsubish
*** 221,235 ****
--- 256,296 ----
{
uint8_t MitsubishiTemplate[] = { 0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00 };
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ uint8_t TempTranslate[] = { 0x82, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81 };
+ // Sun Mon Tue Wed Thu Fri Sat
uint8_t checksum = 0x00;
+ #ifdef USE_TIME_H
+ time_t now;
+ struct tm * timeinfo;
+ #endif
+ char pbyte[16];
+
+ // MSY has a bit different template
+ if (_mitsubishiModel == MITSUBISHI_MSY) {
+ MitsubishiTemplate[14] = 0x00;
+ MitsubishiTemplate[15] = 0x00;
+ }
+
+ // FA also has a bit different template
+ if (_mitsubishiModel == MITSUBISHI_FA)
+ {
+ MitsubishiTemplate[10] = 0x00;
+ MitsubishiTemplate[15] = 0x00;
+ }
+ // 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;
// Set the temperature on the template message
if (temperature == 10) {
+ Serial.println(F("Temp=10 maintenance mode"));
MitsubishiTemplate[7] = 0x00; // Maintenance mode
MitsubishiTemplate[15] = 0x20; // This seems to be set to 0x20 on maintenance mode
} else {
*************** void MitsubishiHeatpumpIR::sendMitsubish
*** 242,264 ****
// Set the fan speed and vertical air direction on the template message
MitsubishiTemplate[9] = fanSpeed | swingV;
! // MSY has a bit different template
! if (_mitsubishiModel == MITSUBISHI_MSY) {
! MitsubishiTemplate[14] = 0x00;
! MitsubishiTemplate[15] = 0x00;
}
! // FA also has a bit different template
! if (_mitsubishiModel == MITSUBISHI_FA)
! {
! MitsubishiTemplate[10] = 0x00;
! MitsubishiTemplate[15] = 0x00;
}
// Calculate the checksum
for (int i=0; i<17; i++) {
checksum += MitsubishiTemplate[i];
}
MitsubishiTemplate[17] = checksum;
--- 303,357 ----
// 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;
! if ( operatingMode == MITSUBISHI_AIRCON1_MODE_DRY )
! MitsubishiTemplate[8] = 0x2;
!
! if ( swingH != 0 ) {
! MitsubishiTemplate[16] = 0x02;
! }
}
! #ifdef USE_TIME_H
! time(&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) {
! Serial.printf("Send time %02d:%02d day %d --> %x\n", sendHour, sendMinute, sendWeekday, (sendHour * 60 + sendMinute)/10);
! MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/10);
! // Sunday is start if week , value 1
! MitsubishiTemplate[14] = TempTranslate[( sendWeekday - 1 ) % 7];
! }
! else {
! Serial.printf("Send time %02d:%02d --> %x\n", sendHour, sendMinute, (sendHour * 60 + sendMinute)/6);
! MitsubishiTemplate[10] = (uint8_t)((sendHour * 60 + sendMinute)/6);
}
+ #endif
+ #ifdef IR_DEBUG_PACKET
+ IRPacket[0] = (char) 0;
+ // Calculate the checksum
+ for (int i=0; i<17; i++) {
+ checksum += MitsubishiTemplate[i];
+ sprintf_P(pbyte, PSTR("[%02d]=%02x "), i, (int) MitsubishiTemplate[i]);
+ strcat(IRPacket, pbyte);
+ }
+ Serial.println(IRPacket);
+ #else
// Calculate the checksum
for (int i=0; i<17; i++) {
checksum += MitsubishiTemplate[i];
}
+ #endif
MitsubishiTemplate[17] = checksum;
*** a/MitsubishiHeatpumpIR.h 2019-08-27 19:41:17.516596300 +0200
--- b/MitsubishiHeatpumpIR.h 2019-09-01 19:16:35.378389700 +0200
***************
*** 4,9 ****
--- 4,13 ----
#ifndef MitsubishiHeatpumpIR_h
#define MitsubishiHeatpumpIR_h
+ // #define USE_TIME_H
+ #define IR_SEND_TIME
+ #define IR_DEBUG_PACKET
+
#include <HeatpumpIR.h>
***************
*** 15,22 ****
#define MITSUBISHI_AIRCON1_ZERO_SPACE 390
#define MITSUBISHI_AIRCON1_MSG_SPACE 17500
! // Mitsubishi mode codes
! #define MITSUBISHI_AIRCON1_MODE_AUTO 0x20
#define MITSUBISHI_AIRCON3_MODE_AUTO 0x60 // FA auto mode
#define MITSUBISHI_AIRCON1_MODE_HEAT 0x08
#define MITSUBISHI_AIRCON3_MODE_HEAT 0x48 // FA heat mode
--- 19,26 ----
#define MITSUBISHI_AIRCON1_ZERO_SPACE 390
#define MITSUBISHI_AIRCON1_MSG_SPACE 17500
! // Mitsubishi codes
! #define MITSUBISHI_AIRCON1_MODE_AUTO 0x20 // Operating mode
#define MITSUBISHI_AIRCON3_MODE_AUTO 0x60 // FA auto mode
#define MITSUBISHI_AIRCON1_MODE_HEAT 0x08
#define MITSUBISHI_AIRCON3_MODE_HEAT 0x48 // FA heat mode
***************
*** 31,37 ****
#define MITSUBISHI_AIRCON1_MODE_ISEE 0x40 // Isee
#define MITSUBISHI_AIRCON2_MODE_IFEEL 0x00 // MSY
! #define MITSUBISHI_AIRCON1_MODE_OFF 0x00 // Power OFF
#define MITSUBISHI_AIRCON1_MODE_ON 0x20 // Power ON
// Mitsubishi fan codes
--- 35,41 ----
#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_ON 0x20 // Power ON
// Mitsubishi fan codes
***************
*** 40,49 ****
--- 44,58 ----
#define MITSUBISHI_AIRCON1_FAN2 0x02
#define MITSUBISHI_AIRCON1_FAN3 0x03
#define MITSUBISHI_AIRCON1_FAN4 0x04
+ #define MITSUBISHI_AIRCON1_FAN5 0x05 // KJ
+ #define MITSUBISHI_AIRCON1_QUIET 0x05 // KJ
// Mitsubishi vertical swing codes
#define MITSUBISHI_AIRCON1_VS_SWING 0x78
#define MITSUBISHI_AIRCON1_VS_AUTO 0x40
+ #define MITSUBISHI_AIRCON1_ECONOCOOL 0x20 // KJ byte 14 + 0x03
+ #define MITSUBISHI_AIRCON1_ISAVE 0x20 // KJ byte 15 w temperature=0
+ #define MITSUBISHI_AIRCON1_1FLOW 0x02 // KJ byte 16
#define MITSUBISHI_AIRCON1_VS_UP 0x48
#define MITSUBISHI_AIRCON1_VS_MUP 0x50
#define MITSUBISHI_AIRCON1_VS_MIDDLE 0x58
***************
*** 70,75 ****
--- 79,85 ----
#define MITSUBISHI_FE 1
#define MITSUBISHI_MSY 2
#define MITSUBISHI_FA 3
+ #define MITSUBISHI_KJ 4
class MitsubishiHeatpumpIR : public HeatpumpIR
{
*************** class MitsubishiFAHeatpumpIR : public Mi
*** 108,111 ****
--- 118,136 ----
MitsubishiFAHeatpumpIR();
};
+ class MitsubishiKJHeatpumpIR : public MitsubishiHeatpumpIR
+ {
+ public:
+ MitsubishiKJHeatpumpIR();
+ };
+
+ #ifdef IR_SEND_TIME
+ extern int sendHour;
+ extern int sendMinute;
+ extern int sendWeekday;
+ #endif
+ #ifdef IR_DEBUG_PACKET
+ extern char IRPacket[180];
+ #endif
+
#endif
+15 -2
View File
@@ -71,6 +71,7 @@ HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpu
new CarrierNQVHeatpumpIR(), new CarrierMCAHeatpumpIR(),
new MideaHeatpumpIR(), new FujitsuHeatpumpIR(),
new MitsubishiFDHeatpumpIR(), new MitsubishiFEHeatpumpIR(), new MitsubishiMSYHeatpumpIR(), new MitsubishiFAHeatpumpIR(),
new MitsubishiKJHeatpumpIR(),
new SamsungAQVHeatpumpIR(), new SamsungFJMHeatpumpIR(),new SharpHeatpumpIR(), new DaikinHeatpumpIR(),
new MitsubishiHeavyZJHeatpumpIR(), new MitsubishiHeavyZMHeatpumpIR(),
new MitsubishiSEZKDXXHeatpumpIR(),
@@ -202,7 +203,11 @@ boolean Plugin_088(byte function, struct EventStruct *event, String& string)
if (GetArgv(command, TmpStr1, 6)) temperature = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 7)) vDir = str2int(TmpStr1.c_str());
if (GetArgv(command, TmpStr1, 8)) hDir = str2int(TmpStr1.c_str());
#ifdef IR_SEND_TIME
sendHour = hour();
sendMinute = minute();
sendWeekday = weekday();
#endif
int i = 0;
do
{
@@ -220,9 +225,17 @@ boolean Plugin_088(byte function, struct EventStruct *event, String& string)
irReceiver->enableIRIn(); // Start the receiver
#endif
addLog(LOG_LEVEL_INFO, F("P088: Heatpump IR code transmitted"));
#ifdef IR_DEBUG_PACKET
addLog(LOG_LEVEL_DEBUG, IRPacket);
#endif
if (printToWeb)
{
printWebString += F("P088: Heatpump IR code transmitted");
#ifdef IR_DEBUG_PACKET
printWebString += F(" <BR>\n"); // do both <BR> and \n to break line both in browser and curl -s
printWebString += IRPacket;
printWebString += F("\n");
#endif
}
// Panasonic CKP can only be turned ON/OFF by using the timer,
@@ -288,4 +301,4 @@ boolean Plugin_088(byte function, struct EventStruct *event, String& string)
return success;
}
#endif // USES_P088
#endif // USES_P088