vedirect/vedirect/mppt.py
Michael Hope 9a36e59d38
All checks were successful
continuous-integration/drone/push Build is passing
vedirect: fixed up the MPPT scale factors
2021-03-28 17:45:23 +02:00

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)',
}