pymate icon indicating copy to clipboard operation
pymate copied to clipboard

Error "No response from the MX unit"

Open francispoisson opened this issue 3 years ago • 5 comments

Hi,

I am trying to communicate with a Outback FlexMax 60 with this code and the python3 repo:

from pymate.matenet import MateNET, MateMXDevice
from time import sleep

import logging

log = logging.getLogger('mate')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

mate_bus = MateNET('COM4')         # Windows

mate_mx = MateMXDevice(mate_bus, port=0) # 0: No hub. 1-9: Hub port
mate_mx.scan()  # This will raise an exception if the device isn't found

This is what I get:

Send [Port0, Type=0x02, Addr=0x0000, Param=0x0000]
TX: [1] 0
TX: [0] b'\x02\x00\x00\x00\x00\x00\x02'
RETRY
TX: [1] 0
TX: [0] b'\x02\x00\x00\x00\x00\x00\x02'
RETRY
TX: [1] 0
TX: [0] b'\x02\x00\x00\x00\x00\x00\x02'
RETRY
Traceback (most recent call last):
  File "C:\Users\francis.poisson\Desktop\pymate\test.py", line 13, in <module>
    mate_mx.scan()  # This will raise an exception if the device isn't found
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\mx.py", line 158, in scan
    raise RuntimeError("No response from the MX unit")
RuntimeError: No response from the MX unit

And this is my scope measure: image

francispoisson avatar Jan 11 '22 18:01 francispoisson

Seems like the first byte is not being sent.

image

francispoisson avatar Jan 11 '22 18:01 francispoisson

I am now having answer from the device.

I had to make the send function in matenet_ser.py like this:

    def send(self, data):
        """
        Send a packet to the MateNET bus
        :param data: str containing the raw data to send (excluding checksum)
        """

        checksum = self._calc_checksum(data)
        footerh = checksum >> 8 & 0xFF
        footerl = checksum & 0xFF

        # First byte has bit8 set (address byte)
        self._write_9b(bytes([data[0]]), 1)

        # Rest of the bytes have bit8 cleared (data byte)
        self._write_9b(data[1:] + bytes([footerh]) + bytes([footerl]), 0)

I am now having this error:

Send [Port0, Type=0x02, Addr=0x0000, Param=0x0000]
TX: [1] b'\x00'
TX: [0] b'\x02\x00\x00\x00\x00\x00\x02'
RX: 02 00 03 00 05
Traceback (most recent call last):
  File "C:\Users\francis.poisson\Desktop\pymate\test.py", line 13, in <module>
    mate_mx.scan()  # This will raise an exception if the device isn't found
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\fx.py", line 213, in scan
    devid = super(MateFXDevice, self).scan()
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\matedevice.py", line 38, in scan
    return self.matenet.scan(self.port)
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\matenet.py", line 171, in scan
    result = self.query(0x00, port=port)
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\matenet.py", line 136, in query
    resp = self.send(MateNET.TYPE_QUERY, addr=reg, param=param, port=port, response_len=MateNET.QueryResponse.size)
  File "C:\Users\francis.poisson\Desktop\pymate\pymate\matenet\matenet.py", line 122, in send
    if ord(rxbuf[0]) & 0x80 == 0x80:
TypeError: ord() expected string of length 1, but int found

francispoisson avatar Jan 11 '22 18:01 francispoisson

I had to replace

line 122 and line 123 of matenet.py:

        if ord(rxbuf[0]) & 0x80 == 0x80:
            raise RuntimeError("Invalid command 0x%.2x" % (ord(rxbuf[0]) & 0x7F))

by

        if rxbuf[0] & 0x80 == 0x80:
            raise RuntimeError("Invalid command 0x%.2x" % (rxbuf[0] & 0x7F))

francispoisson avatar Jan 11 '22 18:01 francispoisson

Finally got it working:

with this code:

from pymate.matenet import MateNET, MateMXDevice
from time import sleep

import logging

log = logging.getLogger('mate')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

mate_bus = MateNET('COM4')         # Windows

mate_mx = MateMXDevice(mate_bus, port=0) # 0: No hub. 1-9: Hub port
mate_mx.scan()  # This will raise an exception if the device isn't found

status = mate_mx.get_status()
print(status)

This is my log:

Send [Port0, Type=0x02, Addr=0x0000, Param=0x0000]
TX: [1] b'\x00'
TX: [0] b'\x02\x00\x00\x00\x00\x00\x02'
RX: 02 00 03 00 05
Send [Port0, Type=0x04, Addr=0x0001, Param=0x0000]
TX: [1] b'\x00'
TX: [0] b'\x04\x00\x01\x00\x00\x00\x05'
RX: 03 87 82 83 00 25 3f 01 00 0a 01 10 01 d2 02 e2
MX Status:
    PV:  46.6V 2A
    Bat: 27.2V 3.7A
    Today: 1.0kWh 37Ah

francispoisson avatar Jan 11 '22 19:01 francispoisson

Great debugging! Life is a lot easier when you can hook up a scope or logic analyzer and see what's really going on at the physical layer...

I'll review your code and merge it in. Hopefully I can find some time next month to merge the python3 branch into master, it shouldn't require too much more to tidy it up.

Thanks!

jorticus avatar Jan 14 '22 23:01 jorticus