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

Basic HVAC/Ventilation system support #36

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Sidiox
Copy link

@Sidiox Sidiox commented Jun 20, 2021

This merge request adds basic support for ventilation systems.
Adds reading of the temperature sensors, some diagnostic info and fan control.

OpenThermIDs based on various spec sheets: 'OpenTherm Technical Specifications v2.3b' and 'OpenTherm-Function-Matrix-v1_0.xls'

Tested (and currently in use) for a Brink HRV.

@lmadean
Copy link

lmadean commented Oct 28, 2021

I also have a Brink HRV and would like to have this as well. Please merge the pull request.

@Sidiox
Copy link
Author

Sidiox commented Oct 28, 2021

I also have a Brink HRV and would like to have this as well. Please merge the pull request.

Have a look at my usage of my fork of the library if you have a Brink HRV (I have some more articles on how to hook up the hardware if you're interested): my article.

@crazypaddo
Copy link

Sidiox i have a brink wtw to are you willing to share your project file arduino ide ore vscode.
I am struggling to put all the software parts together but failed. I would like to integrate the system with the heatpump i installed to get the fans in sync.

@webstar-nl
Copy link

Sidiox i have a brink wtw to are you willing to share your project file arduino ide ore vscode. I am struggling to put all the software parts together but failed. I would like to integrate the system with the heatpump i installed to get the fans in sync.

Hi, I am experimenting as well with this Brink WTW and already got it running: reading and writing values. Great!

@crazypaddo
Copy link

crazypaddo commented Nov 16, 2021 via email

@Sidiox
Copy link
Author

Sidiox commented Nov 16, 2021

I can share my code, I'll try to get an example blog/github in a couple of days! It does presume knowledge of MQTT and Home-assistant how ever

@crazypaddo
Copy link

crazypaddo commented Nov 16, 2021 via email

@webstar-nl
Copy link

I will share my project as well, probably tomorrow. I use ESP32, programming over OTA and BLYNK for convenient interface. The nice thing of this opentherm protocol: as soon as you write 0 as setpoint Ventilation, device just stops.
Regards, Mark Wester

@crazypaddo
Copy link

crazypaddo commented Nov 17, 2021 via email

@webstar-nl
Copy link

This is my Arduino project. It is 'as-is' see feel free to use it.
Just copied modified OpenTherm.CPP + OpenTherm.H in same directory as project.
Components:
ESP32 WROOM
ESP8266 Thermostat Shield from diyless.com
5 wires connected: +5 / GND / 21 / 22 / 18

#include "OpenTherm.h" //local > in same directory as INO
// ESP32 Dev Module
// 16/11/2021 ...
// OTA + BLYNK + OpenTherm
#define BLYNK_PRINT Serial
#define VERSION 02 // Version in BLYNK
#include <Blynk.h> //
#include <BlynkSimpleEsp32.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>

char auth[] = "xxxxxxxxxxxxxxxx";// BLYNK ESP32 11/2021
const char* ssid = "xxxxxxxxxxxxx";
const char* password = "xxxxxxxxxxxx";
int counter;
BlynkTimer timer;
WidgetTerminal terminal(V0); //Text
// Use Virtual pin 0 for current room temperature display
unsigned int WTW_SetVentilation; //V2
// Opentherm:
const int inPin = 21; //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int outPin = 22; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32
OpenTherm ot(inPin, outPin); // true = slave

//Temperature sensor pin
const int ROOM_TEMP_PIN = 18; //14 for ESP8266 (D5), 18 for ESP32

OneWire oneWire(ROOM_TEMP_PIN);
DallasTemperature sensors(&oneWire);
//////////////////////////////////////////////////////////////////////////
float getTemp() { return sensors.getTempCByIndex(0); }
void ICACHE_RAM_ATTR handleInterrupt() { ot.handleInterrupt(); }

BLYNK_CONNECTED(){ // Sync
Blynk.syncVirtual(V2); // Setpoint Ventilatoin %
Blynk.virtualWrite(V50, VERSION);
}

BLYNK_WRITE(V2) { // Setpoint WTW
WTW_SetVentilation = param.asInt();
}

void setup() {
Serial.begin(115200);
terminal.println("Booting");
WiFi.mode(WIFI_STA);
Blynk.begin(auth, ssid, password);
delay(100);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
ArduinoOTA.setHostname("Esp32");
ArduinoOTA.onStart( {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd( { Serial.println("\nEnd"); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
terminal.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
terminal.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) terminal.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) terminal.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) terminal.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) terminal.println("Receive Failed");
else if (error == OTA_END_ERROR) terminal.println("End Failed");
});
ArduinoOTA.begin();
terminal.println("Ready");
terminal.print("IP address: ");
terminal.println(WiFi.localIP());
//
terminal.clear();
terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
terminal.flush();
timer.setInterval(5000L, DataOpentherm); // 1.0 s
ot.begin(handleInterrupt);
// ot.begin(handleInterrupt, processRequest);
//Init DS18B20 sensor
sensors.begin();
sensors.requestTemperatures();
sensors.setWaitForConversion(false); //switch to async mode
}

void loop() {
Blynk.run();
ArduinoOTA.handle();
timer.run();
ot.process();
} // loop
//-----------------------------//

void DataOpentherm() {
//Set/Get WTW Status
ot.setVentilation(WTW_SetVentilation); // Setpoint! V2 from BLYNK

unsigned int WTW_gVent = ot.getVentilation();
bool WTW_gVMode = ot.getVentilationMode();
float WTW_gVSIT = ot.getVentSupplyInTemperature();
float WTW_gVSOT = ot.getVentSupplyOutTemperature();
float WTW_gVEIT = ot.getVentExhaustInTemperature();
float WTW_gVEOT = ot.getVentExhaustOutTemperature();
terminal.println("WTW Ventilation%: " + String(WTW_gVent));
terminal.println("WTW VentilationMode: " + String(WTW_gVMode));
terminal.println("WTW VentSupplyInTemperature: " + String(WTW_gVSIT));
terminal.println("WTW VentSupplyInTemperature: " + String(WTW_gVSOT));
terminal.println("WTW VentSupplyInTemperature: " + String(WTW_gVEIT));
terminal.println("WTW VentSupplyInTemperature: " + String(WTW_gVEOT));
Blynk.virtualWrite(V3, WTW_gVent);
Blynk.virtualWrite(V4, WTW_gVMode);
Blynk.virtualWrite(V5, WTW_gVSIT);
Blynk.virtualWrite(V6, WTW_gVSOT);
Blynk.virtualWrite(V7, WTW_gVEIT);
Blynk.virtualWrite(V8, WTW_gVEOT);

float temperature = sensors.getTempCByIndex(0);
terminal.println("OT Room temperature is " + String(temperature) + " C");
terminal.println("-------------------------------");
Blynk.virtualWrite(V1, temperature);
terminal.flush();
}
/*
VentStatus = 70, // flag8 / flag8 Master and Slave Status flags specific to Vent systems
VentNomVentSet, // _ / u8 Set the relative ventilation 0-100%
VentFault, // flag8 / flag8 Application specific fault flags
VentOEMFault, // flag8 / flag8 Oem specific fault flags
VentSlaveVentConfig = 74, // Slave Configuration Flags / Slave MemberID Code
VentNomVent = 77, // _ / u8 Read the relative ventilation 0-100%
VentRelHumid, // _ / u8 Read the relative humidity 0-100%
VentCO2level, // u16 CO2 level in PPM (0-2000)
VentTsupplyin, // f8.8 Supply Outlet temperature
VentTsupplyout, // f8.8 Supply Outlet temperature
VentTexhaustin,// f8.8 Exhaust Inlet temperature
VentTexhaustout, // f8.8 Exhaust Outlet temperature
VentRPMexhaust, // u16 Actual RPM for inlet fan
VentRPMsupply, // u16 Actual RPM for supply fan
VentNomRelVent = 87, // _ / u8 Get the current relative ventilation
*/

@Sidiox
Copy link
Author

Sidiox commented Nov 21, 2021

Here is a repo that shows how I use my fork of the library with home-assistant: https://github.com/Sidiox/hrv-control

See my blog for more details on the hardware and such.

@crazypaddo
Copy link

crazypaddo commented Nov 23, 2021 via email

@crazypaddo
Copy link

crazypaddo commented Nov 25, 2021 via email

@Sidiox
Copy link
Author

Sidiox commented Nov 26, 2021

My Brink HRV is I think a medium from that same era.
Keep in mind that not all sensors are available in those units.
OpenTherm has 4 temperature ids, but I can only read 2. (There are only 2 physical temperature sensors in the unit and no CO2 sensors either and no humidity sensors either).

I'd try running an OpenTherm ID scan. I've added my scanning code to my repo: Scanner
I explain some of my process here: Blog

I got the following IDs:

70
72
74
75
77
80
81
82
83
86
88
89

I did find that Brink doesn't seem to quite follow the spec, but these IDs are plenty to control the HRV.

@webstar-nl
Copy link

I also don't get all data, most likely because not all sensors are implemented in standard equipment. But control speed, read supply inlet temperature and exhaust inlet temperature for me is enough.

@crazypaddo
Copy link

crazypaddo commented Nov 26, 2021 via email

@Sidiox
Copy link
Author

Sidiox commented Nov 26, 2021

If the scanner doesn't return the IDs then the HRV either doesn't support them or doesn't have them, or its encoded in another id. My scanner just does a raw read, so the HRV should always respond.

The scanner should also provide the raw data so it should be semi doable to reverse engineer most of the unknowns if I didn't implement them if you use the various specs floating around. I have an excel sheet with all the HRV IDs and their official designation, but Brink doesn't quite follow that spec sheet.

I remember I couldn't get the RPM readings. You can look at the raw scanner 0 and 1s, but I think I had some problem with that (either it didn't respond or didn't make sense).

@raf1000
Copy link

raf1000 commented Dec 13, 2021

Hello, I have managed to access all (or almost all) data available at Brink Renovent HR including adjustable parameters (TSP). You can find details here: (https://github.com/raf1000/brink_openhab)
The Arduno directory includes codes you can leverage in your project.
In case of questions please use the link as above.

PS. Based on my experience the otgw does not process all brink data :-( as it was designed for heating. the solution deecribed in the link above provides all avaiable data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants