Skip to content

Commit

Permalink
testing combining pi30 and pi30max
Browse files Browse the repository at this point in the history
  • Loading branch information
jblance authored Jan 27, 2025
1 parent 999ef16 commit 1783018
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 14 deletions.
4 changes: 4 additions & 0 deletions powermon/protocols/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Protocol(StrEnum):
PI18 = auto() # WIP
PI30 = auto()
PI30MAX = auto()
PI30MAXA = auto()
PI30MST = auto()
DALY = auto()
NEEY = auto()
Expand Down Expand Up @@ -52,6 +53,9 @@ def get_protocol_definition(protocol, model=None):
case Protocol.PI30MAX:
from powermon.protocols.pi30max import PI30MAX
return PI30MAX(model=model)
case Protocol.PI30MAXA:
from powermon.protocols.pi30 import PI30
return PI30(model="MAX")
case Protocol.PI30MST:
from powermon.protocols.pi30max import PI30MAX
return PI30MAX(model='PIP4048MST')
Expand Down
114 changes: 102 additions & 12 deletions powermon/protocols/pi30.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

log = logging.getLogger("pi30")

SOURCE_PRIORITY_LIST = ["Utility > Solar > Battery", "Solar > Utility > Battery", "Solar > Battery > Utility"]

OUTPUT_MODE_LIST = ["single machine output",
"parallel output",
"Phase 1 of 3 Phase output",
Expand All @@ -30,6 +32,51 @@
"LIb-protocol compatible",
"3rd party Lithium"]

MST_QPIGS2 = {
"name": "QPIGS2",
"description": "General Status Parameters inquiry 2",
"result_type": ResultType.ORDERED,
"reading_definitions": [
{"description": "PV2 Input Current",
"reading_type": ReadingType.CURRENT, "icon": "mdi:solar-power", "device_class": "current", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV2 Input Voltage",
"reading_type": ReadingType.VOLTS, "icon": "mdi:solar-power", "device_class": "voltage", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "Battery voltage from SCC 2",
"reading_type": ReadingType.VOLTS, "icon": "mdi:solar-power", "device_class": "voltage", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV2 Charging Power",
"reading_type": ReadingType.WATTS, "icon": "mdi:solar-power", "device_class": "power", "state_class": "measurement",
"response_type": ResponseType.INT},
{"description": "Device status", "reading_type": ReadingType.MESSAGE,},
{"description": "AC charging current",
"reading_type": ReadingType.CURRENT, "icon": "mdi:transmission-tower-export", "device_class": "current", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "AC charging power",
"reading_type": ReadingType.WATTS, "icon": "mdi:transmission-tower-export", "device_class": "power", "state_class": "measurement",
"response_type": ResponseType.INT},
{"description": "PV3 Input Current",
"reading_type": ReadingType.CURRENT, "icon": "mdi:solar-power", "device_class": "current", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV3 Input Voltage",
"reading_type": ReadingType.VOLTS, "icon": "mdi:solar-power", "device_class": "voltage", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "Battery voltage from SCC 3",
"reading_type": ReadingType.VOLTS, "icon": "mdi:solar-power", "device_class": "voltage", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV3 Charging Power",
"reading_type": ReadingType.WATTS, "icon": "mdi:solar-power", "device_class": "power", "state_class": "measurement",
"response_type": ResponseType.INT},
{"description": "PV total charging power",
"reading_type": ReadingType.WATTS, "icon": "mdi:solar-power", "device_class": "power", "state_class": "measurement",
"response_type": ResponseType.INT},
],
"test_responses": [
b"(03.1 327.3 52.3 123 1 1234 122 327.1 52.4 234 567 \x23\xc7\r",
],
}

SETTER_COMMANDS = {
"F": {
"name": "F",
Expand Down Expand Up @@ -117,7 +164,7 @@
"POP": {
"name": "POP",
"description": "Set Device Output Source Priority",
"help": " -- examples: POP00 (set utility first), POP01 (set solar first), POP02 (set SBU priority)",
"help": " -- examples: POP00 (set Utility > Solar > Battery), POP01 (set Solar > Utility > Battery), POP02 (set Solar > Battery > Utility)",
"regex": "POP(0[012])$",
},
"POPLG": {
Expand Down Expand Up @@ -223,11 +270,11 @@
{"description": "Battery Recharge Voltage", "reading_type": ReadingType.VOLTS, "response_type": ResponseType.FLOAT},
{"description": "Max Charging Current", "reading_type": ReadingType.CURRENT, "response_type": ResponseType.INT},
{"description": "Input Voltage Range", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Appliance", "UPS"]},
{"description": "Output Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Utility first", "Solar first", "SBU first"]},
{"description": "Output Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": SOURCE_PRIORITY_LIST},
{"description": "Charger Source Priority",
"reading_type": ReadingType.MESSAGE,
"response_type": ResponseType.LIST,
"options": ["Utility first", "Solar first", "Solar + Utility", "Only solar charging permitted"]},
"options": ["Utility first", "Solar first", "Solar + Utility", "Solar only"]},
{"description": "Battery Type", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": BATTERY_TYPE_LIST},
{"description": "Buzzer", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["enabled", "disabled"]},
{"description": "Power saving", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["disabled", "enabled"]},
Expand Down Expand Up @@ -386,15 +433,12 @@
{"description": "Battery Under Voltage", "reading_type": ReadingType.VOLTS, "response_type": ResponseType.FLOAT},
{"description": "Battery Bulk Charge Voltage", "reading_type": ReadingType.VOLTS, "response_type": ResponseType.FLOAT},
{"description": "Battery Float Charge Voltage", "reading_type": ReadingType.VOLTS, "response_type": ResponseType.FLOAT},
{"description": "Battery Type",
"reading_type": ReadingType.MESSAGE,
"response_type": ResponseType.LIST,
"options": BATTERY_TYPE_LIST},
{"description": "Battery Type", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": BATTERY_TYPE_LIST},
{"description": "Max AC Charging Current", "reading_type": ReadingType.CURRENT, "response_type": ResponseType.INT},
{"description": "Max Charging Current", "reading_type": ReadingType.CURRENT, "response_type": ResponseType.INT},
{"description": "Input Voltage Range", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Appliance", "UPS"]},
{"description": "Output Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Utility first", "Solar first", "SBU first"]},
{"description": "Charger Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Utility first", "Solar first", "Solar + Utility", "Only solar charging permitted"]},
{"description": "Output Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": SOURCE_PRIORITY_LIST},
{"description": "Charger Source Priority", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["Utility first", "Solar first", "Solar + Utility", "Solar only"]},
{"description": "Max Parallel Units", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.INT, "default": "not set"},
{"description": "Machine Type", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.OPTION, "options": {"00": "Grid tie", "01": "Off Grid", "10": "Hybrid"}},
{"description": "Topology", "reading_type": ReadingType.MESSAGE, "response_type": ResponseType.LIST, "options": ["transformerless", "transformer"]},
Expand Down Expand Up @@ -665,20 +709,66 @@
},
}

QPIGS2 = {
"name": "QPIGS2",
"description": "General Status Parameters inquiry 2",
"result_type": ResultType.ORDERED,
"reading_definitions": [
{"description": "PV2 Input Current",
"reading_type": ReadingType.CURRENT, "icon": "mdi:solar-power", "device_class": "current", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV2 Input Voltage",
"reading_type": ReadingType.VOLTS, "icon": "mdi:solar-power", "device_class": "voltage", "state_class": "measurement",
"response_type": ResponseType.FLOAT},
{"description": "PV2 Charging Power",
"reading_type": ReadingType.WATTS, "icon": "mdi:solar-power", "device_class": "power", "state_class": "measurement",
"response_type": ResponseType.INT},
],
"test_responses": [
b"(03.1 327.3 01026 \xc9\x8b\r",
],
}

QSID = {
"name": "QSID",
"aliases": ["default", "get_id"],
"description": "Device Serial Number inquiry",
"help": " -- queries the device serial number (length greater than 14)",
"result_type": ResultType.SINGLE,
"reading_definitions": [
{"description": "Serial Number",
"reading_type": ReadingType.MESSAGE, "icon": "mdi:identifier",
"response_type": ResponseType.TEMPLATE_BYTES, "format_template" : "r[2:int(r[0:2])+2]"}],
"test_responses": [b"(1492932105105335005535\x94\x0e\r", ],
}

class PI30(AbstractProtocol):
""" pi30 protocol handler """
def __str__(self):
return "PI30 protocol handler"
return self.description

def __init__(self, model=None) -> None:
super().__init__()
self.protocol_id = b"PI30"
self.model = model
self.add_command_definitions(QUERY_COMMANDS)
self.add_command_definitions(SETTER_COMMANDS, result_type=ResultType.ACK)
self.check_definitions_count(expected=45)
self.add_supported_ports([PortType.SERIAL, PortType.USB])
# self.id_command = "QID"
match model:
case 'MAX':
self.description = "PI30 protocol handler for LV6048MAX and similar inverters"
# Add new commands
self.add_command_definition(QPIGS2)
self.add_command_definition(QSID)
# Remove QID ID aliases
self.command_definitions["QID"].aliases = None
case "MST" | 'PIP4048MST':
self.description = "PI30 protocol handler for PIP4048MST and similar inverters"
self.replace_command_definition("QPIGS2", MST_QPIGS2)
self.check_definitions_count(expected=67)
case _:
self.description = "PI30 protocol handler"
self.check_definitions_count(expected=45)

def check_valid(self, response: str, command_definition: CommandDefinition = None) -> bool:
""" check response is valid """
Expand Down
6 changes: 4 additions & 2 deletions powermon/protocols/pi30max.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
log = logging.getLogger("pi30max")

SOURCE_PRIORITY_LIST = ["Utility", "Solar first", "Solar + Utility", "Only Solar"]
_SOURCE = ["Utility Solar Battery", "Solar Utility Battery", "Solar Battery Utility"]
OUTPUT_MODE_LIST = ["single machine",
"parallel",
"Phase 1 of 3 phase",
Expand Down Expand Up @@ -925,8 +926,7 @@ def __init__(self, model=None) -> None:
self.model = model
self.add_command_definitions(QUERY_COMMANDS)
self.add_command_definitions(SETTER_COMMANDS, result_type=ResultType.ACK)
self.remove_command_definitions(COMMANDS_TO_REMOVE)
self.check_definitions_count(expected=67)
self.remove_command_definitions(COMMANDS_TO_REMOVE)

if model:
log.info("%s got model specifier: %s", self.protocol_id, model)
Expand All @@ -935,6 +935,8 @@ def __init__(self, model=None) -> None:
self.check_definitions_count(expected=67)
# else:
# raise PowermonProtocolError(f"unknown model {model}")
else:
self.check_definitions_count(expected=67)

self.STATUS_COMMANDS = ["QPIGS", "QPIGS2"]
self.SETTINGS_COMMANDS = ["QPIRI", "QFLAG"]
Expand Down

0 comments on commit 1783018

Please sign in to comment.