diff --git a/AquaMqttLogger/README.md b/AquaMqttLogger/README.md new file mode 100644 index 0000000..bc1922b --- /dev/null +++ b/AquaMqttLogger/README.md @@ -0,0 +1,15 @@ +# AquaMQTTLogger + +*Prototype* + +Intercepts the one-wire bus, parsing messages exchanged by the HMI Controller and the main board. + +Any messages known in the [Protocol description](../Protocol.md) are extracted and published to +several [MQTT topics](../MQTT.md). + +The project runs on an Arduino Mega 2560 together with an ESP8266 piggyback (running esp-link) for WiFi/MQTT functionalities. + +For proofing controllability of the heatpump, AquaMQTTLogger *may* act as simplified HMI controller via MQTT. +*The original HMI controller must be disconnected in this case.* + +**Successfully tested against the original main controller** \ No newline at end of file diff --git a/AquaMqttLogger/include/ESPLink.h b/AquaMqttLogger/include/ESPLink.h index 45ba04b..1818854 100644 --- a/AquaMqttLogger/include/ESPLink.h +++ b/AquaMqttLogger/include/ESPLink.h @@ -47,7 +47,6 @@ class ESPLink static void mqttDisconnected(void* response); static void mqttData(void* response); - Stream* mSerial; ELClient* mElClient; ELClientCmd* mELClientCmd; ELClientMqtt* mELClientMqtt; diff --git a/AquaMqttLogger/src/ESPLink.cpp b/AquaMqttLogger/src/ESPLink.cpp index cff5528..ddcfacd 100644 --- a/AquaMqttLogger/src/ESPLink.cpp +++ b/AquaMqttLogger/src/ESPLink.cpp @@ -6,13 +6,7 @@ ESPLink::ESPLink() : mElClient(nullptr), mELClientCmd(nullptr), mELClientMqtt(nullptr), mCallback(nullptr) { -} - -void ESPLink::init(Stream* serial) -{ - - mSerial = serial; - mElClient = new ELClient(serial); + mElClient = new ELClient(&Serial); mELClientCmd = new ELClientCmd(mElClient); mELClientMqtt = new ELClientMqtt(mElClient); } @@ -26,11 +20,11 @@ bool ESPLink::setup() retry++; if (retry >= 5) { - mSerial->println(F("esp:nosync")); + Serial.println(F("esp:nosync")); return false; } } - mSerial->println(F("esp:sync")); + Serial.println(F("esp:sync")); mELClientMqtt->connectedCb.attach(mqttConnected); mELClientMqtt->disconnectedCb.attach(mqttDisconnected); diff --git a/AquaMqttLogger/src/main.cpp b/AquaMqttLogger/src/main.cpp index 3616704..8839167 100644 --- a/AquaMqttLogger/src/main.cpp +++ b/AquaMqttLogger/src/main.cpp @@ -1,18 +1,22 @@ #include -#include #include +#include #include "ESPLink.h" #include "FrameBuffer.h" #include "FrameHandler.h" #include "HMIState.h" -ESPLink& espLink = ESPLink::getInstance(); -FrameHandler handler(&espLink); -FrameBuffer buffer(&handler); -HMIState hmiState; +ESPLink& espLink = ESPLink::getInstance(); +FrameHandler handler(&espLink); +FrameBuffer buffer(&handler); +HMIState hmiState; +FastCRC16 mCRC; -FastCRC16 mCRC; +/** + * In case no HMI is connected, this application will act as headless HMI which is controlled using MQTT + */ +const bool hmiConnected = false; void setup() { @@ -21,10 +25,8 @@ void setup() wdt_enable(WDTO_2S); Serial.begin(115200); - espLink.init(&Serial); Serial.println(F("REBOOT")); - // heatpump serial is only started, if esp8266 is in sync if (espLink.setup()) { @@ -34,7 +36,6 @@ void setup() espLink.setMqttCallback(&hmiState); - Serial.println("SETUP OK"); } @@ -47,29 +48,27 @@ void loop() while (Serial1.available()) { int val = Serial1.read(); + buffer.pushByte(val); - // TODO, this will cause any magic byte 194 to emit a message, this is truly bad. - // we need something better.... for our poc this will be sufficient. - if (val != 194) + if (hmiConnected) { - buffer.pushByte(val); - } - else if (hmiState.updateMessage()) - { - uint16_t actualCRC = mCRC.ccitt(hmiState.getMessage(), 35); - Serial1.write(hmiState.getMessage(), 35); - Serial1.write((uint8_t) (actualCRC >> 8)); // extract the high byte - Serial1.write((uint8_t) (actualCRC & 0xFF)); // extract the low byte - - // eat our own dogfood, we are not reading when writing to the one-wire bus .... - buffer.pushByte(val); - - for (int i = 0; i < 35; ++i) + // TODO: this will cause any magic byte 194 to emit a message + // TODO: assert sequence before emitting an hmi message + if (val == 194 && hmiState.updateMessage()) { - buffer.pushByte(hmiState.getMessage()[i]); + uint16_t actualCRC = mCRC.ccitt(hmiState.getMessage(), 35); + Serial1.write(hmiState.getMessage(), 35); + Serial1.write((uint8_t) (actualCRC >> 8)); // extract the high byte + Serial1.write((uint8_t) (actualCRC & 0xFF)); // extract the low byte + + // provide the messages we wer writing to our own buffer as well (updating any mqtt topics) + for (int i = 0; i < 35; ++i) + { + buffer.pushByte(hmiState.getMessage()[i]); + } + buffer.pushByte((uint8_t) (actualCRC >> 8)); + buffer.pushByte((uint8_t) (actualCRC & 0xFF)); } - buffer.pushByte((uint8_t) (actualCRC >> 8)); - buffer.pushByte((uint8_t) (actualCRC & 0xFF)); } } } \ No newline at end of file diff --git a/AquaSimuUno/README.md b/AquaSimuUno/README.md index 3c3ba44..b8300af 100644 --- a/AquaSimuUno/README.md +++ b/AquaSimuUno/README.md @@ -1,5 +1,7 @@ # AquaSimuUno +*Prototype* + Is a very lightweight heatpump bus simulation which is repeating the pattern 194 - 193 - 67 pattern. The 194 message acts as a request to the hmi controller, which is completing the packet on the bus. diff --git a/README.md b/README.md index de5b050..c702987 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,23 @@ [![PlatformIO CI](https://github.com/tspopp/AquaMQTT/actions/workflows/main.yml/badge.svg)](https://github.com/tspopp/AquaMQTT/actions/workflows/main.yml) -Monitor your DHW heat pump locally using MQTT: +Monitor and control your DHW heat pump locally using MQTT: - Access sensor data and operational states from your heat pump. +- Control the heat pump: Set operational states e.g. water temperature and operation modes (e.g. BOOST). +- Automate the behaviour of your heat pump according to your local energy production or energy availability. - Easily integrate AquaMQTT with smart home systems like [Home Assistant](https://www.home-assistant.io/). ## Compatible Devices -This project is built and tested against the [Windhager AquaWin Air3](https://www.windhager.com/en/products/hot-water-tanks/aquawin-air3/) DHW heat pump. +This project is built and tested against +the [Windhager AquaWin Air3](https://www.windhager.com/en/products/hot-water-tanks/aquawin-air3/) DHW heat pump. -It seems the heatpump is built by the [Groupe Atlantic](https://www.groupe-atlantic.fr/) and branded for various companies. It is very likely but yet unconfirmed that this project is compatible to similar products with other branding such as: +It seems the heatpump is built by the [Groupe Atlantic](https://www.groupe-atlantic.fr/) and branded for various +companies. It is very likely but yet unconfirmed that this project is compatible to similar products with other branding +such as: - [Atlantic Explorer](https://www.atlantic-comfort.com/Water-Heaters/Heat-pump-water-heaters/Explorer) - [Austria Email Explorer](https://www.austria-email.de/produkte/waermepumpensysteme/waermepumpen-trinkwasser/explorer-evo-2/) @@ -22,7 +27,14 @@ It seems the heatpump is built by the [Groupe Atlantic](https://www.groupe-atlan ## How does it work? -This project intercepts the communication between the HMI controller and the main controller of the heatpump. Any identified values contained within the serial messages are extracted, parsed and published via [MQTT](./MQTT.md). The identified portions of the heatpump serial protocol is described in [PROTOCOL.md](./PROTOCOL.md). To intercept the communication, an arduino based microcontroller is added between the communication lines of the HMI controller and the main controller. +This project intercepts the communication between the HMI controller and the main controller of the heatpump. Any +identified values contained within the serial messages are extracted, parsed and published via [MQTT](./MQTT.md). The +identified portions of the heatpump serial protocol is described in [PROTOCOL.md](./PROTOCOL.md). To intercept the +communication, an arduino based microcontroller is added between the communication lines of the HMI controller and the +main controller. + +If AquaMQTT is used for controlling the heat pump, it will act as HMI controller and communicates directly with the main +controller of the heatpump, without the need for the original HMI controller. ## Why not using cozytouch / io-homecontrol? @@ -33,5 +45,9 @@ Unfortunately, I had no success pairing those solutions with my Windhager brande - [x] HW prototype: arduino nano + esp8266 - [x] SW prototype: Provide sensor data via MQTT - [x] Visualize data within HomeAssistant -- [ ] Control the heat pump (mock HMI controller, man in the middle) +- [x] Prototype: Control the heat pump (replaces original HMI controller) +- [ ] Prototype: Control the heat pump (man in the middle) - [ ] Final hardware, board layout and instructions +- [ ] HomeAssistant configuration + +