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