Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding next devices to plugin #34

Open
wants to merge 21 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ A Domoticz Python Plugin that can read data from the Growatt webserver interface

## ONLY TESTED FOR Raspberry Pi

With Python version 3.5 & Domoticz V4.11214 (beta) / Domoticz V2020.1 (stable)

V1.0.0 With Python version 3.5 & Domoticz V4.11214 (beta) / Domoticz V2020.1 (stable)
V1.0.1 With Python version 3.7 & Domoticz V2022.2 (stable)

## Installation

Expand Down
49 changes: 24 additions & 25 deletions plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,26 @@
# This plugin will read the status from the running inverter via the webservice. #
# #
# V 1.0.0. Initial Release (25-08-2019) #
# V 1.0.1. Release (20-11-2022), Fix for Domoticz 2022.2 #
# V 1.0.2. Release (21-11-2022), Fix for Errorhandling tnx to JoostDkr #
# V 1.0.3. Release (20-08-2023), Fix for new API "oepi-loepi" #
# V 1.0.4. Release (22-08-2023), Run Again updated every 5 minutes tnx fgerrits #
########################################################################################


"""
<plugin key="GrowattWeb" name="Growatt Web Inverter" author="sincze" version="1.0.0" externallink="https://github.com/sincze/Domoticz-Growatt-Webserver-Plugin">
<plugin key="GrowattWeb" name="Growatt Web Inverter" author="sincze" version="1.0.4" externallink="https://github.com/sincze/Domoticz-Growatt-Webserver-Plugin">
<description>
<h2>Retrieve available Growatt Inverter information from the webservice</h2><br/>
</description>
<params>
<param field="Address" label="Server Address" width="200px" required="true" default="server-api.growatt.com"/>
<param field="Address" label="Server Address" width="200px" required="true" default="server.growatt.com"/>
<param field="Mode2" label="Portal Username" width="200px" required="true" default="admin"/>
<param field="Mode3" label="Portal Password" width="200px" required="true" password="true"/>
<param field="Mode1" label="Protocol" width="75px">
<options>
<option label="HTTPS" value="443"/>
<option label="HTTP" value="80" default="true" />
<option label="HTTPS" value="443" default="true" />
<option label="HTTP" value="80" />
</options>
</param>
<param field="Mode6" label="Debug" width="150px">
Expand All @@ -67,6 +71,7 @@
import hashlib
import json
import re # Needed to extract data from Some JSON result
import urllib.parse # Needed to encode request body messages

local = False
except ImportError:
Expand All @@ -77,7 +82,7 @@

class BasePlugin:
httpConn = None
runAgain = 6
runAgain = 24 # To check every 5 minutes.
disconnectCount = 0
sProtocol = "HTTP"
cookieAvailable = False
Expand All @@ -93,9 +98,8 @@ def apiRequestHeaders(self): # Needed headers for Login Function
return {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Connection': 'keep-alive',
'Host': 'server-api.growatt.com',
'User-Agent': 'Domoticz/1.0',
'Accept-Encoding': 'gzip'
'Host': 'server.growatt.com',
'User-Agent': 'Domoticz/1.0'
}

def apiRequestHeaders_cookie(self): # Needed headers for Data retrieval
Expand All @@ -104,9 +108,8 @@ def apiRequestHeaders_cookie(self): # Needed headers for Data retrieval
'URL': '/newTwoPlantAPI.do?op=getUserCenterEnertyDataByPlantid',
'Headers' : { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Connection': 'keep-alive',
'Host': 'server-api.growatt.com',
'Host': 'server.growatt.com',
'User-Agent': 'Domoticz/1.0',
'Accept-Encoding': 'gzip',
'Cookie': ['JSESSIONID='+self.sessionId, 'SERVERID='+self.serverId]
},
'Data': "plantId="+str(self.plantId)+"&language=1"
Expand Down Expand Up @@ -152,7 +155,7 @@ def onConnect(self, Connection, Status, Description):
sendData = { 'Verb' : 'POST',
'URL' : '/newTwoLoginAPI.do',
'Headers' : self.apiRequestHeaders(),
'Data': "password="+password_md5+"&userName="+Parameters["Mode2"]
'Data': "password="+password_md5+"&userName="+urllib.parse.quote_plus(Parameters["Mode2"])
}
Domoticz.Debug("Step 1. Login SendData: "+str(sendData))
Connection.Send(sendData)
Expand All @@ -163,20 +166,16 @@ def onConnect(self, Connection, Status, Description):

def onMessage(self, Connection, Data):
DumpHTTPResponseToLog(Data)

strData = Data["Data"].decode("utf-8", "ignore")
Status = int(Data["Status"])
LogMessage(strData)
Status = int(Data["Status"])

if (Status == 200):
strData = Data["Data"].decode("utf-8", "ignore")
LogMessage(strData)
apiResponse = json.loads(strData)
Domoticz.Debug("Retrieved following json: "+json.dumps(apiResponse))

try:
if ('back' in apiResponse):
#if not ['back']['success']:
# Domoticz.Log("Login Failed")
#elif ('back' in apiResponse):
if ('back' in apiResponse and strData.find('data') > -1 and strData.find('plantId') > -1): # 17-12-2022 Tip from JoostDkr
Domoticz.Log("Login Succesfull")
self.plantId = apiResponse["back"]["data"][0]["plantId"]
Domoticz.Log("Plant ID: "+str(self.plantId)+" was found")
Expand All @@ -190,20 +189,20 @@ def onMessage(self, Connection, Data):
current = apiResponse['powerValue']
total = apiResponse['totalValue'] # Convert kWh to Wh
sValue=str(current)+";"+str( float(total)*1000 )
Domoticz.Log("Currently producing: "+str(current)+" Watt. Totall produced: "+str(total)+" kWh in Wh that is: "+str(float(total)*1000) )
Domoticz.Log("Currently producing: "+str(current)+" Watt. Total produced: "+str(total)+" kWh in Wh that is: "+str(float(total)*1000) )
UpdateDevice(Unit=1, nValue=0, sValue=sValue, TimedOut=0)
UpdateDevice(Unit=2, nValue=0, sValue=current, TimedOut=0)
else:
Domoticz.Debug("Not received anything usefull!")
Domoticz.Debug("Not received anything useful!")
except KeyError:
Domoticz.Debug("No defined keys found!")

elif (Status == 400):
Domoticz.Error("Google returned a Bad Request Error.")
Domoticz.Error("Growatt returned a Bad Request Error.")
elif (Status == 500):
Domoticz.Error("Google returned a Server Error.")
Domoticz.Error("Growatt returned a Server Error.")
else:
Domoticz.Error("Google returned a status: "+str(Status))
Domoticz.Error("Growatt 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))
Expand All @@ -221,7 +220,7 @@ def onHeartbeat(self):
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 = 6
self.runAgain = 24
else:
Domoticz.Debug("onHeartbeat called, run again in "+str(self.runAgain)+" heartbeats.")
#Domoticz.Trace(False)
Expand Down