opentherm gateway tussen thermostaat en ketel

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • j.otte
  • Registratie: Augustus 2023
  • Laatst online: 25-08-2023
Hallo,

ik ben aan het proberen om met een esp2866 en een opentherm gateway shield van diyless er voor te zorgen dat ik de thermostaat setpoint kan uitlezen en de ketel kan uitlezen en aan sturen. nu zijn we al zo ver gekomen dat we de ketel uit kunnen lezen en misschien ook aan kunnen passen maar dat is nog niet helemaal duidelijk. Maar het probleem zit hem in de thermostaat, we krijgen het maar niet voor elkaar dat we daar de data van uit kunnen lezen. We hebben al verschillende thermostaten geprobeerd maar geen succes. heeft iemand nog tips?

Hardware:
esp 2866 met opentherm gateway (https://diyless.com/product/esp8266-opentherm-gateway)
danfoss RET2001OT (er knippert heel de tijd 2e op het scherm)
Nefit ProLine NxT HRC 24-CW4 CT (nog niet aangesloten)

code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
OpenTherm Gateway/Monitor Example
By: Ihor Melnyk
Date: May 1st, 2019
http://ihormelnyk.com
*/


#include <Arduino.h>
#include <OpenTherm.h>

bool didMyOneTimeActionRun = false;

const int mInPin = D2; //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int mOutPin = D1; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32

const int sInPin = D6; //for Arduino, 12 for ESP8266 (D6), 19 for ESP32
const int sOutPin = D7; //for Arduino, 13 for ESP8266 (D7), 23 for ESP32

OpenTherm mOT(mInPin, mOutPin);
OpenTherm sOT(sInPin, sOutPin, true);

void IRAM_ATTR mHandleInterrupt() {
    mOT.handleInterrupt();
}

void IRAM_ATTR sHandleInterrupt() {
    sOT.handleInterrupt();
}

void processRequest(unsigned long request, OpenThermResponseStatus status) {
    Serial.println("T" + String(request, HEX)); //master/thermostat request

    unsigned long response = 0;
    OpenThermMessageID id = sOT.getDataID(request);
    uint16_t data = sOT.getUInt(request);
    float f = sOT.getFloat(request);
    switch(id)
    {
      case OpenThermMessageID::Status:
      {
        uint8_t statusRequest = data >> 8;
        uint8_t chEnable = statusRequest & 0x1;
        uint8_t dhwEnable = statusRequest & 0x2;
        data &= 0xFF00;
        //data |= 0x01; //fault indication
        if (chEnable) data |= 0x02; //CH active
        if (dhwEnable) data |= 0x04; //DHW active
        if (chEnable || dhwEnable) data |= 0x08; //flame on
        //data |= 0x10; //cooling active
        //data |= 0x20; //CH2 active
        //data |= 0x40; //diagnostic/service event
        //data |= 0x80; //electricity production on

        response = sOT.buildResponse(OpenThermMessageType::READ_ACK, id, data);
        break;
      }
      case OpenThermMessageID::TSet:
      {
        response = sOT.buildResponse(OpenThermMessageType::WRITE_ACK, id, data);
        break;
      }
      case OpenThermMessageID::TrSet:
      {
        response =  sOT.buildResponse(OpenThermMessageType::READ_ACK, id, data);
        break;
      }
      case OpenThermMessageID::Tboiler:
      {
        data = sOT.temperatureToData(45);
        response = sOT.buildResponse(OpenThermMessageType::READ_ACK, id, data);
        break;
      }
      default:
      {
        //build UNKNOWN-DATAID response
        response = sOT.buildResponse(OpenThermMessageType::UNKNOWN_DATA_ID, mOT.getDataID(request), 0);   
      }
    }
    Serial.println("B" + String(response, HEX)); //slave/boiler response

    //send response
    delay(20); //20..400ms, usually 100ms
    sOT.sendResponse(response);
}


void setup() {
  Serial.begin(9600); //9600 supported by OpenTherm Monitor App
   
  delay(1000);
  mOT.begin(mHandleInterrupt);
  delay(1000);
   
  sOT.begin(sHandleInterrupt, processRequest);
  delay(1000);
}

void loop()
{
    //sOT.process();
    mOT.process();
    getInfo();
    //setBoilerData();
    delay(1000);
}

void getInfo() {
  //Aanvoer temperatuur
  float ch_temperature = mOT.getBoilerTemperature();
  //Retour temperatuur
  float ret_temperature = mOT.getReturnTemperature();
  float setpoint = sOT.getFault();
  bool enableCentralHeating = true;
  bool enableHotWater = true;
  bool enableCooling = false;
  unsigned long response = mOT.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling);
  OpenThermResponseStatus responseStatus = mOT.getLastResponseStatus();
  Serial.println(responseStatus);
  Serial.println(mOT.statusToString(responseStatus));
  if (responseStatus == OpenThermResponseStatus::SUCCESS) {
      Serial.println("Central Heating: " + String(mOT.isCentralHeatingActive(response)? "on" : "off"));
      Serial.println("Hot Water: " + String(mOT.isHotWaterActive(response) ? "on" : "off"));
      Serial.println("Flame: " + String(mOT.isFlameOn(response) ? "on" : "off"));
      Serial.println("CH temperature is " + String(ch_temperature) + " degrees C");
      Serial.println("RET temperature is " + String(ret_temperature) + " degrees C");
      Serial.println("Setpoint is " + String(setpoint) + " degrees C");
      Serial.println();
  }
  if (responseStatus == OpenThermResponseStatus::NONE) {
      Serial.println("Error: OpenTherm is not initialized");
  }
  else if (responseStatus == OpenThermResponseStatus::INVALID) {
      Serial.println("Error: Invalid response " + String(response, HEX));
  }
  else if (responseStatus == OpenThermResponseStatus::TIMEOUT) {
      Serial.println("Error: Response timeout");
  }
      //Get DHW Temperature
//    float dhw_temperature = mOT.getDHWTemperature();
//    Serial.println("DHW temperature is " + String(dhw_temperature) + " degrees C");
}

void setBoilerData() {
    //Set Boiler Temperature to 64 degrees C
    //WERKT NIET
    mOT.setBoilerTemperature(64);
    //Set DHW setpoint to 40 degrees C
    mOT.setDHWSetpoint(40);
}
/*

Alle reacties


  • metamarty
  • Registratie: Juli 2002
  • Laatst online: 01:08

metamarty

Private RocketTwinky reporting

Het script dat je gebruikt is erg statisch in opentherm ID's. Hij laat alleen enkele specifieke ID's en stuurt een foutmelding terug naar de thermostaat bij alle ID's behalve een aantal.

In mijn ervaring zijn er tal van ID's die in gebruik zijn en je hebt goede kans dat de thermostaat staat te wachten en niet door zo'n initialisatie komt.

Stap 1 is altijd om enkel en alleen alle communicatie te loggen en direct naar de boiler te sturen en daarna het antwoord terug te sturen naar de thermostaat. Daarmee komt de thermostaat als het goed is in operationele mode. Pas als je een stroom aan opentherm packets heen en weer ziet gaan, kun je proberen om ergens in te grijpen.

Acties:
  • 0 Henk 'm!

  • BartSr1954
  • Registratie: Maart 2023
  • Laatst online: 20-02 10:39
Waarom niet een andere OTGW proberen. Schelte Bron ontwikkelde in 2009 er zelf een die alles biedt wat mogelijk is. https://otgw.tclcode.com/
Nodoshop verkoopt deze. Bij voorkeur de oude software kiezen. Die is probleemloos.
Wil je niet met domotica aan de slag dan is deze OTGW ook prima standalone te gebruiken via de OTmonitor. Zie info daarover op de website.