Michael Hope
9a36e59d38
All checks were successful
continuous-integration/drone/push Build is passing
695 lines
29 KiB
Python
695 lines
29 KiB
Python
"""MPPT HEX Protocol specification."""
|
|
|
|
from dataclasses import dataclass
|
|
import enum
|
|
|
|
from . import schema
|
|
from .hex import Register, Field
|
|
|
|
import pint
|
|
|
|
_ureg = pint.get_application_registry()
|
|
|
|
|
|
class ID(enum.IntEnum):
|
|
# Product information registers
|
|
# 0x0100,Product Id,-,un32,-
|
|
PRODUCT_ID = 0x0100
|
|
# 0x0104,Group Id,-,un8,-
|
|
GROUP_ID = 0x0104
|
|
# 0x010A,Serial number,-,string,-
|
|
SERIAL_NUMBER = 0x010A
|
|
# 0x010B,Model name,-,string,-
|
|
MODEL_NAME = 0x010B
|
|
# 0x0140,Capabilities,-,un32,-
|
|
CAPABILITIES = 0x0140
|
|
|
|
# Generic device control registers
|
|
# 0x0200,Device mode,-,un8,-
|
|
DEVICE_MODE = 0x0200
|
|
# 0x0201,Device state,-,un8,-
|
|
DEVICE_STATE = 0x0201
|
|
# 0x0202,Remote control used,-,un32,-
|
|
REMOTE_CONTROL_USED = 0x0202
|
|
# 0x0205,Device off reason,-,un8,-
|
|
DEVICE_OFF_REASON = 0x0205
|
|
# 0x0207,Device off reason,-,un32,-
|
|
DEVICE_OFF_REASON_EXTENDED = 0x0207
|
|
|
|
# Battery settings registers
|
|
# 0xEDFF,Batterysafe mode,-,un8,0=off, 1=on
|
|
BATTERYSAFE_MODE = 0xEDFF
|
|
# 0xEDFE,Adaptive mode,-,un8,0=off, 1=on
|
|
ADAPTIVE_MODE = 0xEDFE
|
|
# 0xEDFD,Automatic equalisation mode,-,un8,0=off, 1..250
|
|
AUTOMATIC_EQUALISATION_MODE = 0xEDFD
|
|
# 0xEDFC,Battery bulk time limit,0.01,un16,hours
|
|
BATTERY_BULK_TIME_LIMIT = 0xEDFC
|
|
# 0xEDFB,Battery absorption time limit,0.01,un16,hours
|
|
BATTERY_ABSORPTION_TIME_LIMIT = 0xEDFB
|
|
# 0xEDF7,Battery absorption voltage,0.01,un16,V
|
|
BATTERY_ABSORPTION_VOLTAGE = 0xEDF7
|
|
# 0xEDF6,Battery float voltage,0.01,un16,V
|
|
BATTERY_FLOAT_VOLTAGE = 0xEDF6
|
|
# 0xEDF4,Battery equalisation voltage,0.01,un16,V
|
|
BATTERY_EQUALISATION_VOLTAGE = 0xEDF4
|
|
# 0xEDF2,Battery temp. compensation,0.01,sn16,mV/K
|
|
BATTERY_TEMP_COMPENSATION = 0xEDF2
|
|
# 0XEDF1,BATTERY TYPE,1,UN8,0XFF = user
|
|
BATTERY_TYPE = 0xEDF1
|
|
# 0xEDF0,Battery maximum current,0.1,un16,A
|
|
BATTERY_MAXIMUM_CURRENT = 0xEDF0
|
|
# 0xEDEF,Battery voltage,1,un8,V
|
|
BATTERY_VOLTAGE = 0xEDEF
|
|
# 0xEDEA,Battery voltage setting,1,un8,V
|
|
BATTERY_VOLTAGE_SETTING = 0xEDEA
|
|
# 0xEDE8,BMS present,-,un8,0=no, 1=yes
|
|
BMS_PRESENT = 0xEDE8
|
|
# 0xEDE7,Tail current,0.1,un16,
|
|
TAIL_CURRENT = 0xEDE7
|
|
# 0xEDE6,Low temperature charge current,0.1,un16,A, 0xFFFF=use max
|
|
LOW_TEMPERATURE_CHARGE_CURRENT = 0xEDE6
|
|
# 0xEDE5,Auto equalise stop on voltage,-,un8,0=no, 1=yes
|
|
AUTO_EQUALISE_STOP_ON_VOLTAGE = 0xEDE5
|
|
# 0xEDE4,Equalisation current level,1,un8,% (of 0xEDF0)
|
|
EQUALISATION_CURRENT_LEVEL = 0xEDE4
|
|
# 0xEDE3,Equalisation duration,0.01,un16,hours
|
|
EQUALISATION_DURATION = 0xEDE3
|
|
# 0xED2E,Re-bulk voltage offset,0.01,un16,V
|
|
RE_BULK_VOLTAGE_OFFSET = 0xED2E
|
|
# 0xEDE0,Battery low temperature level,0.01,sn16,°C
|
|
BATTERY_LOW_TEMPERATURE_LEVEL = 0xEDE0
|
|
# 0xEDCA,Voltage compensation,0.01,un16,V
|
|
VOLTAGE_COMPENSATION = 0xEDCA
|
|
|
|
# Charger data registers
|
|
# 0xEDEC,Battery temperature,0.01,un16,K
|
|
BATTERY_TEMPERATURE = 0xEDEC
|
|
# 0xEDDF,Charger maximum current,0.01,un16,A
|
|
CHARGER_MAXIMUM_CURRENT = 0xEDDF
|
|
# 0xEDDD,System yield,0.01,un32,kWh
|
|
SYSTEM_YIELD = 0xEDDD
|
|
# 0xEDDC,User yield (*2),0.01,un32,kWh
|
|
USER_YIELD = 0xEDDC
|
|
# 0xEDDB,Charger internal temperature,0.01,sn16,°C
|
|
CHARGER_INTERNAL_TEMPERATURE = 0xEDDB
|
|
# 0xEDDA,Charger error code,-,un8,-
|
|
CHARGER_ERROR_CODE = 0xEDDA
|
|
# 0xEDD7,Charger current,0.1,un16,A
|
|
CHARGER_CURRENT = 0xEDD7
|
|
# 0xEDD5,Charger voltage,0.01,un16,V
|
|
CHARGER_VOLTAGE = 0xEDD5
|
|
# 0xEDD4,Additional charger state info,-,un8,-
|
|
ADDITIONAL_CHARGER_STATE_INFO = 0xEDD4
|
|
# 0xEDD3,Yield today,0.01,(*4),kWh
|
|
YIELD_TODAY = 0xEDD3
|
|
# 0xEDD2,Maximum power today,1,un16,W
|
|
MAXIMUM_POWER_TODAY = 0xEDD2
|
|
# 0xEDD1,Yield yesterday,0.01,(*4),kWh
|
|
YIELD_YESTERDAY = 0xEDD1
|
|
# 0xEDD0,Maximum power yesterday,1,un16,W
|
|
MAXIMUM_POWER_YESTERDAY = 0xEDD0
|
|
# 0xEDCE,Voltage settings range,-,un16,-
|
|
VOLTAGE_SETTINGS_RANGE = 0xEDCE
|
|
# 0xEDCD,History version,-,un8,-
|
|
HISTORY_VERSION = 0xEDCD
|
|
# 0xEDCC,Streetlight version,-,un8,-
|
|
STREETLIGHT_VERSION = 0xEDCC
|
|
# 0x2211,Adjustable voltage minimum,0.01,un16,V
|
|
ADJUSTABLE_VOLTAGE_MINIMUM = 0x2211
|
|
# 0x2212 Adjustable voltage maximum 0.01 un16 V
|
|
ADJUSTABLE_VOLTAGE_MAXIMUM = 0x2212
|
|
|
|
# Solar panel data registers
|
|
# 0xEDBC,Panel power,0.01,un32,W
|
|
PANEL_POWER = 0xEDBC
|
|
# 0xEDBB,Panel voltage,0.01,un16,V
|
|
PANEL_VOLTAGE = 0xEDBB
|
|
# 0xEDBD,Panel current,0.1,un16,A
|
|
PANEL_CURRENT = 0xEDBD
|
|
# 0xEDB8,Panel maximum voltage,0.01,un16,V
|
|
PANEL_MAXIMUM_VOLTAGE = 0xEDB8
|
|
# 0xEDB3,Tracker mode,-,un8,-
|
|
TRACKER_MODE = 0xEDB3
|
|
|
|
# Load output data/settings registers
|
|
# 0xEDAD,Load current,0.1,un16,A
|
|
LOAD_CURRENT = 0xEDAD
|
|
# 0xEDAC,Load offset voltage,0.01,un16,V
|
|
LOAD_OFFSET_VOLTAGE = 0xEDAC
|
|
# 0xEDAB,Load output control,-,un8,-
|
|
LOAD_OUTPUT_CONTROL = 0xEDAB
|
|
# 0xEDA9,Load output voltage,0.01,un16,V
|
|
LOAD_OUTPUT_VOLTAGE = 0xEDA9
|
|
# 0xEDA8,Load output state,-,un8,-
|
|
LOAD_OUTPUT_STATE = 0xEDA8
|
|
# 0xED9D,Load switch high level,0.01,un16,V
|
|
LOAD_SWITCH_HIGH_LEVEL = 0xED9D
|
|
# 0xED9C,Load switch low level,0.01,un16,V
|
|
LOAD_SWITCH_LOW_LEVEL = 0xED9C
|
|
# 0xED91,Load output off reason,-,un8,-
|
|
LOAD_OUTPUT_OFF_REASON = 0xED91
|
|
# 0xED90,Load AES timer,1,un16,minute
|
|
LOAD_AES_TIMER = 0xED90
|
|
|
|
# Relay settings registers
|
|
# 0xEDD9,Relay operation mode,-,un8,-
|
|
RELAY_OPERATION_MODE = 0xEDD9
|
|
# 0x0350,Relay battery low voltage set,0.01,un16,V
|
|
RELAY_BATTERY_LOW_VOLTAGE_SET = 0x0350
|
|
# 0x0351,Relay battery low voltage clear,0.01,un16,V
|
|
RELAY_BATTERY_LOW_VOLTAGE_CLEAR = 0x0351
|
|
# 0x0352,Relay battery high voltage set,0.01,un16,V
|
|
RELAY_BATTERY_HIGH_VOLTAGE_SET = 0x0352
|
|
# 0x0353,Relay battery high voltage clear,0.01,un16,V
|
|
RELAY_BATTERY_HIGH_VOLTAGE_CLEAR = 0x0353
|
|
# 0xEDBA,Relay panel high voltage set,0.01,un16,V
|
|
RELAY_PANEL_HIGH_VOLTAGE_SET = 0xEDBA
|
|
# 0xEDB9,Relay panel high voltage clear,0.01,un16,V
|
|
RELAY_PANEL_HIGH_VOLTAGE_CLEAR = 0xEDB9
|
|
# 0x100A Relay minimum enabled time 1 un16 minute
|
|
RELAY_MINIMUM_ENABLED_TIME = 0x100A
|
|
|
|
# Lighting controller timer
|
|
# Timer events 0..5,-,un32,-
|
|
TIMER_EVENT_0 = 0xEDA0
|
|
# 0xEDA7,Mid-point shift,1,sn16,min
|
|
MID_POINT_SHIFT = 0xEDA7
|
|
# 0xED9B,Gradual dim speed,1,un8,s
|
|
GRADUAL_DIM_SPEED = 0xED9B
|
|
# 0xED9A,Panel voltage night,0.01,un16,V
|
|
PANEL_VOLTAGE_NIGHT = 0xED9A
|
|
# 0xED99,Panel voltage day,0.01,un16,V
|
|
PANEL_VOLTAGE_DAY = 0xED99
|
|
# 0xED96,Sunset delay,1,un16,min
|
|
SUNSET_DELAY = 0xED96
|
|
# 0xED97,Sunrise delay,1,un16,min
|
|
SUNRISE_DELAY = 0xED97
|
|
# 0xED90,AES Timer,1,un16,min
|
|
AES_TIMER = 0xED90
|
|
# 0x2030,Solar activity,-,un8,0=dark, 1=light
|
|
SOLAR_ACTIVITY = 0x2030
|
|
# 0x2031 Time-of-day 1 un16 min, 0=mid-night
|
|
TIME_OF_DAY = 0x2031
|
|
|
|
# VE.Direct port functions
|
|
# 0xED9E,TX Port operation mode,-,un8,-
|
|
TX_PORT_OPERATION_MODE = 0xED9E
|
|
# 0xED98 RX Port operation mode - un8 -
|
|
RX_PORT_OPERATION_MODE = 0xED98
|
|
|
|
# Restore factory defaults
|
|
# 0x0004,Restore default
|
|
RESTORE_DEFAULT = 0x0004
|
|
|
|
# History data
|
|
# 0x1030,Clear history
|
|
CLEAR_HISTORY = 0x1030
|
|
# 0x104F,Total history
|
|
TOTAL_HISTORY = 0x104F
|
|
# Items
|
|
HISTORY_0 = 0x1050
|
|
|
|
# Pluggable display settings
|
|
# 0x0400,Display backlight mode,,,un8
|
|
DISPLAY_BACKLIGHT_MODE = 0x0400
|
|
# 0x0401,Display backlight intensity,,un8,
|
|
DISPLAY_BACKLIGHT_INTENSITY = 0x0401
|
|
# 0x0402,Display scroll text speed,,un8,
|
|
DISPLAY_SCROLL_TEXT_SPEED = 0x0402
|
|
# 0x0403,Display setup lock (*2),,,un8
|
|
DISPLAY_SETUP_LOCK = 0x0403
|
|
# 0x0404,Display temperature unit (*2),,,un8
|
|
DISPLAY_TEMPERATURE_UNIT = 0x0404
|
|
|
|
# Remote control registers
|
|
# 0x2000,Charge algorithm version,-,un8,-
|
|
CHARGE_ALGORITHM_VERSION = 0x2000
|
|
# 0x2001,Charge voltage set-point,0.01,un16,V
|
|
CHARGE_VOLTAGE_SET_POINT = 0x2001
|
|
# 0x2002,Battery voltage sense,0.01,un16,V
|
|
BATTERY_VOLTAGE_SENSE = 0x2002
|
|
# 0x2003,Battery temperature sense,0.01,sn16,°C
|
|
BATTERY_TEMPERATURE_SENSE = 0x2003
|
|
# 0x2004,Remote command,-,un8,-
|
|
REMOTE_COMMAND = 0x2004
|
|
# 0x2007,Charge state elapsed time,1,un32,ms
|
|
CHARGE_STATE_ELAPSED_TIME = 0x2007
|
|
# 0x2008,Absorption time,0.01,un16,hours
|
|
ABSORPTION_TIME = 0x2008
|
|
# 0x2009,Error code,-,un8,-
|
|
ERROR_CODE = 0x2009
|
|
# 0x200A,Battery charge current,0.001,sn32,A
|
|
BATTERY_CHARGE_CURRENT = 0x200A
|
|
# 0x200B,Battery idle voltage,0.01,un16,V
|
|
BATTERY_IDLE_VOLTAGE = 0x200B
|
|
# 0x200C,Device state,-,un8,-
|
|
REMOTE_DEVICE_STATE = 0x200C
|
|
# 0x200D,Network info,-,un8,-
|
|
NETWORK_INFO = 0x200D
|
|
# 0x200E,Network mode,-,un8,-
|
|
NETWORK_MODE = 0x200E
|
|
# 0x200F,Network status register,-,un8,-
|
|
NETWORK_STATUS_REGISTER = 0x200F
|
|
# 0x2013,Total charge current,0.001,sn32,A
|
|
TOTAL_CHARGE_CURRENT = 0x2013
|
|
# 0x2014,Charge current percentage,1,un8,%
|
|
CHARGE_CURRENT_PERCENTAGE = 0x2014
|
|
# 0x2015,Charge current limit,0.1,un16,A
|
|
CHARGE_CURRENT_LIMIT = 0x2015
|
|
# 0x2018,Manual equalisation pending,-,un8,-
|
|
MANUAL_EQUALISATION_PENDING = 0x2018
|
|
# 0x2027,Total DC input power,0.01,un32,W
|
|
TOTAL_DC_INPUT_POWER = 0x2027
|
|
|
|
|
|
# Product information registers
|
|
PRODUCT_ID = Register(0x0100, 'Product ID', 'xHx')
|
|
GROUP_ID = Register(0x0104, 'Group ID', 'B')
|
|
SERIAL_NUMBER = Register(0x010A, 'Serial number', 'S')
|
|
MODEL_NAME = Register(0x010B, 'Model name', 'S')
|
|
CAPABILITIES = Register(0x0140, 'Capabilities', 'I', None, None,
|
|
schema.Capabilities)
|
|
|
|
# Generic device control registers
|
|
DEVICE_MODE = Register(0x0200, 'Device mode', 'B')
|
|
DEVICE_STATE = Register(0x0201, 'Device state', 'B', None, None, schema.State)
|
|
REMOTE_CONTROL_USED = Register(0x0202, 'Remote control used', 'I')
|
|
DEVICE_OFF_REASON = Register(0x0205, 'Device off reason', 'B')
|
|
DEVICE_OFF_REASON_EXTENDED = Register(0x0207, 'Device off reason', 'I')
|
|
|
|
# Battery settings registers
|
|
BATTERYSAFE_MODE = Register(0xEDFF, '')
|
|
ADAPTIVE_MODE = Register(0xEDFE, 'Adaptive mode', 'B', None, None, bool)
|
|
AUTOMATIC_EQUALISATION_MODE = Register(0xEDFD, 'Automatic equalisation mode',
|
|
'B')
|
|
|
|
BATTERY_BULK_TIME_LIMIT = Register(0xEDFC, 'Battery bulk time limit', 'H',
|
|
None, 0.01, _ureg.hour)
|
|
BATTERY_ABSORPTION_TIME_LIMIT = Register(0xEDFB,
|
|
'Battery absorption time limit', 'H',
|
|
None, 0.01, _ureg.hour)
|
|
BATTERY_ABSORPTION_VOLTAGE = Register(0xEDF7, 'Battery absorption voltage',
|
|
'H', None, 0.01, _ureg.volt)
|
|
BATTERY_FLOAT_VOLTAGE = Register(0xEDF6, 'Battery float voltage', 'H', None,
|
|
0.01, _ureg.volt)
|
|
BATTERY_EQUALISATION_VOLTAGE = Register(0xEDF4, 'Battery equalisation voltage',
|
|
'H', None, 0.01, _ureg.volt)
|
|
BATTERY_TEMP_COMPENSATION = Register(0xEDF2, 'Battery temp. compensation', 'h',
|
|
None, 0.01, 'mV/K')
|
|
BATTERY_TYPE = Register(0XEDF1, 'Battery type', 'B')
|
|
BATTERY_MAXIMUM_CURRENT = Register(0xEDF0, 'Battery maximum current', 'H',
|
|
None, 0.1, _ureg.ampere)
|
|
BATTERY_VOLTAGE = Register(0xEDEF, 'Battery voltage', 'B', None, None,
|
|
_ureg.volt)
|
|
BATTERY_VOLTAGE_SETTING = Register(0xEDEA, 'Battery voltage setting', 'B',
|
|
None, None, _ureg.volt)
|
|
BMS_PRESENT = Register(0xEDE8, 'BMS present', 'B', None, 1, bool)
|
|
TAIL_CURRENT = Register(0xEDE7, 'Tail current', 'H', None, 0.1, '')
|
|
LOW_TEMPERATURE_CHARGE_CURRENT = Register(0xEDE6,
|
|
'Low temperature charge current',
|
|
'H', None, 0.1, _ureg.ampere)
|
|
AUTO_EQUALISE_STOP_ON_VOLTAGE = Register(0xEDE5,
|
|
'Auto equalise stop on voltage', 'B',
|
|
None, 1, bool)
|
|
EQUALISATION_CURRENT_LEVEL = Register(0xEDE4, 'Equalisation current level',
|
|
'B')
|
|
EQUALISATION_DURATION = Register(0xEDE3, 'Equalisation duration', 'H', None,
|
|
0.01, _ureg.hour)
|
|
RE_BULK_VOLTAGE_OFFSET = Register(0xED2E, 'Re-bulk voltage offset', 'H', None,
|
|
0.01, _ureg.volt)
|
|
BATTERY_LOW_TEMPERATURE_LEVEL = Register(0xEDE0,
|
|
'Battery low temperature level', 'h',
|
|
None, 0.01, _ureg.degC)
|
|
VOLTAGE_COMPENSATION = Register(0xEDCA, 'Voltage compensation', 'H', None,
|
|
0.01, _ureg.volt)
|
|
|
|
# Charger data registers
|
|
BATTERY_TEMPERATURE = Register(0xEDEC, 'Battery temperature', 'H', None, 0.01,
|
|
_ureg.kelvin)
|
|
CHARGER_MAXIMUM_CURRENT = Register(0xEDDF, 'Charger maximum current', 'H',
|
|
None, 0.01, _ureg.ampere)
|
|
SYSTEM_YIELD = Register(0xEDDD, 'System yield', 'I', None, 10, _ureg.watt_hour)
|
|
USER_YIELD = Register(0xEDDC, 'User yield', 'I', None, 10, _ureg.watt_hour)
|
|
CHARGER_INTERNAL_TEMPERATURE = Register(0xEDDB, 'Charger internal temperature',
|
|
'h', None, 0.01, _ureg.degC)
|
|
CHARGER_ERROR_CODE = Register(0xEDDA, 'Charger error code', 'B', None, None,
|
|
schema.Err)
|
|
CHARGER_CURRENT = Register(0xEDD7, 'Charger current', 'H', None, 0.1,
|
|
_ureg.ampere)
|
|
CHARGER_VOLTAGE = Register(0xEDD5, 'Charger voltage', 'H', None, 0.01,
|
|
_ureg.volt)
|
|
ADDITIONAL_CHARGER_STATE_INFO = Register(0xEDD4,
|
|
'Additional charger state info', 'B',
|
|
None, None,
|
|
schema.AdditionalChargerState)
|
|
YIELD_TODAY = Register(0xEDD3, 'Yield today', 'H', None, 10, _ureg.watt_hour)
|
|
MAXIMUM_POWER_TODAY = Register(0xEDD2, 'Maximum power today', 'H', None, 1,
|
|
_ureg.watt)
|
|
YIELD_YESTERDAY = Register(0xEDD1, 'Yield yesterday', 'H', None, 10,
|
|
_ureg.watt_hour)
|
|
MAXIMUM_POWER_YESTERDAY = Register(0xEDD0, 'Maximum power yesterday', 'H',
|
|
None, 1, _ureg.watt)
|
|
VOLTAGE_SETTINGS_RANGE = Register(
|
|
0xEDCE,
|
|
'Voltage settings range',
|
|
'H',
|
|
None,
|
|
)
|
|
HISTORY_VERSION = Register(0xEDCD, 'History version', 'B')
|
|
STREETLIGHT_VERSION = Register(0xEDCC, 'Streetlight version', 'B')
|
|
ADJUSTABLE_VOLTAGE_MINIMUM = Register(0x2211, 'Adjustable voltage minimum',
|
|
'H', None, 0.01, _ureg.volt)
|
|
ADJUSTABLE_VOLTAGE_MAXIMUM = Register(0x2212, 'Adjustable voltage maximum',
|
|
'H', None, 0.01, _ureg.volt)
|
|
|
|
# Solar panel data registers
|
|
PANEL_POWER = Register(0xEDBC, 'Panel power', 'I', None, 0.01, _ureg.watt)
|
|
PANEL_VOLTAGE = Register(0xEDBB, 'Panel voltage', 'H', None, 0.01, _ureg.volt)
|
|
PANEL_CURRENT = Register(0xEDBD, 'Panel current', 'H', None, 0.1, _ureg.ampere)
|
|
PANEL_MAXIMUM_VOLTAGE = Register(0xEDB8, 'Panel maximum voltage', 'H', None,
|
|
0.01, _ureg.volt)
|
|
TRACKER_MODE = Register(0xEDB3, 'Tracker mode', 'B', None, None,
|
|
schema.TrackerMode)
|
|
|
|
# Load output data/settings registers
|
|
LOAD_CURRENT = Register(0xEDAD, 'Load current', 'H', None, 0.1, _ureg.ampere)
|
|
# TODO: spec says H.
|
|
LOAD_OFFSET_VOLTAGE = Register(0xEDAC, 'Load offset voltage', 'B', None, 0.01,
|
|
_ureg.volt)
|
|
LOAD_OUTPUT_CONTROL = Register(0xEDAB, 'Load output control', 'B', None, None,
|
|
schema.LoadOutputControl)
|
|
LOAD_OUTPUT_VOLTAGE = Register(0xEDA9, 'Load output voltage', 'H', None, 0.01,
|
|
_ureg.volt)
|
|
LOAD_OUTPUT_STATE = Register(0xEDA8, 'Load output state', 'B')
|
|
LOAD_SWITCH_HIGH_LEVEL = Register(0xED9D, 'Load switch high level', 'H', None,
|
|
0.01, _ureg.volt)
|
|
LOAD_SWITCH_LOW_LEVEL = Register(0xED9C, 'Load switch low level', 'H', None,
|
|
0.01, _ureg.volt)
|
|
LOAD_OUTPUT_OFF_REASON = Register(0xED91, 'Load output off reason', 'B', None,
|
|
None, schema.OffReason)
|
|
LOAD_AES_TIMER = Register(0xED90, 'Load AES timer', 'H', None, 1, _ureg.minute)
|
|
|
|
# Relay settings registers
|
|
RELAY_OPERATION_MODE = Register(0xEDD9, 'Relay operation mode', 'B', None,
|
|
None, schema.RelayMode)
|
|
RELAY_BATTERY_LOW_VOLTAGE_SET = Register(0x0350,
|
|
'Relay battery low voltage set', 'H',
|
|
None, 0.01, _ureg.volt)
|
|
RELAY_BATTERY_LOW_VOLTAGE_CLEAR = Register(0x0351,
|
|
'Relay battery low voltage clear',
|
|
'H', None, 0.01, _ureg.volt)
|
|
RELAY_BATTERY_HIGH_VOLTAGE_SET = Register(0x0352,
|
|
'Relay battery high voltage set',
|
|
'H', None, 0.01, _ureg.volt)
|
|
RELAY_BATTERY_HIGH_VOLTAGE_CLEAR = Register(
|
|
0x0353, 'Relay battery high voltage clear', 'H', None, 0.01, _ureg.volt)
|
|
RELAY_PANEL_HIGH_VOLTAGE_SET = Register(0xEDBA, 'Relay panel high voltage set',
|
|
'H', None, 0.01, _ureg.volt)
|
|
RELAY_PANEL_HIGH_VOLTAGE_CLEAR = Register(0xEDB9,
|
|
'Relay panel high voltage clear',
|
|
'H', None, 0.01, _ureg.volt)
|
|
RELAY_MINIMUM_ENABLED_TIME = Register(0x100A, 'Relay minimum enabled time',
|
|
'H', None, 1, _ureg.minute)
|
|
|
|
# Lighting controller timer
|
|
# TIMER_EVENT_0 = Register(, 'Timer events None, 0..5,un32,-,-')
|
|
MID_POINT_SHIFT = Register(0xEDA7, 'Mid-point shift', 'h', None, 60,
|
|
_ureg.second)
|
|
GRADUAL_DIM_SPEED = Register(0xED9B, 'Gradual dim speed', 'B', None, 1,
|
|
_ureg.second)
|
|
PANEL_VOLTAGE_NIGHT = Register(0xED9A, 'Panel voltage night', 'H', None, 0.01,
|
|
_ureg.volt)
|
|
PANEL_VOLTAGE_DAY = Register(0xED99, 'Panel voltage day', 'H', None, 0.01,
|
|
_ureg.volt)
|
|
SUNSET_DELAY = Register(0xED96, 'Sunset delay', 'H', None, 60, _ureg.second)
|
|
SUNRISE_DELAY = Register(0xED97, 'Sunrise delay', 'H', None, 60, _ureg.second)
|
|
AES_TIMER = Register(0xED90, 'AES Timer', 'H', None, 60, _ureg.second)
|
|
SOLAR_ACTIVITY = Register(0x2030, 'Solar activity', 'B', None, 1, bool)
|
|
TIME_OF_DAY = Register(0x2031, 'Time-of-day', 'H')
|
|
|
|
# VE.Direct port functions
|
|
TX_PORT_OPERATION_MODE = Register(0xED9E, 'TX Port operation mode', 'B', None,
|
|
None, schema.TXPortMode)
|
|
RX_PORT_OPERATION_MODE = Register(0xED98, 'RX Port operation mode', 'B', None,
|
|
None, schema.RXPortMode)
|
|
|
|
# Restore factory defaults
|
|
RESTORE_DEFAULT = Register(0x0004, 'Restore default')
|
|
|
|
# History data
|
|
# CLEAR_HISTORY = Register(0x1030, 'Total history')
|
|
# HISTORY_0 = Register(0, 'Clear history')
|
|
# TOTAL_HISTORY = Register(0x104F, 'Items')
|
|
|
|
# Pluggable display settings
|
|
DISPLAY_BACKLIGHT_MODE = Register(0x0400, 'Display backlight mode,,,un8')
|
|
DISPLAY_BACKLIGHT_INTENSITY = Register(0x0401, 'Display backlight intensity',
|
|
'B')
|
|
DISPLAY_SCROLL_TEXT_SPEED = Register(0x0402, 'Display scroll text speed', 'B',
|
|
None)
|
|
DISPLAY_SETUP_LOCK = Register(0x0403, 'Display setup lock', 'B')
|
|
DISPLAY_TEMPERATURE_UNIT = Register(0x0404, 'Display temperature unit', 'B',
|
|
None)
|
|
|
|
# Remote control registers
|
|
CHARGE_ALGORITHM_VERSION = Register(0x2000, 'Charge algorithm version', 'B',
|
|
None)
|
|
CHARGE_VOLTAGE_SET_POINT = Register(0x2001, 'Charge voltage set-point', 'H',
|
|
None, 0.01, _ureg.volt)
|
|
BATTERY_VOLTAGE_SENSE = Register(0x2002, 'Battery voltage sense', 'H', None,
|
|
0.01, _ureg.volt)
|
|
BATTERY_TEMPERATURE_SENSE = Register(0x2003, 'Battery temperature sense', 'h',
|
|
None, 0.01, _ureg.degC)
|
|
REMOTE_COMMAND = Register(0x2004, 'Remote command', 'B')
|
|
CHARGE_STATE_ELAPSED_TIME = Register(0x2007, 'Charge state elapsed time', 'I',
|
|
None, 1e-3, _ureg.second)
|
|
ABSORPTION_TIME = Register(0x2008, 'Absorption time', 'H', None, 0.01,
|
|
_ureg.hour)
|
|
ERROR_CODE = Register(0x2009, 'Error code', 'B')
|
|
BATTERY_CHARGE_CURRENT = Register(0x200A, 'Battery charge current', 'i', None,
|
|
0.001, _ureg.ampere)
|
|
BATTERY_IDLE_VOLTAGE = Register(0x200B, 'Battery idle voltage', 'H', None,
|
|
0.01, _ureg.volt)
|
|
REMOTE_DEVICE_STATE = Register(0x200C, 'Device state', 'B')
|
|
NETWORK_INFO = Register(0x200D, 'Network info', 'B')
|
|
NETWORK_MODE = Register(0x200E, 'Network mode', 'B')
|
|
NETWORK_STATUS_REGISTER = Register(0x200F, 'Network status register', 'B',
|
|
None)
|
|
TOTAL_CHARGE_CURRENT = Register(0x2013, 'Total charge current', 'i', None,
|
|
0.001, _ureg.ampere)
|
|
CHARGE_CURRENT_PERCENTAGE = Register(0x2014, 'Charge current percentage', 'B')
|
|
CHARGE_CURRENT_LIMIT = Register(0x2015, 'Charge current limit', 'H', None, 0.1,
|
|
_ureg.ampere)
|
|
MANUAL_EQUALISATION_PENDING = Register(0x2018, 'Manual equalisation pending',
|
|
'B')
|
|
TOTAL_DC_INPUT_POWER = Register(0x2027, 'Total DC input power', 'I', None,
|
|
0.01, _ureg.watt)
|
|
|
|
REGISTERS = {
|
|
ID(r.id): r
|
|
for r in globals().values() if isinstance(r, Register)
|
|
}
|
|
|
|
for register in REGISTERS.values():
|
|
assert register.mode is None, register
|
|
if register.scale is not None:
|
|
assert isinstance(register.scale, (float, int)), register
|
|
|
|
|
|
@dataclass
|
|
class Information:
|
|
product_id: int = Field(PRODUCT_ID)
|
|
# group_id: float = Field(GROUP_ID)
|
|
serial_number: str = Field(SERIAL_NUMBER)
|
|
model_name: str = Field(MODEL_NAME)
|
|
capabilities: schema.Capabilities = Field(CAPABILITIES)
|
|
|
|
|
|
@dataclass
|
|
class Generic:
|
|
mode: int = Field(DEVICE_MODE)
|
|
state: schema.State = Field(DEVICE_STATE)
|
|
|
|
|
|
@dataclass
|
|
class Settings:
|
|
absorption_time_limit: float = Field(BATTERY_ABSORPTION_TIME_LIMIT)
|
|
absorption_voltage: float = Field(BATTERY_ABSORPTION_VOLTAGE)
|
|
float_voltage: float = Field(BATTERY_FLOAT_VOLTAGE)
|
|
equalisation_voltage: float = Field(BATTERY_EQUALISATION_VOLTAGE)
|
|
temp_compensation: float = Field(BATTERY_TEMP_COMPENSATION)
|
|
type: int = Field(BATTERY_TYPE)
|
|
maximum_current: float = Field(BATTERY_MAXIMUM_CURRENT)
|
|
voltage: float = Field(BATTERY_VOLTAGE)
|
|
voltage_setting: float = Field(BATTERY_VOLTAGE_SETTING)
|
|
|
|
|
|
@dataclass
|
|
class Charger:
|
|
maximum_current: float = Field(CHARGER_MAXIMUM_CURRENT)
|
|
system_yield: float = Field(SYSTEM_YIELD)
|
|
user_yield: float = Field(USER_YIELD)
|
|
internal_temperature: float = Field(CHARGER_INTERNAL_TEMPERATURE)
|
|
error_code: schema.Err = Field(CHARGER_ERROR_CODE)
|
|
current: float = Field(CHARGER_CURRENT)
|
|
voltage: float = Field(CHARGER_VOLTAGE)
|
|
additional_state_info: schema.AdditionalChargerState = Field(
|
|
ADDITIONAL_CHARGER_STATE_INFO)
|
|
yield_today: float = Field(YIELD_TODAY)
|
|
maximum_power_today: float = Field(MAXIMUM_POWER_TODAY)
|
|
yield_yesterday: float = Field(YIELD_YESTERDAY)
|
|
maximum_power_yesterday: float = Field(MAXIMUM_POWER_YESTERDAY)
|
|
|
|
|
|
@dataclass
|
|
class Solar:
|
|
power: float = Field(PANEL_POWER)
|
|
voltage: float = Field(PANEL_VOLTAGE)
|
|
maximum_voltage: float = Field(PANEL_MAXIMUM_VOLTAGE)
|
|
tracker_mode: schema.TrackerMode = Field(TRACKER_MODE)
|
|
|
|
|
|
@dataclass
|
|
class Load:
|
|
current: float = Field(LOAD_CURRENT)
|
|
offset_voltage: float = Field(LOAD_OFFSET_VOLTAGE)
|
|
output_control: float = Field(LOAD_OUTPUT_CONTROL)
|
|
output_state: float = Field(LOAD_OUTPUT_STATE)
|
|
switch_high_level: float = Field(LOAD_SWITCH_HIGH_LEVEL)
|
|
mswitch_low_level: float = Field(LOAD_SWITCH_LOW_LEVEL)
|
|
|
|
|
|
GROUPS = (Information, Generic, Settings, Charger, Solar, Load)
|
|
|
|
PRODUCT_IDS = {
|
|
0x203: 'BMV-700',
|
|
0x204: 'BMV-702',
|
|
0x205: 'BMV-700H',
|
|
0x0300: 'BlueSolar MPPT 70|15',
|
|
0xA040: 'BlueSolar MPPT 75|50',
|
|
0xA041: 'BlueSolar MPPT 150|35',
|
|
0xA042: 'BlueSolar MPPT 75|15',
|
|
0xA043: 'BlueSolar MPPT 100|15',
|
|
0xA044: 'BlueSolar MPPT 100|30',
|
|
0xA045: 'BlueSolar MPPT 100|50',
|
|
0xA046: 'BlueSolar MPPT 150|70',
|
|
0xA047: 'BlueSolar MPPT 150|100',
|
|
0xA049: 'BlueSolar MPPT 100|50 rev2',
|
|
0xA04A: 'BlueSolar MPPT 100|30 rev2',
|
|
0xA04B: 'BlueSolar MPPT 150|35 rev2',
|
|
0xA04C: 'BlueSolar MPPT 75|10',
|
|
0xA04D: 'BlueSolar MPPT 150|45',
|
|
0xA04E: 'BlueSolar MPPT 150|60',
|
|
0xA04F: 'BlueSolar MPPT 150|85',
|
|
0xA050: 'SmartSolar MPPT 250|100',
|
|
0xA051: 'SmartSolar MPPT 150|100',
|
|
0xA052: 'SmartSolar MPPT 150|85',
|
|
0xA053: 'SmartSolar MPPT 75|15',
|
|
0xA054: 'SmartSolar MPPT 75|10',
|
|
0xA055: 'SmartSolar MPPT 100|15',
|
|
0xA056: 'SmartSolar MPPT 100|30',
|
|
0xA057: 'SmartSolar MPPT 100|50',
|
|
0xA058: 'SmartSolar MPPT 150|35',
|
|
0xA059: 'SmartSolar MPPT 150|100 rev2',
|
|
0xA05A: 'SmartSolar MPPT 150|85 rev2',
|
|
0xA05B: 'SmartSolar MPPT 250|70',
|
|
0xA05C: 'SmartSolar MPPT 250|85',
|
|
0xA05D: 'SmartSolar MPPT 250|60',
|
|
0xA05E: 'SmartSolar MPPT 250|45',
|
|
0xA05F: 'SmartSolar MPPT 100|20',
|
|
0xA060: 'SmartSolar MPPT 100|20 48V',
|
|
0xA061: 'SmartSolar MPPT 150|45',
|
|
0xA062: 'SmartSolar MPPT 150|60',
|
|
0xA063: 'SmartSolar MPPT 150|70',
|
|
0xA064: 'SmartSolar MPPT 250|85 rev2',
|
|
0xA065: 'SmartSolar MPPT 250|100 rev2',
|
|
0xA066: 'BlueSolar MPPT 100|20',
|
|
0xA067: 'BlueSolar MPPT 100|20 48V',
|
|
0xA068: 'SmartSolar MPPT 250|60 rev2',
|
|
0xA069: 'SmartSolar MPPT 250|70 rev2',
|
|
0xA06A: 'SmartSolar MPPT 150|45 rev2',
|
|
0xA06B: 'SmartSolar MPPT 150|60 rev2',
|
|
0xA06C: 'SmartSolar MPPT 150|70 rev2',
|
|
0xA06D: 'SmartSolar MPPT 150|85 rev3',
|
|
0xA06E: 'SmartSolar MPPT 150|100 rev3',
|
|
0xA06F: 'BlueSolar MPPT 150|45 rev2',
|
|
0xA070: 'BlueSolar MPPT 150|60 rev2',
|
|
0xA071: 'BlueSolar MPPT 150|70 rev2',
|
|
0xA102: 'SmartSolar MPPT VE.Can 150/70',
|
|
0xA103: 'SmartSolar MPPT VE.Can 150/45',
|
|
0xA104: 'SmartSolar MPPT VE.Can 150/60',
|
|
0xA105: 'SmartSolar MPPT VE.Can 150/85',
|
|
0xA106: 'SmartSolar MPPT VE.Can 150/100',
|
|
0xA107: 'SmartSolar MPPT VE.Can 250/45',
|
|
0xA108: 'SmartSolar MPPT VE.Can 250/60',
|
|
0xA109: 'SmartSolar MPPT VE.Can 250/70',
|
|
0xA10A: 'SmartSolar MPPT VE.Can 250/85',
|
|
0xA10B: 'SmartSolar MPPT VE.Can 250/100',
|
|
0xA10C: 'SmartSolar MPPT VE.Can 150/70 rev2',
|
|
0xA10D: 'SmartSolar MPPT VE.Can 150/85 rev2',
|
|
0xA10E: 'SmartSolar MPPT VE.Can 150/100 rev2',
|
|
0xA10F: 'BlueSolar MPPT VE.Can 150/100',
|
|
0xA112: 'BlueSolar MPPT VE.Can 250/70',
|
|
0xA113: 'BlueSolar MPPT VE.Can 250/100',
|
|
0xA114: 'SmartSolar MPPT VE.Can 250/70 rev2',
|
|
0xA115: 'SmartSolar MPPT VE.Can 250/100 rev2',
|
|
0xA116: 'SmartSolar MPPT VE.Can 250/85 rev2',
|
|
0xA201: 'Phoenix Inverter 12V 250VA 230V',
|
|
0xA202: 'Phoenix Inverter 24V 250VA 230V',
|
|
0xA204: 'Phoenix Inverter 48V 250VA 230V',
|
|
0xA211: 'Phoenix Inverter 12V 375VA 230V',
|
|
0xA212: 'Phoenix Inverter 24V 375VA 230V',
|
|
0xA214: 'Phoenix Inverter 48V 375VA 230V',
|
|
0xA221: 'Phoenix Inverter 12V 500VA 230V',
|
|
0xA222: 'Phoenix Inverter 24V 500VA 230V',
|
|
0xA224: 'Phoenix Inverter 48V 500VA 230V',
|
|
0xA231: 'Phoenix Inverter 12V 250VA 230V',
|
|
0xA232: 'Phoenix Inverter 24V 250VA 230V',
|
|
0xA234: 'Phoenix Inverter 48V 250VA 230V',
|
|
0xA239: 'Phoenix Inverter 12V 250VA 120V',
|
|
0xA23A: 'Phoenix Inverter 24V 250VA 120V',
|
|
0xA23C: 'Phoenix Inverter 48V 250VA 120V',
|
|
0xA241: 'Phoenix Inverter 12V 375VA 230V',
|
|
0xA242: 'Phoenix Inverter 24V 375VA 230V',
|
|
0xA244: 'Phoenix Inverter 48V 375VA 230V',
|
|
0xA249: 'Phoenix Inverter 12V 375VA 120V',
|
|
0xA24A: 'Phoenix Inverter 24V 375VA 120V',
|
|
0xA24C: 'Phoenix Inverter 48V 375VA 120V',
|
|
0xA251: 'Phoenix Inverter 12V 500VA 230V',
|
|
0xA252: 'Phoenix Inverter 24V 500VA 230V',
|
|
0xA254: 'Phoenix Inverter 48V 500VA 230V',
|
|
0xA259: 'Phoenix Inverter 12V 500VA 120V',
|
|
0xA25A: 'Phoenix Inverter 24V 500VA 120V',
|
|
0xA25C: 'Phoenix Inverter 48V 500VA 120V',
|
|
0xA261: 'Phoenix Inverter 12V 800VA 230V',
|
|
0xA262: 'Phoenix Inverter 24V 800VA 230V',
|
|
0xA264: 'Phoenix Inverter 48V 800VA 230V',
|
|
0xA269: 'Phoenix Inverter 12V 800VA 120V',
|
|
0xA26A: 'Phoenix Inverter 24V 800VA 120V',
|
|
0xA26C: 'Phoenix Inverter 48V 800VA 120V',
|
|
0xA271: 'Phoenix Inverter 12V 1200VA 230V',
|
|
0xA272: 'Phoenix Inverter 24V 1200VA 230V',
|
|
0xA274: 'Phoenix Inverter 48V 1200VA 230V',
|
|
0xA279: 'Phoenix Inverter 12V 1200VA 120V',
|
|
0xA27A: 'Phoenix Inverter 24V 1200VA 120V',
|
|
0xA27C: 'Phoenix Inverter 48V 1200VA 120V',
|
|
0xA281: 'Phoenix Inverter 12V 1600VA 230V',
|
|
0xA282: 'Phoenix Inverter 24V 1600VA 230V',
|
|
0xA284: 'Phoenix Inverter 48V 1600VA 230V',
|
|
0xA291: 'Phoenix Inverter 12V 2000VA 230V',
|
|
0xA292: 'Phoenix Inverter 24V 2000VA 230V',
|
|
0xA294: 'Phoenix Inverter 48V 2000VA 230V',
|
|
0xA2A1: 'Phoenix Inverter 12V 3000VA 230V',
|
|
0xA2A2: 'Phoenix Inverter 24V 3000VA 230V',
|
|
0xA2A4: 'Phoenix Inverter 48V 3000VA 230V',
|
|
0xA340: 'Phoenix Smart IP43 Charger 12|50 (1+1)',
|
|
0xA341: 'Phoenix Smart IP43 Charger 12|50 (3)',
|
|
0xA342: 'Phoenix Smart IP43 Charger 24|25 (1+1)',
|
|
0xA343: 'Phoenix Smart IP43 Charger 24|25 (3)',
|
|
0xA344: 'Phoenix Smart IP43 Charger 12|30 (1+1)',
|
|
0xA345: 'Phoenix Smart IP43 Charger 12|30 (3)',
|
|
0xA346: 'Phoenix Smart IP43 Charger 24|16 (1+1)',
|
|
0xA347: 'Phoenix Smart IP43 Charger 24|16 (3)',
|
|
}
|