Skip to content

Commit

Permalink
feat(pv-overrides): use excess energy to reach maximum temperature (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
tspopp authored Feb 27, 2024
1 parent b21f532 commit 8790dd9
Show file tree
Hide file tree
Showing 13 changed files with 800 additions and 111 deletions.
4 changes: 2 additions & 2 deletions AquaMQTT/include/config/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ constexpr bool OVERRIDE_TIME_AND_DATE_IN_MITM = true;
*/
constexpr uint8_t WATCHDOG_TIMEOUT_S = 60;
constexpr uint16_t MQTT_STATS_UPDATE_MS = 5000;
constexpr uint8_t MQTT_MAX_TOPIC_SIZE = 50;
constexpr uint8_t MQTT_MAX_PAYLOAD_SIZE = 50;
constexpr uint8_t MQTT_MAX_TOPIC_SIZE = 80;
constexpr uint8_t MQTT_MAX_PAYLOAD_SIZE = 255;

/**
* Pin assignments for AquaMQTT Board Rev 1.0
Expand Down
24 changes: 24 additions & 0 deletions AquaMQTT/include/config/ExampleConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ constexpr char brokerPassword[] = "";
constexpr char mqttPrefix[] = "";

} // namespace config

namespace mqtt
{
// Optional and additional MQTT topics which are configured by the user.

// Possibility to publish the current heat pump power to an additional mqtt topic of your choice.
// Leave blank if not needed / unused
constexpr char optionalPublishTopicHeatPumpCurrentPower[] = { /*"openWB/LegacySmartHome/set/Devices/1/Aktpower"*/ };

// Possibility to publish the current heat element power to an additional mqtt topic of your choice.
// Leave blank if not needed / unused
constexpr char optionalPublishTopicHeatElementCurrentPower[] = { /*"openWB/LegacySmartHome/set/Devices/2/Aktpower"*/ };

// Possibility to subscribe an additional mqtt topic for triggering the heat pump flag.
// A boolean representation e.g "0" for unset and "1" for set is expected here.
// Leave blank if not needed / unused
constexpr char optionalSubscribeTopicSetPvHeatPumpFlag[] = { /*"openWB/LegacySmartHome/set/Devices/1/ReqRelay"*/ };

// Possibility to subscribe an additional mqtt topic for triggering the heat element flag.
// A boolean representation e.g "0" for unset and "1" for set is expected here.
// Leave blank if not needed / unused
constexpr char optionalSubscribeTopicSetPvHeatElementFlag[] = { /*"openWB/LegacySmartHome/set/Devices/2/ReqRelay"*/ };

} // namespace mqtt
} // namespace aquamqtt

#endif // AQUAMQTT_EXAMPLECONFIGURATION_H
6 changes: 4 additions & 2 deletions AquaMQTT/include/message/HMIMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class HMIMessage

void setOperationMode(HMIOperationMode operationMode);

bool isTimerModeEnabled();
HMIOperationType getOperationType();

void setTimerModeEnabled(bool enabled);
void setOperationType(HMIOperationType operationType);

bool isEmergencyModeEnabled();

Expand Down Expand Up @@ -82,6 +82,8 @@ class HMIMessage

void setDateDay(uint8_t day);

void setInstallationMode(HMIInstallation mode);

private:
uint8_t* mData;
};
Expand Down
34 changes: 26 additions & 8 deletions AquaMQTT/include/message/MessageConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,31 @@ static const char* operationModeStr(HMIOperationMode mode)
}
}

enum HMIOperationType : bool
{
ALWAYS_ON = false,
TIMER = true
};

static const char* operationTypeStr(HMIOperationType type)
{
switch (type)
{
case ALWAYS_ON:
return reinterpret_cast<const char*>(mqtt::ENUM_OPERATION_TYPE_ALWAYS_ON);
case TIMER:
return reinterpret_cast<const char*>(mqtt::ENUM_OPERATION_TYPE_TIMER);
default:
return reinterpret_cast<const char*>(mqtt::ENUM_UNKNOWN);
}
}

enum HMIAirDuctConfig : int
{
AD_UNKNOWN = -1,
AD_INT_INT = 0, // Umluft
AD_INT_EXT = 16, // 1 Kanal Luftanschluss
AD_EXT_EXT = 32 // 2 Kanal Luftamschluss
AD_EXT_EXT = 32 // 2 Kanal Luftanschluss
};

static const char* airDuctConfigStr(HMIAirDuctConfig config)
Expand Down Expand Up @@ -106,16 +125,15 @@ static const char* testModeStr(HMITestMode config)
}
}


enum HMIInstallation
{
INST_HP_UNKNOWN = -1,
INST_HP_ONLY = 0, // 0000 0000
INST_HP_AND_EXT_PRIO_HP = 1, // 0000 0001
INST_HP_AND_EXT_OPT_HP = 17, // 0001 0001
INST_HP_AND_EXT_OPT_EXT = 33, // 0010 0001
INST_HP_AND_EXT_PRIO_EXT = 49, // 0011 0001
INST_HP_AND_SOLAR = 2, // 0000 0010
INST_HP_ONLY = 0, // 0000 0000
INST_HP_AND_EXT_PRIO_HP = 1, // 0000 0001
INST_HP_AND_EXT_OPT_HP = 17, // 0001 0001
INST_HP_AND_EXT_OPT_EXT = 33, // 0010 0001
INST_HP_AND_EXT_PRIO_EXT = 49, // 0011 0001
INST_HP_AND_SOLAR = 2, // 0000 0010
};

static const char* installationModeStr(HMIInstallation installation)
Expand Down
18 changes: 18 additions & 0 deletions AquaMQTT/include/mqtt/IMQTTCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ class IMQTTCallback
// $prefix/aquamqtt/ctrl/waterTempTarget + float
virtual void onWaterTempTargetChanged(std::unique_ptr<float> value) = 0;

// $prefix/aquamqtt/ctrl/heatingElementEnabled + bool
virtual void onHeatingElementEnabledChanged(std::unique_ptr<bool> enabled) = 0;

// $prefix/aquamqtt/ctrl/emergencyModeEnabled + bool
virtual void onEmergencyModeEnabledChanged(std::unique_ptr<bool> enabled) = 0;

// $prefix/aquamqtt/ctrl/operationType + ENUM OPERATION TYPE
virtual void onOperationTypeChanged(std::unique_ptr<message::HMIOperationType> type) = 0;

// $prefix/aquamqtt/ctrl/configInstallation + ENUM INSTALLATION
virtual void onInstallationModeChanged(std::unique_ptr<message::HMIInstallation> mode) = 0;

// $prefic/aquamqtt/ctrl/flagPVModeHeatPump + bool
virtual void onPVModeHeatpumpEnabled(bool enabled) = 0;

// $prefic/aquamqtt/ctrl/flagPVModeHeatElement + bool
virtual void onPVModeHeatElementEnabled(bool enabled) = 0;

// $prefix/aquamqtt/ctrl/reset
virtual void onResetOverrides() = 0;
};
Expand Down
30 changes: 19 additions & 11 deletions AquaMQTT/include/mqtt/MQTTDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ const char ENUM_SETUP_COMPLETED[] PROGMEM = { "OK" };
const char ENUM_SETUP_INCOMPLETE[] PROGMEM = { "PARTIAL RESET" };
const char ENUM_SETUP_RESET[] PROGMEM = { "FACTORY RESET" };

const char ENUM_AQUAMQTT_OVERRIDE_MODE_DEFAULT[] PROGMEM = { "DEFAULT" };
const char ENUM_AQUAMQTT_OVERRIDE_MODE_HP_ONLY[] PROGMEM = { "PV HP" };
const char ENUM_AQUAMQTT_OVERRIDE_MODE_HE_ONLY[] PROGMEM = { "PV HE" };
const char ENUM_AQUAMQTT_OVERRIDE_MODE_PV_FULL[] PROGMEM = { "PV BOOST" };

// Subtopics
const char MAIN_HOT_WATER_TEMP[] PROGMEM = { "waterTemp" };
const char MAIN_SUPPLY_AIR_TEMP[] PROGMEM = { "supplyAirTemp" };
Expand All @@ -76,7 +81,7 @@ const char HMI_OPERATION_TYPE[] PROGMEM = { "operationType" };
const char HMI_TIME[] PROGMEM = { "time" };
const char HMI_DATE[] PROGMEM = { "date" };
const char HMI_TIME_AND_DATE[] PROGMEM = { "time/date" };
const char HMI_EMERGENCY_MODE[] PROGMEM = { "emergencyMode" };
const char HMI_EMERGENCY_MODE[] PROGMEM = { "emergencyModeEnabled" };
const char HMI_HEATING_ELEMENT_ENABLED[] PROGMEM = { "heatingElementEnabled" };
const char HMI_LEGIONELLA[] PROGMEM = { "antiLegionellaPerMonth" };
const char HMI_TIMER_WINDOW_A[] PROGMEM = { "timerWindowA" };
Expand All @@ -94,16 +99,19 @@ const char ENERGY_POWER_TOTAL[] PROGMEM = { "powerTotal" };
const char ENERGY_POWER_HEAT_ELEMENT[] PROGMEM = { "powerHeatingElem" };
const char ENERGY_POWER_HEATPUMP[] PROGMEM = { "powerHeatpump" };

const char STATS_AQUAMQTT_ADDR[] PROGMEM = { "ipAddress" };
const char STATS_AQUAMQTT_RSSI[] PROGMEM = { "rssiDb" };
const char STATS_AQUAMQTT_MODE[] PROGMEM = { "aquamqttMode" };
const char STATS_AQUAMQTT_LAST_WILL[] PROGMEM = { "lwlState" };
const char STATS_MSG_HANDLED[] PROGMEM = { "msgHandled" };
const char STATS_MSG_UNHANDLED[] PROGMEM = { "msgUnhandled" };
const char STATS_MSG_SENT[] PROGMEM = { "msgSent" };
const char STATS_MSG_CRC_NOK[] PROGMEM = { "msgCRCNOK" };
const char STATS_DROPPED_BYTES[] PROGMEM = { "droppedBytes" };
const char STATS_ACTIVE_OVERRIDES[] PROGMEM = { "activeOverrides" };
const char STATS_AQUAMQTT_ADDR[] PROGMEM = { "ipAddress" };
const char STATS_AQUAMQTT_RSSI[] PROGMEM = { "rssiDb" };
const char STATS_AQUAMQTT_MODE[] PROGMEM = { "aquamqttMode" };
const char STATS_AQUAMQTT_OVERRIDE_MODE[] PROGMEM = { "overrideMode" };
const char STATS_AQUAMQTT_LAST_WILL[] PROGMEM = { "lwlState" };
const char STATS_MSG_HANDLED[] PROGMEM = { "msgHandled" };
const char STATS_MSG_UNHANDLED[] PROGMEM = { "msgUnhandled" };
const char STATS_MSG_SENT[] PROGMEM = { "msgSent" };
const char STATS_MSG_CRC_NOK[] PROGMEM = { "msgCRCNOK" };
const char STATS_DROPPED_BYTES[] PROGMEM = { "droppedBytes" };
const char STATS_ACTIVE_OVERRIDES[] PROGMEM = { "activeOverrides" };
const char STATS_ENABLE_FLAG_PV_HEATPUMP[] PROGMEM = { "flagPVModeHeatPump" };
const char STATS_ENABLE_FLAG_PV_HEATELEMENT[] PROGMEM = { "flagPVModeHeatElement" };

// CTRL
const char AQUAMQTT_RESET_OVERRIDES[] PROGMEM = { "reset" };
Expand Down
55 changes: 55 additions & 0 deletions AquaMQTT/include/state/HMIStateProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,38 @@ namespace aquamqtt
struct AquaMqttOverrides
{
bool operationMode;
bool operationType;
bool waterTempTarget;
bool heatingElementEnabled;
bool emergencyModeEnabled;
bool installationMode;
};

enum AquaMqttOverrideMode
{
AM_MODE_STANDARD = 0,
AM_MODE_PV_HP_ONLY = 1,
AM_MODE_PV_HE_ONLY = 2,
AM_MODE_PV_FULL = 3
};

static const char* aquamqttOverrideStr(AquaMqttOverrideMode mode)
{
switch (mode)
{
case AM_MODE_STANDARD:
return reinterpret_cast<const char*>(mqtt::ENUM_AQUAMQTT_OVERRIDE_MODE_DEFAULT);
case AM_MODE_PV_HP_ONLY:
return reinterpret_cast<const char*>(mqtt::ENUM_AQUAMQTT_OVERRIDE_MODE_HP_ONLY);
case AM_MODE_PV_HE_ONLY:
return reinterpret_cast<const char*>(mqtt::ENUM_AQUAMQTT_OVERRIDE_MODE_HE_ONLY);
case AM_MODE_PV_FULL:
return reinterpret_cast<const char*>(mqtt::ENUM_AQUAMQTT_OVERRIDE_MODE_PV_FULL);
default:
return reinterpret_cast<const char*>(mqtt::ENUM_UNKNOWN);
}
}

/**
* HMIStateProxy accesses current HMI message from the DHW state
* and applies overrides depending on the AquaMQTT Operation Mode
Expand Down Expand Up @@ -43,15 +72,35 @@ class HMIStateProxy : public mqtt::IMQTTCallback

void onOperationModeChanged(std::unique_ptr<message::HMIOperationMode> value) override;

void onOperationTypeChanged(std::unique_ptr<message::HMIOperationType> type) override;

void onInstallationModeChanged(std::unique_ptr<message::HMIInstallation> mode) override;

void onWaterTempTargetChanged(std::unique_ptr<float> value) override;

void onHeatingElementEnabledChanged(std::unique_ptr<bool> enabled) override;

void onEmergencyModeEnabledChanged(std::unique_ptr<bool> enabled) override;

void onPVModeHeatpumpEnabled(bool enabled) override;

bool isPVModeHeatPumpEnabled();

void onPVModeHeatElementEnabled(bool enabled) override;

bool isPVModeHeatElementEnabled();

void onResetOverrides() override;

AquaMqttOverrides getOverrides();

AquaMqttOverrideMode getOverrideMode();

void updateTime(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t days, uint8_t month, uint16_t year);

private:
AquaMqttOverrideMode currentOverrideMode() const;

TaskHandle_t mNotify;
SemaphoreHandle_t mMutex;
bool mTimeIsSet;
Expand All @@ -64,7 +113,13 @@ class HMIStateProxy : public mqtt::IMQTTCallback

// since we do not have optionals, use nullptr if override is not set
std::unique_ptr<float> mTargetTemperature;
std::unique_ptr<message::HMIOperationType> mOperationType;
std::unique_ptr<message::HMIOperationMode> mOperationMode;
std::unique_ptr<message::HMIInstallation> mInstallationMode;
std::unique_ptr<bool> mEmergencyModeEnabled;
std::unique_ptr<bool> mHeatingElementEnabled;
bool mPVModeHeatPump;
bool mPVModeHeatElement;
};

} // namespace aquamqtt
Expand Down
Loading

0 comments on commit 8790dd9

Please sign in to comment.