Skip to content

Commit

Permalink
doc(readme): updated status and roadmap
Browse files Browse the repository at this point in the history
  • Loading branch information
tspopp committed Nov 7, 2023
1 parent 3bb8ba8 commit ee159a0
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 43 deletions.
15 changes: 15 additions & 0 deletions AquaMqttLogger/README.md
Original file line number Diff line number Diff line change
@@ -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**
1 change: 0 additions & 1 deletion AquaMqttLogger/include/ESPLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class ESPLink
static void mqttDisconnected(void* response);
static void mqttData(void* response);

Stream* mSerial;
ELClient* mElClient;
ELClientCmd* mELClientCmd;
ELClientMqtt* mELClientMqtt;
Expand Down
12 changes: 3 additions & 9 deletions AquaMqttLogger/src/ESPLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
55 changes: 27 additions & 28 deletions AquaMqttLogger/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
#include <Arduino.h>
#include <avr/wdt.h>
#include <SoftwareSerial.h>
#include <avr/wdt.h>

#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()
{
Expand All @@ -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())
{
Expand All @@ -34,7 +36,6 @@ void setup()

espLink.setMqttCallback(&hmiState);


Serial.println("SETUP OK");
}

Expand All @@ -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));
}
}
}
2 changes: 2 additions & 0 deletions AquaSimuUno/README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/).

<img src="../media/homeassistant.png?raw=true" width=40% height=40%>

## 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/)
Expand All @@ -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?

Expand All @@ -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


0 comments on commit ee159a0

Please sign in to comment.