Skip to content

Commit

Permalink
Standardize registers on W for all that don't have kW in their name, …
Browse files Browse the repository at this point in the history
…add disconnect method (#19)

Co-authored-by: @daniel309
  • Loading branch information
daniel309 authored Mar 11, 2023
1 parent f9a49b4 commit 7fcb1b1
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 59 deletions.
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| ModelID | Number | 1 | | |
| NumberOfPVStrings | Number | 1 | | |
| NumberOfMPPTrackers | Number | 1 | | |
| RatedPower | Number | 1000 | kW | |
| MaximumActivePower | Number | 1000 | kW | |
| RatedPower | Number | 1 | W | |
| MaximumActivePower | Number | 1 | W | |
| MaximumApparentPower | Number | 1000 | kVA | |
| MaximumReactivePowerFedToTheGrid | Number | 1000 | kvar | |
| MaximumReactivePowerAbsorbedFromTheGrid | Number | 1000 | kvar | |
Expand All @@ -99,7 +99,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| PV3Current | Number | 100 | A | |
| PV4Voltage | Number | 10 | V | |
| PV4Current | Number | 100 | A | |
| InputPower | Number | 1000 | kW | |
| InputPower | Number | 1 | W | |
| LineVoltageBetweenPhasesAAndB | Number | 10 | V | |
| LineVoltageBetweenPhasesBAndC | Number | 10 | V | |
| LineVoltageBetweenPhasesCAndA | Number | 10 | V | |
Expand All @@ -109,8 +109,8 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| PhaseACurrent | Number | 1000 | A | |
| PhaseBCurrent | Number | 1000 | A | |
| PhaseCCurrent | Number | 1000 | A | |
| PeakActivePowerOfCurrentDay | Number | 1000 | kW | |
| ActivePower | Number | 1000 | kW | |
| PeakActivePowerOfCurrentDay | Number | 1 | W | |
| ActivePower | Number | 1 | W | |
| ReactivePower | Number | 1000 | kvar | |
| PowerFactor | Number | 1000 | | |
| GridFrequency | Number | 100 | Hz | |
Expand Down Expand Up @@ -183,17 +183,17 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| GridChargeCutoffSOC | Number | 10 | % | |
| ForcibleChargeDischarge | Number | 1 | | Write only, not available for read |
| FixedChargingAndDischargingPeriods | Bytestring | | | |
| PowerOfChargeFromGrid | Number | 100 | kW | |
| MaximumPowerOfChargeFromGrid | Number | 100 | kW | |
| PowerOfChargeFromGrid | Number | 0.1 | W | |
| MaximumPowerOfChargeFromGrid | Number | 0.1 | W | |
| ForcibleChargeDischargeSettingMode | Number | 1 | | |
| ForcibleChargePower | Number | 100 | kW | |
| ForcibleDischargePower | Number | 100 | kW | |
| ForcibleChargePower | Number | 0.1 | W | |
| ForcibleDischargePower | Number | 0.1 | W | |
| TimeOfUseChargingAndDischargingPeriods | Bytestring | | | |
| ExcessPVEnergyUseInTOU | Number | 1 | | |
| ActivePowerControlMode | Number | 1 | | |
| MaximumFeedGridPowerInKW | Number | 1000 | kW | |
| MaximumFeedGridPowerInPercentage | Number | 10 | % | |
| MaximumChargeFromGridPower | Number | 100 | kW | |
| MaximumChargeFromGridPower | Number | 0.1 | W | |
| SwitchToOffGrid | Number | 1 | | |
| VoltageInIndependentOperation | Number | 1 | | |
| Unit1ProductModel | Number | 1 | | |
Expand Down Expand Up @@ -238,7 +238,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit1BatteryPack1Voltage | Number | 10 | V | |
| Unit1BatteryPack1Current | Number | 10 | A | |
| Unit1BatteryPack1SOC | Number | 10 | % | |
| Unit1BatteryPack1ChargeDischargePower | Number | 100 | kW | |
| Unit1BatteryPack1ChargeDischargePower | Number | 0.1 | W | |
| Unit1BatteryPack1TotalCharge | Number | 100 | kWh | |
| Unit1BatteryPack1TotalDischarge | Number | 100 | kWh | |
| Unit1BatteryPack1MinimumTemperature | Number | 10 | °C | |
Expand All @@ -250,7 +250,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit1BatteryPack2Voltage | Number | 10 | V | |
| Unit1BatteryPack2Current | Number | 10 | A | |
| Unit1BatteryPack2SOC | Number | 10 | % | |
| Unit1BatteryPack2ChargeDischargePower | Number | 100 | kW | |
| Unit1BatteryPack2ChargeDischargePower | Number | 0.1 | W | |
| Unit1BatteryPack2TotalCharge | Number | 100 | kWh | |
| Unit1BatteryPack2TotalDischarge | Number | 100 | kWh | |
| Unit1BatteryPack2MinimumTemperature | Number | 10 | °C | |
Expand All @@ -262,7 +262,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit1BatteryPack3Voltage | Number | 10 | V | |
| Unit1BatteryPack3Current | Number | 10 | A | |
| Unit1BatteryPack3SOC | Number | 10 | % | |
| Unit1BatteryPack3ChargeDischargeStatus | Number | 100 | kW | |
| Unit1BatteryPack3ChargeDischargeStatus | Number | 0.1 | W | |
| Unit1BatteryPack3TotalCharge | Number | 100 | kWh | |
| Unit1BatteryPack3TotalDischarge | Number | 100 | kWh | |
| Unit1BatteryPack3MinimumTemperature | Number | 10 | °C | |
Expand All @@ -274,7 +274,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit2BatteryPack1Voltage | Number | 10 | V | |
| Unit2BatteryPack1Current | Number | 10 | A | |
| Unit2BatteryPack1SOC | Number | 10 | % | |
| Unit2BatteryPack1ChargeDischargePower | Number | 100 | kW | |
| Unit2BatteryPack1ChargeDischargePower | Number | 0.1 | W | |
| Unit2BatteryPack1TotalCharge | Number | 100 | kWh | |
| Unit2BatteryPack1TotalDischarge | Number | 100 | kWh | |
| Unit2BatteryPack1MinimumTemperature | Number | 10 | °C | |
Expand All @@ -286,7 +286,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit2BatteryPack2Voltage | Number | 10 | V | |
| Unit2BatteryPack2Current | Number | 10 | A | |
| Unit2BatteryPack2SOC | Number | 10 | % | |
| Unit2BatteryPack2ChargeDischargePower | Number | 100 | kW | |
| Unit2BatteryPack2ChargeDischargePower | Number | 0.1 | W | |
| Unit2BatteryPack2TotalCharge | Number | 100 | kWh | |
| Unit2BatteryPack2TotalDischarge | Number | 100 | kWh | |
| Unit2BatteryPack2MinimumTemperature | Number | 10 | °C | |
Expand All @@ -298,7 +298,7 @@ The following registers are provided by the Sun2000's Modbus interface and can b
| Unit2BatteryPack3Voltage | Number | 10 | V | |
| Unit2BatteryPack3Current | Number | 10 | A | |
| Unit2BatteryPack3SOC | Number | 10 | % | |
| Unit2BatteryPack3ChargeDischargePower | Number | 100 | kW | |
| Unit2BatteryPack3ChargeDischargePower | Number | 0.1 | W | |
| Unit2BatteryPack3TotalCharge | Number | 100 | kWh | |
| Unit2BatteryPack3TotalDischarge | Number | 100 | kWh | |
| Unit2BatteryPack3MinimumTemperature | Number | 10 | °C | |
Expand Down
31 changes: 19 additions & 12 deletions sun2000_modbus/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,44 @@


class Sun2000:
def __init__(self, host, port=502, timeout=5, wait=2, unit=0):
def __init__(self, host, port=502, timeout=5, wait=2, unit=0): # some models need unit=1
self.wait = wait
self.connected = False
self.unit = unit
self.inverter = ModbusTcpClient(host, port, timeout=timeout)

def connect(self):
if not self.connected:
self.connected = self.inverter.connect()
if not self.isConnected():
self.inverter.connect()
time.sleep(self.wait)
if self.connected:
if self.isConnected():
logging.info('Successfully connected to inverter')
return True
else:
logging.error('Connection to inverter failed')
return False

def disconnect(self):
"""Close the underlying tcp socket"""
# Some Sun2000 models with the SDongle WLAN-FE require the TCP connection to be closed
# as soon as possible. Leaving the TCP connection open for an extended time may cause
# dongle reboots and/or FusionSolar portal updates to be delayed or even paused.
self.inverter.close()

def isConnected(self):
"""Check if underlying tcp socket is open"""
return self.inverter.is_socket_open()

def read_raw_value(self, register):
if not self.connected:
if not self.isConnected():
raise ValueError('Inverter is not connected')

try:
register_value = self.inverter.read_holding_registers(register.value.address, register.value.quantity, unit=self.unit)
if type(register_value) == ModbusIOException:
logging.error("Inverter unit did not respond")
self.connected = False
raise register_value
except ConnectionException:
logging.error("A connection error occurred")
self.connected = False
raise

return datatypes.decode(register_value.encode()[1:], register.value.data_type)
Expand Down Expand Up @@ -68,8 +78,7 @@ def read_range(self, start_address, quantity=0, end_address=0):
if end_address != 0 and end_address <= start_address:
raise ValueError("end_address must be greater than start_address")

if not self.connected:
self.connected = False
if not self.isConnected():
raise ValueError('Inverter is not connected')

if end_address != 0:
Expand All @@ -78,11 +87,9 @@ def read_range(self, start_address, quantity=0, end_address=0):
register_range_value = self.inverter.read_holding_registers(start_address, quantity, unit=self.unit)
if type(register_range_value) == ModbusIOException:
logging.error("Inverter unit did not respond")
self.connected = False
raise register_range_value
except ConnectionException:
logging.error("A connection error occurred")
self.connected = False
raise

return datatypes.decode(register_range_value.encode()[1:], datatypes.DataType.MULTIDATA)
Loading

0 comments on commit 7fcb1b1

Please sign in to comment.