Added ESS Battery Life SoC Limit (GX >= 2.80 ONLY !)
Added modbus retry (2 times max) if there is an error during decode of message (this can be rare but) Refactor the code using the modbus function Added string converted data from Average() class Commented the Max Class since it is not used in this module Bumped version
This commit is contained in:
@ -7,7 +7,7 @@ Requirements:
|
|||||||
2. pymodbus AND pymodbusTCP
|
2. pymodbus AND pymodbusTCP
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
<plugin key="VictronEnergy_MultiplusII" name="Victron Energy Multiplus II + Modbus" author="Xavier Beaudouin" version="0.0.1" externallink="https://github.com/xbeaudouin/victron-energy-domoticz/mppt">
|
<plugin key="VictronEnergy_MultiplusII" name="Victron Energy Multiplus II + Modbus" author="Xavier Beaudouin" version="0.0.2" externallink="https://github.com/xbeaudouin/victron-energy-domoticz/mppt">
|
||||||
<params>
|
<params>
|
||||||
<param field="Address" label="GX IP Address" width="150px" required="true" />
|
<param field="Address" label="GX IP Address" width="150px" required="true" />
|
||||||
<param field="Port" label="GX Modbus Port Number" width="100px" required="true" default="502" />
|
<param field="Port" label="GX Modbus Port Number" width="100px" required="true" default="502" />
|
||||||
@ -70,6 +70,10 @@ class Average:
|
|||||||
def get(self):
|
def get(self):
|
||||||
return sum(self.samples) / len(self.samples)
|
return sum(self.samples) / len(self.samples)
|
||||||
|
|
||||||
|
def strget(self):
|
||||||
|
return str(sum(self.samples) / len(self.samples))
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Domoticz shows graphs with intervals of 5 minutes.
|
# Domoticz shows graphs with intervals of 5 minutes.
|
||||||
# When collecting information from the inverter more frequently than that, then it makes no sense to only show the last value.
|
# When collecting information from the inverter more frequently than that, then it makes no sense to only show the last value.
|
||||||
@ -78,30 +82,29 @@ class Average:
|
|||||||
# The number of samples stored depends on the interval used to collect the value from the inverter itself.
|
# The number of samples stored depends on the interval used to collect the value from the inverter itself.
|
||||||
#
|
#
|
||||||
|
|
||||||
class Maximum:
|
#class Maximum:
|
||||||
|
#
|
||||||
def __init__(self):
|
# def __init__(self):
|
||||||
self.samples = []
|
# self.samples = []
|
||||||
self.max_samples = 30
|
# self.max_samples = 30
|
||||||
|
#
|
||||||
def set_max_samples(self, max):
|
# def set_max_samples(self, max):
|
||||||
self.max_samples = max
|
# self.max_samples = max
|
||||||
if self.max_samples < 1:
|
# if self.max_samples < 1:
|
||||||
self.max_samples = 1
|
# self.max_samples = 1
|
||||||
|
#
|
||||||
def update(self, new_value, scale = 0):
|
# def update(self, new_value, scale = 0):
|
||||||
self.samples.append(new_value * (10 ** scale))
|
# self.samples.append(new_value * (10 ** scale))
|
||||||
while (len(self.samples) > self.max_samples):
|
# while (len(self.samples) > self.max_samples):
|
||||||
del self.samples[0]
|
# del self.samples[0]
|
||||||
|
#
|
||||||
Domoticz.Debug("Maximum: {} - {} values".format(self.get(), len(self.samples)))
|
# Domoticz.Debug("Maximum: {} - {} values".format(self.get(), len(self.samples)))
|
||||||
|
#
|
||||||
def get(self):
|
# def get(self):
|
||||||
return max(self.samples)
|
# return max(self.samples)
|
||||||
|
|
||||||
# Plugin itself
|
# Plugin itself
|
||||||
class BasePlugin:
|
class BasePlugin:
|
||||||
#enabled = False
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# AC IN Voltage for last 5 minutes
|
# AC IN Voltage for last 5 minutes
|
||||||
self.acInVoltage=Average()
|
self.acInVoltage=Average()
|
||||||
@ -170,7 +173,6 @@ class BasePlugin:
|
|||||||
Domoticz.Debug("Query IP " + self.IPAddress + ":" + str(self.IPPort) +" on GX device : "+str(self.MBAddr)+" Multi Device : "+str(self.MultiAddr)+" and Battery : "+str(self.BattAddr))
|
Domoticz.Debug("Query IP " + self.IPAddress + ":" + str(self.IPPort) +" on GX device : "+str(self.MBAddr)+" Multi Device : "+str(self.MultiAddr)+" and Battery : "+str(self.BattAddr))
|
||||||
|
|
||||||
# Create the devices if they does not exists
|
# Create the devices if they does not exists
|
||||||
# TODO: refactor this.
|
|
||||||
# Multiplus Devices
|
# Multiplus Devices
|
||||||
if 1 not in Devices:
|
if 1 not in Devices:
|
||||||
Domoticz.Device(Name="Voltage IN L1", Unit=1, TypeName="Voltage", Used=0).Create()
|
Domoticz.Device(Name="Voltage IN L1", Unit=1, TypeName="Voltage", Used=0).Create()
|
||||||
@ -222,6 +224,8 @@ class BasePlugin:
|
|||||||
Domoticz.Device(Name="Battery Power", Unit=33, TypeName="Custom", Used=0, Options=Options).Create()
|
Domoticz.Device(Name="Battery Power", Unit=33, TypeName="Custom", Used=0, Options=Options).Create()
|
||||||
if 34 not in Devices:
|
if 34 not in Devices:
|
||||||
Domoticz.Device(Name="ESS Battery Life State", Unit=34, TypeName="Text", Used=0).Create()
|
Domoticz.Device(Name="ESS Battery Life State", Unit=34, TypeName="Text", Used=0).Create()
|
||||||
|
if 35 not in Devices:
|
||||||
|
Domoticz.Device(Name="ESS Battery Life SoC Limit", Unit=35, TypeName="Percentage", Used=0).Create()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -229,22 +233,6 @@ class BasePlugin:
|
|||||||
def onStop(self):
|
def onStop(self):
|
||||||
Domoticz.Debugging(0)
|
Domoticz.Debugging(0)
|
||||||
|
|
||||||
def onConnect(self, Connection, Status, Description):
|
|
||||||
Domoticz.Log("onConnect called")
|
|
||||||
return
|
|
||||||
|
|
||||||
def onMessage(self, Connection, Data):
|
|
||||||
Domoticz.Log("onMessage called")
|
|
||||||
|
|
||||||
def onCommand(self, Unit, Command, Level, Hue):
|
|
||||||
Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
|
|
||||||
|
|
||||||
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
|
|
||||||
Domoticz.Log("Notification: " + Name + "," + Subject + "," + Text + "," + Status + "," + str(Priority) + "," + Sound + "," + ImageFile)
|
|
||||||
|
|
||||||
def onDisconnect(self, Connection):
|
|
||||||
Domoticz.Log("onDisconnect called")
|
|
||||||
|
|
||||||
def onHeartbeat(self):
|
def onHeartbeat(self):
|
||||||
|
|
||||||
# Multiplus devices
|
# Multiplus devices
|
||||||
@ -266,138 +254,39 @@ class BasePlugin:
|
|||||||
Devices[10].Update(1, "0")
|
Devices[10].Update(1, "0")
|
||||||
|
|
||||||
# Ac In Voltage
|
# Ac In Voltage
|
||||||
data = client.read_holding_registers(3, 1)
|
self.acInVoltage.update(round(getmodbus16(3, client)/10.0, 3))
|
||||||
Domoticz.Debug("Data from register 3: "+str(data))
|
Devices[1].Update(1, self.acInVoltage.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acInVoltage.update(value)
|
|
||||||
value = self.acInVoltage.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[1].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac In Current
|
# Ac In Current
|
||||||
data = client.read_holding_registers(6, 1)
|
self.acInCurrent.update(round(getmodbus16(6, client)/10.0, 3))
|
||||||
Domoticz.Debug("Data from register 6: "+str(data))
|
Devices[2].Update(1, self.acInCurrent.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acInCurrent.update(value)
|
|
||||||
value = self.acInCurrent.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[2].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac In Power
|
# Ac In Power
|
||||||
data = client.read_holding_registers(12, 1)
|
self.acInPower.update(round(getmodbus16(12, client)/0.1, 3))
|
||||||
Domoticz.Debug("Data from register 12: "+str(data))
|
Devices[3].Update(1, self.acInPower.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 0.1
|
|
||||||
value = round (value / 0.1, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acInPower.update(value)
|
|
||||||
value = self.acInPower.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[3].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac In Frequency
|
# Ac In Frequency
|
||||||
data = client.read_holding_registers(9, 1)
|
self.acInFrequency.update(round(getmodbus16(9, client)/100.0, 3))
|
||||||
Domoticz.Debug("Data from register 9: "+str(data))
|
Devices[4].Update(1, self.acInFrequency.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acInFrequency.update(value)
|
|
||||||
value = self.acInFrequency.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[4].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac Out Voltage
|
# Ac Out Voltage
|
||||||
data = client.read_holding_registers(15, 1)
|
self.acOutVoltage.update(round(getmodbus16(15, client)/10.0, 3))
|
||||||
Domoticz.Debug("Data from register 15: "+str(data))
|
Devices[5].Update(1, self.acOutVoltage.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acOutVoltage.update(value)
|
|
||||||
value = self.acOutVoltage.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[5].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac Out Current
|
# Ac Out Current
|
||||||
data = client.read_holding_registers(18, 1)
|
self.acOutCurrent.update(round(getmodbus16(18, client)/10.0, 3))
|
||||||
Domoticz.Debug("Data from register 18: "+str(data))
|
Devices[6].Update(1, self.acOutCurrent.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acOutCurrent.update(value)
|
|
||||||
value = self.acOutCurrent.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[6].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac Out Power
|
# Ac Out Power
|
||||||
data = client.read_holding_registers(23, 1)
|
self.acOutPower.update(round(getmodbus16(23, client)/0.1, 3))
|
||||||
Domoticz.Debug("Data from register 23: "+str(data))
|
Devices[7].Update(1, self.acOutPower.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 0.1
|
|
||||||
value = round (value / 0.1, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acOutPower.update(value)
|
|
||||||
value = self.acOutPower.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[7].Update(1, str(value))
|
|
||||||
|
|
||||||
# Ac Out Frequency
|
# Ac Out Frequency
|
||||||
data = client.read_holding_registers(21, 1)
|
self.acOutFrequency.update(round(getmodbus16(21, client)/100.0, 3))
|
||||||
Domoticz.Debug("Data from register 21: "+str(data))
|
Devices[8].Update(1, self.acOutFrequency.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.acOutFrequency.update(value)
|
|
||||||
value = self.acOutFrequency.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[8].Update(1, str(value))
|
|
||||||
|
|
||||||
# Grid lost
|
# Grid lost
|
||||||
data = client.read_holding_registers(64, 1)
|
value = getmodbus16(61, client)
|
||||||
Domoticz.Debug("Data from register 64: "+str(data))
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
if value == 0:
|
if value == 0:
|
||||||
Devices[9].Update(nValue=value, sValue="Ok")
|
Devices[9].Update(nValue=value, sValue="Ok")
|
||||||
elif value == 2:
|
elif value == 2:
|
||||||
@ -406,10 +295,7 @@ class BasePlugin:
|
|||||||
Devices[9].Update(nValue=3, sValue="Unknown state ?")
|
Devices[9].Update(nValue=3, sValue="Unknown state ?")
|
||||||
|
|
||||||
# VE.Bus state
|
# VE.Bus state
|
||||||
data = client.read_holding_registers(31, 1)
|
value = getmodbus16(31, client)
|
||||||
Domoticz.Debug("Data from register 31: "+str(data))
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
vebus = 'Unknown?'
|
vebus = 'Unknown?'
|
||||||
if value == 0:
|
if value == 0:
|
||||||
vebus = 'Off'
|
vebus = 'Off'
|
||||||
@ -451,68 +337,20 @@ class BasePlugin:
|
|||||||
Devices[23].Update(1, "0")
|
Devices[23].Update(1, "0")
|
||||||
|
|
||||||
# Battery Voltage
|
# Battery Voltage
|
||||||
data = battery.read_holding_registers(259, 1)
|
self.batteryVoltage.update(round(getmodbus16(259, battery)/100.0, 3))
|
||||||
Domoticz.Debug("Data from register 259: "+str(data))
|
Devices[20].Update(1, self.batteryVoltage.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.batteryVoltage.update(value)
|
|
||||||
value = self.batteryVoltage.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[20].Update(1, str(value))
|
|
||||||
|
|
||||||
# Battery Current
|
# Battery Current
|
||||||
data = battery.read_holding_registers(261, 1)
|
self.batteryCurrent.update(round(getmodbus16(261, battery)/10.0,3))
|
||||||
Domoticz.Debug("Data from register 261: "+str(data))
|
Devices[21].Update(1, self.batteryCurrent.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.batteryCurrent.update(value)
|
|
||||||
value = self.batteryCurrent.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[21].Update(1, str(value))
|
|
||||||
|
|
||||||
# Battery SOC
|
# Battery SOC
|
||||||
data = battery.read_holding_registers(266, 1)
|
self.batterySoc.update(round(getmodbus16(266, battery)/10.0,3))
|
||||||
Domoticz.Debug("Data from register 266: "+str(data))
|
Devices[22].Update(1, self.batterySoc.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.batterySoc.update(value)
|
|
||||||
value = self.batterySoc.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[22].Update(1, str(value))
|
|
||||||
|
|
||||||
# Battery Temperature
|
# Battery Temperature
|
||||||
data = battery.read_holding_registers(262, 1)
|
self.batteryTemp.update(round(getmodbus16(262, battery)/10.0,3))
|
||||||
Domoticz.Debug("Data from register 262: "+str(data))
|
Devices[23].Update(1, self.batteryTemp.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.batteryTemp.update(value)
|
|
||||||
value = self.batteryTemp.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[23].Update(1, str(value))
|
|
||||||
|
|
||||||
# Victron devices
|
# Victron devices
|
||||||
Domoticz.Debug("Multiplus Interface : IP="+self.IPAddress +", Port="+str(self.IPPort)+" ID="+str(self.MBAddr))
|
Domoticz.Debug("Multiplus Interface : IP="+self.IPAddress +", Port="+str(self.IPPort)+" ID="+str(self.MBAddr))
|
||||||
@ -526,78 +364,26 @@ class BasePlugin:
|
|||||||
Devices[32].Update(1, "0")
|
Devices[32].Update(1, "0")
|
||||||
Devices[33].Update(1, "0")
|
Devices[33].Update(1, "0")
|
||||||
Devices[34].Update(1, "0")
|
Devices[34].Update(1, "0")
|
||||||
|
Devices[35].Update(1, "0")
|
||||||
|
|
||||||
# Grid Power L1
|
# Grid Power L1
|
||||||
data = victron.read_holding_registers(820, 1)
|
self.gridpower.update(getmodbus16(820, victron))
|
||||||
Domoticz.Debug("Data from register 820: "+str(data))
|
Devices[30].Update(1, self.gridpower.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
##value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.gridpower.update(value)
|
|
||||||
value = self.gridpower.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[30].Update(1, str(value))
|
|
||||||
|
|
||||||
# Consumption L1
|
# Consumption L1
|
||||||
data = victron.read_holding_registers(817, 1)
|
self.conso.update(getmodbus16(817, victron))
|
||||||
Domoticz.Debug("Data from register 817: "+str(data))
|
Devices[31].Update(1, self.conso.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
#value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.conso.update(value)
|
|
||||||
value = self.conso.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[31].Update(1, str(value))
|
|
||||||
|
|
||||||
# PV on Output
|
# PV on Output
|
||||||
data = victron.read_holding_registers(808, 1)
|
self.pv.update(getmodbus16(808, victron))
|
||||||
Domoticz.Debug("Data from register 808: "+str(data))
|
Devices[32].Update(1, self.pv.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 100.0
|
|
||||||
#value = round (value / 100.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.pv.update(value)
|
|
||||||
value = self.pv.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[32].Update(1, str(value))
|
|
||||||
|
|
||||||
# Battery Power
|
# Battery Power
|
||||||
data = victron.read_holding_registers(842, 1)
|
self.batteryPower.update(getmodbus16(842, victron))
|
||||||
Domoticz.Debug("Data from register 262: "+str(data))
|
Devices[33].Update(1, self.batteryPower.strget())
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
# Scale factor / 10.0
|
|
||||||
##value = round (value / 10.0, 3)
|
|
||||||
Domoticz.Debug("Value after conversion : "+str(value))
|
|
||||||
Domoticz.Debug("-> Calculating average")
|
|
||||||
self.batteryPower.update(value)
|
|
||||||
value = self.batteryPower.get()
|
|
||||||
Domoticz.Debug(" = {}".format(value))
|
|
||||||
Devices[33].Update(1, str(value))
|
|
||||||
|
|
||||||
# ESS Battery State
|
# ESS Battery State
|
||||||
data = victron.read_holding_registers(2900, 1)
|
value = getmodbus16(2900, victron)
|
||||||
Domoticz.Debug("Data from register 2900: "+str(data))
|
|
||||||
# Unsigned 16
|
|
||||||
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
|
||||||
# Value
|
|
||||||
value = decoder.decode_16bit_int()
|
|
||||||
batterystate = "Unknown?"
|
batterystate = "Unknown?"
|
||||||
onbattery = 0
|
onbattery = 0
|
||||||
if value == 0:
|
if value == 0:
|
||||||
@ -627,7 +413,11 @@ class BasePlugin:
|
|||||||
batterystate = "Battery Life disabled (low SoC)"
|
batterystate = "Battery Life disabled (low SoC)"
|
||||||
Devices[34].Update(1, str(value)+": "+batterystate)
|
Devices[34].Update(1, str(value)+": "+batterystate)
|
||||||
# TODO: add a device to say on battery yes/no
|
# TODO: add a device to say on battery yes/no
|
||||||
# use the "onbatteryy" variable
|
# use the "onbattery" variable
|
||||||
|
|
||||||
|
# ESS Battery Life SoC Limit
|
||||||
|
value = (getmodbus16(2903, victron) / 10.0)
|
||||||
|
Devices[35].Update(1, str(value))
|
||||||
|
|
||||||
global _plugin
|
global _plugin
|
||||||
_plugin = BasePlugin()
|
_plugin = BasePlugin()
|
||||||
@ -640,26 +430,6 @@ def onStop():
|
|||||||
global _plugin
|
global _plugin
|
||||||
_plugin.onStop()
|
_plugin.onStop()
|
||||||
|
|
||||||
def onConnect(Connection, Status, Description):
|
|
||||||
global _plugin
|
|
||||||
_plugin.onConnect(Connection, Status, Description)
|
|
||||||
|
|
||||||
def onMessage(Connection, Data):
|
|
||||||
global _plugin
|
|
||||||
_plugin.onMessage(Connection, Data)
|
|
||||||
|
|
||||||
def onCommand(Unit, Command, Level, Hue):
|
|
||||||
global _plugin
|
|
||||||
_plugin.onCommand(Unit, Command, Level, Hue)
|
|
||||||
|
|
||||||
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
|
|
||||||
global _plugin
|
|
||||||
_plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
|
|
||||||
|
|
||||||
def onDisconnect(Connection):
|
|
||||||
global _plugin
|
|
||||||
_plugin.onDisconnect(Connection)
|
|
||||||
|
|
||||||
def onHeartbeat():
|
def onHeartbeat():
|
||||||
global _plugin
|
global _plugin
|
||||||
_plugin.onHeartbeat()
|
_plugin.onHeartbeat()
|
||||||
@ -678,3 +448,25 @@ def DumpConfigToLog():
|
|||||||
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
|
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
|
||||||
Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
|
Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# get Modbus 16 bits values
|
||||||
|
def getmodbus16(register, client):
|
||||||
|
value = 0
|
||||||
|
try:
|
||||||
|
data = client.read_holding_registers(register, 1)
|
||||||
|
Domoticz.Debug("Data from register "+str(register)+": "+str(data))
|
||||||
|
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
||||||
|
value = decoder.decode_16bit_int()
|
||||||
|
except:
|
||||||
|
Domoticz.Error("Error getting data from "+str(register) + ", try 1")
|
||||||
|
try:
|
||||||
|
data = client.read_holding_registers(register, 1)
|
||||||
|
Domoticz.Debug("Data from register "+str(register)+": "+str(data))
|
||||||
|
decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)
|
||||||
|
value = decoder.decode_16bit_int()
|
||||||
|
except:
|
||||||
|
Domoticz.Error("Error getting data from "+str(register) + ", try 2")
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user