From 4118314447ead4888bfb67a90c4c05d157488509 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Fri, 14 Feb 2025 21:41:06 -0600 Subject: [PATCH 01/53] Create python-3.13.yml --- .github/workflows/python-3.13.yml | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/python-3.13.yml diff --git a/.github/workflows/python-3.13.yml b/.github/workflows/python-3.13.yml new file mode 100644 index 0000000..9368392 --- /dev/null +++ b/.github/workflows/python-3.13.yml @@ -0,0 +1,42 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python 3.13 + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.13"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + + # don't care about coding standards + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest From ae69e4e289f4bf4cf2e8656765c3a1e61aca6cbd Mon Sep 17 00:00:00 2001 From: HotNoob Date: Fri, 14 Feb 2025 21:43:59 -0600 Subject: [PATCH 02/53] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c25a622..ca1f14f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ![Python 3.10](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/python-3.10.yml/badge.svg) ![Python 3.11](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/python-3.11.yml/badge.svg) ![Python 3.12](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/python-3.12.yml/badge.svg) +![Python 3.13](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/python-3.13.yml/badge.svg) [![CodeQL](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/HotNoob/PythonProtocolGateway/actions/workflows/github-code-scanning/codeql) From 2486f3e0f0909917a2802a3a7bdfd29907e8abc6 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 10:09:58 -0500 Subject: [PATCH 03/53] fix pymodbus compatability --- classes/transports/modbus_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index c849b81..417d778 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -403,7 +403,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if ushortValue == None: raise ValueError("Invalid value - None") - self.write_register(entry.register, ushortValue, registry_type=registry_type) + self.write_register(entry.register, ushortValue) def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): From 33fe4f28fe252f91db579af36281e0ce7ede78dd Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:17:45 -0500 Subject: [PATCH 04/53] variable register read timing -- testing --- classes/protocol_settings.py | 67 ++++++++++++++++++++++++++-- classes/transports/modbus_base.py | 5 ++- classes/transports/transport_base.py | 25 ++++++----- protocol_gateway.py | 4 +- 4 files changed, 83 insertions(+), 18 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index d0fea16..4a84d0a 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -3,6 +3,7 @@ from enum import Enum import glob import logging +import time from typing import Union from defs.common import strtoint import itertools @@ -12,6 +13,11 @@ import math import ast +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from configparser import SectionProxy + class Data_Type(Enum): BYTE = 1 '''8bit byte''' @@ -206,6 +212,13 @@ class registry_map_entry: read_command : bytes = None ''' for transports/protocols that require sending a command ontop of "register" ''' + + read_interval : int = 1000 + ''' how often to read register in ms''' + + next_read_timestamp : int = 0 + ''' unix timestamp in ms ''' + write_mode : WriteMode = WriteMode.READ ''' enable disable reading/writing ''' @@ -241,12 +254,14 @@ class protocol_settings: settings : dict[str, str] ''' default settings provided by protocol json ''' + transport_settings : 'SectionProxy' = None + byteorder : str = "big" _log : logging.Logger = None - def __init__(self, protocol : str, settings_dir : str = 'protocols'): + def __init__(self, protocol : str, transport_settings : 'SectionProxy' = None, settings_dir : str = 'protocols'): #apply log level to logger self._log_level = getattr(logging, logging.getLevelName(logging.getLogger().getEffectiveLevel()), logging.INFO) @@ -359,6 +374,9 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP registry_map : list[registry_map_entry] = [] register_regex = re.compile(r'(?P(?:0?x[\da-z]+|[\d]+))\.(b(?Px?\d{1,2})|(?Px?\d{1,2}))') + read_interval_regex = re.compile(r'(?P[\.\d]+)(?P[xs]|ms') + + data_type_regex = re.compile(r'(?P\w+)\.(?P\d+)') range_regex = re.compile(r'(?Pr|)(?P(?:0?x[\da-z]+|[\d]+))[\-~](?P(?:0?x[\da-z]+|[\d]+))') @@ -366,6 +384,12 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP list_regex = re.compile(r'\s*(?:(?P(?:0?x[\da-z]+|[\d]+))-(?P(?:0?x[\da-z]+|[\d]+))|(?P[^,\s][^,]*?))\s*(?:,|$)') + #load read_interval from transport settings, for #x per register read intervals + transport_read_interval : int = 1000 + if self.transport_settings is not None: + transport_read_interval = self.transport_settings.getint("read_interval", transport_read_interval) + + if not os.path.exists(path): #return empty is file doesnt exist. return registry_map @@ -393,10 +417,40 @@ def process_row(row): # Initialize variables to hold numeric and character parts unit_multiplier : float = 1 unit_symbol : str = '' + read_interval : int = 0 + ''' read interval in ms ''' #clean up doc name, for extra parsing row['documented name'] = row['documented name'].strip().lower().replace(' ', '_') + #region read_interval + + + if 'read_interval' in row: + row['read_interval'] = row['read_interval'].lower() #ensure is all lower case + match = read_interval_regex.search(row['read_interval']) + if match: + register = strtoint(match.group('register')) + + unit = match.group('unit') + value = match.group('value') + if value: + value = float(value) + if unit == 'x': + read_interval = int((transport_read_interval * 1000) * value) + else: # seconds or ms + read_interval = value + if unit != 'ms': + read_interval *= 1000 + + if read_interval == 0: + read_interval = transport_read_interval + if "read_interval" in self.settings: + try: + read_interval = int(self.settings['read_interval']) + except ValueError: + read_interval = transport_read_interval + #region overrides if overrides != None: @@ -609,6 +663,7 @@ def process_row(row): value_max=value_max, value_regex=value_regex, read_command = read_command, + read_interval=read_interval, write_mode=writeMode ) registry_map.append(item) @@ -720,6 +775,9 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register start = -max_batch_size ranges : list[tuple] = [] + timestamp_ms = int(time.time() * 1000) + + while (start := start+max_batch_size) <= max_register: registers : list[int] = [] #use a list, im too lazy to write logic @@ -731,8 +789,11 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register continue if register.write_mode == WriteMode.WRITEONLY: ##Write Only; skip continue - - registers.append(register.register) + + #we are assuming calc registry ranges is being called EVERY READ. + if register.next_read_timestamp < timestamp_ms: + register.next_read_timestamp = timestamp_ms + register.read_interval + registers.append(register.register) if registers: #not empty ranges.append((min(registers), max(registers)-min(registers)+1)) ## APPENDING A TUPLE! diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 417d778..db35886 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -155,7 +155,10 @@ def read_data(self) -> dict[str, str]: if registry_type == Registry_Type.HOLDING and not self.send_holding_register: continue - registry = self.read_modbus_registers(ranges=self.protocolSettings.get_registry_ranges(registry_type=registry_type), registry_type=registry_type) + #calculate ranges dynamically -- for variable read timing + ranges = self.protocolSettings.calculate_registry_ranges(self.protocolSettings.registry_map[registry_type], self.protocolSettings.registry_map_size[registry_type]) + + registry = self.read_modbus_registers(ranges=ranges, registry_type=registry_type) new_info = self.protocolSettings.process_registery(registry, self.protocolSettings.get_registry_map(registry_type)) if False: diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index 89913f0..9f818b6 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -32,7 +32,7 @@ class transport_base: _log : logging.Logger = None - def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None) -> None: + def __init__(self, settings : 'SectionProxy') -> None: self.transport_name = settings.name #section name @@ -45,17 +45,6 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self.type = self.__class__.__name__ - self.protocolSettings = protocolSettings - if not self.protocolSettings: #if not, attempt to load. lazy i know - self.protocol_version = settings.get('protocol_version') - if self.protocol_version: - self.protocolSettings = protocol_settings(self.protocol_version) - - if self.protocolSettings: - self.protocol_version = self.protocolSettings.protocol - - #todo, reimplement default settings from protocolsettings - if settings: self.device_serial_number = settings.get(["device_serial_number", "serial_number"], self.device_serial_number) self.device_manufacturer = settings.get(["device_manufacturer", "manufacturer"], self.device_manufacturer) @@ -67,6 +56,18 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self.write_enabled = settings.getboolean(["write_enabled", "enable_write"], self.write_enabled) else: self.write_enabled = settings.getboolean("write", self.write_enabled) + + + #load a protocol_settings class for every transport; required for adv features. ie, variable timing. + #must load after settings + self.protocol_version = settings.get('protocol_version') + if self.protocol_version: + self.protocolSettings = protocol_settings(self.protocol_version, transport_settings=settings) + + if self.protocolSettings: + self.protocol_version = self.protocolSettings.protocol + + #todo, reimplement default settings from protocolsettings self.update_identifier() diff --git a/protocol_gateway.py b/protocol_gateway.py index 6ef43f8..32ab131 100644 --- a/protocol_gateway.py +++ b/protocol_gateway.py @@ -133,7 +133,7 @@ def __init__(self, config_file : str): raise ValueError('Missing Transport / Protocol Version') - if not transport_type and protocol_version: #get transport from protocol settings... + if not transport_type and protocol_version: #get transport from protocol settings... todo need to make a quick function instead of this protocolSettings : protocol_settings = protocol_settings(protocol_version) if not transport_type and not protocolSettings.transport: @@ -211,7 +211,7 @@ def run(self): traceback.print_exc() self.__log.error(err) - time.sleep(7) + time.sleep(0.7) #change this in future. probably reduce to allow faster reads. From 1cac5b7cd786c35352163b3f3b8919a72ad71628 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:21:25 -0500 Subject: [PATCH 05/53] Update modbus_base.py --- classes/transports/modbus_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index db35886..9ab9e3d 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -43,7 +43,7 @@ class modbus_base(transport_base): send_input_register : bool = True def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None): - super().__init__(settings, protocolSettings=protocolSettings) + super().__init__(settings) self.analyze_protocol_enabled = settings.getboolean('analyze_protocol', fallback=self.analyze_protocol_enabled) self.analyze_protocol_save_load = settings.getboolean('analyze_protocol_save_load', fallback=self.analyze_protocol_save_load) From 68e114af7d9e5a94a843e527d5dd2f979f1c77ee Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Mar 2025 14:40:24 -0500 Subject: [PATCH 06/53] bug fix new variable timing --- classes/protocol_settings.py | 2 +- classes/transports/transport_base.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 4a84d0a..44ed953 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -374,7 +374,7 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP registry_map : list[registry_map_entry] = [] register_regex = re.compile(r'(?P(?:0?x[\da-z]+|[\d]+))\.(b(?Px?\d{1,2})|(?Px?\d{1,2}))') - read_interval_regex = re.compile(r'(?P[\.\d]+)(?P[xs]|ms') + read_interval_regex = re.compile(r'(?P[\.\d]+)(?P[xs]|ms)') data_type_regex = re.compile(r'(?P\w+)\.(?P\d+)') diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index 9f818b6..287415c 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -58,14 +58,14 @@ def __init__(self, settings : 'SectionProxy') -> None: self.write_enabled = settings.getboolean("write", self.write_enabled) - #load a protocol_settings class for every transport; required for adv features. ie, variable timing. - #must load after settings - self.protocol_version = settings.get('protocol_version') - if self.protocol_version: - self.protocolSettings = protocol_settings(self.protocol_version, transport_settings=settings) - - if self.protocolSettings: - self.protocol_version = self.protocolSettings.protocol + #load a protocol_settings class for every transport; required for adv features. ie, variable timing. + #must load after settings + self.protocol_version = settings.get('protocol_version') + if self.protocol_version: + self.protocolSettings = protocol_settings(self.protocol_version, transport_settings=settings) + + if self.protocolSettings: + self.protocol_version = self.protocolSettings.protocol #todo, reimplement default settings from protocolsettings From 92a90fbd5de067f0b6ede2cb91f8263230ee3d85 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:41:47 -0500 Subject: [PATCH 07/53] ; to , --- ...rowatt_2020_v1.24.holding_registry_map.csv | 1128 ++++++++--------- 1 file changed, 564 insertions(+), 564 deletions(-) diff --git a/protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv b/protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv index 419a890..5760c42 100644 --- a/protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv +++ b/protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv @@ -1,564 +1,564 @@ -variable name;data type;register;documented name;description;write;values;unit;Initial value;note;;;;;;; -;;0;OnOff;"Remote On/Off . On(1);Of(f 0)Inverter On(3);Off(2)BDC";W;0;1;2;3;;1;The inverter can be switched on and off; and the BDC can be switched on and off for the batt ready function.;;; -;;1;SaftyFuncEn;Bit0: SPI enable Bit1: AutoTestStart Bit2: LVFRT enable Bit3:FreqDerating Enable Bit4: Softstart enable Bit5: DRMS enable Bit6:PowerVoltFunc Enable Bit7: HVFRT enable Bit8:ROCOF enable Bit9: Recover FreqDeratingMode Enable Bit10:Split phase enable Bit10~15:??;W;0 :Disable1: enable;;;SPI: systemprotectioninterfaceBit0~3:for CEI0-21Bit4~6:for SAA;;;;;;; -;;2;PF CMDmemoryState;Set Holding register3;4;5;99 CMD will be memory or not(1/0); if not; these settings are the initial value. ;W;0or1;;0;Means these settings will beacting or not whennextpower on ;; -;;3;Active P Rate;Inverter Max output active power percent;W;0-100 or 255;%;255;255: power is not be limited;;;;;;; -;;4;Reactive P Rate;Inverter max output reactive power percent;W;-100-100 or 255;%;255;255: power is not be limited;;;;;;; -;;5;Power factor;Inverter output powerfactor's 10000 times;W;0-20000; 0-10000isunderexcited; otherisoverexcitEd;;;;0;;;; -;;6;Pmax H;Normal power (high);;;0.1VA;;;;;;;;; -;;7;Pmax L;Normal power (low);;;0.1VA;;;;;;;;; -;;8;Vnormal;Normal work PV voltage;;;0.1V;;;;;;;;; -;;9;Fw version H;Firmware version (high);;;ASCII;;;;;;;;; -;;10;Fw version M;Firmware version (middle);;;;;;;;;;;; -;;11;Fw version L;Firmware version (low);;;;;;;;;;;; -;;12;Fw version2 H;Control Firmware version (high);;;ASCII;;;;;;;;; -;;13;Fw version2 M;Control Firmware version (middle);;;;;;;;;;;; -;;14;Fw version2 L;Control Firmware version (low);;;;;;;;;;;; -;;15;LCD language;LCD language;W;0-5;;;"0: Italian; 1: English; 2: German; 3: Spanish; 4: French; 5: Chinese; 6:Polish 7:Portugues 8:Hungary";;;;;;; -;;16;CountrySele cted;Country Selected or not;W;"0: need to select; 1: have selected";;;;;;;;;; -;;17;Vpv start;Input start voltage;W;;0.1V;;;;;;;;; -;;18;Time start;Start time;W;;1s;;;;;;;;; -;;19;RestartDelay Time;"Restart Delay Time after fault back;";W;;1s;;;;;;;;; -;;20;wPowerStart Slope;Power start slope;W;01/01/00;0.10%;;;;;;;;; -;;21;wPowerRest artSlopeEE;Power restart slope;W;01/01/00;0.10%;;;;;;;;; -;;22;wSelectBaud rate;Select communicationbaudrat e 0: 9600bps 1:38400bps;W;0-1;;0;;;;;;;; -;;23;Serial NO 1;Serial number 1-2;;;ASCII;;;;;;;;; -;;24;Serial NO 2;Serial number 3-4;;;;;;;;;;;; -;;25;Serial NO 3;Serial number 5-6;;;;;;;;;;;; -;;26;Serial NO 4;Serial number 7-8;;;;;;;;;;;; -;;27;Serial NO 5;Serial number 9-10;;;;;;;;;;;; -;;28;Module H;Inverter Module (high);;&*5;;;;;;;;;; -;;29;Module L;Inverter Module (low);;&*5;;;;;;;;;; -;;30;Com Address;Communicate address;W;01/01/54;;1;;;;;;;; -;;31;FlashStart;Update firmware;W;1;;;;;;;;;; -;;32;Reset User Info;Reset User Information;W;0x0001;;;;;;;;;; -;;33;Reset to factory;Reset to factory;W;0x0001;;;;;;;;;; -;;34;Manufacturer Info 8;Manufacturer information (high);;;ASCII;;;;;;;;; -;;35;Manufacturer Info 7;Manufacturer information (middle);;;;;;;;;;;; -;;36;Manufacturer Info 6;Manufacturer information (low);;;;;;;;;;;; -;;37;Manufacturer Info 5;Manufacturer information (high);;;;;;;;;;;; -;;38;Manufacturer Info 4;Manufacturer information (middle);;;;;;;;;;;; -;;39;Manufacturer Info3;Manufacturer information (low);;;;;;;;;;;; -;;40;Manufacturer Info 2;Manufacturer information (low);;;;;;;;;;;; -;;41;Manufacturer Info 1;Manufacturer information (high);;;;;;;;;;;; -;;42;bfailsafeEn;G100 fail safe;W;Enable:1 Disable:0;;;English G100 fail safe set;;;;;;; -;;43;DTC;Device Type Code;;&*6;;;;;;;;;; -;;44;TP;Input tracker num and output phase num;;Eg:0x020 3 is two MPPT and 3ph output;;;;;;;;;; -;;45;Sys Year;System time-year;W;Year offset is 0;;;Local time;;;;;;; -;;46;Sys Month;System time- Month;W;;;;;;;;;;; -;;47;Sys Day;System time- Day;W;;;;;;;;;;; -;;48;Sys Hour;System time- Hour;W;;;;;;;;;;; -;;49;Sys Min;System time- Min;W;;;;;;;;;;; -;;50;Sys Sec;System time- Second;W;;;;;;;;;;; -;;51;Sys Weekly;System Weekly;W;0-6;;;;;;;;;; -;;52;Vac low;Grid voltage low limit protect;W;;0.1V;;;;;;;;; -;;53;Vac high;Grid voltage high limit protect;W;;0.1V;;;;;;;;; -;;54;Fac low;Grid frequency low limit protect;W;;0.01 Hz;;;;;;;;; -;;55;Fac high;Grid high frequencylimit protect;W;;0.01 Hz;;;;;;;;; -;;56;Vac low 2;Grid voltage low limit protect 2;W;;0.1V;;;;;;;;; -;;57;Vac high 2;Grid voltage high limit protect 2;W;;0.1V;;;;;;;;; -;;58;Fac low 2;Grid frequency low limit protect 2;W;;0.01 Hz;;;;;;;;; -;;59;Fac high 2;Grid high frequency limit protect 2;W;;0.01 Hz;;;;;;;;; -;;60;Vac low 3;Grid voltage low limit protect 3;W;;0.1V;;;;;;;;; -;;61;Vac high 3;Grid voltage high limit protect 3;W;;0.1V;;;;;;;;; -;;62;Fac low 3;Grid frequency low limit protect 3;W;;0.01Hz;;;;;;;;; -;;63;Fac high 3;Grid frequency high limit protect 3;W;;0.01Hz;;;;;;;;; -;;64;Vac low C;Grid low voltage limit connect to Grid;W;;0.1V;;;;;;;;; -;;65;Vac high C;Grid high voltage limit connect to Grid;W;;0.1V;;;;;;;;; -;;66;Fac low C;Grid low frequency limit connect to Grid;W;;0.01 Hz;;;;;;;;; -;;67;Fac high C;Grid high frequency limit connect to Grid;W;;0.01 Hz;;;;;;;;; -;;68;Vac low1 time;Grid voltage low limit protect time 1;W;;Cycle;;;;;;;;; -;;69;Vac high1 time;Grid voltage high limit protect time 1;W;;Cycle;;;;;;;;; -;;70;Vac low2 time;Grid voltage low limit protect time 2;W;;Cycle;;;;;;;;; -;;71;Vac high2 time;Grid voltage high limit protect time 2;W;;Cycle;;;;;;;;; -;;72;Fac low1 time;Grid frequency low limit protect time 1;W;;Cycle;;;;;;;;; -;;73;Fac high1 time;Grid frequency high limit protect time 1;W;;Cycle;;;;;;;;; -;;74;Fac low2 time;Grid frequency low limit protect time 2;W;;Cycle;;;;;;;;; -;;75;Fac high2 time;Grid frequency high limit protect time 2;W;;Cycle;;;;;;;;; -;;76;Vac low3 time;Grid voltage low limit protect time 3;W;;Cycle;;;;;;;;; -;;77;Vac high3 time;Grid voltage high limit protect time 3;W;;Cycle;;;;;;;;; -;;78;Fac low3 time;Grid frequency low limit protect time 3;W;;Cycle;;;;;;;;; -;;79;Fac high3 time;Grid frequency high limit protect time 3;W;;Cycle;;;;;;;;; -;;80;U10min;Volt protection for 10 min;W;;0.1V;1.1Vn;;;;;;;; -;;81;PV Voltage High Fault;PV Voltage High Fault;W;;0.1V;;;;;;;;; -;;82;FW Build No_ 5;Model letter version number (TJ);;;ASCII;;;;;;;;; -;;83;FW Build No_ 4;Model letter version number (AA);;;ASCII;;;;;;;;; -;;84;FW Build No_ 3;DSP1 FW Build No.;;;ASCII;;;;;;;;; -;;85;FW Build No_ 2;DSP2/M0 FW Build No.;;;ASCII;;;;;;;;; -;;86;FW Build No_ 1;CPLD/AFCI FW Build No.;;;ASCII;;;;;;;;; -;;87;FW Build No_ 0;M3 FW Build No.;;;ASCII;;;;;;;;; -;;88;ModbusVers ion;Modbus Version;;Eg:207 is V2.07;Int(16 bits);;;;;;;;; -;;89;PFModel;Set PF function Model 0: PF=1 1: PF by set 2: default PF line 3: User PF line 4: UnderExcited (Inda) Reactive Power 5: OverExcited(Capa) Reactive Power 6:Q(v)model 7:Direct Control mode;W;;;;;;;;;;; -;;90;GPRS IP Flag;"Bit0-3:read:1;Set GPRS IP Successed Write:2;Read GPRS IP Successed Bit4-7:GPRS status";W;Bit0-3:ab out GPRS IP SET Bit4-7:ab out GRPRS Status;;;;;;;;;; -;;91;FreqDerateS tart;Frequency derating start point;W;;0.01H Z;;;;;;;;; -;;92;FLrate;Frequency - load limit rate;W;0-100;10tim es;;;;;;;;; -;;93;V1S;CEI021 V1S Q(v);W;V1S50;W;;0.1V;;Clear battery low voltage error voltage point;;;;;;; -;;1004;Vbatstopfo rdischarge;Should stop discharge when lower than this voltage(only lead-Acid): 46.0V <20% 44.8V 20%~50% 44.2V >50%;W;;0.01V;;;;;;;;; -;;1005;Vbat stop for charge;Should stop charge when higher than this voltage;W;;0.01V;5800;;;;;;;; -;;1006;Vbat start for discharge;Should not discharge when lower than this voltage;W;;0.01V;4800;;;;;;;; -;;1007;Vbat constant charge;can charge when lower than this voltage;W;;0.01V;5800;CV voltage(acid);;;;;;; -;;1008;EESysInfo_S ysSetEn;"Bit0:Resved; Bit1:Resved; Bit2:Resved; Bit3:Resved; Bit4:Resved; Bit5:bDischargeEn; Bit6:ForceDischrEn; Bit7:ChargeEn; Bit8:bForceChrEn; Bit9:bBackUpEn; Bit10:bInvLimitLoadE; Bit11:bSpLimitLoadEn; Bit12:bACChargeEn; Bit13:bPVLoadLimitEn; Bit14,15:UnUsed;";W;;;;System Enable;;;;;;; -;;1009;Battemp lower limit d;Battery temperature lower limit for discharge;W;0-200:0-2 0? 1000-140 0:-40-0?;0.1?;1170;;;;;;;; -;;1010;Bat temp upper limit d;Battery temperature upper limit for discharge;W;200-1000;0.1?;420;;;;;;;; -;;1011;Bat temp lower limit c;Battery temperature lower limit for charge;W;0-200:0-2 0? 1000-140 0:-40-0?;0.1?;30;Lower temperature limit;;;;;;; -;;1012;Bat temp upper limit c;Battery temperature upper limit for charge;W;200-1000;0.1?;370;Upper temperature limit;;;;;;; -;;1013;uwUnderFr eDischarge DelyTime;Under Fre Delay Time;s;0-20;50ms;;Under Fre Delay Time;;;;;;; -;;1014;BatMdlSeri alNum;Battery serial number;W;12:00:00 AM;;;SPH4-11K used;;;;;;; -;;1015;BatMdlPara llNum;Battery parallel section;W;12:00:00 AM;;;SPH4-11K used;;;;;;; -;;1016;DRMS_EN;/;/;/;/;/;0:disable 1:enable;;;;;;; -;;1017;Bat First Start Time 4;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1018;Bat First Stop Time 4;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1019;BatFirst on_off Switch 4;Enable:1 Disable:0;;0 or 1;;;Battery priority enable 1;;;;;;; -;;1020;Bat First Start Time 5;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1021;Bat First Stop Time 5;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1022;BatFirst on_off Switch 5;Enable:1 Disable:0;;0 or 1;;;Battery priority enable 1;;;;;;; -;;1023;Bat First Start Time 6;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1024;Bat First Stop Time 6;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1025;BatFirst on_off Switch 6;Enable:1 Disable:0;;0 or 1;;;Battery priority enable 1;;;;;;; -;;1026;Grid First Start Time 4;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1027;Grid First Stop Time 4;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1028;Grid First Stop Switch 4;Enable:1 Disable:0;;0 or 1;;;Grid priority enable;;;;;;; -;;1029;Grid First Start Time 5;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1030;Grid First Stop Time 5;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1031;Grid First Stop Switch 5;Enable:1 Disable:0;;0 or 1;;;Grid priority enable;;;;;;; -;;1032;Grid First Start Time 6;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1033;Grid First Stop Time 6;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1034;Grid First Stop Switch 6;Enable:1 Disable:0;;0 or 1;;;Grid priority enable;;;;;;; -;;1035;Bat First Start Time 4;High eight:hours Low eight: minutes;;0-23 0-59;;;;;;;;;; -;;1037;bCTMode;Use the CTMode to Choose RFCT \ Cable CT\METER;W;2:METER 1:cWirele ssCT 0:cWiredC T;;0;;;;;;;; -;;1038;CTAdjust;CTAdjust enable;W;0:disable 1:enable;;0;;;;;;;; -;;1044;Priority;ForceChrEn/ForceDischr En Load first/bat first /grid first;R;0.Load(de fault)/1.B attery/2.G rid;;;bForceChrEn/disbForceDischrE n/dis;;;;;;; -;;1047;AgingTestSt ep Cmd;Command for aging test;;0: default 1: charge 2: discharge;;;Cmd for aging test;;;;;;; -;;1048;BatteryTyp e;Battery type choose of buck-boost input;;0:Lithium 1:Lead-aci d 2:other;;0;Battery type;;;;;;; -;;1060;BuckUpsFunE n;Ups function enable or disable;;0:disable 1:enable;;;;;;;;;; -;;1061;BuckUPSVoltSet;UPS output voltage;;0:230 1:208 2:240;;230V;;;;;;;; -;;1062;UPSFreqSet;UPS output frequency;;0:50Hz 1:60Hz;;50Hz;;;;;;;; -;;1070;GridFirstDisch argePowerRat e;Discharge Power Rate when Grid First;W;0-100;1.00%;;Discharge Power Rate when Grid First;;;;;;; -;;1071;GridFirstStopS OC;Stop Discharge soc when Grid First;W;0-100;1.00%;;Stop Discharge soc when Grid First;;;;;;; -;;1080;Grid First Start Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1081;Grid First Stop Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1082;Grid First Stop Switch 1;Enable :1 Disable:0;;0 or 1;;;Grid First enable;;;;;;; -;;1083;Grid First Start Time 2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1084;Grid First Stop Time 2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1085;Grid First Stop Switch 2;ForceDischarge.bSwitch&L CD_SET_FORCE_TRUE_2)= =LCD_SET_FORCE_TRUE_2;;0 or 1;;;Grid First enable;;"ForceDischarge; LCD_SET_FORCE_T RUE_2";;;;; -;;1086;Grid First Start Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1087;Grid First Stop Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1088;Grid First Stop Switch 3;Enable :1 Disable:0;;0 or 1;;;Grid First enable;;;;;;; -;;1090;BatFirstPower Rate;Charge Power Rate when Bat First;W;0-100;1.00%;;Charge Power Rate when Bat First;;;;;;; -;;1091;wBatFirst stop SOC;Stop Charge soc when Bat First;W;0-100;1.00%;;Stop Charge soc when Bat First;;;;;;; -;;1092;AC charge Switch;When Bat First Enable:1 Disable:0;;Enable:1 Disable:0;;;AC Charge Enable;;;;;;; -;;1100;Bat First Start Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1101;Bat First Stop Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1102;BatFirst on_off Switch 1;Enable :1 Disable:0;;0 or 1;;;Bat First Enable1;;;;;;; -;;1103;Bat First Start Time 2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1104;Bat First Stop Time 2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1105;BatFirston_off Switch 2;Enable :1 Disable:0;;0 or 1;;;Bat First Enable2;;;;;;; -;;1106;Bat First Start Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1107;Bat First Stop Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;;;;;; -;;1108;BatFirston_off Switch 3;Enable :1 Disable:0;;0 or 1;;;Bat First Enable3;;;;;;; -;;1110;Load First Start Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1111;Load First Stop Time 1;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1112;Load First Switch 1;Enable :1 Disable:0;;0 or 1;;;Load First Enable;;SPA/ reserve;;;;; -;;1113;Load First Start Time2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1114;Load First Stop Time 2;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1115;Load First Switch 2;Enable :1 Disable:0;;0 or 1;;;Load First Enable;;SPA/ reserve;;;;; -;;1116;Load First Start Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1117;Load First Stop Time 3;High eight bit:hour Low eight bit:minute;;0-23 0-59;;;;;SPA/ reserve;;;;; -;;1118;Load First Switch 3;Enable :1 Disable:0;;0 or 1;;;Load First Enable;;SPA/ reserve;;;;; -;;1119;NewEPowerC alcFlag;/;;/;;;/;;0:The old formula 1 : The new formula;;;;; -;;1120;BackUpEn;BackUp Enable;;;;;;;MIX US;;;;; -;;1121;SGIPEn;SGIP Enable;;;;;;;MIX US;;;;; -;;1125;BatSerialNO_ 8_B1;Product serial number of the first PACK of energy storage batteries;;/;ASCII;;;;;;;;; -;;1126;BatSerialNO_ 7_B1;;;/;ASCII;;;;;;;;; -;;1127;BatSerialNO_ 6_B1;;;/;ASCII;;;;;;;;; -;;1128;BatSerialNO_ 5_B1;;;/;ASCII;;;;;;;;; -;;1129;BatSerialNO_ 4_B1;;;/;ASCII;;;;;;;;; -;;1130;BatSerialNO_ 3_B1;;;/;ASCII;;;;;;;;; -;;1131;BatSerialNO_ 2_B1;;;/;ASCII;;;;;;;;; -;;1132;BatSerialNO_ 1_B1;;;;;;;;;;;;; -;;1244;Com version NameH;Name of the battery main control firmware version;;;ASCII;;;;;;;;; -;;1245;Com version NameL;Name of the battery main control firmware version;;;ASCII;;;;;;;;; -;;1246;Com version No;Version of the battery main control firmware;;;digital;;;;;;;;; -;;1247;Com version NameH;Name of battery monitoring firmware version;;;ASCII;;;;;;;;; -;;1248;Com version NameL;Name of battery monitoring firmware version;;;ASCII;;;;;;;;; -;;1249;Com version No;Battery monitoring firmware version;;;digital;;;;;;;;; -;;3000;ExportLimitFa iledPowerRat e;The power rate when exportLimit failed;R/W;;0.10%;;;;The power rate when exportLimit failed;;;;; -;;3001;New Serial NO;Serial number 1-2;R/W;;ASCII;;;;"The new model uses the following registers to record the serial number; The representation is the same as the original: one register holds two characters and the new serial number is 30 characters.";;;;; -;;3002;New Serial NO;Serial number 3-4;R/W;;ASCII;;;;;;;;; -;;3003;New Serial NO;Serial number 5-6;R/W;;ASCII;;;;;;;;; -;;3004;New Serial NO;Serial number 7-8;R/W;;ASCII;;;;;;;;; -;;3005;New Serial NO;Serial number 9-10;R/W;;ASCII;;;;;;;;; -;;3006;New Serial NO;Serial number 11-12;R/W;;ASCII;;;;;;;;; -;;3007;New Serial NO;Serial number 13-14;R/W;;ASCII;;;;;;;;; -;;3008;New Serial NO;Serial number 15-16;R/W;;ASCII;;;;;;;;; -;;3009;New Serial NO;Serial number 17-18;R/W;;ASCII;;;;;;;;; -;;3010;New Serial NO;Serial number 19-20;R/W;;ASCII;;;;;;;;; -;;3011;New Serial NO;Serial number 21-22;R/W;;ASCII;;;;;;;;; -;;3012;New Serial NO;Serial number 23-24;R/W;;ASCII;;;;;;;;; -;;3013;New Serial NO;Serial number 25-26;R/W;;ASCII;;;;;;;;; -;;3014;New Serial NO;Serial number 27-28;R/W;;ASCII;;;;;;;;; -;;3015;New Serial NO;Serial number 29-30;R/W;;ASCII;;;;;;;;; -;;3016;DryContactFu ncEn;DryContact function enable;R/W;0:Disable 1: Enable;;;;;DryContact function enable;;;;; -;;3017;DryContactOn Rate;The power rate of drycontact turn on;R/W;0~1000;0.10%;;;;The power rate of drycontact turn on;;;;; -;;3018;bWorkMode;WorkMode 0:default 1: System Retrofit 2: Multi-Parallel;R/W;1;2;3;;;;;;MIN2.5~6KTL-XH/ XA Double CT special;; -;;3019;DryContactOffRate;Dry contact closure power;R/W ;0~100 0;0.10%;;;;Dry contact closure power pe rcentage;;;;; -;;3020;BoxCtrlInvOrder;Off-net box control instruct ion;R/W ;;;;;;;;;;; -;;3021;ExterCommOf fGridEn;External communication setting manual off-network enable;R/W;;;;;;"0x00: Disable; (default) 0x01: Enable;";;;;; -;;3022;uwBdcStopW orkOfBusVolt;BdcStopWorkOfBusVolt;R;;;;;;;;;;; -;;3023;bGridType;GridType---0:SinglePhase 1:ThreePhase 2:SplitPhase;R/W;1;2;3;;;;;MIN2.5~6KTL-XH/ XA Double CT special;;; -;;3024;Float charge current limit;When charge current battery need is lower than this value enter into float charge;R/W;;0.1A;;600;;CC current;;;;; -;;3025;VbatWarning;"""Battery-low"" warning setup voltage";R/W;;0.1V;;4800;;Lead acid battery LV voltage;;;;; -;;3026;VbatlowWarn Clr;"""Battery-low"" warning clear voltage";R/W;;0.1V;;;;"Clear battery low voltage error voltage point LoadPercent(only lead-Acid): 45.5V(Load < 20%); 48.0V(20%<=Load <=50%); 49.0V(Load > 50%);";;;;; -;;3027;Vbatstopfordi scharge;Battery cut off voltage;R/W;;0.1V;;;;"Should stop discharge when lower than this voltage(only lead-Acid): 46.0V(Load < 20%); 44.8V(20%<=Load <=50%); 44.2V(Load > 50%);";;;;; -;;3028;Vbat stop for charge;Battery over charge voltage;R/W;;0.01V;;5800;;Should stop charge when higher than this voltage;;;;; -;;3029;Vbat start for discharge;Battery start discharge voltage;R/W;;0.01V;;4800;;Should not discharge when lower than this voltage;;;;; -;;3030;Vbat constant charge;Battery constant charge voltage;R/W;;0.01V;;5800;;CV voltage(acid) can charge when lower than this voltage;;;;; -;;3031;Battemp lower limit d;Battery temperature lower limit for discharge;R/W;;0.1?;;1170;;0-200:0-20? 1000-1400: -40-0?;;;;; -;;3032;Bat temp upper limit d;Battery temperature upper limit for discharge;R/W;;0.1?;;420;;;;;;; -;;3033;Bat temp lower limit c;Battery temperature lower limit for charge;R/W;;0.1?;;30;;Battery temperature lower limit 0-200:0-20? 1000-1400: -40-0?;;;;; -;;3034;Bat temp upper limit c;Battery temperature upper limit for charge;R/W;;0.1?;;370;;Battery temperature upper limit;;;;; -;;3035;uwUnderFreD ischargeDelyT ime;Under Fre Delay Time;R/W;;50ms;;;;Under Fre Delay Time;;;;; -;;3036;GridFirstDisch argePowerRat e;Discharge Power Rate when Grid First;W;0-100 ;1.00%;;;;;;;;; -;;3037;GridFirstStopS OC;Stop Discharge soc when Grid First;W;0-100 ;1.00%;;;;;;;;; -;;3038;Time 1_xh_ Start;Period 1: [Start Time ~ End Time] [Charge/Discharge] [Disable/Enable] 3038 enable charge and discharge;R/W;;;;;;;;;;;"Bit0~7: minutes; Bit8~12: hour; Bit13~14, 0: load priority; 1: battery priority; 2: Grid priority; Bit15, 0: prohibited; 1: enabled;" -;;3039;Time 1_xh_ End;;R/W;;;;;;"Bit0~7: minutes; Bit8~12: hour; Bit13~15: reserved";;;;; -;;3040;Time 2_xh_ Start;Time period 2: [start time ~ end time] [charge / discharge] [disable / enable] 3040 enable charge and discharge;R/W;;;;;;;;;;;"Bit0~7: minutes; Bit8~12: hour; Bit13~14, 0: load priority; 1: battery priority; 2: Grid priority; Bit15, 0: prohibited; 1:" -;;3041;Time 2_xh_ End;;R/W;;;;;;"enabled;";;;;; -;;3042;Time 3_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3043;Time 3_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3044;Time 4_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3045;Time 4_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3047;BatFirstPower Rate;Charge Power Rate when Bat First;;;;;;;;;;;; -;;3048;wBatFirst stop SOC;Stop Charge soc when Bat First;;;;;;;;;;;; -;;3049;AcChargeEna ble;AcChargeEnable;;;;;;;Enable :1 Disable:0;;;;; -;;3050;Time 5_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3051;Time 5_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3052;Time 6_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3053;Time 6_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3054;Time 7_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3055;Time 7_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3056;Time 8_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3057;Time 8_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3058;Time 9_xh_ Start;With Time1;R/W;;;;;;With Time1;;;;; -;;3059;Time 9_xh_ End;;R/W;;;;;;With Time1;;;;; -;;3070;BatteryType;Battery type choose of buck-boost input;R/W;;;;;;Battery type 0:Lithium 1:Lead-acid 2:other;;;;; -;;3071;BatMdlSeria_ ParalNum;BatMdlSeria/ParalNum;R/W;;;;;;"BatMdlSeria/Paral Num; SPH4-11K used The upper 8 bits indicate the number of series segments; The lower 8 bits indicate the number of parallel sections;";;;;; -;;3079;UpsFunEn;Ups function enable or disable;R/W;;;;0;;0:disable 1:enable;;;;; -;;3080;UPSVoltSet;UPS output voltage;R/W;;;;0;;0:230V 1:208V 2:240V;;;;; -;;3081;UPSFreqSet;UPS output frequency;R/W;;;;0;;0:50Hz 1:60Hz;;;;; -;;3082;bLoadFirstSto pSocSet;StopSoc When LoadFirst;R/W;13-100;;;;;ratio;;;;; -;;3085;Com Address;Communication addr;R/W;;;;1;;1 : Communication addr=1 1 ~ 254 : Communication addr=1~254;;;;; -;;3086;BaudRate;Communication BaudRate;R/W;;;;0;;0: 9600 bps 1: 38400 bps;;;;; -;;3087;Serial NO_ 1;Serial Number 1-2;R/W;;ASCII;;;;For battery;;;;; -;;3088;Serial NO_ 2;Serial Number 3-4;R/W;;ASCII;;;;;;;;; -;;3089;Serial NO_ 3;Serial Number 5-6;R/W;;ASCII;;;;;;;;; -;;3090;Serial NO_ 4;Serial Number 7-8;R/W;;ASCII;;;;;;;;; -;;3091;Serial No_ 5;Serial Number 9-10;R/W;;ASCII;;;;;;;;; -;;3092;Serial No_6;Serial Number 11-12;R/W;;ASCII;;;;;;;;; -;;3093;Serial No_ 7;Serial Number 13-14;R/W;;ASCII;;;;;;;;; -;;3094;Serial No_ 8;Serial Number 15-16;R/W;;ASCII;;;;;;;;; -;;3095;BdcResetCmd;BDC Reset command;R/W;;;;;;0:Invalid data 1:Reset setting parameters 2:Reset correction parameter 3:Clear historical power;;;;; -;;3096;ARKM3 Code;BDCMonitoring software code;R;;ASCII;;;;ZEBA;;;;; -;;3098;DTC;DTC;R;;;;;;;;;;; -;;3099;FW Code;DSP software code;R;;ASCII;;;;;;;;; -;;3101;Processor1 FW Vision;DSP Software Version;R;;ASCII;;;;;;;;; -;;3102;BusVoltRef;Minimum BUS voltage for charging and discharging batteries;R;;;;;;;;;;; -;;3103;ARKM3Ver;BDC monitoring software version;R;;;;;;;;;;; -;;3104;BMS_MCUVer sion;BMS hardware version information;R;1;;;;;;;;;; -;;3105;BMS_FW;BMS software version information;R;1;;;;;;;;;; -;;3106;BMS_Info;BMS ManufacturerName;R;1;;;;;;;;;; -;;3107;BMSCommTy pe;BMSCommType;R;1;;;;;"BMSCommunicati on interface type: 0: RS485; 1: CAN;";;;;; -;;3108;Module 4;BDCmodel (4);R/W;&*11;;;;;SxxBxx;;;;; -;;3109;Module 3;BDCmodel (3);R/W;&*11;;;;;DxxTxx;;;;; -;;3110;Module 2;BDCmodel (2);R/W;&*11;;;;;PxxUxx;;;;; -;;3111;Module 1;BDCmodel (1);R/W;&*11;;;;;Mxxxx;;;;; -;;3113;unProtocolVe r;BDCProtocolVer;R;1;;;;;Bit8-bit15 The major version number ranges from 0-256. In principle; it cannot be changed Bit0-bit7 Minor version number [0-256]. If the protocol is changed; you need to update this version No.;;; -;;3114;uwCertificatio nVer;BDC CertificationVer;R;1;;;;;;;;;; -;;3125;Time Month1;Use with Time1-9(us) Add month time;R/W;;;;;;;"bit0~3:month_L; bit4~7: month_H bit8, 0:disable 1:enable Bit9~15:reserve";;;; -;;3126;Time Month2;Use with Time10-18(us) Add month time;R/W;;;;;;;With Time Month1;;;; -;;3127;Time Month3;Use with Time19-27(us) Add month time;R/W;;;;;;;With Time Month1;;;; -;;3128;Time Month4;Use with Time28-36(us) Add month time;R/W;;;;;;;With Time Month1;;;; -;;3129;Time 1_us_ start;time1:[starttime~endtime];R/W;;;;;;"bit0~6:min; bit7~11:hour; bit12~14, 0:loadfirst;";;;;; -;;3130;Time 1_us_ end;;R/W;;;;;;;"1:batfirst; 2:gridfirst; 3: anti-reflux bit15, 0:disable; 1:enable;";;;; -;;3131;Time 2_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3132;Time 2_us_ end;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3133;Time 3_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3134;Time 3_us_ end;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3135;Time 4_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3135;Time 4_us_ end;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3137;Time 5_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3138;Time 5_us_ end;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3139;Time 6_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3140;Time 6_us_ end;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3141;Time 7_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3142;Time 7_us_ end;Same as above;R/W;;;;;;;;;;; -;;3143;Time 8_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3144;Time 8_us_ end;Same as above;R/W;;;;;;;;;;; -;;3145;Time 9_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3146;Time 9_us_ end;Same as above;R/W;;;;;;;;;;; -;;3147;Time 10_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3148;Time 10_us_ end;Same as above;R/W;;;;;;;;;;; -;;3149;Time 11_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3150;Time 11_us_ end;Same as above;R/W;;;;;;;;;;; -;;3151;Time 12_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3152;Time 12_us_ end;Same as above;R/W;;;;;;;;;;; -;;3153;Time 13_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3154;Time 13_us_ end;Same as above;R/W;;;;;;;;;;; -;;3155;Time 14_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3156;Time 14_us_ end;Same as above;R/W;;;;;;;;;;; -;;3157;Time 15_us_ start;Same as above;R/W;;;;;;Same as Time 1 (us);;;;; -;;3158;Time 15_us_ end;Same as above;R/W;;;;;;;;;;; -;;3159;Time 16_us_ start;Same as above;R/W;;;;;;;;;;; -;;3160;Time 16_us_ end;Same as above;R/W;;;;;;;;;;; -;;3201;SpecialDay1;SpecialDay1(month; Day);R/W;;;;;;;"bit0~7:day; bit8~14:month bit15, 0:disable 1: enable";;; -;;3202;SpecialDay1_Time1_Start;Start time;R/W;;;;;;"bit0~6:min; bit7~11:hour; bit12~14, 0:loadfirst; 1:batfirst; 2:gridfirst; 3: anti-reflux bit15, 0: disable; 1: enable;";;;;; -;;3203;SpecialDay1_Time1_End;endtime;R/W;;;;;;"bit0~6:min; bit7~11:hour; bit12~15:reserve";;;;; -;;3204;SpecialDay1_ Time2_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3205;SpecialDay1_ Time2_End;;R/W;;;;;;;;;;; -;;3206;SpecialDay1_ Time3_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3207;SpecialDay1_ Time3_End;;R/W;;;;;;;;;;; -;;3208;SpecialDay1_ Time4_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3209;SpecialDay1_ Time4_End;;R/W;;;;;;;;;;; -;;3210;SpecialDay1_ Time5_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3211;SpecialDay1_ Time5_End;;R/W;;;;;;;;;;; -;;3212;SpecialDay1_ Time6_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3213;SpecialDay1_ Time6_End;;R/W;;;;;;;;;;; -;;3214;SpecialDay1_ Time7_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3215;SpecialDay1_ Time7_End;;R/W;;;;;;;;;;; -;;3216;SpecialDay1_ Time8_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3217;SpecialDay1_ Time8_End;;R/W;;;;;;;;;;; -;;3218;SpecialDay1_ Time9_Start;Same as above;R/W;;;;;;Same as SpecialDay1_Time 1;;;;; -;;3219;SpecialDay1_ Time9_End;;R/W;;;;;;;;;;; -;;3220;SpecialDay2;SpecialDay2(month; Day);R/W;;;;;;;"bit0~7:day; bit8~14:month bit15, 0:disable 1:enable";;; -;;3221;SpecialDay2_ Time1_Start;Start time;R/W;;;;;;"bit0~6: min; bit7~11: hour; bit12~14, 0: loadfirst; 1: batfirst; 2: gridfirst; 3: anti-reflux bit15, 0: disable; 1: enable;";;;;; -;;3222;SpecialDay2_ Time1_End;endtime;R/W;;;;;;"bit0~6: min; bit7~11: hour; bit12~15:reserve";;;;; -;;3223;SpecialDay2_ Time2_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3224;SpecialDay2_ Time2_End;;R/W;;;;;;;;;;; -;;3225;SpecialDay2_ Time3_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3226;SpecialDay2_ Time3_End;;R/W;;;;;;;;;;; -;;3227;SpecialDay2_ Time4_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3228;SpecialDay2_ Time4_End;;R/W;;;;;;;;;;; -;;3229;SpecialDay2_ Time5_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3230;SpecialDay2_ Time5_End;;R/W;;;;;;;;;;; -;;3231;SpecialDay2_ Time6_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3232;SpecialDay2_ Time6_End;;R/W;;;;;;;;;;; -;;3233;SpecialDay2_ Time7_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3234;SpecialDay2_ Time7_End;;R/W;;;;;;;;;;; -;;3235;SpecialDay2_ Time8_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3236;SpecialDay2_ Time8_End;;R/W;;;;;;;;;;; -;;3237;SpecialDay2_ Time9_Start;Same as above;R/W;;;;;;Same as SpecialDay2_Time 1;;;;; -;;3238;SpecialDay2_ Time9_End;;R/W;;;;;;;;;;; +variable name,data type,register,documented name,description,write,values,unit,Initial value,note,,,,,,, +,,0,OnOff,Remote On/Off . On(1);Of(f 0)Inverter On(3);Off(2)BDC,W,0,1,2,3,,1,The inverter can be switched on and off, and the BDC can be switched on and off for the batt ready function.,,, +,,1,SaftyFuncEn,Bit0: SPI enable Bit1: AutoTestStart Bit2: LVFRT enable Bit3:FreqDerating Enable Bit4: Softstart enable Bit5: DRMS enable Bit6:PowerVoltFunc Enable Bit7: HVFRT enable Bit8:ROCOF enable Bit9: Recover FreqDeratingMode Enable Bit10:Split phase enable Bit10~15:??,W,0 :Disable1: enable,,,SPI: systemprotectioninterfaceBit0~3:for CEI0-21Bit4~6:for SAA,,,,,,, +,,2,PF CMDmemoryState,Set Holding register3,4,5,99 CMD will be memory or not(1/0), if not, these settings are the initial value. ,W,0or1,,0,Means these settings will beacting or not whennextpower on ,, +,,3,Active P Rate,Inverter Max output active power percent,W,0-100 or 255,%,255,255: power is not be limited,,,,,,, +,,4,Reactive P Rate,Inverter max output reactive power percent,W,-100-100 or 255,%,255,255: power is not be limited,,,,,,, +,,5,Power factor,Inverter output powerfactor's 10000 times,W,0-20000, 0-10000isunderexcited, otherisoverexcitEd,,,,0,,,, +,,6,Pmax H,Normal power (high),,,0.1VA,,,,,,,,, +,,7,Pmax L,Normal power (low),,,0.1VA,,,,,,,,, +,,8,Vnormal,Normal work PV voltage,,,0.1V,,,,,,,,, +,,9,Fw version H,Firmware version (high),,,ASCII,,,,,,,,, +,,10,Fw version M,Firmware version (middle),,,,,,,,,,,, +,,11,Fw version L,Firmware version (low),,,,,,,,,,,, +,,12,Fw version2 H,Control Firmware version (high),,,ASCII,,,,,,,,, +,,13,Fw version2 M,Control Firmware version (middle),,,,,,,,,,,, +,,14,Fw version2 L,Control Firmware version (low),,,,,,,,,,,, +,,15,LCD language,LCD language,W,0-5,,,0: Italian; 1: English; 2: German; 3: Spanish; 4: French; 5: Chinese; 6:Polish 7:Portugues 8:Hungary,,,,,,, +,,16,CountrySele cted,Country Selected or not,W,0: need to select; 1: have selected,,,,,,,,,, +,,17,Vpv start,Input start voltage,W,,0.1V,,,,,,,,, +,,18,Time start,Start time,W,,1s,,,,,,,,, +,,19,RestartDelay Time,Restart Delay Time after fault back;,W,,1s,,,,,,,,, +,,20,wPowerStart Slope,Power start slope,W,01/01/00,0.10%,,,,,,,,, +,,21,wPowerRest artSlopeEE,Power restart slope,W,01/01/00,0.10%,,,,,,,,, +,,22,wSelectBaud rate,Select communicationbaudrat e 0: 9600bps 1:38400bps,W,0-1,,0,,,,,,,, +,,23,Serial NO 1,Serial number 1-2,,,ASCII,,,,,,,,, +,,24,Serial NO 2,Serial number 3-4,,,,,,,,,,,, +,,25,Serial NO 3,Serial number 5-6,,,,,,,,,,,, +,,26,Serial NO 4,Serial number 7-8,,,,,,,,,,,, +,,27,Serial NO 5,Serial number 9-10,,,,,,,,,,,, +,,28,Module H,Inverter Module (high),,&*5,,,,,,,,,, +,,29,Module L,Inverter Module (low),,&*5,,,,,,,,,, +,,30,Com Address,Communicate address,W,01/01/54,,1,,,,,,,, +,,31,FlashStart,Update firmware,W,1,,,,,,,,,, +,,32,Reset User Info,Reset User Information,W,0x0001,,,,,,,,,, +,,33,Reset to factory,Reset to factory,W,0x0001,,,,,,,,,, +,,34,Manufacturer Info 8,Manufacturer information (high),,,ASCII,,,,,,,,, +,,35,Manufacturer Info 7,Manufacturer information (middle),,,,,,,,,,,, +,,36,Manufacturer Info 6,Manufacturer information (low),,,,,,,,,,,, +,,37,Manufacturer Info 5,Manufacturer information (high),,,,,,,,,,,, +,,38,Manufacturer Info 4,Manufacturer information (middle),,,,,,,,,,,, +,,39,Manufacturer Info3,Manufacturer information (low),,,,,,,,,,,, +,,40,Manufacturer Info 2,Manufacturer information (low),,,,,,,,,,,, +,,41,Manufacturer Info 1,Manufacturer information (high),,,,,,,,,,,, +,,42,bfailsafeEn,G100 fail safe,W,Enable:1 Disable:0,,,English G100 fail safe set,,,,,,, +,,43,DTC,Device Type Code,,&*6,,,,,,,,,, +,,44,TP,Input tracker num and output phase num,,Eg:0x020 3 is two MPPT and 3ph output,,,,,,,,,, +,,45,Sys Year,System time-year,W,Year offset is 0,,,Local time,,,,,,, +,,46,Sys Month,System time- Month,W,,,,,,,,,,, +,,47,Sys Day,System time- Day,W,,,,,,,,,,, +,,48,Sys Hour,System time- Hour,W,,,,,,,,,,, +,,49,Sys Min,System time- Min,W,,,,,,,,,,, +,,50,Sys Sec,System time- Second,W,,,,,,,,,,, +,,51,Sys Weekly,System Weekly,W,0-6,,,,,,,,,, +,,52,Vac low,Grid voltage low limit protect,W,,0.1V,,,,,,,,, +,,53,Vac high,Grid voltage high limit protect,W,,0.1V,,,,,,,,, +,,54,Fac low,Grid frequency low limit protect,W,,0.01 Hz,,,,,,,,, +,,55,Fac high,Grid high frequencylimit protect,W,,0.01 Hz,,,,,,,,, +,,56,Vac low 2,Grid voltage low limit protect 2,W,,0.1V,,,,,,,,, +,,57,Vac high 2,Grid voltage high limit protect 2,W,,0.1V,,,,,,,,, +,,58,Fac low 2,Grid frequency low limit protect 2,W,,0.01 Hz,,,,,,,,, +,,59,Fac high 2,Grid high frequency limit protect 2,W,,0.01 Hz,,,,,,,,, +,,60,Vac low 3,Grid voltage low limit protect 3,W,,0.1V,,,,,,,,, +,,61,Vac high 3,Grid voltage high limit protect 3,W,,0.1V,,,,,,,,, +,,62,Fac low 3,Grid frequency low limit protect 3,W,,0.01Hz,,,,,,,,, +,,63,Fac high 3,Grid frequency high limit protect 3,W,,0.01Hz,,,,,,,,, +,,64,Vac low C,Grid low voltage limit connect to Grid,W,,0.1V,,,,,,,,, +,,65,Vac high C,Grid high voltage limit connect to Grid,W,,0.1V,,,,,,,,, +,,66,Fac low C,Grid low frequency limit connect to Grid,W,,0.01 Hz,,,,,,,,, +,,67,Fac high C,Grid high frequency limit connect to Grid,W,,0.01 Hz,,,,,,,,, +,,68,Vac low1 time,Grid voltage low limit protect time 1,W,,Cycle,,,,,,,,, +,,69,Vac high1 time,Grid voltage high limit protect time 1,W,,Cycle,,,,,,,,, +,,70,Vac low2 time,Grid voltage low limit protect time 2,W,,Cycle,,,,,,,,, +,,71,Vac high2 time,Grid voltage high limit protect time 2,W,,Cycle,,,,,,,,, +,,72,Fac low1 time,Grid frequency low limit protect time 1,W,,Cycle,,,,,,,,, +,,73,Fac high1 time,Grid frequency high limit protect time 1,W,,Cycle,,,,,,,,, +,,74,Fac low2 time,Grid frequency low limit protect time 2,W,,Cycle,,,,,,,,, +,,75,Fac high2 time,Grid frequency high limit protect time 2,W,,Cycle,,,,,,,,, +,,76,Vac low3 time,Grid voltage low limit protect time 3,W,,Cycle,,,,,,,,, +,,77,Vac high3 time,Grid voltage high limit protect time 3,W,,Cycle,,,,,,,,, +,,78,Fac low3 time,Grid frequency low limit protect time 3,W,,Cycle,,,,,,,,, +,,79,Fac high3 time,Grid frequency high limit protect time 3,W,,Cycle,,,,,,,,, +,,80,U10min,Volt protection for 10 min,W,,0.1V,1.1Vn,,,,,,,, +,,81,PV Voltage High Fault,PV Voltage High Fault,W,,0.1V,,,,,,,,, +,,82,FW Build No_ 5,Model letter version number (TJ),,,ASCII,,,,,,,,, +,,83,FW Build No_ 4,Model letter version number (AA),,,ASCII,,,,,,,,, +,,84,FW Build No_ 3,DSP1 FW Build No.,,,ASCII,,,,,,,,, +,,85,FW Build No_ 2,DSP2/M0 FW Build No.,,,ASCII,,,,,,,,, +,,86,FW Build No_ 1,CPLD/AFCI FW Build No.,,,ASCII,,,,,,,,, +,,87,FW Build No_ 0,M3 FW Build No.,,,ASCII,,,,,,,,, +,,88,ModbusVers ion,Modbus Version,,Eg:207 is V2.07,Int(16 bits),,,,,,,,, +,,89,PFModel,Set PF function Model 0: PF=1 1: PF by set 2: default PF line 3: User PF line 4: UnderExcited (Inda) Reactive Power 5: OverExcited(Capa) Reactive Power 6:Q(v)model 7:Direct Control mode,W,,,,,,,,,,, +,,90,GPRS IP Flag,Bit0-3:read:1;Set GPRS IP Successed Write:2;Read GPRS IP Successed Bit4-7:GPRS status,W,Bit0-3:ab out GPRS IP SET Bit4-7:ab out GRPRS Status,,,,,,,,,, +,,91,FreqDerateS tart,Frequency derating start point,W,,0.01H Z,,,,,,,,, +,,92,FLrate,Frequency - load limit rate,W,0-100,10tim es,,,,,,,,, +,,93,V1S,CEI021 V1S Q(v),W,V1S50,W,,0.1V,,Clear battery low voltage error voltage point,,,,,,, +,,1004,Vbatstopfo rdischarge,Should stop discharge when lower than this voltage(only lead-Acid): 46.0V <20% 44.8V 20%~50% 44.2V >50%,W,,0.01V,,,,,,,,, +,,1005,Vbat stop for charge,Should stop charge when higher than this voltage,W,,0.01V,5800,,,,,,,, +,,1006,Vbat start for discharge,Should not discharge when lower than this voltage,W,,0.01V,4800,,,,,,,, +,,1007,Vbat constant charge,can charge when lower than this voltage,W,,0.01V,5800,CV voltage(acid),,,,,,, +,,1008,EESysInfo_S ysSetEn,"Bit0:Resved; Bit1:Resved; Bit2:Resved; Bit3:Resved; Bit4:Resved; Bit5:bDischargeEn; Bit6:ForceDischrEn; Bit7:ChargeEn; Bit8:bForceChrEn; Bit9:bBackUpEn; Bit10:bInvLimitLoadE; Bit11:bSpLimitLoadEn; Bit12:bACChargeEn; Bit13:bPVLoadLimitEn; Bit14,15:UnUsed;",W,,,,System Enable,,,,,,, +,,1009,Battemp lower limit d,Battery temperature lower limit for discharge,W,0-200:0-2 0? 1000-140 0:-40-0?,0.1?,1170,,,,,,,, +,,1010,Bat temp upper limit d,Battery temperature upper limit for discharge,W,200-1000,0.1?,420,,,,,,,, +,,1011,Bat temp lower limit c,Battery temperature lower limit for charge,W,0-200:0-2 0? 1000-140 0:-40-0?,0.1?,30,Lower temperature limit,,,,,,, +,,1012,Bat temp upper limit c,Battery temperature upper limit for charge,W,200-1000,0.1?,370,Upper temperature limit,,,,,,, +,,1013,uwUnderFr eDischarge DelyTime,Under Fre Delay Time,s,0-20,50ms,,Under Fre Delay Time,,,,,,, +,,1014,BatMdlSeri alNum,Battery serial number,W,12:00:00 AM,,,SPH4-11K used,,,,,,, +,,1015,BatMdlPara llNum,Battery parallel section,W,12:00:00 AM,,,SPH4-11K used,,,,,,, +,,1016,DRMS_EN,/,/,/,/,/,0:disable 1:enable,,,,,,, +,,1017,Bat First Start Time 4,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1018,Bat First Stop Time 4,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1019,BatFirst on_off Switch 4,Enable:1 Disable:0,,0 or 1,,,Battery priority enable 1,,,,,,, +,,1020,Bat First Start Time 5,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1021,Bat First Stop Time 5,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1022,BatFirst on_off Switch 5,Enable:1 Disable:0,,0 or 1,,,Battery priority enable 1,,,,,,, +,,1023,Bat First Start Time 6,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1024,Bat First Stop Time 6,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1025,BatFirst on_off Switch 6,Enable:1 Disable:0,,0 or 1,,,Battery priority enable 1,,,,,,, +,,1026,Grid First Start Time 4,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1027,Grid First Stop Time 4,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1028,Grid First Stop Switch 4,Enable:1 Disable:0,,0 or 1,,,Grid priority enable,,,,,,, +,,1029,Grid First Start Time 5,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1030,Grid First Stop Time 5,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1031,Grid First Stop Switch 5,Enable:1 Disable:0,,0 or 1,,,Grid priority enable,,,,,,, +,,1032,Grid First Start Time 6,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1033,Grid First Stop Time 6,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1034,Grid First Stop Switch 6,Enable:1 Disable:0,,0 or 1,,,Grid priority enable,,,,,,, +,,1035,Bat First Start Time 4,High eight:hours Low eight: minutes,,0-23 0-59,,,,,,,,,, +,,1037,bCTMode,Use the CTMode to Choose RFCT \ Cable CT\METER,W,2:METER 1:cWirele ssCT 0:cWiredC T,,0,,,,,,,, +,,1038,CTAdjust,CTAdjust enable,W,0:disable 1:enable,,0,,,,,,,, +,,1044,Priority,ForceChrEn/ForceDischr En Load first/bat first /grid first,R,0.Load(de fault)/1.B attery/2.G rid,,,bForceChrEn/disbForceDischrE n/dis,,,,,,, +,,1047,AgingTestSt ep Cmd,Command for aging test,,0: default 1: charge 2: discharge,,,Cmd for aging test,,,,,,, +,,1048,BatteryTyp e,Battery type choose of buck-boost input,,0:Lithium 1:Lead-aci d 2:other,,0,Battery type,,,,,,, +,,1060,BuckUpsFunE n,Ups function enable or disable,,0:disable 1:enable,,,,,,,,,, +,,1061,BuckUPSVoltSet,UPS output voltage,,0:230 1:208 2:240,,230V,,,,,,,, +,,1062,UPSFreqSet,UPS output frequency,,0:50Hz 1:60Hz,,50Hz,,,,,,,, +,,1070,GridFirstDisch argePowerRat e,Discharge Power Rate when Grid First,W,0-100,1.00%,,Discharge Power Rate when Grid First,,,,,,, +,,1071,GridFirstStopS OC,Stop Discharge soc when Grid First,W,0-100,1.00%,,Stop Discharge soc when Grid First,,,,,,, +,,1080,Grid First Start Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1081,Grid First Stop Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1082,Grid First Stop Switch 1,Enable :1 Disable:0,,0 or 1,,,Grid First enable,,,,,,, +,,1083,Grid First Start Time 2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1084,Grid First Stop Time 2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1085,Grid First Stop Switch 2,ForceDischarge.bSwitch&L CD_SET_FORCE_TRUE_2)= =LCD_SET_FORCE_TRUE_2,,0 or 1,,,Grid First enable,,ForceDischarge; LCD_SET_FORCE_T RUE_2,,,,, +,,1086,Grid First Start Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1087,Grid First Stop Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1088,Grid First Stop Switch 3,Enable :1 Disable:0,,0 or 1,,,Grid First enable,,,,,,, +,,1090,BatFirstPower Rate,Charge Power Rate when Bat First,W,0-100,1.00%,,Charge Power Rate when Bat First,,,,,,, +,,1091,wBatFirst stop SOC,Stop Charge soc when Bat First,W,0-100,1.00%,,Stop Charge soc when Bat First,,,,,,, +,,1092,AC charge Switch,When Bat First Enable:1 Disable:0,,Enable:1 Disable:0,,,AC Charge Enable,,,,,,, +,,1100,Bat First Start Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1101,Bat First Stop Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1102,BatFirst on_off Switch 1,Enable :1 Disable:0,,0 or 1,,,Bat First Enable1,,,,,,, +,,1103,Bat First Start Time 2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1104,Bat First Stop Time 2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1105,BatFirston_off Switch 2,Enable :1 Disable:0,,0 or 1,,,Bat First Enable2,,,,,,, +,,1106,Bat First Start Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1107,Bat First Stop Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,,,,,, +,,1108,BatFirston_off Switch 3,Enable :1 Disable:0,,0 or 1,,,Bat First Enable3,,,,,,, +,,1110,Load First Start Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1111,Load First Stop Time 1,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1112,Load First Switch 1,Enable :1 Disable:0,,0 or 1,,,Load First Enable,,SPA/ reserve,,,,, +,,1113,Load First Start Time2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1114,Load First Stop Time 2,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1115,Load First Switch 2,Enable :1 Disable:0,,0 or 1,,,Load First Enable,,SPA/ reserve,,,,, +,,1116,Load First Start Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1117,Load First Stop Time 3,High eight bit:hour Low eight bit:minute,,0-23 0-59,,,,,SPA/ reserve,,,,, +,,1118,Load First Switch 3,Enable :1 Disable:0,,0 or 1,,,Load First Enable,,SPA/ reserve,,,,, +,,1119,NewEPowerC alcFlag,/,,/,,,/,,0:The old formula 1 : The new formula,,,,, +,,1120,BackUpEn,BackUp Enable,,,,,,,MIX US,,,,, +,,1121,SGIPEn,SGIP Enable,,,,,,,MIX US,,,,, +,,1125,BatSerialNO_ 8_B1,Product serial number of the first PACK of energy storage batteries,,/,ASCII,,,,,,,,, +,,1126,BatSerialNO_ 7_B1,,,/,ASCII,,,,,,,,, +,,1127,BatSerialNO_ 6_B1,,,/,ASCII,,,,,,,,, +,,1128,BatSerialNO_ 5_B1,,,/,ASCII,,,,,,,,, +,,1129,BatSerialNO_ 4_B1,,,/,ASCII,,,,,,,,, +,,1130,BatSerialNO_ 3_B1,,,/,ASCII,,,,,,,,, +,,1131,BatSerialNO_ 2_B1,,,/,ASCII,,,,,,,,, +,,1132,BatSerialNO_ 1_B1,,,,,,,,,,,,, +,,1244,Com version NameH,Name of the battery main control firmware version,,,ASCII,,,,,,,,, +,,1245,Com version NameL,Name of the battery main control firmware version,,,ASCII,,,,,,,,, +,,1246,Com version No,Version of the battery main control firmware,,,digital,,,,,,,,, +,,1247,Com version NameH,Name of battery monitoring firmware version,,,ASCII,,,,,,,,, +,,1248,Com version NameL,Name of battery monitoring firmware version,,,ASCII,,,,,,,,, +,,1249,Com version No,Battery monitoring firmware version,,,digital,,,,,,,,, +,,3000,ExportLimitFa iledPowerRat e,The power rate when exportLimit failed,R/W,,0.10%,,,,The power rate when exportLimit failed,,,,, +,,3001,New Serial NO,Serial number 1-2,R/W,,ASCII,,,,The new model uses the following registers to record the serial number; The representation is the same as the original: one register holds two characters and the new serial number is 30 characters.,,,,, +,,3002,New Serial NO,Serial number 3-4,R/W,,ASCII,,,,,,,,, +,,3003,New Serial NO,Serial number 5-6,R/W,,ASCII,,,,,,,,, +,,3004,New Serial NO,Serial number 7-8,R/W,,ASCII,,,,,,,,, +,,3005,New Serial NO,Serial number 9-10,R/W,,ASCII,,,,,,,,, +,,3006,New Serial NO,Serial number 11-12,R/W,,ASCII,,,,,,,,, +,,3007,New Serial NO,Serial number 13-14,R/W,,ASCII,,,,,,,,, +,,3008,New Serial NO,Serial number 15-16,R/W,,ASCII,,,,,,,,, +,,3009,New Serial NO,Serial number 17-18,R/W,,ASCII,,,,,,,,, +,,3010,New Serial NO,Serial number 19-20,R/W,,ASCII,,,,,,,,, +,,3011,New Serial NO,Serial number 21-22,R/W,,ASCII,,,,,,,,, +,,3012,New Serial NO,Serial number 23-24,R/W,,ASCII,,,,,,,,, +,,3013,New Serial NO,Serial number 25-26,R/W,,ASCII,,,,,,,,, +,,3014,New Serial NO,Serial number 27-28,R/W,,ASCII,,,,,,,,, +,,3015,New Serial NO,Serial number 29-30,R/W,,ASCII,,,,,,,,, +,,3016,DryContactFu ncEn,DryContact function enable,R/W,0:Disable 1: Enable,,,,,DryContact function enable,,,,, +,,3017,DryContactOn Rate,The power rate of drycontact turn on,R/W,0~1000,0.10%,,,,The power rate of drycontact turn on,,,,, +,,3018,bWorkMode,WorkMode 0:default 1: System Retrofit 2: Multi-Parallel,R/W,1,2,3,,,,,,MIN2.5~6KTL-XH/ XA Double CT special,, +,,3019,DryContactOffRate,Dry contact closure power,R/W ,0~100 0,0.10%,,,,Dry contact closure power pe rcentage,,,,, +,,3020,BoxCtrlInvOrder,Off-net box control instruct ion,R/W ,,,,,,,,,,, +,,3021,ExterCommOf fGridEn,External communication setting manual off-network enable,R/W,,,,,,0x00: Disable; (default) 0x01: Enable;,,,,, +,,3022,uwBdcStopW orkOfBusVolt,BdcStopWorkOfBusVolt,R,,,,,,,,,,, +,,3023,bGridType,GridType---0:SinglePhase 1:ThreePhase 2:SplitPhase,R/W,1,2,3,,,,,MIN2.5~6KTL-XH/ XA Double CT special,,, +,,3024,Float charge current limit,When charge current battery need is lower than this value enter into float charge,R/W,,0.1A,,600,,CC current,,,,, +,,3025,VbatWarning,"""Battery-low"" warning setup voltage",R/W,,0.1V,,4800,,Lead acid battery LV voltage,,,,, +,,3026,VbatlowWarn Clr,"""Battery-low"" warning clear voltage",R/W,,0.1V,,,,Clear battery low voltage error voltage point LoadPercent(only lead-Acid): 45.5V(Load < 20%); 48.0V(20%<=Load <=50%); 49.0V(Load > 50%);,,,,, +,,3027,Vbatstopfordi scharge,Battery cut off voltage,R/W,,0.1V,,,,Should stop discharge when lower than this voltage(only lead-Acid): 46.0V(Load < 20%); 44.8V(20%<=Load <=50%); 44.2V(Load > 50%);,,,,, +,,3028,Vbat stop for charge,Battery over charge voltage,R/W,,0.01V,,5800,,Should stop charge when higher than this voltage,,,,, +,,3029,Vbat start for discharge,Battery start discharge voltage,R/W,,0.01V,,4800,,Should not discharge when lower than this voltage,,,,, +,,3030,Vbat constant charge,Battery constant charge voltage,R/W,,0.01V,,5800,,CV voltage(acid) can charge when lower than this voltage,,,,, +,,3031,Battemp lower limit d,Battery temperature lower limit for discharge,R/W,,0.1?,,1170,,0-200:0-20? 1000-1400: -40-0?,,,,, +,,3032,Bat temp upper limit d,Battery temperature upper limit for discharge,R/W,,0.1?,,420,,,,,,, +,,3033,Bat temp lower limit c,Battery temperature lower limit for charge,R/W,,0.1?,,30,,Battery temperature lower limit 0-200:0-20? 1000-1400: -40-0?,,,,, +,,3034,Bat temp upper limit c,Battery temperature upper limit for charge,R/W,,0.1?,,370,,Battery temperature upper limit,,,,, +,,3035,uwUnderFreD ischargeDelyT ime,Under Fre Delay Time,R/W,,50ms,,,,Under Fre Delay Time,,,,, +,,3036,GridFirstDisch argePowerRat e,Discharge Power Rate when Grid First,W,0-100 ,1.00%,,,,,,,,, +,,3037,GridFirstStopS OC,Stop Discharge soc when Grid First,W,0-100 ,1.00%,,,,,,,,, +,,3038,Time 1_xh_ Start,Period 1: [Start Time ~ End Time] [Charge/Discharge] [Disable/Enable] 3038 enable charge and discharge,R/W,,,,,,,,,,,"Bit0~7: minutes; Bit8~12: hour; Bit13~14, 0: load priority; 1: battery priority; 2: Grid priority; Bit15, 0: prohibited; 1: enabled;" +,,3039,Time 1_xh_ End,,R/W,,,,,,Bit0~7: minutes; Bit8~12: hour; Bit13~15: reserved,,,,, +,,3040,Time 2_xh_ Start,Time period 2: [start time ~ end time] [charge / discharge] [disable / enable] 3040 enable charge and discharge,R/W,,,,,,,,,,,"Bit0~7: minutes; Bit8~12: hour; Bit13~14, 0: load priority; 1: battery priority; 2: Grid priority; Bit15, 0: prohibited; 1:" +,,3041,Time 2_xh_ End,,R/W,,,,,,enabled;,,,,, +,,3042,Time 3_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3043,Time 3_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3044,Time 4_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3045,Time 4_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3047,BatFirstPower Rate,Charge Power Rate when Bat First,,,,,,,,,,,, +,,3048,wBatFirst stop SOC,Stop Charge soc when Bat First,,,,,,,,,,,, +,,3049,AcChargeEna ble,AcChargeEnable,,,,,,,Enable :1 Disable:0,,,,, +,,3050,Time 5_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3051,Time 5_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3052,Time 6_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3053,Time 6_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3054,Time 7_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3055,Time 7_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3056,Time 8_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3057,Time 8_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3058,Time 9_xh_ Start,With Time1,R/W,,,,,,With Time1,,,,, +,,3059,Time 9_xh_ End,,R/W,,,,,,With Time1,,,,, +,,3070,BatteryType,Battery type choose of buck-boost input,R/W,,,,,,Battery type 0:Lithium 1:Lead-acid 2:other,,,,, +,,3071,BatMdlSeria_ ParalNum,BatMdlSeria/ParalNum,R/W,,,,,,BatMdlSeria/Paral Num; SPH4-11K used The upper 8 bits indicate the number of series segments; The lower 8 bits indicate the number of parallel sections;,,,,, +,,3079,UpsFunEn,Ups function enable or disable,R/W,,,,0,,0:disable 1:enable,,,,, +,,3080,UPSVoltSet,UPS output voltage,R/W,,,,0,,0:230V 1:208V 2:240V,,,,, +,,3081,UPSFreqSet,UPS output frequency,R/W,,,,0,,0:50Hz 1:60Hz,,,,, +,,3082,bLoadFirstSto pSocSet,StopSoc When LoadFirst,R/W,13-100,,,,,ratio,,,,, +,,3085,Com Address,Communication addr,R/W,,,,1,,1 : Communication addr=1 1 ~ 254 : Communication addr=1~254,,,,, +,,3086,BaudRate,Communication BaudRate,R/W,,,,0,,0: 9600 bps 1: 38400 bps,,,,, +,,3087,Serial NO_ 1,Serial Number 1-2,R/W,,ASCII,,,,For battery,,,,, +,,3088,Serial NO_ 2,Serial Number 3-4,R/W,,ASCII,,,,,,,,, +,,3089,Serial NO_ 3,Serial Number 5-6,R/W,,ASCII,,,,,,,,, +,,3090,Serial NO_ 4,Serial Number 7-8,R/W,,ASCII,,,,,,,,, +,,3091,Serial No_ 5,Serial Number 9-10,R/W,,ASCII,,,,,,,,, +,,3092,Serial No_6,Serial Number 11-12,R/W,,ASCII,,,,,,,,, +,,3093,Serial No_ 7,Serial Number 13-14,R/W,,ASCII,,,,,,,,, +,,3094,Serial No_ 8,Serial Number 15-16,R/W,,ASCII,,,,,,,,, +,,3095,BdcResetCmd,BDC Reset command,R/W,,,,,,0:Invalid data 1:Reset setting parameters 2:Reset correction parameter 3:Clear historical power,,,,, +,,3096,ARKM3 Code,BDCMonitoring software code,R,,ASCII,,,,ZEBA,,,,, +,,3098,DTC,DTC,R,,,,,,,,,,, +,,3099,FW Code,DSP software code,R,,ASCII,,,,,,,,, +,,3101,Processor1 FW Vision,DSP Software Version,R,,ASCII,,,,,,,,, +,,3102,BusVoltRef,Minimum BUS voltage for charging and discharging batteries,R,,,,,,,,,,, +,,3103,ARKM3Ver,BDC monitoring software version,R,,,,,,,,,,, +,,3104,BMS_MCUVer sion,BMS hardware version information,R,1,,,,,,,,,, +,,3105,BMS_FW,BMS software version information,R,1,,,,,,,,,, +,,3106,BMS_Info,BMS ManufacturerName,R,1,,,,,,,,,, +,,3107,BMSCommTy pe,BMSCommType,R,1,,,,,BMSCommunicati on interface type: 0: RS485; 1: CAN;,,,,, +,,3108,Module 4,BDCmodel (4),R/W,&*11,,,,,SxxBxx,,,,, +,,3109,Module 3,BDCmodel (3),R/W,&*11,,,,,DxxTxx,,,,, +,,3110,Module 2,BDCmodel (2),R/W,&*11,,,,,PxxUxx,,,,, +,,3111,Module 1,BDCmodel (1),R/W,&*11,,,,,Mxxxx,,,,, +,,3113,unProtocolVe r,BDCProtocolVer,R,1,,,,,Bit8-bit15 The major version number ranges from 0-256. In principle, it cannot be changed Bit0-bit7 Minor version number [0-256]. If the protocol is changed, you need to update this version No.,,, +,,3114,uwCertificatio nVer,BDC CertificationVer,R,1,,,,,,,,,, +,,3125,Time Month1,Use with Time1-9(us) Add month time,R/W,,,,,,,"bit0~3:month_L; bit4~7: month_H bit8, 0:disable 1:enable Bit9~15:reserve",,,, +,,3126,Time Month2,Use with Time10-18(us) Add month time,R/W,,,,,,,With Time Month1,,,, +,,3127,Time Month3,Use with Time19-27(us) Add month time,R/W,,,,,,,With Time Month1,,,, +,,3128,Time Month4,Use with Time28-36(us) Add month time,R/W,,,,,,,With Time Month1,,,, +,,3129,Time 1_us_ start,time1:[starttime~endtime],R/W,,,,,,"bit0~6:min; bit7~11:hour; bit12~14, 0:loadfirst;",,,,, +,,3130,Time 1_us_ end,,R/W,,,,,,,"1:batfirst; 2:gridfirst; 3: anti-reflux bit15, 0:disable; 1:enable;",,,, +,,3131,Time 2_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3132,Time 2_us_ end,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3133,Time 3_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3134,Time 3_us_ end,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3135,Time 4_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3135,Time 4_us_ end,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3137,Time 5_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3138,Time 5_us_ end,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3139,Time 6_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3140,Time 6_us_ end,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3141,Time 7_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3142,Time 7_us_ end,Same as above,R/W,,,,,,,,,,, +,,3143,Time 8_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3144,Time 8_us_ end,Same as above,R/W,,,,,,,,,,, +,,3145,Time 9_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3146,Time 9_us_ end,Same as above,R/W,,,,,,,,,,, +,,3147,Time 10_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3148,Time 10_us_ end,Same as above,R/W,,,,,,,,,,, +,,3149,Time 11_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3150,Time 11_us_ end,Same as above,R/W,,,,,,,,,,, +,,3151,Time 12_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3152,Time 12_us_ end,Same as above,R/W,,,,,,,,,,, +,,3153,Time 13_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3154,Time 13_us_ end,Same as above,R/W,,,,,,,,,,, +,,3155,Time 14_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3156,Time 14_us_ end,Same as above,R/W,,,,,,,,,,, +,,3157,Time 15_us_ start,Same as above,R/W,,,,,,Same as Time 1 (us),,,,, +,,3158,Time 15_us_ end,Same as above,R/W,,,,,,,,,,, +,,3159,Time 16_us_ start,Same as above,R/W,,,,,,,,,,, +,,3160,Time 16_us_ end,Same as above,R/W,,,,,,,,,,, +,,3201,SpecialDay1,SpecialDay1(month, Day),R/W,,,,,,,"bit0~7:day; bit8~14:month bit15, 0:disable 1: enable",,, +,,3202,SpecialDay1_Time1_Start,Start time,R/W,,,,,,"bit0~6:min; bit7~11:hour; bit12~14, 0:loadfirst; 1:batfirst; 2:gridfirst; 3: anti-reflux bit15, 0: disable; 1: enable;",,,,, +,,3203,SpecialDay1_Time1_End,endtime,R/W,,,,,,bit0~6:min; bit7~11:hour; bit12~15:reserve,,,,, +,,3204,SpecialDay1_ Time2_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3205,SpecialDay1_ Time2_End,,R/W,,,,,,,,,,, +,,3206,SpecialDay1_ Time3_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3207,SpecialDay1_ Time3_End,,R/W,,,,,,,,,,, +,,3208,SpecialDay1_ Time4_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3209,SpecialDay1_ Time4_End,,R/W,,,,,,,,,,, +,,3210,SpecialDay1_ Time5_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3211,SpecialDay1_ Time5_End,,R/W,,,,,,,,,,, +,,3212,SpecialDay1_ Time6_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3213,SpecialDay1_ Time6_End,,R/W,,,,,,,,,,, +,,3214,SpecialDay1_ Time7_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3215,SpecialDay1_ Time7_End,,R/W,,,,,,,,,,, +,,3216,SpecialDay1_ Time8_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3217,SpecialDay1_ Time8_End,,R/W,,,,,,,,,,, +,,3218,SpecialDay1_ Time9_Start,Same as above,R/W,,,,,,Same as SpecialDay1_Time 1,,,,, +,,3219,SpecialDay1_ Time9_End,,R/W,,,,,,,,,,, +,,3220,SpecialDay2,SpecialDay2(month, Day),R/W,,,,,,,"bit0~7:day; bit8~14:month bit15, 0:disable 1:enable",,, +,,3221,SpecialDay2_ Time1_Start,Start time,R/W,,,,,,"bit0~6: min; bit7~11: hour; bit12~14, 0: loadfirst; 1: batfirst; 2: gridfirst; 3: anti-reflux bit15, 0: disable; 1: enable;",,,,, +,,3222,SpecialDay2_ Time1_End,endtime,R/W,,,,,,bit0~6: min; bit7~11: hour; bit12~15:reserve,,,,, +,,3223,SpecialDay2_ Time2_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3224,SpecialDay2_ Time2_End,,R/W,,,,,,,,,,, +,,3225,SpecialDay2_ Time3_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3226,SpecialDay2_ Time3_End,,R/W,,,,,,,,,,, +,,3227,SpecialDay2_ Time4_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3228,SpecialDay2_ Time4_End,,R/W,,,,,,,,,,, +,,3229,SpecialDay2_ Time5_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3230,SpecialDay2_ Time5_End,,R/W,,,,,,,,,,, +,,3231,SpecialDay2_ Time6_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3232,SpecialDay2_ Time6_End,,R/W,,,,,,,,,,, +,,3233,SpecialDay2_ Time7_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3234,SpecialDay2_ Time7_End,,R/W,,,,,,,,,,, +,,3235,SpecialDay2_ Time8_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3236,SpecialDay2_ Time8_End,,R/W,,,,,,,,,,, +,,3237,SpecialDay2_ Time9_Start,Same as above,R/W,,,,,,Same as SpecialDay2_Time 1,,,,, +,,3238,SpecialDay2_ Time9_End,,R/W,,,,,,,,,,, From 1703721b1fd0f3b45f62754d15d350aa246f2c06 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:42:38 -0500 Subject: [PATCH 08/53] ; to , --- .../growatt_2020_v1.24.input_registry_map.csv | 1718 ++++++++--------- 1 file changed, 859 insertions(+), 859 deletions(-) diff --git a/protocols/growatt/growatt_2020_v1.24.input_registry_map.csv b/protocols/growatt/growatt_2020_v1.24.input_registry_map.csv index c15d67a..61e3983 100644 --- a/protocols/growatt/growatt_2020_v1.24.input_registry_map.csv +++ b/protocols/growatt/growatt_2020_v1.24.input_registry_map.csv @@ -1,859 +1,859 @@ -variable name;data type;register;documented name;description;values;unit;note;;Note;;;;; -;;0;Inverter Status;Inverter run state;0:waiting 1:normal 3:fault;;;;;;;;; -PV Watts;;1;Ppv H;Input power (high);;0.1W;;;;;;;; -;;2;Ppv L;Input power (low);;0.1W;;;;;;;; -PV1 Voltage;;3;Vpv1;PV1 voltage;;0.1V;;;;;;;; -PV1 Current;;4;PV1Curr;PV1 input current;;0.1A;;;;;;;; -PV1 Watts;;5;Ppv1 H;PV1 input power(high);;0.1W;;;;;;;; -;;6;Ppv1 L;PV1 input power(low);;0.1W;;;;;;;; -PV2 Voltage;;7;Vpv2;PV2 voltage;;0.1V;;;;;;;; -PV2 Current;;8;PV2Curr;PV2 input current;;0.1A;;;;;;;; -PV2 Watts;;9;Ppv2 H;PV2 input power (high);;0.1W;;;;;;;; -;;10;Ppv2 L;PV2 input power (low);;0.1W;;;;;;;; -PV3 Voltage;;11;Vpv3;PV3 voltage;;0.1V;;;;;;;; -PV3 Current;;12;PV3Curr;PV3 input current;;0.1A;;;;;;;; -PV3 Watts;;13;Ppv3 H;PV3 input power (high);;0.1W;;;;;;;; -;;14;Ppv3 L;PV3 input power (low);;0.1W;;;;;;;; -PV4 Voltage;;15;Vpv4;PV4 voltage;;0.1V;;;;;;;; -PV4 Current;;16;PV4Curr;PV4 input current;;0.1A;;;;;;;; -PV4 Watts;;17;Ppv4 H;PV4 input power (high);;0.1W;;;;;;;; -;;18;Ppv4 L;PV4 input power (low);;0.1W;;;;;;;; -PV5 Voltage;;19;Vpv5;PV5 voltage;;0.1V;;;;;;;; -PV5 Current;;20;PV5Curr;PV5 input current;;0.1A;;;;;;;; -PV5 Watts;;21;Ppv5H;PV5 input power(high);;0.1W;;;;;;;; -;;22;Ppv5 L;PV5 input power(low);;0.1W;;;;;;;; -PV6 Voltage;;23;Vpv6;PV6 voltage;;0.1V;;;;;;;; -PV6 Current;;24;PV6Curr;PV6 input current;;0.1A;;;;;;;; -PV6 Watts;;25;Ppv6 H;PV6 input power (high);;0.1W;;;;;;;; -;;26;Ppv6 L;PV6 input power (low);;0.1W;;;;;;;; -PV7 Voltage;;27;Vpv7;PV7 voltage;;0.1V;;;;;;;; -PV7 Current;;28;PV7Curr;PV7 input current;;0.1A;;;;;;;; -PV7 Watts;;29;Ppv7 H;PV7 input power (high);;0.1W;;;;;;;; -;;30;Ppv7 L;PV7 input power (low);;0.1W;;;;;;;; -PV8 Voltage;;31;Vpv8;PV8 voltage;;0.1V;;;;;;;; -PV8 Current;;32;PV8Curr;PV8 input current;;0.1A;;;;;;;; -PV8 Watts;;33;Ppv8 H;PV8 input power (high);;0.1W;;;;;;;; -;;34;Ppv8 L;PV8 input power (low);;0.1W;;;;;;;; -Output Watts;;35;Pac H;Output power (high);;0.1W;;;;;;;; -;;36;Pac L;Output power (low);;0.1W;;;;;;;; -Grid Hz;;37;Fac;Grid frequency;;0.01Hz;;;;;;;; -Grid Voltage Phase 1;;38;Vac1;Three/single phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 1;;39;Iac1;Three/single phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 1;;40;Pac1 H;Three/single phase grid output watt VA (high);;0.1VA;;;;;;;; -;;41;Pac1 L;Three/single phase grid output watt VA(low);;0.1VA;;;;;;;; -Grid Voltage Phase 2;;42;Vac2;Three phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 2;;43;Iac2;Three phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 2;;44;Pac2 H;Three phase grid output power (high);;0.1VA;;;;;;;; -;;45;Pac2 L;Three phase grid output power (low);;0.1VA;;;;;;;; -Grid Voltage Phase 3;;46;Vac3;Three phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 3;;47;Iac3;Three phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 3;;48;Pac3 H;Three phase grid output power (high);;0.1VA;;;;;;;; -;;49;Pac3 L;Three phase grid output power (low);;0.1VA;;;;;;;; -;;50;Vac_RS;Three phase grid voltage;;0.1V;;;Line voltage;;;;; -;;51;Vac_ST;Three phase grid voltage;;0.1V;;;Line voltage;;;;; -;;52;Vac_TR;Three phase grid voltage;;0.1V;;;Line voltage;;;;; -;;53;Eac today H;Today generate energy (high);;0.1kWH;;;;;;;; -;;54;Eac today L;Today generate energy (low);;0.1kWH;;;;;;;; -;;55;Eac total H;Total generate energy (high);;0.1kWH;;;;;;;; -;;56;Eac total L;Total generate energy (low);;0.1kWH;;;;;;;; -;;57;Time total H;Work time total (high);;0.5s;;;;;;;; -;;58;Time total L;Work time total (low);;0.5s;;;;;;;; -PV1 KWH Today;;59;Epv1_today H;PV1Energy today(high);;0.1kWh;;;;;;;; -;;60;Epv1_today L;PV1Energy today (low);;0.1kWh;;;;;;;; -PV1 KWH Total;;61;Epv1_total H;PV1Energy total(high);;0.1kWh;;;;;;;; -;;62;Epv1_total L;PV1Energy total (low);;0.1kWh;;;;;;;; -PV2 KWH Today;;63;Epv2_today H;PV2Energy today(high);;0.1kWh;;;;;;;; -;;64;Epv2_today L;PV2Energy today (low);;0.1kWh;;;;;;;; -PV2 KWH Total;;65;Epv2_total H;PV2Energy total(high);;0.1kWh;;;;;;;; -;;66;Epv2_total L;PV2Energy total (low);;0.1kWh;;;;;;;; -PV3 KWH Today;;67;Epv3_today H;PV3 Energy today(high);;0.1kWh;;;;;;;; -;;68;Epv3_today L;PV3 Energy today (low);;0.1kWh;;;;;;;; -PV3 KWH Total;;69;Epv3_total H;PV3 Energy total(high);;0.1kWh;;;;;;;; -;;70;Epv3_total L;PV3 Energy total (low);;0.1kWh;;;;;;;; -PV4 KWH Today;;71;Epv4_today H;PV4Energy today(high);;0.1kWh;;;;;;;; -;;72;Epv4_today L;PV4Energy today (low);;0.1kWh;;;;;;;; -PV4 KWH Total;;73;Epv4_total H;PV4Energy total(high);;0.1kWh;;;;;;;; -;;74;Epv4_total L;PV4Energy total (low);;0.1kWh;;;;;;;; -PV5 KWH Today;;75;Epv5_today H;PV5Energy today(high);;0.1kWh;;;;;;;; -;;76;Epv5_today L;PV5Energy today (low);;0.1kWh;;;;;;;; -PV5 KWH Total;;77;Epv5_total H;PV5Energy total(high);;0.1kWh;;;;;;;; -;;78;Epv5_total L;PV5Energy total (low);;0.1kWh;;;;;;;; -PV6 KWH Today;;79;Epv6_today H;PV6Energy today(high);;0.1kWh;;;;;;;; -;;80;Epv6_today L;PV6Energy today (low);;0.1kWh;;;;;;;; -PV6 KWH Total;;81;Epv6_total H;PV6Energy total(high);;0.1kWh;;;;;;;; -;;82;Epv6_total L;PV6Energy total (low);;0.1kWh;;;;;;;; -PV7 KWH Today;;83;Epv7_today H;PV7Energy today(high);;0.1kWh;;;;;;;; -;;84;Epv7_today L;PV7Energy today (low);;0.1kWh;;;;;;;; -PV7 KWH Total;;85;Epv7_total H;PV7 Energy total(high);;0.1kWh;;;;;;;; -;;86;Epv7_total L;PV7Energy total (low);;0.1kWh;;;;;;;; -PV8 KWH Today;;87;Epv8_today H;PV8Energy today(high);;0.1kWh;;;;;;;; -;;88;Epv8_today L;PV8Energy today (low);;0.1kWh;;;;;;;; -PV8 KWH Total;;89;Epv8_total H;PV8Energy total(high);;0.1kWh;;;;;;;; -;;90;Epv8_total L;PV8Energy total (low);;0.1kWh;;;;;;;; -PV KWH Total;;91;Epv_total H;PV Energy total(high);;0.1kWh;;;;;;;; -;;92;Epv_total L;PV Energy total (low);;0.1kWh;;;;;;;; -;;93;Temp1;Inverter temperature;;0.1C;;;;;;;; -;;94;Temp2;The inside IPM in inverter Temperature;;0.1C;;;;;;;; -;;95;Temp3;Boost temperature;;0.1C;;;;;;;; -;;96;Temp4;;;;;;reserved;;;;; -;;97;uwBatVolt_DSP;BatVolt_DSP;;0.1V;;;BatVolt(DSP);;;;; -;;98;P Bus Voltage;P Bus inside Voltage;;0.1V;;;;;;;; -;;99;N Bus Voltage;N Bus inside Voltage;;0.1V;;;;;;;; -Inverter Power Factor;;100;IPF;Inverter output PF now;0-20000;;;;;;;;; -;;101;RealOPPercent;Real Output power Percent;;1.00%;;;;;;;; -;;102;OPFullwatt H;Output Maxpower Limited high;;;;;;;;;; -;;103;OPFullwatt L;Output Maxpower Limited low;;0.1W;;;;;;;; -;;104;DeratingMode;DeratingMode;0:no derate; 1:PV; 2:*; 9:*OverBack ByTime; 4:Fac; 9:*OverBack ByTime; 9:*OverBack ByTime; 9:*OverBack ByTime; 9:*OverBack ByTime; 9:*OverBack ByTime -;;105;Fault Maincode;Inverter fault maincode;;;;;;;;;; -;;106;Fault Bitcode H ;;;;;;;;;;; -;;107;Fault Bitcode L;;;Inverter fault subcode;;;;;;;; -;;108;RemoteCtrlEn;/;0.Load First 1.BatFirst 2.Grid;/;;;StoragePow er (SPA);;;;; -;;109;RemoteCtrlPower;;;/;/;;StoragePow er (SPA);;;;; -;;110;Warning bit H;Warning bit H;;;;;;;;;; -;;111;Warn Subcode;;;Inverter warn subcode;;;;;;;; -;;112;Warn Maincode;Inverter warn maincode;;;;;;;;;; -;;113;real Power Percent;real Power Percent;0-100;%;;;MAX;;;;; -;;114;inv start delay time;inv start delay time;;;;;MAX;;;;; -;;115;bINVAllFaultCode;bINVAllFaultCode;;;;;MAX;;;;; -;;116;AC charge Power_H;Grid power to local load;;0.1kwh;;;Storage Power;;;;; -;;117;AC charge Power_L;Grid power to local load;;0.1kwh;;;Storage Power;;;;; -;;118;Priority;0:Load First 1:Battery First 2:Grid First;;;;;Storage;;;;; -;;119;Battery Type;0:Lead-acid 1:Lithium battery;;;;;Storage Power;;;;; -;;120;AutoProofreadCMD;Aging mode Command Auto-calibration;;;;;Storage Power;;;;; -;;125;PID PV1Plus Voltage;PID PV1PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;126;PID PV1Plus Current;PID PV1PE Curr;-10~10mA;0.1mA;;;;;;;; -;;127;PID PV2Plus Voltage;PID PV2PE Volt/ Flyspan voltage (MAX HV) Flyspan;0~1000V;0.1V;;;;;;;; -;;128;PID PV2Plus Current;PID PV2PE Curr;-10~10mA;0.1mA;;;;;;;; -;;129;PID PV3Plus Voltage;PID PV3PE Volt/ Flyspan voltage (MAX HV) ;0~1000V;0.1V;;;;;;;; -;;130;PID PV3Plus Current;PID PV3PE Curr;-10~10mA;0.1mA;;;;;;;; -;;131;PID PV4Plus Voltage;PID PV4PE Volt/ Flyspan voltage (MAX HV) ;0~1000V;0.1V;;;;;;;; -;;132;PID PV4Plus Current;PID PV4PE Curr;-10~10mA;0.1mA;;;;;;;; -;;133;PID PV5Plus Voltage;PID PV5PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;134;PID PV5Plus Current;PID PV5PE Curr;-10~10mA;0.1mA;;;;;;;; -;;135;PID PV6Plus Voltage;PID PV6PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;136;PID PV6Plus Current;PID PV6PE Curr;-10~10mA;0.1mA;;;;;;;; -;;137;PID PV7Plus Voltage;PID PV7PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;138;PID PV7Plus Current;PID PV7PE Curr;-10~10mA;0.1mA;;;;;;;; -;;139;PID PV8Plus Voltage;PID PV8PE Volt/ Flyspan voltage (MAX HV) ;0~1000V;0.1V;;;;;;;; -;;140;PID PV8Plus Current;PID PV8PE Curr;-10~10mA;0.1mA;;;;;;;; -;;141;PID Status;Bit0~7:PID Working Status 1:Wait Status 2:Normal Status 3:Fault Status Bit8~15:Reversed;0~3;;;;;;;;; -;;142;PV String1;PV String1 voltage;;0.1V;;;;;;;; -;;143;PV Curr_String1;PV String1 current;-15~15A;0.1A;;;;;;;; -;;144;PV_String2;PV String2 voltage;;0.1V;;;;;;;; -;;145;PV Curr_String2;PV String2 current;-15~15A;0.1A;;;;;;;; -;;146;PV_String3;PV String3 voltage;;0.1V;;;;;;;; -;;147;PV Curr_String3;PV String3 current;-15~15A;0.1A;;;;;;;; -;;148;PV_String4;PV String4 voltage;;0.1V;;;;;;;; -;;149;PV Curr_String4;PV String4 current;-15~15A;0.1A;;;;;;;; -;;150;PV_String5;PV String5 voltage;;0.1V;;;;;;;; -;;151;PV Curr_String5;PV String5 current;-15~15A;0.1A;;;;;;;; -;;152;PV_String6;PV String6 voltage;;0.1V;;;;;;;; -;;153;PV Curr_String6;PV String6 current;-15~15A;0.1A;;;;;;;; -;;154;PV_String7;PV String7 voltage;;0.1V;;;;;;;; -;;155;PV Curr_String7;PV String7 current;-15~15A;0.1A;;;;;;;; -;;156;PV_String8;PV String8 voltage;;0.1V;;;;;;;; -;;157;PV Curr_String8;PV String8 current;-15A~15A;0.1A;;;;;;;; -;;158;PV_String9;PV String9 voltage;;0.1V;;;;;;;; -;;159;PV Curr_String9;PV String9 current;-15A~15A;0.1A;;;;;;;; -;;160;PV_String10;PV String10 voltage;;0.1V;;;;;;;; -;;161;PV Curr_String10;PV String10 current;-15~15A;0.1A;;;;;;;; -;;162;PV_String11;PV String11 voltage;;0.1V;;;;;;;; -;;163;PV Curr_String11;PV String11 current;-15~15A;0.1A;;;;;;;; -;;164;PV_String12;PV String12 voltage;;0.1V;;;;;;;; -;;165;PV Curr_String12;PV String12 current;-15~15A;0.1A;;;;;;;; -;;166;PV_String13;PV String13 voltage;;0.1V;;;;;;;; -;;167;PV Curr_String13;PV String13 current;-15A~15A;0.1A;;;;;;;; -;;168;PV_String14;PV String14 voltage;;0.1V;;;;;;;; -;;169;PV Curr_String14;PV String14 current;-15~15A;0.1A;;;;;;;; -;;170;PV_String15;PV String15 voltage;;0.1V;;;;;;;; -;;171;PV Curr_String15;PV String15 current;-15~15A;0.1A;;;;;;;; -;;172;PV_String16;PV String16 voltage;;0.1V;;;;;;;; -;;173;PV Curr_String16;PV String16 current;-15~15A;0.1A;;;;;;;; -;;174;StrUnmatch;Bit0~15: String1~16 unmatch;;;;;suggestive;;;;; -;;175;StrCurrentUnblance;Bit0~15: String1~16 current unblance;;;;;suggestive;;;;; -;;176;StrDisconnect;Bit0~15: String1~16 disconnect;;;;;suggestive;;;;; -;;177;PIDFaultCode;Bit0:Output over voltage Bit1: ISO fault Bit2: BUS voltage abnormal Bit3~15:reserved;;;;;;;;;; -;;178;String Prompt;String Prompt Bit0:String Unmatch Bit1:StrDisconnect Bit2:StrCurrentUnblance Bit3~15:reserved;;;;;;;;;; -;;179;PV Warning Value;PV Warning Value;;;;;;;;;; -;;180;DSP075 Warning Value;DSP075 Warning Value;;;;;;;;;; -;;181;DSP075 Fault Value;DSP075 Fault Value;;;;;;;;;; -;;182;DSP067 Debug Data1;DSP067 Debug Data1;;;;;;;;;; -;;183;DSP067 Debug Data2;DSP067 Debug Data2;;;;;;;;;; -;;184;DSP067 Debug Data3;DSP067 Debug Data3;;;;;;;;;; -;;185;DSP067 Debug Data4;DSP067 Debug Data4;;;;;;;;;; -;;186;DSP067 Debug Data5;DSP067 Debug Data5;;;;;;;;;; -;;187;DSP067 Debug Data6;DSP067 Debug Data6;;;;;;;;;; -;;188;DSP067 Debug Data7;DSP067 Debug Data7;;;;;;;;;; -;;189;DSP067 Debug Data8;DSP067 Debug Data8;;;;;;;;;; -;;190;DSP075 Debug Data1;DSP075 Debug Data1;;;;;;;;;; -;;191;DSP075 Debug Data2;DSP075 Debug Data2;;;;;;;;;; -;;192;DSP075 Debug Data3;DSP075 Debug Data3;;;;;;;;;; -;;193;DSP075 Debug Data4;DSP075 Debug Data4;;;;;;;;;; -;;194;DSP075 Debug Data55;DSP075 Debug Data5;;;;;;;;;; -;;195;DSP075 Debug Data6;DSP075 Debug Data6;;;;;;;;;; -;;196;DSP075 Debug Data7;DSP075 Debug Data7;;;;;;;;;; -;;197;DSP075 Debug Data8;DSP075 Debug Data8;;;;;;;;;; -;;198;bUSBAgingTestOk Flag;USBAgingTestOkFlag;0-1;;;;;;;;; -;;199;bFlashEraseAging OkFlag;FlashEraseAgingOkFlag;0-1;;;;;;;;; -;;200;PVISO;PVISOValue;;K?;;;;;;;; -;;201;R_DCI;R DCI Curr;;0.1mA;;;;;;;; -;;202;S_DCI;S DCI Curr;;0.1mA;;;;;;;; -;;203;T_DCI;T DCI Curr;;0.1mA;;;;;;;; -;;204;PID_Bus;PIDBusVolt;;0.1V;;;;;;;; -;;205;GFCI;GFCI Curr;;mA;;;;;;;; -;;206;SVG_APF StatusPlusSVGAPFEqualRatio;SVG/APF StatusPlusSVGAPFEqualRatio;High 8 bit: SVGAPFEqua lRatio Low 8 bit: SVG/APF Status 0:None 1:SVG Run 2:APF Run 3:SVG/APF Run;;;;;;;;; -;;207;CT_I_R;R phase load side current for SVG;;0.1A;;;;;;;; -;;208;CT_I_S;S phase load side current for SVG;;0.1A;;;;;;;; -;;209;CT_I_T;T phase load side current for SVG;;0.1A;;;;;;;; -;;210;CT_Q_R H;R phase load side output reactive power for SVG(High);;0.1Var;;;;;;;; -;;211;CT_Q_R L;R phase load side output reactive power for SVG(low);;0.1Var;;;;;;;; -;;212;CT_Q_S H;S phase load side output reactive power for SVG(High);;0.1Var;;;;;;;; -;;213;CT_Q_S L;S phase load side output reactive power for SVG(low);;0.1Var;;;;;;;; -;;214;CT_Q_T H;T phase load side output reactive power for SVG(High);;0.1Var;;;;;;;; -;;215;CT_Q_T L;T phase load side output reactive power for SVG(low);;0.1Var;;;;;;;; -;;216;CT HAR_I_R;R phase load side harmonic;;0.1A;;;;;;;; -;;217;CT HAR_I_S;S phase load side harmonic;;0.1A;;;;;;;; -;;218;CT HAR_I_T;T phase load side harmonic;;0.1A;;;;;;;; -;;219;COMP_Q_R H;R phase compensate reactive power for SVG(High);;0.1Var;;;;;;;; -;;220;COMP_Q_R L;R phase compensate reactive power for SVG(low);;0.1Var;;;;;;;; -;;221;COMP_Q_S H;S phase compensate reactive power for SVG(High);;0.1Var;;;;;;;; -;;222;COMP_Q_S L;S phase compensate reactive power for SVG(low);;0.1Var;;;;;;;; -;;223;COMP_Q_T H;T phase compensate reactive power for SVG(High);;0.1Var;;;;;;;; -;;224;COMP_Q_T L;T phase compensate reactive power for SVG(low);;0.1Var;;;;;;;; -;;225;COMP HAR_I_R;R phase compensate harmonic for SVG;;0.1A;;;;;;;; -;;226;COMP HAR_I_S;S phase compensate harmonic for SVG;;0.1A;;;;;;;; -;;227;COMP HAR_I_T;T phase compensate harmonic for SVG;;0.1A;;;;;;;; -;;228;bRS232AgingTest OkFlag;RS232AgingTestOkFlag;0-1;;;;;;;;; -;;229;bFanFaultBit;;Bit0: Fan 1 fault bit Bit1: Fan 2 fault bit Bit2: Fan 3 fault bit Bit3: Fan 4 fault bit Bit4-7: Reserved;;;;;;;;; -;;230;Sac H;Output apparent power H;;0.1W;;;;;;;; -;;231;Sac L;Output apparent power L;;0.1W;;;;;;;; -;;232;ReActPowerH;Real Output Reactive Power H;Int32;0.1W;;;;;;;; -;;233;ReActPowerL;Real Output Reactive Power L;;;;;;;;;; -;;234;ReActPowerMaxH;Nominal Output Reactive Power H;;0.1var;;;;;;;; -;;235;ReActPowerMaxL;Nominal Output Reactive Power L;;;;;;;;;; -;;236;ReActPower_Total H;Reactive power generation;;0.1kwh;;;;;;;; -;;237;ReActPower_Total L;Reactive power generation;;;;;;;;;; -;;238;bAfciStatus;;0:Waiting 1:Self-check state 2:Detect pull arc state 3:Fault 4:Update;;;;;;;;; -;;239;uwPresentFFTValue_CHANNEL_A_;PresentFFTValue [CHANNEL_A];;;;;;;;;; -;;240;uwPresentFFTValue_CHANNEL_B_;PresentFFTValue [CHANNEL_B];;;;;;;;;; -;;241;DSP067 Debug Data1;DSP067 Debug Data1;;;;;;;;;; -;;242;DSP067 Debug Data2;DSP067 Debug Data2;;;;;;;;;; -;;243;DSP067 Debug;DSP067 Debug Data3;;;;;;;;;; -;;244;DSP067 Debug Data4;DSP067 Debug Data4;;;;;;;;;; -;;245;DSP067 Debug Data5;DSP067 Debug Data5;;;;;;;;;; -;;246;DSP067 Debug Data6;DSP067 Debug Data6;;;;;;;;;; -;;247;DSP067 Debug Data7;DSP067 Debug Data7;;;;;;;;;; -;;248;DSP067 Debug Data8;DSP067 Debug Data8;;;;;;;;;; -PV9 Voltage;;875;Vpv9;PV9 voltage;;0.1V;;;;;;;; -PV9 Current;;876;PV9Curr;PV9 Input current;;0.1A;;;;;;;; -PV9 Watts;;877;Ppv9 H;PV9 input power (High);;0.1W;;;;;;;; -;;878;Ppv9 L;PV9 input power (Low);;0.1W;;;;;;;; -PV10 Voltage;;879;Vpv10;PV10 voltage;;0.1V;;;;;;;; -PV10 Current;;880;PV10Curr;PV10 Input current;;0.1A;;;;;;;; -PV10 Watts;;881;Ppv10 H;PV10 input power (High);;0.1W;;;;;;;; -;;882;Ppv10 L;PV10 input power (Low);;0.1W;;;;;;;; -PV11 Voltage;;883;Vpv11;PV11 voltage;;0.1V;;;;;;;; -PV11 Current;;884;PV11Curr;PV11 Input current;;0.1A;;;;;;;; -PV11 Watts;;885;Ppv11 H;PV11 input power (High);;0.1W;;;;;;;; -;;886;Ppv11 L;PV11 input power (Low);;0.1W;;;;;;;; -PV12 Voltage;;887;Vpv12;PV12 voltage;;0.1V;;;;;;;; -PV12 Current;;888;PV12Curr;PV12 Input current;;0.1A;;;;;;;; -PV12 Watts;;889;Ppv12 H;PV12 input power (High);;0.1W;;;;;;;; -;;890;Ppv12 L;PV12 input power (Low);;0.1W;;;;;;;; -PV13 Voltage;;891;Vpv13;PV13 voltage;;0.1V;;;;;;;; -PV13 Current;;892;PV13Curr;PV13 Input current;;0.1A;;;;;;;; -PV13 Watts;;893;Ppv13H;PV13 input power (High);;0.1W;;;;;;;; -;;894;Ppv13 L;PV13 input power (Low);;0.1W;;;;;;;; -PV14 Voltage;;895;Vpv14;PV14 voltage;;0.1V;;;;;;;; -PV14 Current;;896;PV14Curr;PV14 Input current;;0.1A;;;;;;;; -PV14 Watts;;897;Ppv14 H;PV14 input power (High);;0.1W;;;;;;;; -;;898;Ppv14 L;PV14 input power (Low);;0.1W;;;;;;;; -PV15 Voltage;;899;Vpv15;PV15 voltage;;0.1V;;;;;;;; -PV15 Current;;900;PV15Curr;PV15 Input current;;0.1A;;;;;;;; -PV15 Watts;;901;Ppv15 H;PV15 input power (High);;0.1W;;;;;;;; -;;902;Ppv15 L;PV15 input power (Low);;0.1W;;;;;;;; -PV16 Voltage;;903;Vpv16;PV16 voltage;;0.1V;;;;;;;; -PV16 Current;;904;PV16Curr;PV16 Input current;;0.1A;;;;;;;; -PV16 Watts;;905;Ppv16 H;PV16 input power (High);;0.1W;;;;;;;; -;;906;Ppv16 L;PV16 input power (Low);;0.1W;;;;;;;; -PV9 KWH Today;;907;Epv9_today H;PV9 energy today (High);;0.1kWh;;;;;;;; -;;908;Epv9_today L;PV9 energy today (Low);;0.1kWh;;;;;;;; -PV9 KWH Total;;909;Epv9_total H;PV9 energy total (High);;0.1kWh;;;;;;;; -;;910;Epv9_total L;PV9 energy total (Low);;0.1kWh;;;;;;;; -PV10 KWH Today;;911;Epv10_today H;PV10 energy today (High);;0.1kWh;;;;;;;; -;;912;Epv10_today L;PV10 energy today (Low);;0.1kWh;;;;;;;; -PV10 KWH Total;;913;Epv10_total H;PV10 energy total (High);;0.1kWh;;;;;;;; -;;914;Epv10_total L;PV10 energy total (Low);;0.1kWh;;;;;;;; -PV11 KWH Today;;915;Epv11_today H;PV11 energy today (High);;0.1kWh;;;;;;;; -;;916;Epv11_today L;PV11 energy today (Low);;0.1kWh;;;;;;;; -PV11 KWH Total;;917;Epv11_total H;PV11 energy total (High);;0.1kWh;;;;;;;; -;;918;Epv11_total L;PV11 energy total (Low);;0.1kWh;;;;;;;; -PV12 KWH Today;;919;Epv12_today H;PV12 energy today (High);;0.1kWh;;;;;;;; -;;920;Epv12_today L;PV12 energy today (Low);;0.1kWh;;;;;;;; -PV12 KWH Total;;921;Epv12_total H;PV12 energy total (High);;0.1kWh;;;;;;;; -;;922;Epv12_total L;PV12 energy total (Low);;0.1kWh;;;;;;;; -PV13 KWH Today;;923;Epv13_today H;PV13 energy today (High);;0.1kWh;;;;;;;; -;;924;Epv13_today L;PV13 energy today (Low);;0.1kWh;;;;;;;; -PV13 KWH Total;;925;Epv13_total H;PV13 energy total (High);;0.1kWh;;;;;;;; -;;926;Epv13_total L;PV13 energy total (Low);;0.1kWh;;;;;;;; -PV14 KWH Today;;927;Epv14_today H;PV14 energy today (High);;0.1kWh;;;;;;;; -;;928;Epv14_today L;PV14 energy today (Low);;0.1kWh;;;;;;;; -PV14 KWH Total;;929;Epv14_total H;PV14 energy total (High);;0.1kWh;;;;;;;; -;;930;Epv14_total L;PV14 energy total (Low);;0.1kWh;;;;;;;; -PV15 KWH Today;;931;Epv15_today H;PV15 energy today (High);;0.1kWh;;;;;;;; -;;932;Epv15_today L;PV15 energy today (Low);;0.1kWh;;;;;;;; -PV15 KWH Total;;933;Epv15_total H;PV15 energy total (High);;0.1kWh;;;;;;;; -;;934;Epv15_total L;PV15 energy total (Low);;0.1kWh;;;;;;;; -PV16 KWH Today;;935;Epv16_today H;PV16 energy today (High);;0.1kWh;;;;;;;; -;;936;Epv16_today L;PV16 energy today (Low);;0.1kWh;;;;;;;; -PV16 KWH Total;;937;Epv16_total H;PV16 energy total (High);;0.1kWh;;;;;;;; -;;938;Epv16_total L;PV16 energy total (Low);;0.1kWh;;;;;;;; -;;939;PID PV9Plus Voltage;PID PV9PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;940;PID PV9Plus Current;PID PV9PE Current;-10~10mA;0.1mA;;;;;;;; -;;941;PID PV10Plus Voltage;PID PV10PE/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;942;PID PV10Plus Current;PID PV10PE Current;-10~10mA;0.1mA;;;;;;;; -;;943;PID PV11Plus Voltage;PID PV11PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;944;PID PV11Plus Current;PID PV11PE Current;-10~10mA;0.1mA;;;;;;;; -;;945;PID PV12Plus Voltage;PID PV12PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;946;PID PV12Plus Current;PID PV12PE Current;-10~10mA;0.1mA;;;;;;;; -;;947;PID PV13Plus Voltage;PID PV13PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;948;PID PV13Plus Current;PID PV13PE Current;-10~10mA;0.1mA;;;;;;;; -;;949;PID PV14Plus Voltage;PID PV14PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;950;PID PV14Plus Current;PID PV14PE Current;-10~10mA;0.1mA;;;;;;;; -;;951;PID PV15Plus Voltage;PID PV15PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;952;PID PV15Plus Current;PID PV15PE Current;-10~10mA;0.1mA;;;;;;;; -;;953;PID PV16Plus Voltage;PID PV16PE Volt/ Flyspan voltage (MAX HV);0~1000V;0.1V;;;;;;;; -;;954;PID PV16Plus Current;PID PV16PE Current;-10~10mA;0.1mA;;;;;;;; -;;955;PV_String17;PV String 17 voltage;;0.1V;;;;;;;; -;;956;PV Curr_String17;PV String 17 Current;-15~15A;0.1A;;;;;;;; -;;957;PV_String18;PV String 18 voltage;;0.1V;;;;;;;; -;;958;PV Curr_String18;PV String 18 Current;-15~15A;0.1A;;;;;;;; -;;959;PV_String19;PV String 19 voltage;;0.1V;;;;;;;; -;;960;PV Curr_String19;PV String 19 Current;-15~15A;0.1A;;;;;;;; -;;961;PV_String20;PV String 20 voltage;;0.1V;;;;;;;; -;;962;PV Curr_String20;PV String 20 Current;-15~15A;0.1A;;;;;;;; -;;963;PV_String21;PV String 21 voltage;;0.1V;;;;;;;; -;;964;PV Curr_String21;PV String 21 Current;-15~15A;0.1A;;;;;;;; -;;965;PV_String22;PV String22 voltage;;0.1V;;;;;;;; -;;966;PV Curr_String22;PV String 22 Current;-15~15A;0.1A;;;;;;;; -;;967;PV_String23;PV String 23 voltage;;0.1V;;;;;;;; -;;968;PV Curr_String23;PV String 23 Current;-15~15A;0.1A;;;;;;;; -;;969;PV_String24;PV String 24 voltage;;0.1V;;;;;;;; -;;970;PV Curr_String24;PV String 24 Current;-15A~15A;0.1A;;;;;;;; -;;971;PV_String25;PV String 25 voltage;;0.1V;;;;;;;; -;;972;PV Curr_String25;PV String 25 Current;-15A~15A;0.1A;;;;;;;; -;;973;PV_String26;PV String 26 voltage;;0.1V;;;;;;;; -;;974;PV Curr_String26;PV String 26 Current;-15~15A;0.1A;;;;;;;; -;;975;PV_String27;PV String 27 voltage;;0.1V;;;;;;;; -;;976;PV Curr_String27;PV String 27 Current;-15~15A;0.1A;;;;;;;; -;;977;PV_String28;PV String 28 voltage;;0.1V;;;;;;;; -;;978;PV Curr_String28;PV String 28 Current;-15~15A;0.1A;;;;;;;; -;;979;PV_String29;PV String 29 voltage;;0.1V;;;;;;;; -;;980;PV Curr_String29;PV String 29 Current;-15A~15A;0.1A;;;;;;;; -;;981;PV_String30;PV String 30 voltage;;0.1V;;;;;;;; -;;982;PV Curr_String30;PV String 30 Current;-15~15A;0.1A;;;;;;;; -;;983;PV_String31;PV String 31 voltage;;0.1V;;;;;;;; -;;984;PV Curr_String31;PV String 31 Current;-15~15A;0.1A;;;;;;;; -;;985;PV_String32;PV String 32 voltage;;0.1V;;;;;;;; -;;986;PV Curr_String32;PV String 32 Current;-15~15A;0.1A;;;;;;;; -;;987;StrUnmatch2;Bit0~15: String 17~32 unmatch;;;;;;;;;; -;;988;StrCurrentUnblance2;Bit0~15:String 17~32 current unblance;;;;;;;;;; -;;989;StrDisconnect2;Bit0~15: String 17~32 disconnect;;;;;;;;;; -;;990;PV Warning Value;PV Warning Value (PV9-PV16) Contains PV9~16 abnormal ; ? Boost9~16 Drive anomalies;;;;;;;;; -;;991;StrWaringvalue1;string1~string16 abnormal;;;;;;;;;; -;;992;StrWaringvalue2;string17~string32 abnormal;;;;;;;;;; -;;999;SystemCmd;M3 to DSP system command;;;;;system command;;;;; -;;1000;uwSysWorkMode;System work mode;0x00:waiting module 0x01: Self-test mode optional 0x02 : Reserved 0x03:SysFault module 0x04: Flash module 0x05 0x06 0x07 0x08;;;; 0x03:fault module 0x04:flash;;;;; -;;1001;Systemfault word0;System fault word0;;;;;;;;;; -;;1002;Systemfault word1;System fault word1;;;;;;;;;; -;;1003;Systemfault word2;System fault word2;;;;;;;;;; -;;1004;Systemfault word3;System fault word3;;;;;;;;;; -;;1005;Systemfault word4;System fault word4;;;;;;;;;; -;;1006;Systemfault word5;System fault word5;;;;;;;;;; -;;1007;Systemfault word6;System fault word6;;;;;;;;;; -;;1008;Systemfault word7;System fault word7;;;;;;;;;; -;;1009;Pdischarge1 H;Discharge power(high);;0.1W;;;;;;;; -;;1010;Pdischarge1 L;Discharge power (low);;0.1W;;;;;;;; -;;1011;Pcharge1 H;Charge power(high);;0.1W;;;;;;;; -;;1012;Pcharge1 L;Charge power (low);;0.1W;;;;;;;; -;;1013;Vbat;Battery voltage;;0.1V;;;;;;;; -;;1014;SOC;State of charge Capacity;0-100;1.00%;lith/leadacid;;;;;;; -;;1015;Pactouser R H;AC power to user H;;0.1w;;;;;;;; -;;1016;Pactouser R L;AC power to user L;;0.1w;;;;;;;; -;;1017;Pactouser S H;Pactouser S H;;0.1w;;;;;;;; -;;1018;Pactouser S L;Pactouser S L;;0.1w;;;;;;;; -;;1019;Pactouser T H;Pactouser T H;;0.1w;;;;;;;; -;;1020;Pactouser T L;Pactouser T L;;0.1w;;;;;;;; -;;1021;PactouserTotal H;AC power to user total H;;0.1w;;;;;;;; -;;1022;PactouserTotal L;AC power to user total L;;0.1w;;;;;;;; -;;1023;Pac to grid R H;AC power to grid H;;0.1w;Ac;;output;;;;; -;;1024;Pac to grid R L;AC power to grid L;;0.1w;;;;;;;; -;;1025;Pactogrid S H;;;0.1w;;;;;;;; -;;1026;Pactogrid S L;;;0.1w;;;;;;;; -;;1027;Pactogrid T H;;;0.1w;;;;;;;; -;;1028;Pactogrid T L;;;0.1w;;;;;;;; -;;1029;Pactogrid total H;AC power to grid total H;;0.1w;;;;;;;; -;;1030;Pactogrid total L;AC power to grid total L;;0.1w;;;;;;;; -;;1031;PLocalLoad R H;INV power to local load H;;0.1w;;;;;;;; -;;1032;PLocalLoad R L;INV power to local load L;;0.1w;;;;;;;; -;;1033;PLocalLoad S H;;;0.1w;;;;;;;; -;;1034;PLocalLoad S L;;;0.1w;;;;;;;; -;;1035;PLocalLoadT H;;;0.1w;;;;;;;; -;;1036;PLocalLoadT L;;;0.1w;;;;;;;; -;;1037;PLocalLoad total H;INV power to local load total H;;0.1w;;;;;;;; -;;1038;PLocalLoad total L;INV power to local load total L;;0.1w;;;;;;;; -;;1039;IPM Temperature;REC Temperature;;0.1?;No use;;;;;;; -;;1040;Battery Temperature;Battery Temperature;;0.1?;Lead acid/lithium battery temp;;;;;;; -;;1041;SP DSP Status;SP state;;;CHG/DisCHG;;;;;;; -;;1042;SP Bus Volt;SP BUS2 Volt;;0.1V;;;;;;;; -;;1044;Etouser_today H;Energy to user today high;;0.1kWh;;;;;;;; -;;1045;Etouser_today L;Energy to user today low;;0.1kWh;;;;;;;; -;;1046;Etouser_total H;Energy to user total high;;0.1kWh;;;;;;;; -;;1047;Etouser_total L;Energy to user total high;;0.1kWh;;;;;;;; -;;1048;Etogrid_today H;Energy to grid today high;;0.1kWh;;;;;;;; -;;1049;Etogrid_today L;Energy to grid today low;;0.1kWh;;;;;;;; -;;1050;Etogrid_total H;Energy to grid total high;;0.1kWh;;;;;;;; -;;1051;Etogrid_ total L;Energy to grid total high;;0.1kWh;;;;;;;; -;;1052;Edischarge1_today H;Discharge energy1 today;;0.1kWh;;;;;;;; -;;1053;Edischarge1_today L;Discharge energy1 today;;0.1kWh;;;;;;;; -;;1054;Edischarge1_total H;Total discharge energy1 (high);;0.1kWh;;;;;;;; -;;1055;Edischarge1_total L;Total discharge energy1 (low);;0.1kWh;;;;;;;; -;;1056;Echarge1_today H ;Charge1 energy today;;0.1kWh;;;;;;;; -;;1057;Echarge1_today L;Charge1 energy today;;0.1kWh;;;;;;;; -;;1058;Echarge1_total H;Charge1 energy total;;0.1kWh;;;;;;;; -;;1059;Echarge1_total L;Charge1 energy total;;0.1kWh;;;;;;;; -;;1060;ElocalLoad_Today H;Local load energy today;;0.1kWh;;;;;;;; -;;1061;ElocalLoad_Today L;Local load energy today;;0.1kWh;;;;;;;; -;;1062;ElocalLoad_Total H;Local load energy total;;0.1kWh;;;;;;;; -;;1063;ElocalLoad_Total L;Local load energy total;;0.1kWh;;;;;;;; -;;1064;dwExportLimitApparentPower ;ExportLimitApparentPower H;;0.1kWh;ApparentPower;;;;;;; -;;1065;dwExportLimitApparentPower ;ExportLimitApparentPower L;;0.1kWh;ApparentPower;;;;;;; -;;1067;EPS Fac;UPSfrequency;5000/6000;0.01Hz;;;;;;;; -;;1068;EPS Vac1 ;UPS phase R output voltage;2300;0.1V;;;;;;;; -;;1069;EPS Iac1 ;UPS phase R output current;;0.1A;;;;;;;; -;;1070;EPS Pac1 H ;UPS phase R output power (H);;0.1VA;;;;;;;; -;;1071;EPS Pac1 L ;UPS phase R output power (L);;0.1VA;;;;;;;; -;;1072;EPS Vac2 ;UPS phase S output voltage;;0.1V;;;;;;;; -;;1073;EPS Iac2 ;UPS phase S output current;;0.1A;No use;;;;;;; -;;1074;EPS Pac2 H ;UPS phase S output power (H);;0.1VA;;;;;;;; -;;1075;EPS Pac2 L ;UPS phase S output power (L);;0.1VA;;;;;;;; -;;1076;EPS Vac3 ;UPS phase T output voltage;;0.1V;;;;;;;; -;;1077;EPS Iac3 ;UPS phase T output current;;0.1A;No use;;;;;;; -;;1078;EPS Pac3 H ;UPS phase T output power (H);;0.1VA;;;;;;;; -;;1079;EPS Pac3 L ;UPS phase T output power (L);;0.1VA;;;;;;;; -;;1080;Loadpercent ;Load percent of UPS ouput;0-100;1.00%;;;;;;;; -;;1081;PF ;Power factor;0-2;0.1;Primary ValuePlus1;;;;;;; -;;1082;BMS_StatusOld;StatusOld from BMS;"Detail information, refer to document:GrowattxxSxx P ESS Protocol;";;;;;;;;; -;;1083;BMS_Status;Status from BMS;;;W/R;;;;;;; -;;1084;BMS_ErrorOld;Error info Old from BMS;;;;;;;;;; -;;1085;BMS_Error;Errorinfomation from BMS;;;;;;;;;; -;;1086;BMS_SOC;SOC from BMS;;;R SPH6K;;;;;;; -;;1087;BMS_BatteryVolt;Battery voltage from BMS;;;R SPH6K;;;;;;; -;;1088;BMS_BatteryCurr;Battery current from BMS;;;;;;;;;; -;;1089;BMS_BatteryTemp;Battery temperature from BMS;;;;;;;;;; -;;1090;BMS_MaxCurr;;;;;;;;;;; -;;1091;BMS_GaugeRM;Gauge RM from BMS;;;;;;;;;; -;;1092;BMS_GaugeFCC;Gauge FCC from BMS;;;;;;;;;; -;;1093;BMS_FW;;;;;;;;;;; -;;1094;BMS_DeltaVolt;Delta V from BMS;;;;;;;;;; -;;1095;BMS_CycleCnt;Cycle Count from BMS;;;;;;;;;; -;;1096;BMS_SOH;SOH from BMS;;;;;;;;;; -;;1097;BMS_ConstantVolt;CV voltage from BMS;;;;;;;;;; -;;1098;BMS_WarnInfoOld;Warning info old from BMS;;;;;;;;;; -;;1099;BMS_WarnInfo;Warning info from BMS;;;;;;;;;; -;;1100;BMS_GaugeICCurr;Gauge IC current from BMS;;;;;;;;;; -;;1101;BMS_MCUVersion;MCU Software version from BMS;;;;;;;;;; -;;1102;BMS_GaugeVersion;Gauge Version from BMS;;;;;;;;;; -;;1103;BMS_wGaugeFR Version_L;Gauge FR Version L16 from BMS;;;;;;;;;; -;;1104;BMS_wGaugeFR Version_H;Gauge FR Version H16 from BMS;;;;;;;;;; -;;1105;BMS_BMSInfo;BMSInformation from BMS;;;;;;;;;; -;;1106;BMS_PackInfo;Pack Information from BMS;;;;;;;;;; -;;1107;BMS_UsingCap;Using Cap from BMS;;;;;;;;;; -;;1108;uwMaxCellVolt;Maximum single battery voltage;;0.001V;;;;;;;; -;;1109;uwMinCellVolt;Lowest single battery voltage;;0.001V;;;;;;;; -;;1110;bModuleNum;Battery parallel number;;1;;;;;;;; -;;1112;uwMaxVoltCellNo;MaxVoltCellNo;;1;;;;;;;; -;;1113;uwMinVoltCellNo;MinVoltCellNo;;1;;;;;;;; -;;1114;uwMaxTemprCell_10T;MaxTemprCell_10T;;0.1C;;;;;;;; -;;1115;uwMinTemprCell_10T;MinTemprCell_10T;;0.1C;;;;;;;; -;;1116;uwMaxTemprCellNo;MaxVoltTemprCellNo;;1;;;;;;;; -;;1117;uwMinTemprCelllNo;MinVoltTemprCellNo;;1;;;;;;;; -;;1118;Protect pack ID;Faulty Battery Address;;1;;;;;;;; -;;1119;MaxSOC;Parallel maximum SOC;;1.00%;;;;;;;; -;;1120;MinSOC;Parallel minimum SOC;;1.00%;;;;;;;; -;;1121;BMS_Error2;Battery Protection 2;;-0;CAN ID : 0x323 Byte4~5;;;;;;; -;;1122;BMS_Error3;Battery Protection3;;-0;CAN ID : 0x323 Byte6;;;;;;; -;;1123;BMS_WarnInfo2;Battery Warn2;;-0;CAN ID : 0x323 Byte7;;;;;;; -;;1124;AC Charge Energy Today H;AC Charge Energy today;kwh;;Energy today;;;;;;; -;;1125;ACCharge Energy Today L;AC Charge Energy today;kwh;;;;;;;;; -;;1126;AC Charge Energy Total H;;;;Energy total;;;;;;; -;;1127;ACCharge Energy Total L;;;;;;;;;;; -;;1128;AC Charge Power H;AC Charge Power;W;;;;;;;;; -;;1129;AC Charge Power L;AC Charge Power;w;;;;;;;;; -;;1130;70Percent INV Power adjust;uwGridPower_70_AdjEE_SP;W;;;;;;;;; -;;1131;Extra AC Power to grid_H;Extra inverte AC Power to grid High;For SPA connect inverter;;SPA used;;;;;;; -;;1132;Extra AC Power to grid_L;Extrainverte AC Power to grid Low;;;SPA used;;;;;;; -;;1133;Eextra_today H;Extra inverter PowerTOUser_Extra today (high);R;0.1kWh;SPA used;;;;;;; -;;1134;Eextra_today L;Extra inverter PowerTOUser_Extra today (low);R;0.1kWh;SPA used;;;;;;; -;;1135;Eextra_total H;Extra inverter PowerTOUser_Extra total(high);;0.1kWh;SPA used;;;;;;; -;;1136;Eextra_total L;Extra inverter PowerTOUser_Extra total(low);;0.1kWh;SPA used;;;;;;; -;;1137;Esystem_today H;System electric energy today H;;0.1kWh;SPA used System electric energy today H;;;;;;; -;;1138;Esystem_today L;System electric energy today L;;0.1kWh;SPA used System electric energy today L;;;;;;; -;;1139;Esystem_total H;System electric energy total H;;0.1kWh;SPA used System electric energy total H;;;;;;; -;;1140;Esystem_total L;System electric energy total L;;0.1kWh;SPA used System electric energy total L;;;;;;; -;;1141;Eself_today H;self electric energy today H;;0.1kWh;self electric energy today H;;;;;;; -;;1142;Eself_today L;self electric energy today L;;0.1kWh;self electric energy today L;;;;;;; -;;1143;Eself_total H;self electric energy total H;;0.1kWh;self electric energy total H;;;;;;; -;;1144;Eself_total L;self electric energy total L;;0.1kWh;self electric energy total L;;;;;;; -;;1145;PSystem H;System power H;;0.1w;System power H;;;;;;; -;;1146;PSystem L;System power L;;0.1w;System power L;;;;;;; -;;1147;PSelf H;self power H;;0.1w;self power H;;;;;;; -;;1148;PSelf L;self power L;;0.1w;self power L;;;;;;; -;;1149;EPVAll_Today H;PV electric energy today H;;;;;;;;;; -;;1150;EPVAll_Today L;PV electric energy today L;;;;;;;;;; -;;1151;AcDischarge PackSn;Discharge Number power;R;;;;;;;;; -;;1152;Accdischarge power_H;Cumulative discharge power high 16-bit byte;R;0.1 kWH;;;;;;;; -;;1153;Accdischarge power_L;Cumulative discharge power low 16-bit byte;R;0.1 kWH;;;;;;;; -;;1154;AccCharge PackSn;charge power pack serial number;R;;;;;;;;; -;;1155;AccCharge power_H;Cumulative charge power high 16-bit byte;R;0.1 kWH;;;;;;;; -;;1156;AccCharge power_L;Cumulative charge power low 16-bit byte;R;0.1 kWH;;;;;;;; -;;1157;FirstBattFaultSn;FirstBattFaultSn;R;;;;;;;;; -;;1158;Second BattFaultSn;Second BattFaultSn;R;;;;;;;;; -;;1159;Third BattFaultSn;Third BattFaultSn;R;;;;;;;;; -;;1160;Fourth BattFaultSn;Fourth BattFaultSn;R;;;;;;;;; -;;1161;Battery history fault code 1;Battery history fault code 1;R;;;;;;;;; -;;1162;Battery history fault code 2;Battery history fault code 2;R;;;;;;;;; -;;1163;Battery history fault code 3;Battery history fault code 3;R;;;;;;;;; -;;1164;Battery history fault code 4;Battery history fault code 4;R;;;;;;;;; -;;1165;Battery history fault code 5;Battery history fault code 5;R;;;;;;;;; -;;1166;Battery history fault code 6;Battery history fault code 6;R;;;;;;;;; -;;1167;Battery history fault code 7;Battery history fault code 7;R;;;;;;;;; -;;1168;Battery history fault code 8;Battery history fault code 8;R;;;;;;;;; -;;1169;Number of battery codes;Number of battery codes PACK number Plus BIC forward and reverse codes;R;;;;;;;;; -;;1199;NewEPowerCalc Flag;Intelligent reading is used to identify software compatibility features;0 : Old energy calculation; 1 : new energy calculation;;;;;;;; -;;1200;MaxCellVolt;Maximum cell voltage;R;0.001V;;;;;;;; -;;1201;MinCellVolt;Minimum cell voltage;R;0.001V;;;;;;;; -;;1202;ModuleNum;Number of Battery modules;R;/;;;;;;;; -;;1203;TotalCellNum;Total number of cells;R;/;;;;;;;; -;;1204;MaxVoltCellNo;MaxVoltCellNo;R;/;;;;;;;; -;;1205;MinVoltCellNo;MinVoltCellNo;R;/;;;;;;;; -;;1206;MaxTemprCell_10T;MaxTemprCell_10T;R;0.1?;;;;;;;; -;;1207;MinTemprCell_10T;MinTemprCell_10T;R;0.1?;;;;;;;; -;;1208;MaxTemprCellNo;MaxTemprCellNo;R;/;;;;;;;; -;;1209;MinTemprCellNo;MinTemprCellNo;R;/;;;;;;;; -;;1210;ProtectPackID;Fault Pack ID;R;/;;;;;;;; -;;1211;MaxSOC;Parallel maximum SOC;R;1.00%;;;;;;;; -;;1212;MinSOC;Parallel minimum SOC;R;1.00%;;;;;;;; -;;1213;BatProtect1Add;BatProtect1Add;R;/;;;;;;;; -;;1214;BatProtect2Add;BatProtect2Add;R;/;;;;;;;; -;;1215;BatWarn1Add;BatWarn1Add;R;/;;;;;;;; -;;1216;BMS_HighestSoftVersion;BMS_HighestSoftVersion;R;/;;;;;;;; -;;1217;BMS_HardwareVersion;BMS_HardwareVersion;R;/;;;;;;;; -;;1218;BMS_RequestType;BMS_RequestType;R;/;;;;;;;; -;;1248;bKeyAgingTestOkFlag;Success sign of key detection before aging;1:Finished test 0 : test not completed;;;;;;;;; -;;2000;Inverter Status;Inverter run state;0:waiting 1:normal 3:fault;;;;;;;;; -Output Watts;;2035;Pac H;Output power (high);;0.1W;;;SPA;;;;; -;;2036;Pac L;Output power (low);;0.1W;;;SPA;;;;; -Grid Hz;;2037;Fac;Grid frequency;;0.01Hz;;;SPA;;;;; -Grid Voltage Phase 1;;2038;Vac1;Three/single phase grid voltage;;0.1V;;;SPA;;;;; -Grid Current Phase 1;;2039;Iac1;Three/single phase grid output current;;0.1A;;;SPA;;;;; -Grid VA Phase 1;;2040;Pac1 H;Three/single phase grid output watt VA (high);;0.1VA;;;SPA;;;;; -;;2041;Pac1 L;Three/single phase grid output watt VA(low);;0.1VA;;;SPA;;;;; -;;2053;Eac today H;Today generate energy (high);;0.1kWH;;;SPA;;;;; -;;2054;Eac today L;Today generate energy (low);;0.1kWH;;;SPA;;;;; -;;2055;Eac total H;Total generate energy (high);;0.1kWH;;;SPA;;;;; -;;2056;Eac total L;Total generate energy (low);;0.1kWH;;;SPA;;;;; -;;2057;Time total H;Work time total (high);;0.5s;;;SPA;;;;; -;;2058;Time total L;Work time total (low);;0.5s;;;SPA;;;;; -;;2093;Temp1;Inverter temperature;;0.1C;;;SPA;;;;; -;;2094;Temp2;The inside IPM in inverter Temperature;;0.1C;;;SPA;;;;; -;;2095;Temp3;Boost temperature;;0.1C;;;SPA;;;;; -;;2096;Temp4;;;;;;reserved;;;;; -;;2097;uwBatVolt_DSP;BatVolt_DSP;;0.1V;;;BatVolt(DSP);;;;; -;;2098;P Bus Voltage;P Bus inside Voltage;;0.1V;;;SPA;;;;; -;;2099;N Bus Voltage;N Bus inside Voltage;;0.1V;;;SPA;;;;; -;;2100;RemoteCtrlEn;/;0.Load First 1.BatFirst 2.Grid;/;;;Remote setup enable;;;;; -;;2101;RemoteCtrlPower;;;/;/;;Remotely set power;;;;; -;;2102;Extra AC Power to grid_H;Extra inverte AC Power to grid High;For SPA connect inverter;;;;SPA used;;;;; -;;2103;Extra AC Power to grid_L;Extrainverte AC Power to grid Low;;;;;SPA used;;;;; -;;2104;Eextra_today H;Extra inverter PowerTOUser_Extra today (high);R;0.1kWh;;;SPA;;;;; -;;2105;Eextra_today L;Extra inverter PowerTOUser_Extra today (low);R;0.1kWh;;;SPA;;;;; -;;2106;Eextra_total H;Extra inverter PowerTOUser_Extratotal(high);;0.1kWh;;;SPA;;;;; -;;2107;Eextra_total L;Extra inverter PowerTOUser_Extra total(low);;0.1kWh;;;SPA;;;;; -;;2108;Esystem_today H;System electric energy today H;;0.1kWh;;;SPA used System electric energy today H;;;;; -;;2109;Esystem_today L;System electric energy today L;;0.1kWh;;;SPA used System electric energy today L;;;;; -;;2110;Esystem_total H;System electric energy total H;;0.1kWh;;;SPA used System;;;;; -;;2111;Esystem_total L;System electric energy total L;;0.1kWh;;;SPA used System electric energy total L;;;;; -;;2112;EACharge_Today_H;ACCharge energy today;;0.1kwh;;;Storage Power;;;;; -;;2113;EACharge_Today_L;ACCharge energy today;;0.1kwh;;;Storage Power;;;;; -;;2114;EACharge_Total_H;ACCharge energy total;;0.1kwh;;;Storage Power;;;;; -;;2115;EACharge_Total_L;ACCharge energy total;;0.1kwh;;;Storage Power;;;;; -;;2116;AC charge Power_H;Grid power to local load;;0.1kwh;;;Storage Power;;;;; -;;2117;AC charge Power_L;Grid power to local load;;0.1kwh;;;Storage Power;;;;; -;;2118;Priority;0:Load First 1:Battery First 2:Grid First;;;;;Storage Power;;;;; -;;2119;Battery Type;0:Lead-acid 1:Lithium battery;;;;;Storage Power;;;;; -;;2120;AutoProofreadCMD;Aging mode;;;;;Storage Power;;;;; -;;3000;Inverter Status;Inverter run state High 8 bits mode (specific mode) ;0: Waiting module 1: Self-test mode 7:PVOfflineMode 8:BatOfflineMode The lower 8 bits indicate the machine status (web page display) 0: StandbyStatus; 1: NormalStatus; 3: FaultStatus 4:FlashStatus;;;;;;; -PV Watts;;3001;Ppv H;PV total power H;;0.1W;;;;;;;; -;;3002;Ppv L;PV total power L;;;;;;;;;; -PV1 Voltage;;3003;Vpv1;PV1 voltage;;0.1V;;;;;;;; -;;3004;Ipv1;PV1 input current;;0.1A;;;;;;;; -PV1 Watts;;3005;Ppv1 H;PV1 power H;;0.1W;;;;;;;; -;;3006;Ppv1 L;PV1 power L;;;;;;;;;; -PV2 Voltage;;3007;Vpv2;PV2 voltage;;0.1V;;;;;;;; -;;3008;Ipv2;PV2 input current;;0.1A;;;;;;;; -PV2 Watts;;3009;Ppv2 H;PV2 power H;;0.1W;;;;;;;; -;;3010;Ppv2 L;PV2 power L;;;;;;;;;; -PV3 Voltage;;3011;Vpv3;PV3 voltage;;0.1V;;;;;;;; -;;3012;Ipv3;PV3 input current;;0.1A;;;;;;;; -PV3 Watts;;3013;Ppv3 H;PV3 power H;;0.1W;;;;;;;; -;;3014;Ppv3 L;PV3 power L;;;;;;;;;; -PV4 Voltage;;3015;Vpv4;PV4 voltage;;;;;;;;;; -;;3016;Ipv4;PV4 input current;;;;;;;;;; -PV4 Watts;;3017;Ppv4 H;PV4 power H;;;;;;;;;; -;;3018;Ppv4 L;PV4 power L;;;;;;;;;; -;;3019;Psys H;System output power H;;0.1W;;;;;;;; -;;3020;Psys L;System output power L;;;;;;;;;; -;;3021;Qac H;reactive power H;;0.1Var;;;;;;;; -;;3022;Qac L;reactive power L;;;;;;;;;; -Output Watts;;3023;Pac H;Output power H;;0.1W;;;;;;;; -;;3024;Pac L;Output power L;;;;;;;;;; -Grid Hz;;3025;Fac;Grid frequency;;0.01Hz;;;;;;;; -Grid Voltage Phase 1;;3026;Vac1;Three/single phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 1;;3027;Iac1;Three/single phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 1;;3028;Pac1 H;Three/single phase grid output watt VA H;;0.1VA;;;;;;;; -;;3029;Pac1 L;Three/single phase grid output watt VA L;;;;;;;;;; -Grid Voltage Phase 2;;3030;Vac2;Three phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 2;;3031;Iac2;Three phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 2;;3032;Pac2 H;Three phase grid output power H;;0.1VA;;;;;;;; -;;3033;Pac2 L;Three phase grid output power L;;;;;;;;;; -Grid Voltage Phase 3;;3034;Vac3;Three phase grid voltage;;0.1V;;;;;;;; -Grid Current Phase 3;;3035;Iac3;Three phase grid output current;;0.1A;;;;;;;; -Grid VA Phase 3;;3036;Pac3 H;Three phase grid output power H;;0.1VA;;;;;;;; -;;3037;Pac3 L;Three phase grid output power L;;;;;;;;;; -;;3038;Vac_RS;Three phase grid voltage;;0.1V;;;;;;;; -;;3039;Vac_ST;Three phase grid voltage;;0.1V;;;;;;;; -;;3040;Vac_TR;Three phase grid voltage;;0.1V;;;;;;;; -;;3041;Ptouser total H;Total forward power H;;0.1W;;;;;;;; -;;3042;Ptouser total L;Total forward power L;;;;;;;;;; -;;3043;Ptogrid total H;Total reverse power H;;0.1W;;;;;;;; -;;3044;Ptogrid total L;Total reverse power L;;;;;;;;;; -;;3045;Ptoload total H;Total load power H;;0.1W;;;;;;;; -;;3046;Ptoload total L;Total load power L;;;;;;;;;; -;;3047;Time total H;Work time total H;;0.5s;;;;;;;; -;;3048;Time total L;Work time total L;;;;;;;;;; -;;3049;Eac today H;Today generate energy H;;0.1kWh;;;;;;;; -;;3050;Eac today L;Today generate energy L;;;;;;;;;; -;;3051;Eac total H;Total generate energy H;;0.1kWh;;;;;;;; -;;3052;Eac total L;Total generate energy L;;;;;;;;;; -PV KWH Total;;3053;Epv_total H;PV energy total H;;0.1kWh;;;;;;;; -;;3054;Epv_total L;PV energy total L;;;;;;;;;; -PV1 KWH Today;;3055;Epv1_today H;PV1 energy today H;;0.1kWh;;;;;;;; -;;3056;Epv1_today L;PV1 energy today L;;;;;;;;;; -PV1 KWH Total;;3057;Epv1_total H;PV1 energy total H;;0.1kWh;;;;;;;; -;;3058;Epv1_total L;PV1 energy total L;;;;;;;;;; -PV2 KWH Today;;3059;Epv2_today H;PV2 energy today H;;0.1kWh;;;;;;;; -;;3060;Epv2_today L;PV2 energy today L;;;;;;;;;; -PV2 KWH Total;;3061;Epv2_total H;PV2 energy total H;;0.1kWh;;;;;;;; -;;3062;Epv2_total L;PV2 energy total L;;;;;;;;;; -PV3 KWH Today;;3063;Epv3_today H;PV3 energy today H;;0.1kWh;;;;;;;; -;;3064;Epv3_today L;PV3 energy today L;;;;;;;;;; -PV3 KWH Total;;3065;Epv3_total H;PV3 energy total H;;0.1kWh;;;;;;;; -;;3066;Epv3_total L;PV3 energy total L;;;;;;;;;; -;;3067;Etouser_today H;Today energy to user H;;0.1kWh;;;;;;;; -;;3068;Etouser_today L;Today energy to user L;;;;;;;;;; -;;3069;Etouser_total H;Total energy to user H;;0.1kWh;;;;;;;; -;;3070;Etouser_total L;Total energy to user L;;;;;;;;;; -;;3071;Etogrid_today H;Today energy to grid H;;0.1kWh;;;;;;;; -;;3072;Etogrid_today L;Today energy to grid L;;;;;;;;;; -;;3073;Etogrid_total H;Total energy to grid H;;0.1kWh;;;;;;;; -;;3074;Etogrid_total L;Total energy to grid L;;;;;;;;;; -;;3075;Eload_today H;Today energy of user load H;;0.1kWh;;;;;;;; -;;3076;Eload_today L;Today energy of user load L;;;;;;;;;; -;;3077;Eload_total H;Total energy of user load H;;0.1kWh;;;;;;;; -;;3078;Eload_total L;Total energy of user load L;;;;;;;;;; -PV4 KWH Today;;3079;Epv4_today H;PV4 energy today H;;0.1kWh;;;;;;;; -;;3080;Epv4_today L;PV4 energy today L;;;;;;;;;; -PV4 KWH Total;;3081;Epv4_total H;PV4 energy total H;;0.1kWh;;;;;;;; -;;3082;Epv4_total L;PV4 energy total L;;;;;;;;;; -;;3083;Epv_today H;PV energy today H;;0.1kWh;;;;;;;; -;;3084;Epv_today L;PV energy today L;;;;;;;;;; -;;3086;DeratingMode;DeratingMode;;;;;;;;;; -;;3087;ISO;PV ISO value;;1K?;;;;;;;; -;;3088;DCI_R;R DCI Curr;;0.1mA;;;;;;;; -;;3089;DCI_S;S DCI Curr;;0.1mA;;;;;;;; -;;3090;DCI_T;T DCI Curr;;0.1mA;;;;;;;; -;;3091;GFCI;GFCI Curr;;1mA;;;;;;;; -;;3092;Bus Voltage;total bus voltage;;0.1V;;;;;;;; -;;3093;Temp1;Inverter temperature;;0.1?;;;;;;;; -;;3094;Temp2;The inside IPM in inverter temperature;;0.1?;;;;;;;; -;;3095;Temp3;Boost temperature;;0.1?;;;;;;;; -;;3096;Temp4;Reserved;;0.1?;;;;;;;; -;;3097;Temp5;Commmunication broad temperature;;0.1?;;;;;;;; -;;3098;P Bus Voltage;P Bus inside Voltage;;0.1V;;;;;;;; -;;3099;N Bus Voltage;N Bus inside Voltage;;0.1V;;;;;;;; -Inverter Power Factor;;3100;IPF;Inverter output PF now;;;;;;;;;; -;;3101;RealOPPercent;Real Output power Percent;;1.00%;;;;;;;; -;;3102;OPFullwatt H;Output Maxpower Limited H;;0.1W;;;;;;;; -;;3103;OPFullwatt L;Output Maxpower Limited L;;;;;;;;;; -;;3104;StandbyFlag;Inverter standby flag;;bitfield;;;;;;;; -;;3105;Fault Maincode;Inverter fault maincode;;;;;;;;;; -;;3106;Warn Maincode;Inverter Warning maincode;;;;;;;;;; -;;3107;Fault Subcode;Inverter fault subcode;;bitfield;;;;;;;; -;;3108;Warn Subcode;Inverter Warning subcode;;bitfield;;;;;;;; -;;3111;uwPresentFFTValue_CHANNEL_A_;PresentFFTValue [CHANNEL_A];;bitfield;;;;;;;; -;;3112;bAfciStatus;AFCI Status;;;;;;;;;; -;;3113;uwStrength_CHANNEL_A_;AFCI Strength[CHANNEL_A];;;;;;;;;; -;;3114;uwSelfCheckValue_CHANNEL_A_;AFCI SelfCheck[CHANNEL_A];;;;;;;;;; -;;3115;inv start delay time;inv start delay time;;1S;;;;;;;; -;;3116;Reserved;;;;;;;;;;; -;;3117;Reserved;;;;;;;;;;; -;;3118;BDC_OnOffState;BDC connect state;;;;;;;;;; -;;3119;DryContactState;Current status of DryContact;;;;;;;;;; -;;3120;Reserved;;;;;;;;;;; -;;3121;Pself H;self-use power H;;0.1W;;;;;;;; -;;3122;Pself L;self-use power L;;;;;;;;;; -;;3123;Esys_today H;System energy today H;;0.1kwh;;;;;;;; -;;3124;Esys_today L;System energy today L ;;;;;;;;;; -;;3125;Edischr_today H;Today discharge energy H;;0.1kWh;;;;;;;; -;;3126;Edischr_today L;Today discharge energy L;;;;;;;;;; -;;3127;Edischr_total H;Total discharge energy H;;0.1kWh;;;;;;;; -;;3128;Edischr_total L;Total discharge energy L;;;;;;;;;; -;;3129;Echr_today H;Charge energy today H;;0.1kWh;;;;;;;; -;;3130;Echr_today L;Charge energy today L;;;;;;;;;; -;;3131;Echr_total H;Charge energy total H;;0.1kWh;;;;;;;; -;;3132;Echr_total L;Charge energy total L;;;;;;;;;; -;;3133;Eacchr_today H;Today energy of AC charge H;;0.1kWh;;;;;;;; -;;3134;Eacchr_today L;Today energy of AC charge L;;;;;;;;;; -;;3135;Eacchr_total H;Total energy of AC charge H;;0.1kWh;;;;;;;; -;;3136;Eacchr_total L;Total energy of AC charge L;;;;;;;;;; -;;3137;Esys_total H;Total energy of system output H;;;;;;;;;; -;;3138;Esys_total L;Total energy of system output L;;0.1kWh;;;;;;;; -;;3139;Eself_today H;Today energy of Self output H;;0.1kWh;;;;;;;; -;;3140;Eself_today L;Today energy of Self output L;;;;;;;;;; -;;3141;Eself_total H;Total energy of Self output H;;0.1kwh;;;;;;;; -;;3142;Eself_total L;Total energy of Self output L;;;;;;;;;; -;;3143;Reserved;;;;;;;;;;; -;;3144;Priority;Word Mode;;;;;;;;;; -;;3145;EPS Fac;UPS frequency;;0.01Hz;;;;;;;; -;;3146;EPS Vac1;UPS phase R output voltage;;0.1V;;;;;;;; -;;3147;EPS Iac1;UPS phase R output current;;0.1A;;;;;;;; -;;3148;EPS Pac1 H;UPS phase R output power H;;0.1VA;;;;;;;; -;;3149;EPS Pac1 L;UPS phase R output power L;;;;;;;;;; -;;3150;EPS Vac2;UPS phase S output voltage;;0.1V;;;;;;;; -;;3151;EPS Iac2;UPS phase S output current;;0.1A;;;;;;;; -;;3152;EPS Pac2 H;UPS phase S output power H;;0.1VA;;;;;;;; -;;3153;EPS Pac2 L;UPS phase S output power L;;;;;;;;;; -;;3154;EPS Vac3;UPS phase T output voltage;;0.1V;;;;;;;; -;;3155;EPS Iac3;UPS phase T output current;;0.1A;;;;;;;; -;;3156;EPS Pac3 H;UPS phase T output power H;;0.1VA;;;;;;;; -;;3157;EPS Pac3 L;UPS phase T output power L;;;;;;;;;; -;;3158;EPS Pac H;UPS output power H;;0.1VA;;;;;;;; -;;3159;EPS Pac L;UPS output power L;;;;;;;;;; -;;3160;Loadpercent;Load percent of UPS ouput;;0.10%;;;;;;;; -;;3161;PF;Power factor;;0.1;;;;;;;; -;;3162;DCV;DC voltage;;1mV;;;;;;;; -;;3163;Reserved;;;;;;;;;;; -;;3164;NewBdcFlag;Whether to parse BDC data separately;;;;;;;;;; -;;3165;BDCDeratingMode;BDCDeratingMode: 0: Normal unrestricted 1:Standby or fault 2:Maximum battery current limit (discharge) 3:Battery discharge Enable (Discharge) 4:High bus discharge derating (discharge) 5:High temperature discharge derating (discharge) 6:System warning No discharge (discharge) 7-15 Reserved (Discharge) 16:Maximum charging current of battery (charging) 17:High Temperature (LLC and Buckboost) (Charging) 18:Final soft charge 19:SOC setting limits (charging) 20:Battery low temperature (charging) 21:High bus voltage (charging) 22:Battery SOC (charging) 23: Need to charge (charge) 24: System warning not charging (charging) 25-29:Reserve (charge);;;;;;;;;; -;;3166;SysState_Mode;System work State and mode The upper 8 bits indicate the mode; 0:No charge and discharge; 1:charge; 2:Discharge;; 0: StandbyStatus;;;;; -;;3167;FaultCode;Storge device fault code;;;;;;;;;; -;;3168;WarnCode;Storge device warning code;;;;;;;;;; -;;3169;Vbat;Battery voltage;;;;;;;;;; -;;3170;Ibat;Battery current;;;;;;;;;; -;;3171;SOC;State of charge Capacity;;;;;;;;;; -;;3172;Vbus1;Total BUS voltage;;;;;;;;;; -;;3173;Vbus2;On the BUS voltage;;;;;;;;;; -;;3174;Ibb;BUCK-BOOST Current;;;;;;;;;; -;;3175;Illc;LLC Current;;;;;;;;;; -;;3176;TempA;Temperture A;;;;;;;;;; -;;3177;TempB;Temperture B;;;;;;;;;; -;;3178;Pdischr H;Discharge power H;;;;;;;;;; -;;3179;Pdischr L;Discharge power L;;;;Pdischr L;;Pdischr L;Pdischr L;Pdischr L;Pdischr L;Pdischr L -;;3180;Pchr H;Charge power H;;0.1W;;;;;;;; -;;3181;Pchr L;Charge power L;;;;;;;;;; -;;3182;Edischr_total H;Discharge total energy of storge device H;;;;;;;;;; -;;3183;Edischr_total L;Discharge total energy of storge device L;;;;Edischr_total L;;Edischr_total L;Edischr_total L;Edischr_total L;Edischr_total L;Edischr_total L -;;3184;Echr_total H;Charge total energy of storge device H;;;;;;;;;; -;;3185;Echr_total L;Charge total energy of storge device L;;;;;;;;;; -;;3186;Reserved;Reserved;;;;;;;;;; -;;3187;BDC1_Flag;"BDC mark (charge and discharge, fault alarm code) Bit0: ChargeEn; BDC allows charging Bit1: DischargeEn; BDC allows discharge Bit2~7: Resvd; reserved Bit8~11: WarnSubCode; BDC sub-warning code Bit12~15: FaultSubCode; BDC sub-error code";;;;;;;;;; -;;3188;Vbus2;Lower BUS voltage;;;;;;;;;; -;;3189;BmsMaxVoltCellNo;BmsMaxVoltCellNo;;;;;;;;;; -;;3190;BmsMinVoltCellNo;BmsMinVoltCellNo;;;;;;;;;; -;;3191;BmsBatteryAvgTemp;BmsBatteryAvgTemp;;;;;;;;;; -;;3192;BmsMaxCellTemp;BmsMaxCellTemp;;0.1?C;;;;;;;; -;;3193;BmsBatteryAvgTemp;BmsBatteryAvgTemp;;0.1?C;;;;;;;; -;;3194;BmsMaxCellTemp;BmsMaxCellTemp;;;;;;;;;; -;;3195;BmsBatteryAvgTemp;BmsBatteryAvgTemp;;;;;;;;;; -;;3196;BmsMaxSOC;BmsMaxSOC;;1.00%;;;;;;;; -;;3197;BmsMinSOC;BmsMinSOC;;1.00%;;;;;;;; -;;3198;ParallelBatteryNum;ParallelBatteryNum;;;;;;;;;; -;;3199;BmsDerateReason;BmsDerateReason;;;;;;;;;; -;;3200;BmsGaugeFCC_Ah;BmsGaugeFCC(Ah);;;;;;;;;; -;;3201;BmsGaugeRM_Ah;BmsGaugeRM(Ah);;;;;;;;;; -;;3202;BmsError;BMS Protect1;;;;;;;;;; -;;3203;BmsWarn;BMSWarn1;;;;;;;;;; -;;3204;BmsFault;BMS Fault1;;;;;;;;;; -;;3205;BmsFault2;BMS Fault2;;;;;;;;;; -;;3210;BatIsoStatus;Battery ISO detection status;;;;;;;;;; -;;3211;BattNeedCharge RequestFlag;battery work request;;"bit0:1: Prohibit chargin g 2 bit8:1: Dischar ge is prohibit ed, 0: allow discharg e bit9:1: Turn on power reductio n 0: turn off power reductio n;";0: Allow the chargin g bit1:1: Enable strong charge;;;;;;; -;;3212;BMS_Status;battery working status;R;;;;;;;;; -;;3213;BmsError2;BMS Protect2;R;1;;;;;;;; -;;3214;BmsWarn2;BMS Warn2;R;1;;;;;;;; -;;3215;BMS_SOC;BMS SOC;R;1.00%;;;;;;;; -;;3216;BMS_BatteryVolt;BMS BatteryVolt;R;0.01V;;;;;;;; -;;3217;BMS_BatteryCurr;BMS BatteryCurr;R;0.01A;;;;;;;; -;;3218;BMS_BatteryTemp;battery cell maximum temperature;R;0.1?;;;;;;;; -;;3219;BMS_MaxCurr;Maximum charging current;R;0.01A;;;;;;;; -;;3220;BMS_MaxDischrCurr;Maximum discharge current;R;0.01A;;;;;;;; -;;3221;BMS_CycleCnt;BMSCycleCnt;R;1;;;;;;;; -;;3222;BMS_SOH;BMS SOH;R;1;;;;;;;; -;;3223;BMS_ChargeVoltLimit;Battery charging voltage limit value;R;0.01V;;;;;;;; -;;3224;BMS_DischargeVoltLimit;Battery discharge voltage limit value;;;;;;;;;; -;;3225;Bms Warn3;BMS Warn 3;R;1;;;;;;;; -;;3226;Bms Error3;BMS Protect3;R;1;;;;;;;; -;;3227;Reserved;;;;;;;;;;; -;;3228;Reserved;;;;;;;;;;; -;;3229;Reserved;;;;;;;;;;; -;;3230;BMSSingleVoltMax;BMS Battery SingleVoltMax;R;0.001V;;;;;;;; -;;3231;BMSSingleVoltMin;BMS Battery SingleVoltMin;R;0.001V;;;;;;;; -;;3232;BatLoadVolt;Battery LoadVolt;R;0.01V;;;650.00];;;;; -;;3234;Debug data1;Debug data1;R;;;;;;;;; -;;3235;Debug data2;Debug data2;R;;;;;;;;; -;;3236;Debug data3;Debug data3;R;;;;;;;;; -;;3237;Debug data4;Debug data4;R;;;;;;;;; -;;3238;Debug data5;Debug data5;R;;;;;;;;; -;;3239;Debug data6;Debug data6;R;;;;;;;;; -;;3240;Debug data7;Debug data7;R;;;;;;;;; -;;3241;Debug data8;Debug data8;R;;;;;;;;; -;;3242;Debug data9;Debug data9;R;;;;;;;;; -;;3243;Debug data10;Debug data10;R;;;;;;;;; -;;3244;Debug data10;Debug data10;R;;;;;;;;; -;;3245;Debug data12;Debug data12;R;;;;;;;;; -;;3246;Debug data13;Debug data13;R;;;;;;;;; -;;3247;Debug data14;Debug data14;R;;;;;;;;; -;;3248;Debug data15;Debug data15;R;;;;;;;;; -;;3249;Debug data16;Debug data16;R;;;;;;;;; -;;3250;Pex1H;PV inverter 1 output power H;R;0.1W;;;;;;;; -;;3251;Pex1L;PV inverter 1 output power L;R;0.1W;;;;;;;; -;;3252;Pex2H;PV inverter 2 output power H;R;0.1W;;;;;;;; -;;3253;Pex2L;PV inverter 2 output power L;R;0.1W;;;;;;;; -;;3254;Eex1TodayH;PV inverter 1 energy Today H;R;0.1kWh;;;;;;;; -;;3255;Eex1TodayL;PV inverter 1 energy Today L;R;0.1kWh;;;;;;;; -;;3256;Eex2TodayH;PV inverter 2 energy Today H;R;0.1kWh;;;;;;;; -;;3257;Eex2TodayL;PV inverter 2 energy Today L;R;0.1kWh;;;;;;;; -;;3258;Eex1TotalH;PV inverter 1 energy Total H;R;0.1kWh;;;;;;;; -;;3259;Eex1TotalL;PV inverter 1 energy Total L;R;0.1kWh;;;;;;;; -;;3260;Eex2TotalH;PV inverter 2 energy Total H;R;0.1kWh;;;;;;;; -;;3261;Eex2TotalL;PV inverter 2 energy Total L;R;0.1kWh;;;;;;;; -;;3262;uwBatNo;battery pack number;R;;;;;;;;; -;;3263;BatSerialNum1;Battery pack serial numberSN[0]SN[1];R;;;;;;;;; -;;3264;BatSerialNum2;Battery pack serial numberSN[2]SN[3];;;;;;;;;; -;;3265;BatSerialNum3;Battery pack serial numberSN[4]SN[5];;;;;;;;;; -;;3266;BatSerialNum4;Battery pack serial numberSN[6]SN[7];;;;;;;;;; -;;3267;BatSerialNum5;Battery pack serial numberSN[8]SN[9];;;;;;;;;; -;;3268;BatSerialNum6;Battery pack serial numberSN[10]SN[11];;;;;;;;;; -;;3269;BatSerialNum7;Battery pack serial numberSN[12]SN[13];;;;;;;;;; -;;3270;BatSerialNum8;Battery pack serial numberSN[14]SN[15];;;;;;;;;; -;;3280;bClrTodayDataFlag;Clear day data flag;R;;;;;;;;; +variable name,data type,register,documented name,description,values,unit,note,,Note,,,,, +,,0,Inverter Status,Inverter run state,0:waiting 1:normal 3:fault,,,,,,,,, +PV Watts,,1,Ppv H,Input power (high),,0.1W,,,,,,,, +,,2,Ppv L,Input power (low),,0.1W,,,,,,,, +PV1 Voltage,,3,Vpv1,PV1 voltage,,0.1V,,,,,,,, +PV1 Current,,4,PV1Curr,PV1 input current,,0.1A,,,,,,,, +PV1 Watts,,5,Ppv1 H,PV1 input power(high),,0.1W,,,,,,,, +,,6,Ppv1 L,PV1 input power(low),,0.1W,,,,,,,, +PV2 Voltage,,7,Vpv2,PV2 voltage,,0.1V,,,,,,,, +PV2 Current,,8,PV2Curr,PV2 input current,,0.1A,,,,,,,, +PV2 Watts,,9,Ppv2 H,PV2 input power (high),,0.1W,,,,,,,, +,,10,Ppv2 L,PV2 input power (low),,0.1W,,,,,,,, +PV3 Voltage,,11,Vpv3,PV3 voltage,,0.1V,,,,,,,, +PV3 Current,,12,PV3Curr,PV3 input current,,0.1A,,,,,,,, +PV3 Watts,,13,Ppv3 H,PV3 input power (high),,0.1W,,,,,,,, +,,14,Ppv3 L,PV3 input power (low),,0.1W,,,,,,,, +PV4 Voltage,,15,Vpv4,PV4 voltage,,0.1V,,,,,,,, +PV4 Current,,16,PV4Curr,PV4 input current,,0.1A,,,,,,,, +PV4 Watts,,17,Ppv4 H,PV4 input power (high),,0.1W,,,,,,,, +,,18,Ppv4 L,PV4 input power (low),,0.1W,,,,,,,, +PV5 Voltage,,19,Vpv5,PV5 voltage,,0.1V,,,,,,,, +PV5 Current,,20,PV5Curr,PV5 input current,,0.1A,,,,,,,, +PV5 Watts,,21,Ppv5H,PV5 input power(high),,0.1W,,,,,,,, +,,22,Ppv5 L,PV5 input power(low),,0.1W,,,,,,,, +PV6 Voltage,,23,Vpv6,PV6 voltage,,0.1V,,,,,,,, +PV6 Current,,24,PV6Curr,PV6 input current,,0.1A,,,,,,,, +PV6 Watts,,25,Ppv6 H,PV6 input power (high),,0.1W,,,,,,,, +,,26,Ppv6 L,PV6 input power (low),,0.1W,,,,,,,, +PV7 Voltage,,27,Vpv7,PV7 voltage,,0.1V,,,,,,,, +PV7 Current,,28,PV7Curr,PV7 input current,,0.1A,,,,,,,, +PV7 Watts,,29,Ppv7 H,PV7 input power (high),,0.1W,,,,,,,, +,,30,Ppv7 L,PV7 input power (low),,0.1W,,,,,,,, +PV8 Voltage,,31,Vpv8,PV8 voltage,,0.1V,,,,,,,, +PV8 Current,,32,PV8Curr,PV8 input current,,0.1A,,,,,,,, +PV8 Watts,,33,Ppv8 H,PV8 input power (high),,0.1W,,,,,,,, +,,34,Ppv8 L,PV8 input power (low),,0.1W,,,,,,,, +Output Watts,,35,Pac H,Output power (high),,0.1W,,,,,,,, +,,36,Pac L,Output power (low),,0.1W,,,,,,,, +Grid Hz,,37,Fac,Grid frequency,,0.01Hz,,,,,,,, +Grid Voltage Phase 1,,38,Vac1,Three/single phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 1,,39,Iac1,Three/single phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 1,,40,Pac1 H,Three/single phase grid output watt VA (high),,0.1VA,,,,,,,, +,,41,Pac1 L,Three/single phase grid output watt VA(low),,0.1VA,,,,,,,, +Grid Voltage Phase 2,,42,Vac2,Three phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 2,,43,Iac2,Three phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 2,,44,Pac2 H,Three phase grid output power (high),,0.1VA,,,,,,,, +,,45,Pac2 L,Three phase grid output power (low),,0.1VA,,,,,,,, +Grid Voltage Phase 3,,46,Vac3,Three phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 3,,47,Iac3,Three phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 3,,48,Pac3 H,Three phase grid output power (high),,0.1VA,,,,,,,, +,,49,Pac3 L,Three phase grid output power (low),,0.1VA,,,,,,,, +,,50,Vac_RS,Three phase grid voltage,,0.1V,,,Line voltage,,,,, +,,51,Vac_ST,Three phase grid voltage,,0.1V,,,Line voltage,,,,, +,,52,Vac_TR,Three phase grid voltage,,0.1V,,,Line voltage,,,,, +,,53,Eac today H,Today generate energy (high),,0.1kWH,,,,,,,, +,,54,Eac today L,Today generate energy (low),,0.1kWH,,,,,,,, +,,55,Eac total H,Total generate energy (high),,0.1kWH,,,,,,,, +,,56,Eac total L,Total generate energy (low),,0.1kWH,,,,,,,, +,,57,Time total H,Work time total (high),,0.5s,,,,,,,, +,,58,Time total L,Work time total (low),,0.5s,,,,,,,, +PV1 KWH Today,,59,Epv1_today H,PV1Energy today(high),,0.1kWh,,,,,,,, +,,60,Epv1_today L,PV1Energy today (low),,0.1kWh,,,,,,,, +PV1 KWH Total,,61,Epv1_total H,PV1Energy total(high),,0.1kWh,,,,,,,, +,,62,Epv1_total L,PV1Energy total (low),,0.1kWh,,,,,,,, +PV2 KWH Today,,63,Epv2_today H,PV2Energy today(high),,0.1kWh,,,,,,,, +,,64,Epv2_today L,PV2Energy today (low),,0.1kWh,,,,,,,, +PV2 KWH Total,,65,Epv2_total H,PV2Energy total(high),,0.1kWh,,,,,,,, +,,66,Epv2_total L,PV2Energy total (low),,0.1kWh,,,,,,,, +PV3 KWH Today,,67,Epv3_today H,PV3 Energy today(high),,0.1kWh,,,,,,,, +,,68,Epv3_today L,PV3 Energy today (low),,0.1kWh,,,,,,,, +PV3 KWH Total,,69,Epv3_total H,PV3 Energy total(high),,0.1kWh,,,,,,,, +,,70,Epv3_total L,PV3 Energy total (low),,0.1kWh,,,,,,,, +PV4 KWH Today,,71,Epv4_today H,PV4Energy today(high),,0.1kWh,,,,,,,, +,,72,Epv4_today L,PV4Energy today (low),,0.1kWh,,,,,,,, +PV4 KWH Total,,73,Epv4_total H,PV4Energy total(high),,0.1kWh,,,,,,,, +,,74,Epv4_total L,PV4Energy total (low),,0.1kWh,,,,,,,, +PV5 KWH Today,,75,Epv5_today H,PV5Energy today(high),,0.1kWh,,,,,,,, +,,76,Epv5_today L,PV5Energy today (low),,0.1kWh,,,,,,,, +PV5 KWH Total,,77,Epv5_total H,PV5Energy total(high),,0.1kWh,,,,,,,, +,,78,Epv5_total L,PV5Energy total (low),,0.1kWh,,,,,,,, +PV6 KWH Today,,79,Epv6_today H,PV6Energy today(high),,0.1kWh,,,,,,,, +,,80,Epv6_today L,PV6Energy today (low),,0.1kWh,,,,,,,, +PV6 KWH Total,,81,Epv6_total H,PV6Energy total(high),,0.1kWh,,,,,,,, +,,82,Epv6_total L,PV6Energy total (low),,0.1kWh,,,,,,,, +PV7 KWH Today,,83,Epv7_today H,PV7Energy today(high),,0.1kWh,,,,,,,, +,,84,Epv7_today L,PV7Energy today (low),,0.1kWh,,,,,,,, +PV7 KWH Total,,85,Epv7_total H,PV7 Energy total(high),,0.1kWh,,,,,,,, +,,86,Epv7_total L,PV7Energy total (low),,0.1kWh,,,,,,,, +PV8 KWH Today,,87,Epv8_today H,PV8Energy today(high),,0.1kWh,,,,,,,, +,,88,Epv8_today L,PV8Energy today (low),,0.1kWh,,,,,,,, +PV8 KWH Total,,89,Epv8_total H,PV8Energy total(high),,0.1kWh,,,,,,,, +,,90,Epv8_total L,PV8Energy total (low),,0.1kWh,,,,,,,, +PV KWH Total,,91,Epv_total H,PV Energy total(high),,0.1kWh,,,,,,,, +,,92,Epv_total L,PV Energy total (low),,0.1kWh,,,,,,,, +,,93,Temp1,Inverter temperature,,0.1C,,,,,,,, +,,94,Temp2,The inside IPM in inverter Temperature,,0.1C,,,,,,,, +,,95,Temp3,Boost temperature,,0.1C,,,,,,,, +,,96,Temp4,,,,,,reserved,,,,, +,,97,uwBatVolt_DSP,BatVolt_DSP,,0.1V,,,BatVolt(DSP),,,,, +,,98,P Bus Voltage,P Bus inside Voltage,,0.1V,,,,,,,, +,,99,N Bus Voltage,N Bus inside Voltage,,0.1V,,,,,,,, +Inverter Power Factor,,100,IPF,Inverter output PF now,0-20000,,,,,,,,, +,,101,RealOPPercent,Real Output power Percent,,1.00%,,,,,,,, +,,102,OPFullwatt H,Output Maxpower Limited high,,,,,,,,,, +,,103,OPFullwatt L,Output Maxpower Limited low,,0.1W,,,,,,,, +,,104,DeratingMode,DeratingMode,0:no derate, 1:PV, 2:*, 9:*OverBack ByTime, 4:Fac, 9:*OverBack ByTime, 9:*OverBack ByTime, 9:*OverBack ByTime, 9:*OverBack ByTime, 9:*OverBack ByTime +,,105,Fault Maincode,Inverter fault maincode,,,,,,,,,, +,,106,Fault Bitcode H ,,,,,,,,,,, +,,107,Fault Bitcode L,,,Inverter fault subcode,,,,,,,, +,,108,RemoteCtrlEn,/,0.Load First 1.BatFirst 2.Grid,/,,,StoragePow er (SPA),,,,, +,,109,RemoteCtrlPower,,,/,/,,StoragePow er (SPA),,,,, +,,110,Warning bit H,Warning bit H,,,,,,,,,, +,,111,Warn Subcode,,,Inverter warn subcode,,,,,,,, +,,112,Warn Maincode,Inverter warn maincode,,,,,,,,,, +,,113,real Power Percent,real Power Percent,0-100,%,,,MAX,,,,, +,,114,inv start delay time,inv start delay time,,,,,MAX,,,,, +,,115,bINVAllFaultCode,bINVAllFaultCode,,,,,MAX,,,,, +,,116,AC charge Power_H,Grid power to local load,,0.1kwh,,,Storage Power,,,,, +,,117,AC charge Power_L,Grid power to local load,,0.1kwh,,,Storage Power,,,,, +,,118,Priority,0:Load First 1:Battery First 2:Grid First,,,,,Storage,,,,, +,,119,Battery Type,0:Lead-acid 1:Lithium battery,,,,,Storage Power,,,,, +,,120,AutoProofreadCMD,Aging mode Command Auto-calibration,,,,,Storage Power,,,,, +,,125,PID PV1Plus Voltage,PID PV1PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,126,PID PV1Plus Current,PID PV1PE Curr,-10~10mA,0.1mA,,,,,,,, +,,127,PID PV2Plus Voltage,PID PV2PE Volt/ Flyspan voltage (MAX HV) Flyspan,0~1000V,0.1V,,,,,,,, +,,128,PID PV2Plus Current,PID PV2PE Curr,-10~10mA,0.1mA,,,,,,,, +,,129,PID PV3Plus Voltage,PID PV3PE Volt/ Flyspan voltage (MAX HV) ,0~1000V,0.1V,,,,,,,, +,,130,PID PV3Plus Current,PID PV3PE Curr,-10~10mA,0.1mA,,,,,,,, +,,131,PID PV4Plus Voltage,PID PV4PE Volt/ Flyspan voltage (MAX HV) ,0~1000V,0.1V,,,,,,,, +,,132,PID PV4Plus Current,PID PV4PE Curr,-10~10mA,0.1mA,,,,,,,, +,,133,PID PV5Plus Voltage,PID PV5PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,134,PID PV5Plus Current,PID PV5PE Curr,-10~10mA,0.1mA,,,,,,,, +,,135,PID PV6Plus Voltage,PID PV6PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,136,PID PV6Plus Current,PID PV6PE Curr,-10~10mA,0.1mA,,,,,,,, +,,137,PID PV7Plus Voltage,PID PV7PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,138,PID PV7Plus Current,PID PV7PE Curr,-10~10mA,0.1mA,,,,,,,, +,,139,PID PV8Plus Voltage,PID PV8PE Volt/ Flyspan voltage (MAX HV) ,0~1000V,0.1V,,,,,,,, +,,140,PID PV8Plus Current,PID PV8PE Curr,-10~10mA,0.1mA,,,,,,,, +,,141,PID Status,Bit0~7:PID Working Status 1:Wait Status 2:Normal Status 3:Fault Status Bit8~15:Reversed,0~3,,,,,,,,, +,,142,PV String1,PV String1 voltage,,0.1V,,,,,,,, +,,143,PV Curr_String1,PV String1 current,-15~15A,0.1A,,,,,,,, +,,144,PV_String2,PV String2 voltage,,0.1V,,,,,,,, +,,145,PV Curr_String2,PV String2 current,-15~15A,0.1A,,,,,,,, +,,146,PV_String3,PV String3 voltage,,0.1V,,,,,,,, +,,147,PV Curr_String3,PV String3 current,-15~15A,0.1A,,,,,,,, +,,148,PV_String4,PV String4 voltage,,0.1V,,,,,,,, +,,149,PV Curr_String4,PV String4 current,-15~15A,0.1A,,,,,,,, +,,150,PV_String5,PV String5 voltage,,0.1V,,,,,,,, +,,151,PV Curr_String5,PV String5 current,-15~15A,0.1A,,,,,,,, +,,152,PV_String6,PV String6 voltage,,0.1V,,,,,,,, +,,153,PV Curr_String6,PV String6 current,-15~15A,0.1A,,,,,,,, +,,154,PV_String7,PV String7 voltage,,0.1V,,,,,,,, +,,155,PV Curr_String7,PV String7 current,-15~15A,0.1A,,,,,,,, +,,156,PV_String8,PV String8 voltage,,0.1V,,,,,,,, +,,157,PV Curr_String8,PV String8 current,-15A~15A,0.1A,,,,,,,, +,,158,PV_String9,PV String9 voltage,,0.1V,,,,,,,, +,,159,PV Curr_String9,PV String9 current,-15A~15A,0.1A,,,,,,,, +,,160,PV_String10,PV String10 voltage,,0.1V,,,,,,,, +,,161,PV Curr_String10,PV String10 current,-15~15A,0.1A,,,,,,,, +,,162,PV_String11,PV String11 voltage,,0.1V,,,,,,,, +,,163,PV Curr_String11,PV String11 current,-15~15A,0.1A,,,,,,,, +,,164,PV_String12,PV String12 voltage,,0.1V,,,,,,,, +,,165,PV Curr_String12,PV String12 current,-15~15A,0.1A,,,,,,,, +,,166,PV_String13,PV String13 voltage,,0.1V,,,,,,,, +,,167,PV Curr_String13,PV String13 current,-15A~15A,0.1A,,,,,,,, +,,168,PV_String14,PV String14 voltage,,0.1V,,,,,,,, +,,169,PV Curr_String14,PV String14 current,-15~15A,0.1A,,,,,,,, +,,170,PV_String15,PV String15 voltage,,0.1V,,,,,,,, +,,171,PV Curr_String15,PV String15 current,-15~15A,0.1A,,,,,,,, +,,172,PV_String16,PV String16 voltage,,0.1V,,,,,,,, +,,173,PV Curr_String16,PV String16 current,-15~15A,0.1A,,,,,,,, +,,174,StrUnmatch,Bit0~15: String1~16 unmatch,,,,,suggestive,,,,, +,,175,StrCurrentUnblance,Bit0~15: String1~16 current unblance,,,,,suggestive,,,,, +,,176,StrDisconnect,Bit0~15: String1~16 disconnect,,,,,suggestive,,,,, +,,177,PIDFaultCode,Bit0:Output over voltage Bit1: ISO fault Bit2: BUS voltage abnormal Bit3~15:reserved,,,,,,,,,, +,,178,String Prompt,String Prompt Bit0:String Unmatch Bit1:StrDisconnect Bit2:StrCurrentUnblance Bit3~15:reserved,,,,,,,,,, +,,179,PV Warning Value,PV Warning Value,,,,,,,,,, +,,180,DSP075 Warning Value,DSP075 Warning Value,,,,,,,,,, +,,181,DSP075 Fault Value,DSP075 Fault Value,,,,,,,,,, +,,182,DSP067 Debug Data1,DSP067 Debug Data1,,,,,,,,,, +,,183,DSP067 Debug Data2,DSP067 Debug Data2,,,,,,,,,, +,,184,DSP067 Debug Data3,DSP067 Debug Data3,,,,,,,,,, +,,185,DSP067 Debug Data4,DSP067 Debug Data4,,,,,,,,,, +,,186,DSP067 Debug Data5,DSP067 Debug Data5,,,,,,,,,, +,,187,DSP067 Debug Data6,DSP067 Debug Data6,,,,,,,,,, +,,188,DSP067 Debug Data7,DSP067 Debug Data7,,,,,,,,,, +,,189,DSP067 Debug Data8,DSP067 Debug Data8,,,,,,,,,, +,,190,DSP075 Debug Data1,DSP075 Debug Data1,,,,,,,,,, +,,191,DSP075 Debug Data2,DSP075 Debug Data2,,,,,,,,,, +,,192,DSP075 Debug Data3,DSP075 Debug Data3,,,,,,,,,, +,,193,DSP075 Debug Data4,DSP075 Debug Data4,,,,,,,,,, +,,194,DSP075 Debug Data55,DSP075 Debug Data5,,,,,,,,,, +,,195,DSP075 Debug Data6,DSP075 Debug Data6,,,,,,,,,, +,,196,DSP075 Debug Data7,DSP075 Debug Data7,,,,,,,,,, +,,197,DSP075 Debug Data8,DSP075 Debug Data8,,,,,,,,,, +,,198,bUSBAgingTestOk Flag,USBAgingTestOkFlag,0-1,,,,,,,,, +,,199,bFlashEraseAging OkFlag,FlashEraseAgingOkFlag,0-1,,,,,,,,, +,,200,PVISO,PVISOValue,,K?,,,,,,,, +,,201,R_DCI,R DCI Curr,,0.1mA,,,,,,,, +,,202,S_DCI,S DCI Curr,,0.1mA,,,,,,,, +,,203,T_DCI,T DCI Curr,,0.1mA,,,,,,,, +,,204,PID_Bus,PIDBusVolt,,0.1V,,,,,,,, +,,205,GFCI,GFCI Curr,,mA,,,,,,,, +,,206,SVG_APF StatusPlusSVGAPFEqualRatio,SVG/APF StatusPlusSVGAPFEqualRatio,High 8 bit: SVGAPFEqua lRatio Low 8 bit: SVG/APF Status 0:None 1:SVG Run 2:APF Run 3:SVG/APF Run,,,,,,,,, +,,207,CT_I_R,R phase load side current for SVG,,0.1A,,,,,,,, +,,208,CT_I_S,S phase load side current for SVG,,0.1A,,,,,,,, +,,209,CT_I_T,T phase load side current for SVG,,0.1A,,,,,,,, +,,210,CT_Q_R H,R phase load side output reactive power for SVG(High),,0.1Var,,,,,,,, +,,211,CT_Q_R L,R phase load side output reactive power for SVG(low),,0.1Var,,,,,,,, +,,212,CT_Q_S H,S phase load side output reactive power for SVG(High),,0.1Var,,,,,,,, +,,213,CT_Q_S L,S phase load side output reactive power for SVG(low),,0.1Var,,,,,,,, +,,214,CT_Q_T H,T phase load side output reactive power for SVG(High),,0.1Var,,,,,,,, +,,215,CT_Q_T L,T phase load side output reactive power for SVG(low),,0.1Var,,,,,,,, +,,216,CT HAR_I_R,R phase load side harmonic,,0.1A,,,,,,,, +,,217,CT HAR_I_S,S phase load side harmonic,,0.1A,,,,,,,, +,,218,CT HAR_I_T,T phase load side harmonic,,0.1A,,,,,,,, +,,219,COMP_Q_R H,R phase compensate reactive power for SVG(High),,0.1Var,,,,,,,, +,,220,COMP_Q_R L,R phase compensate reactive power for SVG(low),,0.1Var,,,,,,,, +,,221,COMP_Q_S H,S phase compensate reactive power for SVG(High),,0.1Var,,,,,,,, +,,222,COMP_Q_S L,S phase compensate reactive power for SVG(low),,0.1Var,,,,,,,, +,,223,COMP_Q_T H,T phase compensate reactive power for SVG(High),,0.1Var,,,,,,,, +,,224,COMP_Q_T L,T phase compensate reactive power for SVG(low),,0.1Var,,,,,,,, +,,225,COMP HAR_I_R,R phase compensate harmonic for SVG,,0.1A,,,,,,,, +,,226,COMP HAR_I_S,S phase compensate harmonic for SVG,,0.1A,,,,,,,, +,,227,COMP HAR_I_T,T phase compensate harmonic for SVG,,0.1A,,,,,,,, +,,228,bRS232AgingTest OkFlag,RS232AgingTestOkFlag,0-1,,,,,,,,, +,,229,bFanFaultBit,,Bit0: Fan 1 fault bit Bit1: Fan 2 fault bit Bit2: Fan 3 fault bit Bit3: Fan 4 fault bit Bit4-7: Reserved,,,,,,,,, +,,230,Sac H,Output apparent power H,,0.1W,,,,,,,, +,,231,Sac L,Output apparent power L,,0.1W,,,,,,,, +,,232,ReActPowerH,Real Output Reactive Power H,Int32,0.1W,,,,,,,, +,,233,ReActPowerL,Real Output Reactive Power L,,,,,,,,,, +,,234,ReActPowerMaxH,Nominal Output Reactive Power H,,0.1var,,,,,,,, +,,235,ReActPowerMaxL,Nominal Output Reactive Power L,,,,,,,,,, +,,236,ReActPower_Total H,Reactive power generation,,0.1kwh,,,,,,,, +,,237,ReActPower_Total L,Reactive power generation,,,,,,,,,, +,,238,bAfciStatus,,0:Waiting 1:Self-check state 2:Detect pull arc state 3:Fault 4:Update,,,,,,,,, +,,239,uwPresentFFTValue_CHANNEL_A_,PresentFFTValue [CHANNEL_A],,,,,,,,,, +,,240,uwPresentFFTValue_CHANNEL_B_,PresentFFTValue [CHANNEL_B],,,,,,,,,, +,,241,DSP067 Debug Data1,DSP067 Debug Data1,,,,,,,,,, +,,242,DSP067 Debug Data2,DSP067 Debug Data2,,,,,,,,,, +,,243,DSP067 Debug,DSP067 Debug Data3,,,,,,,,,, +,,244,DSP067 Debug Data4,DSP067 Debug Data4,,,,,,,,,, +,,245,DSP067 Debug Data5,DSP067 Debug Data5,,,,,,,,,, +,,246,DSP067 Debug Data6,DSP067 Debug Data6,,,,,,,,,, +,,247,DSP067 Debug Data7,DSP067 Debug Data7,,,,,,,,,, +,,248,DSP067 Debug Data8,DSP067 Debug Data8,,,,,,,,,, +PV9 Voltage,,875,Vpv9,PV9 voltage,,0.1V,,,,,,,, +PV9 Current,,876,PV9Curr,PV9 Input current,,0.1A,,,,,,,, +PV9 Watts,,877,Ppv9 H,PV9 input power (High),,0.1W,,,,,,,, +,,878,Ppv9 L,PV9 input power (Low),,0.1W,,,,,,,, +PV10 Voltage,,879,Vpv10,PV10 voltage,,0.1V,,,,,,,, +PV10 Current,,880,PV10Curr,PV10 Input current,,0.1A,,,,,,,, +PV10 Watts,,881,Ppv10 H,PV10 input power (High),,0.1W,,,,,,,, +,,882,Ppv10 L,PV10 input power (Low),,0.1W,,,,,,,, +PV11 Voltage,,883,Vpv11,PV11 voltage,,0.1V,,,,,,,, +PV11 Current,,884,PV11Curr,PV11 Input current,,0.1A,,,,,,,, +PV11 Watts,,885,Ppv11 H,PV11 input power (High),,0.1W,,,,,,,, +,,886,Ppv11 L,PV11 input power (Low),,0.1W,,,,,,,, +PV12 Voltage,,887,Vpv12,PV12 voltage,,0.1V,,,,,,,, +PV12 Current,,888,PV12Curr,PV12 Input current,,0.1A,,,,,,,, +PV12 Watts,,889,Ppv12 H,PV12 input power (High),,0.1W,,,,,,,, +,,890,Ppv12 L,PV12 input power (Low),,0.1W,,,,,,,, +PV13 Voltage,,891,Vpv13,PV13 voltage,,0.1V,,,,,,,, +PV13 Current,,892,PV13Curr,PV13 Input current,,0.1A,,,,,,,, +PV13 Watts,,893,Ppv13H,PV13 input power (High),,0.1W,,,,,,,, +,,894,Ppv13 L,PV13 input power (Low),,0.1W,,,,,,,, +PV14 Voltage,,895,Vpv14,PV14 voltage,,0.1V,,,,,,,, +PV14 Current,,896,PV14Curr,PV14 Input current,,0.1A,,,,,,,, +PV14 Watts,,897,Ppv14 H,PV14 input power (High),,0.1W,,,,,,,, +,,898,Ppv14 L,PV14 input power (Low),,0.1W,,,,,,,, +PV15 Voltage,,899,Vpv15,PV15 voltage,,0.1V,,,,,,,, +PV15 Current,,900,PV15Curr,PV15 Input current,,0.1A,,,,,,,, +PV15 Watts,,901,Ppv15 H,PV15 input power (High),,0.1W,,,,,,,, +,,902,Ppv15 L,PV15 input power (Low),,0.1W,,,,,,,, +PV16 Voltage,,903,Vpv16,PV16 voltage,,0.1V,,,,,,,, +PV16 Current,,904,PV16Curr,PV16 Input current,,0.1A,,,,,,,, +PV16 Watts,,905,Ppv16 H,PV16 input power (High),,0.1W,,,,,,,, +,,906,Ppv16 L,PV16 input power (Low),,0.1W,,,,,,,, +PV9 KWH Today,,907,Epv9_today H,PV9 energy today (High),,0.1kWh,,,,,,,, +,,908,Epv9_today L,PV9 energy today (Low),,0.1kWh,,,,,,,, +PV9 KWH Total,,909,Epv9_total H,PV9 energy total (High),,0.1kWh,,,,,,,, +,,910,Epv9_total L,PV9 energy total (Low),,0.1kWh,,,,,,,, +PV10 KWH Today,,911,Epv10_today H,PV10 energy today (High),,0.1kWh,,,,,,,, +,,912,Epv10_today L,PV10 energy today (Low),,0.1kWh,,,,,,,, +PV10 KWH Total,,913,Epv10_total H,PV10 energy total (High),,0.1kWh,,,,,,,, +,,914,Epv10_total L,PV10 energy total (Low),,0.1kWh,,,,,,,, +PV11 KWH Today,,915,Epv11_today H,PV11 energy today (High),,0.1kWh,,,,,,,, +,,916,Epv11_today L,PV11 energy today (Low),,0.1kWh,,,,,,,, +PV11 KWH Total,,917,Epv11_total H,PV11 energy total (High),,0.1kWh,,,,,,,, +,,918,Epv11_total L,PV11 energy total (Low),,0.1kWh,,,,,,,, +PV12 KWH Today,,919,Epv12_today H,PV12 energy today (High),,0.1kWh,,,,,,,, +,,920,Epv12_today L,PV12 energy today (Low),,0.1kWh,,,,,,,, +PV12 KWH Total,,921,Epv12_total H,PV12 energy total (High),,0.1kWh,,,,,,,, +,,922,Epv12_total L,PV12 energy total (Low),,0.1kWh,,,,,,,, +PV13 KWH Today,,923,Epv13_today H,PV13 energy today (High),,0.1kWh,,,,,,,, +,,924,Epv13_today L,PV13 energy today (Low),,0.1kWh,,,,,,,, +PV13 KWH Total,,925,Epv13_total H,PV13 energy total (High),,0.1kWh,,,,,,,, +,,926,Epv13_total L,PV13 energy total (Low),,0.1kWh,,,,,,,, +PV14 KWH Today,,927,Epv14_today H,PV14 energy today (High),,0.1kWh,,,,,,,, +,,928,Epv14_today L,PV14 energy today (Low),,0.1kWh,,,,,,,, +PV14 KWH Total,,929,Epv14_total H,PV14 energy total (High),,0.1kWh,,,,,,,, +,,930,Epv14_total L,PV14 energy total (Low),,0.1kWh,,,,,,,, +PV15 KWH Today,,931,Epv15_today H,PV15 energy today (High),,0.1kWh,,,,,,,, +,,932,Epv15_today L,PV15 energy today (Low),,0.1kWh,,,,,,,, +PV15 KWH Total,,933,Epv15_total H,PV15 energy total (High),,0.1kWh,,,,,,,, +,,934,Epv15_total L,PV15 energy total (Low),,0.1kWh,,,,,,,, +PV16 KWH Today,,935,Epv16_today H,PV16 energy today (High),,0.1kWh,,,,,,,, +,,936,Epv16_today L,PV16 energy today (Low),,0.1kWh,,,,,,,, +PV16 KWH Total,,937,Epv16_total H,PV16 energy total (High),,0.1kWh,,,,,,,, +,,938,Epv16_total L,PV16 energy total (Low),,0.1kWh,,,,,,,, +,,939,PID PV9Plus Voltage,PID PV9PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,940,PID PV9Plus Current,PID PV9PE Current,-10~10mA,0.1mA,,,,,,,, +,,941,PID PV10Plus Voltage,PID PV10PE/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,942,PID PV10Plus Current,PID PV10PE Current,-10~10mA,0.1mA,,,,,,,, +,,943,PID PV11Plus Voltage,PID PV11PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,944,PID PV11Plus Current,PID PV11PE Current,-10~10mA,0.1mA,,,,,,,, +,,945,PID PV12Plus Voltage,PID PV12PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,946,PID PV12Plus Current,PID PV12PE Current,-10~10mA,0.1mA,,,,,,,, +,,947,PID PV13Plus Voltage,PID PV13PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,948,PID PV13Plus Current,PID PV13PE Current,-10~10mA,0.1mA,,,,,,,, +,,949,PID PV14Plus Voltage,PID PV14PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,950,PID PV14Plus Current,PID PV14PE Current,-10~10mA,0.1mA,,,,,,,, +,,951,PID PV15Plus Voltage,PID PV15PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,952,PID PV15Plus Current,PID PV15PE Current,-10~10mA,0.1mA,,,,,,,, +,,953,PID PV16Plus Voltage,PID PV16PE Volt/ Flyspan voltage (MAX HV),0~1000V,0.1V,,,,,,,, +,,954,PID PV16Plus Current,PID PV16PE Current,-10~10mA,0.1mA,,,,,,,, +,,955,PV_String17,PV String 17 voltage,,0.1V,,,,,,,, +,,956,PV Curr_String17,PV String 17 Current,-15~15A,0.1A,,,,,,,, +,,957,PV_String18,PV String 18 voltage,,0.1V,,,,,,,, +,,958,PV Curr_String18,PV String 18 Current,-15~15A,0.1A,,,,,,,, +,,959,PV_String19,PV String 19 voltage,,0.1V,,,,,,,, +,,960,PV Curr_String19,PV String 19 Current,-15~15A,0.1A,,,,,,,, +,,961,PV_String20,PV String 20 voltage,,0.1V,,,,,,,, +,,962,PV Curr_String20,PV String 20 Current,-15~15A,0.1A,,,,,,,, +,,963,PV_String21,PV String 21 voltage,,0.1V,,,,,,,, +,,964,PV Curr_String21,PV String 21 Current,-15~15A,0.1A,,,,,,,, +,,965,PV_String22,PV String22 voltage,,0.1V,,,,,,,, +,,966,PV Curr_String22,PV String 22 Current,-15~15A,0.1A,,,,,,,, +,,967,PV_String23,PV String 23 voltage,,0.1V,,,,,,,, +,,968,PV Curr_String23,PV String 23 Current,-15~15A,0.1A,,,,,,,, +,,969,PV_String24,PV String 24 voltage,,0.1V,,,,,,,, +,,970,PV Curr_String24,PV String 24 Current,-15A~15A,0.1A,,,,,,,, +,,971,PV_String25,PV String 25 voltage,,0.1V,,,,,,,, +,,972,PV Curr_String25,PV String 25 Current,-15A~15A,0.1A,,,,,,,, +,,973,PV_String26,PV String 26 voltage,,0.1V,,,,,,,, +,,974,PV Curr_String26,PV String 26 Current,-15~15A,0.1A,,,,,,,, +,,975,PV_String27,PV String 27 voltage,,0.1V,,,,,,,, +,,976,PV Curr_String27,PV String 27 Current,-15~15A,0.1A,,,,,,,, +,,977,PV_String28,PV String 28 voltage,,0.1V,,,,,,,, +,,978,PV Curr_String28,PV String 28 Current,-15~15A,0.1A,,,,,,,, +,,979,PV_String29,PV String 29 voltage,,0.1V,,,,,,,, +,,980,PV Curr_String29,PV String 29 Current,-15A~15A,0.1A,,,,,,,, +,,981,PV_String30,PV String 30 voltage,,0.1V,,,,,,,, +,,982,PV Curr_String30,PV String 30 Current,-15~15A,0.1A,,,,,,,, +,,983,PV_String31,PV String 31 voltage,,0.1V,,,,,,,, +,,984,PV Curr_String31,PV String 31 Current,-15~15A,0.1A,,,,,,,, +,,985,PV_String32,PV String 32 voltage,,0.1V,,,,,,,, +,,986,PV Curr_String32,PV String 32 Current,-15~15A,0.1A,,,,,,,, +,,987,StrUnmatch2,Bit0~15: String 17~32 unmatch,,,,,,,,,, +,,988,StrCurrentUnblance2,Bit0~15:String 17~32 current unblance,,,,,,,,,, +,,989,StrDisconnect2,Bit0~15: String 17~32 disconnect,,,,,,,,,, +,,990,PV Warning Value,PV Warning Value (PV9-PV16) Contains PV9~16 abnormal , ? Boost9~16 Drive anomalies,,,,,,,,, +,,991,StrWaringvalue1,string1~string16 abnormal,,,,,,,,,, +,,992,StrWaringvalue2,string17~string32 abnormal,,,,,,,,,, +,,999,SystemCmd,M3 to DSP system command,,,,,system command,,,,, +,,1000,uwSysWorkMode,System work mode,0x00:waiting module 0x01: Self-test mode optional 0x02 : Reserved 0x03:SysFault module 0x04: Flash module 0x05 0x06 0x07 0x08,,,, 0x03:fault module 0x04:flash,,,,, +,,1001,Systemfault word0,System fault word0,,,,,,,,,, +,,1002,Systemfault word1,System fault word1,,,,,,,,,, +,,1003,Systemfault word2,System fault word2,,,,,,,,,, +,,1004,Systemfault word3,System fault word3,,,,,,,,,, +,,1005,Systemfault word4,System fault word4,,,,,,,,,, +,,1006,Systemfault word5,System fault word5,,,,,,,,,, +,,1007,Systemfault word6,System fault word6,,,,,,,,,, +,,1008,Systemfault word7,System fault word7,,,,,,,,,, +,,1009,Pdischarge1 H,Discharge power(high),,0.1W,,,,,,,, +,,1010,Pdischarge1 L,Discharge power (low),,0.1W,,,,,,,, +,,1011,Pcharge1 H,Charge power(high),,0.1W,,,,,,,, +,,1012,Pcharge1 L,Charge power (low),,0.1W,,,,,,,, +,,1013,Vbat,Battery voltage,,0.1V,,,,,,,, +,,1014,SOC,State of charge Capacity,0-100,1.00%,lith/leadacid,,,,,,, +,,1015,Pactouser R H,AC power to user H,,0.1w,,,,,,,, +,,1016,Pactouser R L,AC power to user L,,0.1w,,,,,,,, +,,1017,Pactouser S H,Pactouser S H,,0.1w,,,,,,,, +,,1018,Pactouser S L,Pactouser S L,,0.1w,,,,,,,, +,,1019,Pactouser T H,Pactouser T H,,0.1w,,,,,,,, +,,1020,Pactouser T L,Pactouser T L,,0.1w,,,,,,,, +,,1021,PactouserTotal H,AC power to user total H,,0.1w,,,,,,,, +,,1022,PactouserTotal L,AC power to user total L,,0.1w,,,,,,,, +,,1023,Pac to grid R H,AC power to grid H,,0.1w,Ac,,output,,,,, +,,1024,Pac to grid R L,AC power to grid L,,0.1w,,,,,,,, +,,1025,Pactogrid S H,,,0.1w,,,,,,,, +,,1026,Pactogrid S L,,,0.1w,,,,,,,, +,,1027,Pactogrid T H,,,0.1w,,,,,,,, +,,1028,Pactogrid T L,,,0.1w,,,,,,,, +,,1029,Pactogrid total H,AC power to grid total H,,0.1w,,,,,,,, +,,1030,Pactogrid total L,AC power to grid total L,,0.1w,,,,,,,, +,,1031,PLocalLoad R H,INV power to local load H,,0.1w,,,,,,,, +,,1032,PLocalLoad R L,INV power to local load L,,0.1w,,,,,,,, +,,1033,PLocalLoad S H,,,0.1w,,,,,,,, +,,1034,PLocalLoad S L,,,0.1w,,,,,,,, +,,1035,PLocalLoadT H,,,0.1w,,,,,,,, +,,1036,PLocalLoadT L,,,0.1w,,,,,,,, +,,1037,PLocalLoad total H,INV power to local load total H,,0.1w,,,,,,,, +,,1038,PLocalLoad total L,INV power to local load total L,,0.1w,,,,,,,, +,,1039,IPM Temperature,REC Temperature,,0.1?,No use,,,,,,, +,,1040,Battery Temperature,Battery Temperature,,0.1?,Lead acid/lithium battery temp,,,,,,, +,,1041,SP DSP Status,SP state,,,CHG/DisCHG,,,,,,, +,,1042,SP Bus Volt,SP BUS2 Volt,,0.1V,,,,,,,, +,,1044,Etouser_today H,Energy to user today high,,0.1kWh,,,,,,,, +,,1045,Etouser_today L,Energy to user today low,,0.1kWh,,,,,,,, +,,1046,Etouser_total H,Energy to user total high,,0.1kWh,,,,,,,, +,,1047,Etouser_total L,Energy to user total high,,0.1kWh,,,,,,,, +,,1048,Etogrid_today H,Energy to grid today high,,0.1kWh,,,,,,,, +,,1049,Etogrid_today L,Energy to grid today low,,0.1kWh,,,,,,,, +,,1050,Etogrid_total H,Energy to grid total high,,0.1kWh,,,,,,,, +,,1051,Etogrid_ total L,Energy to grid total high,,0.1kWh,,,,,,,, +,,1052,Edischarge1_today H,Discharge energy1 today,,0.1kWh,,,,,,,, +,,1053,Edischarge1_today L,Discharge energy1 today,,0.1kWh,,,,,,,, +,,1054,Edischarge1_total H,Total discharge energy1 (high),,0.1kWh,,,,,,,, +,,1055,Edischarge1_total L,Total discharge energy1 (low),,0.1kWh,,,,,,,, +,,1056,Echarge1_today H ,Charge1 energy today,,0.1kWh,,,,,,,, +,,1057,Echarge1_today L,Charge1 energy today,,0.1kWh,,,,,,,, +,,1058,Echarge1_total H,Charge1 energy total,,0.1kWh,,,,,,,, +,,1059,Echarge1_total L,Charge1 energy total,,0.1kWh,,,,,,,, +,,1060,ElocalLoad_Today H,Local load energy today,,0.1kWh,,,,,,,, +,,1061,ElocalLoad_Today L,Local load energy today,,0.1kWh,,,,,,,, +,,1062,ElocalLoad_Total H,Local load energy total,,0.1kWh,,,,,,,, +,,1063,ElocalLoad_Total L,Local load energy total,,0.1kWh,,,,,,,, +,,1064,dwExportLimitApparentPower ,ExportLimitApparentPower H,,0.1kWh,ApparentPower,,,,,,, +,,1065,dwExportLimitApparentPower ,ExportLimitApparentPower L,,0.1kWh,ApparentPower,,,,,,, +,,1067,EPS Fac,UPSfrequency,5000/6000,0.01Hz,,,,,,,, +,,1068,EPS Vac1 ,UPS phase R output voltage,2300,0.1V,,,,,,,, +,,1069,EPS Iac1 ,UPS phase R output current,,0.1A,,,,,,,, +,,1070,EPS Pac1 H ,UPS phase R output power (H),,0.1VA,,,,,,,, +,,1071,EPS Pac1 L ,UPS phase R output power (L),,0.1VA,,,,,,,, +,,1072,EPS Vac2 ,UPS phase S output voltage,,0.1V,,,,,,,, +,,1073,EPS Iac2 ,UPS phase S output current,,0.1A,No use,,,,,,, +,,1074,EPS Pac2 H ,UPS phase S output power (H),,0.1VA,,,,,,,, +,,1075,EPS Pac2 L ,UPS phase S output power (L),,0.1VA,,,,,,,, +,,1076,EPS Vac3 ,UPS phase T output voltage,,0.1V,,,,,,,, +,,1077,EPS Iac3 ,UPS phase T output current,,0.1A,No use,,,,,,, +,,1078,EPS Pac3 H ,UPS phase T output power (H),,0.1VA,,,,,,,, +,,1079,EPS Pac3 L ,UPS phase T output power (L),,0.1VA,,,,,,,, +,,1080,Loadpercent ,Load percent of UPS ouput,0-100,1.00%,,,,,,,, +,,1081,PF ,Power factor,0-2,0.1,Primary ValuePlus1,,,,,,, +,,1082,BMS_StatusOld,StatusOld from BMS,"Detail information, refer to document:GrowattxxSxx P ESS Protocol;",,,,,,,,, +,,1083,BMS_Status,Status from BMS,,,W/R,,,,,,, +,,1084,BMS_ErrorOld,Error info Old from BMS,,,,,,,,,, +,,1085,BMS_Error,Errorinfomation from BMS,,,,,,,,,, +,,1086,BMS_SOC,SOC from BMS,,,R SPH6K,,,,,,, +,,1087,BMS_BatteryVolt,Battery voltage from BMS,,,R SPH6K,,,,,,, +,,1088,BMS_BatteryCurr,Battery current from BMS,,,,,,,,,, +,,1089,BMS_BatteryTemp,Battery temperature from BMS,,,,,,,,,, +,,1090,BMS_MaxCurr,,,,,,,,,,, +,,1091,BMS_GaugeRM,Gauge RM from BMS,,,,,,,,,, +,,1092,BMS_GaugeFCC,Gauge FCC from BMS,,,,,,,,,, +,,1093,BMS_FW,,,,,,,,,,, +,,1094,BMS_DeltaVolt,Delta V from BMS,,,,,,,,,, +,,1095,BMS_CycleCnt,Cycle Count from BMS,,,,,,,,,, +,,1096,BMS_SOH,SOH from BMS,,,,,,,,,, +,,1097,BMS_ConstantVolt,CV voltage from BMS,,,,,,,,,, +,,1098,BMS_WarnInfoOld,Warning info old from BMS,,,,,,,,,, +,,1099,BMS_WarnInfo,Warning info from BMS,,,,,,,,,, +,,1100,BMS_GaugeICCurr,Gauge IC current from BMS,,,,,,,,,, +,,1101,BMS_MCUVersion,MCU Software version from BMS,,,,,,,,,, +,,1102,BMS_GaugeVersion,Gauge Version from BMS,,,,,,,,,, +,,1103,BMS_wGaugeFR Version_L,Gauge FR Version L16 from BMS,,,,,,,,,, +,,1104,BMS_wGaugeFR Version_H,Gauge FR Version H16 from BMS,,,,,,,,,, +,,1105,BMS_BMSInfo,BMSInformation from BMS,,,,,,,,,, +,,1106,BMS_PackInfo,Pack Information from BMS,,,,,,,,,, +,,1107,BMS_UsingCap,Using Cap from BMS,,,,,,,,,, +,,1108,uwMaxCellVolt,Maximum single battery voltage,,0.001V,,,,,,,, +,,1109,uwMinCellVolt,Lowest single battery voltage,,0.001V,,,,,,,, +,,1110,bModuleNum,Battery parallel number,,1,,,,,,,, +,,1112,uwMaxVoltCellNo,MaxVoltCellNo,,1,,,,,,,, +,,1113,uwMinVoltCellNo,MinVoltCellNo,,1,,,,,,,, +,,1114,uwMaxTemprCell_10T,MaxTemprCell_10T,,0.1C,,,,,,,, +,,1115,uwMinTemprCell_10T,MinTemprCell_10T,,0.1C,,,,,,,, +,,1116,uwMaxTemprCellNo,MaxVoltTemprCellNo,,1,,,,,,,, +,,1117,uwMinTemprCelllNo,MinVoltTemprCellNo,,1,,,,,,,, +,,1118,Protect pack ID,Faulty Battery Address,,1,,,,,,,, +,,1119,MaxSOC,Parallel maximum SOC,,1.00%,,,,,,,, +,,1120,MinSOC,Parallel minimum SOC,,1.00%,,,,,,,, +,,1121,BMS_Error2,Battery Protection 2,,0,CAN ID : 0x323 Byte4~5,,,,,,, +,,1122,BMS_Error3,Battery Protection3,,0,CAN ID : 0x323 Byte6,,,,,,, +,,1123,BMS_WarnInfo2,Battery Warn2,,0,CAN ID : 0x323 Byte7,,,,,,, +,,1124,AC Charge Energy Today H,AC Charge Energy today,kwh,,Energy today,,,,,,, +,,1125,ACCharge Energy Today L,AC Charge Energy today,kwh,,,,,,,,, +,,1126,AC Charge Energy Total H,,,,Energy total,,,,,,, +,,1127,ACCharge Energy Total L,,,,,,,,,,, +,,1128,AC Charge Power H,AC Charge Power,W,,,,,,,,, +,,1129,AC Charge Power L,AC Charge Power,w,,,,,,,,, +,,1130,70Percent INV Power adjust,uwGridPower_70_AdjEE_SP,W,,,,,,,,, +,,1131,Extra AC Power to grid_H,Extra inverte AC Power to grid High,For SPA connect inverter,,SPA used,,,,,,, +,,1132,Extra AC Power to grid_L,Extrainverte AC Power to grid Low,,,SPA used,,,,,,, +,,1133,Eextra_today H,Extra inverter PowerTOUser_Extra today (high),R,0.1kWh,SPA used,,,,,,, +,,1134,Eextra_today L,Extra inverter PowerTOUser_Extra today (low),R,0.1kWh,SPA used,,,,,,, +,,1135,Eextra_total H,Extra inverter PowerTOUser_Extra total(high),,0.1kWh,SPA used,,,,,,, +,,1136,Eextra_total L,Extra inverter PowerTOUser_Extra total(low),,0.1kWh,SPA used,,,,,,, +,,1137,Esystem_today H,System electric energy today H,,0.1kWh,SPA used System electric energy today H,,,,,,, +,,1138,Esystem_today L,System electric energy today L,,0.1kWh,SPA used System electric energy today L,,,,,,, +,,1139,Esystem_total H,System electric energy total H,,0.1kWh,SPA used System electric energy total H,,,,,,, +,,1140,Esystem_total L,System electric energy total L,,0.1kWh,SPA used System electric energy total L,,,,,,, +,,1141,Eself_today H,self electric energy today H,,0.1kWh,self electric energy today H,,,,,,, +,,1142,Eself_today L,self electric energy today L,,0.1kWh,self electric energy today L,,,,,,, +,,1143,Eself_total H,self electric energy total H,,0.1kWh,self electric energy total H,,,,,,, +,,1144,Eself_total L,self electric energy total L,,0.1kWh,self electric energy total L,,,,,,, +,,1145,PSystem H,System power H,,0.1w,System power H,,,,,,, +,,1146,PSystem L,System power L,,0.1w,System power L,,,,,,, +,,1147,PSelf H,self power H,,0.1w,self power H,,,,,,, +,,1148,PSelf L,self power L,,0.1w,self power L,,,,,,, +,,1149,EPVAll_Today H,PV electric energy today H,,,,,,,,,, +,,1150,EPVAll_Today L,PV electric energy today L,,,,,,,,,, +,,1151,AcDischarge PackSn,Discharge Number power,R,,,,,,,,, +,,1152,Accdischarge power_H,Cumulative discharge power high 16-bit byte,R,0.1 kWH,,,,,,,, +,,1153,Accdischarge power_L,Cumulative discharge power low 16-bit byte,R,0.1 kWH,,,,,,,, +,,1154,AccCharge PackSn,charge power pack serial number,R,,,,,,,,, +,,1155,AccCharge power_H,Cumulative charge power high 16-bit byte,R,0.1 kWH,,,,,,,, +,,1156,AccCharge power_L,Cumulative charge power low 16-bit byte,R,0.1 kWH,,,,,,,, +,,1157,FirstBattFaultSn,FirstBattFaultSn,R,,,,,,,,, +,,1158,Second BattFaultSn,Second BattFaultSn,R,,,,,,,,, +,,1159,Third BattFaultSn,Third BattFaultSn,R,,,,,,,,, +,,1160,Fourth BattFaultSn,Fourth BattFaultSn,R,,,,,,,,, +,,1161,Battery history fault code 1,Battery history fault code 1,R,,,,,,,,, +,,1162,Battery history fault code 2,Battery history fault code 2,R,,,,,,,,, +,,1163,Battery history fault code 3,Battery history fault code 3,R,,,,,,,,, +,,1164,Battery history fault code 4,Battery history fault code 4,R,,,,,,,,, +,,1165,Battery history fault code 5,Battery history fault code 5,R,,,,,,,,, +,,1166,Battery history fault code 6,Battery history fault code 6,R,,,,,,,,, +,,1167,Battery history fault code 7,Battery history fault code 7,R,,,,,,,,, +,,1168,Battery history fault code 8,Battery history fault code 8,R,,,,,,,,, +,,1169,Number of battery codes,Number of battery codes PACK number Plus BIC forward and reverse codes,R,,,,,,,,, +,,1199,NewEPowerCalc Flag,Intelligent reading is used to identify software compatibility features,0 : Old energy calculation, 1 : new energy calculation,,,,,,,, +,,1200,MaxCellVolt,Maximum cell voltage,R,0.001V,,,,,,,, +,,1201,MinCellVolt,Minimum cell voltage,R,0.001V,,,,,,,, +,,1202,ModuleNum,Number of Battery modules,R,/,,,,,,,, +,,1203,TotalCellNum,Total number of cells,R,/,,,,,,,, +,,1204,MaxVoltCellNo,MaxVoltCellNo,R,/,,,,,,,, +,,1205,MinVoltCellNo,MinVoltCellNo,R,/,,,,,,,, +,,1206,MaxTemprCell_10T,MaxTemprCell_10T,R,0.1?,,,,,,,, +,,1207,MinTemprCell_10T,MinTemprCell_10T,R,0.1?,,,,,,,, +,,1208,MaxTemprCellNo,MaxTemprCellNo,R,/,,,,,,,, +,,1209,MinTemprCellNo,MinTemprCellNo,R,/,,,,,,,, +,,1210,ProtectPackID,Fault Pack ID,R,/,,,,,,,, +,,1211,MaxSOC,Parallel maximum SOC,R,1.00%,,,,,,,, +,,1212,MinSOC,Parallel minimum SOC,R,1.00%,,,,,,,, +,,1213,BatProtect1Add,BatProtect1Add,R,/,,,,,,,, +,,1214,BatProtect2Add,BatProtect2Add,R,/,,,,,,,, +,,1215,BatWarn1Add,BatWarn1Add,R,/,,,,,,,, +,,1216,BMS_HighestSoftVersion,BMS_HighestSoftVersion,R,/,,,,,,,, +,,1217,BMS_HardwareVersion,BMS_HardwareVersion,R,/,,,,,,,, +,,1218,BMS_RequestType,BMS_RequestType,R,/,,,,,,,, +,,1248,bKeyAgingTestOkFlag,Success sign of key detection before aging,1:Finished test 0 : test not completed,,,,,,,,, +,,2000,Inverter Status,Inverter run state,0:waiting 1:normal 3:fault,,,,,,,,, +Output Watts,,2035,Pac H,Output power (high),,0.1W,,,SPA,,,,, +,,2036,Pac L,Output power (low),,0.1W,,,SPA,,,,, +Grid Hz,,2037,Fac,Grid frequency,,0.01Hz,,,SPA,,,,, +Grid Voltage Phase 1,,2038,Vac1,Three/single phase grid voltage,,0.1V,,,SPA,,,,, +Grid Current Phase 1,,2039,Iac1,Three/single phase grid output current,,0.1A,,,SPA,,,,, +Grid VA Phase 1,,2040,Pac1 H,Three/single phase grid output watt VA (high),,0.1VA,,,SPA,,,,, +,,2041,Pac1 L,Three/single phase grid output watt VA(low),,0.1VA,,,SPA,,,,, +,,2053,Eac today H,Today generate energy (high),,0.1kWH,,,SPA,,,,, +,,2054,Eac today L,Today generate energy (low),,0.1kWH,,,SPA,,,,, +,,2055,Eac total H,Total generate energy (high),,0.1kWH,,,SPA,,,,, +,,2056,Eac total L,Total generate energy (low),,0.1kWH,,,SPA,,,,, +,,2057,Time total H,Work time total (high),,0.5s,,,SPA,,,,, +,,2058,Time total L,Work time total (low),,0.5s,,,SPA,,,,, +,,2093,Temp1,Inverter temperature,,0.1C,,,SPA,,,,, +,,2094,Temp2,The inside IPM in inverter Temperature,,0.1C,,,SPA,,,,, +,,2095,Temp3,Boost temperature,,0.1C,,,SPA,,,,, +,,2096,Temp4,,,,,,reserved,,,,, +,,2097,uwBatVolt_DSP,BatVolt_DSP,,0.1V,,,BatVolt(DSP),,,,, +,,2098,P Bus Voltage,P Bus inside Voltage,,0.1V,,,SPA,,,,, +,,2099,N Bus Voltage,N Bus inside Voltage,,0.1V,,,SPA,,,,, +,,2100,RemoteCtrlEn,/,0.Load First 1.BatFirst 2.Grid,/,,,Remote setup enable,,,,, +,,2101,RemoteCtrlPower,,,/,/,,Remotely set power,,,,, +,,2102,Extra AC Power to grid_H,Extra inverte AC Power to grid High,For SPA connect inverter,,,,SPA used,,,,, +,,2103,Extra AC Power to grid_L,Extrainverte AC Power to grid Low,,,,,SPA used,,,,, +,,2104,Eextra_today H,Extra inverter PowerTOUser_Extra today (high),R,0.1kWh,,,SPA,,,,, +,,2105,Eextra_today L,Extra inverter PowerTOUser_Extra today (low),R,0.1kWh,,,SPA,,,,, +,,2106,Eextra_total H,Extra inverter PowerTOUser_Extratotal(high),,0.1kWh,,,SPA,,,,, +,,2107,Eextra_total L,Extra inverter PowerTOUser_Extra total(low),,0.1kWh,,,SPA,,,,, +,,2108,Esystem_today H,System electric energy today H,,0.1kWh,,,SPA used System electric energy today H,,,,, +,,2109,Esystem_today L,System electric energy today L,,0.1kWh,,,SPA used System electric energy today L,,,,, +,,2110,Esystem_total H,System electric energy total H,,0.1kWh,,,SPA used System,,,,, +,,2111,Esystem_total L,System electric energy total L,,0.1kWh,,,SPA used System electric energy total L,,,,, +,,2112,EACharge_Today_H,ACCharge energy today,,0.1kwh,,,Storage Power,,,,, +,,2113,EACharge_Today_L,ACCharge energy today,,0.1kwh,,,Storage Power,,,,, +,,2114,EACharge_Total_H,ACCharge energy total,,0.1kwh,,,Storage Power,,,,, +,,2115,EACharge_Total_L,ACCharge energy total,,0.1kwh,,,Storage Power,,,,, +,,2116,AC charge Power_H,Grid power to local load,,0.1kwh,,,Storage Power,,,,, +,,2117,AC charge Power_L,Grid power to local load,,0.1kwh,,,Storage Power,,,,, +,,2118,Priority,0:Load First 1:Battery First 2:Grid First,,,,,Storage Power,,,,, +,,2119,Battery Type,0:Lead-acid 1:Lithium battery,,,,,Storage Power,,,,, +,,2120,AutoProofreadCMD,Aging mode,,,,,Storage Power,,,,, +,,3000,Inverter Status,Inverter run state High 8 bits mode (specific mode) ,0: Waiting module 1: Self-test mode 7:PVOfflineMode 8:BatOfflineMode The lower 8 bits indicate the machine status (web page display) 0: StandbyStatus, 1: NormalStatus, 3: FaultStatus 4:FlashStatus,,,,,,, +PV Watts,,3001,Ppv H,PV total power H,,0.1W,,,,,,,, +,,3002,Ppv L,PV total power L,,,,,,,,,, +PV1 Voltage,,3003,Vpv1,PV1 voltage,,0.1V,,,,,,,, +,,3004,Ipv1,PV1 input current,,0.1A,,,,,,,, +PV1 Watts,,3005,Ppv1 H,PV1 power H,,0.1W,,,,,,,, +,,3006,Ppv1 L,PV1 power L,,,,,,,,,, +PV2 Voltage,,3007,Vpv2,PV2 voltage,,0.1V,,,,,,,, +,,3008,Ipv2,PV2 input current,,0.1A,,,,,,,, +PV2 Watts,,3009,Ppv2 H,PV2 power H,,0.1W,,,,,,,, +,,3010,Ppv2 L,PV2 power L,,,,,,,,,, +PV3 Voltage,,3011,Vpv3,PV3 voltage,,0.1V,,,,,,,, +,,3012,Ipv3,PV3 input current,,0.1A,,,,,,,, +PV3 Watts,,3013,Ppv3 H,PV3 power H,,0.1W,,,,,,,, +,,3014,Ppv3 L,PV3 power L,,,,,,,,,, +PV4 Voltage,,3015,Vpv4,PV4 voltage,,,,,,,,,, +,,3016,Ipv4,PV4 input current,,,,,,,,,, +PV4 Watts,,3017,Ppv4 H,PV4 power H,,,,,,,,,, +,,3018,Ppv4 L,PV4 power L,,,,,,,,,, +,,3019,Psys H,System output power H,,0.1W,,,,,,,, +,,3020,Psys L,System output power L,,,,,,,,,, +,,3021,Qac H,reactive power H,,0.1Var,,,,,,,, +,,3022,Qac L,reactive power L,,,,,,,,,, +Output Watts,,3023,Pac H,Output power H,,0.1W,,,,,,,, +,,3024,Pac L,Output power L,,,,,,,,,, +Grid Hz,,3025,Fac,Grid frequency,,0.01Hz,,,,,,,, +Grid Voltage Phase 1,,3026,Vac1,Three/single phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 1,,3027,Iac1,Three/single phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 1,,3028,Pac1 H,Three/single phase grid output watt VA H,,0.1VA,,,,,,,, +,,3029,Pac1 L,Three/single phase grid output watt VA L,,,,,,,,,, +Grid Voltage Phase 2,,3030,Vac2,Three phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 2,,3031,Iac2,Three phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 2,,3032,Pac2 H,Three phase grid output power H,,0.1VA,,,,,,,, +,,3033,Pac2 L,Three phase grid output power L,,,,,,,,,, +Grid Voltage Phase 3,,3034,Vac3,Three phase grid voltage,,0.1V,,,,,,,, +Grid Current Phase 3,,3035,Iac3,Three phase grid output current,,0.1A,,,,,,,, +Grid VA Phase 3,,3036,Pac3 H,Three phase grid output power H,,0.1VA,,,,,,,, +,,3037,Pac3 L,Three phase grid output power L,,,,,,,,,, +,,3038,Vac_RS,Three phase grid voltage,,0.1V,,,,,,,, +,,3039,Vac_ST,Three phase grid voltage,,0.1V,,,,,,,, +,,3040,Vac_TR,Three phase grid voltage,,0.1V,,,,,,,, +,,3041,Ptouser total H,Total forward power H,,0.1W,,,,,,,, +,,3042,Ptouser total L,Total forward power L,,,,,,,,,, +,,3043,Ptogrid total H,Total reverse power H,,0.1W,,,,,,,, +,,3044,Ptogrid total L,Total reverse power L,,,,,,,,,, +,,3045,Ptoload total H,Total load power H,,0.1W,,,,,,,, +,,3046,Ptoload total L,Total load power L,,,,,,,,,, +,,3047,Time total H,Work time total H,,0.5s,,,,,,,, +,,3048,Time total L,Work time total L,,,,,,,,,, +,,3049,Eac today H,Today generate energy H,,0.1kWh,,,,,,,, +,,3050,Eac today L,Today generate energy L,,,,,,,,,, +,,3051,Eac total H,Total generate energy H,,0.1kWh,,,,,,,, +,,3052,Eac total L,Total generate energy L,,,,,,,,,, +PV KWH Total,,3053,Epv_total H,PV energy total H,,0.1kWh,,,,,,,, +,,3054,Epv_total L,PV energy total L,,,,,,,,,, +PV1 KWH Today,,3055,Epv1_today H,PV1 energy today H,,0.1kWh,,,,,,,, +,,3056,Epv1_today L,PV1 energy today L,,,,,,,,,, +PV1 KWH Total,,3057,Epv1_total H,PV1 energy total H,,0.1kWh,,,,,,,, +,,3058,Epv1_total L,PV1 energy total L,,,,,,,,,, +PV2 KWH Today,,3059,Epv2_today H,PV2 energy today H,,0.1kWh,,,,,,,, +,,3060,Epv2_today L,PV2 energy today L,,,,,,,,,, +PV2 KWH Total,,3061,Epv2_total H,PV2 energy total H,,0.1kWh,,,,,,,, +,,3062,Epv2_total L,PV2 energy total L,,,,,,,,,, +PV3 KWH Today,,3063,Epv3_today H,PV3 energy today H,,0.1kWh,,,,,,,, +,,3064,Epv3_today L,PV3 energy today L,,,,,,,,,, +PV3 KWH Total,,3065,Epv3_total H,PV3 energy total H,,0.1kWh,,,,,,,, +,,3066,Epv3_total L,PV3 energy total L,,,,,,,,,, +,,3067,Etouser_today H,Today energy to user H,,0.1kWh,,,,,,,, +,,3068,Etouser_today L,Today energy to user L,,,,,,,,,, +,,3069,Etouser_total H,Total energy to user H,,0.1kWh,,,,,,,, +,,3070,Etouser_total L,Total energy to user L,,,,,,,,,, +,,3071,Etogrid_today H,Today energy to grid H,,0.1kWh,,,,,,,, +,,3072,Etogrid_today L,Today energy to grid L,,,,,,,,,, +,,3073,Etogrid_total H,Total energy to grid H,,0.1kWh,,,,,,,, +,,3074,Etogrid_total L,Total energy to grid L,,,,,,,,,, +,,3075,Eload_today H,Today energy of user load H,,0.1kWh,,,,,,,, +,,3076,Eload_today L,Today energy of user load L,,,,,,,,,, +,,3077,Eload_total H,Total energy of user load H,,0.1kWh,,,,,,,, +,,3078,Eload_total L,Total energy of user load L,,,,,,,,,, +PV4 KWH Today,,3079,Epv4_today H,PV4 energy today H,,0.1kWh,,,,,,,, +,,3080,Epv4_today L,PV4 energy today L,,,,,,,,,, +PV4 KWH Total,,3081,Epv4_total H,PV4 energy total H,,0.1kWh,,,,,,,, +,,3082,Epv4_total L,PV4 energy total L,,,,,,,,,, +,,3083,Epv_today H,PV energy today H,,0.1kWh,,,,,,,, +,,3084,Epv_today L,PV energy today L,,,,,,,,,, +,,3086,DeratingMode,DeratingMode,,,,,,,,,, +,,3087,ISO,PV ISO value,,1K?,,,,,,,, +,,3088,DCI_R,R DCI Curr,,0.1mA,,,,,,,, +,,3089,DCI_S,S DCI Curr,,0.1mA,,,,,,,, +,,3090,DCI_T,T DCI Curr,,0.1mA,,,,,,,, +,,3091,GFCI,GFCI Curr,,1mA,,,,,,,, +,,3092,Bus Voltage,total bus voltage,,0.1V,,,,,,,, +,,3093,Temp1,Inverter temperature,,0.1?,,,,,,,, +,,3094,Temp2,The inside IPM in inverter temperature,,0.1?,,,,,,,, +,,3095,Temp3,Boost temperature,,0.1?,,,,,,,, +,,3096,Temp4,Reserved,,0.1?,,,,,,,, +,,3097,Temp5,Commmunication broad temperature,,0.1?,,,,,,,, +,,3098,P Bus Voltage,P Bus inside Voltage,,0.1V,,,,,,,, +,,3099,N Bus Voltage,N Bus inside Voltage,,0.1V,,,,,,,, +Inverter Power Factor,,3100,IPF,Inverter output PF now,,,,,,,,,, +,,3101,RealOPPercent,Real Output power Percent,,1.00%,,,,,,,, +,,3102,OPFullwatt H,Output Maxpower Limited H,,0.1W,,,,,,,, +,,3103,OPFullwatt L,Output Maxpower Limited L,,,,,,,,,, +,,3104,StandbyFlag,Inverter standby flag,,bitfield,,,,,,,, +,,3105,Fault Maincode,Inverter fault maincode,,,,,,,,,, +,,3106,Warn Maincode,Inverter Warning maincode,,,,,,,,,, +,,3107,Fault Subcode,Inverter fault subcode,,bitfield,,,,,,,, +,,3108,Warn Subcode,Inverter Warning subcode,,bitfield,,,,,,,, +,,3111,uwPresentFFTValue_CHANNEL_A_,PresentFFTValue [CHANNEL_A],,bitfield,,,,,,,, +,,3112,bAfciStatus,AFCI Status,,,,,,,,,, +,,3113,uwStrength_CHANNEL_A_,AFCI Strength[CHANNEL_A],,,,,,,,,, +,,3114,uwSelfCheckValue_CHANNEL_A_,AFCI SelfCheck[CHANNEL_A],,,,,,,,,, +,,3115,inv start delay time,inv start delay time,,1S,,,,,,,, +,,3116,Reserved,,,,,,,,,,, +,,3117,Reserved,,,,,,,,,,, +,,3118,BDC_OnOffState,BDC connect state,,,,,,,,,, +,,3119,DryContactState,Current status of DryContact,,,,,,,,,, +,,3120,Reserved,,,,,,,,,,, +,,3121,Pself H,self-use power H,,0.1W,,,,,,,, +,,3122,Pself L,self-use power L,,,,,,,,,, +,,3123,Esys_today H,System energy today H,,0.1kwh,,,,,,,, +,,3124,Esys_today L,System energy today L ,,,,,,,,,, +,,3125,Edischr_today H,Today discharge energy H,,0.1kWh,,,,,,,, +,,3126,Edischr_today L,Today discharge energy L,,,,,,,,,, +,,3127,Edischr_total H,Total discharge energy H,,0.1kWh,,,,,,,, +,,3128,Edischr_total L,Total discharge energy L,,,,,,,,,, +,,3129,Echr_today H,Charge energy today H,,0.1kWh,,,,,,,, +,,3130,Echr_today L,Charge energy today L,,,,,,,,,, +,,3131,Echr_total H,Charge energy total H,,0.1kWh,,,,,,,, +,,3132,Echr_total L,Charge energy total L,,,,,,,,,, +,,3133,Eacchr_today H,Today energy of AC charge H,,0.1kWh,,,,,,,, +,,3134,Eacchr_today L,Today energy of AC charge L,,,,,,,,,, +,,3135,Eacchr_total H,Total energy of AC charge H,,0.1kWh,,,,,,,, +,,3136,Eacchr_total L,Total energy of AC charge L,,,,,,,,,, +,,3137,Esys_total H,Total energy of system output H,,,,,,,,,, +,,3138,Esys_total L,Total energy of system output L,,0.1kWh,,,,,,,, +,,3139,Eself_today H,Today energy of Self output H,,0.1kWh,,,,,,,, +,,3140,Eself_today L,Today energy of Self output L,,,,,,,,,, +,,3141,Eself_total H,Total energy of Self output H,,0.1kwh,,,,,,,, +,,3142,Eself_total L,Total energy of Self output L,,,,,,,,,, +,,3143,Reserved,,,,,,,,,,, +,,3144,Priority,Word Mode,,,,,,,,,, +,,3145,EPS Fac,UPS frequency,,0.01Hz,,,,,,,, +,,3146,EPS Vac1,UPS phase R output voltage,,0.1V,,,,,,,, +,,3147,EPS Iac1,UPS phase R output current,,0.1A,,,,,,,, +,,3148,EPS Pac1 H,UPS phase R output power H,,0.1VA,,,,,,,, +,,3149,EPS Pac1 L,UPS phase R output power L,,,,,,,,,, +,,3150,EPS Vac2,UPS phase S output voltage,,0.1V,,,,,,,, +,,3151,EPS Iac2,UPS phase S output current,,0.1A,,,,,,,, +,,3152,EPS Pac2 H,UPS phase S output power H,,0.1VA,,,,,,,, +,,3153,EPS Pac2 L,UPS phase S output power L,,,,,,,,,, +,,3154,EPS Vac3,UPS phase T output voltage,,0.1V,,,,,,,, +,,3155,EPS Iac3,UPS phase T output current,,0.1A,,,,,,,, +,,3156,EPS Pac3 H,UPS phase T output power H,,0.1VA,,,,,,,, +,,3157,EPS Pac3 L,UPS phase T output power L,,,,,,,,,, +,,3158,EPS Pac H,UPS output power H,,0.1VA,,,,,,,, +,,3159,EPS Pac L,UPS output power L,,,,,,,,,, +,,3160,Loadpercent,Load percent of UPS ouput,,0.10%,,,,,,,, +,,3161,PF,Power factor,,0.1,,,,,,,, +,,3162,DCV,DC voltage,,1mV,,,,,,,, +,,3163,Reserved,,,,,,,,,,, +,,3164,NewBdcFlag,Whether to parse BDC data separately,,,,,,,,,, +,,3165,BDCDeratingMode,BDCDeratingMode: 0: Normal unrestricted 1:Standby or fault 2:Maximum battery current limit (discharge) 3:Battery discharge Enable (Discharge) 4:High bus discharge derating (discharge) 5:High temperature discharge derating (discharge) 6:System warning No discharge (discharge) 7-15 Reserved (Discharge) 16:Maximum charging current of battery (charging) 17:High Temperature (LLC and Buckboost) (Charging) 18:Final soft charge 19:SOC setting limits (charging) 20:Battery low temperature (charging) 21:High bus voltage (charging) 22:Battery SOC (charging) 23: Need to charge (charge) 24: System warning not charging (charging) 25-29:Reserve (charge),,,,,,,,,, +,,3166,SysState_Mode,System work State and mode The upper 8 bits indicate the mode, 0:No charge and discharge, 1:charge, 2:Discharge,, 0: StandbyStatus,,,,, +,,3167,FaultCode,Storge device fault code,,,,,,,,,, +,,3168,WarnCode,Storge device warning code,,,,,,,,,, +,,3169,Vbat,Battery voltage,,,,,,,,,, +,,3170,Ibat,Battery current,,,,,,,,,, +,,3171,SOC,State of charge Capacity,,,,,,,,,, +,,3172,Vbus1,Total BUS voltage,,,,,,,,,, +,,3173,Vbus2,On the BUS voltage,,,,,,,,,, +,,3174,Ibb,BUCK-BOOST Current,,,,,,,,,, +,,3175,Illc,LLC Current,,,,,,,,,, +,,3176,TempA,Temperture A,,,,,,,,,, +,,3177,TempB,Temperture B,,,,,,,,,, +,,3178,Pdischr H,Discharge power H,,,,,,,,,, +,,3179,Pdischr L,Discharge power L,,,,Pdischr L,,Pdischr L,Pdischr L,Pdischr L,Pdischr L,Pdischr L +,,3180,Pchr H,Charge power H,,0.1W,,,,,,,, +,,3181,Pchr L,Charge power L,,,,,,,,,, +,,3182,Edischr_total H,Discharge total energy of storge device H,,,,,,,,,, +,,3183,Edischr_total L,Discharge total energy of storge device L,,,,Edischr_total L,,Edischr_total L,Edischr_total L,Edischr_total L,Edischr_total L,Edischr_total L +,,3184,Echr_total H,Charge total energy of storge device H,,,,,,,,,, +,,3185,Echr_total L,Charge total energy of storge device L,,,,,,,,,, +,,3186,Reserved,Reserved,,,,,,,,,, +,,3187,BDC1_Flag,"BDC mark (charge and discharge, fault alarm code) Bit0: ChargeEn; BDC allows charging Bit1: DischargeEn; BDC allows discharge Bit2~7: Resvd; reserved Bit8~11: WarnSubCode; BDC sub-warning code Bit12~15: FaultSubCode; BDC sub-error code",,,,,,,,,, +,,3188,Vbus2,Lower BUS voltage,,,,,,,,,, +,,3189,BmsMaxVoltCellNo,BmsMaxVoltCellNo,,,,,,,,,, +,,3190,BmsMinVoltCellNo,BmsMinVoltCellNo,,,,,,,,,, +,,3191,BmsBatteryAvgTemp,BmsBatteryAvgTemp,,,,,,,,,, +,,3192,BmsMaxCellTemp,BmsMaxCellTemp,,0.1?C,,,,,,,, +,,3193,BmsBatteryAvgTemp,BmsBatteryAvgTemp,,0.1?C,,,,,,,, +,,3194,BmsMaxCellTemp,BmsMaxCellTemp,,,,,,,,,, +,,3195,BmsBatteryAvgTemp,BmsBatteryAvgTemp,,,,,,,,,, +,,3196,BmsMaxSOC,BmsMaxSOC,,1.00%,,,,,,,, +,,3197,BmsMinSOC,BmsMinSOC,,1.00%,,,,,,,, +,,3198,ParallelBatteryNum,ParallelBatteryNum,,,,,,,,,, +,,3199,BmsDerateReason,BmsDerateReason,,,,,,,,,, +,,3200,BmsGaugeFCC_Ah,BmsGaugeFCC(Ah),,,,,,,,,, +,,3201,BmsGaugeRM_Ah,BmsGaugeRM(Ah),,,,,,,,,, +,,3202,BmsError,BMS Protect1,,,,,,,,,, +,,3203,BmsWarn,BMSWarn1,,,,,,,,,, +,,3204,BmsFault,BMS Fault1,,,,,,,,,, +,,3205,BmsFault2,BMS Fault2,,,,,,,,,, +,,3210,BatIsoStatus,Battery ISO detection status,,,,,,,,,, +,,3211,BattNeedCharge RequestFlag,battery work request,,"bit0:1: Prohibit chargin g 2 bit8:1: Dischar ge is prohibit ed, 0: allow discharg e bit9:1: Turn on power reductio n 0: turn off power reductio n;",0: Allow the chargin g bit1:1: Enable strong charge,,,,,,, +,,3212,BMS_Status,battery working status,R,,,,,,,,, +,,3213,BmsError2,BMS Protect2,R,1,,,,,,,, +,,3214,BmsWarn2,BMS Warn2,R,1,,,,,,,, +,,3215,BMS_SOC,BMS SOC,R,1.00%,,,,,,,, +,,3216,BMS_BatteryVolt,BMS BatteryVolt,R,0.01V,,,,,,,, +,,3217,BMS_BatteryCurr,BMS BatteryCurr,R,0.01A,,,,,,,, +,,3218,BMS_BatteryTemp,battery cell maximum temperature,R,0.1?,,,,,,,, +,,3219,BMS_MaxCurr,Maximum charging current,R,0.01A,,,,,,,, +,,3220,BMS_MaxDischrCurr,Maximum discharge current,R,0.01A,,,,,,,, +,,3221,BMS_CycleCnt,BMSCycleCnt,R,1,,,,,,,, +,,3222,BMS_SOH,BMS SOH,R,1,,,,,,,, +,,3223,BMS_ChargeVoltLimit,Battery charging voltage limit value,R,0.01V,,,,,,,, +,,3224,BMS_DischargeVoltLimit,Battery discharge voltage limit value,,,,,,,,,, +,,3225,Bms Warn3,BMS Warn 3,R,1,,,,,,,, +,,3226,Bms Error3,BMS Protect3,R,1,,,,,,,, +,,3227,Reserved,,,,,,,,,,, +,,3228,Reserved,,,,,,,,,,, +,,3229,Reserved,,,,,,,,,,, +,,3230,BMSSingleVoltMax,BMS Battery SingleVoltMax,R,0.001V,,,,,,,, +,,3231,BMSSingleVoltMin,BMS Battery SingleVoltMin,R,0.001V,,,,,,,, +,,3232,BatLoadVolt,Battery LoadVolt,R,0.01V,,,650.00],,,,, +,,3234,Debug data1,Debug data1,R,,,,,,,,, +,,3235,Debug data2,Debug data2,R,,,,,,,,, +,,3236,Debug data3,Debug data3,R,,,,,,,,, +,,3237,Debug data4,Debug data4,R,,,,,,,,, +,,3238,Debug data5,Debug data5,R,,,,,,,,, +,,3239,Debug data6,Debug data6,R,,,,,,,,, +,,3240,Debug data7,Debug data7,R,,,,,,,,, +,,3241,Debug data8,Debug data8,R,,,,,,,,, +,,3242,Debug data9,Debug data9,R,,,,,,,,, +,,3243,Debug data10,Debug data10,R,,,,,,,,, +,,3244,Debug data10,Debug data10,R,,,,,,,,, +,,3245,Debug data12,Debug data12,R,,,,,,,,, +,,3246,Debug data13,Debug data13,R,,,,,,,,, +,,3247,Debug data14,Debug data14,R,,,,,,,,, +,,3248,Debug data15,Debug data15,R,,,,,,,,, +,,3249,Debug data16,Debug data16,R,,,,,,,,, +,,3250,Pex1H,PV inverter 1 output power H,R,0.1W,,,,,,,, +,,3251,Pex1L,PV inverter 1 output power L,R,0.1W,,,,,,,, +,,3252,Pex2H,PV inverter 2 output power H,R,0.1W,,,,,,,, +,,3253,Pex2L,PV inverter 2 output power L,R,0.1W,,,,,,,, +,,3254,Eex1TodayH,PV inverter 1 energy Today H,R,0.1kWh,,,,,,,, +,,3255,Eex1TodayL,PV inverter 1 energy Today L,R,0.1kWh,,,,,,,, +,,3256,Eex2TodayH,PV inverter 2 energy Today H,R,0.1kWh,,,,,,,, +,,3257,Eex2TodayL,PV inverter 2 energy Today L,R,0.1kWh,,,,,,,, +,,3258,Eex1TotalH,PV inverter 1 energy Total H,R,0.1kWh,,,,,,,, +,,3259,Eex1TotalL,PV inverter 1 energy Total L,R,0.1kWh,,,,,,,, +,,3260,Eex2TotalH,PV inverter 2 energy Total H,R,0.1kWh,,,,,,,, +,,3261,Eex2TotalL,PV inverter 2 energy Total L,R,0.1kWh,,,,,,,, +,,3262,uwBatNo,battery pack number,R,,,,,,,,, +,,3263,BatSerialNum1,Battery pack serial numberSN[0]SN[1],R,,,,,,,,, +,,3264,BatSerialNum2,Battery pack serial numberSN[2]SN[3],,,,,,,,,, +,,3265,BatSerialNum3,Battery pack serial numberSN[4]SN[5],,,,,,,,,, +,,3266,BatSerialNum4,Battery pack serial numberSN[6]SN[7],,,,,,,,,, +,,3267,BatSerialNum5,Battery pack serial numberSN[8]SN[9],,,,,,,,,, +,,3268,BatSerialNum6,Battery pack serial numberSN[10]SN[11],,,,,,,,,, +,,3269,BatSerialNum7,Battery pack serial numberSN[12]SN[13],,,,,,,,,, +,,3270,BatSerialNum8,Battery pack serial numberSN[14]SN[15],,,,,,,,,, +,,3280,bClrTodayDataFlag,Clear day data flag,R,,,,,,,,, From bc45b8cb1e28f5e8726bdea29536af510f0eed9c Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:46:24 -0500 Subject: [PATCH 09/53] ; to , --- .../growatt/v0.14.holding_registry_map.csv | 184 +++++++++--------- .../growatt/v0.14.input_registry_map.csv | 180 ++++++++--------- 2 files changed, 182 insertions(+), 182 deletions(-) diff --git a/protocols/growatt/v0.14.holding_registry_map.csv b/protocols/growatt/v0.14.holding_registry_map.csv index 6661066..2ff7288 100644 --- a/protocols/growatt/v0.14.holding_registry_map.csv +++ b/protocols/growatt/v0.14.holding_registry_map.csv @@ -1,92 +1,92 @@ -variable name;data type;register;documented name;description;writable;values;unit;initial value;note;;; -;1bit;0;On_Off low;;;standby on, standby off;;;;;; -;1bit;0.b8;On_Off high;"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0). ";;0x0000: Output enable 0x0100: Output disable;;;;;0; -;;1;OutputConfig;AC output set;W;"{""0"": ""BAT First"", ""1"": ""PV First"", ""2"": ""UTI First"", ""3"": ""PV&UTI First""}";; 2: UTI First; 3: PV&UTI First;;;0 -;;2;ChargeConfig;Charge source set;W;"{""0"": ""PV first"", ""1"": ""PV&UTI"", ""2"": ""PV Only""}";; 2: PV Only;;;;0 -;;3;UtiOutStart;Uti Output Start Time;W;0-23;;H(hour);0;;; -;;4;UtiOutEnd;Uti Output End Time;W;0-23;;H(hour);0;;; -;;5;UtiChargeStart;Uti Charge Start Time;W;0-23;;H(hour);0;;; -;;6;UtiChargeEnd;Uti Charge End Time;W;0-23;;H(hour);0;;; -PV Input Mode;;7;PVModel;PV Input Mode;W;"{""0"": ""Independent"", ""1"": ""Parallel""}";;;;;0; -AC Input Mode;;8;ACInModel;AC Input Mode;W;"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC"", ""2"": ""GEN""}";;;0;;; -;ASCII;r9~11;Fw version;Firmware version (high);;;;ASCII;;;; -;ASCII;r12~14;Fw version2;Control Firmware version (high);;;;ASCII;;;; -;;15;LCD language;LCD language;W;{{lcd_language_codes}};1;English;;;; -;;16;GridV_Adj;;;;;;;;; -;;17;InvV_Adj;;;;;;;;; -;;18;OutputVoltType;Output Volt Type;W;"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC"", ""3"": ""220VAC"", ""4"": ""100VAC"", ""5"": ""110VAC"", ""6"": ""120VAC""}";;1;;;; -;;19;OutputFreqType;Output Freq Type;W;"{""0"": ""50Hz"", ""1"": ""60Hz""}";;0;;;; -;;20;OverLoadRestart;Over Load Restart;W;"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}";;0;Yes(over 1mins restart; Load to after over Load three times to stop output); ; -;;21;OverTempRestart;Over Temperature Restart;W;"{""0"": ""Yes"", ""1"": ""No""}";;0;Yes(over Temperature to restart ; after over Temperature three times to stop output) ;; -;;22;BuzzerEN;Buzzer on/off enable;W;"{""1"": ""Enable"", ""0"": ""Disable""}";;;1;;; -Serial Number;ASCII;23-27;Serial No;Serial number 5;WD;[A-Z0-9];;;;;; -;;28;Moudle H;Inverter Moudle (high);W;;;Can be set at standy state Only ;;;; -;;29;Moudle L;Inverter Moudle (low);W;P-battery type: 0: Lead_Acid 1: Lithium 2: CustomLead_Acid U-user type: ;;Can be set at;;;; -;;30;Com Address;Communicate address;W;1~254;;;1;;; -;;31;FlashStart;Update firmware;WD;0x0001: own 0X0100: control broad;;;;;; -;;32;Reset User Info;Reset User Information;WD;0x0001;;;;;; -;;33;Reset to factory;Reset to factory;WD;0x0001;;;;;; -;;34;MaxChargeCurr;Max Charge Current;W;0~180;1A;;70;;; -;;35;BulkChargeVolt;Bulk Charge Volt;W;500~640;0.1V;;564;;; -;;36;FloatChargeVolt;Float Charge Volt;W;500~560;0.1V;;540;;; -;;37;BatLowToUtiVolt;Bat Low Volt Switch To Uti;W;200~640 (non Lithium) or 5~100 (Lithium);0.1V Or 1%;;460 Or 50%;;; -;;38;ACChargeCurr;AC Charge Current;W;0~100;1A;;30;;; -;;39;Battery Type;Battery Type;W;"{""0"": ""AGM"", ""1"": ""FLD"", ""2"": ""USE"", ""3"": ""Lithium"", ""4"": ""USE2""}";;;1;Can be set at standy Only ;; -;;40;Aging Mode;Aging Mode;W;"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}";;;;;0;Can be set at standy state Only -;1bit;41;Etl check enable;;W;"{""1"": ""Enable"", ""0"": ""Disable""}";;;;0:Disable; 1:Enable; -;1bit;41.b1;Pv ISO Check enable;;W;"{""1"": ""Enable"", ""0"": ""Disable""}";;;;;; -;;42;Safety Type;;W;"{""1"": ""standard"", ""2"": ""ETL"", ""3"": ""AS4777"", ""4"": ""CQC"", ""5"": ""VDE4105""}";1;;;;; -;;43;DTC;Device Type Code;&*6;;;;;;; -System Year;;45;Sys Year;System time-year;W;Year offset is 2000;;;;;; -System Month;;46;Sys Month;System time- Month;W;;;;;;; -System Day;;47;Sys Day;System time- Day;W;;;;;;; -System Hour;;48;Sys Hour;System time- Hour;W;;;;;;; -System Minute;;49;Sys Min;System time- Min;W;;;;;;; -System Second;;50;Sys Sec;System time- Second;W;;;;;;; -;;52;uwAcVoltHighL;;;;;;;;; -;;53;uwAcVoltLowL;;;;;;;;; -;;54;uwAcFreqHighL;;;;;;;;; -;;55;uwAcFreqLowL;;;;;;;;; -;ASCII;59-66;Manufacturer Info;Manufacturer information (high);;ASCII;;;;;; -;;67;FW Build No_ 4;Control FW Build No. 2;;;;;;;; -;;68;FW Build No_ 3;Control FW Build No. 1;;;;;;;; -;;69;FW Build No_ 2;COM FW Build No. 2;;;;;;;; -;;70;FW Build No_ 1;COM FW Build No. 1;;;;;;;; -;;72;Sys Weekly;Sys Weekly;W;0-6;;;;;; -;;73;ModbusVersion;Modbus Version;;Eg:207 is V2.07 Int(16bit s);0.01;;;;; -;;75;SCC_ComMode;SCC Communication;;;;For;BMS;;; -;;76;Rate Watt H;Rate active power(high);;;0.1W;;;;; -;;77;Rate Watt L;Rate active power(low);;;0.1W;;;;; -;;78;Rate VA H;Rata apparent power (high);;;0.1VA;;;;; -;;79;Rate VA L;Rate apparent power (low);;;0.1VA;;;;; -;;80;ComboardVer;Communicaiton board Version;;;;For boad;bms;;; -;;81;uwBatPieceNum;;;;;;;;; -;;82;wBatLowCutOff;Bat voltage low cutoff;;200~640 (non Lithium) or 5~100 (Lithium);0.1V Or 1%;460 Or 50%;;;; -;;84;NomGridVolt;;;;;;;;; -;;85;NomGridFreq;;;;;;;;; -;;86;NomBatVolt;;;;;;;;; -;;87;NomPvCurr;;;;;;;;; -;;88;NomAcChgCurr;;;;;;;;; -;;89;NomOpVolt;;;;;;;;; -;;90;NomOpFreq;;;;;;;;; -;;91;NomOpPow;;;;;;;;; -;;95;uwAC2BatVolt;AC switch to Battery;;200~640 (non Lithium) or 5~100 (Lithium);0.1V Or 1%;460 Or 50%;;;; -;;96;BypEnable;;;;;;;;; -;;97;PowSavingEn;;;;;;;;; -;;98;SpowBalEn;;;;;;;;; -;;99;ClrEnergyToday;;;;;;;;; -;;100;clrEnergyAll;;;;;;;;; -;;101;BurnInTestEn;;;;;;;;; -;;102;ManualStartEn;;;;;;;;; -;;103;SciLossChkEn;;;;;;;;; -;;104;BlightEn;;;;;;;;; -;;105;ParaMaxChgCurr;Parallel Maximum current;;;;;;;; -;;106;LiProtocolType;Protocol battery;;for;;1~99;;1;; -;;107;AudioAlarmEn;;;;;;;;; -;;108;uwEqEn;;;;;;;;; -;;109;uwEqChgVolt;;;;;;;;; -;;110;uwEqTime;;;;;;;;; -;;111;uwEqTimeOut;;;;;;;;; -;;112;uwEqInterval;;;;;;;;; -;;113;uwMaxDisChgCu rr;;;;;;;;; -;;162;BLVersion2;Boot loader version2;;;R;;;;M3 bootloader version; +variable name,data type,register,documented name,description,writable,values,unit,initial value,note,,, +,1bit,0,On_Off low,,,"standby on, standby off",,,,,, +,1bit,0.b8,On_Off high,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0). ",,0x0000: Output enable 0x0100: Output disable,,,,,0, +,,1,OutputConfig,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"", ""2"": ""UTI First"", ""3"": ""PV&UTI First""}",, 2: UTI First, 3: PV&UTI First,,,0 +,,2,ChargeConfig,Charge source set,W,"{""0"": ""PV first"", ""1"": ""PV&UTI"", ""2"": ""PV Only""}",, 2: PV Only,,,,0 +,,3,UtiOutStart,Uti Output Start Time,W,0-23,,H(hour),0,,, +,,4,UtiOutEnd,Uti Output End Time,W,0-23,,H(hour),0,,, +,,5,UtiChargeStart,Uti Charge Start Time,W,0-23,,H(hour),0,,, +,,6,UtiChargeEnd,Uti Charge End Time,W,0-23,,H(hour),0,,, +PV Input Mode,,7,PVModel,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,,0, +AC Input Mode,,8,ACInModel,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC"", ""2"": ""GEN""}",,,0,,, +,ASCII,r9~11,Fw version,Firmware version (high),,,,ASCII,,,, +,ASCII,r12~14,Fw version2,Control Firmware version (high),,,,ASCII,,,, +,,15,LCD language,LCD language,W,{{lcd_language_codes}},1,English,,,, +,,16,GridV_Adj,,,,,,,,, +,,17,InvV_Adj,,,,,,,,, +,,18,OutputVoltType,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC"", ""3"": ""220VAC"", ""4"": ""100VAC"", ""5"": ""110VAC"", ""6"": ""120VAC""}",,1,,,, +,,19,OutputFreqType,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,0,,,, +,,20,OverLoadRestart,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",,0,Yes(over 1mins restart, Load to after over Load three times to stop output), , +,,21,OverTempRestart,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,0,Yes(over Temperature to restart , after over Temperature three times to stop output) ,, +,,22,BuzzerEN,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,1,,, +Serial Number,ASCII,23-27,Serial No,Serial number 5,WD,[A-Z0-9],,,,,, +,,28,Moudle H,Inverter Moudle (high),W,,,Can be set at standy state Only ,,,, +,,29,Moudle L,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid 1: Lithium 2: CustomLead_Acid U-user type: ,,Can be set at,,,, +,,30,Com Address,Communicate address,W,1~254,,,1,,, +,,31,FlashStart,Update firmware,WD,0x0001: own 0X0100: control broad,,,,,, +,,32,Reset User Info,Reset User Information,WD,0x0001,,,,,, +,,33,Reset to factory,Reset to factory,WD,0x0001,,,,,, +,,34,MaxChargeCurr,Max Charge Current,W,0~180,1A,,70,,, +,,35,BulkChargeVolt,Bulk Charge Volt,W,500~640,0.1V,,564,,, +,,36,FloatChargeVolt,Float Charge Volt,W,500~560,0.1V,,540,,, +,,37,BatLowToUtiVolt,Bat Low Volt Switch To Uti,W,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,,460 Or 50%,,, +,,38,ACChargeCurr,AC Charge Current,W,0~100,1A,,30,,, +,,39,Battery Type,Battery Type,W,"{""0"": ""AGM"", ""1"": ""FLD"", ""2"": ""USE"", ""3"": ""Lithium"", ""4"": ""USE2""}",,,1,Can be set at standy Only ,, +,,40,Aging Mode,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,,0,Can be set at standy state Only +,1bit,41,Etl check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,0:Disable, 1:Enable, +,1bit,41.b1,Pv ISO Check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,,, +,,42,Safety Type,,W,"{""1"": ""standard"", ""2"": ""ETL"", ""3"": ""AS4777"", ""4"": ""CQC"", ""5"": ""VDE4105""}",1,,,,, +,,43,DTC,Device Type Code,&*6,,,,,,, +System Year,,45,Sys Year,System time-year,W,Year offset is 2000,,,,,, +System Month,,46,Sys Month,System time- Month,W,,,,,,, +System Day,,47,Sys Day,System time- Day,W,,,,,,, +System Hour,,48,Sys Hour,System time- Hour,W,,,,,,, +System Minute,,49,Sys Min,System time- Min,W,,,,,,, +System Second,,50,Sys Sec,System time- Second,W,,,,,,, +,,52,uwAcVoltHighL,,,,,,,,, +,,53,uwAcVoltLowL,,,,,,,,, +,,54,uwAcFreqHighL,,,,,,,,, +,,55,uwAcFreqLowL,,,,,,,,, +,ASCII,59-66,Manufacturer Info,Manufacturer information (high),,ASCII,,,,,, +,,67,FW Build No_ 4,Control FW Build No. 2,,,,,,,, +,,68,FW Build No_ 3,Control FW Build No. 1,,,,,,,, +,,69,FW Build No_ 2,COM FW Build No. 2,,,,,,,, +,,70,FW Build No_ 1,COM FW Build No. 1,,,,,,,, +,,72,Sys Weekly,Sys Weekly,W,0-6,,,,,, +,,73,ModbusVersion,Modbus Version,,Eg:207 is V2.07 Int(16bit s),0.01,,,,, +,,75,SCC_ComMode,SCC Communication,,,,For,BMS,,, +,,76,Rate Watt H,Rate active power(high),,,0.1W,,,,, +,,77,Rate Watt L,Rate active power(low),,,0.1W,,,,, +,,78,Rate VA H,Rata apparent power (high),,,0.1VA,,,,, +,,79,Rate VA L,Rate apparent power (low),,,0.1VA,,,,, +,,80,ComboardVer,Communicaiton board Version,,,,For boad,bms,,, +,,81,uwBatPieceNum,,,,,,,,, +,,82,wBatLowCutOff,Bat voltage low cutoff,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, +,,84,NomGridVolt,,,,,,,,, +,,85,NomGridFreq,,,,,,,,, +,,86,NomBatVolt,,,,,,,,, +,,87,NomPvCurr,,,,,,,,, +,,88,NomAcChgCurr,,,,,,,,, +,,89,NomOpVolt,,,,,,,,, +,,90,NomOpFreq,,,,,,,,, +,,91,NomOpPow,,,,,,,,, +,,95,uwAC2BatVolt,AC switch to Battery,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, +,,96,BypEnable,,,,,,,,, +,,97,PowSavingEn,,,,,,,,, +,,98,SpowBalEn,,,,,,,,, +,,99,ClrEnergyToday,,,,,,,,, +,,100,clrEnergyAll,,,,,,,,, +,,101,BurnInTestEn,,,,,,,,, +,,102,ManualStartEn,,,,,,,,, +,,103,SciLossChkEn,,,,,,,,, +,,104,BlightEn,,,,,,,,, +,,105,ParaMaxChgCurr,Parallel Maximum current,,,,,,,, +,,106,LiProtocolType,Protocol battery,,for,,1~99,,1,, +,,107,AudioAlarmEn,,,,,,,,, +,,108,uwEqEn,,,,,,,,, +,,109,uwEqChgVolt,,,,,,,,, +,,110,uwEqTime,,,,,,,,, +,,111,uwEqTimeOut,,,,,,,,, +,,112,uwEqInterval,,,,,,,,, +,,113,uwMaxDisChgCu rr,,,,,,,,, +,,162,BLVersion2,Boot loader version2,,,R,,,,M3 bootloader version, diff --git a/protocols/growatt/v0.14.input_registry_map.csv b/protocols/growatt/v0.14.input_registry_map.csv index fc293e2..024a20a 100644 --- a/protocols/growatt/v0.14.input_registry_map.csv +++ b/protocols/growatt/v0.14.input_registry_map.csv @@ -1,90 +1,90 @@ -variable name;data type;register;documented name;description;values;unit;note;;;;;;;;;; -;;0;System Status;System run state;{{system_status_codes}};1; PV an Grid Combine Discharge2: Discharge;3: Fault;4: Flash;5: PV charge;6: AC charge;7: Combine charge;8: Combine charge and Bypass;9: PV charge and Bypass;10: AC charge and Bypass; 11: Bypass;12: PV charge andDischarge -PV1 Voltage;;1;Vpv1;PV1 voltage;;0.1V;;;;;;;;;;; -PV2 Voltage;;2;Vpv2;PV2 voltage;;0.1V;;;;;;;;;;; -PV1 Watts;;3;Ppv1 H;PV1 charge power (high);;0.1W;;;;;;;;;;; -;;4;Ppv1 L;PV1 charge power (low);;0.1W;;;;;;;;;;; -PV2 Watts;;5;Ppv2 H;PV2 charge power (high);;0.1W;;;;;;;;;;; -;;6;Ppv2 L;PV2 charge power (low);;0.1W;;;;;;;;;;; -Buck1 Current;;7;Buck1Curr;Buck1 current;;0.1A;;;;;;;;;;; -Buck2 Current;;8;Buck2Curr;Buck2 current;;0.1A;;;;;;;;;;; -Output Wattage;;9;OP_Watt H;Output active power (high);;0.1W;;;;;;;;;;; -;;10;OP_Watt L;Output active power (low);;0.1W;;;;;;;;;;; -Output VA;;11;OP_VA H;Output apparent power (high);;0.1VA;;;;;;;;;;; -;;12;OP_VA L;Output apparent power (low);;0.1VA;;;;;;;;;;; -AC Charge Watts;;13;ACChr_Watt H;AC charge watt (high);;0.1W;;;;;;;;;;; -;;14;ACChr_Watt L;AC charge watt (low);;0.1W;;;;;;;;;;; -AC Charge VA;;15;ACChr_VA H;AC charge apparent power (high);;0.1VA;;;;;;;;;;; -;;16;ACChr_VA L;AC charge apparent power (low);;0.1VA;;;;;;;;;;; -Battery Voltage;;17;Bat Volt;Battery volt (M3);;0.01V;;;;;;;;;;; -Battery SOC;;18;BatterySOC;Battery SOC;0~100;1.00%;;;;;;;;;;; -Bus Voltage;;19;Bus Volt;Bus Voltage;;0.1V;;;;;;;;;;; -Grid Voltage;;20;Grid Volt;AC input Volt;;0.1V;;;;;;;;;;; -Grid Hz;;21;Line Freq;AC input frequency;;0.01Hz;;;;;;;;;;; -Output Voltage;16bit;22.b0;OutputVolt;AC output Volt;;0.1V;;;;;;;;;;; -Output Hz;;23;OutputFreq;AC output frequency;;0.01Hz;;;;;;;;;;; -Output DCV;;24;Ouput DCV;Ouput DC Volt;;0.1V;;;;;;;;;;; -;;25;InvTemp;Inv Temperature;;0.1C;;;;;;;;;;; -;;26;DcDc Temp;DC-DC Temperature;;0.1C;;;;;;;;;;; -Load Percentage;;27;LoadPercent;Load Percent;0~1000;0.10%;;;;;;;;;;; -Battery Port Voltage;;28;Bat_s_Volt;Battery-port volt (DSP);;0.01V;;;;;;;;;;; -Battery Bus Voltage;;29;Bat_Volt_DSP;Battery-bus volt (DSP);;0.01V;;;;;;;;;;; -;;30;Time total H;Work time total (high);;0.5S;;;;;;;;;;; -;;31;Time total L;Work time total (low);;0.5S;;;;;;;;;;; -Buck1 Temperature;;32;Buck1_NTC;Buck1 Temperature;;0.1C;;;;;;;;;;; -Buck2 Temperature;;33;Buck2_NTC;Buck2 Temperature;;0.1C;;;;;;;;;;; -Output Current;;34;OP_Curr;Output Current;;0.1A;;;;;;;;;;; -Inverter Current;;35;Inv_Curr;Inv Current;;0.1A;;;;;;;;;;; -AC Input Watts;;36;AC_InWatt H;AC input watt (high);;0.1W;;;;;;;;;;; -;;37;AC_InWatt L;AC input watt (low);;0.1W;;;;;;;;;;; -AC Input VA;;38;AC_InVA H;AC input apparent power (high);;0.1VA;;;;;;;;;;; -;;39;AC_InVA L;AC input apparent power (low);;0.1VA;;;;;;;;;;; -;;40;Fault bit;fault bit;{{fault_bit_codes}};;;;;;;;;;;; -;16bit_flags;41;Warning bit;Warning bit;{{warning_bit_codes}};;;;;;;;;;;; -;16bit_flags;42;Warning bit high;;{{warning_bit_high_codes}};;;;;;;;;;;; -;;43;warning value;warning value;;;;;;;;;;;;; -;;44;DTC;Device Type Code;&*6;;;;;;;;;;;; -;;45;Check Step;Product check step;{{check_step_codes}};;;;;;;;;;;; -;;46;Production Line Mode;Production Line Mode;{{production_line_mode_codes}};;;;;;;;;;;; -;;47;ConstantPowerOKFlag;Constant Power OK Flag;0: Not OK 1: OK;;;;;;;;;;;; -PV1 KWH Today;;48;Epv1_today H;PV Energy today;;0.1kWh;;;;;;;;;;; -;;49;Epv1_today L;PV Energy today;;0.1kWh;;;;;;;;;;; -PV1 KWH Total;;50;Epv1_total H;PV Energy total;;0.1kWh;;;;;;;;;;; -;;51;Epv1_total L;PV Energy total;;0.1kWh;;;;;;;;;;; -PV2 KWH Today;;52;Epv2_today H;PV Energy today;;0.1kWh;;;;;;;;;;; -;;53;Epv2_today L;PV Energy today;;0.1kWh;;;;;;;;;;; -PV2 KWH Total;;54;Epv2_total H;PV Energy total;;0.1kWh;;;;;;;;;;; -;;55;Epv2_total L;PV Energy total;;0.1kWh;;;;;;;;;;; -AC Input KWH Today;;56;Eac_chrToday H;AC charge Energy today;;0.1kWh;;;;;;;;;;; -;;57;Eac_chrToday L;AC charge Energy today;;0.1kWh;;;;;;;;;;; -AC Input KWH Total;;58;Eac_chrTotal H;AC charge Energy total;;0.1kWh;;;;;;;;;;; -;;59;Eac_chrTotal L;AC charge Energy total;;0.1kWh;;;;;;;;;;; -Battery Discharge KWH Today;;60;Ebat_dischrToday H;Bat discharge Energy today;;0.1kWh;;;;;;;;;;; -;;61;Ebat_dischrToday L;Bat discharge Energy today;;0.1kWh;;;;;;;;;;; -Battery Discharge KWH Total;;62;Ebat_dischrTotal H;Bat discharge Energy total;;0.1kWh;;;;;;;;;;; -;;63;Ebat_dischrTotal L;Bat discharge Energy total;;0.1kWh;;;;;;;;;;; -AC Discharge KWH Today;;64;Eac_dischrToday H;AC discharge Energy today;;0.1kWh;;;;;;;;;;; -;;65;Eac_dischrToday L;AC discharge Energy today;;0.1kWh;;;;;;;;;;; -AC Discharge KWH Total;;66;Eac_dischrTotal H;AC discharge Energy total;;0.1kWh;;;;;;;;;;; -;;67;Eac_dischrTotal L;AC discharge Energy total;;0.1kWh;;;;;;;;;;; -AC Charge Current;;68;ACChrCurr;AC Charge Battery Current;;0.1A;;;;;;;;;;; -AC Discharge Watts;;69;AC_DisChrWatt H;AC discharge watt (high);;0.1W;;;;;;;;;;; -;;70;AC_DisChrWatt L;AC discharge watt (low);;0.1W;;;;;;;;;;; -AC Discharge VA;;71;AC_DisChrVA H;AC discharge apparent power (high);;0.1VA;;;;;;;;;;; -;;72;AC_DisChrVA L;AC discharge apparent power (low);;0.1VA;;;;;;;;;;; -Battery Discharge Watts;;73;Bat_DisChrWatt H;Bat discharge watt (high);;0.1W;;;;;;;;;;; -;;74;Bat_DisChrWatt L;Bat discharge watt (low);;0.1W;;;;;;;;;;; -Battery Discharge VA;;75;Bat_DisChrVA H;Bat discharge apparent power (high);;0.1VA;;;;;;;;;;; -;;76;Bat_DisChrVA L;Bat discharge apparent power (low);;0.1VA;;;;;;;;;;; -Battery Input Watts;INT;77;Bat_Watt H;Bat watt (high);(signed int 32) Positive:Battery Discharge Power Negative: Battery Charge Power;0.1W;;0.1W;;;;;;;;; -;;78;Bat_Watt L;Bat watt (low);;0.1W;;;;;;;;;;; -;;79;uwSlaveExistCnt ;uwSlaveExistCnt ;;;;;;;;;;;;; -Battery Over Charge Flag;;80;BatOverCharge ;Battery Over Charge Flag ;0:Battery not over charge 1:Battery over charge ;; ;;;;;;;;;; -MPPT Fan Speed Percent;;81;MpptFanSpeed ;Fan speed of MPPT Charger ;0~100 ;1.00%;;;;;;;;;;; -Inverter Fan Speed Percent;;82;InvFanSpeed ;Fan speed of Inverter ;0~100 ;1.00%;;;;;;;;;;; -Total Charge Current;;83;TotalChgCur ;Total Charge current ;;0.1A;;;;;;;;;;; -;;85;Eop_dischrToday H ;Op discharge Enerday today ;;;;;;;;;;;;; -;;86;Eop_dischrToday L ;;;;;;;;;;;;;; -;;87;Eop_dischrTotal H ;Op discharge Enerday total ;;;;;;;;;;;;; -;;88;Eop_dischrTotal L ;;;;;;;;;;;;;; -Parallel Charge Current;;90;ParaChgCurr ;Para system charge current ;;0.1A;;;;;;;;;;; +variable name,data type,register,documented name,description,values,unit,note,,,,,,,,,, +,,0,System Status,System run state,{{system_status_codes}},1, PV an Grid Combine Discharge2: Discharge,3: Fault,4: Flash,5: PV charge,6: AC charge,7: Combine charge,8: Combine charge and Bypass,9: PV charge and Bypass,10: AC charge and Bypass, 11: Bypass,12: PV charge andDischarge +PV1 Voltage,,1,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, +PV2 Voltage,,2,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, +PV1 Watts,,3,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, +,,4,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, +PV2 Watts,,5,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, +,,6,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, +Buck1 Current,,7,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, +Buck2 Current,,8,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, +Output Wattage,,9,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, +,,10,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, +Output VA,,11,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, +,,12,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, +AC Charge Watts,,13,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, +,,14,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, +AC Charge VA,,15,ACChr_VA H,AC charge apparent power (high),,0.1VA,,,,,,,,,,, +,,16,ACChr_VA L,AC charge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Voltage,,17,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, +Battery SOC,,18,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, +Bus Voltage,,19,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, +Grid Voltage,,20,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, +Grid Hz,,21,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, +Output Voltage,16bit,22.b0,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, +Output Hz,,23,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, +Output DCV,,24,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, +,,25,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, +,,26,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, +Load Percentage,,27,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, +Battery Port Voltage,,28,Bat_s_Volt,Battery-port volt (DSP),,0.01V,,,,,,,,,,, +Battery Bus Voltage,,29,Bat_Volt_DSP,Battery-bus volt (DSP),,0.01V,,,,,,,,,,, +,,30,Time total H,Work time total (high),,0.5S,,,,,,,,,,, +,,31,Time total L,Work time total (low),,0.5S,,,,,,,,,,, +Buck1 Temperature,,32,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, +Buck2 Temperature,,33,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, +Output Current,,34,OP_Curr,Output Current,,0.1A,,,,,,,,,,, +Inverter Current,,35,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, +AC Input Watts,,36,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, +,,37,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, +AC Input VA,,38,AC_InVA H,AC input apparent power (high),,0.1VA,,,,,,,,,,, +,,39,AC_InVA L,AC input apparent power (low),,0.1VA,,,,,,,,,,, +,,40,Fault bit,fault bit,{{fault_bit_codes}},,,,,,,,,,,, +,16bit_flags,41,Warning bit,Warning bit,{{warning_bit_codes}},,,,,,,,,,,, +,16bit_flags,42,Warning bit high,,{{warning_bit_high_codes}},,,,,,,,,,,, +,,43,warning value,warning value,,,,,,,,,,,,, +,,44,DTC,Device Type Code,&*6,,,,,,,,,,,, +,,45,Check Step,Product check step,{{check_step_codes}},,,,,,,,,,,, +,,46,Production Line Mode,Production Line Mode,{{production_line_mode_codes}},,,,,,,,,,,, +,,47,ConstantPowerOKFlag,Constant Power OK Flag,0: Not OK 1: OK,,,,,,,,,,,, +PV1 KWH Today,,48,Epv1_today H,PV Energy today,,0.1kWh,,,,,,,,,,, +,,49,Epv1_today L,PV Energy today,,0.1kWh,,,,,,,,,,, +PV1 KWH Total,,50,Epv1_total H,PV Energy total,,0.1kWh,,,,,,,,,,, +,,51,Epv1_total L,PV Energy total,,0.1kWh,,,,,,,,,,, +PV2 KWH Today,,52,Epv2_today H,PV Energy today,,0.1kWh,,,,,,,,,,, +,,53,Epv2_today L,PV Energy today,,0.1kWh,,,,,,,,,,, +PV2 KWH Total,,54,Epv2_total H,PV Energy total,,0.1kWh,,,,,,,,,,, +,,55,Epv2_total L,PV Energy total,,0.1kWh,,,,,,,,,,, +AC Input KWH Today,,56,Eac_chrToday H,AC charge Energy today,,0.1kWh,,,,,,,,,,, +,,57,Eac_chrToday L,AC charge Energy today,,0.1kWh,,,,,,,,,,, +AC Input KWH Total,,58,Eac_chrTotal H,AC charge Energy total,,0.1kWh,,,,,,,,,,, +,,59,Eac_chrTotal L,AC charge Energy total,,0.1kWh,,,,,,,,,,, +Battery Discharge KWH Today,,60,Ebat_dischrToday H,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, +,,61,Ebat_dischrToday L,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, +Battery Discharge KWH Total,,62,Ebat_dischrTotal H,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, +,,63,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, +AC Discharge KWH Today,,64,Eac_dischrToday H,AC discharge Energy today,,0.1kWh,,,,,,,,,,, +,,65,Eac_dischrToday L,AC discharge Energy today,,0.1kWh,,,,,,,,,,, +AC Discharge KWH Total,,66,Eac_dischrTotal H,AC discharge Energy total,,0.1kWh,,,,,,,,,,, +,,67,Eac_dischrTotal L,AC discharge Energy total,,0.1kWh,,,,,,,,,,, +AC Charge Current,,68,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, +AC Discharge Watts,,69,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, +,,70,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, +AC Discharge VA,,71,AC_DisChrVA H,AC discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,72,AC_DisChrVA L,AC discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Discharge Watts,,73,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, +,,74,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, +Battery Discharge VA,,75,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,76,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Input Watts,INT,77,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative: Battery Charge Power,0.1W,,0.1W,,,,,,,,, +,,78,Bat_Watt L,Bat watt (low),,0.1W,,,,,,,,,,, +,,79,uwSlaveExistCnt ,uwSlaveExistCnt ,,,,,,,,,,,,, +Battery Over Charge Flag,,80,BatOverCharge ,Battery Over Charge Flag ,0:Battery not over charge 1:Battery over charge ,, ,,,,,,,,,, +MPPT Fan Speed Percent,,81,MpptFanSpeed ,Fan speed of MPPT Charger ,0~100 ,1.00%,,,,,,,,,,, +Inverter Fan Speed Percent,,82,InvFanSpeed ,Fan speed of Inverter ,0~100 ,1.00%,,,,,,,,,,, +Total Charge Current,,83,TotalChgCur ,Total Charge current ,,0.1A,,,,,,,,,,, +,,85,Eop_dischrToday H ,Op discharge Enerday today ,,,,,,,,,,,,, +,,86,Eop_dischrToday L ,,,,,,,,,,,,,, +,,87,Eop_dischrTotal H ,Op discharge Enerday total ,,,,,,,,,,,,, +,,88,Eop_dischrTotal L ,,,,,,,,,,,,,, +Parallel Charge Current,,90,ParaChgCurr ,Para system charge current ,,0.1A,,,,,,,,,,, From 246783a4a9feb211f8b58a8a3b4cef07b0994486 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 17 Mar 2025 14:49:46 -0500 Subject: [PATCH 10/53] quick variable timing --- .../growatt/v0.14.holding_registry_map.csv | 184 +++++++++--------- .../growatt/v0.14.input_registry_map.csv | 180 ++++++++--------- 2 files changed, 182 insertions(+), 182 deletions(-) diff --git a/protocols/growatt/v0.14.holding_registry_map.csv b/protocols/growatt/v0.14.holding_registry_map.csv index 2ff7288..835f848 100644 --- a/protocols/growatt/v0.14.holding_registry_map.csv +++ b/protocols/growatt/v0.14.holding_registry_map.csv @@ -1,92 +1,92 @@ -variable name,data type,register,documented name,description,writable,values,unit,initial value,note,,, -,1bit,0,On_Off low,,,"standby on, standby off",,,,,, -,1bit,0.b8,On_Off high,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0). ",,0x0000: Output enable 0x0100: Output disable,,,,,0, -,,1,OutputConfig,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"", ""2"": ""UTI First"", ""3"": ""PV&UTI First""}",, 2: UTI First, 3: PV&UTI First,,,0 -,,2,ChargeConfig,Charge source set,W,"{""0"": ""PV first"", ""1"": ""PV&UTI"", ""2"": ""PV Only""}",, 2: PV Only,,,,0 -,,3,UtiOutStart,Uti Output Start Time,W,0-23,,H(hour),0,,, -,,4,UtiOutEnd,Uti Output End Time,W,0-23,,H(hour),0,,, -,,5,UtiChargeStart,Uti Charge Start Time,W,0-23,,H(hour),0,,, -,,6,UtiChargeEnd,Uti Charge End Time,W,0-23,,H(hour),0,,, -PV Input Mode,,7,PVModel,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,,0, -AC Input Mode,,8,ACInModel,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC"", ""2"": ""GEN""}",,,0,,, -,ASCII,r9~11,Fw version,Firmware version (high),,,,ASCII,,,, -,ASCII,r12~14,Fw version2,Control Firmware version (high),,,,ASCII,,,, -,,15,LCD language,LCD language,W,{{lcd_language_codes}},1,English,,,, -,,16,GridV_Adj,,,,,,,,, -,,17,InvV_Adj,,,,,,,,, -,,18,OutputVoltType,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC"", ""3"": ""220VAC"", ""4"": ""100VAC"", ""5"": ""110VAC"", ""6"": ""120VAC""}",,1,,,, -,,19,OutputFreqType,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,0,,,, -,,20,OverLoadRestart,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",,0,Yes(over 1mins restart, Load to after over Load three times to stop output), , -,,21,OverTempRestart,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,0,Yes(over Temperature to restart , after over Temperature three times to stop output) ,, -,,22,BuzzerEN,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,1,,, -Serial Number,ASCII,23-27,Serial No,Serial number 5,WD,[A-Z0-9],,,,,, -,,28,Moudle H,Inverter Moudle (high),W,,,Can be set at standy state Only ,,,, -,,29,Moudle L,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid 1: Lithium 2: CustomLead_Acid U-user type: ,,Can be set at,,,, -,,30,Com Address,Communicate address,W,1~254,,,1,,, -,,31,FlashStart,Update firmware,WD,0x0001: own 0X0100: control broad,,,,,, -,,32,Reset User Info,Reset User Information,WD,0x0001,,,,,, -,,33,Reset to factory,Reset to factory,WD,0x0001,,,,,, -,,34,MaxChargeCurr,Max Charge Current,W,0~180,1A,,70,,, -,,35,BulkChargeVolt,Bulk Charge Volt,W,500~640,0.1V,,564,,, -,,36,FloatChargeVolt,Float Charge Volt,W,500~560,0.1V,,540,,, -,,37,BatLowToUtiVolt,Bat Low Volt Switch To Uti,W,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,,460 Or 50%,,, -,,38,ACChargeCurr,AC Charge Current,W,0~100,1A,,30,,, -,,39,Battery Type,Battery Type,W,"{""0"": ""AGM"", ""1"": ""FLD"", ""2"": ""USE"", ""3"": ""Lithium"", ""4"": ""USE2""}",,,1,Can be set at standy Only ,, -,,40,Aging Mode,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,,0,Can be set at standy state Only -,1bit,41,Etl check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,0:Disable, 1:Enable, -,1bit,41.b1,Pv ISO Check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,,, -,,42,Safety Type,,W,"{""1"": ""standard"", ""2"": ""ETL"", ""3"": ""AS4777"", ""4"": ""CQC"", ""5"": ""VDE4105""}",1,,,,, -,,43,DTC,Device Type Code,&*6,,,,,,, -System Year,,45,Sys Year,System time-year,W,Year offset is 2000,,,,,, -System Month,,46,Sys Month,System time- Month,W,,,,,,, -System Day,,47,Sys Day,System time- Day,W,,,,,,, -System Hour,,48,Sys Hour,System time- Hour,W,,,,,,, -System Minute,,49,Sys Min,System time- Min,W,,,,,,, -System Second,,50,Sys Sec,System time- Second,W,,,,,,, -,,52,uwAcVoltHighL,,,,,,,,, -,,53,uwAcVoltLowL,,,,,,,,, -,,54,uwAcFreqHighL,,,,,,,,, -,,55,uwAcFreqLowL,,,,,,,,, -,ASCII,59-66,Manufacturer Info,Manufacturer information (high),,ASCII,,,,,, -,,67,FW Build No_ 4,Control FW Build No. 2,,,,,,,, -,,68,FW Build No_ 3,Control FW Build No. 1,,,,,,,, -,,69,FW Build No_ 2,COM FW Build No. 2,,,,,,,, -,,70,FW Build No_ 1,COM FW Build No. 1,,,,,,,, -,,72,Sys Weekly,Sys Weekly,W,0-6,,,,,, -,,73,ModbusVersion,Modbus Version,,Eg:207 is V2.07 Int(16bit s),0.01,,,,, -,,75,SCC_ComMode,SCC Communication,,,,For,BMS,,, -,,76,Rate Watt H,Rate active power(high),,,0.1W,,,,, -,,77,Rate Watt L,Rate active power(low),,,0.1W,,,,, -,,78,Rate VA H,Rata apparent power (high),,,0.1VA,,,,, -,,79,Rate VA L,Rate apparent power (low),,,0.1VA,,,,, -,,80,ComboardVer,Communicaiton board Version,,,,For boad,bms,,, -,,81,uwBatPieceNum,,,,,,,,, -,,82,wBatLowCutOff,Bat voltage low cutoff,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, -,,84,NomGridVolt,,,,,,,,, -,,85,NomGridFreq,,,,,,,,, -,,86,NomBatVolt,,,,,,,,, -,,87,NomPvCurr,,,,,,,,, -,,88,NomAcChgCurr,,,,,,,,, -,,89,NomOpVolt,,,,,,,,, -,,90,NomOpFreq,,,,,,,,, -,,91,NomOpPow,,,,,,,,, -,,95,uwAC2BatVolt,AC switch to Battery,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, -,,96,BypEnable,,,,,,,,, -,,97,PowSavingEn,,,,,,,,, -,,98,SpowBalEn,,,,,,,,, -,,99,ClrEnergyToday,,,,,,,,, -,,100,clrEnergyAll,,,,,,,,, -,,101,BurnInTestEn,,,,,,,,, -,,102,ManualStartEn,,,,,,,,, -,,103,SciLossChkEn,,,,,,,,, -,,104,BlightEn,,,,,,,,, -,,105,ParaMaxChgCurr,Parallel Maximum current,,,,,,,, -,,106,LiProtocolType,Protocol battery,,for,,1~99,,1,, -,,107,AudioAlarmEn,,,,,,,,, -,,108,uwEqEn,,,,,,,,, -,,109,uwEqChgVolt,,,,,,,,, -,,110,uwEqTime,,,,,,,,, -,,111,uwEqTimeOut,,,,,,,,, -,,112,uwEqInterval,,,,,,,,, -,,113,uwMaxDisChgCu rr,,,,,,,,, -,,162,BLVersion2,Boot loader version2,,,R,,,,M3 bootloader version, +variable name,data type,register,read_interval,documented name,description,writable,values,unit,initial value,note,,, +,1bit,0,,On_Off low,,,"standby on, standby off",,,,,, +,1bit,0.b8,,On_Off high,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0). ",,0x0000: Output enable 0x0100: Output disable,,,,,0, +,,1,10x,OutputConfig,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"", ""2"": ""UTI First"", ""3"": ""PV&UTI First""}",, 2: UTI First, 3: PV&UTI First,,,0 +,,2,10x,ChargeConfig,Charge source set,W,"{""0"": ""PV first"", ""1"": ""PV&UTI"", ""2"": ""PV Only""}",, 2: PV Only,,,,0 +,,3,10x,UtiOutStart,Uti Output Start Time,W,0-23,,H(hour),0,,, +,,4,10x,UtiOutEnd,Uti Output End Time,W,0-23,,H(hour),0,,, +,,5,10x,UtiChargeStart,Uti Charge Start Time,W,0-23,,H(hour),0,,, +,,6,10x,UtiChargeEnd,Uti Charge End Time,W,0-23,,H(hour),0,,, +PV Input Mode,,7,10x,PVModel,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,,0, +AC Input Mode,,8,10x,ACInModel,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC"", ""2"": ""GEN""}",,,0,,, +,ASCII,r9~11,100x,Fw version,Firmware version (high),,,,ASCII,,,, +,ASCII,r12~14,100x,Fw version2,Control Firmware version (high),,,,ASCII,,,, +,,15,10x,LCD language,LCD language,W,{{lcd_language_codes}},1,English,,,, +,,16,10x,GridV_Adj,,,,,,,,, +,,17,10x,InvV_Adj,,,,,,,,, +,,18,10x,OutputVoltType,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC"", ""3"": ""220VAC"", ""4"": ""100VAC"", ""5"": ""110VAC"", ""6"": ""120VAC""}",,1,,,, +,,19,10x,OutputFreqType,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,0,,,, +,,20,10x,OverLoadRestart,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",,0,Yes(over 1mins restart, Load to after over Load three times to stop output), , +,,21,10x,OverTempRestart,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,0,Yes(over Temperature to restart , after over Temperature three times to stop output) ,, +,,22,10x,BuzzerEN,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,1,,, +Serial Number,ASCII,23-27,100x,Serial No,Serial number 5,WD,[A-Z0-9],,,,,, +,,28,10x,Moudle H,Inverter Moudle (high),W,,,Can be set at standy state Only ,,,, +,,29,10x,Moudle L,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid 1: Lithium 2: CustomLead_Acid U-user type: ,,Can be set at,,,, +,,30,10x,Com Address,Communicate address,W,1~254,,,1,,, +,,31,10x,FlashStart,Update firmware,WD,0x0001: own 0X0100: control broad,,,,,, +,,32,100x,Reset User Info,Reset User Information,WD,0x0001,,,,,, +,,33,100x,Reset to factory,Reset to factory,WD,0x0001,,,,,, +,,34,10x,MaxChargeCurr,Max Charge Current,W,0~180,1A,,70,,, +,,35,10x,BulkChargeVolt,Bulk Charge Volt,W,500~640,0.1V,,564,,, +,,36,10x,FloatChargeVolt,Float Charge Volt,W,500~560,0.1V,,540,,, +,,37,10x,BatLowToUtiVolt,Bat Low Volt Switch To Uti,W,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,,460 Or 50%,,, +,,38,10x,ACChargeCurr,AC Charge Current,W,0~100,1A,,30,,, +,,39,10x,Battery Type,Battery Type,W,"{""0"": ""AGM"", ""1"": ""FLD"", ""2"": ""USE"", ""3"": ""Lithium"", ""4"": ""USE2""}",,,1,Can be set at standy Only ,, +,,40,10x,Aging Mode,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,,0,Can be set at standy state Only +,1bit,41,10x,Etl check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,0:Disable, 1:Enable, +,1bit,41.b1,10x,Pv ISO Check enable,,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,,, +,,42,10x,Safety Type,,W,"{""1"": ""standard"", ""2"": ""ETL"", ""3"": ""AS4777"", ""4"": ""CQC"", ""5"": ""VDE4105""}",1,,,,, +,,43,100x,DTC,Device Type Code,&*6,,,,,,, +System Year,,45,10x,Sys Year,System time-year,W,Year offset is 2000,,,,,, +System Month,,46,10x,Sys Month,System time- Month,W,,,,,,, +System Day,,47,10x,Sys Day,System time- Day,W,,,,,,, +System Hour,,48,10x,Sys Hour,System time- Hour,W,,,,,,, +System Minute,,49,10x,Sys Min,System time- Min,W,,,,,,, +System Second,,50,10x,Sys Sec,System time- Second,W,,,,,,, +,,52,10x,uwAcVoltHighL,,,,,,,,, +,,53,10x,uwAcVoltLowL,,,,,,,,, +,,54,10x,uwAcFreqHighL,,,,,,,,, +,,55,10x,uwAcFreqLowL,,,,,,,,, +,ASCII,59-66,100x,Manufacturer Info,Manufacturer information (high),,ASCII,,,,,, +,,67,100x,FW Build No_ 4,Control FW Build No. 2,,,,,,,, +,,68,100x,FW Build No_ 3,Control FW Build No. 1,,,,,,,, +,,69,100x,FW Build No_ 2,COM FW Build No. 2,,,,,,,, +,,70,100x,FW Build No_ 1,COM FW Build No. 1,,,,,,,, +,,72,10x,Sys Weekly,Sys Weekly,W,0-6,,,,,, +,,73,10x,ModbusVersion,Modbus Version,,Eg:207 is V2.07 Int(16bit s),0.01,,,,, +,,75,10x,SCC_ComMode,SCC Communication,,,,For,BMS,,, +,,76,10x,Rate Watt H,Rate active power(high),,,0.1W,,,,, +,,77,10x,Rate Watt L,Rate active power(low),,,0.1W,,,,, +,,78,10x,Rate VA H,Rata apparent power (high),,,0.1VA,,,,, +,,79,10x,Rate VA L,Rate apparent power (low),,,0.1VA,,,,, +,,80,10x,ComboardVer,Communicaiton board Version,,,,For boad,bms,,, +,,81,10x,uwBatPieceNum,,,,,,,,, +,,82,100x,wBatLowCutOff,Bat voltage low cutoff,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, +,,84,10x,NomGridVolt,,,,,,,,, +,,85,10x,NomGridFreq,,,,,,,,, +,,86,10x,NomBatVolt,,,,,,,,, +,,87,10x,NomPvCurr,,,,,,,,, +,,88,10x,NomAcChgCurr,,,,,,,,, +,,89,10x,NomOpVolt,,,,,,,,, +,,90,10x,NomOpFreq,,,,,,,,, +,,91,10x,NomOpPow,,,,,,,,, +,,95,10x,uwAC2BatVolt,AC switch to Battery,,200~640 (non Lithium) or 5~100 (Lithium),0.1V Or 1%,460 Or 50%,,,, +,,96,10x,BypEnable,,,,,,,,, +,,97,10x,PowSavingEn,,,,,,,,, +,,98,10x,SpowBalEn,,,,,,,,, +,,99,10x,ClrEnergyToday,,,,,,,,, +,,100,10x,clrEnergyAll,,,,,,,,, +,,101,10x,BurnInTestEn,,,,,,,,, +,,102,10x,ManualStartEn,,,,,,,,, +,,103,10x,SciLossChkEn,,,,,,,,, +,,104,10x,BlightEn,,,,,,,,, +,,105,10x,ParaMaxChgCurr,Parallel Maximum current,,,,,,,, +,,106,10x,LiProtocolType,Protocol battery,,for,,1~99,,1,, +,,107,10x,AudioAlarmEn,,,,,,,,, +,,108,10x,uwEqEn,,,,,,,,, +,,109,10x,uwEqChgVolt,,,,,,,,, +,,110,10x,uwEqTime,,,,,,,,, +,,111,10x,uwEqTimeOut,,,,,,,,, +,,112,10x,uwEqInterval,,,,,,,,, +,,113,10x,uwMaxDisChgCu rr,,,,,,,,, +,,162,100x,BLVersion2,Boot loader version2,,,R,,,,M3 bootloader version, diff --git a/protocols/growatt/v0.14.input_registry_map.csv b/protocols/growatt/v0.14.input_registry_map.csv index 024a20a..0075dd9 100644 --- a/protocols/growatt/v0.14.input_registry_map.csv +++ b/protocols/growatt/v0.14.input_registry_map.csv @@ -1,90 +1,90 @@ -variable name,data type,register,documented name,description,values,unit,note,,,,,,,,,, -,,0,System Status,System run state,{{system_status_codes}},1, PV an Grid Combine Discharge2: Discharge,3: Fault,4: Flash,5: PV charge,6: AC charge,7: Combine charge,8: Combine charge and Bypass,9: PV charge and Bypass,10: AC charge and Bypass, 11: Bypass,12: PV charge andDischarge -PV1 Voltage,,1,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, -PV2 Voltage,,2,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, -PV1 Watts,,3,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, -,,4,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, -PV2 Watts,,5,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, -,,6,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, -Buck1 Current,,7,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, -Buck2 Current,,8,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, -Output Wattage,,9,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, -,,10,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, -Output VA,,11,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, -,,12,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, -AC Charge Watts,,13,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, -,,14,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, -AC Charge VA,,15,ACChr_VA H,AC charge apparent power (high),,0.1VA,,,,,,,,,,, -,,16,ACChr_VA L,AC charge apparent power (low),,0.1VA,,,,,,,,,,, -Battery Voltage,,17,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, -Battery SOC,,18,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, -Bus Voltage,,19,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, -Grid Voltage,,20,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, -Grid Hz,,21,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, -Output Voltage,16bit,22.b0,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, -Output Hz,,23,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, -Output DCV,,24,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, -,,25,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, -,,26,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, -Load Percentage,,27,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, -Battery Port Voltage,,28,Bat_s_Volt,Battery-port volt (DSP),,0.01V,,,,,,,,,,, -Battery Bus Voltage,,29,Bat_Volt_DSP,Battery-bus volt (DSP),,0.01V,,,,,,,,,,, -,,30,Time total H,Work time total (high),,0.5S,,,,,,,,,,, -,,31,Time total L,Work time total (low),,0.5S,,,,,,,,,,, -Buck1 Temperature,,32,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, -Buck2 Temperature,,33,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, -Output Current,,34,OP_Curr,Output Current,,0.1A,,,,,,,,,,, -Inverter Current,,35,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, -AC Input Watts,,36,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, -,,37,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, -AC Input VA,,38,AC_InVA H,AC input apparent power (high),,0.1VA,,,,,,,,,,, -,,39,AC_InVA L,AC input apparent power (low),,0.1VA,,,,,,,,,,, -,,40,Fault bit,fault bit,{{fault_bit_codes}},,,,,,,,,,,, -,16bit_flags,41,Warning bit,Warning bit,{{warning_bit_codes}},,,,,,,,,,,, -,16bit_flags,42,Warning bit high,,{{warning_bit_high_codes}},,,,,,,,,,,, -,,43,warning value,warning value,,,,,,,,,,,,, -,,44,DTC,Device Type Code,&*6,,,,,,,,,,,, -,,45,Check Step,Product check step,{{check_step_codes}},,,,,,,,,,,, -,,46,Production Line Mode,Production Line Mode,{{production_line_mode_codes}},,,,,,,,,,,, -,,47,ConstantPowerOKFlag,Constant Power OK Flag,0: Not OK 1: OK,,,,,,,,,,,, -PV1 KWH Today,,48,Epv1_today H,PV Energy today,,0.1kWh,,,,,,,,,,, -,,49,Epv1_today L,PV Energy today,,0.1kWh,,,,,,,,,,, -PV1 KWH Total,,50,Epv1_total H,PV Energy total,,0.1kWh,,,,,,,,,,, -,,51,Epv1_total L,PV Energy total,,0.1kWh,,,,,,,,,,, -PV2 KWH Today,,52,Epv2_today H,PV Energy today,,0.1kWh,,,,,,,,,,, -,,53,Epv2_today L,PV Energy today,,0.1kWh,,,,,,,,,,, -PV2 KWH Total,,54,Epv2_total H,PV Energy total,,0.1kWh,,,,,,,,,,, -,,55,Epv2_total L,PV Energy total,,0.1kWh,,,,,,,,,,, -AC Input KWH Today,,56,Eac_chrToday H,AC charge Energy today,,0.1kWh,,,,,,,,,,, -,,57,Eac_chrToday L,AC charge Energy today,,0.1kWh,,,,,,,,,,, -AC Input KWH Total,,58,Eac_chrTotal H,AC charge Energy total,,0.1kWh,,,,,,,,,,, -,,59,Eac_chrTotal L,AC charge Energy total,,0.1kWh,,,,,,,,,,, -Battery Discharge KWH Today,,60,Ebat_dischrToday H,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, -,,61,Ebat_dischrToday L,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, -Battery Discharge KWH Total,,62,Ebat_dischrTotal H,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, -,,63,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, -AC Discharge KWH Today,,64,Eac_dischrToday H,AC discharge Energy today,,0.1kWh,,,,,,,,,,, -,,65,Eac_dischrToday L,AC discharge Energy today,,0.1kWh,,,,,,,,,,, -AC Discharge KWH Total,,66,Eac_dischrTotal H,AC discharge Energy total,,0.1kWh,,,,,,,,,,, -,,67,Eac_dischrTotal L,AC discharge Energy total,,0.1kWh,,,,,,,,,,, -AC Charge Current,,68,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, -AC Discharge Watts,,69,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, -,,70,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, -AC Discharge VA,,71,AC_DisChrVA H,AC discharge apparent power (high),,0.1VA,,,,,,,,,,, -,,72,AC_DisChrVA L,AC discharge apparent power (low),,0.1VA,,,,,,,,,,, -Battery Discharge Watts,,73,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, -,,74,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, -Battery Discharge VA,,75,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, -,,76,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, -Battery Input Watts,INT,77,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative: Battery Charge Power,0.1W,,0.1W,,,,,,,,, -,,78,Bat_Watt L,Bat watt (low),,0.1W,,,,,,,,,,, -,,79,uwSlaveExistCnt ,uwSlaveExistCnt ,,,,,,,,,,,,, -Battery Over Charge Flag,,80,BatOverCharge ,Battery Over Charge Flag ,0:Battery not over charge 1:Battery over charge ,, ,,,,,,,,,, -MPPT Fan Speed Percent,,81,MpptFanSpeed ,Fan speed of MPPT Charger ,0~100 ,1.00%,,,,,,,,,,, -Inverter Fan Speed Percent,,82,InvFanSpeed ,Fan speed of Inverter ,0~100 ,1.00%,,,,,,,,,,, -Total Charge Current,,83,TotalChgCur ,Total Charge current ,,0.1A,,,,,,,,,,, -,,85,Eop_dischrToday H ,Op discharge Enerday today ,,,,,,,,,,,,, -,,86,Eop_dischrToday L ,,,,,,,,,,,,,, -,,87,Eop_dischrTotal H ,Op discharge Enerday total ,,,,,,,,,,,,, -,,88,Eop_dischrTotal L ,,,,,,,,,,,,,, -Parallel Charge Current,,90,ParaChgCurr ,Para system charge current ,,0.1A,,,,,,,,,,, +variable name,data type,register,read_interval,documented name,description,values,unit,note,,,,,,,,,, +,,0,,System Status,System run state,{{system_status_codes}},1, PV an Grid Combine Discharge2: Discharge,3: Fault,4: Flash,5: PV charge,6: AC charge,7: Combine charge,8: Combine charge and Bypass,9: PV charge and Bypass,10: AC charge and Bypass, 11: Bypass,12: PV charge andDischarge +PV1 Voltage,,1,,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, +PV2 Voltage,,2,,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, +PV1 Watts,,3,,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, +,,4,,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, +PV2 Watts,,5,,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, +,,6,,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, +Buck1 Current,,7,,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, +Buck2 Current,,8,,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, +Output Wattage,,9,,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, +,,10,,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, +Output VA,,11,,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, +,,12,,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, +AC Charge Watts,,13,,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, +,,14,,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, +AC Charge VA,,15,,ACChr_VA H,AC charge apparent power (high),,0.1VA,,,,,,,,,,, +,,16,,ACChr_VA L,AC charge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Voltage,,17,,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, +Battery SOC,,18,,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, +Bus Voltage,,19,,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, +Grid Voltage,,20,,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, +Grid Hz,,21,,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, +Output Voltage,16bit,22.b0,,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, +Output Hz,,23,,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, +Output DCV,,24,,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, +,,25,,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, +,,26,,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, +Load Percentage,,27,,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, +Battery Port Voltage,,28,,Bat_s_Volt,Battery-port volt (DSP),,0.01V,,,,,,,,,,, +Battery Bus Voltage,,29,,Bat_Volt_DSP,Battery-bus volt (DSP),,0.01V,,,,,,,,,,, +,,30,,Time total H,Work time total (high),,0.5S,,,,,,,,,,, +,,31,,Time total L,Work time total (low),,0.5S,,,,,,,,,,, +Buck1 Temperature,,32,,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, +Buck2 Temperature,,33,,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, +Output Current,,34,,OP_Curr,Output Current,,0.1A,,,,,,,,,,, +Inverter Current,,35,,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, +AC Input Watts,,36,,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, +,,37,,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, +AC Input VA,,38,,AC_InVA H,AC input apparent power (high),,0.1VA,,,,,,,,,,, +,,39,,AC_InVA L,AC input apparent power (low),,0.1VA,,,,,,,,,,, +,,40,,Fault bit,fault bit,{{fault_bit_codes}},,,,,,,,,,,, +,16bit_flags,41,,Warning bit,Warning bit,{{warning_bit_codes}},,,,,,,,,,,, +,16bit_flags,42,,Warning bit high,,{{warning_bit_high_codes}},,,,,,,,,,,, +,,43,,warning value,warning value,,,,,,,,,,,,, +,,44,,DTC,Device Type Code,&*6,,,,,,,,,,,, +,,45,,Check Step,Product check step,{{check_step_codes}},,,,,,,,,,,, +,,46,,Production Line Mode,Production Line Mode,{{production_line_mode_codes}},,,,,,,,,,,, +,,47,,ConstantPowerOKFlag,Constant Power OK Flag,0: Not OK 1: OK,,,,,,,,,,,, +PV1 KWH Today,,48,10x,Epv1_today H,PV Energy today,,0.1kWh,,,,,,,,,,, +,,49,10x,Epv1_today L,PV Energy today,,0.1kWh,,,,,,,,,,, +PV1 KWH Total,,50,10x,Epv1_total H,PV Energy total,,0.1kWh,,,,,,,,,,, +,,51,10x,Epv1_total L,PV Energy total,,0.1kWh,,,,,,,,,,, +PV2 KWH Today,,52,10x,Epv2_today H,PV Energy today,,0.1kWh,,,,,,,,,,, +,,53,10x,Epv2_today L,PV Energy today,,0.1kWh,,,,,,,,,,, +PV2 KWH Total,,54,10x,Epv2_total H,PV Energy total,,0.1kWh,,,,,,,,,,, +,,55,10x,Epv2_total L,PV Energy total,,0.1kWh,,,,,,,,,,, +AC Input KWH Today,,56,10x,Eac_chrToday H,AC charge Energy today,,0.1kWh,,,,,,,,,,, +,,57,10x,Eac_chrToday L,AC charge Energy today,,0.1kWh,,,,,,,,,,, +AC Input KWH Total,,58,10x,Eac_chrTotal H,AC charge Energy total,,0.1kWh,,,,,,,,,,, +,,59,10x,Eac_chrTotal L,AC charge Energy total,,0.1kWh,,,,,,,,,,, +Battery Discharge KWH Today,,60,10x,Ebat_dischrToday H,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, +,,61,10x,Ebat_dischrToday L,Bat discharge Energy today,,0.1kWh,,,,,,,,,,, +Battery Discharge KWH Total,,62,10x,Ebat_dischrTotal H,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, +,,63,10x,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kWh,,,,,,,,,,, +AC Discharge KWH Today,,64,10x,Eac_dischrToday H,AC discharge Energy today,,0.1kWh,,,,,,,,,,, +,,65,10x,Eac_dischrToday L,AC discharge Energy today,,0.1kWh,,,,,,,,,,, +AC Discharge KWH Total,,66,10x,Eac_dischrTotal H,AC discharge Energy total,,0.1kWh,,,,,,,,,,, +,,67,10x,Eac_dischrTotal L,AC discharge Energy total,,0.1kWh,,,,,,,,,,, +AC Charge Current,,68,,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, +AC Discharge Watts,,69,,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, +,,70,,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, +AC Discharge VA,,71,,AC_DisChrVA H,AC discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,72,,AC_DisChrVA L,AC discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Discharge Watts,,73,,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, +,,74,,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, +Battery Discharge VA,,75,,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,76,,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Input Watts,INT,77,,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative: Battery Charge Power,0.1W,,0.1W,,,,,,,,, +,,78,,Bat_Watt L,Bat watt (low),,0.1W,,,,,,,,,,, +,,79,,uwSlaveExistCnt ,uwSlaveExistCnt ,,,,,,,,,,,,, +Battery Over Charge Flag,,80,,BatOverCharge ,Battery Over Charge Flag ,0:Battery not over charge 1:Battery over charge ,, ,,,,,,,,,, +MPPT Fan Speed Percent,,81,,MpptFanSpeed ,Fan speed of MPPT Charger ,0~100 ,1.00%,,,,,,,,,,, +Inverter Fan Speed Percent,,82,,InvFanSpeed ,Fan speed of Inverter ,0~100 ,1.00%,,,,,,,,,,, +Total Charge Current,,83,,TotalChgCur ,Total Charge current ,,0.1A,,,,,,,,,,, +,,85,,Eop_dischrToday H ,Op discharge Enerday today ,,,,,,,,,,,,, +,,86,,Eop_dischrToday L ,,,,,,,,,,,,,, +,,87,,Eop_dischrTotal H ,Op discharge Enerday total ,,,,,,,,,,,,, +,,88,,Eop_dischrTotal L ,,,,,,,,,,,,,, +Parallel Charge Current,,90,,ParaChgCurr ,Para system charge current ,,0.1A,,,,,,,,,,, From f85a358df72192282182a0d743e8c7c642c44a0a Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Mar 2025 15:03:09 -0500 Subject: [PATCH 11/53] finish fixing new variable timing --- classes/protocol_settings.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 44ed953..30a2fb3 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -270,6 +270,7 @@ def __init__(self, protocol : str, transport_settings : 'SectionProxy' = None, s self.protocol = protocol self.settings_dir = settings_dir + self.transport_settings = transport_settings #load variable mask self.variable_mask = [] @@ -426,12 +427,10 @@ def process_row(row): #region read_interval - if 'read_interval' in row: - row['read_interval'] = row['read_interval'].lower() #ensure is all lower case - match = read_interval_regex.search(row['read_interval']) + if 'read interval' in row: + row['read interval'] = row['read interval'].lower() #ensure is all lower case + match = read_interval_regex.search(row['read interval']) if match: - register = strtoint(match.group('register')) - unit = match.group('unit') value = match.group('value') if value: @@ -444,12 +443,12 @@ def process_row(row): read_interval *= 1000 if read_interval == 0: - read_interval = transport_read_interval + read_interval = transport_read_interval * 1000 if "read_interval" in self.settings: try: read_interval = int(self.settings['read_interval']) except ValueError: - read_interval = transport_read_interval + read_interval = transport_read_interval * 1000 #region overrides @@ -762,7 +761,7 @@ def process_row(row): return registry_map - def calculate_registry_ranges(self, map : list[registry_map_entry], max_register : int) -> list[tuple]: + def calculate_registry_ranges(self, map : list[registry_map_entry], max_register : int, init : bool = False) -> list[tuple]: ''' read optimization; calculate which ranges to read''' max_batch_size = 45 #see manual; says max batch is 45 @@ -776,7 +775,8 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register ranges : list[tuple] = [] timestamp_ms = int(time.time() * 1000) - + if init : #hack so that all registers are read initially without adding extra if in loop + timestamp_ms = 0 while (start := start+max_batch_size) <= max_register: @@ -843,7 +843,7 @@ def load_registry_map(self, registry_type : Registry_Type, file : str = '', sett size = item.register self.registry_map_size[registry_type] = size - self.registry_map_ranges[registry_type] = self.calculate_registry_ranges(self.registry_map[registry_type], self.registry_map_size[registry_type]) + self.registry_map_ranges[registry_type] = self.calculate_registry_ranges(self.registry_map[registry_type], self.registry_map_size[registry_type], init=True) def process_register_bytes(self, registry : dict[int,bytes], entry : registry_map_entry): ''' process bytes into data''' From 410dbb70d521a9ea4047a7c47aa8ad7dcd351843 Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Tue, 18 Mar 2025 12:13:18 +0000 Subject: [PATCH 12/53] baby steps --- classes/protocol_settings.py | 161 +++++++++++---------- classes/transports/canbus.py | 52 +++---- classes/transports/modbus_base.py | 94 ++++++------ classes/transports/modbus_rtu.py | 37 ++--- classes/transports/modbus_tcp.py | 14 +- classes/transports/modbus_tls.py | 20 +-- classes/transports/modbus_udp.py | 12 +- classes/transports/mqtt.py | 61 ++++---- classes/transports/pace.py | 34 ++--- classes/transports/serial_frame_client.py | 14 +- classes/transports/serial_pylon.py | 40 +++-- classes/transports/transport_base.py | 16 +- defs/common.py | 22 +-- documentation/.scripts/generate_indexes.py | 8 +- protocol_gateway.py | 31 ++-- pytests/test_example_config.py | 5 +- pytests/test_protocol_settings.py | 5 +- requirements.txt | 4 +- test.py | 16 +- tools/apply_common_names_to_csv.py | 8 +- tools/get_common_names_from_csv.py | 4 +- tools/list_to_json.py | 4 +- 22 files changed, 313 insertions(+), 349 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index d0fea16..a145bf7 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -9,7 +9,6 @@ import json import re import os -import math import ast class Data_Type(Enum): @@ -97,12 +96,12 @@ def fromString(cls, name : str): "UINT32" : "UINT", "INT32" : "INT" } - + if name in alias: name = alias[name] return getattr(cls, name) - + @classmethod def getSize(cls, data_type : 'Data_Type'): sizes = { @@ -115,16 +114,16 @@ def getSize(cls, data_type : 'Data_Type'): Data_Type._16BIT_FLAGS : 16, Data_Type._32BIT_FLAGS : 32 } - + if data_type in sizes: return sizes[data_type] if data_type.value > 400: #signed magnitude bits return data_type.value-400 - + if data_type.value > 300: #signed bits return data_type.value-300 - + if data_type.value > 200: #unsigned bits return data_type.value-200 @@ -162,7 +161,7 @@ def fromString(cls, name : str): "YES" : "WRITE", "WO" : "WRITEONLY" } - + if name in alias: name = alias[name] else: @@ -176,20 +175,20 @@ class Registry_Type(Enum): HOLDING = 0x03 INPUT = 0x04 - + @dataclass class registry_map_entry: registry_type : Registry_Type register : int register_bit : int - register_byte : int + register_byte : int ''' byte offset for canbus ect... ''' variable_name : str documented_name : str unit : str unit_mod : float concatenate : bool - concatenate_registers : list[int] + concatenate_registers : list[int] values : list value_regex : str = "" @@ -206,16 +205,16 @@ class registry_map_entry: read_command : bytes = None ''' for transports/protocols that require sending a command ontop of "register" ''' - + write_mode : WriteMode = WriteMode.READ ''' enable disable reading/writing ''' - + def __str__(self): return self.variable_name def __eq__(self, other): - return ( isinstance(other, registry_map_entry) - and self.register == other.register + return ( isinstance(other, registry_map_entry) + and self.register == other.register and self.register_bit == other.register_bit and self.registry_type == other.registry_type and self.register_byte == other.register_byte) @@ -293,7 +292,7 @@ def __init__(self, protocol : str, settings_dir : str = 'protocols'): def get_registry_map(self, registry_type : Registry_Type = Registry_Type.ZERO) -> list[registry_map_entry]: return self.registry_map[registry_type] - + def get_registry_ranges(self, registry_type : Registry_Type) -> list[registry_map_entry]: return self.registry_map_ranges[registry_type] @@ -301,18 +300,18 @@ def get_registry_ranges(self, registry_type : Registry_Type) -> list[registry_ma def get_holding_registry_entry(self, name : str): ''' deprecated ''' return self.get_registry_entry(name, registry_type=Registry_Type.HOLDING) - + def get_input_registry_entry(self, name : str): ''' deprecated ''' return self.get_registry_entry(name, registry_type=Registry_Type.INPUT) def get_registry_entry(self, name : str, registry_type : Registry_Type) -> registry_map_entry: - + name = name.strip().lower().replace(' ', '_') #clean name for item in self.registry_map[registry_type]: if item.documented_name == name: return item - + return None def load__json(self, file : str = '', settings_dir : str = ''): @@ -342,7 +341,7 @@ def load__json(self, file : str = '', settings_dir : str = ''): def load_registry_overrides(self, override_path, keys : list[str]): """Load overrides into a multidimensional dictionary keyed by each specified key.""" overrides = {key: {} for key in keys} - + with open(override_path, newline='', encoding='latin-1') as csvfile: reader = csv.DictReader(csvfile) for row in reader: @@ -355,7 +354,7 @@ def load_registry_overrides(self, override_path, keys : list[str]): return overrides - def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INPUT) -> list[registry_map_entry]: + def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INPUT) -> list[registry_map_entry]: registry_map : list[registry_map_entry] = [] register_regex = re.compile(r'(?P(?:0?x[\da-z]+|[\d]+))\.(b(?Px?\d{1,2})|(?Px?\d{1,2}))') @@ -368,7 +367,7 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP if not os.path.exists(path): #return empty is file doesnt exist. return registry_map - + overrides : dict[str, dict] = None override_keys = ['documented name', 'register'] @@ -382,13 +381,13 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP self._log.info("loading override file: " + override_path) overrides = self.load_registry_overrides(override_path, override_keys) - + def determine_delimiter(first_row) -> str: if first_row.count(';') > first_row.count(','): return ';' else: - return ',' - + return ',' + def process_row(row): # Initialize variables to hold numeric and character parts unit_multiplier : float = 1 @@ -399,7 +398,7 @@ def process_row(row): #region overrides - if overrides != None: + if overrides is not None: #apply overrides using documented name or register override_row = None # Check each key in order until a match is found @@ -409,7 +408,7 @@ def process_row(row): override_row = overrides[key][key_value] overrided_keys.add(key_value) break - + # Apply non-empty override values if an override row is found if override_row: for field, override_value in override_row.items(): @@ -418,7 +417,7 @@ def process_row(row): #endregion overrides - #region unit + #region unit #if or is in the unit; ignore unit if "or" in row['unit'].lower() or ":" in row['unit'].lower(): @@ -438,7 +437,7 @@ def process_row(row): #convert to float try: unit_multiplier = float(unit_multiplier) - except: + except Exception: unit_multiplier = float(1) if unit_multiplier == 0: @@ -449,12 +448,12 @@ def process_row(row): variable_name = row['variable name'] if row['variable name'] else row['documented name'] variable_name = variable_name.strip().lower().replace(' ', '_').replace('__', '_') #clean name - + if re.search(r"[^a-zA-Z0-9\_]", variable_name) : self._log.warning("Invalid Name : " + str(variable_name) + " reg: " + str(row['register']) + " doc name: " + str(row['documented name']) + " path: " + str(path)) - if not variable_name and not row['documented name']: #skip empty entry / no name. todo add more invalidator checks. + if not variable_name and not row['documented name']: #skip empty entry / no name. todo add more invalidator checks. return #region data type @@ -470,7 +469,7 @@ def process_row(row): else: data_type = Data_Type.fromString(row['data type']) - + if 'values' not in row: row['values'] = "" self._log.warning("No Value Column : path: " + str(path)) @@ -522,7 +521,7 @@ def process_row(row): #value_regex val_match = ascii_value_regex.search(row['values']) if val_match: - value_regex = val_match.group('regex') + value_regex = val_match.group('regex') matched = True if not matched: #single value @@ -571,7 +570,7 @@ def process_row(row): else: for i in range(start, end+1): concatenate_registers.append(i) - + if concatenate_registers: r = range(len(concatenate_registers)) else: @@ -589,7 +588,7 @@ def process_row(row): writeMode : WriteMode = WriteMode.READ if "writable" in row: writeMode = WriteMode.fromString(row['writable']) - + for i in r: item = registry_map_entry( registry_type = registry_type, @@ -615,19 +614,19 @@ def process_row(row): register = register + 1 - + with open(path, newline='', encoding='latin-1') as csvfile: #clean column names before passing to csv dict reader - delimeter = ';' + delimeter = ';' first_row = next(csvfile).lower().replace('_', ' ') if first_row.count(';') < first_row.count(','): delimeter = ',' first_row = re.sub(r"\s+" + re.escape(delimeter) +"|" + re.escape(delimeter) +r"\s+", delimeter, first_row) #trim values - csvfile = itertools.chain([first_row], csvfile) #add clean header to begining of iterator + csvfile = itertools.chain([first_row], csvfile) #add clean header to begining of iterator # Create a CSV reader object reader = csv.DictReader(csvfile, delimiter=delimeter) @@ -636,33 +635,33 @@ def process_row(row): for row in reader: process_row(row) - if overrides != None: + if overrides is not None: # Add any unmatched overrides as new entries... probably need to add some better error handling to ensure entry isnt empty ect... for key in override_keys: applied = False for key_value, override_row in overrides[key].items(): # Check if both keys are unique before applying - if all(override_row.get(k) for k in override_keys): + if all(override_row.get(k) for k in override_keys): if all(override_row.get(k) not in overrided_keys for k in override_keys): self._log.info("Loading unique entry from overrides for both unique keys") process_row(override_row) - + # Mark both keys as applied for k in override_keys: overrided_keys.add(override_row.get(k)) - + applied = True break # Exit inner loop after applying unique entry - if applied: + if applied: continue - + for index in reversed(range(len(registry_map))): item = registry_map[index] if index > 0: #if high/low, its a double if ( - item.documented_name.endswith('_l') + item.documented_name.endswith('_l') and registry_map[index-1].documented_name.replace('_h', '_l') == item.documented_name ): combined_item = registry_map[index-1] @@ -676,7 +675,7 @@ def process_row(row): if combined_item.documented_name == combined_item.variable_name: combined_item.variable_name = combined_item.variable_name[:-2].strip() - + combined_item.documented_name = combined_item.documented_name[:-2].strip() if not combined_item.unit: #fix inconsistsent documentation @@ -690,23 +689,23 @@ def process_row(row): for index in reversed(range(len(registry_map))): item = registry_map[index] if ( - item.documented_name.strip().lower() not in self.variable_mask + item.documented_name.strip().lower() not in self.variable_mask and item.variable_name.strip().lower() not in self.variable_mask ): del registry_map[index] - #apply variable screen + #apply variable screen if self.variable_screen: for index in reversed(range(len(registry_map))): item = registry_map[index] if ( - item.documented_name.strip().lower() in self.variable_mask + item.documented_name.strip().lower() in self.variable_mask and item.variable_name.strip().lower() in self.variable_mask ): - del registry_map[index] + del registry_map[index] return registry_map - + def calculate_registry_ranges(self, map : list[registry_map_entry], max_register : int) -> list[tuple]: ''' read optimization; calculate which ranges to read''' max_batch_size = 45 #see manual; says max batch is 45 @@ -721,7 +720,7 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register ranges : list[tuple] = [] while (start := start+max_batch_size) <= max_register: - + registers : list[int] = [] #use a list, im too lazy to write logic end = start+max_batch_size @@ -731,7 +730,7 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register continue if register.write_mode == WriteMode.WRITEONLY: ##Write Only; skip continue - + registers.append(register.register) if registers: #not empty @@ -743,13 +742,13 @@ def find_protocol_file(self, file : str, base_dir : str = '' ) -> str: path = base_dir + '/' + file if os.path.exists(path): return path - + suffix = file.split('_', 1)[0] path = base_dir + '/' + suffix +'/' + file if os.path.exists(path): return path - + #find file by name, recurisvely. last resort search_pattern = os.path.join(base_dir, '**', file) matches = glob.glob(search_pattern, recursive=True) @@ -775,7 +774,7 @@ def load_registry_map(self, registry_type : Registry_Type, file : str = '', sett self.registry_map[registry_type] = self.load__registry(path, registry_type) size : int = 0 - + #get max register size for item in self.registry_map[registry_type]: if item.register > size: @@ -791,7 +790,7 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma register = registry[entry.register][0] #can bus uses tuple for timestamp else: register = registry[entry.register] - + if entry.register_byte > 0: register = register[entry.register_byte:] @@ -817,13 +816,13 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma #handle custom sizes, less than 1 register end_bit = flag_size + start_bit - + if entry.documented_name+'_codes' in self.codes: code_key : str = entry.documented_name+'_codes' flags : list[str] = [] flag_indexes : list[str] = [] for i in range(start_bit, end_bit): # Iterate over each bit position (0 to 15) - byte = i // 8 + byte = i // 8 bit = i % 8 val = register[byte] # Check if the i-th bit is set @@ -842,7 +841,7 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma bits = multibit_flag.split('&') # Split key into 'bits' if all(bit in flag_indexes_set for bit in bits): # Check if all bits are present in the flag_indexes_set flags.append(self.codes[code_key][multibit_flag]) - + value = ",".join(flags) else: flags : list[str] = [] @@ -904,10 +903,10 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma entry.documented_name+'_codes' in self.codes): try: cleanval = str(int(value)) - + if cleanval in self.codes[entry.documented_name+'_codes']: value = self.codes[entry.documented_name+'_codes'][cleanval] - except: + except Exception: #do nothing; try is for intval value = value @@ -919,7 +918,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma if entry.data_type == Data_Type.UINT: #read uint if entry.register + 1 not in registry: return - + value = float((registry[entry.register] << 16) + registry[entry.register + 1]) elif entry.data_type == Data_Type.SHORT: #read signed short val = registry[entry.register] @@ -934,7 +933,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma elif entry.data_type == Data_Type.INT: #read int if entry.register + 1 not in registry: return - + combined_value_unsigned = (registry[entry.register] << 16) + registry[entry.register + 1] # Convert the combined unsigned value to a signed integer if necessary @@ -947,7 +946,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma #value = struct.unpack(' dict[str,str]: '''process registry into appropriate datatypes and names -- maybe add func for single entry later?''' - + concatenate_registry : dict = {} info = {} for entry in map: if entry.register not in registry: continue - value = '' + value = '' if isinstance(registry[entry.register], bytes): value = self.process_register_bytes(registry, entry) else: value = self.process_register_ushort(registry, entry) - + #if item.unit: # value = str(value) + item.unit if entry.concatenate: @@ -1080,7 +1079,7 @@ def process_registery(self, registry : Union[dict[int, int], dict[int, bytes]] , return info def validate_registry_entry(self, entry : registry_map_entry, val) -> int: - #if code, validate first. + #if code, validate first. if entry.documented_name+'_codes' in self.codes: if val in self.codes[entry.documented_name+'_codes']: return 1 @@ -1098,7 +1097,9 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int: if int(val) >= entry.value_min and int(val) <= entry.value_max: return 1 - return 0 + self._log.error(f"validate_registry_entry fail overall {entry.value_min} / {entry.value_max} / {int(val)}") + + return 0 def evaluate_expressions(self, expression, variables : dict[str,str]): # Define the register string @@ -1151,7 +1152,7 @@ def evaluate_ranges(expression): return results - def evaluate_expression(expression): + def evaluate_expression(expression): # Define a regular expression pattern to match "maths" var_pattern = re.compile(r'\[(?P.*?)\]') @@ -1160,15 +1161,15 @@ def replace_vars(match): try: maths = match.group("maths") maths = re.sub(r'\s', '', maths) #remove spaces, because ast.parse doesnt like them - + # Parse the expression safely tree = ast.parse(maths, mode='eval') # Evaluate the expression end_value = eval(compile(tree, filename='', mode='eval')) - + return str(end_value) - except : + except Exception: return match.group(0) # Replace variables with their values @@ -1188,5 +1189,5 @@ def replace_vars(match): for r in results: print(evaluate_expression(r)) - -#settings = protocol_settings('v0.14') \ No newline at end of file + +#settings = protocol_settings('v0.14') diff --git a/classes/transports/canbus.py b/classes/transports/canbus.py index a212070..f715817 100644 --- a/classes/transports/canbus.py +++ b/classes/transports/canbus.py @@ -9,8 +9,8 @@ from .transport_base import transport_base -from ..protocol_settings import Data_Type, Registry_Type, registry_map_entry, protocol_settings -from defs.common import strtobool, strtoint +from ..protocol_settings import Registry_Type, registry_map_entry, protocol_settings +from defs.common import strtoint from collections import OrderedDict from typing import TYPE_CHECKING @@ -46,7 +46,7 @@ class canbus(transport_base): cacheTimeout : int = 120 ''' seconds to keep message in cache ''' - emptyTime : float = None + emptyTime : float = None ''' the last time values were read for watchdog''' watchDogTime : float = 120 @@ -93,7 +93,7 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti thread = threading.Thread(target=self.start_loop) - thread.daemon = True + thread.daemon = True thread.start() self.connected = True @@ -116,21 +116,21 @@ def is_socketcan_up(self) -> bool: if not self.linux: self._log.error("socketcan status not implemented for windows") return True - + try: with open(f'/sys/class/net/{self.port}/operstate', 'r') as f: state = f.read().strip() return state == 'up' except FileNotFoundError: return False - + def start_loop(self): self.read_bus(self.bus) def read_bus(self, bus : can.BusABC): ''' read canbus asynco and store results in cache''' msg = None #fix scope bug - + while True: try: msg = self.bus.recv() # This will be non-blocking with asyncio @@ -145,13 +145,13 @@ def read_bus(self, bus : can.BusABC): except Exception as e: # Handle unexpected errors self._log.error(f"An unexpected error occurred: {e}") - + if msg: self._log.info(f"Received message: {msg.arbitration_id:X}, data: {msg.data}") - - with self.lock: - #convert bytearray to bytes; were working with bytes. + + with self.lock: + #convert bytearray to bytes; were working with bytes. self.cache[msg.arbitration_id] = (bytes(msg.data), time.time()) #time.sleep(1) no need for sleep because recv is blocking @@ -159,27 +159,27 @@ def read_bus(self, bus : can.BusABC): def clean_cache(self): current_time = time.time() - + with self.lock: # Create a list of keys to remove (don't remove while iterating) keys_to_delete = [msg_id for msg_id, (_, timestamp) in self.cache.items() if current_time - timestamp > self.cacheTimeout] - + # Remove old messages from the dictionary for key in keys_to_delete: del self.cache[key] def init_after_connect(self): return True - + ''' todo, a startup phase to get serial number''' #from transport_base settings if self.write_enabled: self.enable_write() #if sn is empty, attempt to autoread it - if not self.device_serial_number: + if not self.device_serial_number: self.device_serial_number = self.read_serial_number() - + def read_serial_number(self) -> str: ''' not so simple in canbus''' return '' @@ -187,7 +187,7 @@ def read_serial_number(self) -> str: print("read SN: " +serial_number) if serial_number: return serial_number - + sn2 = "" sn3 = "" fields = ['Serial No 1', 'Serial No 2', 'Serial No 3', 'Serial No 4', 'Serial No 5'] @@ -200,19 +200,19 @@ def read_serial_number(self) -> str: if not hasattr(data, 'registers') or data.registers is None: self._log.critical("Failed to get serial number register ("+field+") ; exiting") exit() - + serial_number = serial_number + str(data.registers[0]) data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder='big') - sn2 = sn2 + str(data_bytes.decode('utf-8')) + sn2 = sn2 + str(data_bytes.decode('utf-8')) sn3 = str(data_bytes.decode('utf-8')) + sn3 time.sleep(self.modbus_delay*2) #sleep inbetween requests so modbus can rest - + print(sn2) print(sn3) - - if not re.search("[^a-zA-Z0-9\_]", sn2) : + + if not re.search(r"[^a-zA-Z0-9\_]", sn2) : serial_number = sn2 return serial_number @@ -236,7 +236,7 @@ def read_data(self) -> dict[str, str]: new_info = self.protocolSettings.process_registery(registry, self.protocolSettings.get_registry_map(Registry_Type.ZERO)) - info.update(new_info) + info.update(new_info) currentTime = time.time() @@ -255,13 +255,13 @@ def read_data(self) -> dict[str, str]: def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): ''' read's variable from cache''' - ##clean for convinecne + ##clean for convinecne if variable_name: variable_name = variable_name.strip().lower().replace(' ', '_') registry_map = self.protocolSettings.get_registry_map(registry_type) - if entry == None: + if entry is None: for e in registry_map: if e.variable_name == variable_name: entry = e @@ -274,4 +274,4 @@ def read_variable(self, variable_name : str, registry_type : Registry_Type, entr results = self.protocolSettings.process_register_bytes(self.cache, entry) return results[entry.variable_name] else: - return None #empty \ No newline at end of file + return None #empty diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index c849b81..ef299c7 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -25,8 +25,8 @@ class modbus_base(transport_base): clients : dict[str, 'BaseModbusClient'] = {} ''' str is identifier, dict of clients when multiple transports use the same ports ''' - #non-static here for reference, type hinting, python bs ect... - modbus_delay_increament : float = 0.05 + #non-static here for reference, type hinting, python bs ect... + modbus_delay_increament : float = 0.05 ''' delay adjustment every error. todo: add a setting for this ''' modbus_delay_setting : float = 0.85 @@ -77,7 +77,7 @@ def init_after_connect(self): self.enable_write() #if sn is empty, attempt to autoread it - if not self.device_serial_number: + if not self.device_serial_number: self.device_serial_number = self.read_serial_number() self.update_identifier() @@ -85,13 +85,13 @@ def connect(self): if self.connected and self.first_connect: self.first_connect = False self.init_after_connect() - + def read_serial_number(self) -> str: serial_number = str(self.read_variable("Serial Number", Registry_Type.HOLDING)) self._log.info("read SN: " +serial_number) if serial_number: return serial_number - + sn2 = "" sn3 = "" fields = ['Serial No 1', 'Serial No 2', 'Serial No 3', 'Serial No 4', 'Serial No 5'] @@ -104,18 +104,18 @@ def read_serial_number(self) -> str: if not hasattr(data, 'registers') or data.registers is None: self._log.critical("Failed to get serial number register ("+field+") ; exiting") exit() - + serial_number = serial_number + str(data.registers[0]) data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder='big') - sn2 = sn2 + str(data_bytes.decode('utf-8')) + sn2 = sn2 + str(data_bytes.decode('utf-8')) sn3 = str(data_bytes.decode('utf-8')) + sn3 time.sleep(self.modbus_delay*2) #sleep inbetween requests so modbus can rest - + print(sn2) print(sn3) - + if not re.search("[^a-zA-Z0-9_]", sn2) : serial_number = sn2 @@ -161,7 +161,7 @@ def read_data(self) -> dict[str, str]: if False: new_info = {self.__input_register_prefix + key: value for key, value in new_info.items()} - info.update(new_info) + info.update(new_info) if not info: self._log.info("Register is Empty; transport busy?") @@ -172,7 +172,7 @@ def validate_protocol(self, protocolSettings : 'protocol_settings') -> float: score_percent = self.validate_registry(Registry_Type.HOLDING) return score_percent - + def validate_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) -> float: score : float = 0 info = {} @@ -185,7 +185,7 @@ def validate_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) if value.concatenate and value.register != value.concatenate_registers[0]: #only eval concated values once evaluate = False - + if evaluate: score = score + self.protocolSettings.validate_registry_entry(value, info[value.variable_name]) @@ -193,7 +193,7 @@ def validate_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) percent = score*100/maxScore self._log.info("validation score: " + str(score) + " of " + str(maxScore) + " : " + str(round(percent)) + "%") return percent - + def analyze_protocol(self, settings_dir : str = 'protocols'): print("=== PROTOCOL ANALYZER ===") protocol_names : list[str] = [] @@ -262,7 +262,7 @@ def analyze_protocol(self, settings_dir : str = 'protocols'): #very well possible the registers will be incomplete due to different hardware sizes #so dont assume they are set / complete #we'll see about the behaviour. if it glitches, this could be a way to determine protocol. - + input_register_score : dict[str, int] = {} holding_register_score : dict[str, int] = {} @@ -280,8 +280,8 @@ def evaluate_score(entry : registry_map_entry, val): if entry.value_regex: #regex validation if re.match(entry.value_regex, val): - mod = mod * 2 - else: + mod = mod * 2 + else: mod = mod * -2 #regex validation failed, double damage! score = score + (2 * mod) #double points for ascii @@ -300,18 +300,18 @@ def evaluate_score(entry : registry_map_entry, val): return score - + for name, protocol in protocols.items(): input_register_score[name] = 0 holding_register_score[name] = 0 - #very rough percentage. tood calc max possible score. + #very rough percentage. tood calc max possible score. input_valid_count[name] = 0 holding_valid_count[name] = 0 #process registry based on protocol input_info = protocol.process_registery(input_registry, protocol.registry_map[Registry_Type.INPUT]) holding_info = protocol.process_registery(input_registry, protocol.registry_map[Registry_Type.HOLDING]) - + for entry in protocol.registry_map[Registry_Type.INPUT]: if entry.variable_name in input_info: @@ -333,7 +333,7 @@ def evaluate_score(entry : registry_map_entry, val): holding_register_score[name] = holding_register_score[name] + score - + protocol_scores: dict[str, int] = {} #combine scores for name, protocol in protocols.items(): @@ -344,23 +344,21 @@ def evaluate_score(entry : registry_map_entry, val): print("=== "+str(name)+" - "+str(protocol_scores[name])+" ===") print("input register score: " + str(input_register_score[name]) + "; valid registers: "+str(input_valid_count[name])+" of " + str(len(protocols[name].get_registry_map(Registry_Type.INPUT)))) print("holding register score : " + str(holding_register_score[name]) + "; valid registers: "+str(holding_valid_count[name])+" of " + str(len(protocols[name].get_registry_map(Registry_Type.HOLDING)))) - - + + def write_variable(self, entry : registry_map_entry, value : str, registry_type : Registry_Type = Registry_Type.HOLDING): """ writes a value to a ModBus register; todo: registry_type to handle other write functions""" #read current value current_registers = self.read_modbus_registers(start=entry.register, end=entry.register, registry_type=registry_type) - results = self.protocolSettings.process_registery(current_registers, self.protocolSettings.get_registry_map(registry_type)) current_value = current_registers[entry.register] - - if not self.protocolSettings.validate_registry_entry(entry, current_value): - raise ValueError("Invalid value in register. unsafe to write") #i need to figure out a better error handler for theese. - +# if not self.protocolSettings.validate_registry_entry(entry, current_value): +# raise ValueError(f"Invalid value in register '{current_value}'. Unsafe to write") + if not self.protocolSettings.validate_registry_entry(entry, value): - raise ValueError("Invalid new value. unsafe to write") - + raise ValueError(f"Invalid new value, '{value}'. Unsafe to write") + #handle codes if entry.variable_name+"_codes" in self.protocolSettings.codes: codes = self.protocolSettings.codes[entry.variable_name+"_codes"] @@ -399,21 +397,21 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type raise ValueError("something went wrong bitwise") else: raise TypeError("Unsupported data type") - - if ushortValue == None: + + if ushortValue is None: raise ValueError("Invalid value - None") - self.write_register(entry.register, ushortValue, registry_type=registry_type) + self.write_register(entry.register, ushortValue) def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): - ##clean for convinecne + ##clean for convinecne if variable_name: variable_name = variable_name.strip().lower().replace(' ', '_') registry_map = self.protocolSettings.get_registry_map(registry_type) - if entry == None: + if entry is None: for e in registry_map: if e.variable_name == variable_name: entry = e @@ -428,18 +426,18 @@ def read_variable(self, variable_name : str, registry_type : Registry_Type, entr else: start = entry.register end = max(entry.concatenate_registers) - + registers = self.read_modbus_registers(start=start, end=end, registry_type=registry_type) results = self.protocolSettings.process_registery(registers, registry_map) return results[entry.variable_name] - + def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, end : int = None, batch_size : int = 45, registry_type : Registry_Type = Registry_Type.INPUT ) -> dict: ''' maybe move this to transport_base ?''' if not ranges: #ranges is empty, use min max - if start == 0 and end == None: + if start == 0 and end is None: return {} #empty - + end = end + 1 ranges = [] start = start - batch_size @@ -465,7 +463,7 @@ def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, en try: register = self.read_registers(range[0], range[1], registry_type=registry_type) - except ModbusIOException as e: + except ModbusIOException as e: self._log.error("ModbusIOException : ", e.error_code) if e.error_code == 4: #if no response; probably time out. retry with increased delay isError = True @@ -476,14 +474,14 @@ def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, en if isinstance(register, bytes) or register.isError() or isError: #sometimes weird errors are handled incorrectly and response is a ascii error string if isinstance(register, bytes): self._log.error(register.decode('utf-8')) - else: + else: self._log.error(register.__str__) self.modbus_delay += self.modbus_delay_increament #increase delay, error is likely due to modbus being busy if self.modbus_delay > 60: #max delay. 60 seconds between requests should be way over kill if it happens self.modbus_delay = 60 - if retry > retries: #instead of none, attempt to continue to read. but with no retires. + if retry > retries: #instead of none, attempt to continue to read. but with no retires. continue else: #undo step in loop and retry read @@ -492,17 +490,17 @@ def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, en self._log.warning("Retry("+str(retry)+" - ("+str(total_retries)+")) range("+str(index)+")") index = index - 1 continue - elif self.modbus_delay > self.modbus_delay_setting: #no error, decrease delay + elif self.modbus_delay > self.modbus_delay_setting: #no error, decrease delay self.modbus_delay -= self.modbus_delay_increament if self.modbus_delay < self.modbus_delay_setting: self.modbus_delay = self.modbus_delay_setting - - + + retry -= 1 if retry < 0: retry = 0 - + #combine registers into "registry" i = -1 while(i := i + 1 ) < range[1]: @@ -510,12 +508,12 @@ def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, en registry[i+range[0]] = register.registers[i] return registry - + def read_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) -> dict[str,str]: map = self.protocolSettings.get_registry_map(registry_type) if not map: return {} - + registry = self.read_modbus_registers(self.protocolSettings.get_registry_ranges(registry_type), registry_type=registry_type) info = self.protocolSettings.process_registery(registry, map) - return info \ No newline at end of file + return info diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index d79b808..561658c 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -1,4 +1,3 @@ -import logging from classes.protocol_settings import Registry_Type, protocol_settings import inspect @@ -18,25 +17,21 @@ class modbus_rtu(modbus_base): port : str = "/dev/ttyUSB0" addresses : list[int] = [] baudrate : int = 9600 - client : ModbusSerialClient + client : ModbusSerialClient pymodbus_slave_arg = 'unit' def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): - #logger = logging.getLogger(__name__) - #logging.basicConfig(level=logging.DEBUG) - super().__init__(settings, protocolSettings=protocolSettings) - self.port = settings.get("port", "") if not self.port: raise ValueError("Port is not set") - - self.port = find_usb_serial_port(self.port) + + self.port = find_usb_serial_port(self.port) if not self.port: raise ValueError("Port is not valid / not found") - + print("Serial Port : " + self.port + " = ", get_usb_serial_port_info(self.port)) #print for config convience if "baud" in self.protocolSettings.settings: @@ -46,7 +41,7 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings address : int = settings.getint("address", 0) self.addresses = [address] - + # pymodbus compatability; unit was renamed to address if 'slave' in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: self.pymodbus_slave_arg = 'slave' @@ -60,22 +55,22 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings if client_str in modbus_base.clients: self.client = modbus_base.clients[client_str] return - + if 'method' in init_signature.parameters: - self.client = ModbusSerialClient(method='rtu', port=self.port, - baudrate=int(self.baudrate), + self.client = ModbusSerialClient(method='rtu', port=self.port, + baudrate=int(self.baudrate), stopbits=1, parity='N', bytesize=8, timeout=2 ) else: self.client = ModbusSerialClient( - port=self.port, - baudrate=int(self.baudrate), + port=self.port, + baudrate=int(self.baudrate), stopbits=1, parity='N', bytesize=8, timeout=2 ) - + #add to clients modbus_base.clients[client_str] = self.client - + def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): if 'unit' not in kwargs: @@ -89,11 +84,11 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr return self.client.read_input_registers(address=start, count=count, **kwargs) elif registry_type == Registry_Type.HOLDING: return self.client.read_holding_registers(address=start, count=count, **kwargs) - + def write_register(self, register : int, value : int, **kwargs): if not self.write_enabled: - return - + return + if 'unit' not in kwargs: kwargs = {'unit': self.addresses[0], **kwargs} @@ -105,4 +100,4 @@ def write_register(self, register : int, value : int, **kwargs): def connect(self): self.connected = self.client.connect() - super().connect() \ No newline at end of file + super().connect() diff --git a/classes/transports/modbus_tcp.py b/classes/transports/modbus_tcp.py index bdf62d9..22ce4af 100644 --- a/classes/transports/modbus_tcp.py +++ b/classes/transports/modbus_tcp.py @@ -1,4 +1,3 @@ -import logging import inspect from classes.protocol_settings import Registry_Type, protocol_settings @@ -16,17 +15,14 @@ class modbus_tcp(modbus_base): port : str = 502 host : str = "" - client : ModbusTcpClient + client : ModbusTcpClient pymodbus_slave_arg = 'unit' def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): - #logger = logging.getLogger(__name__) - #logging.basicConfig(level=logging.DEBUG) - self.host = settings.get("host", "") if not self.host: raise ValueError("Host is not set") - + self.port = settings.getint("port", self.port) # pymodbus compatability; unit was renamed to address @@ -45,7 +41,7 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings modbus_base.clients[client_str] = self.client super().__init__(settings, protocolSettings=protocolSettings) - + def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): if 'unit' not in kwargs: @@ -59,7 +55,7 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr return self.client.read_input_registers(start, count, **kwargs ) elif registry_type == Registry_Type.HOLDING: return self.client.read_holding_registers(start, count, **kwargs) - + def connect(self): self.connected = self.client.connect() - super().connect() \ No newline at end of file + super().connect() diff --git a/classes/transports/modbus_tls.py b/classes/transports/modbus_tls.py index 2afeb0d..c6b464a 100644 --- a/classes/transports/modbus_tls.py +++ b/classes/transports/modbus_tls.py @@ -1,4 +1,3 @@ -import logging from classes.protocol_settings import Registry_Type, protocol_settings from pymodbus.client.sync import ModbusTlsClient from .transport_base import transport_base @@ -11,15 +10,12 @@ class modbus_udp(transport_base): hostname : str = "" ''' optional for cert ''' - + certfile : str = "" keyfile : str = "" - client : ModbusTlsClient + client : ModbusTlsClient def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): - #logger = logging.getLogger(__name__) - #logging.basicConfig(level=logging.DEBUG) - self.host = settings.get("host", "") if not self.host: raise ValueError("Host is not set") @@ -29,19 +25,19 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings self.certfile = settings.get("certfile", "") if not self.certfile: raise ValueError("certfile is not set") - + self.keyfile = settings.get("keyfile", "") if not self.keyfile: raise ValueError("keyfile is not set") - + self.hostname = settings.get("hostname", self.host) - self.client = ModbusTlsClient(host=self.host, + self.client = ModbusTlsClient(host=self.host, hostname = self.hostname, certfile = self.certfile, keyfile = self.keyfile, - port=self.port, - timeout=7, + port=self.port, + timeout=7, retries=3) super().__init__(settings, protocolSettings=protocolSettings) @@ -53,4 +49,4 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr def connect(self): self.connected = self.client.connect() - super().connect() \ No newline at end of file + super().connect() diff --git a/classes/transports/modbus_udp.py b/classes/transports/modbus_udp.py index 9f4533b..a9f77b4 100644 --- a/classes/transports/modbus_udp.py +++ b/classes/transports/modbus_udp.py @@ -1,4 +1,3 @@ -import logging from classes.protocol_settings import Registry_Type, protocol_settings from pymodbus.client.sync import ModbusUdpClient from .transport_base import transport_base @@ -8,22 +7,19 @@ class modbus_udp(transport_base): port : int = 502 host : str = "" - client : ModbusUdpClient + client : ModbusUdpClient def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): - #logger = logging.getLogger(__name__) - #logging.basicConfig(level=logging.DEBUG) - self.host = settings.get("host", "") if not self.host: raise ValueError("Host is not set") - + self.port = settings.getint("port", self.port) self.client = ModbusUdpClient(host=self.host, port=self.port, timeout=7, retries=3) super().__init__(settings, protocolSettings=protocolSettings) - + def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): if registry_type == Registry_Type.INPUT: return self.client.read_input_registers(start, count, **kwargs) @@ -32,4 +28,4 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr def connect(self): self.connected = self.client.connect() - super().connect() \ No newline at end of file + super().connect() diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index 5600aae..9a6227e 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -1,8 +1,7 @@ import atexit -import logging import random import time -import json +import json import warnings import paho.mqtt.client @@ -26,14 +25,10 @@ class mqtt(transport_base): discovery_topic : str = "homeassistant" discovery_enabled : bool = False json : bool = False - reconnect_delay : int = 7 - ''' seconds ''' - + reconnect_delay : int = 7 # seconds reconnect_attempts : int = 21 - #max_precision : int = - 1 - holding_register_prefix : str = "" input_register_prefix : str = "" @@ -48,7 +43,7 @@ def __init__(self, settings : SectionProxy): self.host = settings.get('host', fallback="") if not self.host: raise ValueError("Host is not set") - + self.port = settings.getint('port', fallback=self.port) self.base_topic = settings.get('base_topic', fallback=self.base_topic).rstrip('/') self.error_topic = settings.get('error_topic', fallback=self.error_topic).rstrip('/') @@ -73,7 +68,7 @@ def __init__(self, settings : SectionProxy): if not username: raise ValueError("User is not set") - + if not password: warnings.warn("MQTT Password is empty", RuntimeWarning) @@ -95,7 +90,7 @@ def __init__(self, settings : SectionProxy): self.write_enabled = True #set default super().__init__(settings) - + def connect(self): self._log.info("mqtt connect") @@ -112,7 +107,7 @@ def exit_handler(self): self._log.warning("MQTT Exiting...") self.client.publish( self.base_topic + '/' + self.device_identifier + "/availability","offline") return - + def mqtt_reconnect(self): self._log.info("Disconnected from MQTT Broker!") if self.__reconnecting != 0: #stop double calls @@ -122,22 +117,22 @@ def mqtt_reconnect(self): self.__reconnecting = time.time() try: self._log.warning("Attempting to reconnect("+str(attempt)+")...") - if random.randint(0,1): #alternate between methods because built in reconnect might be unreliable. + if random.randint(0,1): #alternate between methods because built in reconnect might be unreliable. self.client.reconnect() else: self.client.loop_stop() self.client.connect(str(self.host), int(self.port), 60) self.client.loop_start() - #sleep to give a chance to reconnect. - time.sleep(self.reconnect_delay) + #sleep to give a chance to reconnect. + time.sleep(self.reconnect_delay) if self.connected: self.__reconnecting = 0 return - except: + except Exception: self._log.warning("Reconnection failed. Retrying in "+str(self.reconnect_delay)+" second(s)...") time.sleep(self.reconnect_delay) - + #failed to reonnect self._log.critical("Failed to Reconnect, Too many attempts") self.__reconnecting = 0 @@ -155,14 +150,14 @@ def on_connect(self, client, userdata, flags, rc): def write_data(self, data : dict[str, str], from_transport : transport_base): if not self.write_enabled: - return - + return + if self.connected: self.connected = self.client.is_connected() - - self._log.info(f"write data from [{from_transport.transport_name}] to mqtt transport") - self._log.info(data) - #have to send this every loop, because mqtt doesnt disconnect when HA restarts. HA bug. + + self._log.info(f"write data from [{from_transport.transport_name}] to mqtt transport") + self._log.info(data) + #have to send this every loop, because mqtt doesnt disconnect when HA restarts. HA bug. info = self.client.publish(self.base_topic + '/' + from_transport.device_identifier + "/availability","online", qos=0,retain=True) if info.rc == MQTT_ERR_NO_CONN: self.connected = False @@ -173,7 +168,7 @@ def write_data(self, data : dict[str, str], from_transport : transport_base): self.client.publish(self.base_topic+'/'+from_transport.device_identifier, json_object, 0, properties=self.mqtt_properties) else: for entry, val in data.items(): - if isinstance(val, float) and self.max_precision >= 0: #apply max_precision on mqtt transport + if isinstance(val, float) and self.max_precision >= 0: #apply max_precision on mqtt transport val = round(val, self.max_precision) self.client.publish(str(self.base_topic+'/'+from_transport.device_identifier+'/'+entry).lower(), str(val)) @@ -189,7 +184,7 @@ def client_on_message(self, client, userdata, msg): #self.write_variable(entry, value=str(msg.payload.decode('utf-8'))) def init_bridge(self, from_transport : transport_base): - + if from_transport.write_enabled: self.__write_topics = {} #subscribe to write topics @@ -217,7 +212,7 @@ def mqtt_discovery(self, from_transport : transport_base): registry_map : list[registry_map_entry] = [] for entries in from_transport.protocolSettings.registry_map.values(): - registry_map.extend(entries) + registry_map.extend(entries) length = len(registry_map) count = 0 @@ -226,7 +221,7 @@ def mqtt_discovery(self, from_transport : transport_base): if item.concatenate and item.register != item.concatenate_registers[0]: continue #skip all except the first register so no duplicates - + if item.write_mode == WriteMode.READDISABLED: #disabled continue @@ -254,25 +249,25 @@ def mqtt_discovery(self, from_transport : transport_base): writePrefix = "" if from_transport.write_enabled and ( item.write_mode == WriteMode.WRITE or item.write_mode == WriteMode.WRITEONLY ): - writePrefix = "" #home assistant doesnt like write prefix + writePrefix = "" #home assistant doesnt like write prefix disc_payload['state_topic'] = self.base_topic + '/' +from_transport.device_identifier + writePrefix+ "/"+clean_name - + if item.unit: disc_payload['unit_of_measurement'] = item.unit discovery_topic = self.discovery_topic+"/sensor/HN-" + from_transport.device_serial_number + writePrefix + "/" + disc_payload['name'].replace(' ', '_') + "/config" - + self.client.publish(discovery_topic, json.dumps(disc_payload),qos=1, retain=True) - + #send WO message to indicate topic is write only if item.write_mode == WriteMode.WRITEONLY: self.client.publish(disc_payload['state_topic'], "WRITEONLY") - + time.sleep(0.07) #slow down for better reliability - + self.client.publish(disc_payload['availability_topic'],"online",qos=0, retain=True) print() - self._log.info("Published HA "+str(count)+"x Discovery Topics") \ No newline at end of file + self._log.info("Published HA "+str(count)+"x Discovery Topics") diff --git a/classes/transports/pace.py b/classes/transports/pace.py index 0bc0c48..4bfb1e9 100644 --- a/classes/transports/pace.py +++ b/classes/transports/pace.py @@ -3,19 +3,15 @@ import logging from classes.protocol_settings import Registry_Type from pymodbus.client.sync import ModbusSerialClient, BaseModbusClient -from pymodbus.transaction import ModbusRtuFramer +from pymodbus.transaction import ModbusRtuFramer from pymodbus.factory import ClientDecoder from pymodbus.constants import Defaults -from pymodbus.exceptions import ModbusIOException -from pymodbus.exceptions import InvalidMessageReceivedException from pymodbus.utilities import checkCRC, computeCRC -from pymodbus.utilities import hexlify_packets, ModbusTransactionState from pymodbus.compat import byte2int -from pymodbus.framer import ModbusFramer, FRAME_HEADER, BYTE_ORDER +from pymodbus.framer import FRAME_HEADER, BYTE_ORDER -import logging _logger = logging.getLogger(__name__) RTU_FRAME_HEADER = BYTE_ORDER + FRAME_HEADER @@ -112,7 +108,7 @@ def calculate_crc(puchMsg, usDataLen): def calcCRC_3(data, size): crcHi = 0XFF crcLo = 0xFF - + crcHiTable = [ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, @@ -190,10 +186,7 @@ def buildPacket(self, message): packet = struct.pack(RTU_FRAME_HEADER, message.unit_id, 0x03) + data - - size = len(packet) crc = computeCRC(packet) - crc2 = calculate_crc(packet,size) #packet struct: #slave address - 0x01 - 0x10 @@ -206,7 +199,7 @@ def buildPacket(self, message): #crc hi #error 0x4 = bad CRC. so standard CRC is correct - + #crc16 = (modbusdata[bufferIndex] * 0x0100) + modbusdata[bufferIndex + 1] #metCRC16 = self.calcCRC16(modbusdata, bufferIndex) @@ -215,7 +208,7 @@ def buildPacket(self, message): message.transaction_id = message.unit_id # Ensure that transaction is actually the unit id for serial comms return packet - + def checkFrame(self): """ Check if the next frame is available. @@ -239,8 +232,8 @@ def checkFrame(self): return False except (IndexError, KeyError, struct.error): return False - -class CustomModbusSerialClient(ModbusSerialClient): + +class CustomModbusSerialClient(ModbusSerialClient): def __init__(self, method='ascii', **kwargs): """ Initialize a serial client instance @@ -297,20 +290,17 @@ class pace: port : str = "/dev/ttyUSB0" baudrate : int = 9600 - client : CustomModbusSerialClient + client : CustomModbusSerialClient def __init__(self, settings : dict[str,str]): - logger = logging.getLogger(__name__) - logging.basicConfig(level=logging.DEBUG) - if "port" in settings: self.port = settings["port"] if "baudrate" in settings: self.baudrate = settings["baudrate"] - self.client = CustomModbusSerialClient(method='binary', port=self.port, - baudrate=int(self.baudrate), + self.client = CustomModbusSerialClient(method='binary', port=self.port, + baudrate=int(self.baudrate), stopbits=1, parity='N', bytesize=8, timeout=2 ) @@ -319,8 +309,8 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr return self.client.read_input_registers(start, count, **kwargs) elif registry_type == Registry_Type.HOLDING: return self.client.read_holding_registers(start, count, **kwargs) - + time.sleep(4) def connect(self): - self.client.connect() \ No newline at end of file + self.client.connect() diff --git a/classes/transports/serial_frame_client.py b/classes/transports/serial_frame_client.py index 30aec00..6778075 100644 --- a/classes/transports/serial_frame_client.py +++ b/classes/transports/serial_frame_client.py @@ -63,11 +63,11 @@ def read(self, reset_buffer = True, frames = 1) -> list[bytes] | bytes: buffer = bytearray() self.pending_frames.clear() - #for shatty order sensitive protocols. + #for shatty order sensitive protocols. # Clear input buffers if reset_buffer: self.client.reset_input_buffer() - + timedout = time.time() + self.timeout self.client.timeout = self.timeout frameCount = 0 @@ -93,11 +93,11 @@ def read(self, reset_buffer = True, frames = 1) -> list[bytes] | bytes: eoi_index = buffer.find(self.eoi) if eoi_index != -1: - + frame = buffer[len(self.soi):eoi_index] if frames == 1: return frame - + if frameCount > 1: # Extract and store the complete frame self.pending_frames.append(frame) @@ -110,7 +110,7 @@ def read(self, reset_buffer = True, frames = 1) -> list[bytes] | bytes: # Find next SOI index in the remaining buffer soi_index = buffer.find(self.soi) - + else: # If no EOI is found and buffer size exceeds max_frame_size, clear buffer if len(buffer) > self.max_frame_size: @@ -164,5 +164,5 @@ def read_thread(self): self.on_message(frame) time.sleep(0.01) - - + + diff --git a/classes/transports/serial_pylon.py b/classes/transports/serial_pylon.py index b4f6ee0..fcc309f 100644 --- a/classes/transports/serial_pylon.py +++ b/classes/transports/serial_pylon.py @@ -47,7 +47,7 @@ class serial_pylon(transport_base): #this format is pretty common; i need a name for it. SOI : bytes = b'\x7e' # aka b"~" - VER : bytes = b'\x00' + VER : bytes = b'\x00' ''' version has to be fetched first ''' ADR : bytes CID1 : bytes @@ -64,8 +64,8 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self.port = settings.get("port", "") if not self.port: raise ValueError("Port is not set") - - self.port = find_usb_serial_port(self.port) + + self.port = find_usb_serial_port(self.port) print("Serial Port : " + self.port + " = "+get_usb_serial_port_info(self.port)) #print for config convience self.baudrate = settings.getint("baudrate", 9600) @@ -76,10 +76,10 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self.ADR = struct.pack('B', address) #todo, multi address support later - self.client = serial_frame_client(self.port, - self.baudrate, - self.SOI, - self.EOI, + self.client = serial_frame_client(self.port, + self.baudrate, + self.SOI, + self.EOI, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, exclusive=True) @@ -97,7 +97,7 @@ def connect(self): self._log.info("pylon protocol version is "+str(version)) self.VER = version - name = self.read_variable('battery_name') + name = self.read_variable('battery_name') self._log.info(name) pass @@ -105,13 +105,13 @@ def read_data(self): info = {} registry_map = self.protocolSettings.get_registry_map() - + data : dict [int, bytes] = {} for entry in registry_map: - + if entry.register not in data: #todo: need to check send data. later. command = entry.register #CID1 and CID2 combined creates a single ushort - self.send_command(command) + self.send_command(command) frame = self.client.read() if frame: #decode info to ascii: bytes.fromhex(name.decode("utf-8")).decode("ascii") raw = getattr(self.decode_frame(frame), 'info') @@ -127,23 +127,23 @@ def read_data(self): return info def read_variable(self, variable_name : str, entry : 'registry_map_entry' = None, attribute : str = 'info'): - ##clean for convinecne + ##clean for convinecne if variable_name: variable_name = variable_name.strip().lower().replace(' ', '_') registry_map = self.protocolSettings.get_registry_map() - if entry == None: + if entry is None: for e in registry_map: if e.variable_name == variable_name: entry = e break - + if entry: #entry.concatenate this protocol probably doesnt require concatenate, since info is variable length. command = entry.register #CID1 and CID2 combined creates a single ushort - self.send_command(command) + self.send_command(command) frame = self.client.read() if frame: #decode info to ascii: bytes.fromhex(name.decode("utf-8")).decode("ascii") raw = getattr(self.decode_frame(frame), attribute) @@ -169,7 +169,6 @@ def calculate_checksum(self, data): return checksum def decode_frame(self, raw_frame: bytes) -> bytes: - b4 = raw_frame raw_frame = bytes(raw_frame) frame_data = raw_frame[0:-4] @@ -196,7 +195,7 @@ def decode_frame(self, raw_frame: bytes) -> bytes: #todo, process info return data - + def build_frame(self, command : int, info: bytes = b''): ''' builds frame without soi and eoi; that is left for frame client''' @@ -210,7 +209,7 @@ def build_frame(self, command : int, info: bytes = b''): info_length = (lenid_invert_plus_one << 12) + lenid - + self.VER = b'\x20' #protocol is in ASCII hex. :facepalm: @@ -229,10 +228,9 @@ def build_frame(self, command : int, info: bytes = b''): #self.decode_frame(frame) return frame - - + + def send_command(self, cmd, info: bytes = b''): data = self.build_frame(cmd, info) self.client.write(data) - \ No newline at end of file diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index 89913f0..824941b 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -33,7 +33,7 @@ class transport_base: _log : logging.Logger = None def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None) -> None: - + self.transport_name = settings.name #section name #apply log level to logger @@ -42,8 +42,8 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self._log : logging.Logger = logging.getLogger(short_name + f"[{self.transport_name}]") self._log.setLevel(self._log_level) - - self.type = self.__class__.__name__ + + self.type = self.__class__.__name__ self.protocolSettings = protocolSettings if not self.protocolSettings: #if not, attempt to load. lazy i know @@ -67,7 +67,7 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti self.write_enabled = settings.getboolean(["write_enabled", "enable_write"], self.write_enabled) else: self.write_enabled = settings.getboolean("write", self.write_enabled) - + self.update_identifier() @@ -93,8 +93,10 @@ def write_data(self, data : dict[str, registry_map_entry], from_transport : 'tra #lets convert this to dict[str, registry_map_entry] def read_data(self) -> dict[str,str]: - ''' general purpose read function for between transports; - return type may be changed to dict[str, registrsy_map_entry]. still thinking about this''' + ''' + general purpose read function for between transports; + return type may be changed to dict[str, registrsy_map_entry]. still thinking about this + ''' pass @@ -117,4 +119,4 @@ def analyse_protocol(self): def validate_protocol(self, protocolSettings : 'protocol_settings') -> float: ''' validates protocol''' pass - #endregion \ No newline at end of file + #endregion diff --git a/defs/common.py b/defs/common.py index 8cedea5..a28c371 100644 --- a/defs/common.py +++ b/defs/common.py @@ -11,15 +11,15 @@ def strtobool (val): val = val.lower() if val in ('y', 'yes', 't', 'true', 'on', '1'): return 1 - + return 0 def strtoint(val : str) -> int: ''' converts str to int, but allows for hex string input, identified by x prefix''' - if isinstance(val, int): #is already int. + if isinstance(val, int): #is already int. return val - + val = val.lower().strip() if val and val[0] == 'x': @@ -29,7 +29,7 @@ def strtoint(val : str) -> int: val = '0' + val return int.from_bytes(bytes.fromhex(val), byteorder='big') - + if val and val.startswith("0x"): val = val[2:] # Pad the string with a leading zero @@ -37,25 +37,25 @@ def strtoint(val : str) -> int: val = '0' + val return int.from_bytes(bytes.fromhex(val), byteorder='big') - + if not val: #empty return 0 - + return int(val) def get_usb_serial_port_info(port : str = '') -> str: for p in serial.tools.list_ports.comports(): if str(p.device).upper() == port.upper(): return "["+hex(p.vid)+":"+hex(p.pid)+":"+str(p.serial_number)+":"+str(p.location)+"]" - + return "" def find_usb_serial_port(port : str = '', vendor_id : str = '', product_id : str = '', serial_number : str = '', location : str = '') -> str: if not port.startswith('['): return port - + port = port.replace('None', '') - + match = re.match(r"\[(?P[\da-zA-Z]+|):?(?P[\da-zA-Z]+|):?(?P[\da-zA-Z]+|):?(?P[\d\-]+|)\]", port) if match: vendor_id = int(match.group("vendor"), 16) if match.group("vendor") else '' @@ -72,5 +72,5 @@ def find_usb_serial_port(port : str = '', vendor_id : str = '', product_id : st else: print("Bad Port Pattern", port) return None - - return None \ No newline at end of file + + return None diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 159e742..a9214a0 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -24,7 +24,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str with open(note_file, "r", encoding="utf-8") as note: readme.write(note.read()) - + previous_folder = "" folder_lines : dict[str, list[str]] = {} @@ -40,7 +40,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str # Create a bold header for each new folder folder_lines[relative_folder] = [] folder_lines[relative_folder].append(f"**{relative_folder}**\n\n") - + previous_folder = relative_folder #generate index in folder @@ -49,7 +49,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str for file in files: file_path = os.path.relpath(os.path.join(root, file), directory).replace("\\", "/") #use linux path structure file_path = urllib.parse.quote(file_path) - + if file == "README.md": #skip continue @@ -91,4 +91,4 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str # Specify the directory you want to index directory_to_index = "../" - generate_readme(directory_to_index, ["3rdparty", "3rdparty/protocols"]) \ No newline at end of file + generate_readme(directory_to_index, ["3rdparty", "3rdparty/protocols"]) diff --git a/protocol_gateway.py b/protocol_gateway.py index 6ef43f8..e446256 100644 --- a/protocol_gateway.py +++ b/protocol_gateway.py @@ -20,14 +20,13 @@ import argparse -import atexit import os import logging import sys import traceback from configparser import ConfigParser, NoOptionError -from classes.protocol_settings import protocol_settings,Data_Type,registry_map_entry,Registry_Type,WriteMode +from classes.protocol_settings import protocol_settings,registry_map_entry from classes.transports.transport_base import transport_base @@ -39,15 +38,15 @@ ██╔â•â•â•╠╚██╔╠██║ ██╔â•â•██║██║ ██║██║╚██╗██║ ██║ ██║ ██║ ██║ ██║╚██████╔â•██║ ╚████║ ╚â•╠╚â•╠╚â•╠╚â•╠╚â•╠╚â•â•â•â•â•╠╚â•╠╚â•â•â•â• - + ██████╗ ██████╗ ██████╗ ████████╗ ██████╗ ██████╗ ██████╗ ██╗ ██████╗ █████╗ ████████╗███████╗██╗ ██╗ █████╗ ██╗ ██╗ ██╔â•â•██╗██╔â•â•██╗██╔â•â•â•██╗╚â•â•██╔â•â•â•██╔â•â•â•██╗██╔â•â•â•â•â•██╔â•â•â•██╗██║ ██╔â•â•â•â•╠██╔â•â•██╗╚â•â•██╔â•â•â•██╔â•â•â•â•â•██║ ██║██╔â•â•██╗╚██╗ ██╔╠██████╔â•██████╔â•██║ ██║ ██║ ██║ ██║██║ ██║ ██║██║ ██║ ███╗███████║ ██║ █████╗ ██║ █╗ ██║███████║ ╚████╔╠██╔â•â•â•╠██╔â•â•██╗██║ ██║ ██║ ██║ ██║██║ ██║ ██║██║ ██║ ██║██╔â•â•██║ ██║ ██╔â•â•╠██║███╗██║██╔â•â•██║ ╚██╔╠██║ ██║ ██║╚██████╔╠██║ ╚██████╔â•╚██████╗╚██████╔â•███████╗ ╚██████╔â•██║ ██║ ██║ ███████╗╚███╔███╔â•██║ ██║ ██║ ╚â•╠╚â•╠╚â•╠╚â•â•â•â•â•╠╚â•╠╚â•â•â•â•â•╠╚â•â•â•â•â•╠╚â•â•â•â•â•╠╚â•â•â•â•â•â•╠╚â•â•â•â•â•╠╚â•╠╚â•╠╚â•╠╚â•â•â•â•â•â•╠╚â•â•â•╚â•â•╠╚â•╠╚â•╠╚â•â• - -""" + +""" # noqa: W291 class CustomConfigParser(ConfigParser): @@ -58,7 +57,7 @@ def get(self, section, option, *args, **kwargs): if 'fallback' in kwargs: #override kwargs fallback, for manually handling here fallback = kwargs['fallback'] kwargs['fallback'] = None - + for name in option: value = super().get(section, name, *args, **kwargs) if value: @@ -67,14 +66,14 @@ def get(self, section, option, *args, **kwargs): if not value: value = fallback - if value == None: + if value is None: raise NoOptionError(option[0], section) else: value = super().get(section, option, *args, **kwargs) if isinstance(value, int): return value - + return value.strip() if value is not None else value class Protocol_Gateway: @@ -131,14 +130,14 @@ def __init__(self, config_file : str): if not transport_type and not protocol_version: raise ValueError('Missing Transport / Protocol Version') - - - if not transport_type and protocol_version: #get transport from protocol settings... + + + if not transport_type and protocol_version: #get transport from protocol settings... protocolSettings : protocol_settings = protocol_settings(protocol_version) if not transport_type and not protocolSettings.transport: raise ValueError('Missing Transport') - + if not transport_type: transport_type = protocolSettings.transport @@ -194,26 +193,26 @@ def run(self): if not transport.connected: transport.connect() #reconnect else: #transport is connected - + info = transport.read_data() if not info: continue - + #todo. broadcast option if transport.bridge: for to_transport in self.__transports: if to_transport.transport_name == transport.bridge: to_transport.write_data(info, transport) break - + except Exception as err: traceback.print_exc() self.__log.error(err) time.sleep(7) - + diff --git a/pytests/test_example_config.py b/pytests/test_example_config.py index 37bf4b3..3f36f27 100644 --- a/pytests/test_example_config.py +++ b/pytests/test_example_config.py @@ -1,12 +1,11 @@ import sys import os -import pytest #move up a folder for tests -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from protocol_gateway import CustomConfigParser def test_example_cfg(): parser = CustomConfigParser() - parser.read("config.cfg.example") \ No newline at end of file + parser.read("config.cfg.example") diff --git a/pytests/test_protocol_settings.py b/pytests/test_protocol_settings.py index dba99ac..c682432 100644 --- a/pytests/test_protocol_settings.py +++ b/pytests/test_protocol_settings.py @@ -5,7 +5,7 @@ #move up a folder for tests -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from classes.protocol_settings import protocol_settings @@ -22,5 +22,4 @@ @pytest.mark.parametrize("protocol", protocols) def test_protocol_setting(protocol : str): print(protocol) - protocolSettings : protocol_settings = protocol_settings(protocol) - + protocolSettings : protocol_settings = protocol_settings(protocol) # noqa: F841 diff --git a/requirements.txt b/requirements.txt index 40e2ac2..f273e37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,6 @@ pymodbus==3.7.0 paho-mqtt pyserial -python-can \ No newline at end of file +python-can +pytz>=2023.3 +python-disk-collections diff --git a/test.py b/test.py index 1ed177f..c383d4c 100644 --- a/test.py +++ b/test.py @@ -1,3 +1,5 @@ +import re +import ast #pip install "python-can[gs_usb]" @@ -40,7 +42,7 @@ # The data is a 2-byte value (un16) soc_bytes = msg.data[:2] soc = int.from_bytes(soc_bytes, byteorder='big', signed=False) / 100.0 - + print(f"State of Charge: {soc:.2f}%") if msg.arbitration_id == 0x0355: @@ -61,10 +63,6 @@ quit() -import re -import ast - - # Define the register string register = "x4642.[ 1 + ((( [battery 1 number of cells] *2 )+ (1~[battery 1 number of temperature] *2)) ) ]" @@ -115,7 +113,7 @@ def evaluate_ranges(expression): return results -def evaluate_expression(expression): +def evaluate_expression(expression): # Define a regular expression pattern to match "maths" var_pattern = re.compile(r'\[(?P.*?)\]') @@ -124,15 +122,15 @@ def replace_vars(match): try: maths = match.group("maths") maths = re.sub(r'\s', '', maths) #remove spaces, because ast.parse doesnt like them - + # Parse the expression safely tree = ast.parse(maths, mode='eval') # Evaluate the expression end_value = eval(compile(tree, filename='', mode='eval')) - + return str(end_value) - except : + except Exception: return match.group(0) # Replace variables with their values diff --git a/tools/apply_common_names_to_csv.py b/tools/apply_common_names_to_csv.py index f7e2141..17535a9 100644 --- a/tools/apply_common_names_to_csv.py +++ b/tools/apply_common_names_to_csv.py @@ -28,7 +28,7 @@ continue if not row['variable name'].strip(): #if empty, apply name - row['variable name'] = common_names[row['documented name']] + row['variable name'] = common_names[row['documented name']] print(row['documented name'] + ' -> ' + common_names[row['documented name']]) new_csv.append(row) continue @@ -37,7 +37,7 @@ # Write data to the output CSV with open(save_path, 'w', newline='') as outfile: writer = csv.DictWriter(outfile, fieldnames=fieldnames) - writer.writeheader() - writer.writerows(new_csv) + writer.writeheader() + writer.writerows(new_csv) -print("saved to "+save_path) \ No newline at end of file +print("saved to "+save_path) diff --git a/tools/get_common_names_from_csv.py b/tools/get_common_names_from_csv.py index b96cbef..f2ba72e 100644 --- a/tools/get_common_names_from_csv.py +++ b/tools/get_common_names_from_csv.py @@ -17,7 +17,7 @@ with open(path, newline='') as csvfile: # Create a CSV reader object reader = csv.DictReader(csvfile, delimiter=';') #compensate for openoffice - + # Iterate over each row in the CSV file for row in reader: if row['variable name'] and row['documented name']: @@ -37,4 +37,4 @@ with open(save_path, 'w') as file: file.write(json_str) -print("saved to "+save_path) \ No newline at end of file +print("saved to "+save_path) diff --git a/tools/list_to_json.py b/tools/list_to_json.py index 38eed52..edd10e2 100644 --- a/tools/list_to_json.py +++ b/tools/list_to_json.py @@ -19,7 +19,7 @@ pairs = user_input.split("=") else: pairs = user_input.split() - + # Create a dictionary from the key-value pairs result = {} @@ -34,7 +34,7 @@ else: key, value = pair.split(":") - + result[key.strip()] = value.strip() # Convert the dictionary to JSON From b1f74147cd74f08d3ebb3f9fd6a5190561c97bfd Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Tue, 18 Mar 2025 12:15:23 +0000 Subject: [PATCH 13/53] remove some requirements --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index f273e37..2158c18 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,3 @@ pymodbus==3.7.0 paho-mqtt pyserial python-can -pytz>=2023.3 -python-disk-collections From e873587253a777b73609fb592bd24251e84dd04f Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Tue, 18 Mar 2025 12:16:30 +0000 Subject: [PATCH 14/53] added ruff --- requirements-dev.txt | 1 + ruff.toml | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 requirements-dev.txt create mode 100644 ruff.toml diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..af3ee57 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +ruff diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,22 @@ +line-length = 88 +indent-width = 4 +target-version = "py311" + +[lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. + +select = ["E", "F", "W"] +ignore = ["E501"] + +#select = ["ALL"] +#ignore = ["C901", "EM101", "TRY003", "E501", "D", "G004", "N", "S105", +# "DTZ007", "S301", "RUF013", "PTH123", "PLW0603", "TRY400", "BLE001", +# "PLR0912", "PLR0915", "FBT001", "FBT002", "FA100", "W191" +#] + +[format] +quote-style = "double" +indent-style = "space" +line-ending = "auto" From cf8c9240b7762e75765e0fd91f8e2d49ef5a769a Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:03:57 -0500 Subject: [PATCH 15/53] ; to , --- .../sigineer_v0.11.holding_registry_map.csv | 104 ++--- .../sigineer_v0.11.input_registry_map.csv | 356 +++++++++--------- 2 files changed, 230 insertions(+), 230 deletions(-) diff --git a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv index aa29484..f399424 100644 --- a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv @@ -1,52 +1,52 @@ -variable name;data type;register;documented name;description;customer write;values;unit;Initial value;note;;;;;;;;;;;; -;;0;On_Off;"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0).";;"0x0000:    Standby    off, Output enable; 0x0001:    Standby    on, Output enable; 0x0100:    Standby    off, Output disable; 0x0101:    Standby    on, Output disable;";;0;;;;;;;;;;;;; -;;1;OutputConfig;AC output set;W;"{""0"": ""BAT First"", ""1"": ""PV First"",""2"": ""UTI First""}";;;;;0;;;;;;;;;; -;;2;ChargeConfig;Charge source set;W;"{""0"": ""PV first"",""1"": ""PV&UTI"",""2"": ""PV Only""}";;;;;0;;;;;;;;;; -;;3;UtiOutStart;Uti Output Start Time;W;0-23;H(hour);0;;;;;;;;;;;;; -;;4;UtiOutEnd;Uti Output End Time;W;0-23;H(hour);0;;;;;;;;;;;;; -;;5;UtiChargeStart;Uti Charge Start Time;W;0-23;H(hour);0;;;;;;;;;;;;; -;;6;UtiChargeEnd;Uti Charge End Time;W;0-23;H(hour);0;;;;;;;;;;;;; -;;7;PVModel;PV Input Mode;W;"{""0"": ""Independent"", ""1"": ""Parallel""}";;;;0;;;;;;;;;;; -;;8;ACInModel;AC Input Mode;W;"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC""}";;0;;;;;;;;;;;;; -;ASCII;r9~11;Fw version;Firmware version (high);;;ASCII;;;;;;;;;;;;;; -;ASCII;r12~14;Fw version2 H;Control Firmware version (high);;;ASCII;;;;;;;;;;;;;; -;;15;LCD language;LCD language;W;"{""0"" : ""Chinese?"", ""1"" : ""English""}";;1;English;;;;;;;;;;;; -;;18;OutputVoltType;Output Volt Type;W;"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC""}";;;1;;;;;;;;;;;; -;;19;OutputFreqType;Output Freq Type;W;"{""0"": ""50Hz"", ""1"": ""60Hz""}";;;0;;;;;;;;;;;; -;;20;OverLoadRestart;Over Load Restart;W;"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}";; 2: Swith to UTI;;;0;Yes(over     Load 1mins              to restart;       after over Load three times   to   stop output);;;;;;;; -;;21;OverTempRestart;Over Temperature Restart;W;"{""0"": ""Yes"", ""1"": ""No""}";;;;0;Yes(over Temperature to     restart   ; after            over Temperature three  times  to stop output);;;;;;;;; -;;22;BuzzerEN;Buzzer on/off enable;W;"{""1"": ""Enable"", ""0"": ""Disable""}";;;;1;;;;;;;;;;; -Serial Number;ASCII;r23-27;Serial NO 5;Serial number 5;W;;ASCII;;;;;;;;;;;;;; -;;28;Moudle H;Inverter Moudle (high);W;;;;Can be set at standy   state Only;;;;;;;;;;;; -;;29;Moudle L;Inverter Moudle (low);W;P-battery type: 0: Lead_Acid;; 2: CustomLead_Acid; U-user type: 0: No verndor; 1: Sigineer; 2: CPS; 3: Haiti; M-power rate: 3: 3KW; 5:5KW; S-Aging; 0: Normal Mode; 1: Aging Mode;;;;Can be set at standy   state Only -;;30;Com Address;Communicate   address;W;1~254;;1;;;;;;;;;;;;; -;;31;FlashStart;Update firmware;W;0x0001: own 0X0100: control broad;;;;;;;;;;;;;;; -;;32;Reset User Info;Reset User Information;W;0x0001;;;;;;;;;;;;;;; -;;33;Reset to factory;Reset to factory;W;0x0001;;;;;;;;;;;;;;; -;;34;MaxChargeCurr;Max Charge Current;W;10~130;1A;70;;;;;;;;;;;;; -;;35;BulkChargeVolt;Bulk Charge Volt;W;500~580;0.1V;564;;;;;;;;;;;;; -;;36;FloatChargeVolt;Float Charge Volt;W;500~560;0.1V;540;;;;;;;;;;;;; -;;37;BatLowToUtiVolt;Bat Low Volt Switch To Uti;W;444~514;0.1V;464;;;;;;;;;;;;; -;;38;FloatChargeCurr;Float Charge Current;W;0~80;0.1A;;;;;;;;;;;;;; -;;39;Battery Type;Battery Type;W;"{""0"": ""Lead_Acid"", ""1"": ""Lithium"", ""2"": ""CustomLead_Acid""}";; 2: CustomLead_Acid;;;1;Can be set at standy   state Only;;;;;;;;; -;;40;Aging Mode;Aging Mode;W;"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}";;;;0;Can be set at standy   state Only;;;;;;;;;; -;;43;DTC;Device Type Code;;&*6;;;;;;;;;;;;;;; -;;45;Sys Year;System time-year;W;Year offset is 2000;;;;;;;;;;;;;;; -;;46;Sys Month;System time- Month;W;;;;;;;;;;;;;;;; -;;47;Sys Day;System time- Day;W;;;;;;;;;;;;;;;; -;;48;Sys Hour;System time- Hour;W;;;;;;;;;;;;;;;; -;;49;Sys Min;System time- Min;W;;;;;;;;;;;;;;;; -;;50;Sys Sec;System time- Second;W;;;;;;;;;;;;;;;; -;ASCII;59-66;Manufacturer Info;Manufacturer information (high);;;ASCII;;;;;;;;;;;;;; -;;67;FW Build No_ 4;Control FW Build No. 2;;;ASCII;;;;;;;;;;;;;; -;;68;FW Build No_ 3;Control FW Build No. 1;;;;;;;;;;;;;;;;; -;;69;FW Build No_ 2;COM FW Build No. 2;;;;;;;;;;;;;;;;; -;;70;FW Build No_ 1;COM FW Build No. 1;;;ASCII;;;;;;;;;;;;;; -;;72;Sys Weekly;Sys Weekly;W;0-6;;;;;;;;;;;;;;; -;;73;ModbusVersion;Modbus Version;;Eg:207 is V2.07;Int(16bit s);;;;;;;;;;;;;; -;;76;Rate Watt H ;Rate active power(high) ;;;0.1W;;;;;;;;;;;;;; -;;77;Rate Watt L ;Rate active power(low) ;;;0.1W;;;;;;;;;;;;;; -;;78;Rate VA H ;Rata apparent power (high) ;;;0.1VA;;;;;;;;;;;;;; -;;79;Rate VA L ;Rate apparent power (low) ;;;0.1VA;;;;;;;;;;;;;; -;;80;Factory;The ODM Info code;;;;;;;;;;;;;;;;; -;;162;BLVersion2;Boot loader version2;R;;;;;;;;;;;;;;;; +variable name,data type,register,documented name,description,customer write,values,unit,Initial value,note,,,,,,,,,,,, +,,0,On_Off,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0).",,"0x0000:??? Standby??? off, Output enable; 0x0001:??? Standby??? on, Output enable; 0x0100:??? Standby??? off, Output disable; 0x0101:??? Standby??? on, Output disable;",,0,,,,,,,,,,,,, +,,1,OutputConfig,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"",""2"": ""UTI First""}",,,,,0,,,,,,,,,, +,,2,ChargeConfig,Charge source set,W,"{""0"": ""PV first"",""1"": ""PV&UTI"",""2"": ""PV Only""}",,,,,0,,,,,,,,,, +,,3,UtiOutStart,Uti Output Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,4,UtiOutEnd,Uti Output End Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,5,UtiChargeStart,Uti Charge Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,6,UtiChargeEnd,Uti Charge End Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,7,PVModel,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,0,,,,,,,,,,, +,,8,ACInModel,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC""}",,0,,,,,,,,,,,,, +,ASCII,r9~11,Fw version,Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,ASCII,r12~14,Fw version2 H,Control Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,,15,LCD language,LCD language,W,"{""0"" : ""Chinese?"", ""1"" : ""English""}",,1,English,,,,,,,,,,,, +,,18,OutputVoltType,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC""}",,,1,,,,,,,,,,,, +,,19,OutputFreqType,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,,0,,,,,,,,,,,, +,,20,OverLoadRestart,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",, 2: Swith to UTI,,,0,Yes(over???? Load 1mins????????????? to restart,?????? after over Load three times?? to?? stop output),,,,,,,, +,,21,OverTempRestart,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,,,0,Yes(over Temperature to???? restart?? , after??????????? over Temperature three? times? to stop output),,,,,,,,, +,,22,BuzzerEN,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,1,,,,,,,,,,, +Serial Number,ASCII,r23-27,Serial NO 5,Serial number 5,W,,ASCII,,,,,,,,,,,,,, +,,28,Moudle H,Inverter Moudle (high),W,,,,Can be set at standy?? state Only,,,,,,,,,,,, +,,29,Moudle L,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid,, 2: CustomLead_Acid, U-user type: 0: No verndor, 1: Sigineer, 2: CPS, 3: Haiti, M-power rate: 3: 3KW, 5:5KW, S-Aging, 0: Normal Mode, 1: Aging Mode,,,,Can be set at standy?? state Only +,,30,Com Address,Communicate?? address,W,1~254,,1,,,,,,,,,,,,, +,,31,FlashStart,Update firmware,W,0x0001: own 0X0100: control broad,,,,,,,,,,,,,,, +,,32,Reset User Info,Reset User Information,W,0x0001,,,,,,,,,,,,,,, +,,33,Reset to factory,Reset to factory,W,0x0001,,,,,,,,,,,,,,, +,,34,MaxChargeCurr,Max Charge Current,W,10~130,1A,70,,,,,,,,,,,,, +,,35,BulkChargeVolt,Bulk Charge Volt,W,500~580,0.1V,564,,,,,,,,,,,,, +,,36,FloatChargeVolt,Float Charge Volt,W,500~560,0.1V,540,,,,,,,,,,,,, +,,37,BatLowToUtiVolt,Bat Low Volt Switch To Uti,W,444~514,0.1V,464,,,,,,,,,,,,, +,,38,FloatChargeCurr,Float Charge Current,W,0~80,0.1A,,,,,,,,,,,,,, +,,39,Battery Type,Battery Type,W,"{""0"": ""Lead_Acid"", ""1"": ""Lithium"", ""2"": ""CustomLead_Acid""}",, 2: CustomLead_Acid,,,1,Can be set at standy?? state Only,,,,,,,,, +,,40,Aging Mode,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,0,Can be set at standy?? state Only,,,,,,,,,, +,,43,DTC,Device Type Code,,&*6,,,,,,,,,,,,,,, +,,45,Sys Year,System time-year,W,Year offset is 2000,,,,,,,,,,,,,,, +,,46,Sys Month,System time- Month,W,,,,,,,,,,,,,,,, +,,47,Sys Day,System time- Day,W,,,,,,,,,,,,,,,, +,,48,Sys Hour,System time- Hour,W,,,,,,,,,,,,,,,, +,,49,Sys Min,System time- Min,W,,,,,,,,,,,,,,,, +,,50,Sys Sec,System time- Second,W,,,,,,,,,,,,,,,, +,ASCII,59-66,Manufacturer Info,Manufacturer information (high),,,ASCII,,,,,,,,,,,,,, +,,67,FW Build No_ 4,Control FW Build No. 2,,,ASCII,,,,,,,,,,,,,, +,,68,FW Build No_ 3,Control FW Build No. 1,,,,,,,,,,,,,,,,, +,,69,FW Build No_ 2,COM FW Build No. 2,,,,,,,,,,,,,,,,, +,,70,FW Build No_ 1,COM FW Build No. 1,,,ASCII,,,,,,,,,,,,,, +,,72,Sys Weekly,Sys Weekly,W,0-6,,,,,,,,,,,,,,, +,,73,ModbusVersion,Modbus Version,,Eg:207 is V2.07,Int(16bit s),,,,,,,,,,,,,, +,,76,Rate Watt H ,Rate active power(high) ,,,0.1W,,,,,,,,,,,,,, +,,77,Rate Watt L ,Rate active power(low) ,,,0.1W,,,,,,,,,,,,,, +,,78,Rate VA H ,Rata apparent power (high) ,,,0.1VA,,,,,,,,,,,,,, +,,79,Rate VA L ,Rate apparent power (low) ,,,0.1VA,,,,,,,,,,,,,, +,,80,Factory,The ODM Info code,,,,,,,,,,,,,,,,, +,,162,BLVersion2,Boot loader version2,R,,,,,,,,,,,,,,,, diff --git a/protocols/sigineer/sigineer_v0.11.input_registry_map.csv b/protocols/sigineer/sigineer_v0.11.input_registry_map.csv index ab672f5..fd2c839 100644 --- a/protocols/sigineer/sigineer_v0.11.input_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.input_registry_map.csv @@ -1,178 +1,178 @@ -variable name;data type;register;documented name;description;values;unit;note;;;;;;;;;; -;;0;System Status;System run state;"{""0"": ""Standby"", ""1"": ""(No Use)"", ""2"": ""Discharge"", ""3"": ""Fault"", ""4"": ""Flash"", ""5"": ""PV charge"", ""6"": ""AC charge"", ""7"": ""Combine charge"", ""8"": ""Combine charge and Bypass"", ""9"": ""PV charge and Bypass"", ""10"": ""AC charge and Bypass"", ""11"": ""Bypass"", ""12"": ""PV charge and Discharge""}";;  (No Use) 2: Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge; 12:    PV    charge    and Discharge -PV1 Voltage;;1;Vpv1;PV1 voltage;;0.1V;;;;;;;;;;; -PV2 Voltage;;2;Vpv2;PV2 voltage;;0.1V;;;;;;;;;;; -PV1 Watts;;3;Ppv1 H;PV1 charge power (high);;0.1W;;;;;;;;;;; -;;4;Ppv1 L;PV1 charge power (low);;0.1W;;;;;;;;;;; -PV2 Watts;;5;Ppv2 H;PV2 charge power (high);;0.1W;;;;;;;;;;; -;;6;Ppv2 L;PV2 charge power (low);;0.1W;;;;;;;;;;; -Buck1 Current;;7;Buck1Curr;Buck1 current;;0.1A;;;;;;;;;;; -Buck2 Current;;8;Buck2Curr;Buck2 current;;0.1A;;;;;;;;;;; -Output Wattage;;9;OP_Watt H;Output active power (high);;0.1W;;;;;;;;;;; -;;10;OP_Watt L;Output active power (low);;0.1W;;;;;;;;;;; -Output VA;;11;OP_VA H;Output apparent power (high);;0.1VA;;;;;;;;;;; -;;12;OP_VA L;Output apparent power (low);;0.1VA;;;;;;;;;;; -AC Charge Watts;;13;ACChr_Watt H;AC charge watt (high);;0.1W;;;;;;;;;;; -;;14;ACChr_Watt L;AC charge watt (low);;0.1W;;;;;;;;;;; -AC Charge VA;;15;ACChr_VA H;AC   charge (high);;0.1VA;;;;;;;;;;; -;;16;ACChr_VA L;AC   charge (low);;0.1VA;;;;;;;;;;; -Battery Voltage;;17;Bat Volt;Battery volt (M3);;0.01V;;;;;;;;;;; -Battery SOC;;18;BatterySOC;Battery SOC;0~100;1.00%;;;;;;;;;;; -Bus Voltage;;19;Bus Volt;Bus Voltage;;0.1V;;;;;;;;;;; -Grid Voltage;;20;Grid Volt;AC input Volt;;0.1V;;;;;;;;;;; -Grid Hz;;21;Line Freq;AC input frequency;;0.01Hz;;;;;;;;;;; -Output Voltage;;22;OutputVolt;AC output Volt;;0.1V;;;;;;;;;;; -Output Hz;;23;OutputFreq;AC output frequency;;0.01Hz;;;;;;;;;;; -Output DCV;;24;Ouput DCV;Ouput DC Volt;;0.1V;;;;;;;;;;; -;;25;InvTemp;Inv Temperature;;0.1C;;;;;;;;;;; -;;26;DcDc Temp;DC-DC Temperature;;0.1C;;;;;;;;;;; -Load Percentage;;27;LoadPercent;Load Percent;0~1000;0.10%;;;;;;;;;;; -;;28;Bat_s_Volt ;Battery-port volt (DSP) ;;0.01V;;;;;;;;;;; -;;29;Bat_Volt_DSP ;Battery-bus volt (DSP) ;;0.01V;;;;;;;;;;; -;;30;Time total H;Work time total (high);;0.5S;;;;;;;;;;; -;;31;Time total L;Work time total (low);;0.5S;;;;;;;;;;; -Buck1 Temperature;;32;Buck1_NTC;Buck1 Temperature;;0.1C;;;;;;;;;;; -Buck2 Temperature;;33;Buck2_NTC;Buck2 Temperature;;0.1C;;;;;;;;;;; -Output Current;;34;OP_Curr;Output Current;;0.1A;;;;;;;;;;; -Inverter Current;;35;Inv_Curr;Inv Current;;0.1A;;;;;;;;;;; -AC Input Watts;;36;AC_InWatt H;AC input watt (high);;0.1W;;;;;;;;;;; -;;37;AC_InWatt L;AC input watt (low);;0.1W;;;;;;;;;;; -AC Input VA;;38;AC_InVA H;;;0.1VA;;;;;;;;;;; -;;39;AC_InVA L;;;0.1VA;;;;;;;;;;; -;;40;Fault bit;fault bit;&*1;;;;;;;;;;;; -;;41;Warning bit;Warning bit;&*1;;;;;;;;;;;; -;;42;fault value;fault value;;;;;;;;;;;;; -;;43;warning value;warning value;;;;;;;;;;;;; -;;44;DTC;Device Type Code;&*6;;;;;;;;;;;; -;;45;Check Step;Product check step;"{""1"": ""PV1 charge powercheck"", ""2"": ""PV2 charge powercheck"", ""3"": ""AC charge Powercheck""}";;;;;;;;;;;; -;;46;Production Line Mode;Production Line Mode;"{""0"": ""Not at ProductionLine Mode"", ""1"": ""Production LineMode"", ""2"": ""Production Line Clear Fault Mode""}";; 2:     Production     Line Clear Fault Mode;;;;;;;;;; -;;47;ConstantPowerOKFlag;Constant Power OK Flag;"{""0"": ""Not OK"", ""1"": ""OK""}";;;;;;;;;;;; -PV1 KWH Today;;48;Epv1_today H;PV Energy today;;;;;;;;;;;;; -;;49;Epv1_today L;PV Energy today;;0.1kW h;;;;;;;;;;; -PV1 KWH Total;;50;Epv1_total H;PV Energy total;;;;;;;;;;;;; -;;51;Epv1_total L;PV Energy total;;0.1kW h;;;;;;;;;;; -PV2 KWH Today;;52;Epv2_today H;PV Energy today;;;;;;;;;;;;; -;;53;Epv2_today L;PV Energy today;;0.1kW h;;;;;;;;;;; -PV2 KWH Total;;54;Epv2_total H;PV Energy total;;;;;;;;;;;;; -;;55;Epv2_total L;PV Energy total;;0.1kW h;;;;;;;;;;; -AC Input KWH Today;;56;Eac_chrToday H;AC charge Energy today;;;;;;;;;;;;; -;;57;Eac_chrToday L;AC charge Energy today;;0.1kW h;;;;;;;;;;; -AC Input KWH Total;;58;Eac_chrTotal H;AC charge Energy total;;;;;;;;;;;;; -;;59;Eac_chrTotal L;AC charge Energy total;;0.1kW h;;;;;;;;;;; -Battery Discharge KWH Today;;60;Ebat_dischrToday H;Bat discharge Energy today;;;;;;;;;;;;; -;;61;Ebat_dischrToday L;Bat discharge Energy today;;0.1kW h;;;;;;;;;;; -Battery Discharge KWH Total;;62;Ebat_dischrTotal H;Bat discharge Energy total;;;;;;;;;;;;; -;;63;Ebat_dischrTotal L;Bat discharge Energy total;;0.1kW h;;;;;;;;;;; -AC Discharge KWH Today;;64;Eac_dischrToday H;AC discharge Energy today;;;;;;;;;;;;; -;;65;Eac_dischrToday L;AC discharge Energy today;;0.1kW h;;;;;;;;;;; -AC Discharge KWH Total;;66;Eac_dischrTotal H;AC discharge Energy total;;;;;;;;;;;;; -;;67;Eac_dischrTotal L;AC discharge Energy total;;0.1kW h;;;;;;;;;;; -AC Charge Current;;68;ACChrCurr;AC Charge Battery Current;;0.1A;;;;;;;;;;; -AC Discharge Watts;;69;AC_DisChrWatt H;AC discharge watt (high);;0.1W;;;;;;;;;;; -;;70;AC_DisChrWatt L;AC discharge watt (low);;0.1W;;;;;;;;;;; -AC Discharge VA;;71;AC_DisChrVA H;AC  discharge  apparent  power (high);;0.1VA;;;;;;;;;;; -;;72;AC_DisChrVA L;AC  discharge  apparent  power (low);;0.1VA;;;;;;;;;;; -Battery Discharge Watts;;73;Bat_DisChrWatt H;Bat discharge watt (high);;0.1W;;;;;;;;;;; -;;74;Bat_DisChrWatt L;Bat discharge watt (low);;0.1W;;;;;;;;;;; -Battery Discharge VA;;75;Bat_DisChrVA H;Bat discharge apparent power (high);;0.1VA;;;;;;;;;;; -;;76;Bat_DisChrVA L;Bat discharge apparent power (low);;0.1VA;;;;;;;;;;; -Battery Input Watts;INT;77;Bat_Watt H;Bat watt (high);(signed int 32) Positive:Battery Discharge Power Negative:          Battery Charge Power;0.1W;;;;;;;;;;; -;INT;78;Bat_Watt L;Bat watt (low);;;;;;;;;;;;; -;;80;BatOverCharge;Battery Over Charge Flag;"{""0"": ""Battery not over charge"", ""1"": ""Battery over charge""}";;;;;;;;;;;; -;;81;MpptFanSpeed;Fan speed of MPPT Charger;0~100;1.00%;;;;;;;;;;; -;;82;InvFanSpeed;Fan speed of Inverter;0~100;1.00%;;;;;;;;;;; -;;90;BMS_Status;Status from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;91;BMS_Error;;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;Error infomation from BMS;;;;;;;;;; -;;92;BMS_ WarnInfo;;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;Warning info from BMS;;;;;;;;;; -;;93;BMS_SOC;SOC from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;94;BMS_ BatteryVolt;Battery voltage from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;95;BMS_ BatteryCurr;Battery current from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;96;BMS_ BatteryTemp;Battery     temperature     from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;97;BMS_ MaxCurr;Max. charge/discharge current from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;98;BMS_ ConstantVolt;CV voltage from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;99;BMS_ BMSInfo;BMS Information from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;100;BMS_ PackInfo;Pack Information from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;101;BMS_ UsingCap;Using Cap from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;102;BMS_ Cell1_Volt;Cell1_Voltage from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;117;BMS_ Cell16_Volt;Cell16_Voltage from BMS;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;118;BMS2_Status;Status from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;119;BMS2_Error;;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;Error infomation from BMS;;;;;;;;;; -;;120;BMS2_ WarnInfo;;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;Warning info from BMS2;;;;;;;;;; -;;121;BMS2_SOC;SOC from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;122;BMS2_ BatteryVolt;Battery voltage from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;123;BMS2_ BatteryCurr;Battery current from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;124;BMS2_ BatteryTemp;Battery     temperature     from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;125;BMS2_ MaxCurr;Max. charge/discharge current from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;126;BMS2_ ConstantVolt;CV voltage from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;127;BMS2_ BMSInfo;BMS Information from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;128;BMS2_ PackInfo;Pack Information from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;129;BMS2_ UsingCap;Using Cap from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;130;BMS2_ Cell1_Volt;Cell1_Voltage from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;145;BMS2_ Cell16_Volt;Cell16_Voltage from BMS2;"Detail    information,    refer    to document:  Sigineer  xxSxxP  ESS Protocol;";;;;;;;;;;;; -;;180;Solar1_Status;Solar Charger1 Status;;;;;;;;;;;;; -;;181;Solar1_FaultCode;Solar Charger1 FaultCode;;;;;;;;;;;;; -;;182;Solar1_WarningCode;Solar Charger1 WarningCode;;;;;;;;;;;;; -;;183;Solar1_BatVolt;Solar Charger1 battery voltage;;0.01V;;;;;;;;;;; -;;184;Solar1_PV1Volt;Solar Charger1 PV1 voltage;;0.1V;;;;;;;;;;; -;;185;Solar1_PV2Volt;Solar Charger1 PV2 voltage;;0.1V;;;;;;;;;;; -;;186;Solar1_Buck1Curr;Solar Charger1 Buck1 current;;0.1A;;;;;;;;;;; -;;187;Solar1_Buck2Curr;Solar Charger1 Buck2 current;;0.1A;;;;;;;;;;; -;;188;Solar1_PV1ChrPower H;Solar    Charger1    PV1    charge Power High 16 bit;;0.1W;;;;;;;;;;; -;;189;Solar1_PV1ChrPower H;Solar    Charger1    PV1    charge Power Low 16 bit;;0.1W;;;;;;;;;;; -;;190;Solar1_PV2ChrPower H;Solar    Charger1    PV2    charge Power High 16 bit;;0.1W;;;;;;;;;;; -;;191;Solar1_PV2ChrPower H;Solar    Charger1    PV2    charge Power Low 16 bit;;0.1W;;;;;;;;;;; -;;192;Solar1_HS1Temp;Solar          Charger1         Buck1 Temperature;;0.1C;;;;;;;;;;; -;;193;Solar1_HS2Temp;Solar          Charger1         Buck2 Temperature;;0.1C;;;;;;;;;;; -;;194;Solar1_Epv1_today;Solar Charger1 PV1 Energy today;;0.1k Wh;;;;;;;;;;; -;;195;Solar1_Epv2_today L;Solar Charger1 PV2 Energy today;;0.1k Wh;;;;;;;;;;; -;;196;Solar1_Epv1_total H;Solar Charger1 PV1 Energy total High 16 bit;;0.1k Wh;;;;;;;;;;; -;;197;Solar1_Epv1_total L;Solar Charger1 PV1 Energy total Low 16 bit;;0.1k Wh;;;;;;;;;;; -;;198;Solar1_Epv2_total H;Solar Charger1 PV2 Energy total High 16 bit;;0.1k Wh;;;;;;;;;;; -;;199;Solar1_Epv2_total L;Solar Charger1 PV2 Energy total Low 16 bit;;0.1k Wh;;;;;;;;;;; -;;200;Solar2_Status;Solar Charger2 Status;;;;;;;;;;;;; -;;201;Solar2_FaultCode;Solar Charger2 FaultCode;;;;;;;;;;;;; -;;202;Solar2_WarningCode;Solar Charger2 WarningCode;;;;;;;;;;;;; -;;203;Solar2_BatVolt;Solar Charger2 battery voltage;;0.01V;;;;;;;;;;; -;;204;Solar2_PV1Volt;Solar Charger2 PV1 voltage;;0.1V;;;;;;;;;;; -;;205;Solar2_PV2Volt;Solar Charger2 PV2 voltage;;0.1V;;;;;;;;;;; -;;206;Solar2_Buck1Curr;Solar Charger2 Buck1 current;;0.1A;;;;;;;;;;; -;;207;Solar2_Buck2Curr;Solar Charger2 Buck2 current;;0.1A;;;;;;;;;;; -;;208;Solar2_PV1ChrPower H;Solar    Charger2    PV1    charge Power High 16 bit;;0.1W;;;;;;;;;;; -;;209;Solar2_PV1ChrPower H;Solar    Charger2    PV1    charge Power Low 16 bit;;0.1W;;;;;;;;;;; -;;210;Solar2_PV2ChrPower H;Solar    Charger2    PV2    charge Power High 16 bit;;0.1W;;;;;;;;;;; -;;211;Solar2_PV2ChrPower H;Solar    Charger2    PV2    charge Power Low 16 bit;;0.1W;;;;;;;;;;; -;;212;Solar2_HS1Temp;Solar          Charger2         Buck1 Temperature;;0.1C;;;;;;;;;;; -;;213;Solar2_HS2Temp;Solar          Charger2         Buck2 Temperature;;0.1C;;;;;;;;;;; -;;214;Solar2_Epv1_today;Solar Charger2 PV1 Energy today;;0.1k Wh;;;;;;;;;;; -;;215;Solar2_Epv2_today;Solar Charger2 PV2 Energy today;;0.1k Wh;;;;;;;;;;; -;;216;Solar2_Epv1_total H;Solar Charger2 PV1 Energy total High 16 bit;;0.1k Wh;;;;;;;;;;; -;;217;Solar2_Epv1_total L;Solar Charger2 PV1 Energy total Low 16 bit;;0.1k Wh;;;;;;;;;;; -;;218;Solar2_Epv2_total H;Solar Charger2 PV2 Energy total High 16 bit;;0.1k Wh;;;;;;;;;;; -;;219;Solar2_Epv2_total L;Solar Charger2 PV2 Energy total Low 16 bit;;0.1k Wh;;;;;;;;;;; -;;220;Solar_ConnectOKFlag;Slave Solar Connect OK Flag;"{""1"": ""Solar Charger1"", ""2"": ""Solar Charger2"", ""3"": ""Solar Charger1 and 2""}";;;;;;;;;;;; -;;221;Solar_BatVoltConsistFl ag;Check Slave Solar Battery Voltage Consist OK Flag;"{""1"": ""Check Solar Charger1battery voltage OK"", ""2"": ""Check Solar Charger2battery voltage OK"", ""3"": ""Check Solar Charger1 and 2 battery voltage OK""}";;;;;;;;;;;; -;;222;Solar_TypeSwState ;Solar Charger Type Swtich State;"{""0"": ""Master SolarCharger"", ""1"": ""Slaver SolarCharger""}";;;;;;;;;;;; -;;223;Solar_ModeSwState ;Solar Charger Mode Swtich State;"{""0"": ""Parallel Mode"", ""1"": ""Single Mode""}";;;;;;;;;;;; -;;224;Solar_AddrSwState ;Solar Charger Addr Swtich State;2~3;;;;;;;;;;;; -;;360;BMS_ GaugeRM ;Gauge RM from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;361;BMS_GaugeFCC;Gauge FCC from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;362;BMS_ FW ;BMS_ FW ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;363;BMS_ DeltaVolt ;Delta V from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;364;BMS_ CycleCnt ;Cycle Count from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;365;BMS_ SOH;SOH from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;366;BMS_ GaugeICCurr;Gauge IC current from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;367;BMS_ MCUVersion ;MCU Software version from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;368;BMS_ GaugeVersion ;Gauge Version from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;369;BMS_ wGaugeFRVersion_ L ;Gauge FR Version L16 from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;370;BMS_ wGaugeFRVersion_H ;Gauge FR Version H16 from BMS ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;371;BMS2_ GaugeRM ;BMS2_ GaugeRM ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;372;BMS2_GaugeFCC ;Gauge FCC from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;373;BMS2_ FW ;BMS2_ FW ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;374;BMS2_ DeltaVolt ;Delta V from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;375;BMS2_ CycleCnt ;Cycle Count from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;376;BMS2_ SOH ;SOH from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;377;BMS2_ GaugeICCurr ;Gauge IC current from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;378;BMS2_ MCUVersion ;MCU Software version from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;379;BMS2_ GaugeVersion ;Gauge Version from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;380;BMS2_ wGaugeFRVersion_ L ;Gauge FR Version L16 from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; -;;381;BMS2_ wGaugeFRVersion_H ;Gauge FR Version H16 from BMS2 ;"Detail         information, refer     to     document: Sigineer     xxSxxP     ESS Protocol;";;;;;;;;;;;; +variable name,data type,register,documented name,description,values,unit,note,,,,,,,,,, +,,0,System Status,System run state,"{""0"": ""Standby"", ""1"": ""(No Use)"", ""2"": ""Discharge"", ""3"": ""Fault"", ""4"": ""Flash"", ""5"": ""PV charge"", ""6"": ""AC charge"", ""7"": ""Combine charge"", ""8"": ""Combine charge and Bypass"", ""9"": ""PV charge and Bypass"", ""10"": ""AC charge and Bypass"", ""11"": ""Bypass"", ""12"": ""PV charge and Discharge""}",,? (No Use) 2: Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge +PV1 Voltage,,1,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, +PV2 Voltage,,2,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, +PV1 Watts,,3,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, +,,4,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, +PV2 Watts,,5,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, +,,6,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, +Buck1 Current,,7,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, +Buck2 Current,,8,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, +Output Wattage,,9,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, +,,10,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, +Output VA,,11,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, +,,12,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, +AC Charge Watts,,13,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, +,,14,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, +AC Charge VA,,15,ACChr_VA H,AC?? charge (high),,0.1VA,,,,,,,,,,, +,,16,ACChr_VA L,AC?? charge (low),,0.1VA,,,,,,,,,,, +Battery Voltage,,17,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, +Battery SOC,,18,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, +Bus Voltage,,19,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, +Grid Voltage,,20,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, +Grid Hz,,21,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, +Output Voltage,,22,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, +Output Hz,,23,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, +Output DCV,,24,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, +,,25,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, +,,26,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, +Load Percentage,,27,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, +,,28,Bat_s_Volt ,Battery-port volt (DSP) ,,0.01V,,,,,,,,,,, +,,29,Bat_Volt_DSP ,Battery-bus volt (DSP) ,,0.01V,,,,,,,,,,, +,,30,Time total H,Work time total (high),,0.5S,,,,,,,,,,, +,,31,Time total L,Work time total (low),,0.5S,,,,,,,,,,, +Buck1 Temperature,,32,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, +Buck2 Temperature,,33,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, +Output Current,,34,OP_Curr,Output Current,,0.1A,,,,,,,,,,, +Inverter Current,,35,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, +AC Input Watts,,36,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, +,,37,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, +AC Input VA,,38,AC_InVA H,,,0.1VA,,,,,,,,,,, +,,39,AC_InVA L,,,0.1VA,,,,,,,,,,, +,,40,Fault bit,fault bit,&*1,,,,,,,,,,,, +,,41,Warning bit,Warning bit,&*1,,,,,,,,,,,, +,,42,fault value,fault value,,,,,,,,,,,,, +,,43,warning value,warning value,,,,,,,,,,,,, +,,44,DTC,Device Type Code,&*6,,,,,,,,,,,, +,,45,Check Step,Product check step,"{""1"": ""PV1 charge powercheck"", ""2"": ""PV2 charge powercheck"", ""3"": ""AC charge Powercheck""}",,,,,,,,,,,, +,,46,Production Line Mode,Production Line Mode,"{""0"": ""Not at ProductionLine Mode"", ""1"": ""Production LineMode"", ""2"": ""Production Line Clear Fault Mode""}",, 2:???? Production???? Line Clear Fault Mode,,,,,,,,,, +,,47,ConstantPowerOKFlag,Constant Power OK Flag,"{""0"": ""Not OK"", ""1"": ""OK""}",,,,,,,,,,,, +PV1 KWH Today,,48,Epv1_today H,PV Energy today,,,,,,,,,,,,, +,,49,Epv1_today L,PV Energy today,,0.1kW h,,,,,,,,,,, +PV1 KWH Total,,50,Epv1_total H,PV Energy total,,,,,,,,,,,,, +,,51,Epv1_total L,PV Energy total,,0.1kW h,,,,,,,,,,, +PV2 KWH Today,,52,Epv2_today H,PV Energy today,,,,,,,,,,,,, +,,53,Epv2_today L,PV Energy today,,0.1kW h,,,,,,,,,,, +PV2 KWH Total,,54,Epv2_total H,PV Energy total,,,,,,,,,,,,, +,,55,Epv2_total L,PV Energy total,,0.1kW h,,,,,,,,,,, +AC Input KWH Today,,56,Eac_chrToday H,AC charge Energy today,,,,,,,,,,,,, +,,57,Eac_chrToday L,AC charge Energy today,,0.1kW h,,,,,,,,,,, +AC Input KWH Total,,58,Eac_chrTotal H,AC charge Energy total,,,,,,,,,,,,, +,,59,Eac_chrTotal L,AC charge Energy total,,0.1kW h,,,,,,,,,,, +Battery Discharge KWH Today,,60,Ebat_dischrToday H,Bat discharge Energy today,,,,,,,,,,,,, +,,61,Ebat_dischrToday L,Bat discharge Energy today,,0.1kW h,,,,,,,,,,, +Battery Discharge KWH Total,,62,Ebat_dischrTotal H,Bat discharge Energy total,,,,,,,,,,,,, +,,63,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kW h,,,,,,,,,,, +AC Discharge KWH Today,,64,Eac_dischrToday H,AC discharge Energy today,,,,,,,,,,,,, +,,65,Eac_dischrToday L,AC discharge Energy today,,0.1kW h,,,,,,,,,,, +AC Discharge KWH Total,,66,Eac_dischrTotal H,AC discharge Energy total,,,,,,,,,,,,, +,,67,Eac_dischrTotal L,AC discharge Energy total,,0.1kW h,,,,,,,,,,, +AC Charge Current,,68,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, +AC Discharge Watts,,69,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, +,,70,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, +AC Discharge VA,,71,AC_DisChrVA H,AC? discharge? apparent? power (high),,0.1VA,,,,,,,,,,, +,,72,AC_DisChrVA L,AC? discharge? apparent? power (low),,0.1VA,,,,,,,,,,, +Battery Discharge Watts,,73,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, +,,74,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, +Battery Discharge VA,,75,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,76,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Input Watts,INT,77,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative:????????? Battery Charge Power,0.1W,,,,,,,,,,, +,INT,78,Bat_Watt L,Bat watt (low),,,,,,,,,,,,, +,,80,BatOverCharge,Battery Over Charge Flag,"{""0"": ""Battery not over charge"", ""1"": ""Battery over charge""}",,,,,,,,,,,, +,,81,MpptFanSpeed,Fan speed of MPPT Charger,0~100,1.00%,,,,,,,,,,, +,,82,InvFanSpeed,Fan speed of Inverter,0~100,1.00%,,,,,,,,,,, +,,90,BMS_Status,Status from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,91,BMS_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, +,,92,BMS_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS,,,,,,,,,, +,,93,BMS_SOC,SOC from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,94,BMS_ BatteryVolt,Battery voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,95,BMS_ BatteryCurr,Battery current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,96,BMS_ BatteryTemp,Battery???? temperature???? from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,97,BMS_ MaxCurr,Max. charge/discharge current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,98,BMS_ ConstantVolt,CV voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,99,BMS_ BMSInfo,BMS Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,100,BMS_ PackInfo,Pack Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,101,BMS_ UsingCap,Using Cap from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,102,BMS_ Cell1_Volt,Cell1_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,117,BMS_ Cell16_Volt,Cell16_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,118,BMS2_Status,Status from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,119,BMS2_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, +,,120,BMS2_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS2,,,,,,,,,, +,,121,BMS2_SOC,SOC from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,122,BMS2_ BatteryVolt,Battery voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,123,BMS2_ BatteryCurr,Battery current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,124,BMS2_ BatteryTemp,Battery???? temperature???? from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,125,BMS2_ MaxCurr,Max. charge/discharge current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,126,BMS2_ ConstantVolt,CV voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,127,BMS2_ BMSInfo,BMS Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,128,BMS2_ PackInfo,Pack Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,129,BMS2_ UsingCap,Using Cap from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,130,BMS2_ Cell1_Volt,Cell1_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,145,BMS2_ Cell16_Volt,Cell16_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,180,Solar1_Status,Solar Charger1 Status,,,,,,,,,,,,, +,,181,Solar1_FaultCode,Solar Charger1 FaultCode,,,,,,,,,,,,, +,,182,Solar1_WarningCode,Solar Charger1 WarningCode,,,,,,,,,,,,, +,,183,Solar1_BatVolt,Solar Charger1 battery voltage,,0.01V,,,,,,,,,,, +,,184,Solar1_PV1Volt,Solar Charger1 PV1 voltage,,0.1V,,,,,,,,,,, +,,185,Solar1_PV2Volt,Solar Charger1 PV2 voltage,,0.1V,,,,,,,,,,, +,,186,Solar1_Buck1Curr,Solar Charger1 Buck1 current,,0.1A,,,,,,,,,,, +,,187,Solar1_Buck2Curr,Solar Charger1 Buck2 current,,0.1A,,,,,,,,,,, +,,188,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,189,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,190,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,191,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,192,Solar1_HS1Temp,Solar????????? Charger1???????? Buck1 Temperature,,0.1C,,,,,,,,,,, +,,193,Solar1_HS2Temp,Solar????????? Charger1???????? Buck2 Temperature,,0.1C,,,,,,,,,,, +,,194,Solar1_Epv1_today,Solar Charger1 PV1 Energy today,,0.1k Wh,,,,,,,,,,, +,,195,Solar1_Epv2_today L,Solar Charger1 PV2 Energy today,,0.1k Wh,,,,,,,,,,, +,,196,Solar1_Epv1_total H,Solar Charger1 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,197,Solar1_Epv1_total L,Solar Charger1 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,198,Solar1_Epv2_total H,Solar Charger1 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,199,Solar1_Epv2_total L,Solar Charger1 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,200,Solar2_Status,Solar Charger2 Status,,,,,,,,,,,,, +,,201,Solar2_FaultCode,Solar Charger2 FaultCode,,,,,,,,,,,,, +,,202,Solar2_WarningCode,Solar Charger2 WarningCode,,,,,,,,,,,,, +,,203,Solar2_BatVolt,Solar Charger2 battery voltage,,0.01V,,,,,,,,,,, +,,204,Solar2_PV1Volt,Solar Charger2 PV1 voltage,,0.1V,,,,,,,,,,, +,,205,Solar2_PV2Volt,Solar Charger2 PV2 voltage,,0.1V,,,,,,,,,,, +,,206,Solar2_Buck1Curr,Solar Charger2 Buck1 current,,0.1A,,,,,,,,,,, +,,207,Solar2_Buck2Curr,Solar Charger2 Buck2 current,,0.1A,,,,,,,,,,, +,,208,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,209,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,210,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,211,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,212,Solar2_HS1Temp,Solar????????? Charger2???????? Buck1 Temperature,,0.1C,,,,,,,,,,, +,,213,Solar2_HS2Temp,Solar????????? Charger2???????? Buck2 Temperature,,0.1C,,,,,,,,,,, +,,214,Solar2_Epv1_today,Solar Charger2 PV1 Energy today,,0.1k Wh,,,,,,,,,,, +,,215,Solar2_Epv2_today,Solar Charger2 PV2 Energy today,,0.1k Wh,,,,,,,,,,, +,,216,Solar2_Epv1_total H,Solar Charger2 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,217,Solar2_Epv1_total L,Solar Charger2 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,218,Solar2_Epv2_total H,Solar Charger2 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,219,Solar2_Epv2_total L,Solar Charger2 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,220,Solar_ConnectOKFlag,Slave Solar Connect OK Flag,"{""1"": ""Solar Charger1"", ""2"": ""Solar Charger2"", ""3"": ""Solar Charger1 and 2""}",,,,,,,,,,,, +,,221,Solar_BatVoltConsistFl ag,Check Slave Solar Battery Voltage Consist OK Flag,"{""1"": ""Check Solar Charger1battery voltage OK"", ""2"": ""Check Solar Charger2battery voltage OK"", ""3"": ""Check Solar Charger1 and 2 battery voltage OK""}",,,,,,,,,,,, +,,222,Solar_TypeSwState ,Solar Charger Type Swtich State,"{""0"": ""Master SolarCharger"", ""1"": ""Slaver SolarCharger""}",,,,,,,,,,,, +,,223,Solar_ModeSwState ,Solar Charger Mode Swtich State,"{""0"": ""Parallel Mode"", ""1"": ""Single Mode""}",,,,,,,,,,,, +,,224,Solar_AddrSwState ,Solar Charger Addr Swtich State,2~3,,,,,,,,,,,, +,,360,BMS_ GaugeRM ,Gauge RM from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,361,BMS_GaugeFCC,Gauge FCC from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,362,BMS_ FW ,BMS_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,363,BMS_ DeltaVolt ,Delta V from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,364,BMS_ CycleCnt ,Cycle Count from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,365,BMS_ SOH,SOH from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,366,BMS_ GaugeICCurr,Gauge IC current from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,367,BMS_ MCUVersion ,MCU Software version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,368,BMS_ GaugeVersion ,Gauge Version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,369,BMS_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,370,BMS_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,371,BMS2_ GaugeRM ,BMS2_ GaugeRM ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,372,BMS2_GaugeFCC ,Gauge FCC from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,373,BMS2_ FW ,BMS2_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,374,BMS2_ DeltaVolt ,Delta V from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,375,BMS2_ CycleCnt ,Cycle Count from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,376,BMS2_ SOH ,SOH from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,377,BMS2_ GaugeICCurr ,Gauge IC current from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,378,BMS2_ MCUVersion ,MCU Software version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,379,BMS2_ GaugeVersion ,Gauge Version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,380,BMS2_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,381,BMS2_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, From 048491ec18aa6d42f0bf05a623b473880fc499df Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:09:24 -0500 Subject: [PATCH 16/53] default read intervals for sigineer --- .../sigineer_v0.11.holding_registry_map.csv | 104 ++--- .../sigineer_v0.11.input_registry_map.csv | 356 +++++++++--------- 2 files changed, 230 insertions(+), 230 deletions(-) diff --git a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv index f399424..400d76f 100644 --- a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv @@ -1,52 +1,52 @@ -variable name,data type,register,documented name,description,customer write,values,unit,Initial value,note,,,,,,,,,,,, -,,0,On_Off,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0).",,"0x0000:??? Standby??? off, Output enable; 0x0001:??? Standby??? on, Output enable; 0x0100:??? Standby??? off, Output disable; 0x0101:??? Standby??? on, Output disable;",,0,,,,,,,,,,,,, -,,1,OutputConfig,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"",""2"": ""UTI First""}",,,,,0,,,,,,,,,, -,,2,ChargeConfig,Charge source set,W,"{""0"": ""PV first"",""1"": ""PV&UTI"",""2"": ""PV Only""}",,,,,0,,,,,,,,,, -,,3,UtiOutStart,Uti Output Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, -,,4,UtiOutEnd,Uti Output End Time,W,0-23,H(hour),0,,,,,,,,,,,,, -,,5,UtiChargeStart,Uti Charge Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, -,,6,UtiChargeEnd,Uti Charge End Time,W,0-23,H(hour),0,,,,,,,,,,,,, -,,7,PVModel,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,0,,,,,,,,,,, -,,8,ACInModel,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC""}",,0,,,,,,,,,,,,, -,ASCII,r9~11,Fw version,Firmware version (high),,,ASCII,,,,,,,,,,,,,, -,ASCII,r12~14,Fw version2 H,Control Firmware version (high),,,ASCII,,,,,,,,,,,,,, -,,15,LCD language,LCD language,W,"{""0"" : ""Chinese?"", ""1"" : ""English""}",,1,English,,,,,,,,,,,, -,,18,OutputVoltType,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC""}",,,1,,,,,,,,,,,, -,,19,OutputFreqType,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,,0,,,,,,,,,,,, -,,20,OverLoadRestart,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",, 2: Swith to UTI,,,0,Yes(over???? Load 1mins????????????? to restart,?????? after over Load three times?? to?? stop output),,,,,,,, -,,21,OverTempRestart,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,,,0,Yes(over Temperature to???? restart?? , after??????????? over Temperature three? times? to stop output),,,,,,,,, -,,22,BuzzerEN,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,1,,,,,,,,,,, -Serial Number,ASCII,r23-27,Serial NO 5,Serial number 5,W,,ASCII,,,,,,,,,,,,,, -,,28,Moudle H,Inverter Moudle (high),W,,,,Can be set at standy?? state Only,,,,,,,,,,,, -,,29,Moudle L,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid,, 2: CustomLead_Acid, U-user type: 0: No verndor, 1: Sigineer, 2: CPS, 3: Haiti, M-power rate: 3: 3KW, 5:5KW, S-Aging, 0: Normal Mode, 1: Aging Mode,,,,Can be set at standy?? state Only -,,30,Com Address,Communicate?? address,W,1~254,,1,,,,,,,,,,,,, -,,31,FlashStart,Update firmware,W,0x0001: own 0X0100: control broad,,,,,,,,,,,,,,, -,,32,Reset User Info,Reset User Information,W,0x0001,,,,,,,,,,,,,,, -,,33,Reset to factory,Reset to factory,W,0x0001,,,,,,,,,,,,,,, -,,34,MaxChargeCurr,Max Charge Current,W,10~130,1A,70,,,,,,,,,,,,, -,,35,BulkChargeVolt,Bulk Charge Volt,W,500~580,0.1V,564,,,,,,,,,,,,, -,,36,FloatChargeVolt,Float Charge Volt,W,500~560,0.1V,540,,,,,,,,,,,,, -,,37,BatLowToUtiVolt,Bat Low Volt Switch To Uti,W,444~514,0.1V,464,,,,,,,,,,,,, -,,38,FloatChargeCurr,Float Charge Current,W,0~80,0.1A,,,,,,,,,,,,,, -,,39,Battery Type,Battery Type,W,"{""0"": ""Lead_Acid"", ""1"": ""Lithium"", ""2"": ""CustomLead_Acid""}",, 2: CustomLead_Acid,,,1,Can be set at standy?? state Only,,,,,,,,, -,,40,Aging Mode,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,0,Can be set at standy?? state Only,,,,,,,,,, -,,43,DTC,Device Type Code,,&*6,,,,,,,,,,,,,,, -,,45,Sys Year,System time-year,W,Year offset is 2000,,,,,,,,,,,,,,, -,,46,Sys Month,System time- Month,W,,,,,,,,,,,,,,,, -,,47,Sys Day,System time- Day,W,,,,,,,,,,,,,,,, -,,48,Sys Hour,System time- Hour,W,,,,,,,,,,,,,,,, -,,49,Sys Min,System time- Min,W,,,,,,,,,,,,,,,, -,,50,Sys Sec,System time- Second,W,,,,,,,,,,,,,,,, -,ASCII,59-66,Manufacturer Info,Manufacturer information (high),,,ASCII,,,,,,,,,,,,,, -,,67,FW Build No_ 4,Control FW Build No. 2,,,ASCII,,,,,,,,,,,,,, -,,68,FW Build No_ 3,Control FW Build No. 1,,,,,,,,,,,,,,,,, -,,69,FW Build No_ 2,COM FW Build No. 2,,,,,,,,,,,,,,,,, -,,70,FW Build No_ 1,COM FW Build No. 1,,,ASCII,,,,,,,,,,,,,, -,,72,Sys Weekly,Sys Weekly,W,0-6,,,,,,,,,,,,,,, -,,73,ModbusVersion,Modbus Version,,Eg:207 is V2.07,Int(16bit s),,,,,,,,,,,,,, -,,76,Rate Watt H ,Rate active power(high) ,,,0.1W,,,,,,,,,,,,,, -,,77,Rate Watt L ,Rate active power(low) ,,,0.1W,,,,,,,,,,,,,, -,,78,Rate VA H ,Rata apparent power (high) ,,,0.1VA,,,,,,,,,,,,,, -,,79,Rate VA L ,Rate apparent power (low) ,,,0.1VA,,,,,,,,,,,,,, -,,80,Factory,The ODM Info code,,,,,,,,,,,,,,,,, -,,162,BLVersion2,Boot loader version2,R,,,,,,,,,,,,,,,, +variable name,data type,register,documented name,read interval,description,customer write,values,unit,Initial value,note,,,,,,,,,,,, +,,0,On_Off,,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0).",,"0x0000:??? Standby??? off, Output enable; 0x0001:??? Standby??? on, Output enable; 0x0100:??? Standby??? off, Output disable; 0x0101:??? Standby??? on, Output disable;",,0,,,,,,,,,,,,, +,,1,OutputConfig,10x,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"",""2"": ""UTI First""}",,,,,0,,,,,,,,,, +,,2,ChargeConfig,10x,Charge source set,W,"{""0"": ""PV first"",""1"": ""PV&UTI"",""2"": ""PV Only""}",,,,,0,,,,,,,,,, +,,3,UtiOutStart,10x,Uti Output Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,4,UtiOutEnd,10x,Uti Output End Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,5,UtiChargeStart,10x,Uti Charge Start Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,6,UtiChargeEnd,10x,Uti Charge End Time,W,0-23,H(hour),0,,,,,,,,,,,,, +,,7,PVModel,10x,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,0,,,,,,,,,,, +,,8,ACInModel,10x,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC""}",,0,,,,,,,,,,,,, +,ASCII,r9~11,Fw version,10x,Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,ASCII,r12~14,Fw version2 H,10x,Control Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,,15,LCD language,10x,LCD language,W,"{""0"" : ""Chinese?"", ""1"" : ""English""}",,1,English,,,,,,,,,,,, +,,18,OutputVoltType,10x,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC""}",,,1,,,,,,,,,,,, +,,19,OutputFreqType,10x,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,,0,,,,,,,,,,,, +,,20,OverLoadRestart,10x,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",, 2: Swith to UTI,,,0,Yes(over???? Load 1mins????????????? to restart,?????? after over Load three times?? to?? stop output),,,,,,,, +,,21,OverTempRestart,10x,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,,,0,Yes(over Temperature to???? restart?? , after??????????? over Temperature three? times? to stop output),,,,,,,,, +,,22,BuzzerEN,10x,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,1,,,,,,,,,,, +Serial Number,ASCII,r23-27,Serial NO 5,10x,Serial number 5,W,,ASCII,,,,,,,,,,,,,, +,,28,Moudle H,10x,Inverter Moudle (high),W,,,,Can be set at standy?? state Only,,,,,,,,,,,, +,,29,Moudle L,10x,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid,, 2: CustomLead_Acid, U-user type: 0: No verndor, 1: Sigineer, 2: CPS, 3: Haiti, M-power rate: 3: 3KW, 5:5KW, S-Aging, 0: Normal Mode, 1: Aging Mode,,,,Can be set at standy?? state Only +,,30,Com Address,10x,Communicate?? address,W,1~254,,1,,,,,,,,,,,,, +,,31,FlashStart,10x,Update firmware,W,0x0001: own 0X0100: control broad,,,,,,,,,,,,,,, +,,32,Reset User Info,10x,Reset User Information,W,0x0001,,,,,,,,,,,,,,, +,,33,Reset to factory,10x,Reset to factory,W,0x0001,,,,,,,,,,,,,,, +,,34,MaxChargeCurr,10x,Max Charge Current,W,10~130,1A,70,,,,,,,,,,,,, +,,35,BulkChargeVolt,10x,Bulk Charge Volt,W,500~580,0.1V,564,,,,,,,,,,,,, +,,36,FloatChargeVolt,10x,Float Charge Volt,W,500~560,0.1V,540,,,,,,,,,,,,, +,,37,BatLowToUtiVolt,10x,Bat Low Volt Switch To Uti,W,444~514,0.1V,464,,,,,,,,,,,,, +,,38,FloatChargeCurr,10x,Float Charge Current,W,0~80,0.1A,,,,,,,,,,,,,, +,,39,Battery Type,10x,Battery Type,W,"{""0"": ""Lead_Acid"", ""1"": ""Lithium"", ""2"": ""CustomLead_Acid""}",, 2: CustomLead_Acid,,,1,Can be set at standy?? state Only,,,,,,,,, +,,40,Aging Mode,10x,Aging Mode,W,"{""0"": ""Normal Mode"", ""1"": ""Aging Mode""}",,,,0,Can be set at standy?? state Only,,,,,,,,,, +,,43,DTC,10x,Device Type Code,,&*6,,,,,,,,,,,,,,, +,,45,Sys Year,10x,System time-year,W,Year offset is 2000,,,,,,,,,,,,,,, +,,46,Sys Month,10x,System time- Month,W,,,,,,,,,,,,,,,, +,,47,Sys Day,10x,System time- Day,W,,,,,,,,,,,,,,,, +,,48,Sys Hour,10x,System time- Hour,W,,,,,,,,,,,,,,,, +,,49,Sys Min,10x,System time- Min,W,,,,,,,,,,,,,,,, +,,50,Sys Sec,10x,System time- Second,W,,,,,,,,,,,,,,,, +,ASCII,59-66,Manufacturer Info,10x,Manufacturer information (high),,,ASCII,,,,,,,,,,,,,, +,,67,FW Build No_ 4,10x,Control FW Build No. 2,,,ASCII,,,,,,,,,,,,,, +,,68,FW Build No_ 3,10x,Control FW Build No. 1,,,,,,,,,,,,,,,,, +,,69,FW Build No_ 2,10x,COM FW Build No. 2,,,,,,,,,,,,,,,,, +,,70,FW Build No_ 1,10x,COM FW Build No. 1,,,ASCII,,,,,,,,,,,,,, +,,72,Sys Weekly,10x,Sys Weekly,W,0-6,,,,,,,,,,,,,,, +,,73,ModbusVersion,10x,Modbus Version,,Eg:207 is V2.07,Int(16bit s),,,,,,,,,,,,,, +,,76,Rate Watt H ,10x,Rate active power(high) ,,,0.1W,,,,,,,,,,,,,, +,,77,Rate Watt L ,10x,Rate active power(low) ,,,0.1W,,,,,,,,,,,,,, +,,78,Rate VA H ,10x,Rata apparent power (high) ,,,0.1VA,,,,,,,,,,,,,, +,,79,Rate VA L ,10x,Rate apparent power (low) ,,,0.1VA,,,,,,,,,,,,,, +,,80,Factory,10x,The ODM Info code,,,,,,,,,,,,,,,,, +,,162,BLVersion2,10x,Boot loader version2,R,,,,,,,,,,,,,,,, diff --git a/protocols/sigineer/sigineer_v0.11.input_registry_map.csv b/protocols/sigineer/sigineer_v0.11.input_registry_map.csv index fd2c839..c4724d8 100644 --- a/protocols/sigineer/sigineer_v0.11.input_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.input_registry_map.csv @@ -1,178 +1,178 @@ -variable name,data type,register,documented name,description,values,unit,note,,,,,,,,,, -,,0,System Status,System run state,"{""0"": ""Standby"", ""1"": ""(No Use)"", ""2"": ""Discharge"", ""3"": ""Fault"", ""4"": ""Flash"", ""5"": ""PV charge"", ""6"": ""AC charge"", ""7"": ""Combine charge"", ""8"": ""Combine charge and Bypass"", ""9"": ""PV charge and Bypass"", ""10"": ""AC charge and Bypass"", ""11"": ""Bypass"", ""12"": ""PV charge and Discharge""}",,? (No Use) 2: Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge -PV1 Voltage,,1,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, -PV2 Voltage,,2,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, -PV1 Watts,,3,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, -,,4,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, -PV2 Watts,,5,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, -,,6,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, -Buck1 Current,,7,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, -Buck2 Current,,8,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, -Output Wattage,,9,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, -,,10,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, -Output VA,,11,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, -,,12,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, -AC Charge Watts,,13,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, -,,14,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, -AC Charge VA,,15,ACChr_VA H,AC?? charge (high),,0.1VA,,,,,,,,,,, -,,16,ACChr_VA L,AC?? charge (low),,0.1VA,,,,,,,,,,, -Battery Voltage,,17,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, -Battery SOC,,18,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, -Bus Voltage,,19,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, -Grid Voltage,,20,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, -Grid Hz,,21,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, -Output Voltage,,22,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, -Output Hz,,23,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, -Output DCV,,24,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, -,,25,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, -,,26,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, -Load Percentage,,27,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, -,,28,Bat_s_Volt ,Battery-port volt (DSP) ,,0.01V,,,,,,,,,,, -,,29,Bat_Volt_DSP ,Battery-bus volt (DSP) ,,0.01V,,,,,,,,,,, -,,30,Time total H,Work time total (high),,0.5S,,,,,,,,,,, -,,31,Time total L,Work time total (low),,0.5S,,,,,,,,,,, -Buck1 Temperature,,32,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, -Buck2 Temperature,,33,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, -Output Current,,34,OP_Curr,Output Current,,0.1A,,,,,,,,,,, -Inverter Current,,35,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, -AC Input Watts,,36,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, -,,37,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, -AC Input VA,,38,AC_InVA H,,,0.1VA,,,,,,,,,,, -,,39,AC_InVA L,,,0.1VA,,,,,,,,,,, -,,40,Fault bit,fault bit,&*1,,,,,,,,,,,, -,,41,Warning bit,Warning bit,&*1,,,,,,,,,,,, -,,42,fault value,fault value,,,,,,,,,,,,, -,,43,warning value,warning value,,,,,,,,,,,,, -,,44,DTC,Device Type Code,&*6,,,,,,,,,,,, -,,45,Check Step,Product check step,"{""1"": ""PV1 charge powercheck"", ""2"": ""PV2 charge powercheck"", ""3"": ""AC charge Powercheck""}",,,,,,,,,,,, -,,46,Production Line Mode,Production Line Mode,"{""0"": ""Not at ProductionLine Mode"", ""1"": ""Production LineMode"", ""2"": ""Production Line Clear Fault Mode""}",, 2:???? Production???? Line Clear Fault Mode,,,,,,,,,, -,,47,ConstantPowerOKFlag,Constant Power OK Flag,"{""0"": ""Not OK"", ""1"": ""OK""}",,,,,,,,,,,, -PV1 KWH Today,,48,Epv1_today H,PV Energy today,,,,,,,,,,,,, -,,49,Epv1_today L,PV Energy today,,0.1kW h,,,,,,,,,,, -PV1 KWH Total,,50,Epv1_total H,PV Energy total,,,,,,,,,,,,, -,,51,Epv1_total L,PV Energy total,,0.1kW h,,,,,,,,,,, -PV2 KWH Today,,52,Epv2_today H,PV Energy today,,,,,,,,,,,,, -,,53,Epv2_today L,PV Energy today,,0.1kW h,,,,,,,,,,, -PV2 KWH Total,,54,Epv2_total H,PV Energy total,,,,,,,,,,,,, -,,55,Epv2_total L,PV Energy total,,0.1kW h,,,,,,,,,,, -AC Input KWH Today,,56,Eac_chrToday H,AC charge Energy today,,,,,,,,,,,,, -,,57,Eac_chrToday L,AC charge Energy today,,0.1kW h,,,,,,,,,,, -AC Input KWH Total,,58,Eac_chrTotal H,AC charge Energy total,,,,,,,,,,,,, -,,59,Eac_chrTotal L,AC charge Energy total,,0.1kW h,,,,,,,,,,, -Battery Discharge KWH Today,,60,Ebat_dischrToday H,Bat discharge Energy today,,,,,,,,,,,,, -,,61,Ebat_dischrToday L,Bat discharge Energy today,,0.1kW h,,,,,,,,,,, -Battery Discharge KWH Total,,62,Ebat_dischrTotal H,Bat discharge Energy total,,,,,,,,,,,,, -,,63,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kW h,,,,,,,,,,, -AC Discharge KWH Today,,64,Eac_dischrToday H,AC discharge Energy today,,,,,,,,,,,,, -,,65,Eac_dischrToday L,AC discharge Energy today,,0.1kW h,,,,,,,,,,, -AC Discharge KWH Total,,66,Eac_dischrTotal H,AC discharge Energy total,,,,,,,,,,,,, -,,67,Eac_dischrTotal L,AC discharge Energy total,,0.1kW h,,,,,,,,,,, -AC Charge Current,,68,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, -AC Discharge Watts,,69,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, -,,70,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, -AC Discharge VA,,71,AC_DisChrVA H,AC? discharge? apparent? power (high),,0.1VA,,,,,,,,,,, -,,72,AC_DisChrVA L,AC? discharge? apparent? power (low),,0.1VA,,,,,,,,,,, -Battery Discharge Watts,,73,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, -,,74,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, -Battery Discharge VA,,75,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, -,,76,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, -Battery Input Watts,INT,77,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative:????????? Battery Charge Power,0.1W,,,,,,,,,,, -,INT,78,Bat_Watt L,Bat watt (low),,,,,,,,,,,,, -,,80,BatOverCharge,Battery Over Charge Flag,"{""0"": ""Battery not over charge"", ""1"": ""Battery over charge""}",,,,,,,,,,,, -,,81,MpptFanSpeed,Fan speed of MPPT Charger,0~100,1.00%,,,,,,,,,,, -,,82,InvFanSpeed,Fan speed of Inverter,0~100,1.00%,,,,,,,,,,, -,,90,BMS_Status,Status from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,91,BMS_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, -,,92,BMS_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS,,,,,,,,,, -,,93,BMS_SOC,SOC from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,94,BMS_ BatteryVolt,Battery voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,95,BMS_ BatteryCurr,Battery current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,96,BMS_ BatteryTemp,Battery???? temperature???? from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,97,BMS_ MaxCurr,Max. charge/discharge current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,98,BMS_ ConstantVolt,CV voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,99,BMS_ BMSInfo,BMS Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,100,BMS_ PackInfo,Pack Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,101,BMS_ UsingCap,Using Cap from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,102,BMS_ Cell1_Volt,Cell1_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,117,BMS_ Cell16_Volt,Cell16_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,118,BMS2_Status,Status from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,119,BMS2_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, -,,120,BMS2_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS2,,,,,,,,,, -,,121,BMS2_SOC,SOC from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,122,BMS2_ BatteryVolt,Battery voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,123,BMS2_ BatteryCurr,Battery current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,124,BMS2_ BatteryTemp,Battery???? temperature???? from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,125,BMS2_ MaxCurr,Max. charge/discharge current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,126,BMS2_ ConstantVolt,CV voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,127,BMS2_ BMSInfo,BMS Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,128,BMS2_ PackInfo,Pack Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,129,BMS2_ UsingCap,Using Cap from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,130,BMS2_ Cell1_Volt,Cell1_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,145,BMS2_ Cell16_Volt,Cell16_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, -,,180,Solar1_Status,Solar Charger1 Status,,,,,,,,,,,,, -,,181,Solar1_FaultCode,Solar Charger1 FaultCode,,,,,,,,,,,,, -,,182,Solar1_WarningCode,Solar Charger1 WarningCode,,,,,,,,,,,,, -,,183,Solar1_BatVolt,Solar Charger1 battery voltage,,0.01V,,,,,,,,,,, -,,184,Solar1_PV1Volt,Solar Charger1 PV1 voltage,,0.1V,,,,,,,,,,, -,,185,Solar1_PV2Volt,Solar Charger1 PV2 voltage,,0.1V,,,,,,,,,,, -,,186,Solar1_Buck1Curr,Solar Charger1 Buck1 current,,0.1A,,,,,,,,,,, -,,187,Solar1_Buck2Curr,Solar Charger1 Buck2 current,,0.1A,,,,,,,,,,, -,,188,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, -,,189,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, -,,190,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, -,,191,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, -,,192,Solar1_HS1Temp,Solar????????? Charger1???????? Buck1 Temperature,,0.1C,,,,,,,,,,, -,,193,Solar1_HS2Temp,Solar????????? Charger1???????? Buck2 Temperature,,0.1C,,,,,,,,,,, -,,194,Solar1_Epv1_today,Solar Charger1 PV1 Energy today,,0.1k Wh,,,,,,,,,,, -,,195,Solar1_Epv2_today L,Solar Charger1 PV2 Energy today,,0.1k Wh,,,,,,,,,,, -,,196,Solar1_Epv1_total H,Solar Charger1 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, -,,197,Solar1_Epv1_total L,Solar Charger1 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, -,,198,Solar1_Epv2_total H,Solar Charger1 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, -,,199,Solar1_Epv2_total L,Solar Charger1 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, -,,200,Solar2_Status,Solar Charger2 Status,,,,,,,,,,,,, -,,201,Solar2_FaultCode,Solar Charger2 FaultCode,,,,,,,,,,,,, -,,202,Solar2_WarningCode,Solar Charger2 WarningCode,,,,,,,,,,,,, -,,203,Solar2_BatVolt,Solar Charger2 battery voltage,,0.01V,,,,,,,,,,, -,,204,Solar2_PV1Volt,Solar Charger2 PV1 voltage,,0.1V,,,,,,,,,,, -,,205,Solar2_PV2Volt,Solar Charger2 PV2 voltage,,0.1V,,,,,,,,,,, -,,206,Solar2_Buck1Curr,Solar Charger2 Buck1 current,,0.1A,,,,,,,,,,, -,,207,Solar2_Buck2Curr,Solar Charger2 Buck2 current,,0.1A,,,,,,,,,,, -,,208,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, -,,209,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, -,,210,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, -,,211,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, -,,212,Solar2_HS1Temp,Solar????????? Charger2???????? Buck1 Temperature,,0.1C,,,,,,,,,,, -,,213,Solar2_HS2Temp,Solar????????? Charger2???????? Buck2 Temperature,,0.1C,,,,,,,,,,, -,,214,Solar2_Epv1_today,Solar Charger2 PV1 Energy today,,0.1k Wh,,,,,,,,,,, -,,215,Solar2_Epv2_today,Solar Charger2 PV2 Energy today,,0.1k Wh,,,,,,,,,,, -,,216,Solar2_Epv1_total H,Solar Charger2 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, -,,217,Solar2_Epv1_total L,Solar Charger2 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, -,,218,Solar2_Epv2_total H,Solar Charger2 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, -,,219,Solar2_Epv2_total L,Solar Charger2 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, -,,220,Solar_ConnectOKFlag,Slave Solar Connect OK Flag,"{""1"": ""Solar Charger1"", ""2"": ""Solar Charger2"", ""3"": ""Solar Charger1 and 2""}",,,,,,,,,,,, -,,221,Solar_BatVoltConsistFl ag,Check Slave Solar Battery Voltage Consist OK Flag,"{""1"": ""Check Solar Charger1battery voltage OK"", ""2"": ""Check Solar Charger2battery voltage OK"", ""3"": ""Check Solar Charger1 and 2 battery voltage OK""}",,,,,,,,,,,, -,,222,Solar_TypeSwState ,Solar Charger Type Swtich State,"{""0"": ""Master SolarCharger"", ""1"": ""Slaver SolarCharger""}",,,,,,,,,,,, -,,223,Solar_ModeSwState ,Solar Charger Mode Swtich State,"{""0"": ""Parallel Mode"", ""1"": ""Single Mode""}",,,,,,,,,,,, -,,224,Solar_AddrSwState ,Solar Charger Addr Swtich State,2~3,,,,,,,,,,,, -,,360,BMS_ GaugeRM ,Gauge RM from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,361,BMS_GaugeFCC,Gauge FCC from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,362,BMS_ FW ,BMS_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,363,BMS_ DeltaVolt ,Delta V from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,364,BMS_ CycleCnt ,Cycle Count from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,365,BMS_ SOH,SOH from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,366,BMS_ GaugeICCurr,Gauge IC current from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,367,BMS_ MCUVersion ,MCU Software version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,368,BMS_ GaugeVersion ,Gauge Version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,369,BMS_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,370,BMS_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,371,BMS2_ GaugeRM ,BMS2_ GaugeRM ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,372,BMS2_GaugeFCC ,Gauge FCC from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,373,BMS2_ FW ,BMS2_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,374,BMS2_ DeltaVolt ,Delta V from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,375,BMS2_ CycleCnt ,Cycle Count from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,376,BMS2_ SOH ,SOH from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,377,BMS2_ GaugeICCurr ,Gauge IC current from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,378,BMS2_ MCUVersion ,MCU Software version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,379,BMS2_ GaugeVersion ,Gauge Version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,380,BMS2_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, -,,381,BMS2_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +variable name,data type,register,read interval,documented name,description,values,unit,note,,,,,,,,,, +,,0,,System Status,System run state,"{""0"": ""Standby"", ""1"": ""(No Use)"", ""2"": ""Discharge"", ""3"": ""Fault"", ""4"": ""Flash"", ""5"": ""PV charge"", ""6"": ""AC charge"", ""7"": ""Combine charge"", ""8"": ""Combine charge and Bypass"", ""9"": ""PV charge and Bypass"", ""10"": ""AC charge and Bypass"", ""11"": ""Bypass"", ""12"": ""PV charge and Discharge""}",,? (No Use) 2: Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge, 12:??? PV??? charge??? and Discharge +PV1 Voltage,,1,,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, +PV2 Voltage,,2,,Vpv2,PV2 voltage,,0.1V,,,,,,,,,,, +PV1 Watts,,3,,Ppv1 H,PV1 charge power (high),,0.1W,,,,,,,,,,, +,,4,,Ppv1 L,PV1 charge power (low),,0.1W,,,,,,,,,,, +PV2 Watts,,5,,Ppv2 H,PV2 charge power (high),,0.1W,,,,,,,,,,, +,,6,,Ppv2 L,PV2 charge power (low),,0.1W,,,,,,,,,,, +Buck1 Current,,7,,Buck1Curr,Buck1 current,,0.1A,,,,,,,,,,, +Buck2 Current,,8,,Buck2Curr,Buck2 current,,0.1A,,,,,,,,,,, +Output Wattage,,9,,OP_Watt H,Output active power (high),,0.1W,,,,,,,,,,, +,,10,,OP_Watt L,Output active power (low),,0.1W,,,,,,,,,,, +Output VA,,11,,OP_VA H,Output apparent power (high),,0.1VA,,,,,,,,,,, +,,12,,OP_VA L,Output apparent power (low),,0.1VA,,,,,,,,,,, +AC Charge Watts,,13,,ACChr_Watt H,AC charge watt (high),,0.1W,,,,,,,,,,, +,,14,,ACChr_Watt L,AC charge watt (low),,0.1W,,,,,,,,,,, +AC Charge VA,,15,,ACChr_VA H,AC?? charge (high),,0.1VA,,,,,,,,,,, +,,16,,ACChr_VA L,AC?? charge (low),,0.1VA,,,,,,,,,,, +Battery Voltage,,17,,Bat Volt,Battery volt (M3),,0.01V,,,,,,,,,,, +Battery SOC,,18,,BatterySOC,Battery SOC,0~100,1.00%,,,,,,,,,,, +Bus Voltage,,19,,Bus Volt,Bus Voltage,,0.1V,,,,,,,,,,, +Grid Voltage,,20,,Grid Volt,AC input Volt,,0.1V,,,,,,,,,,, +Grid Hz,,21,,Line Freq,AC input frequency,,0.01Hz,,,,,,,,,,, +Output Voltage,,22,,OutputVolt,AC output Volt,,0.1V,,,,,,,,,,, +Output Hz,,23,,OutputFreq,AC output frequency,,0.01Hz,,,,,,,,,,, +Output DCV,,24,,Ouput DCV,Ouput DC Volt,,0.1V,,,,,,,,,,, +,,25,,InvTemp,Inv Temperature,,0.1C,,,,,,,,,,, +,,26,,DcDc Temp,DC-DC Temperature,,0.1C,,,,,,,,,,, +Load Percentage,,27,,LoadPercent,Load Percent,0~1000,0.10%,,,,,,,,,,, +,,28,,Bat_s_Volt ,Battery-port volt (DSP) ,,0.01V,,,,,,,,,,, +,,29,,Bat_Volt_DSP ,Battery-bus volt (DSP) ,,0.01V,,,,,,,,,,, +,,30,10x,Time total H,Work time total (high),,0.5S,,,,,,,,,,, +,,31,10x,Time total L,Work time total (low),,0.5S,,,,,,,,,,, +Buck1 Temperature,,32,,Buck1_NTC,Buck1 Temperature,,0.1C,,,,,,,,,,, +Buck2 Temperature,,33,,Buck2_NTC,Buck2 Temperature,,0.1C,,,,,,,,,,, +Output Current,,34,,OP_Curr,Output Current,,0.1A,,,,,,,,,,, +Inverter Current,,35,,Inv_Curr,Inv Current,,0.1A,,,,,,,,,,, +AC Input Watts,,36,,AC_InWatt H,AC input watt (high),,0.1W,,,,,,,,,,, +,,37,,AC_InWatt L,AC input watt (low),,0.1W,,,,,,,,,,, +AC Input VA,,38,,AC_InVA H,,,0.1VA,,,,,,,,,,, +,,39,,AC_InVA L,,,0.1VA,,,,,,,,,,, +,,40,,Fault bit,fault bit,&*1,,,,,,,,,,,, +,,41,,Warning bit,Warning bit,&*1,,,,,,,,,,,, +,,42,,fault value,fault value,,,,,,,,,,,,, +,,43,,warning value,warning value,,,,,,,,,,,,, +,,44,100x,DTC,Device Type Code,&*6,,,,,,,,,,,, +,,45,,Check Step,Product check step,"{""1"": ""PV1 charge powercheck"", ""2"": ""PV2 charge powercheck"", ""3"": ""AC charge Powercheck""}",,,,,,,,,,,, +,,46,,Production Line Mode,Production Line Mode,"{""0"": ""Not at ProductionLine Mode"", ""1"": ""Production LineMode"", ""2"": ""Production Line Clear Fault Mode""}",, 2:???? Production???? Line Clear Fault Mode,,,,,,,,,, +,,47,,ConstantPowerOKFlag,Constant Power OK Flag,"{""0"": ""Not OK"", ""1"": ""OK""}",,,,,,,,,,,, +PV1 KWH Today,,48,10x,Epv1_today H,PV Energy today,,,,,,,,,,,,, +,,49,10x,Epv1_today L,PV Energy today,,0.1kW h,,,,,,,,,,, +PV1 KWH Total,,50,10x,Epv1_total H,PV Energy total,,,,,,,,,,,,, +,,51,10x,Epv1_total L,PV Energy total,,0.1kW h,,,,,,,,,,, +PV2 KWH Today,,52,10x,Epv2_today H,PV Energy today,,,,,,,,,,,,, +,,53,10x,Epv2_today L,PV Energy today,,0.1kW h,,,,,,,,,,, +PV2 KWH Total,,54,10x,Epv2_total H,PV Energy total,,,,,,,,,,,,, +,,55,10x,Epv2_total L,PV Energy total,,0.1kW h,,,,,,,,,,, +AC Input KWH Today,,56,10x,Eac_chrToday H,AC charge Energy today,,,,,,,,,,,,, +,,57,10x,Eac_chrToday L,AC charge Energy today,,0.1kW h,,,,,,,,,,, +AC Input KWH Total,,58,10x,Eac_chrTotal H,AC charge Energy total,,,,,,,,,,,,, +,,59,10x,Eac_chrTotal L,AC charge Energy total,,0.1kW h,,,,,,,,,,, +Battery Discharge KWH Today,,60,10x,Ebat_dischrToday H,Bat discharge Energy today,,,,,,,,,,,,, +,,61,10x,Ebat_dischrToday L,Bat discharge Energy today,,0.1kW h,,,,,,,,,,, +Battery Discharge KWH Total,,62,10x,Ebat_dischrTotal H,Bat discharge Energy total,,,,,,,,,,,,, +,,63,10x,Ebat_dischrTotal L,Bat discharge Energy total,,0.1kW h,,,,,,,,,,, +AC Discharge KWH Today,,64,10x,Eac_dischrToday H,AC discharge Energy today,,,,,,,,,,,,, +,,65,10x,Eac_dischrToday L,AC discharge Energy today,,0.1kW h,,,,,,,,,,, +AC Discharge KWH Total,,66,10x,Eac_dischrTotal H,AC discharge Energy total,,,,,,,,,,,,, +,,67,10x,Eac_dischrTotal L,AC discharge Energy total,,0.1kW h,,,,,,,,,,, +AC Charge Current,,68,,ACChrCurr,AC Charge Battery Current,,0.1A,,,,,,,,,,, +AC Discharge Watts,,69,,AC_DisChrWatt H,AC discharge watt (high),,0.1W,,,,,,,,,,, +,,70,,AC_DisChrWatt L,AC discharge watt (low),,0.1W,,,,,,,,,,, +AC Discharge VA,,71,,AC_DisChrVA H,AC? discharge? apparent? power (high),,0.1VA,,,,,,,,,,, +,,72,,AC_DisChrVA L,AC? discharge? apparent? power (low),,0.1VA,,,,,,,,,,, +Battery Discharge Watts,,73,,Bat_DisChrWatt H,Bat discharge watt (high),,0.1W,,,,,,,,,,, +,,74,,Bat_DisChrWatt L,Bat discharge watt (low),,0.1W,,,,,,,,,,, +Battery Discharge VA,,75,,Bat_DisChrVA H,Bat discharge apparent power (high),,0.1VA,,,,,,,,,,, +,,76,,Bat_DisChrVA L,Bat discharge apparent power (low),,0.1VA,,,,,,,,,,, +Battery Input Watts,INT,77,,Bat_Watt H,Bat watt (high),(signed int 32) Positive:Battery Discharge Power Negative:????????? Battery Charge Power,0.1W,,,,,,,,,,, +,INT,78,,Bat_Watt L,Bat watt (low),,,,,,,,,,,,, +,,80,,BatOverCharge,Battery Over Charge Flag,"{""0"": ""Battery not over charge"", ""1"": ""Battery over charge""}",,,,,,,,,,,, +,,81,,MpptFanSpeed,Fan speed of MPPT Charger,0~100,1.00%,,,,,,,,,,, +,,82,,InvFanSpeed,Fan speed of Inverter,0~100,1.00%,,,,,,,,,,, +,,90,,BMS_Status,Status from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,91,,BMS_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, +,,92,,BMS_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS,,,,,,,,,, +,,93,,BMS_SOC,SOC from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,94,,BMS_ BatteryVolt,Battery voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,95,,BMS_ BatteryCurr,Battery current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,96,,BMS_ BatteryTemp,Battery???? temperature???? from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,97,,BMS_ MaxCurr,Max. charge/discharge current from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,98,,BMS_ ConstantVolt,CV voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,99,,BMS_ BMSInfo,BMS Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,100,,BMS_ PackInfo,Pack Information from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,101,,BMS_ UsingCap,Using Cap from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,102,,BMS_ Cell1_Volt,Cell1_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,117,,BMS_ Cell16_Volt,Cell16_Voltage from BMS,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,118,,BMS2_Status,Status from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,119,,BMS2_Error,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Error infomation from BMS,,,,,,,,,, +,,120,,BMS2_ WarnInfo,,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,Warning info from BMS2,,,,,,,,,, +,,121,,BMS2_SOC,SOC from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,122,,BMS2_ BatteryVolt,Battery voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,123,,BMS2_ BatteryCurr,Battery current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,124,,BMS2_ BatteryTemp,Battery???? temperature???? from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,125,,BMS2_ MaxCurr,Max. charge/discharge current from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,126,,BMS2_ ConstantVolt,CV voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,127,,BMS2_ BMSInfo,BMS Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,128,,BMS2_ PackInfo,Pack Information from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,129,,BMS2_ UsingCap,Using Cap from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,130,,BMS2_ Cell1_Volt,Cell1_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,145,,BMS2_ Cell16_Volt,Cell16_Voltage from BMS2,"Detail??? information,??? refer??? to document:? Sigineer? xxSxxP? ESS Protocol;",,,,,,,,,,,, +,,180,,Solar1_Status,Solar Charger1 Status,,,,,,,,,,,,, +,,181,,Solar1_FaultCode,Solar Charger1 FaultCode,,,,,,,,,,,,, +,,182,,Solar1_WarningCode,Solar Charger1 WarningCode,,,,,,,,,,,,, +,,183,,Solar1_BatVolt,Solar Charger1 battery voltage,,0.01V,,,,,,,,,,, +,,184,,Solar1_PV1Volt,Solar Charger1 PV1 voltage,,0.1V,,,,,,,,,,, +,,185,,Solar1_PV2Volt,Solar Charger1 PV2 voltage,,0.1V,,,,,,,,,,, +,,186,,Solar1_Buck1Curr,Solar Charger1 Buck1 current,,0.1A,,,,,,,,,,, +,,187,,Solar1_Buck2Curr,Solar Charger1 Buck2 current,,0.1A,,,,,,,,,,, +,,188,,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,189,,Solar1_PV1ChrPower H,Solar??? Charger1??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,190,,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,191,,Solar1_PV2ChrPower H,Solar??? Charger1??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,192,,Solar1_HS1Temp,Solar????????? Charger1???????? Buck1 Temperature,,0.1C,,,,,,,,,,, +,,193,,Solar1_HS2Temp,Solar????????? Charger1???????? Buck2 Temperature,,0.1C,,,,,,,,,,, +,,194,10x,Solar1_Epv1_today,Solar Charger1 PV1 Energy today,,0.1k Wh,,,,,,,,,,, +,,195,10x,Solar1_Epv2_today L,Solar Charger1 PV2 Energy today,,0.1k Wh,,,,,,,,,,, +,,196,10x,Solar1_Epv1_total H,Solar Charger1 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,197,10x,Solar1_Epv1_total L,Solar Charger1 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,198,10x,Solar1_Epv2_total H,Solar Charger1 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,199,10x,Solar1_Epv2_total L,Solar Charger1 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,200,,Solar2_Status,Solar Charger2 Status,,,,,,,,,,,,, +,,201,,Solar2_FaultCode,Solar Charger2 FaultCode,,,,,,,,,,,,, +,,202,,Solar2_WarningCode,Solar Charger2 WarningCode,,,,,,,,,,,,, +,,203,,Solar2_BatVolt,Solar Charger2 battery voltage,,0.01V,,,,,,,,,,, +,,204,,Solar2_PV1Volt,Solar Charger2 PV1 voltage,,0.1V,,,,,,,,,,, +,,205,,Solar2_PV2Volt,Solar Charger2 PV2 voltage,,0.1V,,,,,,,,,,, +,,206,,Solar2_Buck1Curr,Solar Charger2 Buck1 current,,0.1A,,,,,,,,,,, +,,207,,Solar2_Buck2Curr,Solar Charger2 Buck2 current,,0.1A,,,,,,,,,,, +,,208,,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,209,,Solar2_PV1ChrPower H,Solar??? Charger2??? PV1??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,210,,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power High 16 bit,,0.1W,,,,,,,,,,, +,,211,,Solar2_PV2ChrPower H,Solar??? Charger2??? PV2??? charge Power Low 16 bit,,0.1W,,,,,,,,,,, +,,212,,Solar2_HS1Temp,Solar????????? Charger2???????? Buck1 Temperature,,0.1C,,,,,,,,,,, +,,213,,Solar2_HS2Temp,Solar????????? Charger2???????? Buck2 Temperature,,0.1C,,,,,,,,,,, +,,214,10x,Solar2_Epv1_today,Solar Charger2 PV1 Energy today,,0.1k Wh,,,,,,,,,,, +,,215,10x,Solar2_Epv2_today,Solar Charger2 PV2 Energy today,,0.1k Wh,,,,,,,,,,, +,,216,10x,Solar2_Epv1_total H,Solar Charger2 PV1 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,217,10x,Solar2_Epv1_total L,Solar Charger2 PV1 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,218,10x,Solar2_Epv2_total H,Solar Charger2 PV2 Energy total High 16 bit,,0.1k Wh,,,,,,,,,,, +,,219,10x,Solar2_Epv2_total L,Solar Charger2 PV2 Energy total Low 16 bit,,0.1k Wh,,,,,,,,,,, +,,220,,Solar_ConnectOKFlag,Slave Solar Connect OK Flag,"{""1"": ""Solar Charger1"", ""2"": ""Solar Charger2"", ""3"": ""Solar Charger1 and 2""}",,,,,,,,,,,, +,,221,,Solar_BatVoltConsistFl ag,Check Slave Solar Battery Voltage Consist OK Flag,"{""1"": ""Check Solar Charger1battery voltage OK"", ""2"": ""Check Solar Charger2battery voltage OK"", ""3"": ""Check Solar Charger1 and 2 battery voltage OK""}",,,,,,,,,,,, +,,222,,Solar_TypeSwState ,Solar Charger Type Swtich State,"{""0"": ""Master SolarCharger"", ""1"": ""Slaver SolarCharger""}",,,,,,,,,,,, +,,223,,Solar_ModeSwState ,Solar Charger Mode Swtich State,"{""0"": ""Parallel Mode"", ""1"": ""Single Mode""}",,,,,,,,,,,, +,,224,,Solar_AddrSwState ,Solar Charger Addr Swtich State,2~3,,,,,,,,,,,, +,,360,,BMS_ GaugeRM ,Gauge RM from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,361,,BMS_GaugeFCC,Gauge FCC from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,362,100x,BMS_ FW ,BMS_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,363,,BMS_ DeltaVolt ,Delta V from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,364,100x,BMS_ CycleCnt ,Cycle Count from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,365,100x,BMS_ SOH,SOH from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,366,,BMS_ GaugeICCurr,Gauge IC current from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,367,100x,BMS_ MCUVersion ,MCU Software version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,368,100x,BMS_ GaugeVersion ,Gauge Version from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,369,100x,BMS_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,370,100x,BMS_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,371,,BMS2_ GaugeRM ,BMS2_ GaugeRM ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,372,,BMS2_GaugeFCC ,Gauge FCC from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,373,100x,BMS2_ FW ,BMS2_ FW ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,374,,BMS2_ DeltaVolt ,Delta V from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,375,,BMS2_ CycleCnt ,Cycle Count from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,376,,BMS2_ SOH ,SOH from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,377,,BMS2_ GaugeICCurr ,Gauge IC current from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,378,100x,BMS2_ MCUVersion ,MCU Software version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,379,100x,BMS2_ GaugeVersion ,Gauge Version from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,380,100x,BMS2_ wGaugeFRVersion_ L ,Gauge FR Version L16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, +,,381,100x,BMS2_ wGaugeFRVersion_H ,Gauge FR Version H16 from BMS2 ,"Detail???????? information, refer???? to???? document: Sigineer???? xxSxxP???? ESS Protocol;",,,,,,,,,,,, From 4bebaa9eefeda0da3950744a8720801da224625c Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:10:32 -0500 Subject: [PATCH 17/53] read interval --- .../sigineer_v0.11.holding_registry_map.csv | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv index 400d76f..2f61de8 100644 --- a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv @@ -8,15 +8,15 @@ variable name,data type,register,documented name,read interval,description,custo ,,6,UtiChargeEnd,10x,Uti Charge End Time,W,0-23,H(hour),0,,,,,,,,,,,,, ,,7,PVModel,10x,PV Input Mode,W,"{""0"": ""Independent"", ""1"": ""Parallel""}",,,,0,,,,,,,,,,, ,,8,ACInModel,10x,AC Input Mode,W,"{""0"": ""APL,90-280VAC"", ""1"": ""UPS,170-280VAC""}",,0,,,,,,,,,,,,, -,ASCII,r9~11,Fw version,10x,Firmware version (high),,,ASCII,,,,,,,,,,,,,, -,ASCII,r12~14,Fw version2 H,10x,Control Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,ASCII,r9~11,Fw version,100x,Firmware version (high),,,ASCII,,,,,,,,,,,,,, +,ASCII,r12~14,Fw version2 H,100x,Control Firmware version (high),,,ASCII,,,,,,,,,,,,,, ,,15,LCD language,10x,LCD language,W,"{""0"" : ""Chinese?"", ""1"" : ""English""}",,1,English,,,,,,,,,,,, ,,18,OutputVoltType,10x,Output Volt Type,W,"{""0"": ""208VAC"", ""1"": ""230VAC"", ""2"": ""240VAC""}",,,1,,,,,,,,,,,, ,,19,OutputFreqType,10x,Output Freq Type,W,"{""0"": ""50Hz"", ""1"": ""60Hz""}",,,0,,,,,,,,,,,, ,,20,OverLoadRestart,10x,Over Load Restart,W,"{""0"": ""Yes"", ""1"": ""No"", ""2"": ""Swith to UTI""}",, 2: Swith to UTI,,,0,Yes(over???? Load 1mins????????????? to restart,?????? after over Load three times?? to?? stop output),,,,,,,, ,,21,OverTempRestart,10x,Over Temperature Restart,W,"{""0"": ""Yes"", ""1"": ""No""}",,,,0,Yes(over Temperature to???? restart?? , after??????????? over Temperature three? times? to stop output),,,,,,,,, ,,22,BuzzerEN,10x,Buzzer on/off enable,W,"{""1"": ""Enable"", ""0"": ""Disable""}",,,,1,,,,,,,,,,, -Serial Number,ASCII,r23-27,Serial NO 5,10x,Serial number 5,W,,ASCII,,,,,,,,,,,,,, +Serial Number,ASCII,r23-27,Serial NO 5,100x,Serial number 5,W,,ASCII,,,,,,,,,,,,,, ,,28,Moudle H,10x,Inverter Moudle (high),W,,,,Can be set at standy?? state Only,,,,,,,,,,,, ,,29,Moudle L,10x,Inverter Moudle (low),W,P-battery type: 0: Lead_Acid,, 2: CustomLead_Acid, U-user type: 0: No verndor, 1: Sigineer, 2: CPS, 3: Haiti, M-power rate: 3: 3KW, 5:5KW, S-Aging, 0: Normal Mode, 1: Aging Mode,,,,Can be set at standy?? state Only ,,30,Com Address,10x,Communicate?? address,W,1~254,,1,,,,,,,,,,,,, @@ -37,16 +37,16 @@ Serial Number,ASCII,r23-27,Serial NO 5,10x,Serial number 5,W,,ASCII,,,,,,,,,,,,, ,,48,Sys Hour,10x,System time- Hour,W,,,,,,,,,,,,,,,, ,,49,Sys Min,10x,System time- Min,W,,,,,,,,,,,,,,,, ,,50,Sys Sec,10x,System time- Second,W,,,,,,,,,,,,,,,, -,ASCII,59-66,Manufacturer Info,10x,Manufacturer information (high),,,ASCII,,,,,,,,,,,,,, -,,67,FW Build No_ 4,10x,Control FW Build No. 2,,,ASCII,,,,,,,,,,,,,, -,,68,FW Build No_ 3,10x,Control FW Build No. 1,,,,,,,,,,,,,,,,, -,,69,FW Build No_ 2,10x,COM FW Build No. 2,,,,,,,,,,,,,,,,, -,,70,FW Build No_ 1,10x,COM FW Build No. 1,,,ASCII,,,,,,,,,,,,,, +,ASCII,59-66,Manufacturer Info,100x,Manufacturer information (high),,,ASCII,,,,,,,,,,,,,, +,,67,FW Build No_ 4,100x,Control FW Build No. 2,,,ASCII,,,,,,,,,,,,,, +,,68,FW Build No_ 3,100x,Control FW Build No. 1,,,,,,,,,,,,,,,,, +,,69,FW Build No_ 2,100x,COM FW Build No. 2,,,,,,,,,,,,,,,,, +,,70,FW Build No_ 1,100x,COM FW Build No. 1,,,ASCII,,,,,,,,,,,,,, ,,72,Sys Weekly,10x,Sys Weekly,W,0-6,,,,,,,,,,,,,,, -,,73,ModbusVersion,10x,Modbus Version,,Eg:207 is V2.07,Int(16bit s),,,,,,,,,,,,,, +,,73,ModbusVersion,100x,Modbus Version,,Eg:207 is V2.07,Int(16bit s),,,,,,,,,,,,,, ,,76,Rate Watt H ,10x,Rate active power(high) ,,,0.1W,,,,,,,,,,,,,, ,,77,Rate Watt L ,10x,Rate active power(low) ,,,0.1W,,,,,,,,,,,,,, ,,78,Rate VA H ,10x,Rata apparent power (high) ,,,0.1VA,,,,,,,,,,,,,, ,,79,Rate VA L ,10x,Rate apparent power (low) ,,,0.1VA,,,,,,,,,,,,,, ,,80,Factory,10x,The ODM Info code,,,,,,,,,,,,,,,,, -,,162,BLVersion2,10x,Boot loader version2,R,,,,,,,,,,,,,,,, +,,162,BLVersion2,100x,Boot loader version2,R,,,,,,,,,,,,,,,, From 9fa688af067eb5ac8f77a1beb040792299e2da8c Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:14:48 -0500 Subject: [PATCH 18/53] Update sigineer_v0.11.holding_registry_map.csv --- protocols/sigineer/sigineer_v0.11.holding_registry_map.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv index 2f61de8..06b9920 100644 --- a/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv +++ b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv @@ -1,4 +1,4 @@ -variable name,data type,register,documented name,read interval,description,customer write,values,unit,Initial value,note,,,,,,,,,,,, +variable name,data type,register,documented name,read_interval,description,customer write,values,unit,Initial value,note,,,,,,,,,,,, ,,0,On_Off,,"The Standby On/Off state and the AC output DisEN/EN state; The low byte is the Standby on/off(1/0), the high byte is the AC output disable/enable (1/0).",,"0x0000:??? Standby??? off, Output enable; 0x0001:??? Standby??? on, Output enable; 0x0100:??? Standby??? off, Output disable; 0x0101:??? Standby??? on, Output disable;",,0,,,,,,,,,,,,, ,,1,OutputConfig,10x,AC output set,W,"{""0"": ""BAT First"", ""1"": ""PV First"",""2"": ""UTI First""}",,,,,0,,,,,,,,,, ,,2,ChargeConfig,10x,Charge source set,W,"{""0"": ""PV first"",""1"": ""PV&UTI"",""2"": ""PV Only""}",,,,,0,,,,,,,,,, From 8f4cef7b4bfee179c7cf9dd28d1aabe9859ef2c8 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:24:01 -0500 Subject: [PATCH 19/53] allow write alias of writable --- classes/protocol_settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 30a2fb3..ad9004c 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -642,6 +642,9 @@ def process_row(row): writeMode : WriteMode = WriteMode.READ if "writable" in row: writeMode = WriteMode.fromString(row['writable']) + + if "write" in row: + writeMode = WriteMode.fromString(row['write']) for i in r: item = registry_map_entry( From d05f9e13de48de600ae47ea0f678813e019b66ae Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:35:07 -0500 Subject: [PATCH 20/53] Update creating_and_editing_protocols.md add read interval documentation --- .../usage/creating_and_editing_protocols.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/documentation/usage/creating_and_editing_protocols.md b/documentation/usage/creating_and_editing_protocols.md index efd3e26..3fa2bfa 100644 --- a/documentation/usage/creating_and_editing_protocols.md +++ b/documentation/usage/creating_and_editing_protocols.md @@ -11,8 +11,8 @@ The .csv files hold the registry or address definitions. CSV = comma seperated values... spreadsheets. delimeter for csv can be , or ; ( not both ) -| variable name | data type | register|documented name|description|writable|values | -| -- | -- | -- | -- | -- | -- | -- | +| variable name | data type | register| documented name|description|writable|values | read interval | +| -- | -- | -- | -- | -- | -- | -- | -- | ### variable name @@ -79,6 +79,28 @@ for example: the format for these flags is json. these flags / codes can also be defined via the .json file by naming them as such: "{{document_name}}_codes" +### read interval +provides a per register read interval; the minimum value is the configured transport read interval. + +#x for read_interval from transport config * # +#s for plainold seconds +#ms for miliseconds + +for example: +``` +[transport.modbus] +read_interval = 7 + ``` + +```7x``` +would set the read interval for that register to 49 seconds. + +```7s``` +would set the read interval to 7s + +```1s``` +because the transport read interval is 7 seconds, the read interval would effectively be 7 seconds + ##### Bit Flag Example ``` {"b0" : "StandBy", "b1" : "On"} From 88e1e6ca82993a23060883572d0b970e4e920cee Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:36:49 -0500 Subject: [PATCH 21/53] Update protocols.md --- documentation/usage/protocols.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/usage/protocols.md b/documentation/usage/protocols.md index ea76190..315d20f 100644 --- a/documentation/usage/protocols.md +++ b/documentation/usage/protocols.md @@ -37,7 +37,7 @@ protocol_version = eg4_v58.custom {protocol_name}.registry_map.csv contains configuration for generic "registers". ### csv format: -https://github.com/HotNoob/PythonProtocolGateway/wiki/Creating-and-Editing-Protocols-%E2%80%90-JSON-%E2%80%90-CSV#csv +[creating_and_editing_protocols.md](documentation/usage/creating_and_editing_protocols.md) - Creating and editing protocolss ## egv_v58 ``` From aff7e46774c8272ff7d0af010dcee7b69ba392bf Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:37:16 -0500 Subject: [PATCH 22/53] Update protocols.md --- documentation/usage/protocols.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/usage/protocols.md b/documentation/usage/protocols.md index 315d20f..9d86a70 100644 --- a/documentation/usage/protocols.md +++ b/documentation/usage/protocols.md @@ -37,7 +37,7 @@ protocol_version = eg4_v58.custom {protocol_name}.registry_map.csv contains configuration for generic "registers". ### csv format: -[creating_and_editing_protocols.md](documentation/usage/creating_and_editing_protocols.md) - Creating and editing protocolss +[creating_and_editing_protocols.md](creating_and_editing_protocols.md) - Creating and editing protocolss ## egv_v58 ``` From 1e997e7e6b617eef60f52b3ccb0bcf96ecb2efca Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 18 Mar 2025 15:39:07 -0500 Subject: [PATCH 23/53] Update protocols.md fix links --- documentation/usage/protocols.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/usage/protocols.md b/documentation/usage/protocols.md index 9d86a70..4a5a908 100644 --- a/documentation/usage/protocols.md +++ b/documentation/usage/protocols.md @@ -43,23 +43,23 @@ protocol_version = eg4_v58.custom ``` protocol_version = eg4_v58 ``` -[Devices\EG4 to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CEG4-to-MQTT) +[Devices\EG4 to MQTT](/documentation/devices/EG4.md) ## v0.14 ``` protocol_version = v0.14 ``` -[Devices\Growatt To MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CGrowatt-To-MQTT) +[Devices\Growatt To MQTT](/documentation/devices/Growatt.md) ## sigineer_v0.11 ``` protocol_version = sigineer_v0.11 ``` -[Devices\Sigineer to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CSigineer-to-MQTT) +[Devices\Sigineer to MQTT](/documentation/devices/Sigineer.md) ## pace_bms_v1.3 ``` protocol_version = pace_bms_v1.3 ``` -[Devices\SOK to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CSOK-to-MQTT) +[Devices\SOK to MQTT](/documentation/devices/SOK.md) From be86abcf4228c2a3389ea1179684468831afc125 Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Tue, 18 Mar 2025 21:13:13 +0000 Subject: [PATCH 24/53] fixes/reverts --- classes/transports/modbus_base.py | 4 ++-- classes/transports/mqtt.py | 4 +++- classes/transports/pace.py | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index ef299c7..ac177f9 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -353,8 +353,8 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type current_registers = self.read_modbus_registers(start=entry.register, end=entry.register, registry_type=registry_type) current_value = current_registers[entry.register] -# if not self.protocolSettings.validate_registry_entry(entry, current_value): -# raise ValueError(f"Invalid value in register '{current_value}'. Unsafe to write") + if not self.protocolSettings.validate_registry_entry(entry, current_value): + raise ValueError(f"Invalid value in register '{current_value}'. Unsafe to write") if not self.protocolSettings.validate_registry_entry(entry, value): raise ValueError(f"Invalid new value, '{value}'. Unsafe to write") diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index 9a6227e..ae5bd17 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -25,7 +25,9 @@ class mqtt(transport_base): discovery_topic : str = "homeassistant" discovery_enabled : bool = False json : bool = False - reconnect_delay : int = 7 # seconds + reconnect_delay : int = 7 + """ seconds """ + reconnect_attempts : int = 21 #max_precision : int = - 1 diff --git a/classes/transports/pace.py b/classes/transports/pace.py index 4bfb1e9..8d12cc1 100644 --- a/classes/transports/pace.py +++ b/classes/transports/pace.py @@ -187,6 +187,7 @@ def buildPacket(self, message): message.unit_id, 0x03) + data crc = computeCRC(packet) + crc2 = calculate_crc(packet,size) #packet struct: #slave address - 0x01 - 0x10 From 3f0980030a328029ed339c6290dcfafc4f2f88d7 Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Tue, 18 Mar 2025 21:14:55 +0000 Subject: [PATCH 25/53] fixes/reverts2 --- classes/transports/pace.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/classes/transports/pace.py b/classes/transports/pace.py index 8d12cc1..6e28885 100644 --- a/classes/transports/pace.py +++ b/classes/transports/pace.py @@ -186,8 +186,10 @@ def buildPacket(self, message): packet = struct.pack(RTU_FRAME_HEADER, message.unit_id, 0x03) + data + crc = computeCRC(packet) - crc2 = calculate_crc(packet,size) +# size = len(packet) +# crc2 = calculate_crc(packet, size) #packet struct: #slave address - 0x01 - 0x10 From ab775c4ca8262e071a31374ea03a202dcd146b0e Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Wed, 19 Mar 2025 01:43:46 +0000 Subject: [PATCH 26/53] add more rules --- classes/protocol_settings.py | 7 ++++++- classes/transports/canbus.py | 4 +++- classes/transports/modbus_base.py | 6 ++++-- classes/transports/mqtt.py | 2 +- ruff.toml | 17 +++++++++++------ test.py | 2 +- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 2644a92..434896e 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -237,13 +237,16 @@ def __hash__(self): class protocol_settings: + protocol : str transport : str settings_dir : str variable_mask : list[str] ''' list of variables to allow and exclude all others ''' + variable_screen : list[str] ''' list of variables to exclude ''' + registry_map : dict[Registry_Type, list[registry_map_entry]] = {} registry_map_size : dict[Registry_Type, int] = {} registry_map_ranges : dict[Registry_Type, list[tuple]] = {} @@ -801,6 +804,8 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register ranges.append((min(registers), max(registers)-min(registers)+1)) ## APPENDING A TUPLE! return ranges + + def find_protocol_file(self, file : str, base_dir : str = '' ) -> str: path = base_dir + '/' + file @@ -1230,7 +1235,7 @@ def replace_vars(match): tree = ast.parse(maths, mode='eval') # Evaluate the expression - end_value = eval(compile(tree, filename='', mode='eval')) + end_value = ast.literal_eval(compile(tree, filename='', mode='eval')) return str(end_value) except Exception: diff --git a/classes/transports/canbus.py b/classes/transports/canbus.py index f715817..5257dc0 100644 --- a/classes/transports/canbus.py +++ b/classes/transports/canbus.py @@ -107,6 +107,7 @@ def setup_socketcan(self): print("socketcan setup not implemented for windows") return + # ruff: noqa: S605, S607 self._log.info("restart and configure socketcan") os.system("ip link set can0 down") os.system("ip link set can0 type can restart-ms 100") @@ -120,9 +121,10 @@ def is_socketcan_up(self) -> bool: try: with open(f'/sys/class/net/{self.port}/operstate', 'r') as f: state = f.read().strip() - return state == 'up' except FileNotFoundError: return False + else: + return state == 'up' def start_loop(self): self.read_bus(self.bus) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 9b0839c..db0f6af 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -357,10 +357,12 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type current_value = current_registers[entry.register] if not self.protocolSettings.validate_registry_entry(entry, current_value): - raise ValueError(f"Invalid value in register '{current_value}'. Unsafe to write") + err = f"Invalid value in register '{current_value}'. Unsafe to write" + raise ValueError(err) if not self.protocolSettings.validate_registry_entry(entry, value): - raise ValueError(f"Invalid new value, '{value}'. Unsafe to write") + err = f"Invalid new value, '{value}'. Unsafe to write" + raise ValueError(err) #handle codes if entry.variable_name+"_codes" in self.protocolSettings.codes: diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index ae5bd17..f4187c5 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -119,7 +119,7 @@ def mqtt_reconnect(self): self.__reconnecting = time.time() try: self._log.warning("Attempting to reconnect("+str(attempt)+")...") - if random.randint(0,1): #alternate between methods because built in reconnect might be unreliable. + if random.randint(0,1): # noqa: S311 alternate between methods because built in reconnect might be unreliable. self.client.reconnect() else: self.client.loop_stop() diff --git a/ruff.toml b/ruff.toml index ddf2766..a73964f 100644 --- a/ruff.toml +++ b/ruff.toml @@ -7,14 +7,19 @@ target-version = "py311" # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["E", "F", "W"] -ignore = ["E501"] +select = ["BLE", "C", "DTZ", "E", "EM", "F", "FA", "FBT", "G", "I", "S", "TRY", "W"] #select = ["ALL"] -#ignore = ["C901", "EM101", "TRY003", "E501", "D", "G004", "N", "S105", -# "DTZ007", "S301", "RUF013", "PTH123", "PLW0603", "TRY400", "BLE001", -# "PLR0912", "PLR0915", "FBT001", "FBT002", "FA100", "W191" -#] +ignore = [ +"BLE001", +"C901", +# "D", +"EM101", +"E501", +"FBT001", "FBT002", +"N", +"TRY003", +] [format] quote-style = "double" diff --git a/test.py b/test.py index c383d4c..235035a 100644 --- a/test.py +++ b/test.py @@ -127,7 +127,7 @@ def replace_vars(match): tree = ast.parse(maths, mode='eval') # Evaluate the expression - end_value = eval(compile(tree, filename='', mode='eval')) + end_value = ast.literal_eval(compile(tree, filename='', mode='eval')) return str(end_value) except Exception: From e4dd4fef17e5829248c1d2f3d7cd694f9f330823 Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Wed, 19 Mar 2025 01:49:24 +0000 Subject: [PATCH 27/53] forgot to run against 'I' rules which formats imports sections --- classes/protocol_settings.py | 17 ++++++++--------- classes/transports/canbus.py | 18 +++++++++--------- classes/transports/modbus_base.py | 13 ++++++++++--- classes/transports/modbus_rtu.py | 8 +++++--- classes/transports/modbus_tcp.py | 3 ++- classes/transports/modbus_tls.py | 7 +++++-- classes/transports/modbus_udp.py | 7 +++++-- classes/transports/mqtt.py | 13 +++++++------ classes/transports/pace.py | 18 +++++++++--------- classes/transports/serial_frame_client.py | 5 +++-- classes/transports/serial_pylon.py | 11 +++++------ classes/transports/transport_base.py | 14 +++++++++----- defs/common.py | 4 +++- protocol_gateway.py | 6 ++---- pytests/test_example_config.py | 3 ++- pytests/test_protocol_settings.py | 6 +++--- test.py | 7 +++---- 17 files changed, 90 insertions(+), 70 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 434896e..8d79338 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1,18 +1,17 @@ +import ast import csv -from dataclasses import dataclass -from enum import Enum import glob -import logging -import time -from typing import Union -from defs.common import strtoint import itertools import json -import re +import logging import os -import ast +import re +import time +from dataclasses import dataclass +from enum import Enum +from typing import TYPE_CHECKING, Union -from typing import TYPE_CHECKING +from defs.common import strtoint if TYPE_CHECKING: from configparser import SectionProxy diff --git a/classes/transports/canbus.py b/classes/transports/canbus.py index 5257dc0..9ea21a2 100644 --- a/classes/transports/canbus.py +++ b/classes/transports/canbus.py @@ -1,19 +1,19 @@ -import re -import time -import can import asyncio -import threading -import platform import os +import platform +import re +import threading +import time +from collections import OrderedDict +from typing import TYPE_CHECKING +import can +from defs.common import strtoint +from ..protocol_settings import Registry_Type, protocol_settings, registry_map_entry from .transport_base import transport_base -from ..protocol_settings import Registry_Type, registry_map_entry, protocol_settings -from defs.common import strtoint -from collections import OrderedDict -from typing import TYPE_CHECKING if TYPE_CHECKING: from configparser import SectionProxy diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index db0f6af..f4a3639 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -3,13 +3,20 @@ import os import re import time +from typing import TYPE_CHECKING + from pymodbus.exceptions import ModbusIOException -from .transport_base import transport_base -from ..protocol_settings import Data_Type, Registry_Type, registry_map_entry, protocol_settings from defs.common import strtobool -from typing import TYPE_CHECKING +from ..protocol_settings import ( + Data_Type, + Registry_Type, + protocol_settings, + registry_map_entry, +) +from .transport_base import transport_base + if TYPE_CHECKING: from configparser import SectionProxy try: diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index 561658c..bf8fd1a 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -1,7 +1,6 @@ -from classes.protocol_settings import Registry_Type, protocol_settings - import inspect +from classes.protocol_settings import Registry_Type, protocol_settings try: from pymodbus.client.sync import ModbusSerialClient @@ -9,10 +8,13 @@ from pymodbus.client import ModbusSerialClient -from .modbus_base import modbus_base from configparser import SectionProxy + from defs.common import find_usb_serial_port, get_usb_serial_port_info, strtoint +from .modbus_base import modbus_base + + class modbus_rtu(modbus_base): port : str = "/dev/ttyUSB0" addresses : list[int] = [] diff --git a/classes/transports/modbus_tcp.py b/classes/transports/modbus_tcp.py index 22ce4af..984f146 100644 --- a/classes/transports/modbus_tcp.py +++ b/classes/transports/modbus_tcp.py @@ -8,9 +8,10 @@ except ImportError: from pymodbus.client import ModbusTcpClient -from .modbus_base import modbus_base from configparser import SectionProxy +from .modbus_base import modbus_base + class modbus_tcp(modbus_base): port : str = 502 diff --git a/classes/transports/modbus_tls.py b/classes/transports/modbus_tls.py index c6b464a..c7e1f3d 100644 --- a/classes/transports/modbus_tls.py +++ b/classes/transports/modbus_tls.py @@ -1,7 +1,10 @@ -from classes.protocol_settings import Registry_Type, protocol_settings +from configparser import SectionProxy + from pymodbus.client.sync import ModbusTlsClient + +from classes.protocol_settings import Registry_Type, protocol_settings + from .transport_base import transport_base -from configparser import SectionProxy class modbus_udp(transport_base): diff --git a/classes/transports/modbus_udp.py b/classes/transports/modbus_udp.py index a9f77b4..a3bfef6 100644 --- a/classes/transports/modbus_udp.py +++ b/classes/transports/modbus_udp.py @@ -1,7 +1,10 @@ -from classes.protocol_settings import Registry_Type, protocol_settings +from configparser import SectionProxy + from pymodbus.client.sync import ModbusUdpClient + +from classes.protocol_settings import Registry_Type, protocol_settings + from .transport_base import transport_base -from configparser import SectionProxy class modbus_udp(transport_base): diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index f4187c5..d6c33aa 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -1,19 +1,20 @@ import atexit +import json import random import time -import json import warnings +from configparser import SectionProxy import paho.mqtt.client -import paho.mqtt.properties import paho.mqtt.packettypes - -from paho.mqtt.client import Client as MQTTClient, MQTT_ERR_NO_CONN +import paho.mqtt.properties +from paho.mqtt.client import MQTT_ERR_NO_CONN +from paho.mqtt.client import Client as MQTTClient from defs.common import strtobool + +from ..protocol_settings import Registry_Type, WriteMode, registry_map_entry from .transport_base import transport_base -from configparser import SectionProxy -from ..protocol_settings import registry_map_entry, WriteMode, Registry_Type class mqtt(transport_base): diff --git a/classes/transports/pace.py b/classes/transports/pace.py index 6e28885..7dae56b 100644 --- a/classes/transports/pace.py +++ b/classes/transports/pace.py @@ -1,16 +1,16 @@ -import time -import struct import logging -from classes.protocol_settings import Registry_Type -from pymodbus.client.sync import ModbusSerialClient, BaseModbusClient -from pymodbus.transaction import ModbusRtuFramer +import struct +import time -from pymodbus.factory import ClientDecoder +from pymodbus.client.sync import BaseModbusClient, ModbusSerialClient +from pymodbus.compat import byte2int from pymodbus.constants import Defaults - +from pymodbus.factory import ClientDecoder +from pymodbus.framer import BYTE_ORDER, FRAME_HEADER +from pymodbus.transaction import ModbusRtuFramer from pymodbus.utilities import checkCRC, computeCRC -from pymodbus.compat import byte2int -from pymodbus.framer import FRAME_HEADER, BYTE_ORDER + +from classes.protocol_settings import Registry_Type _logger = logging.getLogger(__name__) diff --git a/classes/transports/serial_frame_client.py b/classes/transports/serial_frame_client.py index 6778075..eef81a9 100644 --- a/classes/transports/serial_frame_client.py +++ b/classes/transports/serial_frame_client.py @@ -1,7 +1,8 @@ -from typing import Callable -import serial import threading import time +from typing import Callable + +import serial class serial_frame_client(): diff --git a/classes/transports/serial_pylon.py b/classes/transports/serial_pylon.py index fcc309f..69e2f51 100644 --- a/classes/transports/serial_pylon.py +++ b/classes/transports/serial_pylon.py @@ -1,19 +1,18 @@ -from enum import Enum import struct +from enum import Enum +from typing import TYPE_CHECKING import serial -from ..Object import Object +from defs.common import find_usb_serial_port, get_usb_serial_port_info +from ..Object import Object from .serial_frame_client import serial_frame_client from .transport_base import transport_base -from defs.common import find_usb_serial_port, get_usb_serial_port_info - - -from typing import TYPE_CHECKING if TYPE_CHECKING: from configparser import SectionProxy + from classes.protocol_settings import protocol_settings, registry_map_entry diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index adeb282..cdff05e 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -1,13 +1,17 @@ - import logging -from classes.protocol_settings import Registry_Type,protocol_settings,registry_map_entry +from typing import TYPE_CHECKING, Callable + +from classes.protocol_settings import ( + Registry_Type, + protocol_settings, + registry_map_entry, +) -from typing import Callable -from typing import TYPE_CHECKING if TYPE_CHECKING: - from .transport_base import transport_base from configparser import SectionProxy + from .transport_base import transport_base + class transport_base: type : str = '' protocolSettings : 'protocol_settings' diff --git a/defs/common.py b/defs/common.py index a28c371..2be9517 100644 --- a/defs/common.py +++ b/defs/common.py @@ -1,6 +1,8 @@ -import serial.tools.list_ports import re +import serial.tools.list_ports + + def strtobool (val): """Convert a string representation of truth to true (1) or false (0). True values are 'y', 'yes', 't', 'true', 'on', and '1' diff --git a/protocol_gateway.py b/protocol_gateway.py index 1a4590a..485beb7 100644 --- a/protocol_gateway.py +++ b/protocol_gateway.py @@ -19,17 +19,15 @@ import argparse - -import os import logging +import os import sys import traceback from configparser import ConfigParser, NoOptionError -from classes.protocol_settings import protocol_settings,registry_map_entry +from classes.protocol_settings import protocol_settings, registry_map_entry from classes.transports.transport_base import transport_base - __logo = """ ██████╗ ██╗ ██╗████████╗██╗ ██╗ ██████╗ ███╗ ██╗ diff --git a/pytests/test_example_config.py b/pytests/test_example_config.py index 3f36f27..d3909c2 100644 --- a/pytests/test_example_config.py +++ b/pytests/test_example_config.py @@ -1,11 +1,12 @@ -import sys import os +import sys #move up a folder for tests sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from protocol_gateway import CustomConfigParser + def test_example_cfg(): parser = CustomConfigParser() parser.read("config.cfg.example") diff --git a/pytests/test_protocol_settings.py b/pytests/test_protocol_settings.py index c682432..bada009 100644 --- a/pytests/test_protocol_settings.py +++ b/pytests/test_protocol_settings.py @@ -1,8 +1,8 @@ -import sys -import os -import pytest import glob +import os +import sys +import pytest #move up a folder for tests sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) diff --git a/test.py b/test.py index 235035a..3272c8a 100644 --- a/test.py +++ b/test.py @@ -1,12 +1,11 @@ -import re import ast +import re #pip install "python-can[gs_usb]" - -import can #v4.2.0+ +import can #v4.2.0+ if False: - import usb #pyusb - requires https://github.com/mcuee/libusb-win32 + import usb #pyusb - requires https://github.com/mcuee/libusb-win32 From b017bbde3d217ca1e86582267bbb0f863862f3f9 Mon Sep 17 00:00:00 2001 From: utdrmac <4413670+utdrmac@users.noreply.github.com> Date: Wed, 19 Mar 2025 01:57:46 +0000 Subject: [PATCH 28/53] Rules for single/double quote (Q) --- classes/protocol_settings.py | 244 ++++++++++----------- classes/transports/canbus.py | 26 +-- classes/transports/modbus_base.py | 48 ++-- classes/transports/modbus_rtu.py | 30 +-- classes/transports/modbus_tcp.py | 14 +- classes/transports/mqtt.py | 68 +++--- classes/transports/pace.py | 20 +- classes/transports/serial_frame_client.py | 2 +- classes/transports/serial_pylon.py | 38 ++-- classes/transports/transport_base.py | 38 ++-- defs/common.py | 28 +-- documentation/.scripts/generate_indexes.py | 8 +- protocol_gateway.py | 36 +-- pytests/test_example_config.py | 2 +- pytests/test_protocol_settings.py | 4 +- ruff.toml | 5 +- test.py | 22 +- tools/apply_common_names_to_csv.py | 26 +-- tools/get_common_names_from_csv.py | 26 +-- tools/list_to_json.py | 6 +- 20 files changed, 346 insertions(+), 345 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 8d79338..543c809 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -108,7 +108,7 @@ def fromString(cls, name : str): return getattr(cls, name) @classmethod - def getSize(cls, data_type : 'Data_Type'): + def getSize(cls, data_type : "Data_Type"): sizes = { Data_Type.BYTE : 8, Data_Type.USHORT : 16, @@ -254,14 +254,14 @@ class protocol_settings: settings : dict[str, str] ''' default settings provided by protocol json ''' - transport_settings : 'SectionProxy' = None + transport_settings : "SectionProxy" = None byteorder : str = "big" _log : logging.Logger = None - def __init__(self, protocol : str, transport_settings : 'SectionProxy' = None, settings_dir : str = 'protocols'): + def __init__(self, protocol : str, transport_settings : "SectionProxy" = None, settings_dir : str = "protocols"): #apply log level to logger self._log_level = getattr(logging, logging.getLevelName(logging.getLogger().getEffectiveLevel()), logging.INFO) @@ -274,20 +274,20 @@ def __init__(self, protocol : str, transport_settings : 'SectionProxy' = None, s #load variable mask self.variable_mask = [] - if os.path.isfile('variable_mask.txt'): - with open('variable_mask.txt') as f: + if os.path.isfile("variable_mask.txt"): + with open("variable_mask.txt") as f: for line in f: - if line[0] == '#': #skip comment + if line[0] == "#": #skip comment continue self.variable_mask.append(line.strip().lower()) #load variable screen self.variable_screen = [] - if os.path.isfile('variable_screen.txt'): - with open('variable_screen.txt') as f: + if os.path.isfile("variable_screen.txt"): + with open("variable_screen.txt") as f: for line in f: - if line[0] == '#': #skip comment + if line[0] == "#": #skip comment continue self.variable_screen.append(line.strip().lower()) @@ -324,19 +324,19 @@ def get_input_registry_entry(self, name : str): def get_registry_entry(self, name : str, registry_type : Registry_Type) -> registry_map_entry: - name = name.strip().lower().replace(' ', '_') #clean name + name = name.strip().lower().replace(" ", "_") #clean name for item in self.registry_map[registry_type]: if item.documented_name == name: return item return None - def load__json(self, file : str = '', settings_dir : str = ''): + def load__json(self, file : str = "", settings_dir : str = ""): if not settings_dir: settings_dir = self.settings_dir if not file: - file = self.protocol + '.json' + file = self.protocol + ".json" path = self.find_protocol_file(file, settings_dir) @@ -359,12 +359,12 @@ def load_registry_overrides(self, override_path, keys : list[str]): """Load overrides into a multidimensional dictionary keyed by each specified key.""" overrides = {key: {} for key in keys} - with open(override_path, newline='', encoding='latin-1') as csvfile: + with open(override_path, newline="", encoding="latin-1") as csvfile: reader = csv.DictReader(csvfile) for row in reader: for key in keys: if key in row: - row[key] = row[key].strip().lower().replace(' ', '_') + row[key] = row[key].strip().lower().replace(" ", "_") key_value = row[key] if key_value: overrides[key][key_value] = row @@ -373,16 +373,16 @@ def load_registry_overrides(self, override_path, keys : list[str]): def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INPUT) -> list[registry_map_entry]: registry_map : list[registry_map_entry] = [] - register_regex = re.compile(r'(?P(?:0?x[\da-z]+|[\d]+))\.(b(?Px?\d{1,2})|(?Px?\d{1,2}))') + register_regex = re.compile(r"(?P(?:0?x[\da-z]+|[\d]+))\.(b(?Px?\d{1,2})|(?Px?\d{1,2}))") - read_interval_regex = re.compile(r'(?P[\.\d]+)(?P[xs]|ms)') + read_interval_regex = re.compile(r"(?P[\.\d]+)(?P[xs]|ms)") - data_type_regex = re.compile(r'(?P\w+)\.(?P\d+)') + data_type_regex = re.compile(r"(?P\w+)\.(?P\d+)") - range_regex = re.compile(r'(?Pr|)(?P(?:0?x[\da-z]+|[\d]+))[\-~](?P(?:0?x[\da-z]+|[\d]+))') - ascii_value_regex = re.compile(r'(?P^\[.+\]$)') - list_regex = re.compile(r'\s*(?:(?P(?:0?x[\da-z]+|[\d]+))-(?P(?:0?x[\da-z]+|[\d]+))|(?P[^,\s][^,]*?))\s*(?:,|$)') + range_regex = re.compile(r"(?Pr|)(?P(?:0?x[\da-z]+|[\d]+))[\-~](?P(?:0?x[\da-z]+|[\d]+))") + ascii_value_regex = re.compile(r"(?P^\[.+\]$)") + list_regex = re.compile(r"\s*(?:(?P(?:0?x[\da-z]+|[\d]+))-(?P(?:0?x[\da-z]+|[\d]+))|(?P[^,\s][^,]*?))\s*(?:,|$)") #load read_interval from transport settings, for #x per register read intervals @@ -396,12 +396,12 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP overrides : dict[str, dict] = None - override_keys = ['documented name', 'register'] + override_keys = ["documented name", "register"] overrided_keys = set() ''' list / set of keys that were used for overriding. to track unique entries''' #assuming path ends with .csv - override_path = path[:-4] + '.override.csv' + override_path = path[:-4] + ".override.csv" if os.path.exists(override_path): self._log.info("loading override file: " + override_path) @@ -409,44 +409,44 @@ def load__registry(self, path, registry_type : Registry_Type = Registry_Type.INP overrides = self.load_registry_overrides(override_path, override_keys) def determine_delimiter(first_row) -> str: - if first_row.count(';') > first_row.count(','): - return ';' + if first_row.count(";") > first_row.count(","): + return ";" else: - return ',' + return "," def process_row(row): # Initialize variables to hold numeric and character parts unit_multiplier : float = 1 - unit_symbol : str = '' + unit_symbol : str = "" read_interval : int = 0 ''' read interval in ms ''' #clean up doc name, for extra parsing - row['documented name'] = row['documented name'].strip().lower().replace(' ', '_') + row["documented name"] = row["documented name"].strip().lower().replace(" ", "_") #region read_interval - if 'read interval' in row: - row['read interval'] = row['read interval'].lower() #ensure is all lower case - match = read_interval_regex.search(row['read interval']) + if "read interval" in row: + row["read interval"] = row["read interval"].lower() #ensure is all lower case + match = read_interval_regex.search(row["read interval"]) if match: - unit = match.group('unit') - value = match.group('value') + unit = match.group("unit") + value = match.group("value") if value: value = float(value) - if unit == 'x': + if unit == "x": read_interval = int((transport_read_interval * 1000) * value) else: # seconds or ms read_interval = value - if unit != 'ms': + if unit != "ms": read_interval *= 1000 if read_interval == 0: read_interval = transport_read_interval * 1000 if "read_interval" in self.settings: try: - read_interval = int(self.settings['read_interval']) + read_interval = int(self.settings["read_interval"]) except ValueError: read_interval = transport_read_interval * 1000 @@ -474,12 +474,12 @@ def process_row(row): #region unit #if or is in the unit; ignore unit - if "or" in row['unit'].lower() or ":" in row['unit'].lower(): + if "or" in row["unit"].lower() or ":" in row["unit"].lower(): unit_multiplier = 1 - unit_symbol = row['unit'] + unit_symbol = row["unit"] else: # Use regular expressions to extract numeric and character parts - matches = re.findall(r'(\-?[0-9.]+)|(.*?)$', row['unit']) + matches = re.findall(r"(\-?[0-9.]+)|(.*?)$", row["unit"]) # Iterate over the matches and assign them to appropriate variables for match in matches: @@ -500,14 +500,14 @@ def process_row(row): #endregion unit - variable_name = row['variable name'] if row['variable name'] else row['documented name'] - variable_name = variable_name.strip().lower().replace(' ', '_').replace('__', '_') #clean name + variable_name = row["variable name"] if row["variable name"] else row["documented name"] + variable_name = variable_name.strip().lower().replace(" ", "_").replace("__", "_") #clean name if re.search(r"[^a-zA-Z0-9\_]", variable_name) : - self._log.warning("Invalid Name : " + str(variable_name) + " reg: " + str(row['register']) + " doc name: " + str(row['documented name']) + " path: " + str(path)) + self._log.warning("Invalid Name : " + str(variable_name) + " reg: " + str(row["register"]) + " doc name: " + str(row["documented name"]) + " path: " + str(path)) - if not variable_name and not row['documented name']: #skip empty entry / no name. todo add more invalidator checks. + if not variable_name and not row["documented name"]: #skip empty entry / no name. todo add more invalidator checks. return #region data type @@ -515,17 +515,17 @@ def process_row(row): data_type_len : int = -1 #optional row, only needed for non-default data types - if 'data type' in row and row['data type']: - matches = data_type_regex.search(row['data type']) + if "data type" in row and row["data type"]: + matches = data_type_regex.search(row["data type"]) if matches: - data_type_len = int(matches.group('length')) - data_type = Data_Type.fromString(matches.group('datatype')) + data_type_len = int(matches.group("length")) + data_type = Data_Type.fromString(matches.group("datatype")) else: - data_type = Data_Type.fromString(row['data type']) + data_type = Data_Type.fromString(row["data type"]) - if 'values' not in row: - row['values'] = "" + if "values" not in row: + row["values"] = "" self._log.warning("No Value Column : path: " + str(path)) #endregion data type @@ -539,12 +539,12 @@ def process_row(row): value_is_json : bool = False #test if value is json. - if "{" in row['values']: #to try and stop non-json values from parsing. the json parser is buggy for validation + if "{" in row["values"]: #to try and stop non-json values from parsing. the json parser is buggy for validation try: - codes_json = json.loads(row['values']) + codes_json = json.loads(row["values"]) value_is_json = True - name = row['documented name']+'_codes' + name = row["documented name"]+"_codes" if name not in self.codes: self.codes[name] = codes_json @@ -552,34 +552,34 @@ def process_row(row): value_is_json = False if not value_is_json: - if ',' in row['values']: - matches = list_regex.finditer(row['values']) + if "," in row["values"]: + matches = list_regex.finditer(row["values"]) for match in matches: groups = match.groupdict() - if groups['range_start'] and groups['range_end']: - start = strtoint(groups['range_start']) - end = strtoint(groups['range_end']) + if groups["range_start"] and groups["range_end"]: + start = strtoint(groups["range_start"]) + end = strtoint(groups["range_end"]) values.extend(range(start, end + 1)) else: - values.append(groups['element']) + values.append(groups["element"]) else: matched : bool = False - val_match = range_regex.search(row['values']) + val_match = range_regex.search(row["values"]) if val_match: - value_min = strtoint(val_match.group('start')) - value_max = strtoint(val_match.group('end')) + value_min = strtoint(val_match.group("start")) + value_max = strtoint(val_match.group("end")) matched = True if data_type == Data_Type.ASCII: #might need to apply too hex values as well? or min-max works for hex? #value_regex - val_match = ascii_value_regex.search(row['values']) + val_match = ascii_value_regex.search(row["values"]) if val_match: - value_regex = val_match.group('regex') + value_regex = val_match.group("regex") matched = True if not matched: #single value - values.append(row['values']) + values.append(row["values"]) #endregion values #region register @@ -589,18 +589,18 @@ def process_row(row): register : int = -1 register_bit : int = 0 register_byte : int = -1 - row['register'] = row['register'].lower() #ensure is all lower case - match = register_regex.search(row['register']) + row["register"] = row["register"].lower() #ensure is all lower case + match = register_regex.search(row["register"]) if match: - register = strtoint(match.group('register')) + register = strtoint(match.group("register")) - register_bit = match.group('bit') + register_bit = match.group("bit") if register_bit: register_bit = strtoint(register_bit) else: register_bit = 0 - register_byte = match.group('byte') + register_byte = match.group("byte") if register_byte: register_byte = strtoint(register_byte) else: @@ -608,13 +608,13 @@ def process_row(row): #print("register: " + str(register) + " bit : " + str(register_bit)) else: - range_match = range_regex.search(row['register']) + range_match = range_regex.search(row["register"]) if not range_match: - register = strtoint(row['register']) + register = strtoint(row["register"]) else: - reverse = range_match.group('reverse') - start = strtoint(range_match.group('start')) - end = strtoint(range_match.group('end')) + reverse = range_match.group("reverse") + start = strtoint(range_match.group("start")) + end = strtoint(range_match.group("end")) register = start if end > start: concatenate = True @@ -633,18 +633,18 @@ def process_row(row): #endregion register read_command = None - if "read command" in row and row['read command']: - if row['read command'][0] == 'x': - read_command = bytes.fromhex(row['read command'][1:]) + if "read command" in row and row["read command"]: + if row["read command"][0] == "x": + read_command = bytes.fromhex(row["read command"][1:]) else: - read_command = row['read command'].encode('utf-8') + read_command = row["read command"].encode("utf-8") writeMode : WriteMode = WriteMode.READ if "writable" in row: - writeMode = WriteMode.fromString(row['writable']) + writeMode = WriteMode.fromString(row["writable"]) if "write" in row: - writeMode = WriteMode.fromString(row['write']) + writeMode = WriteMode.fromString(row["write"]) for i in r: item = registry_map_entry( @@ -653,7 +653,7 @@ def process_row(row): register_bit=register_bit, register_byte= register_byte, variable_name= variable_name, - documented_name = row['documented name'], + documented_name = row["documented name"], unit= str(unit_symbol), unit_mod= unit_multiplier, data_type= data_type, @@ -673,14 +673,14 @@ def process_row(row): register = register + 1 - with open(path, newline='', encoding='latin-1') as csvfile: + with open(path, newline="", encoding="latin-1") as csvfile: #clean column names before passing to csv dict reader - delimeter = ';' - first_row = next(csvfile).lower().replace('_', ' ') - if first_row.count(';') < first_row.count(','): - delimeter = ',' + delimeter = ";" + first_row = next(csvfile).lower().replace("_", " ") + if first_row.count(";") < first_row.count(","): + delimeter = "," first_row = re.sub(r"\s+" + re.escape(delimeter) +"|" + re.escape(delimeter) +r"\s+", delimeter, first_row) #trim values @@ -719,8 +719,8 @@ def process_row(row): if index > 0: #if high/low, its a double if ( - item.documented_name.endswith('_l') - and registry_map[index-1].documented_name.replace('_h', '_l') == item.documented_name + item.documented_name.endswith("_l") + and registry_map[index-1].documented_name.replace("_h", "_l") == item.documented_name ): combined_item = registry_map[index-1] @@ -771,7 +771,7 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register if "batch_size" in self.settings: try: - max_batch_size = int(self.settings['batch_size']) + max_batch_size = int(self.settings["batch_size"]) except ValueError: pass @@ -805,33 +805,33 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register return ranges - def find_protocol_file(self, file : str, base_dir : str = '' ) -> str: + def find_protocol_file(self, file : str, base_dir : str = "" ) -> str: - path = base_dir + '/' + file + path = base_dir + "/" + file if os.path.exists(path): return path - suffix = file.split('_', 1)[0] + suffix = file.split("_", 1)[0] - path = base_dir + '/' + suffix +'/' + file + path = base_dir + "/" + suffix +"/" + file if os.path.exists(path): return path #find file by name, recurisvely. last resort - search_pattern = os.path.join(base_dir, '**', file) + search_pattern = os.path.join(base_dir, "**", file) matches = glob.glob(search_pattern, recursive=True) return matches[0] if matches else None - def load_registry_map(self, registry_type : Registry_Type, file : str = '', settings_dir : str = ''): + def load_registry_map(self, registry_type : Registry_Type, file : str = "", settings_dir : str = ""): if not settings_dir: settings_dir = self.settings_dir if not file: if registry_type == Registry_Type.ZERO: - file = self.protocol + '.registry_map.csv' + file = self.protocol + ".registry_map.csv" else: - file = self.protocol + '.'+registry_type.name.lower()+'_registry_map.csv' + file = self.protocol + "."+registry_type.name.lower()+"_registry_map.csv" path = self.find_protocol_file(file, settings_dir) @@ -885,8 +885,8 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma #handle custom sizes, less than 1 register end_bit = flag_size + start_bit - if entry.documented_name+'_codes' in self.codes: - code_key : str = entry.documented_name+'_codes' + if entry.documented_name+"_codes" in self.codes: + code_key : str = entry.documented_name+"_codes" flags : list[str] = [] flag_indexes : list[str] = [] for i in range(start_bit, end_bit): # Iterate over each bit position (0 to 15) @@ -901,12 +901,12 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma flags.append(self.codes[code_key][flag_index]) #check multibit flags - multibit_flags = [key for key in self.codes if '&' in key] + multibit_flags = [key for key in self.codes if "&" in key] if multibit_flags: #if multibit flags are found flag_indexes_set : set[str] = set(flag_indexes) for multibit_flag in multibit_flags: - bits = multibit_flag.split('&') # Split key into 'bits' + bits = multibit_flag.split("&") # Split key into 'bits' if all(bit in flag_indexes_set for bit in bits): # Check if all bits are present in the flag_indexes_set flags.append(self.codes[code_key][multibit_flag]) @@ -919,7 +919,7 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma flags.append("1") else: flags.append("0") - value = ''.join(flags) + value = "".join(flags) elif entry.data_type.value > 400: #signed-magnitude bit types ( sign bit is the last bit instead of front ) @@ -968,12 +968,12 @@ def process_register_bytes(self, registry : dict[int,bytes], entry : registry_ma #apply codes if (entry.data_type != Data_Type._16BIT_FLAGS and - entry.documented_name+'_codes' in self.codes): + entry.documented_name+"_codes" in self.codes): try: cleanval = str(int(value)) - if cleanval in self.codes[entry.documented_name+'_codes']: - value = self.codes[entry.documented_name+'_codes'][cleanval] + if cleanval in self.codes[entry.documented_name+"_codes"]: + value = self.codes[entry.documented_name+"_codes"][cleanval] except Exception: #do nothing; try is for intval value = value @@ -1037,7 +1037,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma val = registry[entry.register] - if entry.documented_name+'_codes' in self.codes: + if entry.documented_name+"_codes" in self.codes: flags : list[str] = [] offset : int = 0 @@ -1047,8 +1047,8 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma # Check if the i-th bit is set if (val >> i) & 1: flag_index = "b"+str(i+offset) - if flag_index in self.codes[entry.documented_name+'_codes']: - flags.append(self.codes[entry.documented_name+'_codes'][flag_index]) + if flag_index in self.codes[entry.documented_name+"_codes"]: + flags.append(self.codes[entry.documented_name+"_codes"][flag_index]) value = ",".join(flags) @@ -1063,7 +1063,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma else: flags.append("0") - value = ''.join(flags) + value = "".join(flags) elif entry.data_type.value > 200 or entry.data_type == Data_Type.BYTE: #bit types bit_size = Data_Type.getSize(entry.data_type) @@ -1091,12 +1091,12 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma # value = round(value, self.max_precision) if (entry.data_type != Data_Type._16BIT_FLAGS and - entry.documented_name+'_codes' in self.codes): + entry.documented_name+"_codes" in self.codes): try: cleanval = str(int(value)) - if cleanval in self.codes[entry.documented_name+'_codes']: - value = self.codes[entry.documented_name+'_codes'][cleanval] + if cleanval in self.codes[entry.documented_name+"_codes"]: + value = self.codes[entry.documented_name+"_codes"][cleanval] except Exception: #do nothing; try is for intval value = value @@ -1112,7 +1112,7 @@ def process_registery(self, registry : Union[dict[int, int], dict[int, bytes]] , if entry.register not in registry: continue - value = '' + value = "" if isinstance(registry[entry.register], bytes): value = self.process_register_bytes(registry, entry) @@ -1148,14 +1148,14 @@ def process_registery(self, registry : Union[dict[int, int], dict[int, bytes]] , def validate_registry_entry(self, entry : registry_map_entry, val) -> int: #if code, validate first. - if entry.documented_name+'_codes' in self.codes: - if val in self.codes[entry.documented_name+'_codes']: + if entry.documented_name+"_codes" in self.codes: + if val in self.codes[entry.documented_name+"_codes"]: return 1 else: return 0 if entry.data_type == Data_Type.ASCII: - if val and not re.match(r'[^a-zA-Z0-9\_\-]', val): #validate ascii + if val and not re.match(r"[^a-zA-Z0-9\_\-]", val): #validate ascii if entry.value_regex: #regex validation if re.match(entry.value_regex, val): if entry.concatenate: @@ -1179,7 +1179,7 @@ def evaluate_expressions(self, expression, variables : dict[str,str]): # Function to evaluate mathematical expressions def evaluate_variables(expression): # Define a regular expression pattern to match variables - var_pattern = re.compile(r'\[([^\[\]]+)\]') + var_pattern = re.compile(r"\[([^\[\]]+)\]") # Replace variables in the expression with their values def replace_vars(match): @@ -1194,7 +1194,7 @@ def replace_vars(match): def evaluate_ranges(expression): # Define a regular expression pattern to match ranges - range_pattern = re.compile(r'\[.*?((?P\d+)\s?\~\s?(?P\d+)).*?\]') + range_pattern = re.compile(r"\[.*?((?P\d+)\s?\~\s?(?P\d+)).*?\]") # Find all ranges in the expression ranges = range_pattern.findall(expression) @@ -1222,19 +1222,19 @@ def evaluate_ranges(expression): def evaluate_expression(expression): # Define a regular expression pattern to match "maths" - var_pattern = re.compile(r'\[(?P.*?)\]') + var_pattern = re.compile(r"\[(?P.*?)\]") # Replace variables in the expression with their values def replace_vars(match): try: maths = match.group("maths") - maths = re.sub(r'\s', '', maths) #remove spaces, because ast.parse doesnt like them + maths = re.sub(r"\s", "", maths) #remove spaces, because ast.parse doesnt like them # Parse the expression safely - tree = ast.parse(maths, mode='eval') + tree = ast.parse(maths, mode="eval") # Evaluate the expression - end_value = ast.literal_eval(compile(tree, filename='', mode='eval')) + end_value = ast.literal_eval(compile(tree, filename="", mode="eval")) return str(end_value) except Exception: diff --git a/classes/transports/canbus.py b/classes/transports/canbus.py index 9ea21a2..ca724d6 100644 --- a/classes/transports/canbus.py +++ b/classes/transports/canbus.py @@ -20,10 +20,10 @@ class canbus(transport_base): ''' canbus is a more passive protocol; todo to include active commands to trigger canbus responses ''' - interface : str = 'socketcan' + interface : str = "socketcan" ''' bustype / interface for canbus device ''' - port : str = '' + port : str = "" ''' 'can0' ''' baudrate : int = 500000 @@ -55,11 +55,11 @@ class canbus(transport_base): linux : bool = True - def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None): + def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_settings" = None): super().__init__(settings, protocolSettings=protocolSettings) #check if running on windows or linux - self.linux = platform.system() != 'Windows' + self.linux = platform.system() != "Windows" self.port = settings.get(["port", "channel"], "") @@ -119,12 +119,12 @@ def is_socketcan_up(self) -> bool: return True try: - with open(f'/sys/class/net/{self.port}/operstate', 'r') as f: + with open(f"/sys/class/net/{self.port}/operstate", "r") as f: state = f.read().strip() except FileNotFoundError: return False else: - return state == 'up' + return state == "up" def start_loop(self): self.read_bus(self.bus) @@ -184,7 +184,7 @@ def init_after_connect(self): def read_serial_number(self) -> str: ''' not so simple in canbus''' - return '' + return "" serial_number = str(self.read_variable("Serial Number", Registry_Type.HOLDING)) print("read SN: " +serial_number) if serial_number: @@ -192,22 +192,22 @@ def read_serial_number(self) -> str: sn2 = "" sn3 = "" - fields = ['Serial No 1', 'Serial No 2', 'Serial No 3', 'Serial No 4', 'Serial No 5'] + fields = ["Serial No 1", "Serial No 2", "Serial No 3", "Serial No 4", "Serial No 5"] for field in fields: self._log.info("Reading " + field) registry_entry = self.protocolSettings.get_holding_registry_entry(field) if registry_entry is not None: self._log.info("Reading " + field + "("+str(registry_entry.register)+")") data = self.read_modbus_registers(registry_entry.register, registry_type=Registry_Type.HOLDING) - if not hasattr(data, 'registers') or data.registers is None: + if not hasattr(data, "registers") or data.registers is None: self._log.critical("Failed to get serial number register ("+field+") ; exiting") exit() serial_number = serial_number + str(data.registers[0]) - data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder='big') - sn2 = sn2 + str(data_bytes.decode('utf-8')) - sn3 = str(data_bytes.decode('utf-8')) + sn3 + data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder="big") + sn2 = sn2 + str(data_bytes.decode("utf-8")) + sn3 = str(data_bytes.decode("utf-8")) + sn3 time.sleep(self.modbus_delay*2) #sleep inbetween requests so modbus can rest @@ -259,7 +259,7 @@ def read_variable(self, variable_name : str, registry_type : Registry_Type, entr ''' read's variable from cache''' ##clean for convinecne if variable_name: - variable_name = variable_name.strip().lower().replace(' ', '_') + variable_name = variable_name.strip().lower().replace(" ", "_") registry_map = self.protocolSettings.get_registry_map(registry_type) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index f4a3639..bc4941d 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -29,7 +29,7 @@ class modbus_base(transport_base): #this is specifically static - clients : dict[str, 'BaseModbusClient'] = {} + clients : dict[str, "BaseModbusClient"] = {} ''' str is identifier, dict of clients when multiple transports use the same ports ''' #non-static here for reference, type hinting, python bs ect... @@ -49,27 +49,27 @@ class modbus_base(transport_base): send_holding_register : bool = True send_input_register : bool = True - def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None): + def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_settings" = None): super().__init__(settings) - self.analyze_protocol_enabled = settings.getboolean('analyze_protocol', fallback=self.analyze_protocol_enabled) - self.analyze_protocol_save_load = settings.getboolean('analyze_protocol_save_load', fallback=self.analyze_protocol_save_load) + self.analyze_protocol_enabled = settings.getboolean("analyze_protocol", fallback=self.analyze_protocol_enabled) + self.analyze_protocol_save_load = settings.getboolean("analyze_protocol_save_load", fallback=self.analyze_protocol_save_load) #get defaults from protocol settings - if 'send_input_register' in self.protocolSettings.settings: - self.send_input_register = strtobool(self.protocolSettings.settings['send_input_register']) + if "send_input_register" in self.protocolSettings.settings: + self.send_input_register = strtobool(self.protocolSettings.settings["send_input_register"]) - if 'send_holding_register' in self.protocolSettings.settings: - self.send_holding_register = strtobool(self.protocolSettings.settings['send_holding_register']) + if "send_holding_register" in self.protocolSettings.settings: + self.send_holding_register = strtobool(self.protocolSettings.settings["send_holding_register"]) - if 'batch_delay' in self.protocolSettings.settings: - self.modbus_delay = float(self.protocolSettings.settings['batch_delay']) + if "batch_delay" in self.protocolSettings.settings: + self.modbus_delay = float(self.protocolSettings.settings["batch_delay"]) #allow enable/disable of which registers to send - self.send_holding_register = settings.getboolean('send_holding_register', fallback=self.send_holding_register) - self.send_input_register = settings.getboolean('send_input_register', fallback=self.send_input_register) - self.modbus_delay = settings.getfloat(['batch_delay', 'modbus_delay'], fallback=self.modbus_delay) + self.send_holding_register = settings.getboolean("send_holding_register", fallback=self.send_holding_register) + self.send_input_register = settings.getboolean("send_input_register", fallback=self.send_input_register) + self.modbus_delay = settings.getfloat(["batch_delay", "modbus_delay"], fallback=self.modbus_delay) self.modbus_delay_setting = self.modbus_delay @@ -101,22 +101,22 @@ def read_serial_number(self) -> str: sn2 = "" sn3 = "" - fields = ['Serial No 1', 'Serial No 2', 'Serial No 3', 'Serial No 4', 'Serial No 5'] + fields = ["Serial No 1", "Serial No 2", "Serial No 3", "Serial No 4", "Serial No 5"] for field in fields: self._log.info("Reading " + field) registry_entry = self.protocolSettings.get_holding_registry_entry(field) if registry_entry is not None: self._log.info("Reading " + field + "("+str(registry_entry.register)+")") data = self.read_modbus_registers(registry_entry.register, registry_type=Registry_Type.HOLDING) - if not hasattr(data, 'registers') or data.registers is None: + if not hasattr(data, "registers") or data.registers is None: self._log.critical("Failed to get serial number register ("+field+") ; exiting") exit() serial_number = serial_number + str(data.registers[0]) - data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder='big') - sn2 = sn2 + str(data_bytes.decode('utf-8')) - sn3 = str(data_bytes.decode('utf-8')) + sn3 + data_bytes = data.registers[0].to_bytes((data.registers[0].bit_length() + 7) // 8, byteorder="big") + sn2 = sn2 + str(data_bytes.decode("utf-8")) + sn3 = str(data_bytes.decode("utf-8")) + sn3 time.sleep(self.modbus_delay*2) #sleep inbetween requests so modbus can rest @@ -178,7 +178,7 @@ def read_data(self) -> dict[str, str]: return info - def validate_protocol(self, protocolSettings : 'protocol_settings') -> float: + def validate_protocol(self, protocolSettings : "protocol_settings") -> float: score_percent = self.validate_registry(Registry_Type.HOLDING) return score_percent @@ -204,13 +204,13 @@ def validate_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) self._log.info("validation score: " + str(score) + " of " + str(maxScore) + " : " + str(round(percent)) + "%") return percent - def analyze_protocol(self, settings_dir : str = 'protocols'): + def analyze_protocol(self, settings_dir : str = "protocols"): print("=== PROTOCOL ANALYZER ===") protocol_names : list[str] = [] protocols : dict[str,protocol_settings] = {} for file in glob.glob(settings_dir + "/*.json"): - file = file.lower().replace(settings_dir, '').replace('/', '').replace('\\', '').replace('\\', '').replace('.json', '') + file = file.lower().replace(settings_dir, "").replace("/", "").replace("\\", "").replace("\\", "").replace(".json", "") print(file) protocol_names.append(file) @@ -283,7 +283,7 @@ def analyze_protocol(self, settings_dir : str = 'protocols'): def evaluate_score(entry : registry_map_entry, val): score = 0 if entry.data_type == Data_Type.ASCII: - if val and not re.match('[^a-zA-Z0-9_-]', val): #validate ascii + if val and not re.match("[^a-zA-Z0-9_-]", val): #validate ascii mod = 1 if entry.concatenate: mod = len(entry.concatenate_registers) @@ -419,7 +419,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): ##clean for convinecne if variable_name: - variable_name = variable_name.strip().lower().replace(' ', '_') + variable_name = variable_name.strip().lower().replace(" ", "_") registry_map = self.protocolSettings.get_registry_map(registry_type) @@ -485,7 +485,7 @@ def read_modbus_registers(self, ranges : list[tuple] = None, start : int = 0, en if isinstance(register, bytes) or register.isError() or isError: #sometimes weird errors are handled incorrectly and response is a ascii error string if isinstance(register, bytes): - self._log.error(register.decode('utf-8')) + self._log.error(register.decode("utf-8")) else: self._log.error(register.__str__) self.modbus_delay += self.modbus_delay_increament #increase delay, error is likely due to modbus being busy diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index bf8fd1a..d4f9147 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -21,7 +21,7 @@ class modbus_rtu(modbus_base): baudrate : int = 9600 client : ModbusSerialClient - pymodbus_slave_arg = 'unit' + pymodbus_slave_arg = "unit" def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): super().__init__(settings, protocolSettings=protocolSettings) @@ -45,8 +45,8 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings self.addresses = [address] # pymodbus compatability; unit was renamed to address - if 'slave' in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: - self.pymodbus_slave_arg = 'slave' + if "slave" in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: + self.pymodbus_slave_arg = "slave" # Get the signature of the __init__ method @@ -58,16 +58,16 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings self.client = modbus_base.clients[client_str] return - if 'method' in init_signature.parameters: - self.client = ModbusSerialClient(method='rtu', port=self.port, + if "method" in init_signature.parameters: + self.client = ModbusSerialClient(method="rtu", port=self.port, baudrate=int(self.baudrate), - stopbits=1, parity='N', bytesize=8, timeout=2 + stopbits=1, parity="N", bytesize=8, timeout=2 ) else: self.client = ModbusSerialClient( port=self.port, baudrate=int(self.baudrate), - stopbits=1, parity='N', bytesize=8, timeout=2 + stopbits=1, parity="N", bytesize=8, timeout=2 ) #add to clients @@ -75,12 +75,12 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): - if 'unit' not in kwargs: - kwargs = {'unit': int(self.addresses[0]), **kwargs} + if "unit" not in kwargs: + kwargs = {"unit": int(self.addresses[0]), **kwargs} #compatability - if self.pymodbus_slave_arg != 'unit': - kwargs['slave'] = kwargs.pop('unit') + if self.pymodbus_slave_arg != "unit": + kwargs["slave"] = kwargs.pop("unit") if registry_type == Registry_Type.INPUT: return self.client.read_input_registers(address=start, count=count, **kwargs) @@ -91,12 +91,12 @@ def write_register(self, register : int, value : int, **kwargs): if not self.write_enabled: return - if 'unit' not in kwargs: - kwargs = {'unit': self.addresses[0], **kwargs} + if "unit" not in kwargs: + kwargs = {"unit": self.addresses[0], **kwargs} #compatability - if self.pymodbus_slave_arg != 'unit': - kwargs['slave'] = kwargs.pop('unit') + if self.pymodbus_slave_arg != "unit": + kwargs["slave"] = kwargs.pop("unit") self.client.write_register(register, value, **kwargs) #function code 0x06 writes to holding register diff --git a/classes/transports/modbus_tcp.py b/classes/transports/modbus_tcp.py index 984f146..3768f44 100644 --- a/classes/transports/modbus_tcp.py +++ b/classes/transports/modbus_tcp.py @@ -17,7 +17,7 @@ class modbus_tcp(modbus_base): port : str = 502 host : str = "" client : ModbusTcpClient - pymodbus_slave_arg = 'unit' + pymodbus_slave_arg = "unit" def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): self.host = settings.get("host", "") @@ -27,8 +27,8 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings self.port = settings.getint("port", self.port) # pymodbus compatability; unit was renamed to address - if 'slave' in inspect.signature(ModbusTcpClient.read_holding_registers).parameters: - self.pymodbus_slave_arg = 'slave' + if "slave" in inspect.signature(ModbusTcpClient.read_holding_registers).parameters: + self.pymodbus_slave_arg = "slave" client_str = self.host+"("+str(self.port)+")" #check if client is already initialied @@ -45,12 +45,12 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): - if 'unit' not in kwargs: - kwargs = {'unit': 1, **kwargs} + if "unit" not in kwargs: + kwargs = {"unit": 1, **kwargs} #compatability - if self.pymodbus_slave_arg != 'unit': - kwargs['slave'] = kwargs.pop('unit') + if self.pymodbus_slave_arg != "unit": + kwargs["slave"] = kwargs.pop("unit") if registry_type == Registry_Type.INPUT: return self.client.read_input_registers(start, count, **kwargs ) diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index d6c33aa..4fecef8 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -43,31 +43,31 @@ class mqtt(transport_base): connected : bool = False def __init__(self, settings : SectionProxy): - self.host = settings.get('host', fallback="") + self.host = settings.get("host", fallback="") if not self.host: raise ValueError("Host is not set") - self.port = settings.getint('port', fallback=self.port) - self.base_topic = settings.get('base_topic', fallback=self.base_topic).rstrip('/') - self.error_topic = settings.get('error_topic', fallback=self.error_topic).rstrip('/') - self.discovery_topic = settings.get('discovery_topic', fallback=self.discovery_topic) - self.discovery_enabled = strtobool(settings.get('discovery_enabled', self.discovery_enabled)) - self.json = strtobool(settings.get('json', self.json)) - self.reconnect_delay = settings.getint('reconnect_delay', fallback=7) + self.port = settings.getint("port", fallback=self.port) + self.base_topic = settings.get("base_topic", fallback=self.base_topic).rstrip("/") + self.error_topic = settings.get("error_topic", fallback=self.error_topic).rstrip("/") + self.discovery_topic = settings.get("discovery_topic", fallback=self.discovery_topic) + self.discovery_enabled = strtobool(settings.get("discovery_enabled", self.discovery_enabled)) + self.json = strtobool(settings.get("json", self.json)) + self.reconnect_delay = settings.getint("reconnect_delay", fallback=7) #self.max_precision = settings.getint('max_precision', fallback=self.max_precision) if not isinstance( self.reconnect_delay , int) or self.reconnect_delay < 1: #minumum 1 second self.reconnect_delay = 1 - self.reconnect_attempts = settings.getint('reconnect_attempts', fallback=21) + self.reconnect_attempts = settings.getint("reconnect_attempts", fallback=21) if not isinstance( self.reconnect_attempts , int) or self.reconnect_attempts < 0: #minimum 0 self.reconnect_attempts = 0 self.holding_register_prefix = settings.get("holding_register_prefix", fallback="") self.input_register_prefix = settings.get("input_register_prefix", fallback="") - username = settings.get('user', fallback="") - password = settings.get('pass', fallback="") + username = settings.get("user", fallback="") + password = settings.get("pass", fallback="") if not username: raise ValueError("User is not set") @@ -108,7 +108,7 @@ def connect(self): def exit_handler(self): '''on exit handler''' self._log.warning("MQTT Exiting...") - self.client.publish( self.base_topic + '/' + self.device_identifier + "/availability","offline") + self.client.publish( self.base_topic + "/" + self.device_identifier + "/availability","offline") return def mqtt_reconnect(self): @@ -161,29 +161,29 @@ def write_data(self, data : dict[str, str], from_transport : transport_base): self._log.info(f"write data from [{from_transport.transport_name}] to mqtt transport") self._log.info(data) #have to send this every loop, because mqtt doesnt disconnect when HA restarts. HA bug. - info = self.client.publish(self.base_topic + '/' + from_transport.device_identifier + "/availability","online", qos=0,retain=True) + info = self.client.publish(self.base_topic + "/" + from_transport.device_identifier + "/availability","online", qos=0,retain=True) if info.rc == MQTT_ERR_NO_CONN: self.connected = False if(self.json): # Serializing json json_object = json.dumps(data, indent=4) - self.client.publish(self.base_topic+'/'+from_transport.device_identifier, json_object, 0, properties=self.mqtt_properties) + self.client.publish(self.base_topic+"/"+from_transport.device_identifier, json_object, 0, properties=self.mqtt_properties) else: for entry, val in data.items(): if isinstance(val, float) and self.max_precision >= 0: #apply max_precision on mqtt transport val = round(val, self.max_precision) - self.client.publish(str(self.base_topic+'/'+from_transport.device_identifier+'/'+entry).lower(), str(val)) + self.client.publish(str(self.base_topic+"/"+from_transport.device_identifier+"/"+entry).lower(), str(val)) def client_on_message(self, client, userdata, msg): """ The callback for when a PUBLISH message is received from the server. """ - self._log.info(msg.topic+" "+str(msg.payload.decode('utf-8'))) + self._log.info(msg.topic+" "+str(msg.payload.decode("utf-8"))) #self.protocolSettings.validate_registry_entry if msg.topic in self.__write_topics: entry = self.__write_topics[msg.topic] - self.on_message(self, entry, msg.payload.decode('utf-8')) + self.on_message(self, entry, msg.payload.decode("utf-8")) #self.write_variable(entry, value=str(msg.payload.decode('utf-8'))) def init_bridge(self, from_transport : transport_base): @@ -194,7 +194,7 @@ def init_bridge(self, from_transport : transport_base): for entry in from_transport.protocolSettings.get_registry_map(Registry_Type.HOLDING): if entry.write_mode == WriteMode.WRITE or entry.write_mode == WriteMode.WRITEONLY: #__write_topics - topic : str = self.base_topic + '/'+ from_transport.device_identifier + "/write/" + entry.variable_name.lower().replace(' ', '_') + topic : str = self.base_topic + "/"+ from_transport.device_identifier + "/write/" + entry.variable_name.lower().replace(" ", "_") self.__write_topics[topic] = entry self.client.subscribe(topic) @@ -205,13 +205,13 @@ def mqtt_discovery(self, from_transport : transport_base): self._log.info("Publishing HA Discovery Topics...") disc_payload = {} - disc_payload['availability_topic'] = self.base_topic + '/' + from_transport.device_identifier + "/availability" + disc_payload["availability_topic"] = self.base_topic + "/" + from_transport.device_identifier + "/availability" device = {} - device['manufacturer'] = from_transport.device_manufacturer - device['model'] = from_transport.device_model - device['identifiers'] = "hotnoob_" + from_transport.device_model + "_" + from_transport.device_serial_number - device['name'] = from_transport.device_name + device["manufacturer"] = from_transport.device_manufacturer + device["model"] = from_transport.device_model + device["identifiers"] = "hotnoob_" + from_transport.device_model + "_" + from_transport.device_serial_number + device["name"] = from_transport.device_name registry_map : list[registry_map_entry] = [] for entries in from_transport.protocolSettings.registry_map.values(): @@ -229,7 +229,7 @@ def mqtt_discovery(self, from_transport : transport_base): continue - clean_name = item.variable_name.lower().replace(' ', '_').strip() + clean_name = item.variable_name.lower().replace(" ", "_").strip() if not clean_name: #if name is empty, skip continue @@ -241,36 +241,36 @@ def mqtt_discovery(self, from_transport : transport_base): clean_name = self.__holding_register_prefix + clean_name - print(('#Publishing Topic '+str(count)+' of ' + str(length) + ' "'+str(clean_name)+'"').ljust(100)+"#", end='\r', flush=True) + print(("#Publishing Topic "+str(count)+" of " + str(length) + ' "'+str(clean_name)+'"').ljust(100)+"#", end="\r", flush=True) #device['sw_version'] = bms_version disc_payload = {} - disc_payload['availability_topic'] = self.base_topic + '/' + from_transport.device_identifier + "/availability" - disc_payload['device'] = device - disc_payload['name'] = clean_name - disc_payload['unique_id'] = "hotnoob_" + from_transport.device_serial_number + "_"+clean_name + disc_payload["availability_topic"] = self.base_topic + "/" + from_transport.device_identifier + "/availability" + disc_payload["device"] = device + disc_payload["name"] = clean_name + disc_payload["unique_id"] = "hotnoob_" + from_transport.device_serial_number + "_"+clean_name writePrefix = "" if from_transport.write_enabled and ( item.write_mode == WriteMode.WRITE or item.write_mode == WriteMode.WRITEONLY ): writePrefix = "" #home assistant doesnt like write prefix - disc_payload['state_topic'] = self.base_topic + '/' +from_transport.device_identifier + writePrefix+ "/"+clean_name + disc_payload["state_topic"] = self.base_topic + "/" +from_transport.device_identifier + writePrefix+ "/"+clean_name if item.unit: - disc_payload['unit_of_measurement'] = item.unit + disc_payload["unit_of_measurement"] = item.unit - discovery_topic = self.discovery_topic+"/sensor/HN-" + from_transport.device_serial_number + writePrefix + "/" + disc_payload['name'].replace(' ', '_') + "/config" + discovery_topic = self.discovery_topic+"/sensor/HN-" + from_transport.device_serial_number + writePrefix + "/" + disc_payload["name"].replace(" ", "_") + "/config" self.client.publish(discovery_topic, json.dumps(disc_payload),qos=1, retain=True) #send WO message to indicate topic is write only if item.write_mode == WriteMode.WRITEONLY: - self.client.publish(disc_payload['state_topic'], "WRITEONLY") + self.client.publish(disc_payload["state_topic"], "WRITEONLY") time.sleep(0.07) #slow down for better reliability - self.client.publish(disc_payload['availability_topic'],"online",qos=0, retain=True) + self.client.publish(disc_payload["availability_topic"],"online",qos=0, retain=True) print() self._log.info("Published HA "+str(count)+"x Discovery Topics") diff --git a/classes/transports/pace.py b/classes/transports/pace.py index 7dae56b..927a92c 100644 --- a/classes/transports/pace.py +++ b/classes/transports/pace.py @@ -222,7 +222,7 @@ def checkFrame(self): """ try: self.populateHeader() - frame_size = self._header['len'] + frame_size = self._header["len"] data = self._buffer[:frame_size - 2] crc = self._buffer[frame_size - 2:frame_size] crc_val = (byte2int(crc[0]) << 8) + byte2int(crc[1]) @@ -238,7 +238,7 @@ def checkFrame(self): class CustomModbusSerialClient(ModbusSerialClient): - def __init__(self, method='ascii', **kwargs): + def __init__(self, method="ascii", **kwargs): """ Initialize a serial client instance The methods to connect are:: @@ -262,12 +262,12 @@ def __init__(self, method='ascii', **kwargs): BaseModbusClient.__init__(self, CustomFramer(ClientDecoder(), self), **kwargs) - self.port = kwargs.get('port', 0) - self.stopbits = kwargs.get('stopbits', Defaults.Stopbits) - self.bytesize = kwargs.get('bytesize', Defaults.Bytesize) - self.parity = kwargs.get('parity', Defaults.Parity) - self.baudrate = kwargs.get('baudrate', Defaults.Baudrate) - self.timeout = kwargs.get('timeout', Defaults.Timeout) + self.port = kwargs.get("port", 0) + self.stopbits = kwargs.get("stopbits", Defaults.Stopbits) + self.bytesize = kwargs.get("bytesize", Defaults.Bytesize) + self.parity = kwargs.get("parity", Defaults.Parity) + self.baudrate = kwargs.get("baudrate", Defaults.Baudrate) + self.timeout = kwargs.get("timeout", Defaults.Timeout) self._strict = kwargs.get("strict", True) self.last_frame_end = None if self.method == "rtu": @@ -302,9 +302,9 @@ def __init__(self, settings : dict[str,str]): if "baudrate" in settings: self.baudrate = settings["baudrate"] - self.client = CustomModbusSerialClient(method='binary', port=self.port, + self.client = CustomModbusSerialClient(method="binary", port=self.port, baudrate=int(self.baudrate), - stopbits=1, parity='N', bytesize=8, timeout=2 + stopbits=1, parity="N", bytesize=8, timeout=2 ) def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): diff --git a/classes/transports/serial_frame_client.py b/classes/transports/serial_frame_client.py index eef81a9..5c65ec9 100644 --- a/classes/transports/serial_frame_client.py +++ b/classes/transports/serial_frame_client.py @@ -17,7 +17,7 @@ class serial_frame_client(): max_frame_size : int = 256 - port : str = '/dev/ttyUSB0' + port : str = "/dev/ttyUSB0" baud : int = 9600 timeout : float = 5 diff --git a/classes/transports/serial_pylon.py b/classes/transports/serial_pylon.py index 69e2f51..33cd011 100644 --- a/classes/transports/serial_pylon.py +++ b/classes/transports/serial_pylon.py @@ -45,8 +45,8 @@ class serial_pylon(transport_base): client : serial_frame_client #this format is pretty common; i need a name for it. - SOI : bytes = b'\x7e' # aka b"~" - VER : bytes = b'\x00' + SOI : bytes = b"\x7e" # aka b"~" + VER : bytes = b"\x00" ''' version has to be fetched first ''' ADR : bytes CID1 : bytes @@ -55,9 +55,9 @@ class serial_pylon(transport_base): ''' 2 bytes - include LENID & LCHKSUM''' INFO : bytes CHKSUM : bytes - EOI : bytes = b'\x0d' # aka b"\r" + EOI : bytes = b"\x0d" # aka b"\r" - def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_settings' = None): + def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_settings" = None): super().__init__(settings, protocolSettings=protocolSettings) '''address is required to be specified ''' self.port = settings.get("port", "") @@ -72,7 +72,7 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti address : int = settings.getint("address", 0) self.addresses = [address] - self.ADR = struct.pack('B', address) + self.ADR = struct.pack("B", address) #todo, multi address support later self.client = serial_frame_client(self.port, @@ -87,16 +87,16 @@ def __init__(self, settings : 'SectionProxy', protocolSettings : 'protocol_setti def connect(self): self.client.connect() #3.1 Get protocol version - if self.VER == b'\x00': + if self.VER == b"\x00": #get VER for communicating #SOI VER ADR 46H 4FH LENGT INFO CHKSUM EOI - version = self.read_variable('version', attribute='ver') + version = self.read_variable("version", attribute="ver") if version: self.connected = True self._log.info("pylon protocol version is "+str(version)) self.VER = version - name = self.read_variable('battery_name') + name = self.read_variable("battery_name") self._log.info(name) pass @@ -113,7 +113,7 @@ def read_data(self): self.send_command(command) frame = self.client.read() if frame: #decode info to ascii: bytes.fromhex(name.decode("utf-8")).decode("ascii") - raw = getattr(self.decode_frame(frame), 'info') + raw = getattr(self.decode_frame(frame), "info") if raw: raw = bytes.fromhex(raw.decode("utf8")) #because protocol is in "ascii" data[entry.register] = raw @@ -125,10 +125,10 @@ def read_data(self): return info - def read_variable(self, variable_name : str, entry : 'registry_map_entry' = None, attribute : str = 'info'): + def read_variable(self, variable_name : str, entry : "registry_map_entry" = None, attribute : str = "info"): ##clean for convinecne if variable_name: - variable_name = variable_name.strip().lower().replace(' ', '_') + variable_name = variable_name.strip().lower().replace(" ", "_") registry_map = self.protocolSettings.get_registry_map() @@ -146,7 +146,7 @@ def read_variable(self, variable_name : str, entry : 'registry_map_entry' = None frame = self.client.read() if frame: #decode info to ascii: bytes.fromhex(name.decode("utf-8")).decode("ascii") raw = getattr(self.decode_frame(frame), attribute) - if raw and attribute == 'info': + if raw and attribute == "info": raw = bytes.fromhex(raw.decode("utf8")) #because protocol is in "ascii" raw = self.protocolSettings.process_registery({entry.register : raw}, map=registry_map) return raw @@ -173,7 +173,7 @@ def decode_frame(self, raw_frame: bytes) -> bytes: frame_data = raw_frame[0:-4] frame_checksum = raw_frame[-4:] - calc_checksum = struct.pack('>H', self.calculate_checksum(raw_frame[0:-4])).hex().upper().encode() + calc_checksum = struct.pack(">H", self.calculate_checksum(raw_frame[0:-4])).hex().upper().encode() if calc_checksum != frame_checksum: self._log.warning(f"Serial Pylon checksum error, got {calc_checksum}, expected {frame_checksum}") @@ -195,7 +195,7 @@ def decode_frame(self, raw_frame: bytes) -> bytes: return data - def build_frame(self, command : int, info: bytes = b''): + def build_frame(self, command : int, info: bytes = b""): ''' builds frame without soi and eoi; that is left for frame client''' info_length = 0 @@ -209,19 +209,19 @@ def build_frame(self, command : int, info: bytes = b''): info_length = (lenid_invert_plus_one << 12) + lenid - self.VER = b'\x20' + self.VER = b"\x20" #protocol is in ASCII hex. :facepalm: frame : str = self.VER.hex().upper() frame = frame + self.ADR.hex().upper() - frame = frame + struct.pack('>H', command).hex().upper() - frame = frame + struct.pack('>H', info_length).hex().upper() + frame = frame + struct.pack(">H", command).hex().upper() + frame = frame + struct.pack(">H", info_length).hex().upper() frame = frame + info.hex().upper() frame = frame.encode() frame_chksum = self.calculate_checksum(frame) - frame = frame + struct.pack('>H', frame_chksum).hex().upper().encode() + frame = frame + struct.pack(">H", frame_chksum).hex().upper().encode() #test frame #self.decode_frame(frame) @@ -229,7 +229,7 @@ def build_frame(self, command : int, info: bytes = b''): return frame - def send_command(self, cmd, info: bytes = b''): + def send_command(self, cmd, info: bytes = b""): data = self.build_frame(cmd, info) self.client.write(data) diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index cdff05e..fde3e47 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -13,16 +13,16 @@ from .transport_base import transport_base class transport_base: - type : str = '' - protocolSettings : 'protocol_settings' - protocol_version : str = '' - transport_name : str = '' - device_name : str = '' - device_serial_number : str = '' - device_manufacturer : str = 'hotnoob' - device_model : str = 'hotnoob' - device_identifier : str = 'hotnoob' - bridge : str = '' + type : str = "" + protocolSettings : "protocol_settings" + protocol_version : str = "" + transport_name : str = "" + device_name : str = "" + device_serial_number : str = "" + device_manufacturer : str = "hotnoob" + device_model : str = "hotnoob" + device_identifier : str = "hotnoob" + bridge : str = "" write_enabled : bool = False max_precision : int = 2 @@ -31,18 +31,18 @@ class transport_base: connected : bool = False - on_message : Callable[['transport_base', registry_map_entry, str], None] = None + on_message : Callable[["transport_base", registry_map_entry, str], None] = None ''' callback, on message recieved ''' _log : logging.Logger = None - def __init__(self, settings : 'SectionProxy') -> None: + def __init__(self, settings : "SectionProxy") -> None: self.transport_name = settings.name #section name #apply log level to logger - self._log_level = getattr(logging, settings.get('log_level', fallback='INFO'), logging.INFO) - short_name : str = __name__[__name__.rfind('.'): ] if '.' in __name__ else None + self._log_level = getattr(logging, settings.get("log_level", fallback="INFO"), logging.INFO) + short_name : str = __name__[__name__.rfind("."): ] if "." in __name__ else None self._log : logging.Logger = logging.getLogger(short_name + f"[{self.transport_name}]") self._log.setLevel(self._log_level) @@ -52,7 +52,7 @@ def __init__(self, settings : 'SectionProxy') -> None: if settings: self.device_serial_number = settings.get(["device_serial_number", "serial_number"], self.device_serial_number) self.device_manufacturer = settings.get(["device_manufacturer", "manufacturer"], self.device_manufacturer) - self.device_name = settings.get(['device_name', 'name'], fallback=self.device_manufacturer+"_"+self.device_serial_number) + self.device_name = settings.get(["device_name", "name"], fallback=self.device_manufacturer+"_"+self.device_serial_number) self.bridge = settings.get("bridge", self.bridge) self.read_interval = settings.getfloat("read_interval", self.read_interval) self.max_precision = settings.getint(["max_precision", "precision"], self.max_precision) @@ -63,7 +63,7 @@ def __init__(self, settings : 'SectionProxy') -> None: #load a protocol_settings class for every transport; required for adv features. ie, variable timing. #must load after settings - self.protocol_version = settings.get('protocol_version') + self.protocol_version = settings.get("protocol_version") if self.protocol_version: self.protocolSettings = protocol_settings(self.protocol_version, transport_settings=settings) @@ -78,7 +78,7 @@ def __init__(self, settings : 'SectionProxy') -> None: def update_identifier(self): self.device_identifier = self.device_serial_number.strip().lower() - def init_bridge(self, from_transport : 'transport_base'): + def init_bridge(self, from_transport : "transport_base"): pass @classmethod @@ -91,7 +91,7 @@ def _get_top_class_name(cls, cls_obj): def connect(self): pass - def write_data(self, data : dict[str, registry_map_entry], from_transport : 'transport_base'): + def write_data(self, data : dict[str, registry_map_entry], from_transport : "transport_base"): ''' general purpose write function for between transports''' pass @@ -120,7 +120,7 @@ def write_register(self, register : int, value : int, **kwargs): def analyse_protocol(self): pass - def validate_protocol(self, protocolSettings : 'protocol_settings') -> float: + def validate_protocol(self, protocolSettings : "protocol_settings") -> float: ''' validates protocol''' pass #endregion diff --git a/defs/common.py b/defs/common.py index 2be9517..7c5a82f 100644 --- a/defs/common.py +++ b/defs/common.py @@ -11,7 +11,7 @@ def strtobool (val): return val val = val.lower() - if val in ('y', 'yes', 't', 'true', 'on', '1'): + if val in ("y", "yes", "t", "true", "on", "1"): return 1 return 0 @@ -24,46 +24,46 @@ def strtoint(val : str) -> int: val = val.lower().strip() - if val and val[0] == 'x': + if val and val[0] == "x": val = val[1:] # Pad the string with a leading zero if len(val) % 2 != 0: - val = '0' + val + val = "0" + val - return int.from_bytes(bytes.fromhex(val), byteorder='big') + return int.from_bytes(bytes.fromhex(val), byteorder="big") if val and val.startswith("0x"): val = val[2:] # Pad the string with a leading zero if len(val) % 2 != 0: - val = '0' + val + val = "0" + val - return int.from_bytes(bytes.fromhex(val), byteorder='big') + return int.from_bytes(bytes.fromhex(val), byteorder="big") if not val: #empty return 0 return int(val) -def get_usb_serial_port_info(port : str = '') -> str: +def get_usb_serial_port_info(port : str = "") -> str: for p in serial.tools.list_ports.comports(): if str(p.device).upper() == port.upper(): return "["+hex(p.vid)+":"+hex(p.pid)+":"+str(p.serial_number)+":"+str(p.location)+"]" return "" -def find_usb_serial_port(port : str = '', vendor_id : str = '', product_id : str = '', serial_number : str = '', location : str = '') -> str: - if not port.startswith('['): +def find_usb_serial_port(port : str = "", vendor_id : str = "", product_id : str = "", serial_number : str = "", location : str = "") -> str: + if not port.startswith("["): return port - port = port.replace('None', '') + port = port.replace("None", "") match = re.match(r"\[(?P[\da-zA-Z]+|):?(?P[\da-zA-Z]+|):?(?P[\da-zA-Z]+|):?(?P[\d\-]+|)\]", port) if match: - vendor_id = int(match.group("vendor"), 16) if match.group("vendor") else '' - product_id = int(match.group("product"), 16) if match.group("product") else '' - serial_number = match.group("serial") if match.group("serial") else '' - location = match.group("location") if match.group("location") else '' + vendor_id = int(match.group("vendor"), 16) if match.group("vendor") else "" + product_id = int(match.group("product"), 16) if match.group("product") else "" + serial_number = match.group("serial") if match.group("serial") else "" + location = match.group("location") if match.group("location") else "" for port in serial.tools.list_ports.comports(): if ((not vendor_id or port.vid == vendor_id) and diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index a9214a0..b6f4368 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -8,17 +8,17 @@ def extract_first_header(file_path): for line in file: line = line.strip() if line.startswith("#"): - return line.replace('#', '') + return line.replace("#", "") return None def generate_readme(directory : str, folder_order : str = [], output_file : str ="README.md"): - with open(directory+'/'+output_file, "w", encoding="utf-8") as readme: + with open(directory+"/"+output_file, "w", encoding="utf-8") as readme: readme.write("# README Index\n\n") readme.write("This README file contains an index of all files in the documentation directory.\n\n") readme.write("## File List\n\n") - note_file : str = directory+'/note.md' + note_file : str = directory+"/note.md" if os.path.exists(note_file): readme.write("\n## Additional Notes\n\n") with open(note_file, "r", encoding="utf-8") as note: @@ -33,7 +33,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str relative_folder = os.path.relpath(root, directory).replace("\\", "/") #use linux path structure #exclude . folders - if relative_folder[0] == '.': + if relative_folder[0] == ".": continue if relative_folder != previous_folder: diff --git a/protocol_gateway.py b/protocol_gateway.py index 485beb7..2f8ea9b 100644 --- a/protocol_gateway.py +++ b/protocol_gateway.py @@ -52,9 +52,9 @@ def get(self, section, option, *args, **kwargs): if isinstance(option, list): fallback = None - if 'fallback' in kwargs: #override kwargs fallback, for manually handling here - fallback = kwargs['fallback'] - kwargs['fallback'] = None + if "fallback" in kwargs: #override kwargs fallback, for manually handling here + fallback = kwargs["fallback"] + kwargs["fallback"] = None for name in option: value = super().get(section, name, *args, **kwargs) @@ -80,7 +80,7 @@ class Protocol_Gateway: """ __log = None # log level, available log levels are CRITICAL, FATAL, ERROR, WARNING, INFO, DEBUG - __log_level = 'DEBUG' + __log_level = "DEBUG" __running : bool = False ''' controls main loop''' @@ -91,15 +91,15 @@ class Protocol_Gateway: config_file : str def __init__(self, config_file : str): - self.__log = logging.getLogger('invertermodbustomqqt_log') + self.__log = logging.getLogger("invertermodbustomqqt_log") handler = logging.StreamHandler(sys.stdout) #self.__log.setLevel(logging.DEBUG) - formatter = logging.Formatter('[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s') + formatter = logging.Formatter("[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s") handler.setFormatter(formatter) self.__log.addHandler(handler) - self.config_file = os.path.dirname(os.path.realpath(__file__)) + '/growatt2mqtt.cfg' - newcfg = os.path.dirname(os.path.realpath(__file__)) + '/'+ config_file + self.config_file = os.path.dirname(os.path.realpath(__file__)) + "/growatt2mqtt.cfg" + newcfg = os.path.dirname(os.path.realpath(__file__)) + "/"+ config_file if os.path.isfile(newcfg): self.config_file = newcfg @@ -114,34 +114,34 @@ def __init__(self, config_file : str): self.__settings.read(self.config_file) ##[general] - self.__log_level = self.__settings.get('general','log_level', fallback='INFO') + self.__log_level = self.__settings.get("general","log_level", fallback="INFO") log_level = getattr(logging, self.__log_level, logging.INFO) self.__log.setLevel(log_level) logging.basicConfig(level=log_level) for section in self.__settings.sections(): - if section.startswith('transport'): + if section.startswith("transport"): transport_cfg = self.__settings[section] - transport_type = transport_cfg.get('transport', fallback="") - protocol_version = transport_cfg.get('protocol_version', fallback="") + transport_type = transport_cfg.get("transport", fallback="") + protocol_version = transport_cfg.get("protocol_version", fallback="") if not transport_type and not protocol_version: - raise ValueError('Missing Transport / Protocol Version') + raise ValueError("Missing Transport / Protocol Version") if not transport_type and protocol_version: #get transport from protocol settings... todo need to make a quick function instead of this protocolSettings : protocol_settings = protocol_settings(protocol_version) if not transport_type and not protocolSettings.transport: - raise ValueError('Missing Transport') + raise ValueError("Missing Transport") if not transport_type: transport_type = protocolSettings.transport # Import the module - module = importlib.import_module('classes.transports.'+transport_type) + module = importlib.import_module("classes.transports."+transport_type) # Get the class from the module cls = getattr(module, transport_type) transport : transport_base = cls(transport_cfg) @@ -227,13 +227,13 @@ def main(): if __name__ == "__main__": # Create ArgumentParser object - parser = argparse.ArgumentParser(description='Python Protocol Gateway') + parser = argparse.ArgumentParser(description="Python Protocol Gateway") # Add arguments - parser.add_argument('--config', '-c', type=str, help='Specify Config File') + parser.add_argument("--config", "-c", type=str, help="Specify Config File") # Add a positional argument with default - parser.add_argument('positional_config', type=str, help='Specify Config File', nargs='?', default='config.cfg') + parser.add_argument("positional_config", type=str, help="Specify Config File", nargs="?", default="config.cfg") # Parse arguments args = parser.parse_args() diff --git a/pytests/test_example_config.py b/pytests/test_example_config.py index d3909c2..f58de27 100644 --- a/pytests/test_example_config.py +++ b/pytests/test_example_config.py @@ -2,7 +2,7 @@ import sys #move up a folder for tests -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from protocol_gateway import CustomConfigParser diff --git a/pytests/test_protocol_settings.py b/pytests/test_protocol_settings.py index bada009..34394c8 100644 --- a/pytests/test_protocol_settings.py +++ b/pytests/test_protocol_settings.py @@ -5,13 +5,13 @@ import pytest #move up a folder for tests -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from classes.protocol_settings import protocol_settings # List of protocols to test # Create the search pattern to find .json files recursively -search_pattern = os.path.join("protocols", '**', '*.json') +search_pattern = os.path.join("protocols", "**", "*.json") # Use glob to find all files matching the pattern files = glob.glob(search_pattern, recursive=True) # Extract file names without extension diff --git a/ruff.toml b/ruff.toml index a73964f..e757077 100644 --- a/ruff.toml +++ b/ruff.toml @@ -7,17 +7,18 @@ target-version = "py311" # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["BLE", "C", "DTZ", "E", "EM", "F", "FA", "FBT", "G", "I", "S", "TRY", "W"] +select = ["BLE", "C", "DTZ", "E", "EM", "F", "FA", "FBT", "G", "I", "LOG", "S", "TRY", "W"] #select = ["ALL"] ignore = [ "BLE001", "C901", -# "D", +"D", "EM101", "E501", "FBT001", "FBT002", "N", +"RUF", "TRY003", ] diff --git a/test.py b/test.py index 3272c8a..dd24198 100644 --- a/test.py +++ b/test.py @@ -10,7 +10,7 @@ # Candlelight firmware on Linux -bus = can.interface.Bus(interface='socketcan', channel='can0', bitrate=500000) +bus = can.interface.Bus(interface="socketcan", channel="can0", bitrate=500000) # Stock slcan firmware on Linux #bus = can.interface.Bus(bustype='slcan', channel='/dev/ttyACM0', bitrate=500000) @@ -40,21 +40,21 @@ if msg.arbitration_id == 0x0FFF: # The data is a 2-byte value (un16) soc_bytes = msg.data[:2] - soc = int.from_bytes(soc_bytes, byteorder='big', signed=False) / 100.0 + soc = int.from_bytes(soc_bytes, byteorder="big", signed=False) / 100.0 print(f"State of Charge: {soc:.2f}%") if msg.arbitration_id == 0x0355: # Extract and print SOC value (U16, 0.01%) - soc_value = int.from_bytes(msg.data[0:0 + 2], byteorder='little') + soc_value = int.from_bytes(msg.data[0:0 + 2], byteorder="little") print(f"State of Charge (SOC) Value: {soc_value / 100:.2f}%") # Extract and print SOH value (U16, 1%) - soh_value = int.from_bytes(msg.data[2:2 + 2], byteorder='little') + soh_value = int.from_bytes(msg.data[2:2 + 2], byteorder="little") print(f"State of Health (SOH) Value: {soh_value:.2f}%") # Extract and print HiRes SOC value (U16, 0.01%) - hires_soc_value = int.from_bytes(msg.data[4:4 + 2], byteorder='little') + hires_soc_value = int.from_bytes(msg.data[4:4 + 2], byteorder="little") print(f"High Resolution SOC Value: {hires_soc_value / 100:.2f}%") except KeyboardInterrupt: @@ -71,7 +71,7 @@ # Function to evaluate mathematical expressions def evaluate_variables(expression): # Define a regular expression pattern to match variables - var_pattern = re.compile(r'\[([^\[\]]+)\]') + var_pattern = re.compile(r"\[([^\[\]]+)\]") # Replace variables in the expression with their values def replace_vars(match): @@ -86,7 +86,7 @@ def replace_vars(match): def evaluate_ranges(expression): # Define a regular expression pattern to match ranges - range_pattern = re.compile(r'\[.*?((?P\d+)\s?\~\s?(?P\d+)).*?\]') + range_pattern = re.compile(r"\[.*?((?P\d+)\s?\~\s?(?P\d+)).*?\]") # Find all ranges in the expression ranges = range_pattern.findall(expression) @@ -114,19 +114,19 @@ def evaluate_ranges(expression): def evaluate_expression(expression): # Define a regular expression pattern to match "maths" - var_pattern = re.compile(r'\[(?P.*?)\]') + var_pattern = re.compile(r"\[(?P.*?)\]") # Replace variables in the expression with their values def replace_vars(match): try: maths = match.group("maths") - maths = re.sub(r'\s', '', maths) #remove spaces, because ast.parse doesnt like them + maths = re.sub(r"\s", "", maths) #remove spaces, because ast.parse doesnt like them # Parse the expression safely - tree = ast.parse(maths, mode='eval') + tree = ast.parse(maths, mode="eval") # Evaluate the expression - end_value = ast.literal_eval(compile(tree, filename='', mode='eval')) + end_value = ast.literal_eval(compile(tree, filename="", mode="eval")) return str(end_value) except Exception: diff --git a/tools/apply_common_names_to_csv.py b/tools/apply_common_names_to_csv.py index 17535a9..6c71d1c 100644 --- a/tools/apply_common_names_to_csv.py +++ b/tools/apply_common_names_to_csv.py @@ -1,41 +1,41 @@ import csv import json -path = 'protocols/eg4_v58.holding_registry_map.csv' -save_path = 'protocols/eg4_v58.holding_registry_map.csv' +path = "protocols/eg4_v58.holding_registry_map.csv" +save_path = "protocols/eg4_v58.holding_registry_map.csv" -common_path = 'tools/common_names.json' +common_path = "tools/common_names.json" common_names : dict[str,str] = {} # Open the file and load the JSON data -with open(common_path, 'r') as file: +with open(common_path, "r") as file: common_names = json.load(file) new_csv : list[dict[str,str]] = [] -with open(path, newline='') as csvfile: +with open(path, newline="") as csvfile: # Create a CSV reader object - reader = csv.DictReader(csvfile, delimiter=';') #compensate for openoffice + reader = csv.DictReader(csvfile, delimiter=";") #compensate for openoffice fieldnames = reader.fieldnames # Iterate over each row in the CSV file for row in reader: - if not row['variable name'] and row['documented name']: - if row['documented name'] not in common_names: - print('no friendly name : ' + row['documented name']) + if not row["variable name"] and row["documented name"]: + if row["documented name"] not in common_names: + print("no friendly name : " + row["documented name"]) new_csv.append(row) continue - if not row['variable name'].strip(): #if empty, apply name - row['variable name'] = common_names[row['documented name']] - print(row['documented name'] + ' -> ' + common_names[row['documented name']]) + if not row["variable name"].strip(): #if empty, apply name + row["variable name"] = common_names[row["documented name"]] + print(row["documented name"] + " -> " + common_names[row["documented name"]]) new_csv.append(row) continue new_csv.append(row) # Write data to the output CSV -with open(save_path, 'w', newline='') as outfile: +with open(save_path, "w", newline="") as outfile: writer = csv.DictWriter(outfile, fieldnames=fieldnames) writer.writeheader() writer.writerows(new_csv) diff --git a/tools/get_common_names_from_csv.py b/tools/get_common_names_from_csv.py index f2ba72e..74439c8 100644 --- a/tools/get_common_names_from_csv.py +++ b/tools/get_common_names_from_csv.py @@ -1,32 +1,32 @@ import csv import json -path = 'protocols/growatt_2020_v1.24.input_registry_map.csv' +path = "protocols/growatt_2020_v1.24.input_registry_map.csv" -save_path = 'tools/common_names.json' +save_path = "tools/common_names.json" common_names = {} -common_path = 'tools/common_names.json' #load existing names +common_path = "tools/common_names.json" #load existing names common_names : dict[str,str] = {} # Open the file and load the JSON data -with open(common_path, 'r') as file: +with open(common_path, "r") as file: common_names = json.load(file) -with open(path, newline='') as csvfile: +with open(path, newline="") as csvfile: # Create a CSV reader object - reader = csv.DictReader(csvfile, delimiter=';') #compensate for openoffice + reader = csv.DictReader(csvfile, delimiter=";") #compensate for openoffice # Iterate over each row in the CSV file for row in reader: - if row['variable name'] and row['documented name']: - if row['documented name'] in common_names and common_names[row['documented name']] != row['variable name']: - print('Warning, Naming Conflict') - print(row['documented name'] + ' -> ' + row['variable name']) - print(row['documented name'] + ' -> ' + common_names[row['documented name']]) + if row["variable name"] and row["documented name"]: + if row["documented name"] in common_names and common_names[row["documented name"]] != row["variable name"]: + print("Warning, Naming Conflict") + print(row["documented name"] + " -> " + row["variable name"]) + print(row["documented name"] + " -> " + common_names[row["documented name"]]) else: - common_names[row['documented name']] = row['variable name'] + common_names[row["documented name"]] = row["variable name"] json_str = json.dumps(common_names, indent=1) @@ -34,7 +34,7 @@ print(json_str) quit() -with open(save_path, 'w') as file: +with open(save_path, "w") as file: file.write(json_str) print("saved to "+save_path) diff --git a/tools/list_to_json.py b/tools/list_to_json.py index edd10e2..167b717 100644 --- a/tools/list_to_json.py +++ b/tools/list_to_json.py @@ -5,9 +5,9 @@ input_string = "1=Charger Only;2=Inverter Only;3=On;4=Off" while True: user_input = input("Enter Data: ") - user_input = re.sub(r'\s+', " ", user_input) - user_input = re.sub(r'\:\s+', ":", user_input) - user_input = re.sub(r'\s+\:', ":", user_input) + user_input = re.sub(r"\s+", " ", user_input) + user_input = re.sub(r"\:\s+", ":", user_input) + user_input = re.sub(r"\s+\:", ":", user_input) # Split the string into key-value pairs From 0763f526d66aa1ed3944d02ff9213427fb05315e Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2025 10:54:34 -0500 Subject: [PATCH 29/53] add write unsafe option --- classes/transports/modbus_base.py | 4 ++++ classes/transports/transport_base.py | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index bc4941d..d87012d 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -129,6 +129,10 @@ def read_serial_number(self) -> str: return serial_number def enable_write(self): + if self.write_enabled and self.write_unsafe: + self._log.warning("enable write - validation SKIPPED") + return + self._log.info("Validating Protocol for Writing") self.write_enabled = False score_percent = self.validate_protocol(Registry_Type.HOLDING) diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index fde3e47..8570e5f 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -24,6 +24,8 @@ class transport_base: device_identifier : str = "hotnoob" bridge : str = "" write_enabled : bool = False + write_unsafe : bool = False + ''' by pass some write validation ''' max_precision : int = 2 read_interval : float = 0 @@ -56,10 +58,16 @@ def __init__(self, settings : "SectionProxy") -> None: self.bridge = settings.get("bridge", self.bridge) self.read_interval = settings.getfloat("read_interval", self.read_interval) self.max_precision = settings.getint(["max_precision", "precision"], self.max_precision) - if "write_enabled" in settings: + if "write_enabled" in settings or "enable_write" in settings: self.write_enabled = settings.getboolean(["write_enabled", "enable_write"], self.write_enabled) - else: - self.write_enabled = settings.getboolean("write", self.write_enabled) + + if "write" in settings: + if settings.get("write", "").lower() == "unsafe": + self.write_enabled = True + self.write_unsafe = True + else: + self.write_enabled = settings.getboolean("write", self.write_enabled) + #load a protocol_settings class for every transport; required for adv features. ie, variable timing. #must load after settings From e9253640355010ddd770419275c581122edcdddb Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2025 11:30:23 -0500 Subject: [PATCH 30/53] fix some validation bugs --- classes/protocol_settings.py | 9 ++++++--- classes/transports/modbus_base.py | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 543c809..a261b0e 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1,3 +1,4 @@ +import sys import ast import csv import glob @@ -780,7 +781,7 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register timestamp_ms = int(time.time() * 1000) if init : #hack so that all registers are read initially without adding extra if in loop - timestamp_ms = 0 + timestamp_ms = sys.maxsize while (start := start+max_batch_size) <= max_register: @@ -1162,10 +1163,12 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int: return len(entry.concatenate_registers) else: #default type - if int(val) >= entry.value_min and int(val) <= entry.value_max: + + intval = int(val) + if intval >= entry.value_min and intval <= entry.value_max: return 1 - self._log.error(f"validate_registry_entry fail overall {entry.value_min} / {entry.value_max} / {int(val)}") + self._log.error(f"validate_registry_entry fail overall {entry.value_min} / {entry.value_max} / {intval}") return 0 diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index d87012d..4bbad90 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -12,6 +12,7 @@ from ..protocol_settings import ( Data_Type, Registry_Type, + WriteMode, protocol_settings, registry_map_entry, ) @@ -204,6 +205,10 @@ def validate_registry(self, registry_type : Registry_Type = Registry_Type.INPUT) score = score + self.protocolSettings.validate_registry_entry(value, info[value.variable_name]) maxScore = len(registry_map) + for entry in registry_map: #adjust max score to exclude disabled registers + if entry.write_mode == WriteMode.WRITEONLY or entry.write_mode == WriteMode.READDISABLED: + maxScore -= 1 + percent = score*100/maxScore self._log.info("validation score: " + str(score) + " of " + str(maxScore) + " : " + str(round(percent)) + "%") return percent From 873dbc4afb2356256759dc8f821a862fa5863450 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2025 11:36:49 -0500 Subject: [PATCH 31/53] sorry my hack failed. let's just do an extra if instead. --- classes/protocol_settings.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index a261b0e..f455673 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -780,8 +780,6 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register ranges : list[tuple] = [] timestamp_ms = int(time.time() * 1000) - if init : #hack so that all registers are read initially without adding extra if in loop - timestamp_ms = sys.maxsize while (start := start+max_batch_size) <= max_register: @@ -796,7 +794,7 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register continue #we are assuming calc registry ranges is being called EVERY READ. - if register.next_read_timestamp < timestamp_ms: + if init or register.next_read_timestamp < timestamp_ms: register.next_read_timestamp = timestamp_ms + register.read_interval registers.append(register.register) From 532d34d99ad9e2674a97ab0300309852b930550a Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 24 Mar 2025 16:38:09 -0500 Subject: [PATCH 32/53] add other data types for validation when writing to modbus --- classes/transports/modbus_base.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 4bbad90..b628e4f 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -368,9 +368,15 @@ def evaluate_score(entry : registry_map_entry, val): def write_variable(self, entry : registry_map_entry, value : str, registry_type : Registry_Type = Registry_Type.HOLDING): """ writes a value to a ModBus register; todo: registry_type to handle other write functions""" + + temp_map = [entry] + ranges = self.protocolSettings.calculate_registry_ranges(temp_map, init=True) #init=True to bypass timechecks + registry = self.read_modbus_registers( ranges=ranges, registry_type=registry_type) + info = self.protocolSettings.process_registery(registry, temp_map) #read current value - current_registers = self.read_modbus_registers(start=entry.register, end=entry.register, registry_type=registry_type) - current_value = current_registers[entry.register] + #current_registers = self.read_modbus_registers(start=entry.register, end=entry.register, registry_type=registry_type) + #current_value = current_registers[entry.register] + current_value = info[entry.variable_name] if not self.protocolSettings.validate_registry_entry(entry, current_value): err = f"Invalid value in register '{current_value}'. Unsafe to write" From 9e788b65e06249f6cd42763898e59840884c60bc Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 25 Mar 2025 21:25:29 -0500 Subject: [PATCH 33/53] clean --- protocols/eg4/eg4_v58.input_registry_map.csv | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/protocols/eg4/eg4_v58.input_registry_map.csv b/protocols/eg4/eg4_v58.input_registry_map.csv index d025de7..a6b71ed 100644 --- a/protocols/eg4/eg4_v58.input_registry_map.csv +++ b/protocols/eg4/eg4_v58.input_registry_map.csv @@ -119,16 +119,16 @@ Grid Hz,,15,Fac,0.01Hz,0-65535,Utility grid frequency,,,,,,,,,,,, ,4bit,113.b4,Resvd,Bit4~7,,Reserved,,,,,,,,,,,, ,8bit,113.b8,ParallelNum,Bit8~16,1~255,Number of inverters in parallel,,,,,,,,,,,, ,,114,OnGridloadPower,W,,Load power of the 12k inverter when it is not off-grid,,,,,,,,,,,, -,8bit,115,SN_0__Year,,0'-'9' 'A'- 'Z',The serial number is a ten-digit ASCII code For example: The serial number is AB12345678 SN[0]=0x41(A) : : : : SN[9]=0x38(8),,,,,,,,,,,, -,8bit,115.b8,SN_1__week,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,116,SN_2__week,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,116.b8,SN_3__factory,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,117,SN_4__product code,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,117.b8,SN_5__product code,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,118,SN_6__serial number,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,118.b8,SN_7__serial number,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,119,SN_8__serial number,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, -,8bit,119.b8,SN_9__serial number,,0'-'9' 'A'- 'Z',,,,,,,,,,,,, +,8bit,115,SN_0__Year,,[0-9a-zA-Z],The serial number is a ten-digit ASCII code For example: The serial number is AB12345678 SN[0]=0x41(A) : : : : SN[9]=0x38(8),,,,,,,,,,,, +,8bit,115.b8,SN_1__week,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,116,SN_2__week,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,116.b8,SN_3__factory,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,117,SN_4__product code,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,117.b8,SN_5__product code,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,118,SN_6__serial number,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,118.b8,SN_7__serial number,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,119,SN_8__serial number,,[0-9a-zA-Z],,,,,,,,,,,,, +,8bit,119.b8,SN_9__serial number,,[0-9a-zA-Z],,,,,,,,,,,,, ,,120,VBusP,0.1V,,,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage,Half BUS voltage ,,121,GenVolt,0.1V,,Generator voltage Voltage of generator for three phase: R phase,,,,,,,,,,,, ,,122,GenFreq,0.01Hz,,Generator frequency,,,,,,,,,,,, @@ -199,34 +199,34 @@ Grid Hz,,15,Fac,0.01Hz,0-65535,Utility grid frequency,,,,,,,,,,,, ,,402,FaultRecord1_MAndS,,,Fault Records 1_ minutes & seconds,,,,,,,,,,,, ,,403,FaultRecord1_Code,,,Fault Records 1_ fault code,,,,,,,,,,,, ,,404,FaultRecord1_Value,,,Fault Records 1_ fault value,,,,,,,,,,,, -,,405,FaultRecord1_SetOrClr,,0/1,Fault Records 1_Fault occurred or cleared (0-fault occurred,,,,,,,,,,,, +,,405,FaultRecord1_SetOrClr,,0~1,Fault Records 1_Fault occurred or cleared (0-fault occurred,,,,,,,,,,,, ,,406,FaultRecord2_YAndM,,,Fault Records 2_ years & months,,,,,,,,,,,, ,,407,FaultRecord2_DAndH,,,Fault Records 2_ days & hours,,,,,,,,,,,, ,,408,FaultRecord2_MAndS,,,Fault Records 2_ minutes & seconds,,,,,,,,,,,, ,,409,FaultRecord2_Code,,,Fault Records 2_ fault code,,,,,,,,,,,, ,,410,FaultRecord2_Value,,,Fault Records 2_Fault value,,,,,,,,,,,, -,,411,FaultRecord2_SetOrClr,,0/1,Fault Records 2_Fault occurred or clear (0 - Fault Occurred,,,,,,,,,,,, +,,411,FaultRecord2_SetOrClr,,0~1,Fault Records 2_Fault occurred or clear (0 - Fault Occurred,,,,,,,,,,,, ,,994,FaultRecord100_YAndM,,,Fault Records 100_ years & months,,,,,,,,,,,, ,,995,FaultRecord100_DAndH,,,Fault records 100_ days & hours,,,,,,,,,,,, ,,996,FaultRecord100_MAndS,,,Fault Records 100_minutes & seconds,,,,,,,,,,,, ,,997,FaultRecord100_Code,,,Fault Records 100_ fault code,,,,,,,,,,,, ,,998,FaultRecord100_Value,,,The fault record is 100_ fault value,,,,,,,,,,,, -,,999,FaultRecord100_SetOrClr,,0/1,Fault Records 100_Fault Occurred or Cleared (0 - Fault Occurred,,,,,,,,,,,, +,,999,FaultRecord100_SetOrClr,,0~1,Fault Records 100_Fault Occurred or Cleared (0 - Fault Occurred,,,,,,,,,,,, ,,1000,WarnRecord1_YAndM,,,Alarm Records 1_ years & months,,,,,,,,,,,, ,,1001,WarnRecord1_DAndH,,,Alarm Records 1_ days & hours,,,,,,,,,,,, ,,1002,WarnRecord1_MAndS,,,Alarm records 1_ minutes &seconds,,,,,,,,,,,, ,,1003,WarnRecord1_Code,,,Alarm Records 1_ alarm code,,,,,,,,,,,, ,,1004,WarnRecord1_Value,,,Alarm Records 1_Alarm value,,,,,,,,,,,, -,,1005,WarnRecord1_SetOrClr,,0/1,Alarm Records 1_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, +,,1005,WarnRecord1_SetOrClr,,0~1,Alarm Records 1_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, ,,1006,WarnRecord2_YAndM,,,Alarm records 2_ years & months,,,,,,,,,,,, ,,1007,WarnRecord2_DAndH,,,Alarm Records 2_ days & hour,,,,,,,,,,,, ,,1008,WarnRecord2_MAndS,,,Alarm Records 2_ minutes & seconds,,,,,,,,,,,, ,,1009,WarnRecord2_Code,,,Alarm Records 2_Alarm code,,,,,,,,,,,, ,,1010,WarnRecord2_Value,,,Alarm Records 2_Alarm value,,,,,,,,,,,, -,,1011,WarnRecord2_SetOrClr,,0/1,Alarm Records 2_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, +,,1011,WarnRecord2_SetOrClr,,0~1,Alarm Records 2_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, ,,1594,WarnRecord100_YAndM,,,Alarm Records 100_ years & months,,,,,,,,,,,, ,,1595,WarnRecord100_DAndH,,,Alarm Records for 100_ days & hours,,,,,,,,,,,, ,,1596,WarnRecord100_MAndS,,,Alarm records 100_ minutes &seconds,,,,,,,,,,,, ,,1597,WarnRecord100_Code,,,Alarm Records 100_ alarm code,,,,,,,,,,,, ,,1598,WarnRecord100_Value,,,Alarm records 100_alarm value,,,,,,,,,,,, -,,1599,WarnRecord100_SetOrClr,,0/1,Alarm Records 100_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, +,,1599,WarnRecord100_SetOrClr,,0~1,Alarm Records 100_Alarm occurred or cleared (0 - alarm occurred,,,,,,,,,,,, From 6f6093a0a147c31127840e46c0f94a837ca84a6f Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Mar 2025 22:35:09 -0500 Subject: [PATCH 34/53] transport writemode cleaned up some debug messages. changed raise error to logerror to be easier to work with added modbus_tcp write support --- classes/protocol_settings.py | 2 +- classes/transports/modbus_base.py | 28 ++++++---- classes/transports/modbus_tcp.py | 13 +++++ classes/transports/mqtt.py | 2 +- classes/transports/transport_base.py | 51 ++++++++++++++++--- .../v0.14.input_registry_map.override.csv | 3 -- requirements-dev.txt | 1 + 7 files changed, 79 insertions(+), 21 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index f455673..caafdf2 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1166,7 +1166,7 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int: if intval >= entry.value_min and intval <= entry.value_max: return 1 - self._log.error(f"validate_registry_entry fail overall {entry.value_min} / {entry.value_max} / {intval}") + self._log.error(f"validate_registry_entry '{entry.variable_name}' fail (INT) {intval} != {entry.value_min}~{entry.value_max}") return 0 diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 4bbad90..83e2ba1 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -16,7 +16,7 @@ protocol_settings, registry_map_entry, ) -from .transport_base import transport_base +from .transport_base import transport_base, TransportWriteMode if TYPE_CHECKING: from configparser import SectionProxy @@ -76,7 +76,7 @@ def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_setti if self.analyze_protocol_enabled: self.connect() - self.analyze_protocol() + self.analyze_protocol() quit() def init_after_connect(self): @@ -130,8 +130,8 @@ def read_serial_number(self) -> str: return serial_number def enable_write(self): - if self.write_enabled and self.write_unsafe: - self._log.warning("enable write - validation SKIPPED") + if self.write_enabled and self.write_mode == TransportWriteMode.UNSAFE: + self._log.warning("enable write - WARNING - UNSAFE MODE - validation SKIPPED") return self._log.info("Validating Protocol for Writing") @@ -140,6 +140,13 @@ def enable_write(self): if(score_percent > 90): self.write_enabled = True self._log.warning("enable write - validation passed") + elif self.write_mode == TransportWriteMode.RELAXED: + self.write_enabled = True + self._log.warning("enable write - WARNING - RELAXED MODE") + else: + self._log.error("enable write FAILED - WRITE DISABLED") + + def write_data(self, data : dict[str, str], from_transport : transport_base) -> None: if not self.write_enabled: @@ -372,13 +379,13 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type current_registers = self.read_modbus_registers(start=entry.register, end=entry.register, registry_type=registry_type) current_value = current_registers[entry.register] - if not self.protocolSettings.validate_registry_entry(entry, current_value): - err = f"Invalid value in register '{current_value}'. Unsafe to write" - raise ValueError(err) + if not self.write_mode == TransportWriteMode.UNSAFE: + if not self.protocolSettings.validate_registry_entry(entry, current_value): + self._log.error(f"WRITE_ERROR: Invalid value in register '{current_value}'. Unsafe to write") + #raise ValueError(err) - if not self.protocolSettings.validate_registry_entry(entry, value): - err = f"Invalid new value, '{value}'. Unsafe to write" - raise ValueError(err) + if not self.protocolSettings.validate_registry_entry(entry, value): + self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write") #handle codes if entry.variable_name+"_codes" in self.protocolSettings.codes: @@ -422,6 +429,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if ushortValue is None: raise ValueError("Invalid value - None") + self._log.info(f"WRITE: {current_value} => {ushortValue} to Register {entry.register}") self.write_register(entry.register, ushortValue) diff --git a/classes/transports/modbus_tcp.py b/classes/transports/modbus_tcp.py index 3768f44..594dda9 100644 --- a/classes/transports/modbus_tcp.py +++ b/classes/transports/modbus_tcp.py @@ -43,6 +43,19 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings super().__init__(settings, protocolSettings=protocolSettings) + def write_register(self, register : int, value : int, **kwargs): + if not self.write_enabled: + return + + if "unit" not in kwargs: + kwargs = {"unit": 1, **kwargs} + + #compatability + if self.pymodbus_slave_arg != "unit": + kwargs["slave"] = kwargs.pop("unit") + + self.client.write_register(register, value, **kwargs) #function code 0x06 writes to holding register + def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): if "unit" not in kwargs: diff --git a/classes/transports/mqtt.py b/classes/transports/mqtt.py index 4fecef8..d1469e4 100644 --- a/classes/transports/mqtt.py +++ b/classes/transports/mqtt.py @@ -178,7 +178,7 @@ def write_data(self, data : dict[str, str], from_transport : transport_base): def client_on_message(self, client, userdata, msg): """ The callback for when a PUBLISH message is received from the server. """ - self._log.info(msg.topic+" "+str(msg.payload.decode("utf-8"))) + self._log.info("MQTT MSG: " + msg.topic+" "+str(msg.payload.decode("utf-8"))) #self.protocolSettings.validate_registry_entry if msg.topic in self.__write_topics: diff --git a/classes/transports/transport_base.py b/classes/transports/transport_base.py index 8570e5f..a0c33b8 100644 --- a/classes/transports/transport_base.py +++ b/classes/transports/transport_base.py @@ -1,3 +1,4 @@ +from enum import Enum import logging from typing import TYPE_CHECKING, Callable @@ -12,6 +13,44 @@ from .transport_base import transport_base +class TransportWriteMode(Enum): + READ = 0x00 + ''' READ ONLY ''' + WRITE = 0x01 + ''' Standard Write Mode, ALL SAFTIES IN PLACE''' + RELAXED = 0x02 + ''' less strict - initial protocol validation skipped''' + UNSAFE = 0x03 + ''' skip all safties ''' + + @classmethod + def fromString(cls, name : str): + name = name.strip().upper() + + #common inputs + alias : dict[str,TransportWriteMode] = { + "" : "READ", #default + "FALSE" : "READ", + "NO" : "READ", + "READ" : "READ", + "R" : "READ", + + "TRUE" : "WRITE", + "YES" : "WRITE", + "WRITE" : "WRITE", + "W" : "WRITE", + + "RELAXED" : "RELAXED", + "UNSAFE" : "UNSAFE", + } + + if name in alias: + name = alias[name] + else: + name = "READ" #default + + return getattr(cls, name) + class transport_base: type : str = "" protocolSettings : "protocol_settings" @@ -23,9 +62,11 @@ class transport_base: device_model : str = "hotnoob" device_identifier : str = "hotnoob" bridge : str = "" + write_enabled : bool = False - write_unsafe : bool = False - ''' by pass some write validation ''' + ''' deprecated -- use / move to write_mode''' + write_mode : TransportWriteMode = None + max_precision : int = 2 read_interval : float = 0 @@ -62,11 +103,9 @@ def __init__(self, settings : "SectionProxy") -> None: self.write_enabled = settings.getboolean(["write_enabled", "enable_write"], self.write_enabled) if "write" in settings: - if settings.get("write", "").lower() == "unsafe": + self.write_mode = TransportWriteMode.fromString(settings.get("write", "")) + if self.write_mode != TransportWriteMode.READ: self.write_enabled = True - self.write_unsafe = True - else: - self.write_enabled = settings.getboolean("write", self.write_enabled) #load a protocol_settings class for every transport; required for adv features. ie, variable timing. diff --git a/protocols/growatt/v0.14.input_registry_map.override.csv b/protocols/growatt/v0.14.input_registry_map.override.csv index d19d04b..f5d5dbc 100644 --- a/protocols/growatt/v0.14.input_registry_map.override.csv +++ b/protocols/growatt/v0.14.input_registry_map.override.csv @@ -1,5 +1,2 @@ variable name,data type,register,documented name,description,values,unit,,,,,,,,,,, ,,0,System Status,System run state,{{system_status_codes}},1,,3: Fault,4: Flash,5: PV charge,6: AC charge,7: Combine charge,8: Combine charge and Bypass,9: PV charge and Bypass,10: AC charge and Bypass, 11: Bypass,12: PV charge andDischarge -OVERRIDE PV VOLTAGE,,,Vpv1,PV1 voltage,,0.1V,,,,,,,,,,, -extra entry,,777,unique extra entry,PV1 voltage,,0.1V,,,,,,,,,,, -extra entry broken,,,unique broken entry,,,-1,,,,,,,,,,, diff --git a/requirements-dev.txt b/requirements-dev.txt index af3ee57..144e14a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1 +1,2 @@ ruff +modbus_tk \ No newline at end of file From 68e3fd40be19aa3ddee1d409d90ef8de17d9b192 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Mar 2025 22:39:30 -0500 Subject: [PATCH 35/53] add modbus_tcp server sim script for testing --- tools/modbus_server_sim.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tools/modbus_server_sim.py diff --git a/tools/modbus_server_sim.py b/tools/modbus_server_sim.py new file mode 100644 index 0000000..c96bfb9 --- /dev/null +++ b/tools/modbus_server_sim.py @@ -0,0 +1,25 @@ +''' simulate modbus tcp server for testing ppg ''' +import sys +from modbus_tk import modbus_tcp, hooks, utils +from modbus_tk.defines import HOLDING_REGISTERS + +def on_write_request(request): + print(f"Write request: {request}") + + +server = modbus_tcp.TcpServer(address="0.0.0.0", port=5020) +slave = server.add_slave(1) +slave.add_block('0', HOLDING_REGISTERS, 0, 100) # 100 registers +slave.set_values('0', 40, [1] * (55 - 40 + 1)) #regiters 40-55 set to 1. for emulating hdhk_16ch_ac_module + +server.start() +print("Modbus server is running on port 5020...") + +hooks.install_hook("modbus.Server.before_handle_request", on_write_request) + +try: + while True: + pass +except KeyboardInterrupt: + print("Stopping server...") + server.stop() From 9fcfc8af5c40b2b103dfb9531e6b50bf37935bbc Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 25 Mar 2025 22:49:11 -0500 Subject: [PATCH 36/53] test protocol for testing / simulating --- protocols/test.csv | 19 +++++++++++++++++++ protocols/test.json | 6 ++++++ 2 files changed, 25 insertions(+) create mode 100644 protocols/test.csv create mode 100644 protocols/test.json diff --git a/protocols/test.csv b/protocols/test.csv new file mode 100644 index 0000000..04d3c9c --- /dev/null +++ b/protocols/test.csv @@ -0,0 +1,19 @@ +variable name,data type,writable,register,documented name,description,values,unit,notes +,,,0,version,Version number (628 - representing V6.2.8),600~700,, +,,,1,channel a-h current,Current A-H (01-08) channel range - unsigned number (value 40, representing 40A),40~120, +,,,2,channel i-p current,Current I-P (09-16) channel range, unsigned number (value 40, representing 40A),40~120 +,byte,WD,3,address,Low byte is setThe standby address (01H-FFH) 00 is the broadcast address.,1~255,, +,4bit,WD,3.b8,buad rate, the high byte has a low four-bit baud rate (0-8),"{""0"": ""9600"", ""1"": ""1200"", ""2"": ""2400"", ""3"": ""4800"", ""4"": ""9600"", ""5"": ""19200"", ""6"": ""38400"", ""7"": ""57600"", ""8"": ""115200""}",, +,4bit,WD,3.b12,check bit, and the high byte has a high four-bit check bit (0-3).,"{""0"" : ""N, 8, 1"", ""1"" : ""E, 8, 1"", ""2"" : ""O, 8, 1"", ""3"": ""N, 8, 2""}",, +,8bit,,4,factory date month,Factory date ( low byte month),1~12,, +,8bit,,4.b8,factory date year,Factory date (high byte year),,,gives me 36 instead of 24. +,,,5,Reserved,Reserved,0,, +,,WD,6,frequency division coefficient,Default 0005H, frequency division coefficient (value 1-5). Working frequency range=[10Hz*5/frequency dividing coefficient]-400Hz,1~5, +,byte,WD,7,selection factor,The low byte is the selection factor and the default is 30. Actual frequency selection factor = (1 + frequency selection coefficient / 10) do not modify in non-special circumstances.,30,, +,byte,WD,7.b8,measurement result threshold,High byte measurement result threshold (directly set to 0 when the original measurement result is less than this value). ,0~120,, +,8bit,W,12,Time_Year,,17-255,, +,8bit,W,12.b8,Time_Month,,1-12,, +,8bit,W,13,Time_Date,,1-31,, +,8bit,W,13.b8,Time_Hour,,0-23,, +,8bit,W,14,Time_Minute,,0-59,, +,8bit,W,14.b8,Time_Second,,0-59,, diff --git a/protocols/test.json b/protocols/test.json new file mode 100644 index 0000000..6173054 --- /dev/null +++ b/protocols/test.json @@ -0,0 +1,6 @@ +{ + "transport" : "modbus_tcp", + "batch_size": 7, + "send_holding_register": true, + "send_input_register" : false +} \ No newline at end of file From 2c2b73e799f118d8362eeeb657e4c0b4c308603f Mon Sep 17 00:00:00 2001 From: HotNoob Date: Tue, 25 Mar 2025 22:53:23 -0500 Subject: [PATCH 37/53] rename --- protocols/{test.csv => test.holding_registry_map.csv} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename protocols/{test.csv => test.holding_registry_map.csv} (100%) diff --git a/protocols/test.csv b/protocols/test.holding_registry_map.csv similarity index 100% rename from protocols/test.csv rename to protocols/test.holding_registry_map.csv From 2c0a3a51269a78e2afa81d9d9a46362d4dfb8d54 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Mar 2025 23:18:12 -0500 Subject: [PATCH 38/53] fix sub ushort writes - bitwise --- classes/transports/modbus_base.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 4a6d05c..2a83415 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -377,7 +377,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type temp_map = [entry] - ranges = self.protocolSettings.calculate_registry_ranges(temp_map, init=True) #init=True to bypass timechecks + ranges = self.protocolSettings.calculate_registry_ranges(temp_map, self.protocolSettings.registry_map_size[registry_type], init=True) #init=True to bypass timechecks registry = self.read_modbus_registers( ranges=ranges, registry_type=registry_type) info = self.protocolSettings.process_registery(registry, temp_map) #read current value @@ -419,14 +419,17 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type clear_mask = ~(bit_mask) # Mask for clearing the bits to be updated # Clear the bits to be updated in the current_value - ushortValue = current_value & clear_mask + ushortValue = registry[entry.register] & clear_mask # Set the bits according to the new_value at the specified bit position ushortValue |= (new_val << bit_index) & bit_mask + #bit_size = Data_Type.getSize(entry.data_type) bit_mask = (1 << bit_size) - 1 # Create a mask for extracting X bits + bit_index = entry.register_bit check_value = (ushortValue >> bit_index) & bit_mask + if check_value != new_val: raise ValueError("something went wrong bitwise") else: @@ -435,7 +438,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if ushortValue is None: raise ValueError("Invalid value - None") - self._log.info(f"WRITE: {current_value} => {ushortValue} to Register {entry.register}") + self._log.info(f"WRITE: {current_value} => {value} ( {registry[entry.register]} => {ushortValue} ) to Register {entry.register}") self.write_register(entry.register, ushortValue) From 012dc72a26cd23d8541041570e4d481d73056690 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Wed, 26 Mar 2025 18:40:52 -0500 Subject: [PATCH 39/53] apply unit_mod when writing --- classes/transports/modbus_base.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 2a83415..cb8ab8b 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -401,6 +401,10 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type value = key break + #apply unit_mod before writing. + if entry.unit_mod != 1: + value = int(value) / entry.unit_mod # say unitmod is 0.1. 100*0.1 = 10.0. 10 / 0.1 = 100. + #results[entry.variable_name] ushortValue : int = None #ushort if entry.data_type == Data_Type.USHORT: @@ -437,7 +441,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if ushortValue is None: raise ValueError("Invalid value - None") - + self._log.info(f"WRITE: {current_value} => {value} ( {registry[entry.register]} => {ushortValue} ) to Register {entry.register}") self.write_register(entry.register, ushortValue) From b955cb35a9a09a627fb24c876a18a60ebec1320b Mon Sep 17 00:00:00 2001 From: HotNoob Date: Wed, 26 Mar 2025 18:43:33 -0500 Subject: [PATCH 40/53] fix write unit_mod --- classes/transports/modbus_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index cb8ab8b..df90975 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -403,7 +403,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type #apply unit_mod before writing. if entry.unit_mod != 1: - value = int(value) / entry.unit_mod # say unitmod is 0.1. 100*0.1 = 10.0. 10 / 0.1 = 100. + value = int(float(value) / entry.unit_mod) # say unitmod is 0.1. 105*0.1 = 10.5. 10.5 / 0.1 = 105. #results[entry.variable_name] ushortValue : int = None #ushort From f8a4d88eaaf8e2ed5c46fc8c06f6fbc710d39c6f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Mar 2025 18:52:17 -0500 Subject: [PATCH 41/53] test modbus decimal write --- classes/transports/modbus_base.py | 1 + protocols/test.holding_registry_map.csv | 2 ++ 2 files changed, 3 insertions(+) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index df90975..e1eec91 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -444,6 +444,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type self._log.info(f"WRITE: {current_value} => {value} ( {registry[entry.register]} => {ushortValue} ) to Register {entry.register}") self.write_register(entry.register, ushortValue) + entry.next_read_timestamp = 0 #ensure is read next interval def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index 04d3c9c..7f2c9b6 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -17,3 +17,5 @@ variable name,data type,writable,register,documented name,description,values,uni ,8bit,W,13.b8,Time_Hour,,0-23,, ,8bit,W,14,Time_Minute,,0-59,, ,8bit,W,14.b8,Time_Second,,0-59,, +,,W,21,decimal,,0-59,0.1, + From 00a2e0507a8e0ff3b82530f7b14487423ab8160c Mon Sep 17 00:00:00 2001 From: HotNoob Date: Wed, 26 Mar 2025 18:59:07 -0500 Subject: [PATCH 42/53] ruff clean --- classes/protocol_settings.py | 2 -- classes/transports/modbus_base.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index caafdf2..0e73af8 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1,4 +1,3 @@ -import sys import ast import csv import glob @@ -1161,7 +1160,6 @@ def validate_registry_entry(self, entry : registry_map_entry, val) -> int: return len(entry.concatenate_registers) else: #default type - intval = int(val) if intval >= entry.value_min and intval <= entry.value_max: return 1 diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index e1eec91..3265b1e 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -16,7 +16,7 @@ protocol_settings, registry_map_entry, ) -from .transport_base import transport_base, TransportWriteMode +from .transport_base import TransportWriteMode, transport_base if TYPE_CHECKING: from configparser import SectionProxy @@ -76,7 +76,7 @@ def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_setti if self.analyze_protocol_enabled: self.connect() - self.analyze_protocol() + self.analyze_protocol() quit() def init_after_connect(self): @@ -441,7 +441,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if ushortValue is None: raise ValueError("Invalid value - None") - + self._log.info(f"WRITE: {current_value} => {value} ( {registry[entry.register]} => {ushortValue} ) to Register {entry.register}") self.write_register(entry.register, ushortValue) entry.next_read_timestamp = 0 #ensure is read next interval From a0ccf3c87377adff81a0dbb97d91de98f02a5aa4 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Thu, 27 Mar 2025 10:55:12 -0500 Subject: [PATCH 43/53] normalize variable timing read intervals --- classes/protocol_settings.py | 7 +++++-- classes/transports/modbus_base.py | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 0e73af8..07a0ea7 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -764,7 +764,7 @@ def process_row(row): return registry_map - def calculate_registry_ranges(self, map : list[registry_map_entry], max_register : int, init : bool = False) -> list[tuple]: + def calculate_registry_ranges(self, map : list[registry_map_entry], max_register : int, init : bool = False, timestamp: int = 0) -> list[tuple]: ''' read optimization; calculate which ranges to read''' max_batch_size = 45 #see manual; says max batch is 45 @@ -778,7 +778,10 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register start = -max_batch_size ranges : list[tuple] = [] - timestamp_ms = int(time.time() * 1000) + if timestamp > 0: + timestamp_ms = timestamp*1000 + else: + timestamp_ms = int(time.time() * 1000) while (start := start+max_batch_size) <= max_register: diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 3265b1e..6f43841 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -175,7 +175,9 @@ def read_data(self) -> dict[str, str]: continue #calculate ranges dynamically -- for variable read timing - ranges = self.protocolSettings.calculate_registry_ranges(self.protocolSettings.registry_map[registry_type], self.protocolSettings.registry_map_size[registry_type]) + ranges = self.protocolSettings.calculate_registry_ranges(self.protocolSettings.registry_map[registry_type], + self.protocolSettings.registry_map_size[registry_type], + timestamp=self.last_read_time) registry = self.read_modbus_registers(ranges=ranges, registry_type=registry_type) new_info = self.protocolSettings.process_registery(registry, self.protocolSettings.get_registry_map(registry_type)) From fdc8d08b030280ed3199dea026c084ecf8233977 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Thu, 27 Mar 2025 11:01:26 -0500 Subject: [PATCH 44/53] change init to exclude read timestamp changes --- classes/protocol_settings.py | 4 +++- classes/transports/modbus_base.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 07a0ea7..3b54910 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -796,7 +796,9 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register continue #we are assuming calc registry ranges is being called EVERY READ. - if init or register.next_read_timestamp < timestamp_ms: + if init: #add but do not update timestamp; can maybe rename init to no timestamp at this point + registers.append(register.register) + elif register.next_read_timestamp < timestamp_ms: register.next_read_timestamp = timestamp_ms + register.read_interval registers.append(register.register) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 6f43841..40ba928 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -446,7 +446,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type self._log.info(f"WRITE: {current_value} => {value} ( {registry[entry.register]} => {ushortValue} ) to Register {entry.register}") self.write_register(entry.register, ushortValue) - entry.next_read_timestamp = 0 #ensure is read next interval + #entry.next_read_timestamp = 0 #ensure is read next interval def read_variable(self, variable_name : str, registry_type : Registry_Type, entry : registry_map_entry = None): From 201a05b4b458c013a5156e385c700aa39a519476 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 31 Mar 2025 15:39:37 -0500 Subject: [PATCH 45/53] basic write support for 16bit and 8bit flags - UNTESTED --- classes/transports/modbus_base.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 40ba928..2f5b8be 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -392,8 +392,9 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type self._log.error(f"WRITE_ERROR: Invalid value in register '{current_value}'. Unsafe to write") #raise ValueError(err) - if not self.protocolSettings.validate_registry_entry(entry, value): - self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write") + if not (entry.data_type == Data_Type._16BIT_FLAGS or entry.data_type == Data_Type._8BIT_FLAGS or entry.data_type == Data_Type._32BIT_FLAGS): #skip validation for write; validate further down + if not self.protocolSettings.validate_registry_entry(entry, value): + self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write") #handle codes if entry.variable_name+"_codes" in self.protocolSettings.codes: @@ -438,6 +439,32 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if check_value != new_val: raise ValueError("something went wrong bitwise") + elif entry.data_type == Data_Type._16BIT_FLAGS or entry.data_type == Data_Type._8BIT_FLAGS or entry.data_type == Data_Type._32BIT_FLAGS: + #16 bit flags + flag_size : int = Data_Type.getSize(entry.data_type) + + if re.match(r"^[0-1]{"+flag_size+"}$", current_value): #bitflag string + #is string of 01... s + # Convert binary string to an integer + value = int(current_value, 2) + + # Ensure it fits within ushort range (0-65535) + if value > 65535: + return self._log.error(f"WRITE_ERROR: '{value}' Exceeds 65535. Unsafe to write") + else: + return self._log.error(f"WRITE_ERROR: Invalid new value for bitflags, '{value}'. Unsafe to write") + + #apply bitmasks + bit_index = entry.register_bit + bit_mask = ((1 << bit_size) - 1) << bit_index # Create a mask for extracting X bits starting from bit_index + clear_mask = ~(bit_mask) # Mask for clearing the bits to be updated + + # Clear the bits to be updated in the current_value + ushortValue = registry[entry.register] & clear_mask + + # Set the bits according to the new_value at the specified bit position + ushortValue |= (value << bit_index) & bit_mask + else: raise TypeError("Unsupported data type") From c420606f2376f9aa99c27913a0f13d6f39bfc0bb Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 31 Mar 2025 15:46:01 -0500 Subject: [PATCH 46/53] testing bitflag writing --- protocols/test.holding_registry_map.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index 7f2c9b6..f4b1a68 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -18,4 +18,4 @@ variable name,data type,writable,register,documented name,description,values,uni ,8bit,W,14,Time_Minute,,0-59,, ,8bit,W,14.b8,Time_Second,,0-59,, ,,W,21,decimal,,0-59,0.1, - +,8bit_flags,,22.b8,bit_flags,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, From 5af8eae6544af73f6144bc6aad8587b96a2a1d36 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 31 Mar 2025 15:51:46 -0500 Subject: [PATCH 47/53] Update test.holding_registry_map.csv --- protocols/test.holding_registry_map.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index f4b1a68..257051d 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -18,4 +18,4 @@ variable name,data type,writable,register,documented name,description,values,uni ,8bit,W,14,Time_Minute,,0-59,, ,8bit,W,14.b8,Time_Second,,0-59,, ,,W,21,decimal,,0-59,0.1, -,8bit_flags,,22.b8,bit_flags,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, +,8bit_flags,W,22.b8,bit_flags,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, From 8ba0cfa8c6fac3f1b5d1155b444e31a14fb1dcb6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 31 Mar 2025 16:12:11 -0500 Subject: [PATCH 48/53] debug and fix write bitflags, also fix offset bitflag reading --- classes/protocol_settings.py | 2 +- classes/transports/modbus_base.py | 7 ++++--- protocols/test.holding_registry_map.csv | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 3b54910..0f01d7b 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1049,7 +1049,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma for i in range(start_bit, end): # Iterate over each bit position (0 to 15) # Check if the i-th bit is set if (val >> i) & 1: - flag_index = "b"+str(i+offset) + flag_index = "b"+str(i+offset-start_bit) if flag_index in self.codes[entry.documented_name+"_codes"]: flags.append(self.codes[entry.documented_name+"_codes"][flag_index]) diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index 2f5b8be..bfde784 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -377,6 +377,7 @@ def evaluate_score(entry : registry_map_entry, val): def write_variable(self, entry : registry_map_entry, value : str, registry_type : Registry_Type = Registry_Type.HOLDING): """ writes a value to a ModBus register; todo: registry_type to handle other write functions""" + value = value.strip() temp_map = [entry] ranges = self.protocolSettings.calculate_registry_ranges(temp_map, self.protocolSettings.registry_map_size[registry_type], init=True) #init=True to bypass timechecks @@ -443,10 +444,10 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type #16 bit flags flag_size : int = Data_Type.getSize(entry.data_type) - if re.match(r"^[0-1]{"+flag_size+"}$", current_value): #bitflag string + if re.match(rf"^[0-1]{{{flag_size}}}$", value): #bitflag string #is string of 01... s # Convert binary string to an integer - value = int(current_value, 2) + value = int(value[::-1], 2) #reverse string # Ensure it fits within ushort range (0-65535) if value > 65535: @@ -456,7 +457,7 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type #apply bitmasks bit_index = entry.register_bit - bit_mask = ((1 << bit_size) - 1) << bit_index # Create a mask for extracting X bits starting from bit_index + bit_mask = ((1 << flag_size) - 1) << bit_index # Create a mask for extracting X bits starting from bit_index clear_mask = ~(bit_mask) # Mask for clearing the bits to be updated # Clear the bits to be updated in the current_value diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index 257051d..17cf9cf 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -15,7 +15,8 @@ variable name,data type,writable,register,documented name,description,values,uni ,8bit,W,12.b8,Time_Month,,1-12,, ,8bit,W,13,Time_Date,,1-31,, ,8bit,W,13.b8,Time_Hour,,0-23,, -,8bit,W,14,Time_Minute,,0-59,, +,8bit,W,14,Time_Minute,,0-59,, ,8bit,W,14.b8,Time_Second,,0-59,, ,,W,21,decimal,,0-59,0.1, -,8bit_flags,W,22.b8,bit_flags,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, +,8bit_flags,W,22,bit_flags1,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, +,8bit_flags,W,22.b8,bit_flags2,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, From 4cd0d409a18d294e5d3d90641737f1329a794a13 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 31 Mar 2025 16:29:41 -0500 Subject: [PATCH 49/53] improve error handling for write bit and test write single bit --- classes/protocol_settings.py | 2 +- classes/transports/modbus_base.py | 8 ++++---- protocols/test.holding_registry_map.csv | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 0f01d7b..fb2cb35 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1058,7 +1058,7 @@ def process_register_ushort(self, registry : dict[int, int], entry : registry_ma else: flags : list[str] = [] if end_bit > 0: - end : int = 16 if end_bit >= 16 else end_bit + end : int = 16 if end_bit >= 16 else end_bit for i in range(start_bit, end): # Iterate over each bit position (0 to 15) # Check if the i-th bit is set if (val >> i) & 1: diff --git a/classes/transports/modbus_base.py b/classes/transports/modbus_base.py index bfde784..d040746 100644 --- a/classes/transports/modbus_base.py +++ b/classes/transports/modbus_base.py @@ -390,12 +390,12 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type if not self.write_mode == TransportWriteMode.UNSAFE: if not self.protocolSettings.validate_registry_entry(entry, current_value): - self._log.error(f"WRITE_ERROR: Invalid value in register '{current_value}'. Unsafe to write") + return self._log.error(f"WRITE_ERROR: Invalid value in register '{current_value}'. Unsafe to write") #raise ValueError(err) if not (entry.data_type == Data_Type._16BIT_FLAGS or entry.data_type == Data_Type._8BIT_FLAGS or entry.data_type == Data_Type._32BIT_FLAGS): #skip validation for write; validate further down if not self.protocolSettings.validate_registry_entry(entry, value): - self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write") + return self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write") #handle codes if entry.variable_name+"_codes" in self.protocolSettings.codes: @@ -419,8 +419,8 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type bit_size = Data_Type.getSize(entry.data_type) new_val = int(value) - if 0 > new_val or new_val > 2**bit_size: - raise ValueError("Invalid value") + if 0 > new_val or new_val > (2**bit_size -1): # Calculate max value for n bits: 2^n - 1 + return self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Exceeds value range. Unsafe to write") bit_index = entry.register_bit bit_mask = ((1 << bit_size) - 1) << bit_index # Create a mask for extracting X bits starting from bit_index diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index 17cf9cf..6f2877b 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -20,3 +20,7 @@ variable name,data type,writable,register,documented name,description,values,uni ,,W,21,decimal,,0-59,0.1, ,8bit_flags,W,22,bit_flags1,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, ,8bit_flags,W,22.b8,bit_flags2,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, +,1bit,W,23.b4,1bit,,0~1,, +,1bit,W,23.b5,1bit_1,,0~1,, +,1bit,W,23.b6,1bit_2,,0~1,, +,1bit,W,23.b7,1bit_3,,0~1,, From 5b8d4eb682ba72dd979a3870fd09d928385f2c26 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 31 Mar 2025 17:05:41 -0500 Subject: [PATCH 50/53] more testing --- protocols/test.holding_registry_map.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/test.holding_registry_map.csv b/protocols/test.holding_registry_map.csv index 6f2877b..2cfd145 100644 --- a/protocols/test.holding_registry_map.csv +++ b/protocols/test.holding_registry_map.csv @@ -20,7 +20,7 @@ variable name,data type,writable,register,documented name,description,values,uni ,,W,21,decimal,,0-59,0.1, ,8bit_flags,W,22,bit_flags1,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, ,8bit_flags,W,22.b8,bit_flags2,,"{""b0"": ""bit 0"", ""b1"": ""bit 1"",""b2"": ""bit 2"",""b3"": ""bit 3"", ""b4"": ""bit 4"",""b5"": ""bit 5"", ""b6"": ""bit 6"", ""b7"": ""bit 7""}",, -,1bit,W,23.b4,1bit,,0~1,, +,1bit,W,23,1bit_0,,0~1,, ,1bit,W,23.b5,1bit_1,,0~1,, ,1bit,W,23.b6,1bit_2,,0~1,, ,1bit,W,23.b7,1bit_3,,0~1,, From fa4f17297f42dc99b5f1fd5b963546b80b79dfd6 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Mon, 31 Mar 2025 17:34:10 -0500 Subject: [PATCH 51/53] missing values entry --- protocols/eg4/eg4_v58.holding_registry_map.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/eg4/eg4_v58.holding_registry_map.csv b/protocols/eg4/eg4_v58.holding_registry_map.csv index 504f1cd..78bd3f5 100644 --- a/protocols/eg4/eg4_v58.holding_registry_map.csv +++ b/protocols/eg4/eg4_v58.holding_registry_map.csv @@ -147,7 +147,7 @@ variable name,data type,register,documented name,unit,values,writable,note,,,, ,1bit,110.b7,FunctionEn1_ BuzzerEn,,"{""0"": ""disable"", ""1"": ""enable""}",W,0-disable 1-enable,,,, ,2bit,110.b8,FunctionEn1_ PVCTSampleType,,"{""0"":""PV power"",""1"":""SpecLoad""}",W,0-PV power 1-SpecLoad,,,, ,1bit,110.b10,FunctionEn1_ TakeLoadTogether,,"{""0"": ""disable"", ""1"": ""enable""}",W,For off-grid: 0-disable 1- enable,,,, -,1bit,110.b11,FunctionEn1_ OnGridWorkingMode,,,W,For 12K: consistant chk mask 0- disable 1-enable 0-self consumption 1-Charge First,,,, +,1bit,110.b11,FunctionEn1_ OnGridWorkingMode,,0~1,W,For 12K: consistant chk mask 0- disable 1-enable 0-self consumption 1-Charge First,,,, ,2bit,110.b12,FunctionEn1_ PVCTSampleRatio,,"{""0"":""1/1000"",""1"":""1/3000""}",W,0 : 1/1000 1- 1/3000,,,, ,1bit,110.b14,FunctionEn1_GreenModeEn,,"{""0"": ""disable"", ""1"": ""enable""}",W,0-disable 1- enable,,,, ,1bit,110.b15,FunctionEn1_EcoModeEn,,"{""0"": ""disable"", ""1"": ""enable""}",W,0-disable 1- enable,,,, From b2b5d15bbcb834b70eb84e16b4ef1ef3e9cb5bc3 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sun, 13 Apr 2025 12:44:54 -0500 Subject: [PATCH 52/53] fix --- classes/transports/canbus.py | 2 +- classes/transports/serial_pylon.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/transports/canbus.py b/classes/transports/canbus.py index ca724d6..7bc1a62 100644 --- a/classes/transports/canbus.py +++ b/classes/transports/canbus.py @@ -56,7 +56,7 @@ class canbus(transport_base): def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_settings" = None): - super().__init__(settings, protocolSettings=protocolSettings) + super().__init__(settings) #check if running on windows or linux self.linux = platform.system() != "Windows" diff --git a/classes/transports/serial_pylon.py b/classes/transports/serial_pylon.py index 33cd011..fe42ef9 100644 --- a/classes/transports/serial_pylon.py +++ b/classes/transports/serial_pylon.py @@ -58,7 +58,7 @@ class serial_pylon(transport_base): EOI : bytes = b"\x0d" # aka b"\r" def __init__(self, settings : "SectionProxy", protocolSettings : "protocol_settings" = None): - super().__init__(settings, protocolSettings=protocolSettings) + super().__init__(settings) '''address is required to be specified ''' self.port = settings.get("port", "") if not self.port: From 6359d67cd0767227c6f5c403e4f3a871bbf22475 Mon Sep 17 00:00:00 2001 From: Julian Eder Date: Sun, 25 May 2025 00:19:45 +0200 Subject: [PATCH 53/53] fix dockerfile --- Dockerfile | 3 +-- README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1dcb260..92598e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,11 +7,10 @@ RUN pip install --prefix=/install -r /requirements.txt FROM base COPY --from=builder /install /usr/local -COPY protocol_settings.py /app/ COPY protocol_gateway.py /app/ -COPY inverter.py /app/ COPY config.cfg /app/ COPY defs/ /app/defs/ COPY classes /app/classes/ +COPY protocols /app/protocols/ WORKDIR /app CMD ["python3", "protocol_gateway.py"] diff --git a/README.md b/README.md index c25a622..8549120 100644 --- a/README.md +++ b/README.md @@ -159,5 +159,5 @@ donations would be appreciated. ```(btc) bc1qh394vazcguedkw2rlklnuhapdq7qgpnnz9c3t0``` ### Use Docker - untested -- ```docker build -t protocol_gateway ``` +- ```docker build . -t protocol_gateway ``` - ```docker run --device=/dev/ttyUSB0 protocol_gateway```