I have Primo 3.0-1 I would see switch on Hardware configuration tab to select between Inverters. We need to use different URL to get data from with different data structure. You can look on draft code that I've changed from original great phyton script from author.
Code: Select all
# Fronius http python plugin
# @2020
# Author: EA4GKQ
#https://github.com/akleber/fronius-json-tools
# 06/05/2020
# - Añadido dummy con valor medio de Grid de las últimas 30 muestras
# - Mejorada reconexión automática
"""
<plugin key="FroniusHttp" name="Fronius http" author="EA4GKQ" version="1.0.2" wikilink="https://github.com/ayasystems/froniusHttp" externallink="https://www.fronius.com/es-es/spain/energia-solar/productos">
<description>
<h2>Fronius HTTP Pluging</h2><br/>
<h3>by @ea4gkq</h3>
<br/>
<a href="https://domotuto.com/fronius_domoticz_plugin/">https://domotuto.com/fronius_domoticz_plugin/</a>
<br/>
</description>
<params>
<param field="Address" label="Fronius IP" width="200px" required="true" default="192.168.1.xx"/>
<param field="Mode1" label="Protocol" width="75px">
<options>
<option label="HTTP" value="80" default="true" />
</options>
</param>
<param field="Mode2" label="Update speed" width="75px">
<options>
<option label="Normal" value="Normal"/>
<option label="High" value="High" default="true" />
</options>
</param>
<param field="Mode6" label="Debug" width="150px">
<options>
<option label="None" value="0" default="true" />
<option label="Python Only" value="2"/>
<option label="Basic Debugging" value="62"/>
<option label="Basic+Messages" value="126"/>
<option label="Connections Only" value="16"/>
<option label="Connections+Queue" value="144"/>
<option label="All" value="-1"/>
</options>
</param>
</params>
</plugin>
"""
errmsg = ""
try:
import Domoticz
except Exception as e:
errmsg += "Domoticz core start error: "+str(e)
try:
import json
except Exception as e:
errmsg += " Json import error: "+str(e)
try:
import time
except Exception as e:
errmsg += " time import error: "+str(e)
try:
import re
except Exception as e:
errmsg += " re import error: "+str(e)
from random import seed
from random import gauss
from functools import reduce
class FroniusHttp:
httpConn = None
interval = 1
runAgain = interval
connectedCount = 0
disconnectCount = 0
sProtocol = "HTTP"
DAY_ENERGY1 = ""
PAC1 = ""
TOTAL_ENERGY1 = ""
DAY_ENERGY = ""
PAC = ""
TOTAL_ENERGY = ""
P_PV = "" #Instant production
E_Day = "" #Total of the day
E_Total = "" #Total Production
E_Year = "" #Production Year
P_Grid = "" #Negative inject Positive consume
UAC = "" #Grid + solar consumption
FAC = ""
IAC = ""
IDC = ""
UDC = ""
UAC = ""
F_PAC = ""
F_FAC = ""
F_IAC = ""
F_IDC = ""
F_UDC = ""
F_UAC = ""
GRID_W = ""
listGrid = []
maxGridList = 30
avgGrid = 0
URL2 = "/solar_api/v1/GetInverterRealtimeData.cgi?Scope=System"
#URL1 = "/solar_api/v1/GetPowerFlowRealtimeData.fcgi"
URL1 = "/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceID=1&DataCollection=CommonInverterData"#jakub
#URL2 = "/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceID=1&DataCollection=CommonInverterData"#jakub
#192.168.1.51/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DataCollection=CommonInverterData&DeviceId=1
current = ""
def __init__(self):
return
def onStart(self):
Domoticz.Error("onStart: "+errmsg)
if errmsg =="":
try:
Domoticz.Debug("onStart - try")
if Parameters["Mode6"] == "": Parameters["Mode6"] = "-1"
if Parameters["Mode6"] != "0":
Domoticz.Debug("if parameters mode 6: "+Parameters["Mode6"])
Domoticz.Debugging(int(Parameters["Mode6"]))
Domoticz.Debug("DumpConfigToLog")
DumpConfigToLog()
createDevices(self,"F_PAC")
createDevices(self,"F_FAC")
createDevices(self,"F_IAC")
createDevices(self,"F_IDC")
createDevices(self,"F_UAC")
createDevices(self,"F_UDC")
if (Parameters["Mode1"].strip() == "443"): self.sProtocol = "HTTPS"
if (Parameters["Mode2"].strip() == "High"): Domoticz.Heartbeat(1)
Domoticz.Debug("Address: "+Parameters["Address"])
Domoticz.Debug("port: "+Parameters["Mode1"].strip())
Domoticz.Debug("Address: "+Parameters["Address"].strip())
self.httpConn = Domoticz.Connection(Name=self.sProtocol+" Test", Transport="TCP/IP", Protocol=self.sProtocol, Address=Parameters["Address"].strip() , Port=Parameters["Mode1"].strip() )
self.httpConn.Connect()
except Exception as e:
Domoticz.Error("Plugin onStart error: "+str(e))
else:
Domoticz.Error("Your Domoticz Python environment is not functional! "+errmsg)
def onStop(self):
Domoticz.Log("onStop - Plugin is stopping.")
def Average(self):
if(len(self.listGrid)>self.maxGridList):
self.listGrid.pop(0)
#Domoticz.Debug("List values: "+str(self.listGrid))
self.avgGrid = reduce(lambda a,b: a + b, self.listGrid) / len(self.listGrid)
self.avgGrid = round(self.avgGrid,0)
def onConnect(self, Connection, Status, Description):
if (Status == 0):
Domoticz.Debug("Fronius connected successfully.")
if(self.current==self.URL2):
self.current=self.URL1
else:
self.current=self.URL2
self.current=self.URL1
sendData = { 'Verb' : 'GET',
'URL' : self.current,
'Headers' : { 'Content-Type': 'text/xml; charset=utf-8', \
'Connection': 'keep-alive', \
'Accept': 'Content-Type: text/html; charset=UTF-8', \
'Host': Parameters["Address"]+":"+Parameters["Mode1"], \
'User-Agent':'Domoticz/1.0' }
}
Connection.Send(sendData)
else:
Domoticz.Log("Failed to connect ("+str(Status)+") to: "+Parameters["Address"]+":"+Parameters["Mode1"]+" with error: "+Description)
def onMessage(self, Connection, Data):
DumpHTTPResponseToLog(Data)
strData = Data["Data"].decode("utf-8", "ignore")
Status = int(Data["Status"])
#LogMessage(strData)
#Domoticz.Debug("Data.onMessage: " + str(Data))
Domoticz.Debug("Status.onMessage: " + str(Status))
#Domoticz.Debug("self.disconnectCount & 1: " + str((self.disconnectCount & 1)) )
if (Status == 200):
if ((self.disconnectCount & 1) == 1):
Domoticz.Log("Good Response received from Solax, Disconnecting.")
self.httpConn.Disconnect()
else:
Domoticz.Log("Good Response received from Solax, Dropping connection.")
self.httpConn = None
self.disconnectCount = self.disconnectCount + 1
processResponse(self,Data)
elif (Status == 302):
Domoticz.Log("Fronius returned a Page Moved Error.")
sendData = { 'Verb' : 'GET',
'URL' : Data["Headers"]["Location"],
'Headers' : { 'Content-Type': 'text/xml; charset=utf-8', \
'Connection': 'keep-alive', \
'Accept': 'Content-Type: text/html; charset=UTF-8', \
'Host': Parameters["Address"]+":"+Parameters["Mode1"], \
'User-Agent':'Domoticz/1.0' },
}
Connection.Send(sendData)
elif (Status == 400):
Domoticz.Error("Solax returned a Bad Request Error.")
self.httpConn.Disconnect()
self.httpConn = None
elif (Status == 500):
Domoticz.Error("Solax returned a Server Error.")
self.httpConn.Disconnect()
self.httpConn = None
else:
Domoticz.Debug("Solax returned a status: "+str(Status))
def onCommand(self, Unit, Command, Level, Hue):
Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
def onDisconnect(self, Connection):
Domoticz.Debug("onDisconnect called for connection to: "+Connection.Address+":"+Connection.Port)
def onHeartbeat(self):
if(self.connectedCount>10):
self.connectedCount = 0
self.httpConn.Disconnect()
self.httpConn = None
#Domoticz.Trace(True)
if (self.httpConn != None and (self.httpConn.Connecting() or self.httpConn.Connected())):
Domoticz.Debug("onHeartbeat called, Connection is alive.")
else:
self.runAgain = self.runAgain - 1
if self.runAgain <= 0:
if (self.httpConn == None):
self.httpConn = Domoticz.Connection(Name=self.sProtocol+" Test", Transport="TCP/IP", Protocol=self.sProtocol, Address=Parameters["Address"], Port=Parameters["Mode1"])
self.httpConn.Connect()
self.runAgain = self.interval
else:
Domoticz.Debug("onHeartbeat called, run again in "+str(self.runAgain)+" heartbeats.")
#Domoticz.Trace(False)
global _plugin
_plugin = FroniusHttp()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_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():
global _plugin
_plugin.onHeartbeat()
# Generic helper functions
def LogMessage(Message):
if Parameters["Mode6"] == "File":
f = open(Parameters["HomeFolder"]+"http.html","w")
f.write(Message)
f.close()
Domoticz.Log("File written")
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug("Device count: " + str(len(Devices)))
for x in Devices:
Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
return
def processResponse(self,httpResp):
DAY_ENERGY1 = ""#jakub
PAC1 = ""
TOTAL_ENERGY1 = ""
stringData = httpResp["Data"].decode("utf-8", "ignore")
jsonData = json.loads(stringData)
Domoticz.Debug("##self.current: "+self.current)
Domoticz.Debug("##self.URL2: "+self.URL2)
Domoticz.Debug("##self.URL1: "+self.URL1)
#Domoticz.Debug("httpResp.processResponse: " + str(httpResp))
if(self.current==self.URL2):
try:
self.DAY_ENERGY1 = str(jsonData['Body']['Data']['DAY_ENERGY']['Values']['1'])
self.PAC1 = str(jsonData['Body']['Data']['PAC']['Values']['1'])
self.TOTAL_ENERGY1 = str(jsonData['Body']['Data']['TOTAL_ENERGY']['Values']['1'])
if Parameters["Mode6"] == "-1":
Domoticz.Debug("DAY_ENERGY1: "+self.DAY_ENERGY1)
Domoticz.Debug("PAC1: "+self.PAC1)
Domoticz.Debug("TOTAL_ENERGY1: "+self.TOTAL_ENERGY1)
self.connectedCount = 0
except:
Domoticz.Debug(str(e))
if(self.current==self.URL1):#jakub
try:
self.PAC = str(jsonData['Body']['Data']['PAC']['Value'])
self.E_Day = str(jsonData['Body']['Data']['DAY_ENERGY']['Value'])
self.E_Total = str(jsonData['Body']['Data']['TOTAL_ENERGY']['Value'])
self.E_Year = str(jsonData['Body']['Data']['YEAR_ENERGY']['Value'])
self.UAC = str(jsonData['Body']['Data']['UAC']['Value'])
self.UDC = str(jsonData['Body']['Data']['UDC']['Value'])
self.IAC = str(jsonData['Body']['Data']['IAC']['Value'])
self.IDC = str(jsonData['Body']['Data']['IDC']['Value'])
self.FAC = str(jsonData['Body']['Data']['FAC']['Value'])
#self.P_PV = str(jsonData['Body']['Data']['Site']['P_PV'])
#self.listGrid.append(F_IDC)
#self.Average()
if Parameters["Mode6"] == "-1":
Domoticz.Error("F_PAC: "+self.PAC)
Domoticz.Error("E_Day: "+self.E_Day)
Domoticz.Error("E_Total: "+self.E_Total)
Domoticz.Error("E_Year: "+self.E_Year)
Domoticz.Error("F_UAC: "+self.UAC)
Domoticz.Error("F_UDC: "+self.UDC)
Domoticz.Error("F_IAC: "+self.IAC)
Domoticz.Error("F_IDC: "+self.IDC)
Domoticz.Error("F_FAC: "+self.FAC)
#Domoticz.Error("List: "+str(self.listGrid))
#Domoticz.Error("AVG Grid: "+str(round(self.avgGrid,0)))
instantaneoFV = self.PAC
acumuladoKwhFV = self.E_Day#daily accumulated
#if(F_IDC>=0):
# UpdateDevice("F_FAC", 0, "0;0")
# UpdateDevice("F_IDC", 0, str(F_IDC)+";0")
#Domoticz.Debug("##self.UAC : " + self.UAC )
#if(F_FAC>0):
#UpdateDevice("F_FAC", 0, self.P_Grid+";0")
# UpdateDevice("F_IDC", 0, "0;0")
UpdateDevice("F_PAC", 0, instantaneoFV+";"+acumuladoKwhFV)
UpdateDevice("F_UAC", 0, self.UAC+";0")
UpdateDevice("F_UDC", 0, self.UDC+";0")
UpdateDevice("F_FAC", 0, self.FAC+";0")
UpdateDevice("F_IAC", 0, self.IAC+";0")
UpdateDevice("F_IDC", 0, self.IDC+";0")
#UpdAteDevice("AVGGRID", 0, self.avgGrid)
self.connectedCount = 0
except:
Domoticz.Debug(str(e))
def DumpHTTPResponseToLog(httpResp, level=0):
if (level==0): Domoticz.Debug("HTTP Details ("+str(len(httpResp))+"):")
indentStr = ""
for x in range(level):
indentStr += "----"
if isinstance(httpResp, dict):
for x in httpResp:
if not isinstance(httpResp[x], dict) and not isinstance(httpResp[x], list):
Domoticz.Debug(indentStr + "a>'" + x + "':'" + str(httpResp[x]) + "'")
else:
Domoticz.Debug(indentStr + "b>'" + x + "':")
DumpHTTPResponseToLog(httpResp[x], level+1)
elif isinstance(httpResp, list):
for x in httpResp:
Domoticz.Debug(indentStr + "['" + x + "']")
else:
Domoticz.Debug(indentStr + "c>'" + x + "':'" + str(httpResp[x]) + "'")
def createDevices(self,unitname):
OptionsSensor = {"Custom": "1;Hz"}
OptionsSensorAVG = {"Custom": "1;w"}
iUnit = -1
for Device in Devices:
try:
if (Devices[Device].DeviceID.strip() == unitname):
iUnit = Device
break
except:
pass
if iUnit<0: # if device does not exists in Domoticz, than create it
try:
iUnit = 0
for x in range(1,256):
if x not in Devices:
iUnit=x
break
Domoticz.Debug("Creating: "+unitname);
if iUnit==0:
iUnit=len(Devices)+1
if(unitname=="F_IDC"): #amper
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=23,Switchtype=0,Used=1,DeviceID=unitname).Create()
if(unitname=="F_IAC"): #amper
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=23,Switchtype=0,Used=1,DeviceID=unitname).Create()
if(unitname=="F_FAC"): #custom
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=31,Switchtype=0,Used=1,DeviceID=unitname).Create()
if(unitname=="F_UAC"): #voltage
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=8,Switchtype=0,Used=1,DeviceID=unitname).Create()
if(unitname=="F_UDC"): #voltage
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=8,Switchtype=0,Used=1,DeviceID=unitname).Create()
if(unitname=="F_PAC"):
Domoticz.Device(Name=unitname, Unit=iUnit,Type=243,Subtype=29,Switchtype=0,Used=1,DeviceID=unitname).Create()
except Exception as e:
Domoticz.Debug(str(e))
return False
return
def UpdateDevice(unitname, nValue, sValue):
# Make sure that the Domoticz device still exists (they can be deleted) before updating it
# if (Devices[Device].DeviceID.strip() == unitname):
iUnit = -1
for Device in Devices:
try:
if (Devices[Device].DeviceID.strip() == unitname):
iUnit = Device
break
except:
pass
if iUnit>=0: # existe, actualizamos
if (Devices[iUnit].nValue != nValue) or (Devices[iUnit].sValue != sValue):
Devices[iUnit].Update(nValue=nValue, sValue=str(sValue))
Domoticz.Debug("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[iUnit].Name+")")
Still trying to get rid of error message during inverter is not operating but still responding to PING.
I've changed graphs as I don't have any battery and I'm collecting other information available.