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 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.diag_message import *
|
||||
#from pymodbus.file_message import *
|
||||
|
@ -65,6 +65,35 @@ class DataType(Enum):
|
|||
else:
|
||||
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):
|
||||
pass
|
||||
|
||||
|
@ -78,8 +107,8 @@ class FroniusReg:
|
|||
def getValue(self, modbusClient):
|
||||
return self.__getRegisterValue(modbusClient)
|
||||
|
||||
def setValue(self, modbusClient):
|
||||
return self.__setRegisterValue(modbusClient)
|
||||
def setValue(self, modbusClient, value):
|
||||
return self.__setRegisterValue(modbusClient, value)
|
||||
|
||||
def __getRegisterValue(self, modbusClient):
|
||||
modbusValue = modbusClient.read_holding_registers(self.address-1,
|
||||
|
@ -91,10 +120,12 @@ class FroniusReg:
|
|||
raise registerReadError("It's NONE!")
|
||||
return self.datatype.decode(modbusValue)
|
||||
|
||||
def __setRegisterValue(self, modbusClient):
|
||||
modbusValue = modbusClient.write_holding_registers(self.address-1,
|
||||
self.datatype.getRegisterLength(),
|
||||
slave=self.unit)
|
||||
def __setRegisterValue(self, modbusClient, value):
|
||||
modbusValue = modbusClient.write_registers(self.address-1,
|
||||
self.datatype.encode(value),
|
||||
count=self.datatype.getRegisterLength(),
|
||||
slave=self.unit,
|
||||
skip_encode=True)
|
||||
return modbusValue
|
||||
|
||||
|
||||
|
@ -106,18 +137,38 @@ class ScaledFroniusReg:
|
|||
def getValue(self, modbusClient):
|
||||
return self.valueReg.getValue(modbusClient) * 10 ** self.scaleReg.getValue(modbusClient)
|
||||
|
||||
def setValue(self, modbusClient):
|
||||
return self.valueReg.setValue(modbusClient, self.scaleReg.getValue(modbusClient))
|
||||
def setValue(self, modbusClient, value):
|
||||
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")
|
||||
storageStateOfChargeSF = FroniusReg(40376, DataType.Int16, 1, "Storage State of Charge Scaling Factor")
|
||||
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")
|
||||
|
||||
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