vpathuis / ultraheat

MIT License
5 stars 3 forks source link

"Can't connect" to serial #10

Open SebastianATgit opened 1 year ago

SebastianATgit commented 1 year ago

Hi, I tried the integration with an "Hichi IR Sensor" that is connected via USB an has an Silicon CP2102 USB to UART chip. While using this device for my electricity meter works fine, ist doesn't work with this integration. What type of IR Reader is tested? ttyUSB0

vpathuis commented 1 year ago

Hi @SebastianATgit, thank you for submitting this. I'm using a Silicon Labs CP2104 myself. I don't know why the CP2102 wouldn't work (both are cp210x). It could be something small, timing, baudrate, things like that. Or perhaps even unrelated to the device type. I'd be willing to send you some test code to see if we could get it to work, or al least find out why it won't. How familiar are you with running some python / looking up logs etc?

SebastianATgit commented 1 year ago

Hi, I tried it again and got the following in the log: -> I don't know wheather it's a problem connecting the heat meter or connect to the serial.. By the way I was in contact with the manufacturer and they told me, my T-330 would not work same as the T-550..

2022-10-24 17:43:52.133 WARNING (MainThread) [homeassistant.setup] Setup of homematic is taking over 10 seconds. 2022-10-24 17:45:37.454 ERROR (SyncWorker_0) [ultraheat_api.ultraheat_reader] No model could be read 2022-10-24 17:45:37.485 WARNING (MainThread) [homeassistant.components.landisgyr_heat_meter.config_flow] Failed read data from: /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0031-if00-port0. No model could be read 2022-10-24 17:47:33.816 ERROR (SyncWorker_8) [ultraheat_api.ultraheat_reader] No model could be read 2022-10-24 17:47:33.830 WARNING (MainThread) [homeassistant.components.landisgyr_heat_meter.config_flow] Failed read data from: /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0031-if00-port0. No model could be read 2022-10-24 17:47:44.315 ERROR (SyncWorker_0) [ultraheat_api.ultraheat_reader] No model could be read 2022-10-24 17:47:44.318 WARNING (MainThread) [homeassistant.components.landisgyr_heat_meter.config_flow] Failed read data from: /dev/ttyS0. No model could be read 2022-10-24 17:47:51.715 ERROR (SyncWorker_6) [ultraheat_api.ultraheat_reader] No model could be read 2022-10-24 17:47:51.734 WARNING (MainThread) [homeassistant.components.landisgyr_heat_meter.config_flow] Failed read data from: /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0031-if00-port0. No model could be read

vpathuis commented 1 year ago

Hi @SebastianATgit: if you get as far as "no model could be read", I suspect the problem is not the IR reader, but the response it gets from T-330. Probably the response from the T-330 is different. But it seems you do get a reponse of some kind. Could you add this to the configuration.yaml and try again and send me the logs?

logger:
  logs:
    homeassistant.components.landisgyr_heat_meter: debug
    custom_components.landisgyr_heat_meter: debug
    ultraheat_api: debug

I'll probably need to add more logging to really solve it, but lets try this first.

vpathuis commented 1 year ago

Alright, if you're up for it, you can also try installing the integration as a custom component. For that you will have to create a custom_components folder in the config folder. Download the integration code into a folder called "landisgyr_heat_meter". Then change the manifest.json file as follows:

{
  "domain": "landisgyr_heat_meter",
  "name": "Landis+Gyr Heat Meter",
  "config_flow": true,
  "documentation": "https://www.home-assistant.io/integrations/landisgyr_heat_meter",
  "requirements": [
    "git+https://github.com/vpathuis/uh50.git#ultraheat-api==0.5.1"
  ],
  "ssdp": [],
  "zeroconf": [],
  "homekit": {},
  "dependencies": [],
  "codeowners": ["@vpathuis"],
  "iot_class": "local_polling",
  "version": "0.0.1"
}

This will add debug logging of the raw response. I'll submit this for the core integration, but that will take a while (approvement process). Try again adding the integration and send me the logging.

danens commented 1 year ago

Any progress regarding this? I have a similar issue trying to read from my T550 Ultra heater. When I run the code from a terminal I sometimes get this error message: WARNING: everytime the unit is read, battery time will go down by about 30 minutes! Reading ... this will take some time... No model could be read Traceback (most recent call last): File "/home/daniel/uh/ultraheat/__main__.py", line 65, in <module> response_data = heat_meter_service.read() File "/home/daniel/uh/ultraheat/ultraheat_api/service.py", line 16, in read (model, raw_response) = self.reader.read() File "/home/daniel/uh/ultraheat/ultraheat_api/ultraheat_reader.py", line 24, in read return self._get_data(conn) File "/home/daniel/uh/ultraheat/ultraheat_api/ultraheat_reader.py", line 59, in _get_data model = self._wake_up(conn) File "/home/daniel/uh/ultraheat/ultraheat_api/ultraheat_reader.py", line 54, in _wake_up raise Exception("No model could be read") Exception: No model could be read

and sometime I get this message:

sudo python3 __main__.py --port /dev/ttyUSB0
WARNING: everytime the unit is read, battery time will go down by about 30 minutes!
Reading ... this will take some time...

HeatMeterResponse(model='\x7f\x7f', heat_usage_gj=None, heat_usage_mwh=None, volume_usage_m3=None, ownership_number=None, volume_previous_year_m3=None, heat_previous_year_gj=None, heat_previous_year_mwh=None, error_number=None, device_number=None, measurement_period_minutes=None, power_max_kw=None, power_max_previous_year_kw=None, flowrate_max_m3ph=None, flow_temperature_max_c=None, flowrate_max_previous_year_m3ph=None, return_temperature_max_c=None, flow_temperature_max_previous_year_c=None, return_temperature_max_previous_year_c=None, operating_hours=None, fault_hours=None, fault_hours_previous_year=None, yearly_set_day=None, monthly_set_day=None, meter_date_time=None, measuring_range_m3ph=None, settings_and_firmware=None, flow_hours=None, raw_response='')

Not sure if it's an issue with the meter or if it's the IR sender/receiver.

I use the following hardware: https://www.amazon.se/gp/product/B0B45WSK3K

lsusb -v

Bus 001 Device 005: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x10c4 Silicon Labs
  idProduct          0xea60 CP210x UART Bridge
  bcdDevice            1.00
  iManufacturer           1 Silicon Labs
  iProduct                2 CP2102N USB to UART Bridge Controller
  iSerial                 3 f29a9ca572d5eb118d70b12944d319e3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0020
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0

Thank you for the good work so far. If you have any suggestion on other IR-hardware I'm willing to test that as well. Do you know if the heater meter be encrypted in any way causing this issue?

vpathuis commented 1 year ago

Hi @danens, thanks for sharing these details. This will definitely help making the module better and more compatible.

Other users with T550 have been able to read succesfully, so something else is going on. The IR-reader seems okay to me too though.

Apparently on first contact there is a reponse (the model), but it could not be decoded. This could mean it cannot handle either the timing or the baudrate. I'll have a better look at this later. I'll see if I can add more raw output, so we can see more precicely what is received.

danens commented 1 year ago

Great, let me know if you need me to test something more.

vpathuis commented 1 year ago

Hi @danens if you pull this branch add_extra_raw_output, you can use a new tag --log DEBUG for more info. sudo python3 . --log DEBUG --port /dev/ttyUSB0

Let me know if you need any help and I'm curious for the output.

danens commented 1 year ago

Thank you! I've tested with the new branch and I got this output with a couple of runs.

$ sudo python3 . --log DEBUG --port /dev/ttyUSB0
WARNING: everytime the unit is read, battery time will go down by about 30 minutes!
Reading ... this will take some time...
DEBUG:ultraheat_api.ultraheat_reader:Initializing UltraheatReader on port: /dev/ttyUSB0
DEBUG:ultraheat_api.ultraheat_reader:Waking up Ultraheat
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
ERROR:ultraheat_api.ultraheat_reader:No model could be read
Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/daniel/extra/ultraheat/./__main__.py", line 74, in <module>
    response_data = heat_meter_service.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/service.py", line 16, in read
    (model, raw_response) = self.reader.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 24, in read
    return self._get_data(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 61, in _get_data
    model = self._wake_up(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 56, in _wake_up
    raise Exception("No model could be read")
Exception: No model could be read

$ sudo python3 . --log DEBUG --port /dev/ttyUSB0
WARNING: everytime the unit is read, battery time will go down by about 30 minutes!
Reading ... this will take some time...
DEBUG:ultraheat_api.ultraheat_reader:Initializing UltraheatReader on port: /dev/ttyUSB0
DEBUG:ultraheat_api.ultraheat_reader:Waking up Ultraheat
DEBUG:ultraheat_api.ultraheat_reader:Got: b'\x7f\x7f'
DEBUG:ultraheat_api.ultraheat_reader:Got model
DEBUG:ultraheat_api.ultraheat_reader:Receiving data
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
DEBUG:ultraheat_api.ultraheat_reader:After decoding:
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
DEBUG:ultraheat_api.ultraheat_reader:After decoding:
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
DEBUG:ultraheat_api.ultraheat_reader:After decoding:
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
DEBUG:ultraheat_api.ultraheat_reader:After decoding:
Ctrl+C

$ sudo python3 . --log DEBUG --port /dev/ttyUSB0
WARNING: everytime the unit is read, battery time will go down by about 30 minutes!
Reading ... this will take some time...
DEBUG:ultraheat_api.ultraheat_reader:Initializing UltraheatReader on port: /dev/ttyUSB0
DEBUG:ultraheat_api.ultraheat_reader:Waking up Ultraheat
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
ERROR:ultraheat_api.ultraheat_reader:No model could be read
Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/daniel/extra/ultraheat/./__main__.py", line 74, in <module>
    response_data = heat_meter_service.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/service.py", line 16, in read
    (model, raw_response) = self.reader.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 24, in read
    return self._get_data(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 61, in _get_data
    model = self._wake_up(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 56, in _wake_up
    raise Exception("No model could be read")
Exception: No model could be read

$ sudo python3 . --log DEBUG --port /dev/ttyUSB0
WARNING: everytime the unit is read, battery time will go down by about 30 minutes!
Reading ... this will take some time...
DEBUG:ultraheat_api.ultraheat_reader:Initializing UltraheatReader on port: /dev/ttyUSB0
DEBUG:ultraheat_api.ultraheat_reader:Waking up Ultraheat
DEBUG:ultraheat_api.ultraheat_reader:Got: b''
ERROR:ultraheat_api.ultraheat_reader:No model could be read
Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/daniel/extra/ultraheat/./__main__.py", line 74, in <module>
    response_data = heat_meter_service.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/service.py", line 16, in read
    (model, raw_response) = self.reader.read()
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 24, in read
    return self._get_data(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 61, in _get_data
    model = self._wake_up(conn)
  File "/home/daniel/extra/ultraheat/./ultraheat_api/ultraheat_reader.py", line 56, in _wake_up
    raise Exception("No model could be read")
Exception: No model could be read
vpathuis commented 1 year ago

Great, this gives some insights into what's going on. The second try gives a response that cannot be translated correctly. The other tries didn't even get that far. But at least there is proof of some contact. The randomness is also information.

It's possible the baudrate for your unit is different. For the UH50 the model is read at 300 baud and the data is read at 2400. It's a shame there is no manual available, so the next step will require some trial and error.

For reading the data (ultraheat_reader.py line 64) you could try and change this to one of these: 9600, 38400 or 115200 You could also try and change the baudrate for reading the model (line 30). Most likely this is any of 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200.

Question: is there a long delay (5 seconds) before the next line (Got: b'') is shown? This could suggest a timeout and no data is received during these 5 seconds.

I hope you're comfortable giving some if this a try and I'm curious what the results will be.

vpathuis commented 1 year ago

As an alternative, it's not too hard to write a small program that will try several baudrates. I'll see if I can make time for this

vpathuis commented 1 year ago

I created a small script "try_baudrates", which you can run: sudo python3 -m try_baudrates --port /dev/ttyUSB0 &> output.txt This will take some time, but I added a break on timeout, so it should be done in under 2 minutes. Is your device on batteries? Because this script will read the device 21 times

If this works, could you share the output.txt?

danens commented 1 year ago

Thank you for that! It will make it faster to test. I will try it later today.

danens commented 1 year ago

Thanks for the script. Unfortunately it crashed when it failed to read the model if no input was received. I did however manage to test all baud rates for the wake up command, but with no luck. Same kind of issue. I've tried to get some data from the serial port but has failed to do so.

To answer your question in previous comments it takes around 5 seconds before the line shows, so it most likely a timeout.

vpathuis commented 1 year ago

Mm, unlucky that you couldn't find a working baudrate for the wake up. The model (wake up) could be done without, so I can see if I can tweak it to prevent the program from stopping. If the timeout occurs on reading the model, I'm guessing the device is not actually awake and it could be the wake up sequence is different for this model. Although it did work once (sort of) .... Perhaps some more googling could shine light on this.

vpathuis commented 1 year ago

If you comment out line 61 (raise Exception), the program should not stop after failing to get a model. This will allow you to try the baudrates for reading the actual data. But I'm affraid if the wakeup times out, the rest will timeout as well ...

danens commented 1 year ago

Thank you for the help so far. I will different serial parameters to see if I can find a solution. I will also try to see if the USB serial port is working correct as well.

I've attached the output.txt file now with the Exception removed. output.txt

vpathuis commented 1 year ago

Hi, sorry for the long silence. I've been studying the protocol. It seems first contact is always at 300 baud. The response (eg !LUGCUH50) should indicate how to procede further (at what baudrate). So since that initial response is not read properly, that doesn't really help us. The T550 uses the same EN 62056-21 protocol as the UH50, so I think we're looking at the wrong problem here. I'm now thinking it could be the IR reader after all. But I'll keep digging into that as well.

danens commented 1 year ago

No worries, I've been busy as well. I think that the IR (send and receive) is working from my simple tests. At least it's sending data and receiving. I will also check with my heat supplier if it's possible that the optical IR interface is disabled on my T550. Thank you for checking on your side!

jensfischer1515 commented 1 year ago

I am also looking into getting data from my Landis+Gyr T330 Ultraheat into HomeAssistant. I already have my Landis+Gyr E220 power meter successfully integrated using Tasmota and MQTT, but my understanding is for this integration I would use some USB IR reader based on cp210x. I would like to support in debugging this setup, especially regarding the wake up procedure. As a software dev I am familiar with running/editing some python scripts.

jensfischer1515 commented 1 year ago

According to operating instructions, the T330 "is equipped with an optical interface in accordance with EN 62056-21 as standard.". This should allow the same wake-up procedure to work as for T550/UH50. Maybe it's worth looking into https://pypi.org/project/iec62056-21/?

vpathuis commented 1 year ago

It could certainly be worth the try, but indeed you'll a usb IR reader. No guarantees it will work, since it's not tested for this model. If you do buy the IR reader and get results (either good or bad), please let us know so perhaps we can work towards supporting this model.

jensfischer1515 commented 11 months ago

Finally got around buying an IR reader (Silicon Labs FTDI CP2102, recognized as "Silicon Labs CP210x UART Bridge") from eBay. With my limited Python knowledge I decided to write a script using serial.Serial myself in order to get a feel for the wake-up sequence and identification message. No matter if sending several b"\x00" or b"\x10" followed by /?!\r\n, when reading the response I always received the same wake-up sequence that I was sending!

My current assumption is: the output diode of my IR reader is directly shining into my input diode, so no real response from my UltraHeat meter is received! I will try to physically fix this by adding some light blocking elements between both diodes before continuing with my tests.

vpathuis commented 11 months ago

Thanks for the feedback! Are you using an USB device with (magnetic) optical interface / port reader, similar to what is shown if you google for EN 62056-21?

jensfischer1515 commented 11 months ago

Yes, I am using such an USB device, which is recognized via lsusb -v as:

Bus 003 Device 004: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x10c4 Silicon Labs
  idProduct          0xea60 CP210x UART Bridge
  bcdDevice            1.00
  iManufacturer           1 Silicon Labs
  iProduct                2 CP2102N USB to UART Bridge Controller
  iSerial                 3 9223f40dbf3bec119b2aa0957a0af07f
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0020
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
  (Bus Powered)

It's comparable to this offer. I might also try the Tasmota-based version (instead of the USB version), but even then the problem will be the same: finding the correct wake-up sequence in order to access the data from the UltraHeat T330.