Open ronbrou opened 3 years ago
Hi,
If you go to the Appdaemon4 log console. Did you see any negative values there?
This shows the values read from the sensor.
I solved it as follows:
def requestSolarGeneration(self, arg):
self.dateOfReading = datetime.now() # Get date & time of reading
req = Request(zeverSolarURL)
try:
response = urlopen(req)
htmlresponse = response.read()
st = htmlresponse.decode()
st = st.split() # Convert the string into a list
#-- Get the string for the Generated Power and Daily Energy
genPower = st[genPowerIndex]
dailyEnergy = st[dailyEnergyIndex]
#-- Convert string into Int and Float
self.generatedPower = float(genPower)/1000 # Its in W eg. 4978. Convert into kW
self.totalEnergyDaily = float(dailyEnergy) # It is already in kWh eg. 14.52
return
except:
self.log("Error in connecting to Zever solar server", log="main_log")
self.generatedPower = 0.00
self.totalEnergyDaily = None
return
def doGetGenAndSendAsSensor(self, arg):
self.log("----- ZeverSolar sensor callback -----", log="main_log")
#-- Get the generated power & energy
self.requestSolarGeneration(self)
lastUpdated = self.dateOfReading.strftime(datetimeFormat) # Last updated
lastReset = self.dateOfReading.strftime("%Y-%m-%d 00:00:00+02:00")
#-- Output the sensor values
#-- Instantaneous Generated power
stateInfo1 = generationFormat.format(self.generatedPower)
self.set_state("sensor.zeverSolar_generated_power", state=stateInfo1, attributes=\
{"unit_of_measurement": "kW", \
"last_reset" : lastReset, \
"state_class": "measurement", \
"device_class": "energy", \
"icon": "mdi:white-balance-sunny", \
"friendly_name": "Generated Power",
"lastUpdated": lastUpdated
})
#-- Daily energy generated
#- Icons are located at http://materialdesignicons.com/
stateInfo2 = generationFormat.format(self.totalEnergyDaily)
self.set_state("sensor.zeverSolar_daily_energy", state=stateInfo2, attributes=\
{"unit_of_measurement": "kWh", \
"last_reset" : lastReset, \
"state_class": "measurement", \
"device_class": "energy", \
"icon": "mdi:white-balance-sunny", \
"friendly_name": "Daily Generated Energy",
"lastUpdated": lastUpdated
})
#-- Send out a log to the appdaemon console
self.log("Updated: " + lastUpdated + " Gen: " + stateInfo1 + "kW, Daily energy: " + stateInfo2 + "kWh", log="main_log")
I have entered the adjustment you indicated, and now I no longer have a negative value, but the last value. thanks,
I have the code like this now, but still get wrong info (see screenshots). I now have production in the middle of the night.....
#-------------------------------------------------------------------------------
# Name: appd_ZeverSolarSensor.py
#
# Purpose: To get the Zeversolar solar generation from the local website
# and send it to the front end. It does it by sending it as a
# sensor to the front end. This module parses the value returned
# by the URL call and gives us the:
# - Instantaneous generated power in kW
# - Total generated energy for the day in kWH
# You don't have to make any changes to your configuration.yaml file.
# It automatically generates the sensor for the front end.
#
# Note: Modified for AppDaemon 4
#
# Author: Cheong Koo
#
# Created: 09/08/2021
#
# Note that at night, the server is down as there is no power hence need to check
# Below the reading from the URL separated by CR
# 1 1 EAB9618A0399 RSQMMVXNNPJMNWHY M11 17A31-727R+17829-719R 10:58 05/10/2019 0 1 BD500001018A0080 4978 14.52 OK Error
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
#
# In your "apps.yaml" file, put the following lines
# zeversolar_sensor:
# module: appd_ZeverSolarSensor
# class: ZeverSolarSensor
#-------------------------------------------------------------------------------
import hassapi as hass
import urllib.request
import datetime
# Check if server is up or down
# https://docs.python.org/3.1/howto/urllib2.html
from urllib.request import Request, urlopen
from urllib.error import URLError
from datetime import datetime
from datetime import timedelta
#-------------------------------------------------------------------------------
# Global constants
# Get the below from Router
#-------------------------------------------------------------------------------
zeverSolarURL = "http://192.168.50.163/home.cgi" # Change this to your ZeverSolar Inverter IP address
datetimeFormat = "%d/%m/%Y %H:%M" # Format for strftime()
generationFormat = "{:.2f}"
refreshInterval = 120 # Time interval to read the URL in seconds
genPowerIndex = 11 # Index into the returned string from the URL
dailyEnergyIndex = 12 # Index into returned string from the URL
#-------------------------------------------------------------------------------
# Class to be called by AppDaemon
# Remember to declare this class and the module in apps.yaml
#-------------------------------------------------------------------------------
class ZeverSolarSensor(hass.Hass):
#---------------------------------------------------------------------
#-- Initialise the module
def initialize(self):
self.log("------------------------------------------------", log="main_log")
self.log("Initiatilize: ZeverSolar Sensor", log="main_log")
#-- Intialise some local variables
self.generatedPower = 0.00 # In kW
self.totalEnergyDaily = 0.00 # In KwH
self.dateOfReading = datetime.now()
#-- Run first time in 5 sec
self.run_in(self.doGetGenAndSendAsSensor, 5)
#-- Then run it every refreshInterval
startTime = datetime.now() + timedelta(seconds=refreshInterval)
self.run_every(self.doGetGenAndSendAsSensor, startTime, refreshInterval)
#---------------------------------------------------------------------
#-- Get generation and send out as sensor
def doGetGenAndSendAsSensor(self, arg):
self.log("----- ZeverSolar sensor callback -----", log="main_log")
#-- Get the generated power & energy
self.requestSolarGeneration(self)
lastUpdated = self.dateOfReading.strftime(datetimeFormat) # Last updated
lastReset = self.dateOfReading.strftime("%Y-%m-%d 00:00:00+02:00")
#-- Output the sensor values
#-- Instantaneous Generated power
stateInfo1 = generationFormat.format(self.generatedPower)
self.set_state("sensor.zeverSolar_generated_power", state=stateInfo1, attributes=\
{"unit_of_measurement": "kW", \
"last_reset" : lastReset, \
"state_class": "measurement", \
"device_class": "energy", \
"icon": "mdi:white-balance-sunny", \
"friendly_name": "Generated Power",
"lastUpdated": lastUpdated
})
#-- Daily energy generated
#- Icons are located at http://materialdesignicons.com/
stateInfo2 = generationFormat.format(self.totalEnergyDaily)
self.set_state("sensor.zeverSolar_daily_energy", state=stateInfo2, attributes=\
{"unit_of_measurement": "kWh", \
"last_reset" : lastReset, \
"state_class": "measurement", \
"device_class": "energy", \
"icon": "mdi:white-balance-sunny", \
"friendly_name": "Daily Generated Energy",
"lastUpdated": lastUpdated
})
#-- Send out a log to the appdaemon console
self.log("Updated: " + lastUpdated + " Gen: " + stateInfo1 + "kW, Daily energy: " + stateInfo2 + "kWh", log="main_log")
#---------------------------------------------------------------------
#-- Gets the reading from the URL. Returns 0 if no generation
def requestSolarGeneration(self, arg):
self.dateOfReading = datetime.now() # Get date & time of reading
req = Request(zeverSolarURL)
try:
response = urlopen(req)
htmlresponse = response.read()
st = htmlresponse.decode()
st = st.split() # Convert the string into a list
#-- Get the string for the Generated Power and Daily Energy
genPower = st[genPowerIndex]
dailyEnergy = st[dailyEnergyIndex]
#-- Convert string into Int and Float
self.generatedPower = float(genPower)/1000 # Its in W eg. 4978. Convert into kW
self.totalEnergyDaily = float(dailyEnergy) # It is already in kWh eg. 14.52
return
except:
self.log("Error in connecting to Zever solar server", log="main_log")
self.generatedPower = 0.00
self.totalEnergyDaily = None
return
@iefke, you should make a small change in the code for the zeverSolar_daily_energy sensor.
Change state_class to "total_increasing"
{"unit_of_measurement": "kWh", \
"last_reset" : lastReset, \
"state_class": "total_increasing", \
"device_class": "energy", \
"icon": "mdi:white-balance-sunny", \
"friendly_name": "Daily Generated Energy",
"lastUpdated": lastUpdated
})
@iefke, you should make a small change in the code for the zeverSolar_daily_energy sensor.
Change state_class to "total_increasing"
{"unit_of_measurement": "kWh", \ "last_reset" : lastReset, \ "state_class": "total_increasing", \ "device_class": "energy", \ "icon": "mdi:white-balance-sunny", \ "friendly_name": "Daily Generated Energy", "lastUpdated": lastUpdated })
Thanks! That's fast. I will let you know tomorrow if it's working.......
Maybe you could also check the issue that I just submitted. #8 It might be something that affects your sensor too
It's working now. Also had to change code like you wrote above.
Thanks!!!
Got a response from Zeversolar support, this bug will not be fixed.
Sorry that Zeversolar ceased trading, we only support aftersales but no resource on the debug now. I don’t recommend you to read the data from /home.cgi, and you can retrieve data from cloud by API.
Hey, I have this app working in HA. And also visible in HA's new Energy Dashboard. Only at the end of the day when there is no more connection with the Zeversolar inverter, the sensor will show 0 (this is also correct). But in the Energy dashboard it goes to a negative value. Can anything be done about this?