leoshusar / 4heat-esphome

ESPHome integration for Tiemme 4Heat controllers.
MIT License
6 stars 0 forks source link

Data doesn't update in Home Assistant #3

Open jorgezazo opened 10 months ago

jorgezazo commented 10 months ago

Hi... Me... again :)

I installed all your code succesfully into an ESP8266, Home Assistant finds it and show all data. The ESP8266 is wired correctly to a MAX232 In TTL and the side of RS232 is correctly wired with the RJ11 RS232 from the stove. After reboot the ESP8266, only two data are shown: state and error

image

... but it doesn´t update after rebooting. If I disconnect the GND connector from RS232 side and connect again, more data is shown...

image

...but still no luck with updating them. Only if GND connector is disconnected and connected, data updates. Of course all input components that change power or turn off the stove doesn't work either.

Do you have any clue of what's going on?

Thank you in advance

leoshusar commented 10 months ago

Hi, great you got "something" :)

You can set debug level to verbose and it will print all sent and received commands as hex strings, that might reveal something.

logger:
  level: VERBOSE

Also can you try to add those sensors and things one by one? I have experienced similar issue - if I send some unsupported(?) command, the stove controller locks up somehow and stops responding completely. I wouldn't be surprised if this was your case too. The log should tell I think, if you look what command was sent last and didn't get a response.

leoshusar commented 10 months ago

@jorgezazo I actually think the "room thermostat state" might be the issue, if you don't have external thermostat relay connected and are using the internal one. It's the one you have never got any value for it (assumed by your screenshots).

jorgezazo commented 10 months ago

Hi again.

Problem seems to be the binary_sensor.

I left this code. No more lines below:

`external_components: source: github://leoshusar/4heat-esphome

uart: tx_pin: 1 rx_pin: 3 baud_rate: 9600

fourheat: offline_sensor: name: Stove offline

binary_sensor:

... and this are the traces:

Updating... [22:33:51][V][fourheat:212]: Sending query (index 0): 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:52][W][component:214]: Component fourheat took a long time for an operation (0.19 s). [22:33:52][W][component:215]: Components should block for at most 20-30ms. [22:33:52][W][fourheat:184]: Response timeout, retrying (0/3) [22:33:52][V][fourheat:204]: Resending data: 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:52][W][component:214]: Component fourheat took a long time for an operation (0.20 s). [22:33:52][W][component:215]: Components should block for at most 20-30ms. [22:33:52][W][fourheat:184]: Response timeout, retrying (1/3) [22:33:52][V][fourheat:204]: Resending data: 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:53][W][component:214]: Component fourheat took a long time for an operation (0.20 s). [22:33:53][W][component:215]: Components should block for at most 20-30ms. [22:33:53][W][fourheat:184]: Response timeout, retrying (2/3) [22:33:53][V][fourheat:204]: Resending data: 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:53][W][component:214]: Component fourheat took a long time for an operation (0.20 s). [22:33:53][W][component:215]: Components should block for at most 20-30ms. [22:33:53][W][fourheat:187]: Response timeout, giving up [22:33:53][W][fourheat:189]: Clearing command TX queue, because the module can reappear in an unknown state [22:33:53][D][binary_sensor:036]: 'Stove offline': Sending state ON [22:33:54][W][component:214]: Component fourheat took a long time for an operation (0.12 s). [22:33:54][W][component:215]: Components should block for at most 20-30ms. [22:33:54][V][fourheat:204]: Resending data: 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:54][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [22:33:54][W][component:215]: Components should block for at most 20-30ms. [22:33:55][V][fourheat:204]: Resending data: 08.49.33.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [22:33:55][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [22:33:55][W][component:215]: Components should block for at most 20-30ms. [22:33:56][V][fourheat:152]: Received data for J30000: 30.30.30.30.30.30.30.30.30.30.30.30 (12) [22:33:56][V][fourheat.binary_sensor:041]: 4Heat reported binary sensor J30000 is: OFF [22:33:56][D][binary_sensor:036]: 'Stove offline': Sending state OFF [22:33:56][W][component:214]: Component fourheat took a long time for an operation (0.25 s). [22:33:56][W][component:215]: Components should block for at most 20-30ms. [22:33:56][W][fourheat:028]: Received incomplete data: 00

leoshusar commented 10 months ago

Ahh, there is no 30000 command, it was just an example without using any specific one :)

You can find an incomplete list of available commands here. Usually those starting with 3 are readonly and prefixed with I/J (like sensors) and those starting with 2 are usually read/write and prefixed with A/B.

jorgezazo commented 10 months ago

Yepe I already notice it and change it. But now, this are the traces:

[23:04:04][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:04][W][component:215]: Components should block for at most 20-30ms. [23:04:05][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:05][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:05][W][component:215]: Components should block for at most 20-30ms. [23:04:06][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:06][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:06][W][component:215]: Components should block for at most 20-30ms. [23:04:07][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:07][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:07][W][component:215]: Components should block for at most 20-30ms. [23:04:08][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:08][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:08][W][component:215]: Components should block for at most 20-30ms. [23:04:09][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:09][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:09][W][component:215]: Components should block for at most 20-30ms. [23:04:10][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:10][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:10][W][component:215]: Components should block for at most 20-30ms. [23:04:11][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:12][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:12][W][component:215]: Components should block for at most 20-30ms. [23:04:13][V][fourheat:204]: Resending data: 08.41.32.30.33.36.34.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [23:04:13][W][component:214]: Component fourheat took a long time for an operation (0.14 s). [23:04:13][W][component:215]: Components should block for at most 20-30ms.

Hundreds of these lines...

leoshusar commented 10 months ago

Can you try to power off and on your stove? This always helped on mine when it stopped responding for any reason.

Also can you try a command that should definitely work, like the state - 30001?

jorgezazo commented 10 months ago

Ok... I think the one that was f*cking me was power select. It blocks all and no data was received any more. And one more thing. Setting a binary_sensor is mandatory in any way? If I don't declare any, the compilation fails... that was happening with the ESP32

jorgezazo commented 10 months ago

Can you try to power off and on your stove? This always helped on mine when it stopped responding for any reason.

Also can you try a command that should definitely work, like the state - 30001?

30001 is the only one that works always... but just one time after it got blocked

leoshusar commented 10 months ago

Yeah I don't know why it stops responding when you send a command it doesn't want to respond to. They are complicating our reverse engineering :) But it was happening to me too when developing and I didn't figure out a way to "unlock" it other than turn off and on again.

I see the issue with binary sensor now. I made the offline sensor mandatory in cpp code by including binary_sensor.h even though it is not supposed to be mandatory. I'll fix it soon.

jorgezazo commented 10 months ago

Definetely, if I try to invoque the command B20364, everything brokes... If I use a sensor_text or a sensor to read data, everything stops. I can read other data, but can't modify anythig in the stove... I leave it for today, Is late and this is very time consuming.

leoshusar commented 10 months ago

There is still a possibility your stove uses different commands, when one works and other doesn't.

I found this fork with different commands, you can maybe try to send something from there.

jorgezazo commented 10 months ago

Guess what? I'm buying a 4Heat module just now... I'll build your ESP32 based logger and start to analyze traffic... You must be right and commands used by my stove are not the right ones and the fork's data you provided neither...

¿Could you publish some photos how did you build your analyzer showing the pin connections? Even the 6P4C to the main board

leoshusar commented 10 months ago

Hey, I've got one idea. Can you try to send these three commands and send me what it responds?

C10000000000000000
E10001000000000000
G10000000000000000

You can use button component for it like:

button:
  - name: Button C
    platform: fourheat
    datapoint: C10000
    press_data: '000000000000'
  - name: Button E
    platform: fourheat
    datapoint: E10001
    press_data: '000000000000'
  - name: Button G
    platform: fourheat
    datapoint: G10000
    press_data: '000000000000'

I'll create the analyzer schematic later.

jorgezazo commented 10 months ago

I pressed it in order C, D, E and these are the traces:

[16:22:52][V][fourheat:152]: Received data for D10000SYEVO: 30.30.30.30.35.34.34 (7) [16:22:52][D][fourheat:164]: Listener for D10000SYEVO not found. Data: 30.30.30.30.35.34.34 (7) [16:22:52][V][fourheat:209]: Sending data: 08.45.31.30.30.30.31.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [16:22:52][W][component:214]: Component fourheat took a long time for an operation (0.44 s). [16:22:52][W][component:215]: Components should block for at most 20-30ms. [16:22:52][V][fourheat:152]: Received data for F10001: 30.30.30.30.30.30.30.30.30.30.30.31 (12) [16:22:52][D][fourheat:164]: Listener for F10001 not found. Data: 30.30.30.30.30.30.30.30.30.30.30.31 (12) [16:22:52][V][fourheat:209]: Sending data: 08.47.31.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.30.0D (20) [16:22:52][W][component:214]: Component fourheat took a long time for an operation (0.47 s). [16:22:52][W][component:215]: Components should block for at most 20-30ms. [16:22:53][V][fourheat:152]: Received data for H10202: 31.34.30.38.32.30.30.30.30.30.34.31 (12) [16:22:53][D][fourheat:164]: Listener for H10202 not found. Data: 31.34.30.38.32.30.30.30.30.30.34.31 (12)

leoshusar commented 10 months ago

I thought I can trick my WiFi module into thinking it's talking with your board model so it would maybe tell me something, but without success. Also when I looked into the firmware binary, there were no other commands than what we know already.

Here is the very simple connection I used: image

This connector I desoldered from an old modem I had laying in the "useful-garbage" box: image

and I made my own cable, I bought 6P4C crimp connectors and pushed the pins carefully with a flat screwdriver, worked perfectly. I didn't want to buy crimpers for this one time thing. I'm sure you can figure something out for yourself.

Pinout is here - the only thing that matters is GND, you can connect RX and TX however you want, since they both go into the ESP RX.

Here is the ESPHome code I posted in the HA community:

uart:
  - id: uart_1
    rx_pin: 3
    baud_rate: 9600
    rx_buffer_size: 4608
    debug:
      dummy_receiver: true
      after:
        bytes: 4096
        timeout: 1s
      sequence:
        - lambda: UARTDebug::log_string(direction, bytes);
  - id: uart_2
    rx_pin: 16
    baud_rate: 9600
    rx_buffer_size: 4608
    debug:
      dummy_receiver: true
      after:
        bytes: 4096
        timeout: 1s
      sequence:
        - lambda: UARTDebug::log_string(direction, bytes);

For decoding I also used this short Python code

from typing import List

data: List[str] = []

with open('input.txt', 'r') as f:
    for line in f:
        data.append(line)

# convert to string
data = [bytes.fromhex(x.replace(':', '')).decode('utf-8') for x in data]

# save to file
with open('output.txt', 'w') as f:
    f.write('\n\n'.join(data))

it expects input to have only bytes separated by colon like:

08:43:31:30:30:30:30:3...
08:44:31:30:30:30:30:5...
08:49:33:30:30:30:31:3..

you can copy the log from ESPHome and remove log prefixes.

jorgezazo commented 10 months ago

Thanks a lot... I will build the logger ASAP and let you know how it goes... I'll use js code... python is not my language XD

leoshusar commented 9 months ago

One more thing I remembered now. Try this (Python code again :D):

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
try:
    s.connect(('1.2.3.4', 80))
    s.send(b'["SEL","0"]')
    response = s.recv(1024)
    decoded = response.decode()
    print(decoded)

finally:
    try:
        s.close()
    except:
        pass

and replace 1.2.3.4 with IP of your WiFi module. This should give you all the same data that the Android app receives.

jorgezazo commented 9 months ago

Okey... I got the power command... B20816 Here are the traces:

["SEL","17","J30001000000000005","J30002000000000000","J30005000000000188","J30006000000000000","B20816000000000003","J30012000000000000","J30017000000000056","B20801000000000001","J30020000000001914","J30026000000000286","J30038000000000000","B20180000000000065","B20211000000000005","B20301000000000001","B20211000000000005","B20005000000000065","B20006000000000080"]

THANK YOUUUUUUU!!!!

leoshusar commented 9 months ago

So you are able to query it and control it too? That's great!

And thanks for the data. I can make some file with most common datapoints for different controllers.

jorgezazo commented 9 months ago

1 more thing. The only that it's missing is the on & off commands. The ones that you found are useless in this stove and looking for them in the data showed by the 4Heat module donesn't work, so maybe I would have to build the logger to find them. Any idea to avoid it?

jorgezazo commented 9 months ago

Ok, no worries... the commands are the same than in your code: on_datapoint: J30253, off_datapoint: J30254

jorgezazo commented 9 months ago

Hi again.

I found how to set minimum and maximum boiler temp. To set minimum water temp is B20005 and maximum B20006. Then with B20180 the target boiler temp can be set. Is there any possibility of feeding min_value and max_value of number component with a lambda to get values from minimum and maximum commands instead of stay fixed?

jorgezazo commented 9 months ago

Aaaaaand me again.

I have found the reason of so many ,many, many traces in logging of type "Component fourheat took a long time for an operation (0.XX s)." It's because the ESP is using the UART0 that RS232 uses too... so if logging, not sending/ transmittting and all ends blocking, so after a intensive research, I found a logger option to use UART1 wich uses pin GPIO2 and only transmission is allowed... perfect for logger so I change the logger part of configuration YAML:

logger:
  level: DEBUG
  hardware_uart: UART1
leoshusar commented 9 months ago

Good to hear you are advancing!

I've already seen queries for getting min and max values, but I didn't consider it important enough haha, so for now they can only be set manually. But I'll look into it.

Thanks for the UART reminder, I will add a notice that UART0 is used by logger by default. For example Tuya component suggests to simply disable logging to serial port, so I might just do the same.

jorgezazo commented 9 months ago

The boiler temperature range is because this stove has the minimum water temperature set at 65 degrees centigrades. At 61 starts the histeresys to avoid reaching the 65 target. But is not very well done because the interchange heating chamber is too small and most of the heat goes out by the exahust pipe (it reachs 240 degrees most part of the time) So one solution to limit the pellet comsumption is reduce this 65 degrees target to 60. With only this meassure I save 33% of pellets... but at the stove ignition start time, this temperature is too low because I haven´t found the open water pump command and open it is fixed at 55 degrees and close at 52 degrees and to heat all the circuit's water it lasts a lot because temperature is too low at the beginning... so I have to start the ignition with the water target at 65 degrees and change it after 1 hour or so to save pellets... As you can see this is a whole world of stuff.. but is funny :)

leoshusar commented 9 months ago

I meant I didn't consider setting number min and max dynamically, so I initially left it at manual setting.

Yeah, that sounds like fun times :D I have my water temp set to 60 and power at 1, because it's still not freezing outside here. When it's colder outside, I raise the water temp and set power to 2 or 3. This worked quite good last year.

Also when you have time, can you share your findings in the HA community thread? I think maxgu would be interested in them.

jorgezazo commented 9 months ago

You are right and I was waiting to have a fully functional ESP... And I think now I have.

image

Now have to solder all components into a breadboard and find an adequate cage... or even a little screen to show data and maybe adding a relay to attach to thermostatic "port" of the stove...

Yeah is funny!!!

leoshusar commented 9 months ago

I think you can safely run update interval at 5 seconds if you want - at least mine doesn't seem to have any issue with that. I set default to 15s just to be sure, I didn't know how the controller will react, since the official module also doesn't query so often.

And you can also have the state switch to be off when it's extinguishing, using something like this:

parser: |-
  auto size = data.size();
  auto last = data[size - 1];

  auto off =
    data[size - 2] == '0' &&
    (last == '0' || last == '7');

  return !off;

I didn't like it when I switch it off it goes back to "on" until the state is completely off.

But these are already just small details. Glad you got it working!

jorgezazo commented 9 months ago

I wrote a comment to say logger doesn´t work... Forget it... it started working after a shell for ESP32 was removed... something was wrong with it...

I'll try to block the stove and I'll send you the result of the logger...

Thank you very much