Can support for Growatt solar panels be added to Home assistant?
There is already an API on github available: https://github.com/Sjord/growatt_api_client
Did not test this of course ;-).
Can support for Growatt solar panels be added to Home assistant?
There is already an API on github available: https://github.com/Sjord/growatt_api_client
Did not test this of course ;-).
Thank you for pointing out the API on Github, I was trying to create a web scraper sensor for some time.
If you have appdaemon installed, I have an app to collect the Current Power Output and Todays Total Power Out put in to sensors as below
"""Create sensors for Current Power Output and Daily Power Generation from Growatt Invertor
Using api client from https://github.com/Sjord/growatt_api_client
Features:
- Updates the sensors every 5 minutes
- Do not fetch the data from Growatt at night
Arguments:
username: Username to login to server.growatt.com
password: Password for server.growatt.com
Example configuration
In apps.yaml:
Growatt:
class: GrowattSensor
module: growattsensor
username: 'user'
password: 'pwd'
"""
from enum import IntEnum
import datetime
import hashlib
import json
import requests
import appdaemon.plugins.hass.hassapi as hass
def hash_password(password):
"""
Normal MD5, except add c if a byte of the digest is less than 10.
"""
password_md5 = hashlib.md5(password.encode('utf-8')).hexdigest()
for i in range(0, len(password_md5), 2):
if password_md5[i] == '0':
password_md5 = password_md5[0:i] + 'c' + password_md5[i + 1:]
return password_md5
class Timespan(IntEnum):
day = 1
month = 2
class GrowattApi:
server_url = 'http://server.growatt.com/'
def __init__(self):
self.session = requests.Session()
def get_url(self, page):
return self.server_url + page
def login(self, username, password):
password_md5 = hash_password(password)
response = self.session.post(self.get_url('LoginAPI.do'), data={
'userName': username,
'password': password_md5
})
data = json.loads(response.content.decode('utf-8'))
return data['back']
def plant_list(self, user_id):
response = self.session.get(self.get_url('PlantListAPI.do'),
params={'userId': user_id},
allow_redirects=False)
if response.status_code != 200:
raise RuntimeError("Request failed: %s", response)
data = json.loads(response.content.decode('utf-8'))
return data['back']
def plant_detail(self, plant_id, timespan, date):
assert timespan in Timespan
if timespan == Timespan.day:
date_str = date.strftime('%Y-%m-%d')
elif timespan == Timespan.month:
date_str = date.strftime('%Y-%m')
response = self.session.get(self.get_url('PlantDetailAPI.do'), params={
'plantId': plant_id,
'type': timespan.value,
'date': date_str
})
data = json.loads(response.content.decode('utf-8'))
return data['back']
class GrowattSensor(hass.Hass):
''' Class to create Growatt Sensors in HA'''
def initialize(self):
self.handle = None
self.username = self.args["username"]
self.password = self.args["password"]
self.api = GrowattApi()
self.currentPowerOutput = "0"
self.totalPowerGenerated = "0"
#update sensor in every 5 minutes
self.run_every(self.updateSensor, self.datetime(), 5 * 60)
#update daily power output at night
#runtime = datetime.time(23, 0, 0)
#self.run_daily(self.run_daily_c, runtime)
def updateSensor(self, kwargs):
'''Function to update sensors)'''
if self.now_is_between("sunrise - 00:45:00", "sunset + 00:45:00"):
self.log("Updating sensors")
login_res = self.api.login(self.username, self.password)
user_id = login_res['userId']
plant_info = self.api.plant_list(user_id)
data, kw = (plant_info['data'][0]['currentPower']).split( )
self.currentPowerOutput = data
self.log("Current power output is {} kW".format(data))
self.set_state('sensor.currentsolarpower',state=data,attributes={"friendly_name":'Current Power Output', 'unit_of_measurement':'kW', 'icon':'mdi:solar-power'})
data1, kwh = (plant_info['data'][0]['todayEnergy']).split( )
self.totalPowerGenerated = data1
self.log("Todays power production is {} kWh".format(data1))
self.set_state('sensor.dailypoweroutput',state=data1,attributes={"friendly_name":'Todays Power Generation', 'unit_of_measurement':'kWh', 'icon':'mdi:solar-power'})
else:
self.log("Insering old data")
self.set_state('sensor.currentsolarpower',state=self.currentPowerOutput,attributes={"friendly_name":'Current Power Output', 'unit_of_measurement':'kW', 'icon':'mdi:solar-power'})
self.set_state('sensor.dailypoweroutput',state=self.totalPowerGenerated,attributes={"friendly_name":'Todays Power Generation', 'unit_of_measurement':'kWh', 'icon':'mdi:solar-power'})```
I managed to create a custom component for this
Please test if you can
Cool, will test this soon, after I figured out to make a dasboard with appdeamon!
I connected my Fronius via JSON, it was handy that the interface card already supported this, i believe you could use SNMP as well, i use SNMP to monitor my UPS and other networking gear, might be worth a look to see if you can get values that way.
Just a question from a noob, (first time I’ve done something like this). So… how does one go about outputting RS232 from the inverter so that it’s readable in HASSIO? I can get an RS232 > Ethernet cable, but surely parsing JSON data from the inverter to HASSIO is more complicated.
App did not initialize:
2019-02-03 17:24:15.994127 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/growattapi.py - ignoring
2019-02-03 17:24:15.995041 INFO AppDaemon: Initializing app Growatt using class GrowattSensor from module growattsensor
2019-02-03 17:24:15.996038 WARNING AppDaemon: Unable to find module module growattsensor - Growatt is not initialized
from enum import IntEnum
import datetime
import hashlib
import json
import requests
import appdaemon.plugins.hass.hassapi as hass
def hash_password(password):
"""
Normal MD5, except add c if a byte of the digest is less than 10.
"""
password_md5 = hashlib.md5(password.encode('utf-8')).hexdigest()
for i in range(0, len(password_md5), 2):
if password_md5[i] == '0':
password_md5 = password_md5[0:i] + 'c' + password_md5[i + 1:]
return password_md5
class Timespan(IntEnum):
day = 1
month = 2
class GrowattApi:
server_url = 'http://server.growatt.com/'
def __init__(self):
self.session = requests.Session()
def get_url(self, page):
return self.server_url + page
def login(self, username, password):
password_md5 = hash_password(password)
response = self.session.post(self.get_url('LoginAPI.do'), data={
'userName': username,
'password': password_md5
})
data = json.loads(response.content.decode('utf-8'))
return data['back']
def plant_list(self, user_id):
response = self.session.get(self.get_url('PlantListAPI.do'),
params={'userId': user_id},
allow_redirects=False)
if response.status_code != 200:
raise RuntimeError("Request failed: %s", response)
data = json.loads(response.content.decode('utf-8'))
return data['back']
def plant_detail(self, plant_id, timespan, date):
assert timespan in Timespan
if timespan == Timespan.day:
date_str = date.strftime('%Y-%m-%d')
elif timespan == Timespan.month:
date_str = date.strftime('%Y-%m')
response = self.session.get(self.get_url('PlantDetailAPI.do'), params={
'plantId': plant_id,
'type': timespan.value,
'date': date_str
})
data = json.loads(response.content.decode('utf-8'))
return data['back']
class GrowattSensor(hass.Hass):
''' Class to create Growatt Sensors in HA'''
def initialize(self):
self.handle = None
self.username = self.args["username"]
self.password = self.args["password"]
self.api = GrowattApi()
self.currentPowerOutput = "0"
self.totalPowerGenerated = "0"
#update sensor in every 5 minutes
self.run_every(self.updateSensor, self.datetime(), 5 * 60)
#update daily power output at night
#runtime = datetime.time(23, 0, 0)
#self.run_daily(self.run_daily_c, runtime)
def updateSensor(self, kwargs):
'''Function to update sensors)'''
if self.now_is_between("sunrise - 00:45:00", "sunset + 00:45:00"):
self.log("Updating sensors")
login_res = self.api.login(self.username, self.password)
user_id = login_res['userId']
plant_info = self.api.plant_list(user_id)
data, kw = (plant_info['data'][0]['currentPower']).split( )
self.currentPowerOutput = data
self.log("Current power output is {} kW".format(data))
self.set_state('sensor.currentsolarpower',state=data,attributes={"friendly_name":'Current Power Output', 'unit_of_measurement':'kW', 'icon':'mdi:solar-power'})
data1, kwh = (plant_info['data'][0]['todayEnergy']).split( )
self.totalPowerGenerated = data1
self.log("Todays power production is {} kWh".format(data1))
self.set_state('sensor.dailypoweroutput',state=data1,attributes={"friendly_name":'Todays Power Generation', 'unit_of_measurement':'kWh', 'icon':'mdi:solar-power'})
else:
self.log("Insering old data")
self.set_state('sensor.currentsolarpower',state=self.currentPowerOutput,attributes={"friendly_name":'Current Power Output', 'unit_of_measurement':'kW', 'icon':'mdi:solar-power'})
self.set_state('sensor.dailypoweroutput',state=self.totalPowerGenerated,attributes={"friendly_name":'Todays Power Generation', 'unit_of_measurement':'kWh', 'icon':'mdi:solar-power'})
Problem was in the apps file.
Content changend to:
growattapi:
class: growattsensor
module: growattapi
username: !secret username
password: !secret password
Now I get readings from the server.
Next thing to find out is how to keep the readings alive after a reset of the system. Appdeamon sensor is pretty volatile.
Instead of appdaemon use the custom component from
https://community.home-assistant.io/t/anyone-experience-with-connecting-a-growatt-solar-inverter/60430/2
Didyou ever got this answered? Rs232 local reading without growatt cloud?
Is this all based on local reading or cloud?
This should be possible with https://pypi.org/project/growattRS232/
However there is no Home Assistant integration for it yet as far as i know and if will require an RS232 to USB adapter.
Any of the integrations for Growatt that need a username and password are likely cloud polling
How can i get the monthly results to see in HA. I see only a sensor created for Today and output power etc. ?? I am using the integration from HA.