Closed jacekowski closed 1 year ago
What happens with the pymodbus driver?
pymodbus driver doesn't work for me at all (for a different reason)
2023-06-02 18:23:25,216 INFO options Loading HASS OS configuration
2023-06-02 18:23:25,233 DEBUG : pymodbus driver options: {'port': 'serial-tcp://10.42.1.176:502', 'server_id': 1, 'timeout': 10, 'read_sensors_batch_size': 60}
2023-06-02 18:23:25,233 INFO sensors Using Single phase sensor definitions.
2023-06-02 18:23:25,234 INFO helpers Importing /share/hass-addon-sunsynk/mysensors.py...
2023-06-02 18:23:25,234 INFO helpers custom sensors: grid_trickle_feed, grid_trickle_feed_ro
2023-06-02 18:23:25,234 DEBUG filter step unit:W, id:rated_power
2023-06-02 18:23:25,235 DEBUG asyncio Using selector: EpollSelector
2023-06-02 18:23:25,235 INFO : Connecting to serial-tcp://10.42.1.176:502
2023-06-02 18:23:25,235 INFO sunsynk.pysunsynk PyModbus 3.2.2 TCP: 10.42.1.176:502
2023-06-02 18:23:25,235 DEBUG pymodbus.logging Connecting to 10.42.1.176:502.
2023-06-02 18:23:25,235 DEBUG pymodbus.logging Connecting.
2023-06-02 18:23:25,245 DEBUG pymodbus.logging Client connected to modbus server
2023-06-02 18:23:25,247 INFO pymodbus.logging Protocol made connection.
2023-06-02 18:23:25,247 DEBUG asyncio <asyncio.TransportSocket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.30.33.2', 55844), raddr=('10.42.1.176', 502)> connected to 10.42.1.176:502: (<_SelectorSocketTransport fd=6 read=polling write=<idle, bufsize=0>>, <pymodbus.client.tcp.AsyncModbusTcpClient object at 0x7fb67e6fa700>)
2023-06-02 18:23:25,248 INFO pymodbus.logging Connected to 10.42.1.176:502.
2023-06-02 18:23:25,248 INFO : Reading startup sensors rated_power, serial, battery_shutdown_capacity, battery_low_capacity, prog6_time, prog2_time, prog1_time, prog3_time, prog4_time, prog5_time
2023-06-02 18:23:25,249 DEBUG pymodbus.logging send: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x3 0x0 0x5
2023-06-02 18:23:25,249 DEBUG pymodbus.logging Adding transaction 1
2023-06-02 18:23:28,284 INFO pymodbus.logging Protocol lost connection.
2023-06-02 18:23:28,287 DEBUG pymodbus.logging Client disconnected from modbus server: trying to send
2023-06-02 18:23:28,287 DEBUG pymodbus.logging Getting transaction 1
2023-06-02 18:23:28,288 INFO pymodbus.logging Protocol lost connection.
2023-06-02 18:23:28,288 WARNING pymodbus.logging Ignoring launch of delayed reconnection, another is in progress
2023-06-02 18:23:28,289 DEBUG pymodbus.logging Client disconnected from modbus server: None
2023-06-02 18:23:28,289 DEBUG pymodbus.logging Waiting 100 ms before next connection attempt.
2023-06-02 18:23:28,290 ERROR sunsynk.sunsynk timeout reading register 3 (5)
2023-06-02 18:23:28,290 INFO : ############################################################
2023-06-02 18:23:28,290 INFO : No response on the Modbus interface serial-tcp://10.42.1.176:502, try checking the wiring to the Inverter, the USB-to-RS485 converter, etc
2023-06-02 18:23:28,290 INFO : ############################################################
2023-06-02 18:23:28,290 CRITICAL : This Add-On will terminate in 30 seconds, use the Supervisor Watchdog to restart automatically.
2023-06-02 18:23:28,393 DEBUG pymodbus.logging Connecting.
2023-06-02 18:23:28,403 DEBUG pymodbus.logging Client connected to modbus server
2023-06-02 18:23:28,403 INFO pymodbus.logging Protocol made connection.
2023-06-02 18:23:28,403 DEBUG asyncio <asyncio.TransportSocket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.30.33.2', 55856), raddr=('10.42.1.176', 502)> connected to 10.42.1.176:502: (<_SelectorSocketTransport fd=6 read=polling write=<idle, bufsize=0>>, <pymodbus.client.tcp.AsyncModbusTcpClient object at 0x7fb67e6fa700>)
2023-06-02 18:23:28,404 INFO pymodbus.logging Connected to 10.42.1.176:502.
If you just have PORT: tcp://10.42.1.176:502
instead of serial-tcp://
?
btw, what other modbus client did you write it with?
just tcp:// doesn't work (my converter does not convert modbus tcp to modbus rtu so i need the addon to send modbus rtu over tcp)
The client i'm using is Modbus Poll
Ok, my only suggestion for now is that you do the inverse of this - https://github.com/kellerza/sunsynk/blob/main/sunsynk/helpers.py#L49
So for a negative number, add 0xFFFF before you write it
That's what i'm doing now (in node red), and i have found another bug, when using Sensor with -1 factor the resulting value is off by 1.
SENSORS += NumberRWSensor(206, "Grid Trickle Feed", WATT, 1,max=65536)
SENSORS += Sensor(206, "Grid Trickle Feed RO", WATT, -1)
however, 65466 = 0xFFBA, Signed 0xFFBA = -70
Try this in mysensors. If it works we need to replace NumberRWSensors class & fix the function I linked above for signed
import attrs
from typing import Union
from sunsynk import WATT
from sunsynk.rwsensors import ResolveType, NumberRWSensor, resolve_num
from sunsynk.sensors import RegType, Sensor, SensorDefinitions, ValType
SENSORS = SensorDefinitions()
@attrs.define(slots=True, eq=False)
class NumberRWSensor2(NumberRWSensor):
"""Numeric sensor which can be read and written."""
min: Union[int, float, Sensor] = attrs.field(default=0)
max: Union[int, float, Sensor] = attrs.field(default=100)
@property
def dependencies(self) -> list[Sensor]:
"""Get a list of sensors upon which this sensor depends."""
return [s for s in (self.min, self.max) if isinstance(s, Sensor)]
def reg_to_value(self, regs: RegType) -> ValType:
"""Decode the register."""
res = super().reg_to_value(self.masked(regs))
return res if res >= 0 else res - 1 # signed needs to -0x10000
def value_to_reg(self, value: ValType, resolve: ResolveType) -> RegType:
"""Get the reg value from a display value, or the current reg value if out of range."""
fval = float(value) # type:ignore
minv = resolve_num(resolve, self.min, 0)
maxv = resolve_num(resolve, self.max, 100)
val = int(max(minv, min(maxv, fval / abs(self.factor))))
if len(self.address) == 1:
if val < 0:
val = 0x10000 + val
return self.reg(val)
if len(self.address) == 2:
return self.reg(val & 0xFFFF, int(val >> 16))
raise NotImplementedError
SENSORS += NumberRWSensor2(206, "Grid Trickle Feed", WATT, -1, min=-500, max=500)
It works.
Issue related to
Sunsynk Home Assistant Add-On
Describe the issue/bug
I want to add register 206 (grid trickle feed) sensor definition, while official sunsynk app and web interface does not permit a negative value, writing negative value with a modbus client actually works and provides expected behaviour. I would like to have easy way to automate adjusting this value (to correct for discrepancy between sunsynk meter and revenue meter), so rw sensor seems like a best idea.
However, when i have added my custom sensor definition
SENSORS += NumberRWSensor(206, "Grid Trickle Feed", WATT, 1,min=-500, max=500)
When attempting to write negative value i get a crash.
Expected behavior
Negative value to be written to the inverter
Your environment
Logs