mirror of
https://github.com/crankyoldgit/IRremoteESP8266.git
synced 2026-01-12 00:05:10 +08:00
@@ -20,7 +20,6 @@ using irutils::addModeToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::minsToString;
|
||||
using irutils::setBit;
|
||||
using irutils::setBits;
|
||||
|
||||
// Constants
|
||||
@@ -154,15 +153,15 @@ IRCoronaAc::IRCoronaAc(const uint16_t pin, const bool inverted,
|
||||
/// @note The state is powered off.
|
||||
void IRCoronaAc::stateReset(void) {
|
||||
// known good state
|
||||
remote_state[kCoronaAcSectionData0Pos] = kCoronaAcSectionData0Base;
|
||||
remote_state[kCoronaAcSectionData1Pos] = 0x00; // ensure no unset mem
|
||||
_.sections[kCoronaAcSettingsSection].Data0 = kCoronaAcSectionData0Base;
|
||||
_.sections[kCoronaAcSettingsSection].Data1 = 0x00; // ensure no unset mem
|
||||
setPowerButton(true); // we default to this on, any timer removes it
|
||||
setTemp(kCoronaAcMinTemp);
|
||||
setMode(kCoronaAcModeCool);
|
||||
setFan(kCoronaAcFanAuto);
|
||||
setOnTimer(kCoronaAcTimerOff);
|
||||
setOffTimer(kCoronaAcTimerOff);
|
||||
// headers and checks are fixed in getRaw by checksum(remote_state)
|
||||
// headers and checks are fixed in getRaw by checksum(_.raw)
|
||||
}
|
||||
|
||||
/// Get the byte that identifies the section
|
||||
@@ -191,45 +190,46 @@ bool IRCoronaAc::validSection(const uint8_t state[], const uint16_t pos,
|
||||
if ((section % kCoronaAcSections) * kCoronaAcSectionBytes != pos)
|
||||
return false;
|
||||
// all individual sections has the same prefix
|
||||
if (state[pos + kCoronaAcSectionHeader0Pos] != kCoronaAcSectionHeader0) {
|
||||
const CoronaSection *p = reinterpret_cast<const CoronaSection*>(state + pos);
|
||||
if (p->Header0 != kCoronaAcSectionHeader0) {
|
||||
DPRINT("State ");
|
||||
DPRINT(pos + kCoronaAcSectionHeader0Pos);
|
||||
DPRINT(&(p->Header0) - state);
|
||||
DPRINT(" expected 0x28 was ");
|
||||
DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader0Pos], 16));
|
||||
DPRINTLN(uint64ToString(p->Header0, 16));
|
||||
return false;
|
||||
}
|
||||
if (state[pos + kCoronaAcSectionHeader1Pos] != kCoronaAcSectionHeader1) {
|
||||
if (p->Header1 != kCoronaAcSectionHeader1) {
|
||||
DPRINT("State ");
|
||||
DPRINT(pos + kCoronaAcSectionHeader1Pos);
|
||||
DPRINT(&(p->Header1) - state);
|
||||
DPRINT(" expected 0x61 was ");
|
||||
DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader1Pos], 16));
|
||||
DPRINTLN(uint64ToString(p->Header1, 16));
|
||||
return false;
|
||||
}
|
||||
|
||||
// checking section byte
|
||||
if (state[pos + kCoronaAcSectionLabelPos] != getSectionByte(section)) {
|
||||
if (p->Label != getSectionByte(section)) {
|
||||
DPRINT("check 2 not matching, got ");
|
||||
DPRINT(uint64ToString(state[pos + kCoronaAcSectionLabelPos], 16));
|
||||
DPRINT(uint64ToString(p->Label, 16));
|
||||
DPRINT(" expected ");
|
||||
DPRINTLN(uint64ToString(getSectionByte(section), 16));
|
||||
return false;
|
||||
}
|
||||
|
||||
// checking inverts
|
||||
uint8_t d0invinv = ~state[pos + kCoronaAcSectionData0InvPos];
|
||||
if (state[pos + kCoronaAcSectionData0Pos] != d0invinv) {
|
||||
uint8_t d0invinv = ~p->Data0Inv;
|
||||
if (p->Data0 != d0invinv) {
|
||||
DPRINT("inverted 3 - 4 not matching, got ");
|
||||
DPRINT(uint64ToString(state[pos + kCoronaAcSectionData0Pos], 16));
|
||||
DPRINT(uint64ToString(p->Data0, 16));
|
||||
DPRINT(" vs ");
|
||||
DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData0InvPos], 16));
|
||||
DPRINTLN(uint64ToString(p->Data0Inv, 16));
|
||||
return false;
|
||||
}
|
||||
uint8_t d1invinv = ~state[pos + kCoronaAcSectionData1InvPos];
|
||||
if (state[pos + kCoronaAcSectionData1Pos] != d1invinv) {
|
||||
uint8_t d1invinv = ~p->Data1Inv;
|
||||
if (p->Data1 != d1invinv) {
|
||||
DPRINT("inverted 5 - 6 not matching, got ");
|
||||
DPRINT(uint64ToString(state[pos + kCoronaAcSectionData1Pos], 16));
|
||||
DPRINT(uint64ToString(p->Data1, 16));
|
||||
DPRINT(" vs ");
|
||||
DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData1InvPos], 16));
|
||||
DPRINTLN(uint64ToString(p->Data1Inv, 16));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -238,16 +238,13 @@ bool IRCoronaAc::validSection(const uint8_t state[], const uint16_t pos,
|
||||
/// Calculate and set the check values for the internal state.
|
||||
/// @param[in,out] data The array to be modified
|
||||
void IRCoronaAc::checksum(uint8_t* data) {
|
||||
uint8_t pos;
|
||||
for (uint8_t section = 0; section < kCoronaAcSections; section++) {
|
||||
pos = section * kCoronaAcSectionBytes;
|
||||
data[pos + kCoronaAcSectionHeader0Pos] = kCoronaAcSectionHeader0;
|
||||
data[pos + kCoronaAcSectionHeader1Pos] = kCoronaAcSectionHeader1;
|
||||
data[pos + kCoronaAcSectionLabelPos] = getSectionByte(section);
|
||||
data[pos + kCoronaAcSectionData0InvPos] =
|
||||
~data[pos + kCoronaAcSectionData0Pos];
|
||||
data[pos + kCoronaAcSectionData1InvPos] =
|
||||
~data[pos + kCoronaAcSectionData1Pos];
|
||||
CoronaProtocol *p = reinterpret_cast<CoronaProtocol*>(data);
|
||||
for (uint8_t i = 0; i < kCoronaAcSections; i++) {
|
||||
p->sections[i].Header0 = kCoronaAcSectionHeader0;
|
||||
p->sections[i].Header1 = kCoronaAcSectionHeader1;
|
||||
p->sections[i].Label = getSectionByte(i);
|
||||
p->sections[i].Data0Inv = ~p->sections[i].Data0;
|
||||
p->sections[i].Data1Inv = ~p->sections[i].Data1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,15 +272,15 @@ void IRCoronaAc::send(const uint16_t repeat) {
|
||||
/// @note To get stable AC state, if no timers, send once
|
||||
/// without PowerButton set, and once with
|
||||
uint8_t* IRCoronaAc::getRaw(void) {
|
||||
checksum(remote_state); // Ensure correct check bits before sending.
|
||||
return remote_state;
|
||||
checksum(_.raw); // Ensure correct check bits before sending.
|
||||
return _.raw;
|
||||
}
|
||||
|
||||
/// Set the internal state from a valid code for this protocol.
|
||||
/// @param[in] new_code A valid state for this protocol.
|
||||
/// @param[in] length of the new_code array.
|
||||
void IRCoronaAc::setRaw(const uint8_t new_code[], const uint16_t length) {
|
||||
memcpy(remote_state, new_code, std::min(length, kCoronaAcStateLength));
|
||||
memcpy(_.raw, new_code, std::min(length, kCoronaAcStateLength));
|
||||
}
|
||||
|
||||
/// Set the temp in deg C.
|
||||
@@ -291,21 +288,13 @@ void IRCoronaAc::setRaw(const uint8_t new_code[], const uint16_t length) {
|
||||
void IRCoronaAc::setTemp(const uint8_t temp) {
|
||||
uint8_t degrees = std::max(temp, kCoronaAcMinTemp);
|
||||
degrees = std::min(degrees, kCoronaAcMaxTemp);
|
||||
setBits(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset,
|
||||
kCoronaAcTempSize, degrees - kCoronaAcMinTemp + 1);
|
||||
_.Temp = degrees - kCoronaAcMinTemp + 1;
|
||||
}
|
||||
|
||||
/// Get the current temperature from the internal state.
|
||||
/// @return The current temperature in Celsius.
|
||||
uint8_t IRCoronaAc::getTemp(void) {
|
||||
return GETBITS8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset,
|
||||
kCoronaAcTempSize) + kCoronaAcMinTemp - 1;
|
||||
}
|
||||
|
||||
/// Change the power setting. (in practice Standby, remote power)
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRCoronaAc::_setPower(const bool on) {
|
||||
setBit(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset, on);
|
||||
uint8_t IRCoronaAc::getTemp(void) const {
|
||||
return _.Temp + kCoronaAcMinTemp - 1;
|
||||
}
|
||||
|
||||
/// Change the power setting. (in practice Standby, remote power)
|
||||
@@ -313,7 +302,7 @@ void IRCoronaAc::_setPower(const bool on) {
|
||||
/// @note If changed, setPowerButton is also needed,
|
||||
/// unless timer is or was active
|
||||
void IRCoronaAc::setPower(const bool on) {
|
||||
_setPower(on);
|
||||
_.Power = on;
|
||||
// setting power state resets timers that would cause the state
|
||||
if (on)
|
||||
setOnTimer(kCoronaAcTimerOff);
|
||||
@@ -323,8 +312,8 @@ void IRCoronaAc::setPower(const bool on) {
|
||||
|
||||
/// Get the current power setting. (in practice Standby, remote power)
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRCoronaAc::getPower(void) {
|
||||
return GETBIT8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset);
|
||||
bool IRCoronaAc::getPower(void) const {
|
||||
return _.Power;
|
||||
}
|
||||
|
||||
/// Change the power button setting.
|
||||
@@ -337,15 +326,13 @@ bool IRCoronaAc::getPower(void) {
|
||||
/// With AC Off, a command with setPower but not setPowerButton gives nothing
|
||||
/// With AC Off, a command with setPower and setPowerButton is ok
|
||||
void IRCoronaAc::setPowerButton(const bool on) {
|
||||
setBit(&remote_state[kCoronaAcSectionData1Pos],
|
||||
kCoronaAcPowerButtonOffset, on);
|
||||
_.PowerButton = on;
|
||||
}
|
||||
|
||||
/// Get the value of the current power button setting.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRCoronaAc::getPowerButton(void) {
|
||||
return GETBIT8(remote_state[kCoronaAcSectionData1Pos],
|
||||
kCoronaAcPowerButtonOffset);
|
||||
bool IRCoronaAc::getPowerButton(void) const {
|
||||
return _.PowerButton;
|
||||
}
|
||||
|
||||
/// Change the power setting to On.
|
||||
@@ -356,9 +343,8 @@ void IRCoronaAc::off(void) { setPower(false); }
|
||||
|
||||
/// Get the operating mode setting of the A/C.
|
||||
/// @return The current operating mode setting.
|
||||
uint8_t IRCoronaAc::getMode(void) {
|
||||
return GETBITS8(remote_state[kCoronaAcSectionData1Pos],
|
||||
kCoronaAcModeOffset, kCoronaAcModeSize);
|
||||
uint8_t IRCoronaAc::getMode(void) const {
|
||||
return _.Mode;
|
||||
}
|
||||
|
||||
/// Set the operating mode of the A/C.
|
||||
@@ -369,12 +355,10 @@ void IRCoronaAc::setMode(const uint8_t mode) {
|
||||
case kCoronaAcModeDry:
|
||||
case kCoronaAcModeFan:
|
||||
case kCoronaAcModeHeat:
|
||||
setBits(&remote_state[kCoronaAcSectionData1Pos],
|
||||
kCoronaAcModeOffset, kCoronaAcModeSize,
|
||||
mode);
|
||||
_.Mode = mode;
|
||||
return;
|
||||
default:
|
||||
this->setMode(kCoronaAcModeCool);
|
||||
_.Mode = kCoronaAcModeCool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,32 +389,29 @@ stdAc::opmode_t IRCoronaAc::toCommonMode(const uint8_t mode) {
|
||||
|
||||
/// Get the operating speed of the A/C Fan
|
||||
/// @return The current operating fan speed setting
|
||||
uint8_t IRCoronaAc::getFan(void) {
|
||||
return GETBITS8(remote_state[kCoronaAcSectionData0Pos],
|
||||
kCoronaAcFanOffset, kCoronaAcFanSize);
|
||||
uint8_t IRCoronaAc::getFan(void) const {
|
||||
return _.Fan;
|
||||
}
|
||||
|
||||
/// Set the operating speed of the A/C Fan
|
||||
/// @param[in] speed The desired fan speed
|
||||
void IRCoronaAc::setFan(const uint8_t speed) {
|
||||
if (speed > kCoronaAcFanHigh)
|
||||
setFan(kCoronaAcFanAuto);
|
||||
_.Fan = kCoronaAcFanAuto;
|
||||
else
|
||||
setBits(&remote_state[kCoronaAcSectionData0Pos],
|
||||
kCoronaAcFanOffset, kCoronaAcFanSize, speed);
|
||||
_.Fan = speed;
|
||||
}
|
||||
|
||||
/// Change the powersave setting.
|
||||
/// @param[in] on true, the setting is on. false, the setting is off.
|
||||
void IRCoronaAc::setEcono(const bool on) {
|
||||
setBit(&remote_state[kCoronaAcSectionData0Pos], kCoronaAcPowerSaveOffset, on);
|
||||
_.Econo = on;
|
||||
}
|
||||
|
||||
/// Get the value of the current powersave setting.
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRCoronaAc::getEcono(void) {
|
||||
return GETBIT8(remote_state[kCoronaAcSectionData0Pos],
|
||||
kCoronaAcPowerSaveOffset);
|
||||
bool IRCoronaAc::getEcono(void) const {
|
||||
return _.Econo;
|
||||
}
|
||||
|
||||
/// Convert a standard A/C Fan speed into its native fan speed.
|
||||
@@ -464,15 +445,13 @@ stdAc::fanspeed_t IRCoronaAc::toCommonFanSpeed(const uint8_t speed) {
|
||||
/// @note This is a button press, and not a state
|
||||
/// after sending it once you should turn it off
|
||||
void IRCoronaAc::setSwingVToggle(const bool on) {
|
||||
setBit(&remote_state[kCoronaAcSectionData0Pos],
|
||||
kCoronaAcSwingVToggleOffset, on);
|
||||
_.SwingVToggle = on;
|
||||
}
|
||||
|
||||
/// Get the Vertical Swing toggle setting
|
||||
/// @return true, the setting is on. false, the setting is off.
|
||||
bool IRCoronaAc::getSwingVToggle(void) {
|
||||
return GETBIT64(remote_state[kCoronaAcSectionData0Pos],
|
||||
kCoronaAcSwingVToggleOffset);
|
||||
bool IRCoronaAc::getSwingVToggle(void) const {
|
||||
return _.SwingVToggle;
|
||||
}
|
||||
|
||||
/// Set the Timer time
|
||||
@@ -486,14 +465,13 @@ void IRCoronaAc::_setTimer(const uint8_t section, const uint16_t nr_of_mins) {
|
||||
if (1 <= nr_of_mins && nr_of_mins <= kCoronaAcTimerMax)
|
||||
hsecs = nr_of_mins * kCoronaAcTimerUnitsPerMin;
|
||||
|
||||
uint8_t pos = section * kCoronaAcSectionBytes;
|
||||
// convert 16 bit value to separate 8 bit parts
|
||||
remote_state[pos + kCoronaAcSectionData1Pos] = hsecs >> 8;
|
||||
remote_state[pos + kCoronaAcSectionData0Pos] = hsecs;
|
||||
_.sections[section].Data1 = hsecs >> 8;
|
||||
_.sections[section].Data0 = hsecs;
|
||||
|
||||
// if any timer is enabled, then (remote) ac must be on (Standby)
|
||||
if (hsecs != kCoronaAcTimerOff) {
|
||||
_setPower(true);
|
||||
_.Power = true;
|
||||
setPowerButton(false);
|
||||
}
|
||||
}
|
||||
@@ -501,11 +479,10 @@ void IRCoronaAc::_setTimer(const uint8_t section, const uint16_t nr_of_mins) {
|
||||
/// Get the current Timer time
|
||||
/// @return The number of minutes it is set for. 0 means it's off.
|
||||
/// @note The A/C protocol supports 2 second increments
|
||||
uint16_t IRCoronaAc::_getTimer(const uint8_t section) {
|
||||
uint8_t pos = section * kCoronaAcSectionBytes;
|
||||
uint16_t IRCoronaAc::_getTimer(const uint8_t section) const {
|
||||
// combine separate 8 bit parts to 16 bit value
|
||||
uint16_t hsecs = remote_state[pos + kCoronaAcSectionData1Pos] << 8 |
|
||||
remote_state[pos + kCoronaAcSectionData0Pos];
|
||||
uint16_t hsecs = _.sections[section].Data1 << 8 |
|
||||
_.sections[section].Data0;
|
||||
|
||||
if (hsecs == kCoronaAcTimerOff)
|
||||
return 0;
|
||||
@@ -515,7 +492,7 @@ uint16_t IRCoronaAc::_getTimer(const uint8_t section) {
|
||||
|
||||
/// Get the current On Timer time
|
||||
/// @return The number of minutes it is set for. 0 means it's off.
|
||||
uint16_t IRCoronaAc::getOnTimer(void) {
|
||||
uint16_t IRCoronaAc::getOnTimer(void) const {
|
||||
return _getTimer(kCoronaAcOnTimerSection);
|
||||
}
|
||||
|
||||
@@ -531,7 +508,7 @@ void IRCoronaAc::setOnTimer(const uint16_t nr_of_mins) {
|
||||
|
||||
/// Get the current Off Timer time
|
||||
/// @return The number of minutes it is set for. 0 means it's off.
|
||||
uint16_t IRCoronaAc::getOffTimer(void) {
|
||||
uint16_t IRCoronaAc::getOffTimer(void) const {
|
||||
return _getTimer(kCoronaAcOffTimerSection);
|
||||
}
|
||||
|
||||
@@ -547,20 +524,20 @@ void IRCoronaAc::setOffTimer(const uint16_t nr_of_mins) {
|
||||
|
||||
/// Convert the internal state into a human readable string.
|
||||
/// @return The current internal state expressed as a human readable String.
|
||||
String IRCoronaAc::toString(void) {
|
||||
String IRCoronaAc::toString(void) const {
|
||||
String result = "";
|
||||
result.reserve(140); // Reserve some heap for the string to reduce fragging.
|
||||
result += addBoolToString(getPower(), kPowerStr, false);
|
||||
result += addBoolToString(getPowerButton(), kPowerButtonStr);
|
||||
result += addModeToString(getMode(), 0xFF, kCoronaAcModeCool,
|
||||
result += addBoolToString(_.Power, kPowerStr, false);
|
||||
result += addBoolToString(_.PowerButton, kPowerButtonStr);
|
||||
result += addModeToString(_.Mode, 0xFF, kCoronaAcModeCool,
|
||||
kCoronaAcModeHeat, kCoronaAcModeDry,
|
||||
kCoronaAcModeFan);
|
||||
result += addTempToString(getTemp());
|
||||
result += addFanToString(getFan(), kCoronaAcFanHigh, kCoronaAcFanLow,
|
||||
result += addFanToString(_.Fan, kCoronaAcFanHigh, kCoronaAcFanLow,
|
||||
kCoronaAcFanAuto, kCoronaAcFanAuto,
|
||||
kCoronaAcFanMedium);
|
||||
result += addBoolToString(getSwingVToggle(), kSwingVToggleStr);
|
||||
result += addBoolToString(getEcono(), kEconoStr);
|
||||
result += addBoolToString(_.SwingVToggle, kSwingVToggleStr);
|
||||
result += addBoolToString(_.Econo, kEconoStr);
|
||||
result += addLabeledString(getOnTimer()
|
||||
? minsToString(getOnTimer()) : kOffStr,
|
||||
kOnTimerStr);
|
||||
@@ -572,18 +549,18 @@ String IRCoronaAc::toString(void) {
|
||||
|
||||
/// Convert the A/C state to it's common stdAc::state_t equivalent.
|
||||
/// @return A stdAc::state_t state.
|
||||
stdAc::state_t IRCoronaAc::toCommon() {
|
||||
stdAc::state_t IRCoronaAc::toCommon() const {
|
||||
stdAc::state_t result;
|
||||
result.protocol = decode_type_t::CORONA_AC;
|
||||
result.model = -1; // No models used.
|
||||
result.power = getPower();
|
||||
result.mode = toCommonMode(getMode());
|
||||
result.power = _.Power;
|
||||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.fanspeed = toCommonFanSpeed(getFan());
|
||||
result.swingv = getSwingVToggle() ?
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.swingv = _.SwingVToggle ?
|
||||
stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
|
||||
result.econo = getEcono();
|
||||
result.econo = _.Econo;
|
||||
// Not supported.
|
||||
result.sleep = -1;
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
|
||||
105
src/ir_Corona.h
105
src/ir_Corona.h
@@ -26,60 +26,72 @@
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
|
||||
struct CoronaSection {
|
||||
uint8_t Header0;
|
||||
uint8_t Header1;
|
||||
uint8_t Label;
|
||||
uint8_t Data0;
|
||||
uint8_t Data0Inv;
|
||||
uint8_t Data1;
|
||||
uint8_t Data1Inv;
|
||||
};
|
||||
|
||||
const uint8_t kCoronaAcSections = 3;
|
||||
|
||||
union CoronaProtocol {
|
||||
uint8_t raw[kCoronaAcStateLength]; ///< The state of the IR remote.
|
||||
CoronaSection sections[kCoronaAcSections];
|
||||
struct {
|
||||
// Byte 0
|
||||
uint8_t :8;
|
||||
// Byte 1
|
||||
uint8_t :8;
|
||||
// Byte 2
|
||||
uint8_t :8;
|
||||
// Byte 3
|
||||
uint8_t Fan :2;
|
||||
uint8_t :1;
|
||||
uint8_t Econo :1;
|
||||
uint8_t :1; // always on
|
||||
uint8_t :1;
|
||||
uint8_t SwingVToggle :1;
|
||||
uint8_t :1;
|
||||
// Byte 4
|
||||
uint8_t :8;
|
||||
// Byte 5
|
||||
uint8_t Temp :4;
|
||||
uint8_t Power :1;
|
||||
uint8_t PowerButton :1;
|
||||
uint8_t Mode :2;
|
||||
};
|
||||
};
|
||||
|
||||
// Constants
|
||||
|
||||
// CORONA_AC
|
||||
const uint8_t kCoronaAcSectionBytes = 7; // kCoronaAcStateLengthShort
|
||||
const uint8_t kCoronaAcSections = 3;
|
||||
const uint8_t kCoronaAcSectionHeader0Pos = 0;
|
||||
const uint8_t kCoronaAcSectionHeader0 = 0x28;
|
||||
const uint8_t kCoronaAcSectionHeader1Pos = 1;
|
||||
const uint8_t kCoronaAcSectionHeader1 = 0x61;
|
||||
const uint8_t kCoronaAcSectionLabelPos = 2;
|
||||
const uint8_t kCoronaAcSectionLabelBase = 0x0D; // 0b1101
|
||||
const uint8_t kCoronaAcSectionData0Pos = 3;
|
||||
const uint8_t kCoronaAcSectionData0InvPos = 4;
|
||||
const uint8_t kCoronaAcSectionData1Pos = 5;
|
||||
const uint8_t kCoronaAcSectionData1InvPos = 6;
|
||||
const uint8_t kCoronaAcSectionData0Base = 0x10; // D0 Pos 4 always on
|
||||
|
||||
const uint8_t kCoronaAcSettingsSection = 0;
|
||||
// D0
|
||||
const uint8_t kCoronaAcFanOffset = 0; // D0 LSB Pos 0-1
|
||||
const uint8_t kCoronaAcFanSize = 2;
|
||||
const uint8_t kCoronaAcFanAuto = 0b00; // 0
|
||||
const uint8_t kCoronaAcFanLow = 0b01; // 1
|
||||
const uint8_t kCoronaAcFanMedium = 0b10; // 2
|
||||
const uint8_t kCoronaAcFanHigh = 0b11; // 3
|
||||
|
||||
// One bit unknown // D0 Pos 2
|
||||
const uint8_t kCoronaAcPowerSaveOffset = 3; // D0 Pos 3
|
||||
// One bit unknown always on // D0 Pos 4
|
||||
// One bit unknown // D0 Pos 5
|
||||
const uint8_t kCoronaAcSwingVToggleOffset = 6; // D0 Pos 6
|
||||
// One bit unknown // D0 MSB Pos 7
|
||||
|
||||
// D1
|
||||
/* full auto mode not supported by this code yet
|
||||
const uint8_t kCoronaAcAutoD0 = 0b00010100; // only combined with power save
|
||||
const uint8_t kCoronaAcAutoD1 = 0b10000011; // only combined with power
|
||||
*/
|
||||
const uint8_t kCoronaAcTempOffset = 0; // D1 LSB Pos 0
|
||||
const uint8_t kCoronaAcTempSize = 4;
|
||||
const uint8_t kCoronaAcMinTemp = 17; // Celsius = 0b0001
|
||||
const uint8_t kCoronaAcMaxTemp = 30; // Celsius = 0b1110
|
||||
const uint8_t kCoronaAcPowerOffset =
|
||||
kCoronaAcTempOffset + kCoronaAcTempSize; // D1 Pos 4
|
||||
const uint8_t kCoronaAcPowerButtonOffset =
|
||||
kCoronaAcPowerOffset + 1; // D1 Pos 5
|
||||
const uint8_t kCoronaAcModeOffset =
|
||||
kCoronaAcPowerButtonOffset + 1; // D1 MSB Pos 6-7
|
||||
const uint8_t kCoronaAcModeSize = 2;
|
||||
const uint8_t kCoronaAcModeHeat = 0b00; // 0
|
||||
const uint8_t kCoronaAcModeDry = 0b01; // 1
|
||||
const uint8_t kCoronaAcModeCool = 0b10; // 2
|
||||
const uint8_t kCoronaAcModeFan = 0b11; // 3
|
||||
|
||||
const uint8_t kCoronaAcSettingsSection = 0;
|
||||
const uint8_t kCoronaAcOnTimerSection = 1;
|
||||
const uint8_t kCoronaAcOffTimerSection = 2;
|
||||
const uint16_t kCoronaAcTimerMax = 12 * 60; // 12H in Minutes
|
||||
@@ -108,33 +120,33 @@ class IRCoronaAc {
|
||||
static bool validSection(const uint8_t state[], const uint16_t pos,
|
||||
const uint8_t section);
|
||||
void setPower(const bool on);
|
||||
bool getPower();
|
||||
bool getPowerButton();
|
||||
void on();
|
||||
void off();
|
||||
bool getPower(void) const;
|
||||
bool getPowerButton(void) const;
|
||||
void on(void);
|
||||
void off(void);
|
||||
void setTemp(const uint8_t temp);
|
||||
uint8_t getTemp();
|
||||
uint8_t getTemp(void) const;
|
||||
void setSwingVToggle(const bool on);
|
||||
bool getSwingVToggle(void);
|
||||
bool getSwingVToggle(void) const;
|
||||
void setFan(const uint8_t speed);
|
||||
uint8_t getFan();
|
||||
uint8_t getFan(void) const;
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode();
|
||||
uint8_t getMode(void) const;
|
||||
void setEcono(const bool on);
|
||||
bool getEcono(void);
|
||||
bool getEcono(void) const;
|
||||
void setOnTimer(const uint16_t nr_of_mins);
|
||||
uint16_t getOnTimer(void);
|
||||
uint16_t getOnTimer(void) const;
|
||||
void setOffTimer(const uint16_t nr_of_mins);
|
||||
uint16_t getOffTimer(void);
|
||||
uint16_t getOffTimer(void) const;
|
||||
uint8_t* getRaw();
|
||||
void setRaw(const uint8_t new_code[],
|
||||
const uint16_t length = kCoronaAcStateLength);
|
||||
uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
static uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
stdAc::state_t toCommon();
|
||||
String toString();
|
||||
stdAc::state_t toCommon(void) const;
|
||||
String toString(void) const;
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
@@ -144,12 +156,11 @@ class IRCoronaAc {
|
||||
IRsendTest _irsend; ///< Instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif
|
||||
uint8_t remote_state[kCoronaAcStateLength]; ///< The state of the IR remote.
|
||||
CoronaProtocol _;
|
||||
static uint8_t getSectionByte(const uint8_t section);
|
||||
static void checksum(uint8_t* data);
|
||||
void setPowerButton(const bool on);
|
||||
void _setPower(const bool on);
|
||||
void _setTimer(const uint8_t section, const uint16_t nr_of_mins);
|
||||
uint16_t _getTimer(const uint8_t section);
|
||||
uint16_t _getTimer(const uint8_t section) const;
|
||||
};
|
||||
#endif // IR_CORONA_H_
|
||||
|
||||
@@ -1404,9 +1404,6 @@ TEST(TestCoronaAcClass, Power) {
|
||||
EXPECT_FALSE(ac.getPower());
|
||||
EXPECT_EQ(0, ac.getOffTimer());
|
||||
EXPECT_FALSE(ac.getPowerButton());
|
||||
|
||||
ASSERT_EQ(4, kCoronaAcPowerOffset);
|
||||
ASSERT_EQ(5, kCoronaAcPowerButtonOffset);
|
||||
}
|
||||
|
||||
TEST(TestCoronaAcClass, Temperature) {
|
||||
|
||||
Reference in New Issue
Block a user