Scaled writing reg works, sample usage
This commit is contained in:
parent
10e03f927d
commit
5de47d78b0
3 changed files with 99 additions and 25 deletions
|
@ -6,7 +6,7 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from pymodbus.constants import Endian
|
from pymodbus.constants import Endian
|
||||||
from pymodbus.payload import BinaryPayloadDecoder
|
from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
|
||||||
#from pymodbus.client.tcp import ModbusTcpClient as ModbusClient
|
#from pymodbus.client.tcp import ModbusTcpClient as ModbusClient
|
||||||
#from pymodbus.diag_message import *
|
#from pymodbus.diag_message import *
|
||||||
#from pymodbus.file_message import *
|
#from pymodbus.file_message import *
|
||||||
|
@ -65,6 +65,35 @@ class DataType(Enum):
|
||||||
else:
|
else:
|
||||||
return str(decoder.decode_bits())
|
return str(decoder.decode_bits())
|
||||||
|
|
||||||
|
def encode(self, value):
|
||||||
|
encoder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)
|
||||||
|
|
||||||
|
if (self == DataType.String8) or (self == DataType.String16) or (self == DataType.String32):
|
||||||
|
return encoder.add_string(value).build()
|
||||||
|
|
||||||
|
elif (self == DataType.Int16):
|
||||||
|
encoder.add_16bit_int(int(value))
|
||||||
|
return encoder.build()
|
||||||
|
# return int(value)
|
||||||
|
|
||||||
|
elif (self == DataType.UInt16):
|
||||||
|
encoder.add_16bit_uint(int(value))
|
||||||
|
return encoder.build()
|
||||||
|
|
||||||
|
elif (self == DataType.Int32):
|
||||||
|
return encoder.add_32bit_int(value).build()
|
||||||
|
|
||||||
|
elif (self == DataType.UInt32):
|
||||||
|
return encoder.add_32bit_uint(value).build()
|
||||||
|
|
||||||
|
elif (self == DataType.Float32):
|
||||||
|
return encoder.add_32bit_float(value).build()
|
||||||
|
|
||||||
|
else:
|
||||||
|
return encoder.add_bits(value).build()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class registerReadError(Exception):
|
class registerReadError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -78,8 +107,8 @@ class FroniusReg:
|
||||||
def getValue(self, modbusClient):
|
def getValue(self, modbusClient):
|
||||||
return self.__getRegisterValue(modbusClient)
|
return self.__getRegisterValue(modbusClient)
|
||||||
|
|
||||||
def setValue(self, modbusClient):
|
def setValue(self, modbusClient, value):
|
||||||
return self.__setRegisterValue(modbusClient)
|
return self.__setRegisterValue(modbusClient, value)
|
||||||
|
|
||||||
def __getRegisterValue(self, modbusClient):
|
def __getRegisterValue(self, modbusClient):
|
||||||
modbusValue = modbusClient.read_holding_registers(self.address-1,
|
modbusValue = modbusClient.read_holding_registers(self.address-1,
|
||||||
|
@ -91,10 +120,12 @@ class FroniusReg:
|
||||||
raise registerReadError("It's NONE!")
|
raise registerReadError("It's NONE!")
|
||||||
return self.datatype.decode(modbusValue)
|
return self.datatype.decode(modbusValue)
|
||||||
|
|
||||||
def __setRegisterValue(self, modbusClient):
|
def __setRegisterValue(self, modbusClient, value):
|
||||||
modbusValue = modbusClient.write_holding_registers(self.address-1,
|
modbusValue = modbusClient.write_registers(self.address-1,
|
||||||
self.datatype.getRegisterLength(),
|
self.datatype.encode(value),
|
||||||
slave=self.unit)
|
count=self.datatype.getRegisterLength(),
|
||||||
|
slave=self.unit,
|
||||||
|
skip_encode=True)
|
||||||
return modbusValue
|
return modbusValue
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,18 +137,38 @@ class ScaledFroniusReg:
|
||||||
def getValue(self, modbusClient):
|
def getValue(self, modbusClient):
|
||||||
return self.valueReg.getValue(modbusClient) * 10 ** self.scaleReg.getValue(modbusClient)
|
return self.valueReg.getValue(modbusClient) * 10 ** self.scaleReg.getValue(modbusClient)
|
||||||
|
|
||||||
def setValue(self, modbusClient):
|
def setValue(self, modbusClient, value):
|
||||||
return self.valueReg.setValue(modbusClient, self.scaleReg.getValue(modbusClient))
|
return self.valueReg.setValue(modbusClient, value / 10 ** self.scaleReg.getValue(modbusClient))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MaxChaRte = FroniusReg(40155, DataType.UInt16, 1, "Max Charge Rate")
|
||||||
|
MaxChaRte_SF = FroniusReg(40156, DataType.Int16, 1, "Max Charge Rate SF")
|
||||||
|
|
||||||
|
wChaGra = FroniusReg(40357, DataType.UInt16, 1, "Max Charge Power")
|
||||||
storageStateOfCharge = FroniusReg(40362, DataType.UInt16, 1, "Storage State of Charge")
|
storageStateOfCharge = FroniusReg(40362, DataType.UInt16, 1, "Storage State of Charge")
|
||||||
storageStateOfChargeSF = FroniusReg(40376, DataType.Int16, 1, "Storage State of Charge Scaling Factor")
|
storageStateOfChargeSF = FroniusReg(40376, DataType.Int16, 1, "Storage State of Charge Scaling Factor")
|
||||||
scaledStateOfCharge = ScaledFroniusReg(storageStateOfCharge, storageStateOfChargeSF)
|
scaledStateOfCharge = ScaledFroniusReg(storageStateOfCharge, storageStateOfChargeSF)
|
||||||
|
|
||||||
OutWRte = FroniusReg(40367, DataType.Int16, 1, "DischargeRate, Negative means Charging")
|
OutWRte = FroniusReg(40366, DataType.Int16, 1, "DischargeRate")
|
||||||
|
InWRte = FroniusReg(40367, DataType.Int16, 1, "ChargeRate")
|
||||||
WRteSF = FroniusReg(40379, DataType.Int16, 1, "ScalingFactor for storage Watts")
|
WRteSF = FroniusReg(40379, DataType.Int16, 1, "ScalingFactor for storage Watts")
|
||||||
|
|
||||||
scaledDischarge = ScaledFroniusReg(OutWRte, WRteSF)
|
StorCtl_Mode = FroniusReg(40359, DataType.UInt16, 1, "Hold/Charge/Discharge enable")
|
||||||
|
MinRsvPct = FroniusReg(40361, DataType.UInt16, 1, "Reserve Percentage")
|
||||||
|
|
||||||
|
InOutWRte_RvrtTms = FroniusReg(40369, DataType.UInt16, 1, "Revert timer for charge settings")
|
||||||
|
|
||||||
|
ChaGriSet = FroniusReg(40371, DataType.UInt16, 1, "enum16, 0 = PV only, 1 = Grid enabled")
|
||||||
|
WChaDisChaGra_SF = FroniusReg(40373, DataType.Int16, 1, "Charge/Discharge Power SF")
|
||||||
|
|
||||||
|
MinRsvPct_SF = FroniusReg(40375, DataType.Int16, 1, "Reserve Percentage Scaling")
|
||||||
|
|
||||||
|
scaledOutWRte = ScaledFroniusReg(OutWRte, WRteSF)
|
||||||
|
scaledInWRte = ScaledFroniusReg(InWRte, WRteSF)
|
||||||
|
scaledReserve = ScaledFroniusReg(MinRsvPct, MinRsvPct_SF)
|
||||||
|
|
||||||
|
scaledMaxChaRte = ScaledFroniusReg(MaxChaRte, MaxChaRte_SF)
|
||||||
|
|
||||||
|
scaledMaxWChaGra = ScaledFroniusReg(wChaGra, WChaDisChaGra_SF)
|
||||||
|
|
14
SoCtest.py
14
SoCtest.py
|
@ -1,14 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import FroniusReg
|
|
||||||
|
|
||||||
from pymodbus.client.tcp import ModbusTcpClient
|
|
||||||
|
|
||||||
fronius1 = ModbusTcpClient("172.19.107.211", port=502, timeout=10)
|
|
||||||
fronius1.connect()
|
|
||||||
|
|
||||||
soc = FroniusReg.scaledStateOfCharge.getValue(fronius1)
|
|
||||||
print(" SOC: %s%%" % soc)
|
|
||||||
|
|
||||||
discharge = FroniusReg.scaledDischarge.getValue(fronius1)
|
|
||||||
print(" Rate: %dW" % discharge)
|
|
37
force_charge.py
Executable file
37
force_charge.py
Executable file
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import FroniusReg
|
||||||
|
|
||||||
|
from pymodbus.client.tcp import ModbusTcpClient
|
||||||
|
|
||||||
|
fronius1 = ModbusTcpClient("172.19.107.211", port=502, timeout=10)
|
||||||
|
fronius1.connect()
|
||||||
|
|
||||||
|
soc = FroniusReg.scaledStateOfCharge.getValue(fronius1)
|
||||||
|
print(" SOC: %s%%" % soc)
|
||||||
|
|
||||||
|
discharge = FroniusReg.scaledOutWRte.getValue(fronius1)
|
||||||
|
print("Pre DRate: %d%%" % discharge)
|
||||||
|
|
||||||
|
charge = FroniusReg.scaledInWRte.getValue(fronius1)
|
||||||
|
print("Pre CRate: %d%%" % charge)
|
||||||
|
|
||||||
|
mode = FroniusReg.StorCtl_Mode.getValue(fronius1)
|
||||||
|
print("Pre Mode: %d" % mode)
|
||||||
|
|
||||||
|
# This should be 'limit discharge' mode
|
||||||
|
err = FroniusReg.StorCtl_Mode.setValue(fronius1, 2)
|
||||||
|
# Charge battery at a rate from -2% discharge to 100% charge
|
||||||
|
# as a percentage of the MaxChaRte, which in our case is 25600W
|
||||||
|
err = FroniusReg.scaledOutWRte.setValue(fronius1, -10)
|
||||||
|
err = FroniusReg.scaledInWRte.setValue(fronius1, 100)
|
||||||
|
|
||||||
|
discharge = FroniusReg.scaledOutWRte.getValue(fronius1)
|
||||||
|
print("Post DRate: %d%%" % discharge)
|
||||||
|
|
||||||
|
charge = FroniusReg.scaledInWRte.getValue(fronius1)
|
||||||
|
print("Post CRate: %d%%" % charge)
|
||||||
|
|
||||||
|
mode = FroniusReg.StorCtl_Mode.getValue(fronius1)
|
||||||
|
print("Post Mode: %d" % mode)
|
||||||
|
|
Loading…
Reference in a new issue