I just finished the config to collect daily energy production from APSystems API using a python script running under AppDaemon and PVoutputs integration.
The result is a sensor showing “live” energy production in kWh every day
Tutorial Steps:
-
Identifying your ECU. Does it have web interface?
ECU is that modem like device that receives signals from microinverters, which are connected with the solar panels.
There are some ECU types, depending the world region you are.
If your ECU has a web interface when accessing its ip address from any browser, you can make the integration localy, just scraping its web interface and get the value from “today” section.
If your ECU does not offer a web interface, you’ll need to use PVOUTPUT integration. -
ECU with web interface:
Use scrape sensor:
sensor:
platform: scrape
resource: http://192.168.0.26/ # your ecu ip address
select: " tr:nth-child(2) > td" # where is the value you want to show here*
name : Lifetime_generation
value_template: ‘{{ ((value.split(" ")[0]) | replace (“KW”, “”)) }}’ # you will need to test the result from scrape select and template it to show just the numbers
unit_of_measurement: “kWh”
scan_interval: 300
How do you write the select part:
Open your ecu web interface on google chrome, select the value you want and right click and select “inspect”. It will open the chrome inspector.
Inside inspector, find the value, right click, “copy selector”
Paste it with " "
- ECU without web interface:
Use PVOUTPUT integration:
3.1) Take note your ECU number id.
3.2) Access your EMA setup web interface
https://www.apsema.com/ema/security/optmainmenu/intoManagementCustomer.action
And check the box “Allow visitors to access to this system” and copy the “Authorized ID”
3.3) Create an account on https://pvoutput.org/ and fill with yout solar system data.
Enable API Settings, generate API Key and take note.
Take note System Id from PVoutput as well.
Now you have all data you need to config home assistant integration.
This works this way:
You need to feed PVOutput system with your power generation and Home Assistant will download data from PVOutput system showing as a sensor.
There is a script from willemstoker https://github.com/willemstoker/aps-to-pvoutput that feed PVOutput with APSystems API and I turned it into a AppDaemon APP.
So, install AppDaemon Add-On if you use HASS.IO
Remend to install Requests package in configuration Add-On before start it:
system_packages: []
python_packages:
- Requests
init_commands: []
Create a file called apstopvoutput.py inside ˜/appdaemon/apps folder with the code bellow and change by the numbers you noted:
import hassapi as hass
import requests
import json
from datetime import date
from datetime import datetime
import os.path
class APStoPVOUTPUT(hass.Hass):
#initialize() function which will be called at startup and reload
def initialize(self):
# Schedule to run every 10 minutes
self.run_every(self.apstopv, "now", 600)
# Our callback function will be called by the scheduler
def apstopv(self, kwargs):
ECU_ID = 'YOUR ECU ID'
PV_OUTPUT_SYSTEMID = 'YOUR PVOUTPUT SYSTEM ID'
PV_OUTPUT_APIKEY = 'YOUT API KEY FROM PVOUTPUT'
LAST_UPDATE_FILE = "/config/appdaemon/apps/lastupdate" # remember to change this folder if you need"
MAX_NUMBER_HISTORY = 20
APSYSTEMS_URL = 'http://api.apsystemsema.com:8073/apsema/v1/ecu/getPowerInfo'
PVOUTPUT_URL = 'http://pvoutput.org/service/r2/addstatus.jsp'
def readLastUpdate():
f = open(LAST_UPDATE_FILE,"r")
datestring = f.read()
f.close()
return datetime.strptime(datestring, "%Y%m%d %H:%M")
def writeLastUpdate(timestringminutes):
f = open(LAST_UPDATE_FILE,"w+")
f.write(getDateStringOfToday()+ ' ' +timestringminutes)
f.close()
def getDateStringOfToday():
return date.today().strftime("%Y%m%d");
def getDataFromAPS():
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'ecuId': ECU_ID,
'filter': 'power',
'date': getDateStringOfToday()
}
response = requests.post(APSYSTEMS_URL, headers=headers, data=data)
return response.json();
def sendUpdateToPVOutput(timestringminutes, powerstring):
pvoutputdata = {
'd': getDateStringOfToday(),
't': timestringminutes,
'v2': powerstring
}
headerspv = {
'X-Pvoutput-SystemId': PV_OUTPUT_SYSTEMID,
'X-Pvoutput-Apikey': PV_OUTPUT_APIKEY
}
responsepv = requests.post(PVOUTPUT_URL, headers=headerspv, data=pvoutputdata)
print ("Response: " + responsepv.text + " updated: " + timestringminutes + " power: " + powerstring)
if not os.path.isfile(LAST_UPDATE_FILE):
writeLastUpdate('00:00') #create file for the first time
rootdict = getDataFromAPS()
timesstring = rootdict.get("data").get("time")
powersstring = rootdict.get("data").get("power")
timelist = json.loads(timesstring)
powerlist = json.loads(powersstring)
latestUpdate = readLastUpdate()
print("Found latest update: ")
print(latestUpdate)
i = len(timelist) - 1
count = 0;
while i >= 0 and count < MAX_NUMBER_HISTORY:
timestringminutes = timelist[i][:-3] #get time and strip the seconds
powerstring = powerlist[i] #get power
currentUpdate = datetime.strptime(getDateStringOfToday()+ ' ' +timestringminutes, "%Y%m%d %H:%M")
if currentUpdate > latestUpdate:
sendUpdateToPVOutput(timestringminutes, powerstring)
else:
print("No update needed for: " + timestringminutes)
if count == 0:
writeLastUpdate(timestringminutes)
i -= 1
count += 1
This app runs every 10 minutes, and upload apsema data to pvoutputs
now, edit the apps.yaml to run the app only during solar generation time with this:
---
apstopvoutput:
module: apstopvoutput
class: APStoPVOUTPUT
constrain_start_time: sunrise # your panels start generating before sunrise, but the app import last 20 entries, which means something like last hour
constrain_end_time: sunset + 00:45:00 # change this if your panels generate after 45 min after sunset
and finaly, home assistant sensors in configuration.yaml:
sensor:
- platform: pvoutput
system_id: 99999 #change with your system Id again from pvoutputs
api_key: 9999999 #change with your api key from pvoutputs
scan_interval: 600
optionally you can create a template sensor to show in kWh unit:
sensor:
- platform: template
sensors:
energia_solar:
friendly_name: 'Today Solar Energy'
value_template: "{{(states('sensor.pvoutput')|float / 1000)|round(1)}}"
unit_of_measurement: "kWh"
Note that pvoutput allows only 60 interactions per hour, including uploading and downloading data.