Remeha hot water boiler + heater service interface support (realtime statistics)

Remeha boilers (cv ketel) have a serial TTL interface with RJ10 (4P4C) interface that can be connected to a computer for reading realtime statistics and changing operation parameters.

Remeha supplies a Windows tool (Recom) for reading out the data (for example input + output temperature, liters/minute, valve status etc) and optionally changing parameters. The hardware cable (USB to RJ10) can be bought for 90 euro, or homemade for a few euro (USB to TTL cable with RJ10 connector using correct pin out)

Optionally, this serial port can be tunneled of an cabled ethernet network using a RPI, or even cooler, directly over WiFi using an ESP8266 module (loaded with ESP-LINK firmware) directly connected to the serial port of the Remeha boiler.

Information on other homebrew efforts:




https://www.domoticz.com/forum/viewtopic.php?t=14814

Using the information above I managed to connect an ESP8266 module (ESP-LINK firmware) and tunnel this to a virtual serial port on my laptop. With the Remeha supplied Recom software I can connect to this virtual serial port and connect to the boiler as if locally connected.

Recom software
http://www.recom-software.com/index.php?id=206

However, it would be even cooler if I could read out the realtime statistics using Home Assistant. This would mean a component that communicates over a local (virtual?) serial port and interprets the data for HASS.

I have been able to adjust the PHP script used by rjblake for his Avanta and remapped the values for a Tzerra boiler.

I also know that there is a pyton script for the Remeha boilers that can run on a Raspberry, and pushes data to statsd and Grafena. https://github.com/aequitas/remeha

Now we would need some way to get it available in Home Assistant.

Iā€™m no programmer, but was able to map the Tzerra boiler in the php scripts that were made for Domoticz. Where to begin is the next question.

Very new to HA, just using it for a few days. This is an old topic, so I donā€™t know if this is the right way to post this message. But I also have a Remeha Boiler.

And I use the eTwist thermostat to control it. Since the last update (13 december 2019) of eTwist it is possible to connect your eTwist with Google Home, Alexa and IFTTT.

Iā€™ve succeeded to connect my eTwist with Google Home, but I also want to connect it with HA. Does someone know how to do this?

I have created a ESPHOME version add on to directly communicate with remeha / dietrich boiler - based on links provided here with mapping of values.

Itā€™s still work in progress, there is possibility to read most of ā€œsampleā€ data from boiler.

1 Like

Can you help me with the connection from boiler to ESP8266?
Is the voltage divider needed, and how do I create this?
Also is the board powered from the boiler, or do I need a separate power supply?

I searched for this, but can only find this topic and your github page. I cannot find the answer on these pages.

Thanks

1 Like

On GitHub there is information how to connect it.
Itā€™s using 5V power from boiler - like on the schematics.
There is information about positble divider for RX/TX from 5V to 3.3V - but in my case (all info on GitHub) it was not working with it - and Iā€™have connected pins directly to boiler.

Thanks for your answer, I kind of forgot I posted a question here.

Turns out, I have a newer boiler. (Remeha Tzerra Ace 39C)
This boiler has another pinout, and a 6p6c connector.

I found another site saying it has a can-bus (Remeha Avanta interface via Recom software - Forum - Circuits Online)

I couldnā€™t find any solution for this (yet)

I now use an OpenTherm gateway (nodo-shop.nl) to interface. You can use the built in MQTT interface, but that does not (yet) support switching the DWH/SWW mode between eco and comfort. But the opentherm_gw integration does.

1 Like

Iā€™m using the custom component kakaki/esphome_dietrich but I keep getting CRC errors:

[09:56:20][D][api:098]: Accepted 192.168.2.5
[09:56:20][D][api.connection:736]: Home Assistant 2021.10.6 (192.168.2.5): Connected successfully
[09:56:20][D][custom:209]: crc error
[09:56:20][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64BD5750000030000000000000000000000F0A7C64B0000000000000000F0A7C64BE2750000000000000000000000000000F0A7C64B00000000
[09:56:31][D][sensor:113]: 'Boiler Uptime': Sending state 41.47600 s with 0 decimals of accuracy
[09:56:35][D][custom:209]: crc error
[09:56:35][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64B6FB00000030000000000000000000000F0A7C64B0000000000000000F0A7C64B7AB00000000000000000000000000000F0A7C64B00000000
[09:56:41][D][sensor:113]: 'Boiler WiFi Signal': Sending state -68.00000 dBm with 0 decimals of accuracy
[09:56:50][D][custom:209]: crc error
[09:56:50][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64B05EB0000030000000000000000000000F0A7C64B0000000000000000F0A7C64B12EB0000000000000000000000000000F0A7C64B00000000
[09:57:05][D][custom:209]: crc error
[09:57:05][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64B9F250100030000000000000000000000F0A7C64B0000000000000000F0A7C64BAA250100000000000000000000000000F0A7C64B00000000
[09:57:20][D][custom:209]: crc error
[09:57:20][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64B3F600100030000000000000000000000F0A7C64B0000000000000000F0A7C64B48600100000000000000000000000000F0A7C64B00000000
[09:57:31][D][sensor:113]: 'Boiler Uptime': Sending state 101.47500 s with 0 decimals of accuracy
[09:57:35][D][custom:209]: crc error
[09:57:35][D][custom:213]: sample data: 7462FF3FE9030000EC6BFF3FFB19204000000000F0A7C64BCD9A0100030000000000000000000000F0A7C64B0000000000000000F0A7C64BDA9A0100000000000000000000000000F0A7C64B00000000

When I flash the ESP8266 with ESPLINK firmwar (UART ā†’ WIFI BRIDGE) and connect the Remeha Service tool from my computer, it gives the correct values. Boiler type: ā€œRemeha Tzerraā€

Any idea on how to fix the CRC errors?

This only works for Calenta, Tzerra has different protocol, check using esphome_dietrich/dietrich_calentaV1_P5.h at 230c6466da92f71b1848f319bb66f0464edf77fa Ā· kakaki/esphome_dietrich Ā· GitHub

how about the avanta?

how can I use this?

Just add a new eps to my EspHome
And write the content of dietrich_en.yaml to the esp?
and connect it too my remeha Tzerra?

What to do with the other files like
dietrich.h

Exactly my question @borre and @kakaki

Iā€™ve got the Wemos D1 mini connected to the RJ10 / 4P4C connector inside my Tzerra M 28c ccs. It works ( takes 5 volt from the boiler it self etc etc).
Connected the ESP8266 to ESPHome in HomeAssistant, and I am able to edit the YAML file. BUT the content of dietrich_en.yaml copied, wonā€™t install. What do I have to do with this dietrich.h file? Do I need to copy the code, place the file somewhere of what?

Installation fails at:

sensor:
  - platform: custom
    lambda: |-
      auto dietrich = new Dietrich(id(uart_bus)); 

The line: new Dietrich is where compiling failsā€¦

/config/esphome/remeha.yaml: In lambda function:
/config/esphome/remeha.yaml:71:27: error: expected type-specifier before 'Dietrich'
   71 |       auto dietrich = new Dietrich(id(uart_bus));
      |                           ^~~~~~~~
/config/esphome/remeha.yaml:85:7: error: could not convert '{<expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>, <expression error>}' from '<brace-enclosed initializer list>' to 'std::vector<esphome::sensor::Sensor*>'
   85 |       };
      |       ^
      |       |
      |       <brace-enclosed initializer list>
*** [/data/remeha/.pioenvs/remeha/src/main.cpp.o] Error 1
========================= [FAILED] Took 97.88 seconds =========================`Preformatted text`

Download the dietrich.h file and put it in the esphome directory:
in my case (with the Samba add-on, I could reach it via network):
\homeassistant.local\config\esphome

Hi all. I have a Remeha Calenta C40 boiler and Iā€™m using this solution to read the data from it: GitHub - kakaki/esphome_dietrich: Dietrich (Remeha) Boiler connectivity using ESP8266 with ESPHOME - Home Assistant
Now this worked flawless for quite some time but after updating ESPHOME to 2023.4, Iā€™m getting the following error during compile:

src/dietrich.h:134:42: error: 'const class esphome::StringRef' has no member named 'length'

I have virtually no coding skills so I have no idea how to fix this. But this may possibly be an easy fix for someone with the proper knowledge. - Anyone? :smiley:

I have also opened an issue at the GitHub repo, but as there has been no commit for 2 years, Iā€™m not confident the owner will post a fix.

Thanks!

Worked around the issue by removing all the ā€œifā€ statements containing the ā€˜lengthā€™ statement.

Hello, do you have a working file for me?
Regards

I donā€™t see a way to upload a file here, so Iā€™ll try it like this. This is my content of dietrich.h, and itā€™s working:

#include "esphome.h"

class Dietrich : public PollingComponent, public UARTDevice {
 public:

  //sample data sensors
  Sensor *flow_temp_sensor = new Sensor();
  Sensor *return_temp_sensor = new Sensor();
  Sensor *dhw_in_temp_sensor = new Sensor();
  Sensor *outside_temp_sensor = new Sensor();
  Sensor *calorifier_temp_sensor = new Sensor();

  Sensor *boiler_control_temp_sensor = new Sensor();
  Sensor *room_temp_sensor = new Sensor();
  Sensor *ch_setpoint_sensor = new Sensor(); //co
  Sensor *dhw_setpoint_sensor = new Sensor(); //cwu
  Sensor *room_temp_setpoint_sensor = new Sensor();

  Sensor *fan_speed_setpoint_sensor = new Sensor();
  Sensor *fan_speed_sensor = new Sensor();

  Sensor *ionisation_current_sensor = new Sensor();
  Sensor *internal_setpoint_sensor = new Sensor();
  Sensor *available_power_sensor = new Sensor();
  Sensor *pump_percentage_sensor = new Sensor();

  Sensor *desired_max_power_sensor = new Sensor();
  Sensor *actual_power_sensor = new Sensor();

  Sensor *demand_source_bit0_sensor = new Sensor(); //BIT0=Mod.Controller Connected,
  Sensor *demand_source_bit1_sensor = new Sensor(); //BIT1=Heat demand from Mod.Controller,
  Sensor *demand_source_bit2_sensor = new Sensor(); //BIT2=Heat demand from on/off controller,
  Sensor *demand_source_bit3_sensor = new Sensor(); //BIT3=Frost Protection,
  Sensor *demand_source_bit4_sensor = new Sensor(); //BIT4=DHW Eco,
  Sensor *demand_source_bit5_sensor = new Sensor(); //BIT5=DHW Blocking,
  Sensor *demand_source_bit6_sensor = new Sensor(); //BIT6=Anti Legionella
  Sensor *demand_source_bit7_sensor = new Sensor(); //BIT7=DHW Heat Demand

  Sensor *input_bit0_sensor = new Sensor(); //BIT0=Shudown Input,
	Sensor *input_bit1_sensor = new Sensor(); //BIT1=Release Input,
	Sensor *input_bit2_sensor = new Sensor(); //BIT2=Ionisation,
	Sensor *input_bit3_sensor = new Sensor(); //BIT3=Flow Switch detecting DHW,
	Sensor *input_bit5_sensor = new Sensor(); //BIT5=Min Gas Pressure,
	Sensor *input_bit6_sensor = new Sensor(); //BIT6=CH Enable,
	Sensor *input_bit7_sensor = new Sensor(); //BIT7=DHW Enable

  Sensor *valve_bit0_sensor = new Sensor(); //BIT0=Gas Valve,
  Sensor *valve_bit2_sensor = new Sensor(); //BIT2=Ignition,
  Sensor *valve_bit3_sensor = new Sensor(); //BIT3=3-Way valve position,
  Sensor *valve_bit4_sensor = new Sensor(); //BIT4=Ext.3-Way Valve,
  Sensor *valve_bit6_sensor = new Sensor(); //BIT6=Ext. Gas Valve

  Sensor *pump_bit0_sensor = new Sensor(); //BIT0=Pump,
  Sensor *pump_bit1_sensor = new Sensor(); //BIT1=Calorifier Pump,
  Sensor *pump_bit2_sensor = new Sensor(); //BIT2=Ext.CH Pump,
  Sensor *pump_bit4_sensor = new Sensor(); //BIT4=Status Report,
  Sensor *pump_bit7_sensor = new Sensor(); //BIT7=Opentherm SmartPower

  Sensor *state_sensor = new Sensor();
  Sensor *lockout_sensor = new Sensor();
  Sensor *blocking_sensor = new Sensor();
  Sensor *sub_state_sensor = new Sensor();

  Sensor *hydro_pressure_sensor = new Sensor();
  Sensor *hru_sensor = new Sensor();
  Sensor *control_temp_sensor = new Sensor();
  Sensor *dhw_flowrate_sensor = new Sensor();

  //counter data sensors 1

	Sensor *hours_run_pump_sensor = new Sensor();
	Sensor *hours_run_3way_sensor = new Sensor();
	Sensor *hours_run_ch_sensor = new Sensor();
	Sensor *hours_run_dhw_sensor = new Sensor();

	Sensor *power_supply_aval_hours_sensor = new Sensor();
	Sensor *pump_starts_sensor = new Sensor();
	Sensor *number_of3way_valce_cycles_sensor = new Sensor();
	Sensor *burner_start_dhw_sensor = new Sensor();

  //counter data sensors 2
	Sensor *total_burner_start_sensor = new Sensor();
	Sensor *failed_burner_start_sensor = new Sensor();
	Sensor *number_flame_loss_sensor = new Sensor();


  Dietrich(UARTComponent *parent) : PollingComponent(15000), UARTDevice(parent) {}

  bool sem_reading_data = false;
  bool sem_read_all = true;
  int counter_timer = 99;

  byte sample[10] =    {0x02, 0xFE, 0x01, 0x05, 0x08, 0x02, 0x01, 0x69, 0xAB, 0x03 };
  byte counter1[10] =  {0x02, 0xFE, 0x00, 0x05, 0x08, 0x10, 0x1C, 0x98, 0xC2, 0x03 };
  byte counter2[10] =  {0x02, 0xFE, 0x00, 0x05, 0x08, 0x10, 0x1D, 0x59, 0x02, 0x03 };

  void array_to_string(byte array[], unsigned int len, char buffer[]) {
    for (unsigned int i = 0; i < len; i++)
    {
        byte nib1 = (array[i] >> 4) & 0x0F;
        byte nib2 = (array[i] >> 0) & 0x0F;
        buffer[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
        buffer[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
    }
    buffer[len*2] = '\0';
  }

  float signedFloat(float avalue) {
	  float f = avalue;
    if (f>32768) f = f-65536;
    return f;
  }


  void getSample() {
    byte readdata[80];
    char str[80] = "";

    //ESP_LOGD("custom", "read sample");

    write_array(sample,sizeof(sample));
    delay(250);

    int n=0;
    while(available()) {
      readdata[n] = read();
      n++;
    }

    if (readdata[0]==2 && readdata[1]==1 && readdata[2]==254) {//add crc check

        int bits = 0;

        if (flow_temp_sensor->get_name().empty()==0) flow_temp_sensor->publish_state(signedFloat((readdata[8]*256)+readdata[7])*0.01); delay(100); //delay for esphome to not disconnect api
        if(return_temp_sensor->get_name().empty()==0) return_temp_sensor->publish_state(signedFloat((readdata[10]*256)+readdata[9])*0.01); delay(100); //delay for esphome to not disconnect api
        if(dhw_in_temp_sensor->get_name().empty()==0) dhw_in_temp_sensor->publish_state(signedFloat((readdata[12]*256)+readdata[11])*0.01); delay(100); //delay for esphome to not disconnect api
        if(outside_temp_sensor->get_name().empty()==0) outside_temp_sensor->publish_state(signedFloat((readdata[14]*256)+readdata[13])*0.01); delay(100); //delay for esphome to not disconnect api
        if(calorifier_temp_sensor->get_name().empty()==0) calorifier_temp_sensor->publish_state(signedFloat((readdata[16]*256)+readdata[15])*0.01); delay(100); //delay for esphome to not disconnect api
        if(boiler_control_temp_sensor->get_name().empty()==0) boiler_control_temp_sensor->publish_state(signedFloat((readdata[20]*256)+readdata[19])*0.01); delay(100); //delay for esphome to not disconnect api
        if(room_temp_sensor->get_name().empty()==0) room_temp_sensor->publish_state(signedFloat((readdata[22]*256)+readdata[21])*0.01); delay(100); //delay for esphome to not disconnect api
        if(ch_setpoint_sensor->get_name().empty()==0) ch_setpoint_sensor->publish_state(signedFloat((readdata[24]*256)+readdata[23])*0.01); delay(100); //delay for esphome to not disconnect api
        if(dhw_setpoint_sensor->get_name().empty()==0) dhw_setpoint_sensor->publish_state(signedFloat((readdata[26]*256)+readdata[25])*0.01); delay(100); //delay for esphome to not disconnect api
        if(room_temp_setpoint_sensor->get_name().empty()==0) room_temp_setpoint_sensor->publish_state(signedFloat((readdata[28]*256)+readdata[27])*0.01); delay(100); //delay for esphome to not disconnect api

        if (sem_read_all) {

					if(fan_speed_setpoint_sensor->get_name().empty()==0) fan_speed_setpoint_sensor->publish_state(signedFloat((readdata[30]*256)+readdata[29])); delay(100); //delay for esphome to not disconnect api
					if(fan_speed_sensor->get_name().empty()==0) fan_speed_sensor->publish_state(signedFloat((readdata[32]*256)+readdata[31])); delay(100); //delay for esphome to not disconnect api
					if(ionisation_current_sensor->get_name().empty()==0) ionisation_current_sensor->publish_state(readdata[33]); delay(100); //delay for esphome to not disconnect api
					if(internal_setpoint_sensor->get_name().empty()==0) internal_setpoint_sensor->publish_state(signedFloat((readdata[35]*256)+readdata[34])*0.01); delay(100); //delay for esphome to not disconnect api
					if(available_power_sensor->get_name().empty()==0) available_power_sensor->publish_state(readdata[36]); delay(100); //delay for esphome to not disconnect api
					if(pump_percentage_sensor->get_name().empty()==0) pump_percentage_sensor->publish_state(readdata[37]); delay(100); //delay for esphome to not disconnect api
					if(desired_max_power_sensor->get_name().empty()==0) desired_max_power_sensor->publish_state(readdata[39]); delay(100); //delay for esphome to not disconnect api
					if(actual_power_sensor->get_name().empty()==0) actual_power_sensor->publish_state(readdata[40]); delay(100); //delay for esphome to not disconnect api

					bits = readdata[43];
					if(demand_source_bit0_sensor->get_name().empty()==0) demand_source_bit0_sensor->publish_state(bitRead(bits, 0)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit1_sensor->get_name().empty()==0) demand_source_bit1_sensor->publish_state(bitRead(bits, 1)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit2_sensor->get_name().empty()==0) demand_source_bit2_sensor->publish_state(bitRead(bits, 2)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit3_sensor->get_name().empty()==0) demand_source_bit3_sensor->publish_state(bitRead(bits, 3)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit4_sensor->get_name().empty()==0) demand_source_bit4_sensor->publish_state(bitRead(bits, 4)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit5_sensor->get_name().empty()==0) demand_source_bit5_sensor->publish_state(bitRead(bits, 5)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit6_sensor->get_name().empty()==0) demand_source_bit6_sensor->publish_state(bitRead(bits, 6)); delay(100); //delay for esphome to not disconnect api
					if(demand_source_bit7_sensor->get_name().empty()==0) demand_source_bit7_sensor->publish_state(bitRead(bits, 7)); delay(100); //delay for esphome to not disconnect api

					bits = readdata[44];
					if(input_bit0_sensor->get_name().empty()==0) input_bit0_sensor->publish_state(bitRead(bits, 0)); delay(100); //delay for esphome to not disconnect api
					if(input_bit1_sensor->get_name().empty()==0) input_bit1_sensor->publish_state(bitRead(bits, 1)); delay(100); //delay for esphome to not disconnect api
					if(input_bit2_sensor->get_name().empty()==0) input_bit2_sensor->publish_state(bitRead(bits, 2)); delay(100); //delay for esphome to not disconnect api
					if(input_bit3_sensor->get_name().empty()==0) input_bit3_sensor->publish_state(bitRead(bits, 3)); delay(100); //delay for esphome to not disconnect api
					if(input_bit5_sensor->get_name().empty()==0) input_bit5_sensor->publish_state(bitRead(bits, 5)); delay(100); //delay for esphome to not disconnect api
					if(input_bit6_sensor->get_name().empty()==0) input_bit6_sensor->publish_state(bitRead(bits, 6)); delay(100); //delay for esphome to not disconnect api
					if(input_bit7_sensor->get_name().empty()==0) input_bit7_sensor->publish_state(bitRead(bits, 7)); delay(100); //delay for esphome to not disconnect api

					bits = readdata[45];
					if(valve_bit0_sensor->get_name().empty()==0) valve_bit0_sensor->publish_state(bitRead(bits, 0)); delay(100); //delay for esphome to not disconnect api
					if(valve_bit2_sensor->get_name().empty()==0) valve_bit2_sensor->publish_state(bitRead(bits, 2)); delay(100); //delay for esphome to not disconnect api
					if(valve_bit3_sensor->get_name().empty()==0) valve_bit3_sensor->publish_state(bitRead(bits, 3)); delay(100); //delay for esphome to not disconnect api
					if(valve_bit4_sensor->get_name().empty()==0) valve_bit4_sensor->publish_state(bitRead(bits, 4)); delay(100); //delay for esphome to not disconnect api
					if(valve_bit6_sensor->get_name().empty()==0) valve_bit6_sensor->publish_state(bitRead(bits, 6)); delay(100); //delay for esphome to not disconnect api

					bits = readdata[46];
					if(pump_bit0_sensor->get_name().empty()==0) pump_bit0_sensor->publish_state(bitRead(bits, 0)); delay(100); //delay for esphome to not disconnect api
					if(pump_bit1_sensor->get_name().empty()==0) pump_bit1_sensor->publish_state(bitRead(bits, 1)); delay(100); //delay for esphome to not disconnect api
					if(pump_bit2_sensor->get_name().empty()==0) pump_bit2_sensor->publish_state(bitRead(bits, 2)); delay(100); //delay for esphome to not disconnect api
					if(pump_bit4_sensor->get_name().empty()==0) pump_bit4_sensor->publish_state(bitRead(bits, 4)); delay(100); //delay for esphome to not disconnect api
					if(pump_bit7_sensor->get_name().empty()==0) pump_bit7_sensor->publish_state(bitRead(bits, 7)); delay(100); //delay for esphome to not disconnect api
        }

        state_sensor->publish_state(readdata[47]); delay(200); //delay for esphome to not disconnect api
        lockout_sensor->publish_state(readdata[48]); delay(200); //delay for esphome to not disconnect api
        blocking_sensor->publish_state(readdata[49]); delay(200); //delay for esphome to not disconnect api
        sub_state_sensor->publish_state(readdata[50]); delay(200); //delay for esphome to not disconnect api

        if (sem_read_all) {
					if(hydro_pressure_sensor->get_name().empty()==0) hydro_pressure_sensor->publish_state(readdata[56]); delay(100); //delay for esphome to not disconnect api

					bits = readdata[57];
					if(hru_sensor->get_name().empty()==0) hru_sensor->publish_state(bitRead(bits, 1)); delay(100); //delay for esphome to not disconnect api

					if(control_temp_sensor->get_name().empty()==0) control_temp_sensor->publish_state(signedFloat((readdata[59]*256)+readdata[58])*0.01); delay(100); //delay for esphome to not disconnect api
					if(dhw_flowrate_sensor->get_name().empty()==0) dhw_flowrate_sensor->publish_state(signedFloat((readdata[61]*256)+readdata[60])*0.01); delay(100); //delay for esphome to not disconnect api
        }

        sem_read_all=!sem_read_all;

    }
    else {
        ESP_LOGD("custom", "crc error");
    }

    array_to_string(readdata, 80, str);
    ESP_LOGD("custom", "sample data: %s", str);

  }

  void getCounter() {
    byte readdata[28];
    char str[28] = "";

    write_array(counter1,sizeof(counter1));
    delay(150);

    int n=0;
    while(available()) {
      readdata[n] = read();
      n++;
    }

    if (readdata[0]==2 && readdata[1]==0 && readdata[2]==254) {//add crc check

      if(hours_run_pump_sensor->get_name().empty()==0) hours_run_pump_sensor->publish_state(((readdata[7]*256)+readdata[8])*2); delay(100); //delay for esphome to not disconnect api
      if(hours_run_3way_sensor->get_name().empty()==0) hours_run_3way_sensor->publish_state(((readdata[9]*256)+readdata[10])*2); delay(100); //delay for esphome to not disconnect api
      if(hours_run_ch_sensor->get_name().empty()==0) hours_run_ch_sensor->publish_state(((readdata[11]*256)+readdata[12])*2); delay(100); //delay for esphome to not disconnect api
      if(hours_run_dhw_sensor->get_name().empty()==0) hours_run_dhw_sensor->publish_state(((readdata[13]*256)+readdata[14])); delay(100); //delay for esphome to not disconnect api
      if(power_supply_aval_hours_sensor->get_name().empty()==0) power_supply_aval_hours_sensor->publish_state(((readdata[15]*256)+readdata[16])*2); delay(100); //delay for esphome to not disconnect api
      if(pump_starts_sensor->get_name().empty()==0) pump_starts_sensor->publish_state(((readdata[17]*256)+readdata[18])*8); delay(100); //delay for esphome to not disconnect api
      if(number_of3way_valce_cycles_sensor->get_name().empty()==0) number_of3way_valce_cycles_sensor->publish_state(((readdata[19]*256)+readdata[20])*8); delay(100); //delay for esphome to not disconnect api
      if(burner_start_dhw_sensor->get_name().empty()==0) burner_start_dhw_sensor->publish_state(((readdata[21]*256)+readdata[22])*8); delay(100); //delay for esphome to not disconnect api
    }

    array_to_string(readdata, 28, str);
    ESP_LOGD("custom", "counter1 data: %s", str);

    write_array(counter2,sizeof(counter2));
    delay(150);

    n=0;
    while(available()) {
      readdata[n] = read();
      n++;
    }

    if (readdata[0]==2 && readdata[1]==0 && readdata[2]==254) {//add crc check
      if(total_burner_start_sensor->get_name().empty()==0) total_burner_start_sensor->publish_state(((readdata[7]*256)+readdata[8])*8); delay(100); //delay for esphome to not disconnect api
      if(failed_burner_start_sensor->get_name().empty()==0) failed_burner_start_sensor->publish_state(((readdata[9]*256)+readdata[10])); delay(100); //delay for esphome to not disconnect api
      if(number_flame_loss_sensor->get_name().empty()==0) number_flame_loss_sensor->publish_state(((readdata[11]*256)+readdata[12])); delay(100); //delay for esphome to not disconnect api
	}

    array_to_string(readdata, 28, str);
    ESP_LOGD("custom", "counter2 data: %s", str);
  }

  void setup() override {
  }

  void update() override {

    if (sem_reading_data) return;

    sem_reading_data=true;

    counter_timer++;

    if (counter_timer>=8) {
			counter_timer=0;
			getCounter();
    }
    else
      getSample();


    sem_reading_data=false;

  }
};