IRremoteIDF
Infrared send & receive for ESP-IDF
Loading...
Searching...
No Matches
ir_Eurom.h
Go to the documentation of this file.
1// Copyright 2025 GottemHams
5
6// Supports:
7// Brand: Eurom, Model: Polar 16CH
8
9#ifndef IR_EUROM_H_
10#define IR_EUROM_H_
11
12#define __STDC_LIMIT_MACROS
13#include <stdint.h>
14#include "IRplatform.h"
15#include "IRremoteESP8266.h"
16#include "IRsend.h"
17#ifdef UNIT_TEST
18#include "IRsend_test.h"
19#endif
20
23 uint8_t raw[kEuromStateLength]; // The state of the IR remote
24 struct {
25 // Byte 0 is used as a negative offset for the checksum and is always 0x18
26 uint8_t Sum1 :8;
27
28 // Byte 1 is used as part of the checksum only and is always 0x27
29 uint8_t Sum2 :8;
30
31 // Byte 2 combines 2 functions and has some considerations:
32 // 1. Cooling mode almost always has the lower nibble set to 0x1,
33 // e.g. 0x01 = 16 C, 0x11 = 17 C, 0xF1 = 31 C.
34 // Exception: 0x09 means 32 C (max temperature).
35 // 2. Dehumidification doesn't support temperatures, so this is always 0x72.
36 // 3. Same goes for fan mode, which is always 0x73.
37 // 4. Heating mode almost always has the lower nibble set to 0x4,
38 // e.g. 0x04 = 16 C, 0x14 = 17 C, 0xF4 = 31 C.
39 // Exception: 0x0C means 32 C (max temperature).
40 uint8_t Mode_Celsius :8;
41
42 // Byte 3 also combines 2 functions, with the values being OR'ed together:
43 // 1. 0x00 means power off, swing off
44 // 2. 0x40 means power off, swing on
45 // 3. 0x80 means power on, swing off
46 // 3. 0xC0 means power on, swing on
47 uint8_t Power_Swing :8;
48
49 // Byte 4 is to track Fahrenheit separately, but note that it will always
50 // reset to 0x00 if Celsius is used. On the other hand, Celsius moves along
51 // with this, i.e. a change of +1/-1 C for roughly every 3 F. The base value
52 // is 0x41 which corresponds to 61 F and increases by 0x01 for every degree.
53 // This gives it a range of 0x41 - 0x5E (inclusive).
54 uint8_t Fahrenheit :8;
55
56 // Byte 5 yet again combines functions:
57 // 1. 0x00 for sleep mode disabled, 0x40 for enabled
58 // 2. The timer duration is simply encoded as BCD and added to this, with a
59 // maximum of 24 hours
60 uint8_t Sleep_OnTimer :8;
61
62 // Byte 6 seems to be truly unused, since it's always 0x00. We'll still
63 // always use it in checksums though.
64 uint8_t Sum3 :8;
65
66 // Byte 7 is always at least 0x80, with the hours also being added as BCD,
67 // e.g. 0x80 = 0 hours, 0x81 = 1 h, 0xA4 = 24 h.
68 uint8_t OffTimer :8;
69
70 // Byte 8 doesn't really seem to matter, but it should be 0x00 or 0x80 for
71 // off and on respectively. Apparently setting the **duration** alone is
72 // already enough to set the timer?
73 uint8_t OffTimerEnabled :8;
74
75 // Byte 9 is used as part of the checksum only and is slways 0x80
76 uint8_t Sum4 :8;
77
78 // Byte 10 is simple: 0x10, 0x20, 0x40 for low, medium and high respectively
79 uint8_t Fan :8;
80
81 // Byte 11 holds a funny checksum. =]
82 // Add all nibbles beyond the first byte (excluding the checksum of course),
83 // then subtract the first byte. The second byte should always be larger, so
84 // this never results in sudden signedness (i.e. underflowing). It might be
85 // pure coincidence that the first byte is always 0x18 and they could have
86 // hardcoded that value elsewhere/otherwise.
87 uint8_t Checksum :8;
88 };
89};
90
91// Constants
92
93// IR signal information
94const uint16_t kEuromHdrMark = 3257;
95const uint16_t kEuromBitMark = 454;
96const uint16_t kEuromHdrSpace = 3187;
97const uint16_t kEuromOneSpace = 1162;
98const uint16_t kEuromZeroSpace = 355;
99const uint16_t kEuromSpaceGap = 50058;
100const uint16_t kEuromFreq = 38000;
101
102// Modes
103const uint8_t kEuromCool = 0x01; // Lowest possible value, 16 C
104const uint8_t kEuromDehumidify = 0x72;
105const uint8_t kEuromVentilate = 0x73;
106const uint8_t kEuromHeat = 0x04; // Also 16 C
107
108// Reaching the highest temperature breaks the formula that is used otherwise,
109// because we should basically just OR this flag to the above mode byte. It
110// seems more like it indicates "max temp" instead of "32 C".
111const uint8_t kEuromMaxTempFlag = 0x08;
112
113// Temperatures
114const uint8_t kEuromMinTempC = 16;
115const uint8_t kEuromMaxTempC = 32;
116
117const uint8_t kEuromMinTempF = 61;
118const uint8_t kEuromMaxTempF = 90;
119
120// The enabled flag will simply be added to chosen temperature
121const uint8_t kEuromFahrenheitDisabled = 0x00;
122const uint8_t kEuromFahrenheitEnabled = 0x04;
123
124// Power and swing
125const uint8_t kEuromPowerSwingDisabled = 0x00;
126const uint8_t kEuromPowerOn = 0x80;
127const uint8_t kEuromSwingOn = 0x40;
128
129// Sleep mode and the "on timer"
130const uint8_t kEuromSleepOnTimerDisabled = 0x00;
131const uint8_t kEuromSleepEnabled = 0x40;
132
133// The "off timer"
134const uint8_t kEuromOffTimerDisabled = 0x00;
135const uint8_t kEuromOffTimerEnabled = 0x80;
136const uint8_t kEuromOffTimer = kEuromOffTimerEnabled; // Corresponds to 0 hours
137
138// Stuff for all timers
139const uint8_t kEuromTimerMin = 0;
140const uint8_t kEuromTimerMax = 24;
141
142// Fan speeds
143const uint8_t kEuromFanLow = 0x10;
144const uint8_t kEuromFanMed = 0x20;
145const uint8_t kEuromFanHigh = 0x40;
146
147// Classes
148
151 public:
152 explicit IREuromAc(const uint16_t pin, const bool inverted = false,
153 const bool use_modulation = true);
154
155 void stateReset();
156#if SEND_EUROM
157 void send(const uint16_t repeat = kNoRepeat);
162 int8_t calibrate(void) {
163 return _irsend.calibrate();
164 }
165#endif // SEND_EUROM
166
167 void begin(void);
168 static uint8_t calcChecksum(const uint8_t state[],
169 const uint16_t length = kEuromStateLength);
170 static bool validChecksum(const uint8_t state[],
171 const uint16_t length = kEuromStateLength);
172
173 void setRaw(const uint8_t state[]);
174 uint8_t *getRaw(void);
175
176 void on(void);
177 void off(void);
178
179 void setPower(const bool state);
180 bool getPower(void) const;
181
182 void setMode(const uint8_t mode);
183 uint8_t getMode(void) const;
184
185 void setTemp(const uint8_t degrees, const bool fahrenheit = false);
186 uint8_t getTemp(void) const;
187 bool getTempIsFahrenheit(void) const;
188
189 void setFan(const uint8_t speed);
190 uint8_t getFan(void) const;
191
192 void setSwing(const bool state);
193 bool getSwing(void) const;
194
195 void setSleep(const bool state);
196 bool getSleep(void) const;
197
198 void setOffTimer(const uint8_t duration);
199 uint8_t getOffTimer(void) const;
200
201 void setOnTimer(const uint8_t duration);
202 uint8_t getOnTimer(void) const;
203
204 static uint8_t convertMode(const stdAc::opmode_t mode);
205 static uint8_t convertFan(const stdAc::fanspeed_t speed);
206 static bool convertSwing(const stdAc::swingv_t swing);
207
208 static stdAc::opmode_t toCommonMode(const uint8_t mode);
209 static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
210 static stdAc::swingv_t toCommonSwing(const bool swing);
211
212 stdAc::state_t toCommon(void) const;
213 String toString(void) const;
214#ifndef UNIT_TEST
215
216 private:
218#else
220 IRsendTest _irsend;
222#endif
224
225 // Due to some bytes combining multiple functions, we'll need to keep track of
226 // some of the original values ourselves. Otherwise we wouldn't really be able
227 // to e.g. return the current mode or temperature, or changing the sleep mode
228 // without also messing with the timer hours.
230 uint8_t state_celsius_ = 23;
231 bool state_sleep_ = false;
233
234 // Some helper functions for reusing the above state variables depending on
235 // context and returning the byte expected by the AC.
236 uint8_t getModeCelsiusByte(const uint8_t mode, const uint8_t celsius) const;
237 uint8_t getSleepOnTimerByte(const bool sleep, const uint8_t hours) const;
238
239 void checksum(void);
240};
241
242#endif // IR_EUROM_H_
std::string String
The protocol code builds human readable output with String. On ESP-IDF that is just std::string.
Definition IRplatform.h:21
const uint16_t kNoRepeat
Definition IRremoteESP8266.h:1171
const uint16_t kEuromStateLength
Definition IRremoteESP8266.h:1467
Class for handling detailed Eurom A/C messages.
Definition ir_Eurom.h:150
void begin(void)
Set up hardware to be able to send a message.
Definition ir_Eurom.cpp:144
bool getSwing(void) const
Get the current swing setting from the internal state.
Definition ir_Eurom.cpp:308
bool getTempIsFahrenheit(void) const
Check if Fahrenheit is currently being used by the internal state.
Definition ir_Eurom.cpp:273
static stdAc::swingv_t toCommonSwing(const bool swing)
Convert a native swing setting into its stdAc enum equivalent.
Definition ir_Eurom.cpp:446
uint8_t state_celsius_
Definition ir_Eurom.h:230
void on(void)
Set the internal state to powered on.
Definition ir_Eurom.cpp:186
void setFan(const uint8_t speed)
Set the internal state to use the desired fan speed.
Definition ir_Eurom.cpp:279
stdAc::state_t toCommon(void) const
Convert the current internal state into its stdAc::state_t equivalent.
Definition ir_Eurom.cpp:453
uint8_t getFan(void) const
Get the current fan speed from the internal state.
Definition ir_Eurom.cpp:293
void setTemp(const uint8_t degrees, const bool fahrenheit=false)
Set the internal state to use the desired temperature.
Definition ir_Eurom.cpp:239
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kEuromStateLength)
Calculate the checksum for the supplied state.
Definition ir_Eurom.cpp:152
void setSwing(const bool state)
Set the internal state to use the desired swing setting.
Definition ir_Eurom.cpp:299
void checksum(void)
Update the checksum value for the current internal state.
Definition ir_Eurom.cpp:167
uint8_t state_mode_
Definition ir_Eurom.h:229
void send(const uint16_t repeat=kNoRepeat)
Send the current internal state as an IR message.
Definition ir_Eurom.cpp:138
static bool validChecksum(const uint8_t state[], const uint16_t length=kEuromStateLength)
Verify if the checksum is valid for a given state.
Definition ir_Eurom.cpp:162
bool getPower(void) const
Get the current power setting from the internal state.
Definition ir_Eurom.cpp:207
void off(void)
Set the internal state to powered off.
Definition ir_Eurom.cpp:191
uint8_t state_on_timer_
Definition ir_Eurom.h:232
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc enum equivalent.
Definition ir_Eurom.cpp:427
void stateReset()
Reset the internals of the object to a known good state.
Definition ir_Eurom.cpp:119
void setOffTimer(const uint8_t duration)
Set the internal state to use the desired "off timer" duration.
Definition ir_Eurom.cpp:327
uint8_t getSleepOnTimerByte(const bool sleep, const uint8_t hours) const
Combine sleep mode and a timer duration into a single byte for the AC. Note that validity is not chec...
Definition ir_Eurom.cpp:112
String toString(void) const
Convert the current internal state into a human-readable string.
Definition ir_Eurom.cpp:468
void setOnTimer(const uint8_t duration)
Set the internal state to use the desired "on timer" duration.
Definition ir_Eurom.cpp:342
uint8_t getOnTimer(void) const
Get the current "on timer" duration from the internal state.
Definition ir_Eurom.cpp:351
uint8_t getOffTimer(void) const
Get the current "off timer" duration from the internal state.
Definition ir_Eurom.cpp:336
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition ir_Eurom.h:162
uint8_t getTemp(void) const
Get the current temperature from the internal state.
Definition ir_Eurom.cpp:263
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native operation mode into its stdAc enum equivalent.
Definition ir_Eurom.cpp:406
void setRaw(const uint8_t state[])
Set the raw state of the remote.
Definition ir_Eurom.cpp:173
bool getSleep(void) const
Get the current sleep setting from the internal state.
Definition ir_Eurom.cpp:321
static bool convertSwing(const stdAc::swingv_t swing)
Convert a stdAc::swingv_t enum into its native swing.
Definition ir_Eurom.cpp:393
void setMode(const uint8_t mode)
Set the internal state to use the desired operation mode.
Definition ir_Eurom.cpp:213
IRsend _irsend
Definition ir_Eurom.h:217
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into its native speed.
Definition ir_Eurom.cpp:376
uint8_t getModeCelsiusByte(const uint8_t mode, const uint8_t celsius) const
Combine a mode flag and temperature into a single byte for the AC. Note that validity is not checked ...
Definition ir_Eurom.cpp:101
uint8_t * getRaw(void)
Get the raw state of the remote, suitable to be sent with the appropriate IRsend object method.
Definition ir_Eurom.cpp:180
EuromProtocol _
Definition ir_Eurom.h:223
void setPower(const bool state)
Set the internal state to use the desired power setting.
Definition ir_Eurom.cpp:197
bool state_sleep_
Definition ir_Eurom.h:231
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native operation mode.
Definition ir_Eurom.cpp:358
uint8_t getMode(void) const
Get the current operation mode setting from the internal state.
Definition ir_Eurom.cpp:232
void setSleep(const bool state)
Set the internal state to use the desired sleep setting.
Definition ir_Eurom.cpp:314
Class for sending all basic IR protocols.
Definition IRsend.h:256
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition IRsend.cpp:286
const uint8_t kEuromSleepOnTimerDisabled
Definition ir_Eurom.h:130
const uint16_t kEuromHdrMark
Definition ir_Eurom.h:94
const uint8_t kEuromSwingOn
Definition ir_Eurom.h:127
const uint8_t kEuromMinTempC
Definition ir_Eurom.h:114
const uint8_t kEuromVentilate
Definition ir_Eurom.h:105
const uint8_t kEuromPowerSwingDisabled
Definition ir_Eurom.h:125
const uint8_t kEuromTimerMin
Definition ir_Eurom.h:139
const uint8_t kEuromMaxTempC
Definition ir_Eurom.h:115
const uint16_t kEuromOneSpace
Definition ir_Eurom.h:97
const uint8_t kEuromCool
Definition ir_Eurom.h:103
const uint8_t kEuromFahrenheitDisabled
Definition ir_Eurom.h:121
const uint8_t kEuromMinTempF
Definition ir_Eurom.h:117
const uint16_t kEuromZeroSpace
Definition ir_Eurom.h:98
const uint8_t kEuromFanMed
Definition ir_Eurom.h:144
const uint8_t kEuromFanLow
Definition ir_Eurom.h:143
const uint8_t kEuromMaxTempF
Definition ir_Eurom.h:118
const uint8_t kEuromFahrenheitEnabled
Definition ir_Eurom.h:122
const uint8_t kEuromSleepEnabled
Definition ir_Eurom.h:131
const uint8_t kEuromFanHigh
Definition ir_Eurom.h:145
const uint8_t kEuromTimerMax
Definition ir_Eurom.h:140
const uint8_t kEuromPowerOn
Definition ir_Eurom.h:126
const uint8_t kEuromOffTimerDisabled
Definition ir_Eurom.h:134
const uint8_t kEuromOffTimer
Definition ir_Eurom.h:136
const uint16_t kEuromSpaceGap
Definition ir_Eurom.h:99
const uint8_t kEuromOffTimerEnabled
Definition ir_Eurom.h:135
const uint16_t kEuromFreq
Definition ir_Eurom.h:100
const uint8_t kEuromHeat
Definition ir_Eurom.h:106
const uint16_t kEuromHdrSpace
Definition ir_Eurom.h:96
const uint8_t kEuromMaxTempFlag
Definition ir_Eurom.h:111
const uint8_t kEuromDehumidify
Definition ir_Eurom.h:104
const uint16_t kEuromBitMark
Definition ir_Eurom.h:95
fanspeed_t
Common A/C settings for Fan Speeds.
Definition IRsend.h:67
opmode_t
Common A/C settings for A/C operating modes.
Definition IRsend.h:55
swingv_t
Common A/C settings for Vertical Swing.
Definition IRsend.h:80
Structure to hold a common A/C state.
Definition IRsend.h:120
Native representation of a Eurom message.
Definition ir_Eurom.h:22
uint8_t Sum1
Definition ir_Eurom.h:26
uint8_t OffTimerEnabled
Definition ir_Eurom.h:73
uint8_t Sum2
Definition ir_Eurom.h:29
uint8_t Sum4
Definition ir_Eurom.h:76
uint8_t Sum3
Definition ir_Eurom.h:64
uint8_t Power_Swing
Definition ir_Eurom.h:47
uint8_t Fahrenheit
Definition ir_Eurom.h:54
uint8_t Fan
Definition ir_Eurom.h:79
uint8_t Mode_Celsius
Definition ir_Eurom.h:40
uint8_t OffTimer
Definition ir_Eurom.h:68
uint8_t raw[kEuromStateLength]
Definition ir_Eurom.h:23
uint8_t Checksum
Definition ir_Eurom.h:87
uint8_t Sleep_OnTimer
Definition ir_Eurom.h:60