Sitelet https://github.com/crankyoldgit/IRremoteESP8266/pull/1666/files
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ tools/mode2_decode

# Mac extended attributes
.DS_Store
/.vs
1 change: 1 addition & 0 deletions src/IRac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,7 @@ void IRac::mitsubishi(IRMitsubishiAC *ac,
ac->setVane(ac->convertSwingV(swingv));
ac->setWideVane(ac->convertSwingH(swingh));
if (quiet) ac->setFan(kMitsubishiAcFanSilent);
ac->setISave10C(false);
// No Turbo setting available.
// No Light setting available.
// No Filter setting available.
Expand Down
8 changes: 8 additions & 0 deletions src/IRtext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ IRTEXT_CONST_STRING(kHoldStr, D_STR_HOLD); ///< "Hold"
IRTEXT_CONST_STRING(kButtonStr, D_STR_BUTTON); ///< "Button"
IRTEXT_CONST_STRING(k8CHeatStr, D_STR_8C_HEAT); ///< "8C Heat"
IRTEXT_CONST_STRING(k10CHeatStr, D_STR_10C_HEAT); ///< "10C Heat"
IRTEXT_CONST_STRING(kISeeStr, D_STR_ISEE); ///< "ISee"
IRTEXT_CONST_STRING(kAbsenseDetectStr, D_STR_ABSENSEDETECT);
///< "AbsenseDetect"
IRTEXT_CONST_STRING(kDirectIndirectModeStr, D_STR_DIRECTINDIRECTMODE);
///< "Direct/Indirect mode"
IRTEXT_CONST_STRING(kDirectStr, D_STR_DIRECT); ///< "Direct"
IRTEXT_CONST_STRING(kIndirectStr, D_STR_INDIRECT); ///< "Indirect"

IRTEXT_CONST_STRING(kNightStr, D_STR_NIGHT); ///< "Night"
IRTEXT_CONST_STRING(kSilentStr, D_STR_SILENT); ///< "Silent"
IRTEXT_CONST_STRING(kFilterStr, D_STR_FILTER); ///< "Filter"
Expand Down
6 changes: 6 additions & 0 deletions src/IRtext.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,11 @@ extern IRTEXT_CONST_PTR(kYbofbStr);
extern IRTEXT_CONST_PTR(kYesStr);
extern IRTEXT_CONST_PTR(kZoneFollowStr);
extern IRTEXT_CONST_PTR(kAllProtocolNamesStr);
extern IRTEXT_CONST_PTR(kISeeStr);
extern IRTEXT_CONST_PTR(kEcocoolStr);
extern IRTEXT_CONST_PTR(kAbsenseDetectStr);
extern IRTEXT_CONST_PTR(kDirectIndirectModeStr);
extern IRTEXT_CONST_PTR(kDirectStr);
extern IRTEXT_CONST_PTR(kIndirectStr);

#endif // IRTEXT_H_
128 changes: 116 additions & 12 deletions src/ir_Mitsubishi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ void IRMitsubishiAC::setTemp(const float degrees) {
// Do we have a half degree celsius?
_.HalfDegree = nrHalfDegrees & 1;
_.Temp = static_cast<uint8_t>(nrHalfDegrees / 2 - kMitsubishiAcMinTemp);
// If temp is modified, iSave10C cannot be ON (because temp is then > 10C)
setISave10C(false);
}

/// Get the current temperature setting.
Expand Down Expand Up @@ -452,8 +454,104 @@ void IRMitsubishiAC::setMode(const uint8_t mode) {
return;
}
_.Mode = mode;
// iSave10C can only be on in Heat mode.
if (mode != kMitsubishiAcHeat) {
setISave10C(false);
}
}

/// Set the iSave10C (i-SAVE) mode of the A/C.
/// @param[in] state true, the setting is on. false, the setting is off.
/// @note Normal minimum temp is 16C; i-SAVE mode works as gate to enable AC
/// to use 10C as setting. However, when Remote control shows 10C, it still
/// emits 16C on the "Temp" bits, and instead it uses other bits to indicate
/// a target temp of 10C.
/// Slightly strange, but I guess it's to keep compatibility to systems
/// without i-SAVE.
/// i-SAVE only has this 10C functionality when the AC is already in Heat mode.
/// In all other modes, minimum temp is 16C.
/// I have found no other difference between normal Heat mode and i-SAVE
/// other than the ability to go to 10C.
/// In this implementation, i-SAVE mode is ONLY used to enable the AC
/// temperature setting to 10C. Therefore "Temp" is set to 16 disregarding
/// what the remote shows, and mode is set to Heat.
void IRMitsubishiAC::setISave10C(const bool state) {
if (state) setMode(kMitsubishiAcHeat);
if (state) setTemp(kMitsubishiAcMinTemp);
_.iSave10C = state;
}

/// Get the iSave10C (i-SAVE) mode of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRMitsubishiAC::getISave10C(void) const {
return _.iSave10C;
}

/// Set the requested iSee mode.
/// @param[in] state requested iSee mode.
void IRMitsubishiAC::setISee(const bool state) {
Comment thread
crankyoldgit marked this conversation as resolved.
_.ISee = state;
}

/// Get the iSee mode of the A/C.
/// @return The iSee mode setting.
bool IRMitsubishiAC::getISee(void) const {
Comment thread
crankyoldgit marked this conversation as resolved.
return _.ISee;
}

/// Set the requested Ecocool mode.
/// @param[in] state requested Ecocool mode.
void IRMitsubishiAC::setEcocool(const bool state) {
Comment thread
crankyoldgit marked this conversation as resolved.
_.Ecocool = state;
}

/// Get the Ecocool mode of the A/C.
/// @return The Ecocool mode setting.
bool IRMitsubishiAC::getEcocool(void) const {
Comment thread
crankyoldgit marked this conversation as resolved.
return _.Ecocool;
}

/// Set the requested Absense Detect mode.
/// @param[in] state requested Absense Detect mode.
void IRMitsubishiAC::setAbsenseDetect(const bool state) {
Comment thread
crankyoldgit marked this conversation as resolved.
_.AbsenseDetect = state;
}

/// Get the Absense Detect mode of the A/C.
/// @return The Absense Detect mode setting.
bool IRMitsubishiAC::getAbsenseDetect(void) const {
Comment thread
crankyoldgit marked this conversation as resolved.
return _.AbsenseDetect;
}

/// Set the requested Direct/Indirect mode. Only works if I-See mode is ON.
/// @param[in] mode requested Direct/Indirect mode.
void IRMitsubishiAC::setDirectIndirect(const uint8_t mode) {
if (_.ISee) {
_.DirectIndirect = std::min(mode, kMitsubishiAcDirect); // bounds check
} else {
_.DirectIndirect = 0;
}
}

/// Get the Direct/Indirect mode of the A/C.
/// @return The native mode setting.
uint8_t IRMitsubishiAC::getDirectIndirect(void) const {
return _.DirectIndirect;
}

/// Set the requested Natural Flow mode.
/// @param[in] state requested Natural Flow mode.
void IRMitsubishiAC::setNaturalFlow(const bool state) {
Comment thread
crankyoldgit marked this conversation as resolved.
_.NaturalFlow = state;
}

/// Get the Natural Flow mode of the A/C.
/// @return The Natural Flow mode setting.
bool IRMitsubishiAC::getNaturalFlow(void) const {
return _.NaturalFlow;
}


/// Set the requested vane (Vertical Swing) operation mode of the a/c unit.
/// @note On some models, this represents the Right vertical vane.
/// @param[in] position The position/mode to set the vane to.
Expand All @@ -463,25 +561,13 @@ void IRMitsubishiAC::setVane(const uint8_t position) {
_.Vane = pos;
}

/// Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.
/// @param[in] position The position/mode to set the wide vane to.
void IRMitsubishiAC::setWideVane(const uint8_t position) {
_.WideVane = std::min(position, kMitsubishiAcWideVaneAuto);
}

/// Get the Vane (Vertical Swing) mode of the A/C.
/// @note On some models, this represents the Right vertical vane.
/// @return The native position/mode setting.
uint8_t IRMitsubishiAC::getVane(void) const {
return _.Vane;
}

/// Get the Wide Vane (Horizontal Swing) mode of the A/C.
/// @return The native position/mode setting.
uint8_t IRMitsubishiAC::getWideVane(void) const {
return _.WideVane;
}

/// Set the requested Left Vane (Vertical Swing) operation mode of the a/c unit.
/// @param[in] position The position/mode to set the vane to.
void IRMitsubishiAC::setVaneLeft(const uint8_t position) {
Expand All @@ -492,6 +578,18 @@ void IRMitsubishiAC::setVaneLeft(const uint8_t position) {
/// @return The native position/mode setting.
uint8_t IRMitsubishiAC::getVaneLeft(void) const { return _.VaneLeft; }

/// Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.
/// @param[in] position The position/mode to set the wide vane to.
void IRMitsubishiAC::setWideVane(const uint8_t position) {
_.WideVane = std::min(position, kMitsubishiAcWideVaneAuto);
}

/// Get the Wide Vane (Horizontal Swing) mode of the A/C.
/// @return The native position/mode setting.
uint8_t IRMitsubishiAC::getWideVane(void) const {
return _.WideVane;
}

/// Get the clock time of the A/C unit.
/// @return Nr. of 10 minute increments past midnight.
/// @note 1 = 1/6 hour (10 minutes). e.g. 4pm = 48.
Expand Down Expand Up @@ -777,6 +875,12 @@ String IRMitsubishiAC::toString(void) const {
result += ')';
}
result += addBoolToString(_.WeeklyTimer, kWeeklyTimerStr);
result += addBoolToString(_.iSave10C, k10CHeatStr);
result += addBoolToString(_.ISee, kISeeStr);
result += addBoolToString(_.Ecocool, kEconoStr);
result += addBoolToString(_.AbsenseDetect, kAbsenseDetectStr);
result += addIntToString(_.DirectIndirect, kDirectIndirectModeStr);
result += addBoolToString(_.NaturalFlow, kFreshStr);
return result;
}

Expand Down
45 changes: 35 additions & 10 deletions src/ir_Mitsubishi.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
// Brand: Mitsubishi Electric, Model: MSZ-SF25VE3 A/C (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: SG15D remote (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: MSZ-ZW4017S A/C (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: MSZ-FHnnVE A/C (MITSUBISHI_AC)

#ifndef IR_MITSUBISHI_H_
#define IR_MITSUBISHI_H_
Expand Down Expand Up @@ -62,7 +63,8 @@ union Mitsubishi144Protocol{
// Byte 6
uint8_t :3;
uint8_t Mode :3;
uint8_t :2;
uint8_t ISee : 1;
uint8_t :1;
// Byte 7
uint8_t Temp :4;
uint8_t HalfDegree :1;
Expand All @@ -72,7 +74,7 @@ union Mitsubishi144Protocol{
uint8_t WideVane:4; // SwingH
// Byte 9
uint8_t Fan :3;
uint8_t Vane :3; // SwingV
uint8_t Vane :3; // SwingV or VaneRight
uint8_t VaneBit :1;
uint8_t FanAuto :1;
// Byte 10
Expand All @@ -86,13 +88,21 @@ union Mitsubishi144Protocol{
uint8_t WeeklyTimer :1;
uint8_t :4;
// Byte 14
uint8_t :8;
uint8_t :5;
uint8_t Ecocool :1;
uint8_t :2;
// Byte 15
uint8_t :8;
uint8_t DirectIndirect:2;
uint8_t AbsenseDetect :1;
uint8_t :2;
uint8_t iSave10C :1; // i-SAVE:mode=Heat & iSave=on AND 10C on remote
uint8_t :2;
// Byte 16
uint8_t :3;
uint8_t VaneLeft :3; // SwingV(Left)
uint8_t :2;
uint8_t :1;
uint8_t NaturalFlow :1;
uint8_t :1;
uint8_t VaneLeft :3; // SwingV(Left)
uint8_t :2;
// Byte 17
uint8_t Sum :8;
};
Expand Down Expand Up @@ -126,6 +136,9 @@ const uint8_t kMitsubishiAcWideVaneRight = 0b0100; // 4
const uint8_t kMitsubishiAcWideVaneRightMax = 0b0101; // 5
const uint8_t kMitsubishiAcWideVaneWide = 0b0110; // 6
const uint8_t kMitsubishiAcWideVaneAuto = 0b1000; // 8
const uint8_t kMitsubishiAcDirectOff = 0b00; // Vanes move when AC wants to.
const uint8_t kMitsubishiAcIndirect = 0b01;
const uint8_t kMitsubishiAcDirect = 0b11;
const uint8_t kMitsubishiAcNoTimer = 0;
const uint8_t kMitsubishiAcStartTimer = 5;
const uint8_t kMitsubishiAcStopTimer = 3;
Expand Down Expand Up @@ -274,12 +287,24 @@ class IRMitsubishiAC {
uint8_t getFan(void) const;
void setMode(const uint8_t mode);
uint8_t getMode(void) const;
void setVane(const uint8_t position);
void setWideVane(const uint8_t position);
void setISave10C(const bool state);
bool getISave10C(void) const;
void setISee(const bool state);
bool getISee(void) const;
void setDirectIndirect(const uint8_t position);
uint8_t getDirectIndirect(void) const;
void setEcocool(const bool state);
bool getEcocool(void) const;
void setAbsenseDetect(const bool state);
bool getAbsenseDetect(void) const;
void setNaturalFlow(const bool state);
bool getNaturalFlow(void) const;
void setVane(const uint8_t position); // controls RIGHT vane on some models
uint8_t getVane(void) const;
uint8_t getWideVane(void) const;
void setVaneLeft(const uint8_t position);
uint8_t getVaneLeft(void) const;
void setWideVane(const uint8_t position);
uint8_t getWideVane(void) const;
uint8_t* getRaw(void);
void setRaw(const uint8_t* data);
uint8_t getClock(void) const;
Expand Down
16 changes: 16 additions & 0 deletions src/locale/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@
#ifndef D_STR_IFEEL
#define D_STR_IFEEL "IFeel"
#endif // D_STR_IFEEL
#ifndef D_STR_ISEE
#define D_STR_ISEE "ISee"
Comment thread
crankyoldgit marked this conversation as resolved.
#endif // D_STR_ISEE
#ifndef D_STR_HUMID
#define D_STR_HUMID "Humid"
#endif // D_STR_HUMID
Expand Down Expand Up @@ -207,6 +210,19 @@
#ifndef D_STR_SENSOR
#define D_STR_SENSOR "Sensor"
#endif // D_STR_SENSOR
#ifndef D_STR_ABSENSEDETECT
#define D_STR_ABSENSEDETECT "Absense detect"
#endif // D_STR_ABSENSEDETECT
#ifndef D_STR_DIRECT
#define D_STR_DIRECT "Direct"
#endif // D_STR_DIRECT
#ifndef D_STR_INDIRECT
#define D_STR_INDIRECT "Indirect"
#endif // D_STR_INDIRECT
#ifndef D_STR_DIRECTINDIRECTMODE
#define D_STR_DIRECTINDIRECTMODE D_STR_DIRECT " / " \
D_STR_INDIRECT " " D_STR_MODE
#endif // D_STR_DIRECTINDIRECTMODE
#ifndef D_STR_DISPLAY
#define D_STR_DISPLAY "Display"
#endif // D_STR_DISPLAY
Expand Down
4 changes: 3 additions & 1 deletion test/IRac_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,9 @@ TEST(TestIRac, Mitsubishi) {
"Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 2 (Medium), "
"Swing(V): 0 (Auto), Swing(H): 3 (Middle), "
"Clock: 14:30, On Timer: 00:00, Off Timer: 00:00, Timer: -, "
"Weekly Timer: Off";
"Weekly Timer: Off"
", 10C Heat: Off, ISee: Off, Econo: Off, Absense detect: Off, "
"Direct / Indirect Mode: 0, Fresh: Off";

ac.begin();
irac.mitsubishi(&ac,
Expand Down
12 changes: 9 additions & 3 deletions test/ir_Mitsubishi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,15 +913,19 @@ TEST(TestMitsubishiACClass, HumanReadable) {
"Power: On, Mode: 1 (Heat), Temp: 22C, Fan: 6 (Quiet), "
"Swing(V): 0 (Auto), Swing(H): 3 (Middle), "
"Clock: 17:10, On Timer: 00:00, Off Timer: 00:00, Timer: -, "
"Weekly Timer: Off",
"Weekly Timer: Off"
", 10C Heat: Off, ISee: Off, Econo: Off, Absense detect: Off, "
"Direct / Indirect Mode: 0, Fresh: Off",
ac.toString());
ac.setTemp(21.5);
ac.setWeeklyTimerEnabled(true);
EXPECT_EQ(
"Power: On, Mode: 1 (Heat), Temp: 21.5C, Fan: 6 (Quiet), "
"Swing(V): 0 (Auto), Swing(H): 3 (Middle), "
"Clock: 17:10, On Timer: 00:00, Off Timer: 00:00, Timer: -, "
"Weekly Timer: On",
"Weekly Timer: On"
", 10C Heat: Off, ISee: Off, Econo: Off, Absense detect: Off, "
"Direct / Indirect Mode: 0, Fresh: Off",
ac.toString());
}

Expand Down Expand Up @@ -1434,7 +1438,9 @@ TEST(TestDecodeMitsubishiAC, Issue891) {
"Power: Off, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), "
"Swing(V): 0 (Auto), Swing(H): 3 (Middle), "
"Clock: 00:00, On Timer: 00:00, Off Timer: 00:00, Timer: -, "
"Weekly Timer: Off",
"Weekly Timer: Off"
", 10C Heat: Off, ISee: Off, Econo: Off, Absense detect: Off, "
"Direct / Indirect Mode: 0, Fresh: Off",
ac.toString());
}

Expand Down