Hello,
I am experimenting with an OpenTherm board from Diyless ( https://diyless.com/blog/domoticz-opentherm-thermostat) This board is connected to an ESP8266.
The diyless OpenTherm board has a temperature sensor on it.
I ran into the following problem, maybe someone has a solution for the following problem.
The thermostat control from Domoticz to my boiler works. However, the problem is that with this plugin he measures the temperature of the temperature sensor on the print of Diyless Opentherm. However, I would like him to measure the temperature of a Domoticz indoor temperature sensor. In the plugin setup you can specify the IDX of the indoor temperature gauge, but it will still use the temperature sensor on the Diyless board. How to modify the plugin script so that it controls from a Domoticz indoor temperature sensor?
Thanks
Robin
Diyless Opentherm to Domoticz
Moderator: leecollings
- waltervl
- Posts: 5148
- Joined: Monday 28 January 2019 18:48
- Target OS: Linux
- Domoticz version: 2024.7
- Location: NL
- Contact:
Re: Diyless Opentherm to Domoticz
As I understand from the link you gave you will have to rewrite the Arduino sketch so that it uses the temperature sensor of Domoticz by MQTT.
In the sketch it uses the build in temperature sensor to control the boiler based on the setpoint from Domoticz.
So you will have to add a section to also read the Domoticz temperature sensor by MQTT (like the setpoint temp).
Domoticz is sending that temperature already by MQTT.
In the sketch it uses the build in temperature sensor to control the boiler based on the setpoint from Domoticz.
So you will have to add a section to also read the Domoticz temperature sensor by MQTT (like the setpoint temp).
Domoticz is sending that temperature already by MQTT.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
-
- Posts: 112
- Joined: Sunday 20 May 2018 12:56
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Stable
- Location: NL
- Contact:
Re: Diyless Opentherm to Domoticz
Hello,
Thank you for the information. But I have no programming skills. Is there anyone who has an example how to adapt the sketch for a temperature sensor from Domoticz instead of:
" // Temperature sensor pin const int ROOM_TEMP_SENSOR_PIN = 14; //for Arduino, 14 for ESP8266 (D5), 18 for ESP32"
Sketch OpenTherm
Thank you for the information. But I have no programming skills. Is there anyone who has an example how to adapt the sketch for a temperature sensor from Domoticz instead of:
" // Temperature sensor pin const int ROOM_TEMP_SENSOR_PIN = 14; //for Arduino, 14 for ESP8266 (D5), 18 for ESP32"
Sketch OpenTherm
Code: Select all
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <OpenTherm.h>
// Your WiFi credentials.
// Set password to "" for open networks.
const char* ssid = "xxxxxx";
const char* pass = "xxxxxx";
// Your MQTT broker address and credentials
const char* mqtt_server = "xxx.xxx.xxx.xxx";
const char* mqtt_user = "xxxxxx";
const char* mqtt_password = "xxxxxx";
const int mqtt_port = 1883;
// Master OpenTherm Shield pins configuration
const int OT_IN_PIN = 4; //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int OT_OUT_PIN = 5; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32
// Temperature sensor pin
const int ROOM_TEMP_SENSOR_PIN = 14; //for Arduino, 14 for ESP8266 (D5), 18 for ESP32
const char* OUT_TOPIC = "domoticz/out";
const char* IN_TOPIC = "domoticz/in";
const String SETPOINT_NORMAL_ID = "xxxxxx";
const String CONTROL_ID = "xxxxxx";
const unsigned long statusUpdateInterval_ms = 1000;
float sp = 15, //set point
t = 15, //current temperature
t_last = 0, //prior temperature
ierr = 25, //integral error
dt = 0, //time between measurements
op = 0; //PID controller output
unsigned long ts = 0, new_ts = 0; //timestamp
unsigned long lastUpdate = 0;
unsigned long lastTempSet = 0;
bool heatingEnabled = true;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
OneWire oneWire(ROOM_TEMP_SENSOR_PIN);
DallasTemperature sensors(&oneWire);
OpenTherm ot(OT_IN_PIN, OT_OUT_PIN);
WiFiClient espClient;
PubSubClient client(espClient);
void ICACHE_RAM_ATTR handleInterrupt() {
ot.handleInterrupt();
}
float getTemp() {
return sensors.getTempCByIndex(0);
}
float pid(float sp, float pv, float pv_last, float& ierr, float dt) {
float KP = 10;
float KI = 0.02;
// upper and lower bounds on heater level
float ophi = 63;
float oplo = 20;
// calculate the error
float error = sp - pv;
// calculate the integral error
ierr = ierr + KI * error * dt;
// calculate the measurement derivative
//float dpv = (pv - pv_last) / dt;
// calculate the PID output
float P = KP * error; //proportional contribution
float I = ierr; //integral contribution
float op = P + I;
// implement anti-reset windup
if ((op < oplo) || (op > ophi)) {
I = I - KI * error * dt;
// clip output
op = max(oplo, min(ophi, op));
}
ierr = I;
Serial.println("sp=" + String(sp) + " pv=" + String(pv) + " dt=" + String(dt) + " op=" + String(op) + " P=" + String(P) + " I=" + String(I));
return op;
}
// This function calculates temperature and sends data to MQTT every second.
void updateData()
{
//Set/Get Boiler Status
bool enableHotWater = true;
bool enableCooling = false;
unsigned long response = ot.setBoilerStatus(heatingEnabled, enableHotWater, enableCooling);
OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
if (responseStatus != OpenThermResponseStatus::SUCCESS) {
Serial.println("Error: Invalid boiler response " + String(response, HEX));
}
t = getTemp();
new_ts = millis();
dt = (new_ts - ts) / 1000.0;
ts = new_ts;
if (responseStatus == OpenThermResponseStatus::SUCCESS) {
op = pid(sp, t, t_last, ierr, dt);
ot.setBoilerTemperature(op);
}
t_last = t;
sensors.requestTemperatures(); //async temperature request
Serial.println("Current temperature: " + String(t) + " °C ");
}
String convertPayloadToStr(byte* payload, unsigned int length) {
char s[length + 1];
s[length] = 0;
for (int i = 0; i < length; ++i)
s[i] = payload[i];
String tempRequestStr(s);
return tempRequestStr;
}
DynamicJsonDocument doc(768);
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println("Callback");
const String topicStr(topic);
String payloadStr = convertPayloadToStr(payload, length);
deserializeJson(doc, payloadStr);
const String id((const char*)doc["id"]);
Serial.println("Received, id=" + id);
if (id == SETPOINT_NORMAL_ID) {
const String targetTemp((const char*)doc["svalue1"]);
sp = targetTemp.toFloat();
}
else if (id == CONTROL_ID) {
const String targetMode((const char*)doc["svalue1"]);
Serial.println("Set mode " + targetMode);
if (targetMode == "0")
heatingEnabled = false;
else if (targetMode == "10" || targetMode == "20")
heatingEnabled = true;
else
Serial.println("Unknown mode");
}
doc.clear();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
const char* clientId = "opentherm-thermostat-test";
if (client.connect(clientId, mqtt_user, mqtt_password)) {
Serial.println("ok");
client.subscribe(OUT_TOPIC);
client.setBufferSize(1024);
} else {
Serial.print(" failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup()
{
Serial.begin(115200);
Serial.println("Connecting to " + String(ssid));
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
int deadCounter = 20;
while (WiFi.status() != WL_CONNECTED && deadCounter-- > 0) {
delay(500);
Serial.print(".");
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Failed to connect to " + String(ssid));
while (true);
}
else {
Serial.println("ok");
}
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
ot.begin(handleInterrupt);
//Init DS18B20 sensor
sensors.begin();
sensors.requestTemperatures();
sensors.setWaitForConversion(false); //switch to async mode
t, t_last = getTemp();
ts = millis();
}
void loop()
{
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastUpdate > statusUpdateInterval_ms) {
lastUpdate = now;
updateData();
}
}
Who is online
Users browsing this forum: No registered users and 1 guest