Michael Hope
66cb355392
All checks were successful
continuous-integration/drone/push Build is passing
430 lines
17 KiB
Python
430 lines
17 KiB
Python
from dataclasses import dataclass
|
|
import dataclasses
|
|
from typing import Optional
|
|
import enum
|
|
|
|
import pint
|
|
|
|
from .hex import Register, Mode, Field
|
|
|
|
_ureg = pint.get_application_registry()
|
|
|
|
|
|
@dataclass
|
|
class Product:
|
|
id: int
|
|
name: str
|
|
remark: Optional[str] = None
|
|
|
|
|
|
PRODUCT_IDS = (
|
|
Product(0xA201, 'Phoenix Inverter 12V 250VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA202, 'Phoenix Inverter 24V 250VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA204, 'Phoenix Inverter 48V 250VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA211, 'Phoenix Inverter 12V 375VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA212, 'Phoenix Inverter 24V 375VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA214, 'Phoenix Inverter 48V 375VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA221, 'Phoenix Inverter 12V 500VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA222, 'Phoenix Inverter 24V 500VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA224, 'Phoenix Inverter 48V 500VA 230Vac', 'obsolete (32k)'),
|
|
Product(0xA231, 'Phoenix Inverter 12V 250VA 230Vac 64k'),
|
|
Product(0xA232, 'Phoenix Inverter 24V 250VA 230Vac 64k'),
|
|
Product(0xA234, 'Phoenix Inverter 48V 250VA 230Vac 64k'),
|
|
Product(0xA239, 'Phoenix Inverter 12V 250VA 120Vac 64k'),
|
|
Product(0xA23A, 'Phoenix Inverter 24V 250VA 120Vac 64k'),
|
|
Product(0xA23C, 'Phoenix Inverter 48V 250VA 120Vac 64k'),
|
|
Product(0xA241, 'Phoenix Inverter 12V 375VA 230Vac 64k'),
|
|
Product(0xA242, 'Phoenix Inverter 24V 375VA 230Vac 64k'),
|
|
Product(0xA244, 'Phoenix Inverter 48V 375VA 230Vac 64k'),
|
|
Product(0xA249, 'Phoenix Inverter 12V 375VA 120Vac 64k'),
|
|
Product(0xA24A, 'Phoenix Inverter 24V 375VA 120Vac 64k'),
|
|
Product(0xA24C, 'Phoenix Inverter 48V 375VA 120Vac 64k'),
|
|
Product(0xA251, 'Phoenix Inverter 12V 500VA 230Vac 64k'),
|
|
Product(0xA252, 'Phoenix Inverter 24V 500VA 230Vac 64k'),
|
|
Product(0xA254, 'Phoenix Inverter 48V 500VA 230Vac 64k'),
|
|
Product(0xA259, 'Phoenix Inverter 12V 500VA 120Vac 64k'),
|
|
Product(0xA25A, 'Phoenix Inverter 24V 500VA 120Vac 64k'),
|
|
Product(0xA25C, 'Phoenix Inverter 48V 500VA 120Vac 64k'),
|
|
Product(0xA261, 'Phoenix Inverter 12V 800VA 230Vac 64k'),
|
|
Product(0xA262, 'Phoenix Inverter 24V 800VA 230Vac 64k'),
|
|
Product(0xA264, 'Phoenix Inverter 48V 800VA 230Vac 64k'),
|
|
Product(0xA269, 'Phoenix Inverter 12V 800VA 120Vac 64k'),
|
|
Product(0xA26A, 'Phoenix Inverter 24V 800VA 120Vac 64k'),
|
|
Product(0xA26C, 'Phoenix Inverter 48V 800VA 120Vac 64k'),
|
|
Product(0xA271, 'Phoenix Inverter 12V 1200VA 230Vac 64k'),
|
|
Product(0xA272, 'Phoenix Inverter 24V 1200VA 230Vac 64k'),
|
|
Product(0xA274, 'Phoenix Inverter 48V 1200VA 230Vac 64k'),
|
|
Product(0xA279, 'Phoenix Inverter 12V 1200VA 120Vac 64k'),
|
|
Product(0xA27A, 'Phoenix Inverter 24V 1200VA 120Vac 64k'),
|
|
Product(0xA27C, 'Phoenix Inverter 48V 1200VA 120Vac 64k'),
|
|
Product(0xA281, 'Phoenix Inverter Smart 12V 1600VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA282, 'Phoenix Inverter Smart 24V 1600VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA284, 'Phoenix Inverter Smart 48V 1600VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA291, 'Phoenix Inverter Smart 12V 2000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA292, 'Phoenix Inverter Smart 24V 2000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA294, 'Phoenix Inverter Smart 48V 2000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA2A1, 'Phoenix Inverter Smart 12V 3000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA2A2, 'Phoenix Inverter Smart 24V 3000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA2A4, 'Phoenix Inverter Smart 48V 3000VA 230Vac 64k',
|
|
'Smart, integrated Bluetooth'),
|
|
Product(0xA2E1, 'Phoenix Inverter 12V 800VA 230Vac 64k HS',
|
|
'redesign (replaces A261)'),
|
|
Product(0xA2E2, 'Phoenix Inverter 24V 800VA 230Vac 64k HS',
|
|
'redesign (replaces A262)'),
|
|
Product(0xA2E4, 'Phoenix Inverter 48V 800VA 230Vac 64k HS',
|
|
'redesign (replaces A264)'),
|
|
Product(0xA2E9, 'Phoenix Inverter 12V 800VA 120Vac 64k HS',
|
|
'redesign (replaces A269)'),
|
|
Product(0xA2EA, 'Phoenix Inverter 24V 800VA 120Vac 64k HS',
|
|
'redesign (replaces A26A)'),
|
|
Product(0xA2EC, 'Phoenix Inverter 48V 800VA 120Vac 64k HS',
|
|
'redesign (replaces A26C)'),
|
|
Product(0xA2F1, 'Phoenix Inverter 12V 1200VA 230Vac 64k HS',
|
|
'redesign (replaces A271)'),
|
|
Product(0xA2F2, 'Phoenix Inverter 24V 1200VA 230Vac 64k HS',
|
|
'redesign (replaces A272)'),
|
|
Product(0xA2F4, 'Phoenix Inverter 48V 1200VA 230Vac 64k HS',
|
|
'redesign (replaces A274)'),
|
|
Product(0xA2F9, 'Phoenix Inverter 12V 1200VA 120Vac 64k HS',
|
|
'redesign (replaces A279)'),
|
|
Product(0xA2FA, 'Phoenix Inverter 24V 1200VA 120Vac 64k HS',
|
|
'redesign (replaces A27A)'),
|
|
Product(0xA2FC, 'Phoenix Inverter 48V 1200VA 120Vac 64k HS',
|
|
'redesign (replaces A27C)'),
|
|
)
|
|
|
|
# NVM registers
|
|
INV_NVM_COMMAND = Register(0xEB99, 'INV_NVM_COMMAND', 'B', Mode.W)
|
|
RESTORE_DEFAULT = Register(0x0004, 'RESTORE_DEFAULT', '-', Mode.W)
|
|
|
|
# class NVMCommand(enum.IntEnum):
|
|
# # 1,NvmSave,Save current user settings to NVM,,,,
|
|
# # 2,NvmRevert,Cancel modified settings.,,,,
|
|
# # ,,Load most recent saved user settings.,,,,
|
|
# # 3,NvmBackup,Undo last save. Load second last time saved settings.,,,,
|
|
# # 4,NvmDefault,Load the factory default values.,,,,
|
|
|
|
|
|
# Product information registers
|
|
class Capabilities(enum.IntFlag):
|
|
# 8,Remote input available
|
|
REMOTE_INPUT_AVAILABLE = 1 << 8
|
|
# 17,Build in user-relay available
|
|
# TYPO
|
|
BUILD_IN_USER_RELAY_AVAILABLE = 1 << 17
|
|
# 28,Support of device hibernation
|
|
SUPPORT_OF_DEVICE_HIBERNATION = 1 << 28
|
|
# 29,Improved load current measurement
|
|
IMPROVED_LOAD_CURRENT_MEASUREMENT = 1 << 29
|
|
|
|
|
|
PRODUCT_ID = Register(0x0100, 'PRODUCT_ID', 'xHx', Mode.R)
|
|
PRODUCT_REVISION = Register(0x0101, 'PRODUCT_REVISION', 'xH', Mode.R, None,
|
|
None)
|
|
APP_VER = Register(0x0102, 'APP_VER', 'xH', Mode.R)
|
|
SERIAL_NUMBER = Register(0x010A, 'SERIAL_NUMBER', 'S', Mode.R)
|
|
MODEL_NAME = Register(0x010B, 'MODEL_NAME', 'S', Mode.R)
|
|
AC_OUT_RATED_POWER = Register(0x2203, 'AC_OUT_RATED_POWER', 'h', Mode.R, 1,
|
|
'VA')
|
|
# Typo.
|
|
CAPABILITIES = Register(0x0140, 'CAPABILITIES', 'I', Mode.R, None,
|
|
Capabilities)
|
|
CAPABILITIES_BLE = Register(0x0150, 'CAPABILITIES_BLE', 'I', Mode.RW)
|
|
AC_OUT_NOM_VOLTAGE = Register(0x2202, 'AC_OUT_NOM_VOLTAGE', 'B', Mode.R, 1,
|
|
'V')
|
|
BAT_VOLTAGE = Register(0xEDEF, 'BAT_VOLTAGE', 'B', Mode.R, 1, 'V')
|
|
|
|
|
|
# # Generic device status registers
|
|
class DeviceState(enum.IntEnum):
|
|
# Off,Not inverting. When due to a protection the inverter will
|
|
# automatically start again when the cause is solved.
|
|
OFF = 0
|
|
# Low Power,Eco load search active
|
|
LOW_POWER = 1
|
|
# Fault,Not inverting due to a fatal active protection. A turn OFF-ON cycle
|
|
# is required to enable the device again.
|
|
FAULT = 2
|
|
# Inverting,Normal operating
|
|
INVERTING = 9
|
|
|
|
|
|
class DeviceOffReason(enum.IntFlag):
|
|
NONE = 0
|
|
# 0,No input power (will also cause a battery alarm),
|
|
NO_INPUT_POWER = 1 << 0
|
|
# 2,Soft power button or SW controlled (VE.Direct or Bluetooth),
|
|
SOFT_POWER_BUTTON_OR_SW_CONTROLLED = 1 << 2
|
|
# 3,HW remote input connector,
|
|
HW_REMOTE_INPUT_CONNECTOR = 1 << 3
|
|
# 4,Internal reason (see alarm reason for more info),
|
|
INTERNAL_REASON = 1 << 4
|
|
# 5,"PayGo, out of credit, need token",
|
|
PAYGO_OUT_OF_CREDIT_NEED_TOKEN = 1 << 5
|
|
|
|
|
|
class WarningReason(enum.IntFlag):
|
|
NONE = 0
|
|
# 0,Low battery voltage,
|
|
LOW_BATTERY_VOLTAGE = 1 << 0
|
|
# 1,High battery voltage,
|
|
HIGH_BATTERY_VOLTAGE = 1 << 1
|
|
# 5,Low temperature,
|
|
LOW_TEMPERATURE = 1 << 5
|
|
# 6,High temperature,
|
|
HIGH_TEMPERATURE = 1 << 6
|
|
# 8,Overload,
|
|
OVERLOAD = 1 << 8
|
|
# 9,Poor DC connection,
|
|
POOR_DC_CONNECTION = 1 << 9
|
|
# 10,Low AC-output voltage,
|
|
LOW_AC_OUTPUT_VOLTAGE = 1 << 10
|
|
# 11,High AC-output voltage,
|
|
HIGH_AC_OUTPUT_VOLTAGE = 1 << 11
|
|
|
|
|
|
DEVICE_STATE = Register(0x0201, 'DEVICE_STATE', 'B', Mode.R, None, DeviceState)
|
|
DEVICE_OFF_REASON = Register(0x0207, 'DEVICE_OFF_REASON', 'I', Mode.R, None,
|
|
DeviceOffReason)
|
|
WARNING_REASON = Register(0x031C, 'WARNING_REASON', 'H', Mode.R, None,
|
|
WarningReason)
|
|
ALARM_REASON = Register(0x031E, 'ALARM_REASON', 'H', Mode.R, None,
|
|
WarningReason)
|
|
|
|
|
|
# Generic device control registers
|
|
class DeviceMode(enum.IntEnum):
|
|
# 2,Inverter On,,,,,
|
|
INVERTER_ON = 2
|
|
# 3,Device On (multi compliant),1),,,,
|
|
DEVICE_ON = 3
|
|
# 4,Device Off,VE.Direct is still enabled,,,,
|
|
DEVICE_OFF = 4
|
|
# 5,Eco mode,,,,,
|
|
ECO_MODE = 5
|
|
# 0xFD,Hibernate,VE.Direct is affected 2),,,,
|
|
HIBERNATE = 0xFD
|
|
|
|
|
|
BLE_MODE = Register(0x0090, 'BLE_MODE', 'B', Mode.RW)
|
|
DEVICE_MODE = Register(0x0200, 'DEVICE_MODE', 'B', Mode.RW, None, DeviceMode)
|
|
SETTINGS_CHANGED = Register(0xEC41, 'SETTINGS_CHANGED', 'I', Mode.RW)
|
|
|
|
# Inverter operation registers
|
|
HISTORY_TIME = Register(0x1040, 'HISTORY_TIME', 'I', Mode.R, 1, _ureg.second)
|
|
HISTORY_ENERGY = Register(0x1041, 'HISTORY_ENERGY', 'I', Mode.R, 0.01 * 1000,
|
|
_ureg.watthour)
|
|
AC_OUT_CURRENT = Register(0x2201, 'AC_OUT_CURRENT', 'h', Mode.R, 0.1,
|
|
_ureg.amp)
|
|
AC_OUT_VOLTAGE = Register(0x2200, 'AC_OUT_VOLTAGE', 'h', Mode.R, 0.01,
|
|
_ureg.volt)
|
|
AC_OUT_APPARENT_POWER = Register(0x2205, 'AC_OUT_APPARENT_POWER', 'i', Mode.R,
|
|
1, _ureg.watt)
|
|
INV_LOOP_GET_IINV = Register(0xEB4E, 'INV_LOOP_GET_IINV', 'h', Mode.R, 0.001,
|
|
_ureg.amp)
|
|
DC_CHANNEL1_VOLTAGE = Register(0xED8D, 'DC_CHANNEL1_VOLTAGE', 'h', Mode.R,
|
|
0.01, _ureg.volt)
|
|
|
|
# User AC-out control registers
|
|
AC_OUT_VOLTAGE_SETPOINT = Register(0x0230, 'AC_OUT_VOLTAGE_SETPOINT', 'H',
|
|
Mode.W, 0.01, _ureg.volt)
|
|
AC_OUT_VOLTAGE_SETPOINT_MIN = Register(0x0231, 'AC_OUT_VOLTAGE_SETPOINT_MIN',
|
|
'H', Mode.R, 0.01, _ureg.volt)
|
|
AC_OUT_VOLTAGE_SETPOINT_MAX = Register(0x0232, 'AC_OUT_VOLTAGE_SETPOINT_MAX',
|
|
'H', Mode.R, 0.01, _ureg.volt)
|
|
AC_LOAD_SENSE_POWER_THRESHOLD = Register(0x2206,
|
|
'AC_LOAD_SENSE_POWER_THRESHOLD', 'H',
|
|
Mode.W, None, _ureg.watt)
|
|
AC_LOAD_SENSE_POWER_CLEAR = Register(0x2207, 'AC_LOAD_SENSE_POWER_CLEAR', 'H',
|
|
Mode.W, None, _ureg.watt)
|
|
INV_WAVE_SET50HZ_NOT60HZ = Register(0xEB03, 'INV_WAVE_SET50HZ_NOT60HZ', 'B',
|
|
Mode.W)
|
|
INV_OPER_ECO_MODE_INV_MIN = Register(0xEB04, 'INV_OPER_ECO_MODE_INV_MIN', 'h',
|
|
Mode.W, 0.001, _ureg.A)
|
|
INV_OPER_ECO_MODE_RETRY_TIME = Register(0xEB06, 'INV_OPER_ECO_MODE_RETRY_TIME',
|
|
'B', Mode.W, 0.25, _ureg.second)
|
|
INV_OPER_ECO_LOAD_DETECT_PERIODS = Register(
|
|
0xEB10, 'INV_OPER_ECO_LOAD_DETECT_PERIODS', 'B', Mode.W, 0.02, _ureg.hertz)
|
|
|
|
# User battery control registers
|
|
SHUTDOWN_LOW_VOLTAGE_SET = Register(0x2210, 'SHUTDOWN_LOW_VOLTAGE_SET', 'H',
|
|
Mode.W, 0.01, _ureg.volt)
|
|
ALARM_LOW_VOLTAGE_SET = Register(0x0320, 'ALARM_LOW_VOLTAGE_SET', 'H', Mode.W,
|
|
0.01, _ureg.volt)
|
|
ALARM_LOW_VOLTAGE_CLEAR = Register(0x0321, 'ALARM_LOW_VOLTAGE_CLEAR', 'H',
|
|
Mode.W, 0.01, _ureg.volt)
|
|
VOLTAGE_RANGE_MIN = Register(0x2211, 'VOLTAGE_RANGE_MIN', 'H', Mode.R, 0.01,
|
|
_ureg.volt)
|
|
VOLTAGE_RANGE_MAX = Register(0x2212, 'VOLTAGE_RANGE_MAX', 'H', Mode.R, 0.01,
|
|
_ureg.volt)
|
|
# Datasheet says H.
|
|
INV_PROT_UBAT_DYN_CUTOFF_ENABLE = Register(0xEBBA,
|
|
'INV_PROT_UBAT_DYN_CUTOFF_ENABLE',
|
|
'B', Mode.W)
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR = Register(0xEBB7,
|
|
'INV_PROT_UBAT_DYN_CUTOFF_FACTOR',
|
|
'H', Mode.W)
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR2000 = Register(
|
|
0xEBB5, 'INV_PROT_UBAT_DYN_CUTOFF_FACTOR2000', 'H', Mode.W)
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR250 = Register(
|
|
0xEBB3, 'INV_PROT_UBAT_DYN_CUTOFF_FACTOR250', 'H', Mode.W)
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR5 = Register(
|
|
0xEBB2, 'INV_PROT_UBAT_DYN_CUTOFF_FACTOR5', 'H', Mode.W)
|
|
INV_PROT_UBAT_DYN_CUTOFF_VOLTAGE = Register(
|
|
0xEBB1, 'INV_PROT_UBAT_DYN_CUTOFF_VOLTAGE', 'H', Mode.R, 0.001, _ureg.volt)
|
|
|
|
|
|
# Relay control registers
|
|
class RelayMode(enum.IntEnum):
|
|
# Normal operation. On during normal operation (warnings are ignored).
|
|
NORMAL_OPERATION = 4
|
|
# Warnings and alarms. Off when a warning or alarm is active (inverter on).
|
|
WARNINGS_AND_ALARMS = 0
|
|
# Battery low. Off when a low battery warning or alarm is active.
|
|
BATTERY_LOW = 5
|
|
# External fan. On when the internal fan is on.
|
|
EXTERNAL_FAN = 6
|
|
# Disabled relay. Always Off.
|
|
DISABLED_RELAY = 3
|
|
# Remote. Controlled by writing to RELAY_CONTROL (0x034E).
|
|
REMOTE = 2
|
|
|
|
|
|
RELAY_CONTROL = Register(0x034E, 'RELAY_CONTROL', 'B', Mode.RW)
|
|
RELAY_MODE = Register(0x034F, 'RELAY_MODE', 'B', Mode.W, None, RelayMode)
|
|
|
|
|
|
class NVMCommand(enum.IntEnum):
|
|
NONE = 0
|
|
SAVE = 1
|
|
REVERT = 2
|
|
LOAD_BACKUP = 3
|
|
LOAD_DEFAULTS = 4
|
|
|
|
|
|
INV_NVM_COMMAND = Register(0xEB99, 'INV_NVM_COMMAND', 'B', Mode.W, None,
|
|
NVMCommand)
|
|
|
|
ID = int
|
|
|
|
REGISTERS = {
|
|
ID(r.id): r
|
|
for r in globals().values() if isinstance(r, Register)
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class NVM:
|
|
inv_nvm_command: int = Field(INV_NVM_COMMAND)
|
|
|
|
|
|
@dataclass
|
|
class Information:
|
|
product_id: int = Field(PRODUCT_ID)
|
|
product_revision: int = Field(PRODUCT_REVISION)
|
|
app_ver: int = Field(APP_VER)
|
|
serial_number: str = Field(SERIAL_NUMBER)
|
|
model_name: str = Field(MODEL_NAME)
|
|
ac_out_rated_power: float = Field(AC_OUT_RATED_POWER)
|
|
capabilities: Capabilities = Field(CAPABILITIES)
|
|
# capabilities_ble: float = Field(CAPABILITIES_BLE)
|
|
ac_out_nom_voltage: float = Field(AC_OUT_NOM_VOLTAGE)
|
|
bat_voltage: float = Field(BAT_VOLTAGE)
|
|
|
|
|
|
@dataclass
|
|
class Status:
|
|
device_state: DeviceState = Field(DEVICE_STATE)
|
|
device_off_reason: DeviceOffReason = Field(DEVICE_OFF_REASON)
|
|
warning_reason: WarningReason = Field(WARNING_REASON)
|
|
alarm_reason: int = Field(ALARM_REASON)
|
|
|
|
|
|
@dataclass
|
|
class DeviceControl:
|
|
# ble_mode: float = Field(BLE_MODE)
|
|
device_mode: DeviceMode = Field(DEVICE_MODE)
|
|
settings_changed: int = Field(SETTINGS_CHANGED)
|
|
|
|
|
|
@dataclass
|
|
class Inverter:
|
|
history_time: float = Field(HISTORY_TIME)
|
|
history_energy: float = Field(HISTORY_ENERGY)
|
|
ac_out_current: float = Field(AC_OUT_CURRENT)
|
|
ac_out_voltage: float = Field(AC_OUT_VOLTAGE)
|
|
# ac_out_apparent_power: float = Field(AC_OUT_APPARENT_POWER)
|
|
inv_loop_get_iinv: float = Field(INV_LOOP_GET_IINV)
|
|
dc_channel1_voltage: float = Field(DC_CHANNEL1_VOLTAGE)
|
|
|
|
|
|
@dataclass
|
|
class ACControl:
|
|
ac_out_voltage_setpoint: float = Field(AC_OUT_VOLTAGE_SETPOINT)
|
|
ac_out_voltage_setpoint_min: float = Field(AC_OUT_VOLTAGE_SETPOINT_MIN)
|
|
ac_out_voltage_setpoint_max: float = Field(AC_OUT_VOLTAGE_SETPOINT_MAX)
|
|
# ac_load_sense_power_threshold: float = Field(
|
|
# AC_LOAD_SENSE_POWER_THRESHOLD)
|
|
# ac_load_sense_power_clear: float = Field(
|
|
# AC_LOAD_SENSE_POWER_CLEAR)
|
|
inv_wave_set50hz_not60hz: int = Field(INV_WAVE_SET50HZ_NOT60HZ)
|
|
inv_oper_eco_mode_inv_min: float = Field(INV_OPER_ECO_MODE_INV_MIN)
|
|
inv_oper_eco_mode_retry_time: float = Field(INV_OPER_ECO_MODE_RETRY_TIME)
|
|
inv_oper_eco_load_detect_periods: float = Field(
|
|
INV_OPER_ECO_LOAD_DETECT_PERIODS)
|
|
|
|
|
|
@dataclass
|
|
class BatteryControl:
|
|
shutdown_low_voltage_set: float = Field(SHUTDOWN_LOW_VOLTAGE_SET)
|
|
alarm_low_voltage_set: float = Field(ALARM_LOW_VOLTAGE_SET)
|
|
alarm_low_voltage_clear: float = Field(ALARM_LOW_VOLTAGE_CLEAR)
|
|
voltage_range_min: float = Field(VOLTAGE_RANGE_MIN)
|
|
voltage_range_max: float = Field(VOLTAGE_RANGE_MAX)
|
|
inv_prot_ubat_dyn_cutoff_enable: int = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_ENABLE)
|
|
inv_prot_ubat_dyn_cutoff_factor: int = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR)
|
|
inv_prot_ubat_dyn_cutoff_factor2000: int = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR2000)
|
|
inv_prot_ubat_dyn_cutoff_factor250: int = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR250)
|
|
inv_prot_ubat_dyn_cutoff_factor5: int = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_FACTOR5)
|
|
inv_prot_ubat_dyn_cutoff_voltage: float = Field(
|
|
INV_PROT_UBAT_DYN_CUTOFF_VOLTAGE)
|
|
|
|
|
|
@dataclass
|
|
class RelayControl:
|
|
relay_control: float = Field(RELAY_CONTROL)
|
|
relay_mode: float = Field(RELAY_MODE)
|
|
|
|
|
|
GROUPS = (
|
|
Information,
|
|
Status,
|
|
DeviceControl,
|
|
Inverter,
|
|
ACControl,
|
|
BatteryControl,
|
|
NVM,
|
|
)
|
|
|
|
for group in GROUPS:
|
|
for field in dataclasses.fields(group):
|
|
r = field.metadata.get('vedirect.Register', None)
|
|
assert r is not None
|
|
if field.type == int:
|
|
assert r.scale is None, r
|
|
elif field.type == float:
|
|
assert r.scale is not None, r
|