Термостат OpenTherm на ESP8266

golosun
Offline
Зарегистрирован: 31.10.2016
Central Heating: on
Hot Water: off
Flame: on
 
 
Get MemberIDcode - OK = 33
Error set MemberIDcode - Response status: 2 - INVALID
Get MemberIDcode - OK = 33
 
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 66.00 C 1075397120
Year=2021
 
 
 
А 19712 это ot.temperatureToData(77)
 
golosun
Offline
Зарегистрирован: 31.10.2016

А с https://github.com/miksumin/OpenTherm - ошибка компиляции

 

miks69
Offline
Зарегистрирован: 16.02.2020

Попробуйте сделать запрос таким образом:

unsigned long request = ot.buildSetBoilerTemperatureRequest(Set_Temp_obr);

response = ot.sendRequest(request);

miks69
Offline
Зарегистрирован: 16.02.2020

golosun пишет:

А с https://github.com/miksumin/OpenTherm - ошибка компиляции

Да, я там немного доработал библиотеку под себя

golosun
Offline
Зарегистрирован: 31.10.2016
Central Heating: on
Hot Water: off
Flame: on
 
 
Get MemberIDcode - OK = 33
set MemberIDcode - OK - 7
Get MemberIDcode - OK = 33
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0xC000030A
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 55.00 C 3222877952
Year=2021
 
miks69
Offline
Зарегистрирован: 16.02.2020

golosun пишет:

New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00

Вы здесь выводите response или request?

golosun
Offline
Зарегистрирован: 31.10.2016
#include <Arduino.h>

#include <OpenTherm.h>

const int inPin = 4;  //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int outPin = 5; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32
OpenTherm ot(inPin, outPin);


void ICACHE_RAM_ATTR handleInterrupt() {
    ot.handleInterrupt();
}

void setup() {
  Serial.begin(115200);
  
   ot.begin(handleInterrupt);
}

void loop() {

 //Set/Get Boiler Status
    bool enableCentralHeating = true;
    bool enableHotWater = true;
    bool enableCooling = false;
    unsigned long response = ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling);
    OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
    if (responseStatus == OpenThermResponseStatus::SUCCESS) {
        Serial.println("Central Heating: " + String(ot.isCentralHeatingActive(response) ? "on" : "off"));
        Serial.println("Hot Water: " + String(ot.isHotWaterActive(response) ? "on" : "off"));
        Serial.println("Flame: " + String(ot.isFlameOn(response) ? "on" : "off"));
    }
    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");
    }
Serial.println("");
Serial.println("");
MembIDcode();
Serial.println("");


float Set_Temp_obr = 77;

    if (!ot.setBoilerTemperature(Set_Temp_obr)) {
     Serial.print("Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(ot.temperatureToData(Set_Temp_obr)) );
     Serial.printf("Response: 0x%08X\r\n", response);
    } else
    Serial.print("Set Boiler Temp - OK");


Serial.println("");

unsigned int data = ot.temperatureToData(Set_Temp_obr);  //(1075395072);
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::TSet, data);
response = ot.sendRequest(request);
 if (!ot.isValidResponse(response)) {
     Serial.print("New Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(data) );
     Serial.printf("Response: 0x%08X\r\n", response);
    }else
    Serial.print("New Set Boiler Temp - OK");

request = ot.buildSetBoilerTemperatureRequest(Set_Temp_obr);
response = ot.sendRequest(request);
 if (!ot.isValidResponse(response)) {
     Serial.print("NewNew Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(data) );
     Serial.printf("Response: 0x%08X\r\n", response);
    }else
    Serial.print("NewNew Set Boiler Temp - OK");


Serial.println("");

    //Get Boiler Temperature
//    response = ot.sendRequest(ot.buildGetBoilerTemperatureRequest());
request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Tboiler, 0);
response = ot.sendRequest(request);
    if (ot.isValidResponse(response)) {
//     Temp_obr = ot.getFloat(response); 
    Serial.println("CH temperature is " + String(ot.getFloat(response)) + " C " + String(response));
     }
     else {
      Serial.println("Get Boiler Temperature - Response status: " + String(ot.getLastResponseStatus()));
    }

 response = ot.sendRequest(ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Year, 0));
 Serial.println("Year=" + String( ((response & 0xFF) << 8) + ((response >> 8) & 0xFF)));



Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
  delay(1000);

}


void MembIDcode() {
  unsigned int data;
  unsigned long request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
  unsigned long response = ot.sendRequest(request);
  if (!ot.isValidResponse(response) ) {
   Serial.print("Error get MemberIDcode - ");
   Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
  } else {
  data = response & 0xFF;
  Serial.println("Get MemberIDcode - OK = " + String(data));
  }
  data = 0x0007;
  request = ot.buildRequest(OpenThermRequestType::WRITE,OpenThermMessageID::MConfigMMemberIDcode, data);
  if (!ot.isValidResponse(response) ) {
     Serial.print("Error set MemberIDcode - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
  } else
  Serial.println("set MemberIDcode - OK - " + String(data));

  request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
  response = ot.sendRequest(request);
  if (!ot.isValidResponse(response) ) {
   Serial.print("Error get MemberIDcode - ");
   Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
  } else {
  data = response & 0xFF;
  Serial.println("Get MemberIDcode - OK = " + String(data));
  }
}  

 

 

response

miks69
Offline
Зарегистрирован: 16.02.2020

response надо сначала получить, однако, прежде чем выводить )))

unsigned long request = ot.buildSetBoilerTemperatureRequest(Set_Temp_obr);

response = ot.sendRequest(request);

Serial.printf("Response: 0x%08X\r\n", response);

 

golosun
Offline
Зарегистрирован: 31.10.2016

Строка 70-71

miks69
Offline
Зарегистрирован: 16.02.2020

Странная какая-то история. В ответе должен быть код ответа, т.е. что-то из:

READ_ACK = B100,

WRITE_ACK = B101,

DATA_INVALID = B110,

UNKNOWN_DATA_ID = B111

А там код запроса (0x10014D00) почему-то...

А первый код ответа (0xC000030A) - это вообще ответ на запрос статуса...

Сегодня поздно уже, завтра ещ раз посмотрю ваш код и напишу.

golosun
Offline
Зарегистрирован: 31.10.2016

А там код запроса (0x10014D00) почему-то... -и что можно/нужно  сделать?

Все читает, но ничего не пишет, хотя - если поставлю температуру НОЛЬ - то обогрев отключается

 

 

А первый код ответа (0xC000030A) - это вообще ответ на запрос статуса... - ДА

miks69
Offline
Зарегистрирован: 16.02.2020

golosun пишет:

А первый код ответа (0xC000030A) - это вообще ответ на запрос статуса... - ДА

Так он у вас в логе после запроса на установку температуры котла потому как там у вас в коде нет получения кода response

miks69
Offline
Зарегистрирован: 16.02.2020

Добавьте там response = ot.getLastResponse();

Хочется все-таки увидеть реальный код ответа с ошибкой

golosun
Offline
Зарегистрирован: 31.10.2016

getLastResponse - ошибка - has no member named 

 а если - getLastResponseStatus - то строка 74

miks69
Offline
Зарегистрирован: 16.02.2020

golosun пишет:

getLastResponse - ошибка - has no member named 

 а если - getLastResponseStatus - то строка 74


Добавьте в коде OpenTherm.cpp:
unsigned long OpenTherm::getLastResponse() {
return response;
}
И в коде OpenTherm.h (в разделе public):
unsigned long getLastResponse();

miks69
Offline
Зарегистрирован: 16.02.2020

И поправьте свой код в строках 70 - 78, у вас там зачем-то стоит html-тег <strong></strong>

golosun
Offline
Зарегистрирован: 31.10.2016

Это я хотел выделить, в коде этого нет

golosun
Offline
Зарегистрирован: 31.10.2016
Central Heating: on
Hot Water: off
Flame: on
 
 
Get MemberIDcode - OK = 33
Error set MemberIDcode - Response status: 2 - INVALID
Get MemberIDcode - OK = 33
 
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 70.00 C 3222881792
Year=2021
 
 
ничего не поменялось
golosun
Offline
Зарегистрирован: 31.10.2016
#include <Arduino.h>

#include <OpenTherm.h>

const int inPin = 4;  //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int outPin = 5; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32
OpenTherm ot(inPin, outPin);


void ICACHE_RAM_ATTR handleInterrupt() {
    ot.handleInterrupt();
}

void setup() {
  Serial.begin(115200);
  
   ot.begin(handleInterrupt);
}

void loop() {

 //Set/Get Boiler Status
    bool enableCentralHeating = true;
    bool enableHotWater = true;
    bool enableCooling = false;
    unsigned long response = ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling);
    OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
    if (responseStatus == OpenThermResponseStatus::SUCCESS) {
        Serial.println("Central Heating: " + String(ot.isCentralHeatingActive(response) ? "on" : "off"));
        Serial.println("Hot Water: " + String(ot.isHotWaterActive(response) ? "on" : "off"));
        Serial.println("Flame: " + String(ot.isFlameOn(response) ? "on" : "off"));
    }
    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");
    }
Serial.println("");
Serial.println("");
MembIDcode();
Serial.println("");
Serial.println("");


float Set_Temp_obr = 77;

    if (!ot.setBoilerTemperature(Set_Temp_obr)) {
     Serial.print("Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(ot.temperatureToData(Set_Temp_obr)) );
response = ot.getLastResponse();
Serial.printf("Response: 0x%08X\r\n", response);     
    } else
    Serial.print("Set Boiler Temp - OK");


Serial.println("");

unsigned int data = ot.temperatureToData(Set_Temp_obr);  //(1075395072);
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::TSet, data);
response = ot.sendRequest(request);
 if (!ot.isValidResponse(response)) {
     Serial.print("New Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(data) );
     Serial.printf("Response: 0x%08X\r\n", response);
    }else
    Serial.print("New Set Boiler Temp - OK");

Serial.println("");
request = ot.buildSetBoilerTemperatureRequest(Set_Temp_obr);
response = ot.sendRequest(request);
 if (!ot.isValidResponse(response)) {
     Serial.print("NewNew Set Boiler Temp Error - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) + "__" + String(data) );
response = ot.getLastResponse();
     Serial.printf("Response: 0x%08X\r\n", response);
    }else
    Serial.print("NewNew Set Boiler Temp - OK");


Serial.println("");

    //Get Boiler Temperature
//    response = ot.sendRequest(ot.buildGetBoilerTemperatureRequest());
request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Tboiler, 0);
response = ot.sendRequest(request);
    if (ot.isValidResponse(response)) {
//     Temp_obr = ot.getFloat(response); 
    Serial.println("CH temperature is " + String(ot.getFloat(response)) + " C " + String(response));
     }
     else {
      Serial.println("Get Boiler Temperature - Response status: " + String(ot.getLastResponseStatus()));
    }

 response = ot.sendRequest(ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Year, 0));
 Serial.println("Year=" + String( ((response & 0xFF) << 8) + ((response >> 8) & 0xFF)));



Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
  delay(1000);

}


void MembIDcode() {
  unsigned int data;
  unsigned long request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
  unsigned long response = ot.sendRequest(request);
  if (!ot.isValidResponse(response) ) {
   Serial.print("Error get MemberIDcode - ");
   Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
  } else {
  data = response & 0xFF;
  Serial.println("Get MemberIDcode - OK = " + String(data));
  }

  data = 0x0007;
  request = ot.buildRequest(OpenThermRequestType::WRITE,OpenThermMessageID::MConfigMMemberIDcode, data);
  response = ot.sendRequest(request);
  if (!ot.isValidResponse(response) ) {
     Serial.print("Error set MemberIDcode - ");
     Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
     Serial.printf("Response: 0x%08X\r\n", response);
  } else
  Serial.println("set MemberIDcode - OK - " + String(data));

  request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
  response = ot.sendRequest(request);
  if (!ot.isValidResponse(response) ) {
   Serial.print("Error get MemberIDcode - ");
   Serial.println("Response status: " + String(ot.getLastResponseStatus()) + " - " + ot.statusToString(ot.getLastResponseStatus()) );
  } else {
  data = response & 0xFF;
  Serial.println("Get MemberIDcode - OK = " + String(data));
  }
}  

 

строка 78

miks69
Offline
Зарегистрирован: 16.02.2020

Вы не добавили запрос кода response.

Строка 54:

response = ot.getLastResponse();

Serial.printf("Response: 0x%08X\r\n", response);

golosun
Offline
Зарегистрирован: 31.10.2016
Central Heating: on
Hot Water: off
Flame: on
 
 
Get MemberIDcode - OK = 33
Error set MemberIDcode - Response status: 2 - INVALID
Response: 0xF0020007
Get MemberIDcode - OK = 33
 
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 67.00 C 3222881024
Year=2021
 
 
И такая-же фигня в set MemberIDcode
golosun
Offline
Зарегистрирован: 31.10.2016

Ничего это не поменяло

 

Central Heating: on
Hot Water: off
Flame: on
 
 
Get MemberIDcode - OK = 33
Error set MemberIDcode - Response status: 2 - INVALID
Response: 0xF0020007
Get MemberIDcode - OK = 33
 
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 58.00 C 1075395072
Year=2021
 
 
miks69
Offline
Зарегистрирован: 16.02.2020

Такое впечатление, что котел по каким-то причинам просто не принимает запрос на установку температуры.

При этом реальный код ответа котла с ошибкой мы пока так и не увидели. Завтра попробую доработать ваш код, чтобы все-таки получить код ошибки.

golosun
Offline
Зарегистрирован: 31.10.2016

Не только температуру, но и MemberIDcode

Ок, спасибо, до завтра

 

tsv_33
Offline
Зарегистрирован: 11.04.2019

golosun пишет:

А как задать ему MasterID ?

Как задать кодом вы уже разобрались, осталось понять для чего...

Согласно протоколу ID2 W(Master MemberID code) и ID3 R(Slave MemberID code) дословный перевод: "Эта группа элементов данных определяет информацию о конфигурации как на ведомых, так и на ведущих сторонах..."

Проще говоря, Slave и Master должны "представиться" друг другу. В вашем случае котёл отправляет мастеру свой Slave MemberID code = 21(hex формат), а вы, почему то, упорно возвращаете котлу чужой Master MemberID code = 07(hex формат). Откуда его взяли?

Что мастер из ID3 котла прочитал, то обратно в ID2 котла и отправил, так должно быть.

golosun
Offline
Зарегистрирован: 31.10.2016

Ок, пишу то, что и получаю, результат тот-же

Central Heating: off
Hot Water: off
Flame: off
 
 
Get MemberIDcode - OK = 33
Error set MemberIDcode (33) - Response status: 2 - INVALID
Response: 0x70020021
Get MemberIDcode - OK = 33
 
 
Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
New Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
NewNew Set Boiler Temp Error - Response status: 2 - INVALID__19712
Response: 0x10014D00
 
CH temperature is 64.00 C 3222880256
Year=2021
 
golosun
Offline
Зарегистрирован: 31.10.2016

Обратите внимание, как читается год - байты надо переставлять местами (это особенность висмана?!)

tsv_33
Offline
Зарегистрирован: 11.04.2019

golosun пишет:

Ок, пишу то, что и получаю, результат тот-же

Не вижу кода обмена переменными.

tsv_33
Offline
Зарегистрирован: 11.04.2019

golosun пишет:

Обратите внимание, как читается год - байты надо переставлять местами (это особенность висмана?!)

Не пойму, зачем какие то танцы с бубном, протокол обязателен для всех. Если делаете правильно, то и результат будет правильным.

p.s.

С Visseman vitopend 100w мой код работает как надо, проверено...

miks69
Offline
Зарегистрирован: 16.02.2020

Попробуем сначала. Немного причесал ваш код, попробуйте запустить и лог в студию

tsv_33
Offline
Зарегистрирован: 11.04.2019

На фига для конкретного котла постоянно вычитывать ID3? 21 там лежит, нового не будет. В секундном цикле пишите в ID2 сразу 0x0021. 

Или так:

// Записать ID-2; мастер-код MemberID
unsigned int data = 0x0021;
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, data);
ot.sendRequest(request);

 

miks69
Offline
Зарегистрирован: 16.02.2020

Поторопился немного...

Поправьте ошибку - после строки 130 и 150 там надо добавить "}"

И еще там String() забыл добавить в нескольких строках...

Вот рабочий код:

#include <Arduino.h>

#include <OpenTherm.h>

const int inPin = 4;  //for Arduino, 4 for ESP8266 (D2), 21 for ESP32
const int outPin = 5; //for Arduino, 5 for ESP8266 (D1), 22 for ESP32
OpenTherm ot(inPin, outPin);

void ICACHE_RAM_ATTR handleInterrupt() {
    ot.handleInterrupt();
}

void setup() {
  Serial.begin(115200);
  
   ot.begin(handleInterrupt);
}

void loop() {
	
	unsigned int data;
	unsigned long request;
	unsigned long response;

	//Set/Get Boiler Status
    bool enableCentralHeating = true;
    bool enableHotWater = true;
    bool enableCooling = false;
	
	// Set-Get Boiler Status
    response = ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling);
    OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
    if (responseStatus == OpenThermResponseStatus::SUCCESS) {
        Serial.println("Central Heating: " + String(ot.isCentralHeatingActive(response) ? "on" : "off"));
        Serial.println("Hot Water: " + String(ot.isHotWaterActive(response) ? "on" : "off"));
        Serial.println("Flame: " + String(ot.isFlameOn(response) ? "on" : "off"));
    }
    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");
    }

	Serial.println("");
	Serial.println("");
	
	MembIDcode();
	
	Serial.println("");
	Serial.println("");


	byte Set_Temp_obr = 77;

	// Set Boiler Temp
	request = ot.buildSetBoilerTemperatureRequest((float)Set_Temp_obr);
	response = ot.sendRequest(request);
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		Serial.println("Set Boiler Temp - OK = " + String(Set_Temp_obr));
	}
	else {
		Serial.print("Set Boiler Temp Error - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response code: 0x%08X\r\n", response);
	}
	
	Serial.println("");

	data = ot.temperatureToData(Set_Temp_obr);
	request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::TSet, data);
	response = ot.sendRequest(request);
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		Serial.println("New Set Boiler Temp - OK");
	}
	else {
		Serial.print("New Set Boiler Temp Error - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response: 0x%08X\r\n", response);
    }
		
	Serial.println("");

    // Get Boiler Temperature
	//response = ot.sendRequest(ot.buildGetBoilerTemperatureRequest());
	request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Tboiler, 0);
	response = ot.sendRequest(request);
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		Serial.println("CH temperature is " + String(ot.getTemperature(response),1) + " C ");
	}
	else {
		Serial.print("Get Boiler Temperature Error - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response: 0x%08X\r\n", response);
	}
	
	Serial.println("");
	
	response = ot.sendRequest(ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Year, 0));
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		Serial.println("Boiler Year = " + String(((response & 0xFF) << 8) + ((response >> 8) & 0xFF)));
	}
	else {
		Serial.print("Get Boiler Year Error - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response: 0x%08X\r\n", response);
	}

	Serial.println("");
	Serial.println("");
	Serial.println("");
	Serial.println("");
	delay(1000);

}

void MembIDcode() {
	
	unsigned int data;
	unsigned long request;
	unsigned long response;
	OpenThermResponseStatus responseStatus;
	
	// Get MemberID code
	request = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
	response = ot.sendRequest(request);
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		data = response & 0xFF;
		Serial.println("Get MemberID code - OK = " + String(data));
	}
	else {
		Serial.print("Error get MemberIDcode - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response code: 0x%08X\r\n", response);
	} 


	// Set MemberID code
	request = ot.buildRequest(OpenThermRequestType::WRITE,OpenThermMessageID::MConfigMMemberIDcode, data);
	response = ot.sendRequest(request);
	responseStatus = ot.getLastResponseStatus();
	if (responseStatus == OpenThermResponseStatus::SUCCESS) {
		Serial.println("Set MemberID code - OK - " + String(data));
	}
	else {
		Serial.print("Error set MemberIDcode - ");
		Serial.println("Response status: " + String(ot.statusToString(ot.getLastResponseStatus())) );
		Serial.printf("Response code: 0x%08X\r\n", response);
	} 

}

 

miks69
Offline
Зарегистрирован: 16.02.2020

tsv_33 пишет:

На фига для конкретного котла постоянно вычитывать ID3? 21 там лежит, нового не будет. В секундном цикле пишите в ID2 сразу 0x0021. 

Или так:

// Записать ID-2; мастер-код MemberID
unsigned int data = 0x0021;
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, data);
ot.sendRequest(request);

Вчера пробовали писать значение MemberID, которое читается, не помогает.

Запрос SetBoilerTemp котел просто не принимает по неизвестным причинам.

Может там какие-то ручные установки есть на котле типа режима котла или что-то еще?

tsv_33
Offline
Зарегистрирован: 11.04.2019

Нет там ни чего подобного. Для многих котлов ID2 и ID3 по барабану. Мой, к примеру, без обмена этой информацией, будет только мониториться.

Зачем загромождать код тем, что есть в самой библиотеке в basic requests. Как в примере, в цикле кода достаточно отправить котлу:

ot.setBoilerTemperature(64); - для ID1

ot.setDHWSetpoint(40); - для  ID56

естественно, вместо (64) и (40) уставки, вычисляемые по своим правилам.

 

 

miks69
Offline
Зарегистрирован: 16.02.2020

tsv_33 пишет:

Нет там ни чего подобного. Для многих котлов ID2 и ID3 по барабану. Мой, к примеру, без обмена этой информацией, будет только мониториться.

Зачем загромождать код тем, что есть в самой библиотеке в basic requests. Как в примере, в цикле кода достаточно отправить котлу:

ot.setBoilerTemperature(64); - для ID1

ot.setDHWSetpoint(40); - для  ID56

естественно, вместо (64) и (40) уставки, вычисляемые по своим правилам.

Согласен, но в случае синхронных запросов приходится после каждого запроса проверять responseStatus и в случае ошибки запрашивать код ответа для диагностики, а setBoilerTemperature() и setDHWSetpoint() его не выдают...

tsv_33
Offline
Зарегистрирован: 11.04.2019

miks69 пишет:

Согласен, но в случае синхронных запросов приходится после каждого запроса проверять responseStatus и в случае ошибки запрашивать код ответа для диагностики, а setBoilerTemperature() его не выдает...

А вот тут я согласен. Потому убрал из библиотеки ОТ все basic requests.

Для проверки работоспособности обмена данными чем проще, тем лучше. Да и понятней разбираться будет. А дальше, уже строить для себя, со своими хотелками.

golosun
Offline
Зарегистрирован: 31.10.2016
 
Central Heating: off
Hot Water: off
Flame: off
 
 
Get MemberID code - OK = 33
Error set MemberIDcode - Response status: INVALID
Response code: 0x70020021
 
 
Set Boiler Temp Error - Response status: INVALID
Response code: 0x10014D00
 
New Set Boiler Temp Error - Response status: INVALID
Response: 0x10014D00
 
CH temperature is 
 
Boiler Year = 2021
 
miks69
Offline
Зарегистрирован: 16.02.2020

golosun пишет:

 
Central Heating: off
Hot Water: off
Flame: off
 
 
Get MemberID code - OK = 33
Error set MemberIDcode - Response status: INVALID
Response code: 0x70020021
 
 
Set Boiler Temp Error - Response status: INVALID
Response code: 0x10014D00
 
New Set Boiler Temp Error - Response status: INVALID
Response: 0x10014D00
 
CH temperature is 
 
Boiler Year = 2021
 

Response: 0x70020021 = UNKNOWN_DATA_ID (ID=2)

Response: 0x10014D00 = WRITE_DATA (ID=1) - но это не ответ, который должен быть WRITE_ACK = B101

miks69
Offline
Зарегистрирован: 16.02.2020

tsv_33 пишет:

Для проверки работоспособности обмена данными чем проще, тем лучше. Да и понятней разбираться будет. А дальше, уже строить для себя, со своими хотелками.

tsv_33, а можете проверить код на своем Viessmann?

tsv_33
Offline
Зарегистрирован: 11.04.2019

У меня Бакси. Висманы у моих клиентов.

miks69
Offline
Зарегистрирован: 16.02.2020

Вообще, как я уже писал, по моим наблюдениям в общении устройства с котлом происходит немало ошибок как в чтении котлом запроса устройства, так и в чтении устройством ответа котла. Но, возможно, это только мой случай с котлом Buderus.

Для полноценной диагностики я замеряю все приходящие от котла импульсы и делаю более детальную их обработку в процедуре обработки прерываний. В случае ошибок вывожу всю информацию в лог и анализирую уже вручную.

miks69
Offline
Зарегистрирован: 16.02.2020

tsv_33 пишет:

У меня Бакси. Висманы у моих клиентов.

Ну может будет возможность проверить у клиента на аналогичной модели котла, чтобы понять, это проблема данной модели или проблема данного котла

golosun
Offline
Зарегистрирован: 31.10.2016

tsv_33 пишет 

С Visseman vitopend 100w мой код работает как надо, проверено...

 

ОК, можете собрать тестовый бинарник из своего рабочего кода, для проверки возможностей моего котла по установке температуры

tsv_33
Offline
Зарегистрирован: 11.04.2019

golosun пишет:

tsv_33 пишет 

С Visseman vitopend 100w мой код работает как надо, проверено...

 

ОК, можете собрать тестовый бинарник из своего рабочего кода, для проверки возможностей моего котла по установке температуры

Возьмите с Яндекс.Диска https://disk.yandex.ru/d/Qcu-3S7WqdUTHg?w=1, только что выложил последнюю прошивку 23.01

tsv_33
Offline
Зарегистрирован: 11.04.2019

miks69 пишет:

Ну может будет возможность проверить у клиента на аналогичной модели котла, чтобы понять, это проблема данной модели или проблема данного котла

Без вариантов, доступа к их котлам у меня нет, как нет проблем и с этой моделью.

golosun
Offline
Зарегистрирован: 31.10.2016

По ссылке написано:

Всем кто приобрёл готовое изделие или отдельно ПО, пожалуйста, не пытайтесь загружать в свой термостат

эту прошивку, она полноценно работать не будет!!!

Ваше ПО индивидуальное.

С ПО, скаченном от сюда, ваше изделие будет работать только в режиме мониторинга OpenTherm, управлять работой котла невозможно

 

У меня и моя прошивка работает в режиме мониторинга, интересует управление котлом - поддерживает ли мой котёл?

tsv_33
Offline
Зарегистрирован: 11.04.2019

Поддерживает!

golosun
Offline
Зарегистрирован: 31.10.2016

Как проверить?

miks69
Offline
Зарегистрирован: 16.02.2020

tsv_33 пишет:

Поддерживает!

Но не работает...

tsv_33
Offline
Зарегистрирован: 11.04.2019

miks69 пишет:

tsv_33 пишет:

Поддерживает!

Но не работает...

Неправда ваша...