-
Notifications
You must be signed in to change notification settings - Fork 835
/
ir_Kelon.h
142 lines (127 loc) · 4.53 KB
/
ir_Kelon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2021 Davide Depau
/// @file
/// @brief Support for Kelan AC protocol.
/// @note Both sending and decoding should be functional for models of series
/// KELON ON/OFF 9000-12000.
/// All features of the standard remote are implemented.
///
/// @note Unsupported:
/// - Explicit on/off due to AC unit limitations
/// - Explicit swing position due to AC unit limitations
/// - Fahrenheit.
///
/// For KELON168:
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1745
// Supports:
// Brand: Kelon, Model: ON/OFF 9000-12000 (KELON)
// Brand: Kelon, Model: DG11R2-01 remote (KELON168)
// Brand: Kelon, Model: AST-09UW4RVETG00A A/C (KELON168)
// Brand: Hisense, Model: AST-09UW4RVETG00A A/C (KELON168)
#ifndef IR_KELON_H_
#define IR_KELON_H_
#ifdef UNIT_TEST
#include "IRsend_test.h"
#endif
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "IRutils.h"
union KelonProtocol {
uint64_t raw;
struct {
uint8_t preamble[2];
uint8_t Fan: 2;
uint8_t PowerToggle: 1;
uint8_t SleepEnabled: 1;
uint8_t DehumidifierGrade: 3;
uint8_t SwingVToggle: 1;
uint8_t Mode: 3;
uint8_t TimerEnabled: 1;
uint8_t Temperature: 4;
uint8_t TimerHalfHour: 1;
uint8_t TimerHours: 6;
uint8_t SmartModeEnabled: 1;
uint8_t pad1: 4;
uint8_t SuperCoolEnabled1: 1;
uint8_t pad2: 2;
uint8_t SuperCoolEnabled2: 1;
};
};
// Constants
const uint8_t kKelonModeHeat = 0;
const uint8_t kKelonModeSmart = 1; // (temp = 26C, but not shown)
const uint8_t kKelonModeCool = 2;
const uint8_t kKelonModeDry = 3; // (temp = 25C, but not shown)
const uint8_t kKelonModeFan = 4; // (temp = 25C, but not shown)
const uint8_t kKelonFanAuto = 0;
// Note! Kelon fan speeds are actually 0:AUTO, 1:MAX, 2:MED, 3:MIN
// Since this is insane, I decided to invert them in the public API, they are
// converted back in setFan/getFan
const uint8_t kKelonFanMin = 1;
const uint8_t kKelonFanMedium = 2;
const uint8_t kKelonFanMax = 3;
const int8_t kKelonDryGradeMin = -2;
const int8_t kKelonDryGradeMax = +2;
const uint8_t kKelonMinTemp = 18;
const uint8_t kKelonMaxTemp = 32;
class IRKelonAc {
public:
explicit IRKelonAc(uint16_t pin, bool inverted = false,
bool use_modulation = true);
void stateReset(void);
#if SEND_KELON
void send(const uint16_t repeat = kNoRepeat);
/// Run the calibration to calculate uSec timing offsets for this platform.
/// @return The uSec timing offset needed per modulation of the IR Led.
/// @note This will produce a 65ms IR signal pulse at 38kHz.
/// Only ever needs to be run once per object instantiation, if at all.
int8_t calibrate(void) { return _irsend.calibrate(); }
/// Since the AC does not support actually setting the power state to a known
/// value, this utility allow ensuring the AC is on or off by exploiting
/// the fact that the AC, according to the user manual, will always turn on
/// when setting it to "smart" or "super" mode.
void ensurePower(const bool on);
#endif // SEND_KELON
void begin(void);
void setTogglePower(const bool toggle);
bool getTogglePower(void) const;
void setTemp(const uint8_t degrees);
uint8_t getTemp(void) const;
void setFan(const uint8_t speed);
uint8_t getFan(void) const;
void setDryGrade(const int8_t grade);
int8_t getDryGrade(void) const;
void setMode(const uint8_t mode);
uint8_t getMode(void) const;
void setToggleSwingVertical(const bool toggle);
bool getToggleSwingVertical(void) const;
void setSleep(const bool on);
bool getSleep(void) const;
void setSupercool(const bool on);
bool getSupercool(void) const;
void setTimer(const uint16_t mins);
uint16_t getTimer(void) const;
void setTimerEnabled(const bool on);
bool getTimerEnabled(void) const;
uint64_t getRaw(void) const;
void setRaw(const uint64_t new_code);
static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t fan);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
stdAc::state_t toCommon(const stdAc::state_t *prev = nullptr) const;
String toString(void) const;
private:
#ifndef UNIT_TEST
IRsend _irsend; ///< Instance of the IR send class
#else // UNIT_TEST
/// @cond IGNORE
IRsendTest _irsend; ///< Instance of the testing IR send class
/// @endcond
#endif // UNIT_TEST
KelonProtocol _;
// Used when exiting supercool mode
uint8_t _previousMode = 0;
uint8_t _previousTemp = kKelonMinTemp;
uint8_t _previousFan = kKelonFanAuto;
};
#endif // IR_KELON_H_