Skip to content

Commit

Permalink
experimental(next): allow overrides in mitm mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tspopp committed Nov 26, 2024
1 parent 56f776c commit 74a773a
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 26 deletions.
43 changes: 29 additions & 14 deletions AquaMQTT/src/message/legacy/HMIMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ uint8_t HMIMessage::getAttr(HMI_ATTR_U8 attr)
switch (attr)
{
case HMI_ATTR_U8::ANTI_LEGIONELLA_CYCLES:
return (uint8_t) (mData[5] & 0x0F);
return mData[5] & 0x0F;
case HMI_ATTR_U8::TIME_SECONDS:
return mData[17];
case HMI_ATTR_U8::TIME_MINUTES:
Expand All @@ -133,7 +133,6 @@ uint8_t HMIMessage::getAttr(HMI_ATTR_U8 attr)
return mData[18] & 0x1F;
case HMI_ATTR_U8::DATE_MONTH:
return (mData[18] >> 5) + ((mData[19] % 2) * 8);

case HMI_ATTR_U8::STATE_SETUP:
if (mData[9] & 0x80)
{
Expand Down Expand Up @@ -189,13 +188,13 @@ uint8_t HMIMessage::getAttr(HMI_ATTR_U8 attr)
}
return HMIInstallation::INST_HP_ONLY;
case HMI_ATTR_U8::CONFIG_AIRDUCT:
switch ((uint8_t) (mData[5] & 0xF0))
switch (mData[5] & 0xF0)
{
case 0:
case 0x00:
return AD_INT_INT;
case 16:
case 0x10:
return AD_INT_EXT;
case 32:
case 0x20:
return AD_EXT_EXT;
default:
return AD_UNKNOWN;
Expand Down Expand Up @@ -415,11 +414,25 @@ void HMIMessage::setAttr(HMI_ATTR_U8 attr, uint8_t value)
break;
case HMI_ATTR_U8::OPERATION_MODE:
{
// FIXME: do not use the enum value here
auto operationMode = static_cast<HMIOperationMode>(value);
if (operationMode != HMIOperationMode::OM_UNKNOWN)
switch (static_cast<HMIOperationMode>(value))
{
mData[3] = (mData[3] & 0xF0) | (operationMode & 0x0F);
case OM_ABSENCE:
mData[3] = (mData[3] & 0xF0) | (0 & 0x0F);
break;
case OM_ECO_ACTIVE:
mData[3] = (mData[3] & 0xF0) | (1 & 0x0F);
break;
case OM_ECO_INACTIVE:
mData[3] = (mData[3] & 0xF0) | (2 & 0x0F);
break;
case OM_BOOST:
mData[3] = (mData[3] & 0xF0) | (3 & 0x0F);
break;
case OM_AUTO:
mData[3] = (mData[3] & 0xF0) | (4 & 0x0F);
break;
case OM_UNKNOWN:
break;
}
}
break;
Expand All @@ -437,12 +450,13 @@ void HMIMessage::setAttr(HMI_ATTR_U8 attr, uint8_t value)
}
break;
case HMI_ATTR_U8::DATE_MONTH:
// use custom method for setting month and year

case HMI_ATTR_U8::STATE_SETUP:
case HMI_ATTR_U8::STATE_TEST:
case HMI_ATTR_U8::HMI_ERROR_ID_REQUESTED:
case HMI_ATTR_U8::HMI_ERROR_NO_REQUESTED:
case HMI_ATTR_U8::ANTI_LEGIONELLA_CYCLES:
// TODO: implement this is needed
break;
}
}
Expand Down Expand Up @@ -475,6 +489,7 @@ void HMIMessage::setAttr(HMI_ATTR_BOOL attr, bool value)

break;
case HMI_ATTR_BOOL::PV_INPUT_ALLOWED:
// TODO: implement this is needed
break;
}
}
Expand All @@ -498,12 +513,12 @@ void HMIMessage::setAttr(HMI_ATTR_U16 attr, uint16_t value)
switch (attr)
{
case HMI_ATTR_U16::TIMER_A_START:
break;
case HMI_ATTR_U16::TIMER_A_LENGTH:
break;
case HMI_ATTR_U16::TIMER_B_START:
break;
case HMI_ATTR_U16::TIMER_B_LENGTH:
// TODO: implement this is needed
case HMI_ATTR_U16::DATE_YEAR:
// use custom method for setting month and year
break;
}
}
Expand Down
215 changes: 203 additions & 12 deletions AquaMQTT/src/message/next/HMIMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ uint8_t HMIMessage::getAttr(HMI_ATTR_U8 attr)
case HMI_ATTR_U8::CONFIG_AIRDUCT:
switch (mData[4] & 0xF0)
{
case 0:
case 0x00:
return AD_INT_INT;
case 1:
case 0x10:
return AD_INT_EXT;
case 2:
case 0x20:
return AD_EXT_EXT;
default:
return AD_UNKNOWN;
Expand Down Expand Up @@ -264,26 +264,212 @@ void HMIMessage::getAttr(HMI_ATTR_STR attr, char* buffer)

void HMIMessage::setAttr(HMI_ATTR_U8 attr, uint8_t value)
{
// TODO: not yet implemented
// void HMIMessage::setOperationMode(HMIOperationMode operationMode) const
//{
// // TODO: Sanity: If Mode OM_AUTO is set, water target temperature is set to 0x00
// }
switch (attr)
{
case HMI_ATTR_U8::TIME_SECONDS:
mData[16] = value;
break;
case HMI_ATTR_U8::TIME_MINUTES:
mData[19] = value;
break;
case HMI_ATTR_U8::TIME_HOURS:
mData[20] = value;
break;
case HMI_ATTR_U8::DATE_DAY:
mData[17] = (mData[17] & 0xE0) | (value & 0x1F);
break;
case HMI_ATTR_U8::STATE_INSTALLATION_MODE:
{
auto mode = static_cast<HMIInstallation>(value);
switch (mode)
{
case INST_HP_ONLY:
mData[6] &= ~0x01;
mData[6] &= ~0x02;
mData[6] &= ~0x10;
mData[6] &= ~0x20;
break;
case INST_HP_AND_EXT_PRIO_HP:
mData[6] |= 0x01;
mData[6] &= ~0x02;
mData[6] &= ~0x10;
mData[6] &= ~0x20;
break;
case INST_HP_AND_EXT_OPT_HP:
mData[6] |= 0x01;
mData[6] &= ~0x02;
mData[6] |= 0x10;
mData[6] &= ~0x20;
break;
case INST_HP_AND_EXT_OPT_EXT:
mData[6] |= 0x01;
mData[6] &= ~0x02;
mData[6] &= ~0x10;
mData[6] |= 0x20;
break;
case INST_HP_AND_EXT_PRIO_EXT:
mData[6] |= 0x01;
mData[6] &= ~0x02;
mData[6] |= 0x10;
mData[6] |= 0x20;
break;
case INST_HP_AND_SOLAR:
mData[6] |= 0x02;
mData[6] &= ~0x01;
mData[6] &= ~0x10;
mData[6] &= ~0x20;
break;
default:
break;
}
}
break;
case HMI_ATTR_U8::CONFIG_AIRDUCT:
{
auto config = static_cast<HMIAirDuctConfig>(value);
if (config == AD_UNKNOWN)
{
return;
}
// clear bit 5 and 6 (INT/INT)
mData[4] &= 0b11001111;
if (config == AD_INT_EXT)
{
mData[4] |= 0b00010000;
}
else if (config == AD_EXT_EXT)
{
mData[4] |= 0b00100000;
}
}
break;
case HMI_ATTR_U8::CONFIG_FAN_EXHAUST:
{
auto mode = static_cast<HMIFanExhaust>(value);
switch (mode)
{
case EXHAUST_STOP:
mData[7] &= 0b11111100;
mData[7] |= 0;
break;
case EXHAUST_LOW_SPEED:
mData[7] &= 0b11111100;
mData[7] |= 1;
break;
case EXHAUST_HIGH_SPEED:
mData[7] &= 0b11111100;
mData[7] |= 2;
break;
case EXHAUST_UNKNOWN:
break;
}
}
break;
case HMI_ATTR_U8::OPERATION_MODE:
switch (static_cast<HMIOperationMode>(value))
{
case OM_ABSENCE:
mData[2] = (mData[2] & 0xF0) | (5 & 0x0F);
break;
case OM_ECO_ACTIVE:
mData[2] = (mData[2] & 0xF0) | (1 & 0x0F);
break;
case OM_ECO_INACTIVE:
mData[2] = (mData[2] & 0xF0) | (2 & 0x0F);
break;
case OM_BOOST:
mData[2] = (mData[2] & 0xF0) | (9 & 0x0F);
break;
case OM_AUTO:
// TODO: Sanity: If Mode OM_AUTO is set, water target temperature is set to 0x00
mData[2] = (mData[2] & 0xF0) | (0 & 0x0F);
break;
case OM_UNKNOWN:
break;
}
break;
case HMI_ATTR_U8::OPERATION_TYPE:
{
auto operationType = static_cast<HMIOperationType>(value);
if (operationType == HMIOperationType::TIMER)
{
mData[3] = (mData[3] & ~(1 << 6)) | (true << 6);
}
else
{
mData[3] = (mData[3] & ~(1 << 6)) | (false << 6);
}
}
break;
case HMI_ATTR_U8::DATE_MONTH:
// use custom method for setting month and year
case HMI_ATTR_U8::HMI_ERROR_ID_REQUESTED:
case HMI_ATTR_U8::HMI_ERROR_NO_REQUESTED:
case HMI_ATTR_U8::STATE_SETUP:
case HMI_ATTR_U8::STATE_TEST:
case HMI_ATTR_U8::ANTI_LEGIONELLA_CYCLES:
// TODO: implement this is needed
break;
}
}

void HMIMessage::setAttr(HMI_ATTR_BOOL attr, bool value)
{
// TODO: not yet implemented
switch (attr)
{
case HMI_ATTR_BOOL::EMERGENCY_MODE_ENABLED:
// Sanity: You cannot activate emergency mode if heating element is disabled
if (value && getAttr(HMI_ATTR_BOOL::HEATING_ELEMENT_ALLOWED))
{
mData[5] |= 0x01;
}
else if (!value)
{
mData[5] &= ~0x01;
}
break;
case HMI_ATTR_BOOL::HEATING_ELEMENT_ALLOWED:
if (value)
{
mData[8] |= 0x04;
}
// Sanity: You cannot disable heating element if emergency mode is activated
else if (!getAttr(HMI_ATTR_BOOL::EMERGENCY_MODE_ENABLED))
{
mData[8] &= ~0x04;
}
break;
case HMI_ATTR_BOOL::PV_INPUT_ALLOWED:
// TODO: implement this is needed
break;
}
}

void HMIMessage::setAttr(HMI_ATTR_FLOAT attr, float value)
{
// TODO: not yet implemented
switch (attr)
{
case HMI_ATTR_FLOAT::WATER_TARGET_TEMPERATURE:
// this heatpump does not support decimals
mData[1] = static_cast<int>(value);
break;
}
}

void HMIMessage::setAttr(HMI_ATTR_U16 attr, uint16_t value)
{
// TODO: not yet implemented
switch (attr)
{

case HMI_ATTR_U16::TIMER_A_START:
case HMI_ATTR_U16::TIMER_A_LENGTH:
case HMI_ATTR_U16::TIMER_B_START:
case HMI_ATTR_U16::TIMER_B_LENGTH:
// TODO: implement this is needed
case HMI_ATTR_U16::DATE_YEAR:
// use custom method for setting month and year
break;
}
}

bool HMIMessage::hasAttr(HMI_ATTR_U8 attr) const
Expand Down Expand Up @@ -390,7 +576,12 @@ uint8_t HMIMessage::getLength()

void HMIMessage::setDateMonthAndYear(uint8_t month, uint16_t year) const
{
// TODO: implement me
int pastJuly = month > 7 ? 1 : 0;
mData[18] = ((year - 2000) * 2) + pastJuly;

int month_off_by_one = month - 1;
int monthValue = (pastJuly ? month_off_by_one - 8 : month_off_by_one) << 5;
mData[17] = (mData[17] & 0x1F) | (monthValue & 0xE0);
}

} // namespace aquamqtt::message::next
34 changes: 34 additions & 0 deletions AquaMQTT/src/message/next/MainStatusMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,40 @@ void MainStatusMessage::setAttr(MAIN_ATTR_FLOAT attr, float value)

void MainStatusMessage::setAttr(MAIN_ATTR_BOOL attr, bool value)
{
switch (attr)
{
case MAIN_ATTR_BOOL::STATE_PV:
if (value)
{
mData[22] |= 0x10;
}
else
{
mData[22] &= ~0x10;
}
break;
case MAIN_ATTR_BOOL::STATE_SOLAR:
if (value)
{
mData[22] |= 0x20;
}
else
{
mData[22] &= ~0x20;
}
break;
case MAIN_ATTR_BOOL::STATE_HEATING_ELEMENT:
case MAIN_ATTR_BOOL::STATE_HEATPUMP:
case MAIN_ATTR_BOOL::STATE_BOILER_BACKUP:
case MAIN_ATTR_BOOL::STATE_FAN:
case MAIN_ATTR_BOOL::STATE_DEFROST:
case MAIN_ATTR_BOOL::CAPABILITY_HAS_HEAT_EXCHANGER:
case MAIN_ATTR_BOOL::CAPABILITY_HAS_CIRCULATION:
case MAIN_ATTR_BOOL::CAPABILITY_HAS_PV_INPUT:
case MAIN_ATTR_BOOL::CAPABILITY_HAS_COMMUNICATION:
case MAIN_ATTR_BOOL::CAPABILITY_HAS_ANTI_DRY_HEATING:
break;
}
}

void MainStatusMessage::setAttr(MAIN_ATTR_U8 attr, uint8_t value)
Expand Down

0 comments on commit 74a773a

Please sign in to comment.