add source
This commit is contained in:
2
src/solaxx3/__init__.py
Normal file
2
src/solaxx3/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Version of the Solax RTU package
|
||||
__version__ = "0.0.6"
|
||||
589
src/solaxx3/registers.py
Normal file
589
src/solaxx3/registers.py
Normal file
@@ -0,0 +1,589 @@
|
||||
class SolaxRegistersInfo:
|
||||
__registers = {
|
||||
# input registers
|
||||
"grid_voltage": {
|
||||
"address": 0x0000,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Grid voltage",
|
||||
},
|
||||
"grid_current": {
|
||||
"address": 0x0001,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 10,
|
||||
"signed": True,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "Grid current",
|
||||
},
|
||||
"grid_power": {
|
||||
"address": 0x0002,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "W",
|
||||
"data_length": 1,
|
||||
"description": "Grid power",
|
||||
},
|
||||
"pv_voltage_1": {
|
||||
"address": 0x0003,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "PV Voltage 1",
|
||||
},
|
||||
"pv_voltage_2": {
|
||||
"address": 0x0004,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "PV Voltage 2",
|
||||
},
|
||||
"pv_current_1": {
|
||||
"address": 0x0005,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "PV Current 1",
|
||||
},
|
||||
"pv_current_2": {
|
||||
"address": 0x0006,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "PV Current 2",
|
||||
},
|
||||
"grid_frequency": {
|
||||
"address": 0x0007,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "Hz",
|
||||
"data_length": 1,
|
||||
"description": "Grid frequency",
|
||||
},
|
||||
"radiator_temperature": {
|
||||
"address": 0x0008,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "C",
|
||||
"data_length": 1,
|
||||
"description": "Radiator temperature",
|
||||
},
|
||||
"run_mode": {
|
||||
"address": 0x0009,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "",
|
||||
"data_length": 1,
|
||||
"description": "Inverter status",
|
||||
},
|
||||
"power_dc1": {
|
||||
"address": 0x000A,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "W",
|
||||
"data_length": 1,
|
||||
"description": "DC Power String 1",
|
||||
},
|
||||
"power_dc2": {
|
||||
"address": 0x000B,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "W",
|
||||
"data_length": 1,
|
||||
"description": "DC Power String 2",
|
||||
},
|
||||
"temperature_fault_value": {
|
||||
"address": 0x000C,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "C",
|
||||
"data_length": 1,
|
||||
"description": "Temperature fault value",
|
||||
},
|
||||
"pv1_volt_fault_value": {
|
||||
"address": 0x000D,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "PV1 volt fault value",
|
||||
},
|
||||
"pv2_volt_fault_value": {
|
||||
"address": 0x000E,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "PV2 volt fault value",
|
||||
},
|
||||
"gfci_fault_value": {
|
||||
"address": 0x000F,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1000,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "GFCI fault value",
|
||||
},
|
||||
"grid_fault_value": {
|
||||
"address": 0x0010,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Grid fault value",
|
||||
},
|
||||
"grid_freq__fault__value_t": {
|
||||
"address": 0x0011,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "Hz",
|
||||
"data_length": 1,
|
||||
"description": "Grid frequency fault value t",
|
||||
},
|
||||
"dci_fault_value": {
|
||||
"address": 0x0012,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "DCI fault value",
|
||||
},
|
||||
"time_count_down": {
|
||||
"address": 0x0013,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1000,
|
||||
"signed": False,
|
||||
"data_unit": "seconds",
|
||||
"data_length": 1,
|
||||
"description": "Time remaining until the current operation finishes (e.g. checking)",
|
||||
},
|
||||
"battery_voltage_charge_1": {
|
||||
"address": 0x0014,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 10,
|
||||
"signed": True,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Battery voltage charge 1",
|
||||
},
|
||||
"battery_current_charge_1": {
|
||||
"address": 0x0015,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 10,
|
||||
"signed": True,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Battery current charge 1",
|
||||
},
|
||||
"battery_power_charge1": {
|
||||
"address": 0x0016,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "W",
|
||||
"data_length": 1,
|
||||
"description": "Battery power charge 1",
|
||||
},
|
||||
"bms_connect_state": {
|
||||
"address": 0x0017,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "",
|
||||
"data_length": 1,
|
||||
"description": "BMS connect state",
|
||||
},
|
||||
"temperature_battery": {
|
||||
"address": 0x0018,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "C",
|
||||
"data_length": 1,
|
||||
"description": "Temperature of the battery",
|
||||
},
|
||||
"battery_capacity": {
|
||||
"address": 0x001C,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "%",
|
||||
"data_length": 1,
|
||||
"description": "Battery charge percentage",
|
||||
},
|
||||
"output_energy_charge": {
|
||||
"address": 0x001D,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Output energy charge",
|
||||
},
|
||||
"output_energy_charge_today": {
|
||||
"address": 0x0020,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 1,
|
||||
"description": "Output energy charge today",
|
||||
},
|
||||
"input_energy_charge": {
|
||||
"address": 0x0021,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Input energy charge",
|
||||
},
|
||||
"input_energy_charge_today": {
|
||||
"address": 0x0023,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 1,
|
||||
"description": "Input energy charge today",
|
||||
},
|
||||
"bms_charge_max_current": {
|
||||
"address": 0x0024,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "BMS charge max current",
|
||||
},
|
||||
"bms_discharge_max_current": {
|
||||
"address": 0x0025,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "A",
|
||||
"data_length": 1,
|
||||
"description": "BMS discharge max current",
|
||||
},
|
||||
"power_to_ev": {
|
||||
"address": 0x0026,
|
||||
"register_type": "input",
|
||||
"data_format": "int32",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "W",
|
||||
"data_length": 2,
|
||||
"description": "Power to EV",
|
||||
},
|
||||
"ref_power_to_ev": {
|
||||
"address": 0x0028,
|
||||
"register_type": "input",
|
||||
"data_format": "int16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "W",
|
||||
"data_length": 1,
|
||||
"description": "ref_power_to_ev",
|
||||
},
|
||||
"feed_in_power": {
|
||||
"address": 0x0046,
|
||||
"register_type": "input",
|
||||
"data_format": "int32",
|
||||
"si_adj": 1,
|
||||
"signed": True,
|
||||
"data_unit": "W ",
|
||||
"data_length": 2,
|
||||
"description": "Feed-in power obtained from Meter or CT",
|
||||
},
|
||||
"energy_to_grid_meter": {
|
||||
"address": 0x0048,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"si_adj": 100,
|
||||
"data_length": 2,
|
||||
"description": "Energy to grid meter value",
|
||||
},
|
||||
"energy_from_grid_meter": {
|
||||
"address": 0x004A,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Energy from grid meter value",
|
||||
},
|
||||
"energy_to_grid_today": {
|
||||
"address": 0x0050,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 1,
|
||||
"description": "The quantity of energy sent to grid today",
|
||||
},
|
||||
"energy_to_grid_total": {
|
||||
"address": 0x0052,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Total energy sent to grid",
|
||||
},
|
||||
"grid_voltage_r": {
|
||||
"address": 0x006A,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Grid voltage for R phase",
|
||||
},
|
||||
"grid_voltage_s": {
|
||||
"address": 0x006E,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Grid voltage for S phase",
|
||||
},
|
||||
"grid_voltage_t": {
|
||||
"address": 0x0072,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "V",
|
||||
"data_length": 1,
|
||||
"description": "Grid voltage for T phase",
|
||||
},
|
||||
"echarge_today": {
|
||||
"address": 0x0091,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 1,
|
||||
"description": "Echarge energy today",
|
||||
},
|
||||
"solar_energy_total": {
|
||||
"address": 0x0094,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Total solar energy",
|
||||
},
|
||||
"solar_energy_today": {
|
||||
"address": 0x0096,
|
||||
"register_type": "input",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 10,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 1,
|
||||
"description": "Solar energy today",
|
||||
},
|
||||
"feed_in_energy_today": {
|
||||
"address": 0x0098,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Energy to grid meter for today",
|
||||
},
|
||||
"consumption_energy_today": {
|
||||
"address": 0x009A,
|
||||
"register_type": "input",
|
||||
"data_format": "uint32",
|
||||
"si_adj": 100,
|
||||
"signed": False,
|
||||
"data_unit": "KWh",
|
||||
"data_length": 2,
|
||||
"description": "Energy from grid meter for today",
|
||||
},
|
||||
# holding registers
|
||||
"serial_number": {
|
||||
"address": 0x0000,
|
||||
"register_type": "holding",
|
||||
"data_format": "varchar",
|
||||
"signed": False,
|
||||
"data_length": 7,
|
||||
"description": "Inverter' serial number",
|
||||
},
|
||||
"firmware_version_dsp": {
|
||||
"address": 0x007D,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Firmware version DSP",
|
||||
},
|
||||
"hardware_version_dsp": {
|
||||
"address": 0x007E,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Hardware version DSP",
|
||||
},
|
||||
"firmware_version_modbus_rtu": {
|
||||
"address": 0x0082,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Firmware version MODBUS RTU",
|
||||
},
|
||||
"firmware_version_arm": {
|
||||
"address": 0x0083,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Firmware version ARM",
|
||||
},
|
||||
"firmware_version_arm_bootloader": {
|
||||
"address": 0x0084,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Firmware version ARM Bootloader",
|
||||
},
|
||||
"rtc_datetime": {
|
||||
"address": 0x0085,
|
||||
"register_type": "holding",
|
||||
"data_format": "datetime",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 6,
|
||||
"description": "RTC datetime",
|
||||
},
|
||||
"registration_code": {
|
||||
"address": 0x00AA,
|
||||
"register_type": "holding",
|
||||
"data_format": "varchar",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 6,
|
||||
"description": "Registration code for external module",
|
||||
},
|
||||
"inverter_power_type": {
|
||||
"address": 0x00BA,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Inverter power type",
|
||||
},
|
||||
"user_password": {
|
||||
"address": 0x00E0,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "User password",
|
||||
},
|
||||
"advanced_password": {
|
||||
"address": 0x00E1,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Advanced password",
|
||||
},
|
||||
"machine_type": {
|
||||
"address": 0x0105,
|
||||
"register_type": "holding",
|
||||
"data_format": "uint16",
|
||||
"si_adj": 1,
|
||||
"signed": False,
|
||||
"data_length": 1,
|
||||
"description": "Machine type: 1:X1, 3:X3",
|
||||
},
|
||||
}
|
||||
|
||||
def get_register_info(self, name: str):
|
||||
return self.__registers[name]
|
||||
|
||||
def list_register_names(self):
|
||||
return list(self.__registers.keys())
|
||||
169
src/solaxx3/rs485.py
Normal file
169
src/solaxx3/rs485.py
Normal file
@@ -0,0 +1,169 @@
|
||||
from typing import Any
|
||||
|
||||
# from pymodbus.client.sync import ModbusSerialClient
|
||||
from pymodbus.client import ModbusSerialClient
|
||||
from datetime import date, datetime, timedelta
|
||||
from struct import *
|
||||
from solaxx3.registers import SolaxRegistersInfo
|
||||
from time import sleep, perf_counter
|
||||
|
||||
|
||||
class SolaxX3:
|
||||
connected: bool = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
method="rtu",
|
||||
port="/dev/ttyUSB0",
|
||||
baudrate=115200,
|
||||
timeout=3,
|
||||
parity="N",
|
||||
stopbits=1,
|
||||
bytesize=8,
|
||||
) -> None:
|
||||
self._input_registers_values_list = []
|
||||
self._holding_registers_values_list = []
|
||||
|
||||
self.client = ModbusSerialClient(
|
||||
method=method,
|
||||
port=port,
|
||||
baudrate=baudrate,
|
||||
timeout=timeout,
|
||||
parity=parity,
|
||||
stopbits=stopbits,
|
||||
bytesize=bytesize,
|
||||
)
|
||||
|
||||
def connect(self) -> bool:
|
||||
self.connected = self.client.connect()
|
||||
return self.connected
|
||||
|
||||
def _join_msb_lsb(self, msb: int, lsb: int) -> int:
|
||||
return (msb << 16) | lsb
|
||||
|
||||
def _unsigned16(self, type: str, addr: int, count: int = 1, unit: int = 1) -> int:
|
||||
|
||||
self._input_registers_values_list
|
||||
if type == "input":
|
||||
return self._input_registers_values_list[addr]
|
||||
elif type == "holding":
|
||||
return self._holding_registers_values_list[addr]
|
||||
|
||||
def _readRegisterRange(
|
||||
self, type: str, addr: int, count: int = 1, unit: int = 1
|
||||
) -> list:
|
||||
if type == "input":
|
||||
return self._input_registers_values_list[addr : addr + count]
|
||||
elif type == "holding":
|
||||
return self._holding_registers_values_list[addr : addr + count]
|
||||
|
||||
def _twos_complement(self, number: int, bits: int) -> int:
|
||||
"""
|
||||
Compute the 2's complement of the int value val
|
||||
"""
|
||||
|
||||
# if sign bit is set e.g., 8bit: 128-255
|
||||
if (number & (1 << (bits - 1))) != 0:
|
||||
|
||||
# compute negative value
|
||||
number = number - (1 << bits)
|
||||
|
||||
return number
|
||||
|
||||
def _read_register(self, register_type: str, register_info: dict) -> Any:
|
||||
"""Read the values from a register based on length and sign
|
||||
|
||||
Parameters:
|
||||
|
||||
register_info:dict - dictionary with register definition fields
|
||||
"""
|
||||
|
||||
if "int" in register_info["data_format"]:
|
||||
if register_info["data_length"] == 1:
|
||||
val = self._unsigned16(register_type, register_info["address"])
|
||||
|
||||
if register_info["data_length"] == 2:
|
||||
val = self._join_msb_lsb(
|
||||
self._unsigned16(register_type, register_info["address"] + 1),
|
||||
self._unsigned16(register_type, register_info["address"]),
|
||||
)
|
||||
|
||||
if register_info["signed"]:
|
||||
val = self._twos_complement(val, register_info["data_length"] * 16)
|
||||
|
||||
val = val / register_info["si_adj"]
|
||||
|
||||
elif "varchar" in register_info["data_format"]:
|
||||
block = self._readRegisterRange(
|
||||
register_type, register_info["address"], register_info["data_length"]
|
||||
)
|
||||
sn = []
|
||||
for i in range(register_info["data_length"]):
|
||||
first_byte, second_byte = unpack(
|
||||
"BB", int.to_bytes(block[i], 2, "little")
|
||||
)
|
||||
if not second_byte == 0x0:
|
||||
sn.append(chr(second_byte))
|
||||
if not first_byte == 0x0:
|
||||
sn.append(chr(first_byte))
|
||||
val = "".join(sn)
|
||||
|
||||
elif "datetime" in register_info["data_format"]:
|
||||
sec, min, hr, day, mon, year = self._readRegisterRange(
|
||||
register_type, register_info["address"], register_info["data_length"]
|
||||
)
|
||||
|
||||
inverter_datetime = (
|
||||
f"{(year+2000):02}-{mon:02}-{day:02} {hr:02}:{min:02}:{sec:02}"
|
||||
)
|
||||
val = datetime.strptime(inverter_datetime, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
return val
|
||||
|
||||
def read_register(self, register_info: dict) -> tuple:
|
||||
"""Read the values from a register based on length and sign
|
||||
|
||||
Parameters:
|
||||
|
||||
register_info:dict - dictionary with register definition fields
|
||||
"""
|
||||
|
||||
val = self._read_register(register_info["register_type"], register_info)
|
||||
|
||||
if not "data_unit" in register_info:
|
||||
return (val, "N/A")
|
||||
|
||||
return (val, register_info["data_unit"])
|
||||
|
||||
def read(self, name: str):
|
||||
"""Retrieve the value for the register with the provided name"""
|
||||
|
||||
r = SolaxRegistersInfo()
|
||||
|
||||
register_info = r.get_register_info(name)
|
||||
value = self.read_register(register_info)
|
||||
|
||||
return value
|
||||
|
||||
def list_register_names(self):
|
||||
r = SolaxRegistersInfo()
|
||||
return r.list_register_names()
|
||||
|
||||
def read_all_registers(self) -> None:
|
||||
self._input_registers_values_list = []
|
||||
self._holding_registers_values_list = []
|
||||
|
||||
read_block_length = 100
|
||||
for i in range(3):
|
||||
address = i * read_block_length
|
||||
values_list = self.client.read_input_registers(
|
||||
address=address, count=read_block_length, slave=1
|
||||
).registers
|
||||
self._input_registers_values_list.extend(values_list)
|
||||
|
||||
for i in range(3):
|
||||
address = i * read_block_length
|
||||
values_list = self.client.read_holding_registers(
|
||||
address=address, count=read_block_length, slave=1
|
||||
).registers
|
||||
self._holding_registers_values_list.extend(values_list)
|
||||
Reference in New Issue
Block a user