Files
ESPEasy/patches/MitsubishiKJ.patch
T
Hans-Rune Bue 684ae2e8db 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.
2019-09-12 21:48:22 +02:00

496 lines
15 KiB
Diff

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