Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite ir_Amcor by using bit field #1263

Merged
merged 1 commit into from
Sep 5, 2020
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
93 changes: 41 additions & 52 deletions src/ir_Amcor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ using irutils::addBoolToString;
using irutils::addModeToString;
using irutils::addFanToString;
using irutils::addTempToString;
using irutils::setBits;

#if SEND_AMCOR
/// Send a Amcor HVAC formatted message.
Expand Down Expand Up @@ -126,31 +125,30 @@ bool IRAmcorAc::validChecksum(const uint8_t state[], const uint16_t length) {

/// Update the checksum value for the internal state.
void IRAmcorAc::checksum(void) {
remote_state[kAmcorChecksumByte] = IRAmcorAc::calcChecksum(remote_state,
kAmcorStateLength);
_.Sum = IRAmcorAc::calcChecksum(_.raw, kAmcorStateLength);
}

/// Reset the internals of the object to a known good state.
void IRAmcorAc::stateReset(void) {
for (uint8_t i = 1; i < kAmcorStateLength; i++) remote_state[i] = 0x0;
remote_state[0] = 0x01;
setFan(kAmcorFanAuto);
setMode(kAmcorAuto);
setTemp(25); // 25C
for (uint8_t i = 1; i < kAmcorStateLength; i++) _.raw[i] = 0x0;
_.raw[0] = 0x01;
_.Fan = kAmcorFanAuto;
_.Mode = kAmcorAuto;
_.Temp = 25; // 25C
}

/// Get the raw state of the object, suitable to be sent with the appropriate
/// IRsend object method.
/// @return A PTR to the internal state.
uint8_t* IRAmcorAc::getRaw(void) {
this->checksum(); // Ensure correct bit array before returning
return remote_state;
checksum(); // Ensure correct bit array before returning
return _.raw;
}

/// Set the raw state of the object.
/// @param[in] state The raw state from the native IR message.
void IRAmcorAc::setRaw(const uint8_t state[]) {
memcpy(remote_state, state, kAmcorStateLength);
std::memcpy(_.raw, state, kAmcorStateLength);
}

/// Set the internal state to have the power on.
Expand All @@ -162,54 +160,48 @@ void IRAmcorAc::off(void) { setPower(false); }
/// Set the internal state to have the desired power.
/// @param[in] on The desired power state.
void IRAmcorAc::setPower(const bool on) {
setBits(&remote_state[kAmcorPowerByte], kAmcorPowerOffset, kAmcorPowerSize,
on ? kAmcorPowerOn : kAmcorPowerOff);
_.Power = (on ? kAmcorPowerOn : kAmcorPowerOff);
}

/// Get the power setting from the internal state.
/// @return A boolean indicating the power setting.
bool IRAmcorAc::getPower(void) {
return GETBITS8(remote_state[kAmcorPowerByte], kAmcorPowerOffset,
kAmcorPowerSize) == kAmcorPowerOn;
bool IRAmcorAc::getPower(void) const {
return _.Power == kAmcorPowerOn;
}

/// Set the temperature.
/// @param[in] degrees The temperature in degrees celsius.
void IRAmcorAc::setTemp(const uint8_t degrees) {
uint8_t temp = std::max(kAmcorMinTemp, degrees);
temp = std::min(kAmcorMaxTemp, temp);
setBits(&remote_state[kAmcorTempByte], kAmcorTempOffset, kAmcorTempSize,
temp);
_.Temp = temp;
}

/// Get the current temperature setting.
/// @return Get current setting for temp. in degrees celsius.
uint8_t IRAmcorAc::getTemp(void) {
return GETBITS8(remote_state[kAmcorTempByte], kAmcorTempOffset,
kAmcorTempSize);
uint8_t IRAmcorAc::getTemp(void) const {
return _.Temp;
}

/// Control the current Maximum Cooling or Heating setting. (i.e. Turbo)
/// @note Only allowed in Cool or Heat mode.
/// @param[in] on The desired setting.
void IRAmcorAc::setMax(const bool on) {
if (on) {
switch (getMode()) {
case kAmcorCool: setTemp(kAmcorMinTemp); break;
case kAmcorHeat: setTemp(kAmcorMaxTemp); break;
switch (_.Mode) {
case kAmcorCool: _.Temp = kAmcorMinTemp; break;
case kAmcorHeat: _.Temp = kAmcorMaxTemp; break;
// Not allowed in all other operating modes.
default: return;
}
}
setBits(&remote_state[kAmcorSpecialByte], kAmcorMaxOffset, kAmcorMaxSize,
on ? kAmcorMax : 0);
_.Max = (on ? kAmcorMax : 0);
}

/// Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on?
/// @return The current value.
bool IRAmcorAc::getMax(void) {
return GETBITS8(remote_state[kAmcorSpecialByte], kAmcorMaxOffset,
kAmcorMaxSize) == kAmcorMax;
bool IRAmcorAc::getMax(void) const {
return _.Max == kAmcorMax;
}

/// Set the speed of the fan.
Expand All @@ -220,26 +212,23 @@ void IRAmcorAc::setFan(const uint8_t speed) {
case kAmcorFanMin:
case kAmcorFanMed:
case kAmcorFanMax:
setBits(&remote_state[kAmcorModeFanByte], kAmcorFanOffset, kAmcorFanSize,
speed);
_.Fan = speed;
break;
default:
setFan(kAmcorFanAuto);
_.Fan = kAmcorFanAuto;
}
}

/// Get the current fan speed setting.
/// @return The current fan speed.
uint8_t IRAmcorAc::getFan(void) {
return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorFanOffset,
kAmcorFanSize);
uint8_t IRAmcorAc::getFan(void) const {
return _.Fan;
}

/// Get the current operation mode setting.
/// @return The current operation mode.
uint8_t IRAmcorAc::getMode(void) {
return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorModeOffset,
kAmcorModeSize);
uint8_t IRAmcorAc::getMode(void) const {
return _.Mode;
}

/// Set the desired operation mode.
Expand All @@ -251,13 +240,13 @@ void IRAmcorAc::setMode(const uint8_t mode) {
case kAmcorHeat:
case kAmcorDry:
case kAmcorAuto:
setBits(&remote_state[kAmcorSpecialByte], kAmcorVentOffset,
kAmcorVentSize, (mode == kAmcorFan) ? kAmcorVentOn : 0);
setBits(&remote_state[kAmcorModeFanByte], kAmcorModeOffset,
kAmcorModeSize, mode);
_.Vent = (mode == kAmcorFan) ? kAmcorVentOn : 0;
_.Mode = mode;
return;
default:
this->setMode(kAmcorAuto);
_.Vent = 0;
_.Mode = kAmcorAuto;
break;
}
}

Expand Down Expand Up @@ -324,14 +313,14 @@ stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) {

/// Convert the current internal state into its stdAc::state_t equivilant.
/// @return The stdAc equivilant of the native settings.
stdAc::state_t IRAmcorAc::toCommon(void) {
stdAc::state_t IRAmcorAc::toCommon(void) const {
stdAc::state_t result;
result.protocol = decode_type_t::AMCOR;
result.power = this->getPower();
result.mode = this->toCommonMode(this->getMode());
result.power = getPower();
result.mode = toCommonMode(_.Mode);
result.celsius = true;
result.degrees = this->getTemp();
result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.degrees = _.Temp;
result.fanspeed = toCommonFanSpeed(_.Fan);
// Not supported.
result.model = -1;
result.turbo = false;
Expand All @@ -350,16 +339,16 @@ stdAc::state_t IRAmcorAc::toCommon(void) {

/// Convert the current internal state into a human readable string.
/// @return A human readable string.
String IRAmcorAc::toString(void) {
String IRAmcorAc::toString(void) const {
String result = "";
result.reserve(70); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
result += addModeToString(getMode(), kAmcorAuto, kAmcorCool,
result += addModeToString(_.Mode, kAmcorAuto, kAmcorCool,
kAmcorHeat, kAmcorDry, kAmcorFan);
result += addFanToString(getFan(), kAmcorFanMax, kAmcorFanMin,
result += addFanToString(_.Fan, kAmcorFanMax, kAmcorFanMin,
kAmcorFanAuto, kAmcorFanAuto,
kAmcorFanMed);
result += addTempToString(getTemp());
result += addTempToString(_.Temp);
result += addBoolToString(getMax(), kMaxStr);
return result;
}
92 changes: 50 additions & 42 deletions src/ir_Amcor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,56 +24,64 @@
#endif


union AmcorProtocol{
uint8_t raw[kAmcorStateLength]; // The state of the IR remote.
struct {
// Byte 0
uint8_t :8; // Typically 0x01
// Byte 1
uint8_t Mode :3;
uint8_t :1;
uint8_t Fan :3;
uint8_t :1;
// Byte 2
uint8_t :1;
uint8_t Temp :6;
uint8_t :1;
// Byte 3
uint8_t :8;
// Byte 4
uint8_t :8;
// Byte 5
uint8_t :4;
uint8_t Power :4;
// Byte 6
uint8_t Max :2;
uint8_t :4;
uint8_t Vent :2;
// Byte 7
uint8_t Sum :8;
};
};

// Constants

// state[1]
const uint8_t kAmcorModeFanByte = 1;
// Fan Control
const uint8_t kAmcorFanMin = 0b001;
const uint8_t kAmcorFanMed = 0b010;
const uint8_t kAmcorFanMax = 0b011;
const uint8_t kAmcorFanAuto = 0b100;
const uint8_t kAmcorFanOffset = 4;
const uint8_t kAmcorFanSize = 3;
// Modes
const uint8_t kAmcorCool = 0b001;
const uint8_t kAmcorHeat = 0b010;
const uint8_t kAmcorFan = 0b011; // Aka "Vent"
const uint8_t kAmcorDry = 0b100;
const uint8_t kAmcorAuto = 0b101;
const uint8_t kAmcorModeOffset = 0;
const uint8_t kAmcorModeSize = 3;

// state[2]
const uint8_t kAmcorTempByte = 2;
const uint8_t kAmcorCool = 0b001;
const uint8_t kAmcorHeat = 0b010;
const uint8_t kAmcorFan = 0b011; // Aka "Vent"
const uint8_t kAmcorDry = 0b100;
const uint8_t kAmcorAuto = 0b101;

// Temperature
const uint8_t kAmcorMinTemp = 12; // Celsius
const uint8_t kAmcorMaxTemp = 32; // Celsius
const uint8_t kAmcorTempOffset = 1;
const uint8_t kAmcorTempSize = 6; // Bits

// state[5]
// Power
const uint8_t kAmcorPowerByte = 5;
const uint8_t kAmcorPowerOffset = 4;
const uint8_t kAmcorPowerSize = 4;
const uint8_t kAmcorPowerOn = 0b0011; // 0x3
const uint8_t kAmcorPowerOff = 0b1100; // 0xC

// state[6]
const uint8_t kAmcorSpecialByte = 6;
// Max Mode (aka "Lo" in Cool and "Hi" in Heat)
const uint8_t kAmcorMax = 0b11;
const uint8_t kAmcorMaxOffset = 0;
const uint8_t kAmcorMaxSize = 2;

// "Vent" Mode
const uint8_t kAmcorVentOn = 0b11;
const uint8_t kAmcorVentOffset = 6;
const uint8_t kAmcorVentSize = 2;
// state[7]
// Checksum byte.
const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1;


// Classes

Expand All @@ -98,25 +106,25 @@ class IRAmcorAc {
static bool validChecksum(const uint8_t state[],
const uint16_t length = kAmcorStateLength);
void setPower(const bool state);
bool getPower();
void on();
void off();
bool getPower(void) const;
void on(void);
void off(void);
void setTemp(const uint8_t temp);
uint8_t getTemp();
uint8_t getTemp(void) const;
void setMax(const bool on);
bool getMax(void);
bool getMax(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* getRaw();
uint8_t getMode(void) const;
uint8_t* getRaw(void);
void setRaw(const uint8_t state[]);
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(void);
String toString();
stdAc::state_t toCommon(void) const;
String toString(void) const;
#ifndef UNIT_TEST

private:
Expand All @@ -126,7 +134,7 @@ class IRAmcorAc {
IRsendTest _irsend;
/// @endcond
#endif
uint8_t remote_state[kAmcorStateLength]; // The state of the IR remote.
AmcorProtocol _;
void checksum(void);
};
#endif // IR_AMCOR_H_