kasbert / epsolar-tracer

Tools for EPsolar Tracer BN solar charge controller
Apache License 2.0
121 stars 76 forks source link

info.py on RPi3 asks for self.client.timeout #52

Open gjmkoper opened 1 year ago

gjmkoper commented 1 year ago

Dear all I have successfully installed the RS485 driver (persistent). If someone is interested I can share the instructions. I also successfully ran readall.py, following https://mitchross09.medium.com/solar-energy-monitoring-with-raspberry-pi-and-node-red-ed59e287cdd4 I moved on to info.py and before that installed pymodbus using pip install -U pymodbus. Now running this file gives an error

Traceback (most recent call last): File "info.py", line 19, in response = client.read_device_info() File "/home/pi/epsolar-tracer/pyepsolartracer/client.py", line 42, in read_device_info response = self.client.execute(request) File "/home/pi/.local/lib/python2.7/site-packages/pymodbus/client/sync.py", line 109, in execute return self.transaction.execute(request) File "/home/pi/.local/lib/python2.7/site-packages/pymodbus/transaction.py", line 178, in execute broadcast=broadcast File "/home/pi/.local/lib/python2.7/site-packages/pymodbus/transaction.py", line 274, in _transact size = self._send(packet) File "/home/pi/.local/lib/python2.7/site-packages/pymodbus/transaction.py", line 309, in _send return self.client.framer.sendPacket(packet) File "/home/pi/.local/lib/python2.7/site-packages/pymodbus/framer/rtu_framer.py", line 263, in sendPacket timeout = start + self.client.timeout AttributeError: 'NoneType' object has no attribute 'timeout'

I tried adding a timeout-parameter to the Modbus call in pyepsolartracer/client.py but that did not help. Any suggestions?

kasbert commented 1 year ago

I upgraded the code to Python 3 and latest pymodbus. Please give it a try.

gjmkoper commented 1 year ago

I cloned again into a temp directory, no change: still same error.

kasbert commented 1 year ago

I forgot to push the changes to github. How about now ?

gjmkoper commented 1 year ago

That helped a bit. I assumed the device driver XRUSB0 was not affected.

What I did:

$ python info.py Traceback (most recent call last): File "info.py", line 3, in from pyepsolartracer.client import EPsolarTracerClient File "/home/pi/temp/pyepsolartracer/client.py", line 4, in from pymodbus.client import ModbusSerialClient as ModbusClient ImportError: cannot import name ModbusSerialClient

Changed pymodbus.client into pymodbus.client.sync in client.py

$ python info.py Traceback (most recent call last): File "info.py", line 5, in from pymodbus.client import ModbusSerialClient as ModbusClient ImportError: cannot import name ModbusSerialClient

Then changed pymodbus.client into pymodbus.client.sync and /dev/ttyUSB0 into /dev/ttyXRUSB0 in info.py

$ python info.py ('Manufacturer:', "'EPsolar Tech co., Ltd'") ('Model:', "'TcerAN4210'") ('Version:', "'V02.00+V01.22'") INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input voltage' Charging equipment rated input voltage = None INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input voltage' Charging equipment rated input voltage = None INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input current' Charging equipment rated input current = None INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input power' Charging equipment rated input power = None INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input power L' Charging equipment rated input power L = None : :

readall.py gave, after similar adaptations, comparable output, this was also with the previous version of the software.

In conclusion, I think data is received such as following "Manufacturer:" but there is something wrong in the conversion of the data. Will go along but maybe you have a good suggestion?

gjmkoper commented 1 year ago

An update on readall.py.

After the following changes

there is intelligent response

{0: 'EPsolar Tech co., Ltd', 1: 'TcerAN4210', 2: 'V02.00+V01.22'} () {'name': 'Charging equipment rated input voltage', 'address': 12288} ('read_input_registers:', 10000) ('read_holding_registers:', 'Exception Response(131, 3, IllegalAddress)') () {'name': 'Charging equipment rated input current', 'address': 12289} ('read_input_registers:', 4000) ('read_holding_registers:', 'Exception Response(131, 3, IllegalAddress)') () {'name': 'Charging equipment rated input power', 'address': 12290} ('read_input_registers:', 38464) ('read_holding_registers:', 'Exception Response(131, 3, IllegalAddress)') () {'name': 'Charging equipment rated input power L', 'address': 12290} ('read_input_registers:', 38464) ('read_holding_registers:', 'Exception Response(131, 3, IllegalAddress)') () {'name': 'Charging equipment rated input power H', 'address': 12291} ('read_input_registers:', 1) ('read_holding_registers:', 'Exception Response(131, 3, IllegalAddress)') : :

Question: do these holding registers make sense, are they actually present?

kasbert commented 1 year ago

You may have python2 as default "python". Try with "python3". You may need to install pymodbus, too "pip3 install pymodbus".

All registers are present in my unit. The mock data in test/testdata.py was recorded from real device.

gjmkoper commented 1 year ago

No difference between python 2 and python 3 as far as I can see.

I made info.py to work by changing "slave = self.unit" to "unit = self.unit" in client.py

Thanks for the help.

gjmkoper commented 1 year ago

The fact that there is no difference in python 2 or 3 is due to the first line

!/usr/bin/env python3

kasbert commented 1 year ago

It makes a difference if you run "python ./info.py" instead of "./info.py".

If I use mock data

kasper@gridbug:~/projects/solar/epsolar-tracer$ git diff info.py
diff --git a/info.py b/info.py
index 8565ec8..276ed35 100755
--- a/info.py
+++ b/info.py
@@ -2,8 +2,8 @@

 from pyepsolartracer.client import EPsolarTracerClient
 from pyepsolartracer.registers import registers,coils
-from pymodbus.client import ModbusSerialClient as ModbusClient
-#from test.testdata import ModbusMockClient as ModbusClient
+#from pymodbus.client import ModbusSerialClient as ModbusClient
+from test.testdata import ModbusMockClient as ModbusClient
 import serial.rs485

 # configure the client logging

I get

kasper@gridbug:~/projects/solar/epsolar-tracer$ python3 info.py
Manufacturer: b'EPsolar Tech co., Ltd'
Model: b'Tracer2215BN'
Version: b'V02.05+V07.12'
Charging equipment rated input voltage = 150.0V
Charging equipment rated input voltage = 150.0V
Charging equipment rated input current = 20.0A
INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated input power'
Charging equipment rated input power = None
Charging equipment rated input power L = -135.36W
Charging equipment rated input power H = 0.0W
Charging equipment rated output voltage = 24.0V
Charging equipment rated output current = 20.0A
INFO:pyepsolartracer.registers:No value for register 'Charging equipment rated output power'
Charging equipment rated output power = None
Charging equipment rated output power L = -155.36W
Charging equipment rated output power H = 0.0W
Charging mode = 2

And my pymodbus version is 3.2.0

kasper@gridbug:~/projects/solar/epsolar-tracer$ pip3 show pymodbus
Name: pymodbus
Version: 3.2.0
Summary: A fully featured modbus protocol stack in python
Home-page: https://github.com/pymodbus-dev/pymodbus/
Author: "Galen Collins, Jan Iversen"
Author-email: 
License: BSD-3-Clause
Location: /usr/local/lib/python3.10/dist-packages
Requires: setuptools
Required-by: 
gjmkoper commented 1 year ago

True! However, I am happy now that it works. Even if this is with changes that you do not need. Later we may look into how the differences come about. For now, I wish to continue with what I have so that my solar data logging can start ...

kasbert commented 1 year ago

Nice.

Would you do me a favor and test the other kernel driver? In linux_usb_serial directory there is a modified linux kernel tree driver. The device will be /dev/ttyUSB0 . It requires that the python code has line

    serialclient.socket.rs485_mode = serial.rs485.RS485Settings()

To install:

sudo rmmod xr_usb_serial_common
cd linux_usb_serial/
make
sudo rmmod xr_serial
sudo insmod ./xr_serial.ko 
gjmkoper commented 1 year ago

Will do in a week or so. If I forget, just ring the bell again :-)

gjmkoper commented 1 year ago

Had some time left, made new card to start all over with the following result:

$ cat /proc/cpuinfo | grep Model Model : Raspberry Pi 3 Model B Plus Rev 1.3 $ cat /etc/os-release | grep PRETTY PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"

After update/upgrade

Make sure we are using python3

$ python3 --version python 3.7.3 $ cd /usr/bin $ sudo rm python $ sudo ln -s /usr/bin/python3.7 python $ python --version python 3.7.3 $ cd ~

Download epsolar-tracer

$ git clone https://github.com/kasbert/epsolar-tracer.git $ cd epsolar-tracer/

install USB driver

$ sudo apt install raspberrypi-kernel-headers $ cd linux_usb_serial/ $ make make -C /lib/modules/5.10.103-v7+/build M=/home/pi/epsolar-tracer/linux_usb_serial make[1]: Entering directory '/usr/src/linux-headers-5.10.103-v7+' CC [M] /home/pi/epsolar-tracer/linux_usb_serial/xr_serial.o /home/pi/epsolar-tracer/linux_usb_serial/xr_serial.c: In function ‘xr_probe’: /home/pi/epsolar-tracer/linux_usb_serial/xr_serial.c:958:8: error: implicit declaration of function ‘usb_serial_claim_interface’; did you mean ‘usb_driver_claim_interface’? [-Werror=implicit-function-declaration] ret = usb_serial_claim_interface(serial, data); ^~~~~~ usb_driver_claim_interface cc1: some warnings being treated as errors make[2]: [scripts/Makefile.build:280: /home/pi/epsolar-tracer/linux_usb_serial/xr_serial.o] Error 1 make[1]: [Makefile:1825: /home/pi/epsolar-tracer/linux_usb_serial] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-5.10.103-v7+' make: *** [Makefile:9: all] Error 2