Skip to content

Add support for OpenDTU Modbus PR #28

@ArekKubacki

Description

@ArekKubacki

Description

Czy jest możliwość dodania wsparcia dla OpenDTU Modbus PR?
tbnobody/OpenDTU#1893
We have tried to maintain as much consistency as possible with the original DTU.

What I Did

Currently I have read from OpenDTU as a workaround by adding a DTU type variable. My simple code below:

                if self._dtu_type == 1:
                    start_address = i * 20 + 0x1000
                    result = self._read_registers(client, start_address, 20, self._unit_id)
                    data_to_unpack = result.encode()[1:41]
                elif self._dtu_type == 2:
                    start_address = i * 40 + 0x1000
                    result = self._read_registers(client, start_address, 40, self._unit_id)
                    data_to_unpack = result.encode()[1:81]
                else:
                    start_address = i * 40 + 0x1000
                    result = self._read_registers(client, start_address, 20, self._unit_id)
                    data_to_unpack = result.encode()[1:41]
                if self._dtu_type == 2:
                    result = self._read_registers(client, 0x2000, 3, self._unit_id)
                    self._dtu_serial_number = _serial_number_t2.unpack(result.encode()[1::])
                else:
                    result = self._read_registers(client, 0x2000, 3, self._unit_id)
                    self._dtu_serial_number = _serial_number_t.unpack(result.encode()[1::])
_udec32p1 = DecimalX(name='udec32p1', nbytes=4, precision=1, byteorder='big', signed=False)
_sdec32p1 = DecimalX(name='sdec32p1', nbytes=4, precision=1, byteorder='big', signed=True)
_udec32p2 = DecimalX(name='udec32p2', nbytes=4, precision=2, byteorder='big', signed=False)

_serial_number_t = _SerialNumberX(name='serial_number_t', nbytes=6)
_serial_number_t2 = _SerialNumberX(name='serial_number_t', nbytes=3)
_reserved = ArrayX(name='reserved', fmt=uint8)
_reserved2 = ArrayX(name='reserved', fmt=uint16)

class _PVCurrentType(Enum):
    """PV current datatype depending on inverter type."""

    MI = _udec16p1
    """MI series."""
    HM = _udec16p2
    """HM series."""
    MIDTU = _udec32p1
    """MI series."""
    HMDTU = _udec32p2
    """HM series."""

class InverterDataOpenDTU(Structure):  # type: ignore[misc]
    """Inverter data structure."""

    data_type: int = member(fmt=uint16)
    serial_number: str = member(fmt=_serial_number_t)
    serial_number2: str = member(fmt=_serial_number_t)
    """Inverter serial number."""
    port_number: int = member(fmt=uint16)
    """Port number."""
    pv_voltage: Decimal = member(fmt=_udec32p1)
    """PV voltage [V]."""
    pv_current: Decimal = member(fmt=_pv_current_type, fmt_arg=serial_number)  # type: ignore[arg-type]
    """PV current [A]."""
    grid_voltage: Decimal = member(fmt=_udec32p1)
    """Grid voltage [V]."""
    grid_frequency: Decimal = member(fmt=_udec32p2)
    """Grid frequency [Hz]."""
    pv_power: Decimal = member(fmt=_udec32p1)
    """PV power [W]."""
    today_production: int = member(fmt=uint32)
    """Today production [Wh]."""
    total_production: int = member(fmt=uint32)
	
    total_production2: int = member(fmt=uint32)
    """Total production [Wh]."""
    temperature: Decimal = member(fmt=_sdec32p1)
    """Inverter temperature [°C]."""
    operating_status: int = member(fmt=uint32)
    """Operating status."""
    alarm_code: int = member(fmt=uint32)
    """Alarm code."""
    alarm_count: int = member(fmt=uint32)
    """Alarm count."""
    link_status: int = member(fmt=uint16)
    """Link status."""
    reserved: list[int] = member(fmt=_reserved)
@dataclass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions