Page 1 of 1

Calculate daily kWh based on a cumulative kWh device

Posted: Tuesday 15 June 2021 20:57
by riko
I would like to have a device that is showing the daily production of my solar panels to present in Dashticz. I'm using the Omnik-Data-Logger python script to retrieve the data from the inverter. Unfortunately this one only communicates TOTAL kWh produced (since installation). This is imported in a General / Custom sensor:
Knipsel.PNG
Knipsel.PNG (22.28 KiB) Viewed 1817 times
Now I'm struggling with a script that calculates the daily production on the basis of the kWh value midnight. I am thinking to use a script to log persistant kWh data during 24 hours. And use the getAtTime function to retrieve value of 00:00 and substract that from the actual reading. The plan is to use dz.time do determine the number of hours and minutes which was midnight. It sounds easy but I get lost in the time formatting. Can anyone help with this? (or is there even a simpeler solution for this challenge?)

What I have so far:

Code: Select all

return 
{
    active = true,
    on = {
      devices = {
                    23 -- IDX van Productie zonnepanelen in totale kwh
                  }
         },


    logging =    
    {   
        level = domoticz.LOG_DEBUG, -- change to LOG_ERROR when OK - was LOG_DEBUG
        marker = 'kwh_calc'
    },
    
    data =     
    { 
        production_store = 
        { 
            history = true, 
            maxHours = 25,
            maxItems = 7500,
		}
	},
    
		

    execute = function(dz, item)
	

		local round = dz.utils.round
		local Time                              = require('Time')
     		local currentTime                       = Time(dz.time.raw)
	
		
		-- begin script
	

	
        	local total_production = dz.devices(23)   -- IDX van Productie zonnepanelen in kwh
        	local daily_production = dz.devices(315)   -- IDX van Productie dummy sensor voor daily production
       
		local lastProductionWatt = round(tonumber(total_production.rawData[1]),1)
		dz.data.production_store.add(lastProductionWatt) 
 
 		local todays_production, index = dz.data.production_store.getAtTime(currentTime)
		
I've created a General / Custom sensor to write back the results (IDX 315)

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 16 June 2021 8:55
by psubiaco
Why not letting Domoticz to compute the kWh for you?
If you just use a Domoticz General/kWh counter, configured as "Computed", you can modify your python script to pass to Domoticz the average power (watt) measured in each interval, then Domoticz will display the power graph and also the computed imported energy.
Regards.
Paolo

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 16 June 2021 10:22
by riko
Thanks for the suggestion. I was considering this as well, there is a actual watt measured and reported every minute I think. But I was afraid that this will lead to wrong calculations as the production can change quite fast (clouds coming over etc). The inverter is registering the total kWh which is the 'real' one and always more precise I think

That means still in need of a script. Or are there also possibilities to let a Domoticz counter device count on the basis of a total kWh counter?

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 16 June 2021 12:42
by waltervl
If that is the case you definitely should use the Domoticz general KWh Counter as that also can accept the total Kwh from the inverter (setting from Device). You should adopt your python script for this. See also https://www.domoticz.com/wiki/Dummy_for ... counter.29

I use the Omnik Python plugin and have no issues. It is running fine reading the data directly from the converter.
https://github.com/sincze/Domoticz-Omni ... Web-Plugin

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 16 June 2021 17:28
by riko
Thanks, I tried different ways but didn't get it. It appears that I'm using another plugin (https://www.domoticz.com/wiki/Omnik_Solar_Inverter). What I've tried:
Create a new virtural device device: General/kWh, changed the python script so the 'idx_E_Total' value is sent to this device. I've ried various configurations (and each of the combinations) of the device
  • Type: Usage
  • Type: Return
  • Energy read: Computed
  • Energy read: From device
I see that the device received the total kWh number:
Knipsel4.PNG
Knipsel4.PNG (11.69 KiB) Viewed 1775 times
But the device value is not updated accordingly:
Knipse5l.PNG
Knipse5l.PNG (8.58 KiB) Viewed 1775 times
I think Domoticz just receives values like: 9331.2, 9131.3, 9131.4, etc etc. The device should calculate the delta and register this instead of taking the full number.

Any ideas?

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 16 June 2021 20:29
by waltervl
The URL for this device should look something like
Http://IP:PORT/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=POWER;ENERGY
POWER = current power
ENERGY = cumulative energy in Watt-hours (Wh)

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Thursday 17 June 2021 17:09
by riko
Thanks, I just saw that the Python script is indeed receiving the daily production from the inverter as well ('E Today': 15 kWh, nice sunny day):
Knipsel.PNG
Knipsel.PNG (16.82 KiB) Viewed 1753 times
But the full package of the script is a bit too complicated for me and I'm not familar with Python. It seems that this data element is not used to be sent to Domoticz (/home/pi/Omnik-Data-Logger/outputs/DomoticzOutput.py):

Code: Select all

#!/usr/bin/python

import PluginLoader
import urllib
import urllib2
import ConfigParser

config = ConfigParser.RawConfigParser()

#change to correct folder.
config.read(['/home/pi/Omnik-Data-Logger/config-default.cfg', '/home/pi/Omnik-Data-Logger/config.cfg'])

domoticz_host    = config.get('domoticz','domoticz_host')
domoticz_port    = config.get('domoticz','domoticz_port')
domoticz_url     = config.get('domoticz','domoticz_url')

idx_Temp = config.get('domoticz','idx_Temp')
idx_PV1_U = config.get('domoticz','idx_PV1_U')
idx_PV2_U = config.get('domoticz','idx_PV2_U')
idx_PV1_A = config.get('domoticz','idx_PV1_A')
idx_PV2_A = config.get('domoticz','idx_PV2_A')
idx_AC_Output = config.get('domoticz','idx_AC_Output')
idx_E_Total = config.get('domoticz','idx_E_Total')
idx_E_Current = config.get('domoticz','idx_E_Current')
url = ("http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url)

class DomoticzOutput(PluginLoader.Plugin):
    """Outputs the data from the Omnik inverter to Domoticz"""

    def process_message(self, msg):
        """Output the information from the inverter to Domoticz.

        Args:
            msg (InverterMsg.InverterMsg): Message to process
        """

        #Total AC energy generated by inverter in kWatt
        get_data = {
                'svalue': msg.e_total,
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_E_Total
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current AC power and today's total power
        get_data = {
                'svalue': str(msg.p_ac(1)) + ';' + str(msg.e_total * 1000),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_E_Current,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current inverter temperature
        if msg.temperature < 300: #inverter displays temperature of +/- 6352 degrees Celcius when not generating power
                get_data = {
                        'svalue': msg.temperature,
                        'type': 'command',
                        'param': 'udevice',
                        'idx' : idx_Temp,
                        'nvalue': '0'
                        }
                get_data_encoded = urllib.urlencode(get_data)
                full_url = url + '?' + get_data_encoded
                urllib.urlopen(full_url)

        #String 1 voltage
        get_data = {
                'svalue': msg.v_pv(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV1_U,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 2 voltage
        get_data = {
                'svalue': msg.v_pv(2),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV2_U,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 1 ampere
        get_data = {
                'svalue': msg.i_pv(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV1_A,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 2 ampere
        get_data = {
                'svalue': msg.i_pv(2),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV2_A,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current AC current
        get_data = {
                'svalue': msg.i_ac(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_AC_Output,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)
Does anybody have suggestion for a quick fix for this?

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Thursday 17 June 2021 17:32
by waltervl
You should change this line
'svalue': str(msg.p_ac(1)) + ';' + str(msg.e_total * 1000)

e_total is apparently today's total. You should find the absolute total from the Omnik values. What value is that in the livestats script? The H value?

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Friday 18 June 2021 13:55
by riko
It seems that I need to additionally export the e_today value to Domoticz. Looking at the code of the LiveStats:

Code: Select all

import PluginLoader


class ConsoleOutput(PluginLoader.Plugin):
    """Outputs the data from the Omnik inverter to stdout"""

    def process_message(self, msg):
        """Output the information from the inverter to stdout.

        Args:
            msg (InverterMsg.InverterMsg): Message to process
        """
        print "ID: {0}".format(msg.id)

        print "E Today: {0:>5}   Total: {1:<5}".format(msg.e_today, msg.e_total)
        print "H Total: {0:>5}   Temp:  {1:<5}"\
            .format(msg.h_total, msg.temperature)

        print "PV1   V: {0:>5}   I: {1:>4}".format(msg.v_pv(1), msg.i_pv(1))
        print "PV2   V: {0:>5}   I: {1:>4}".format(msg.v_pv(2), msg.i_pv(2))
        print "PV3   V: {0:>5}   I: {1:>4}".format(msg.v_pv(3), msg.i_pv(3))

        print "L1    P: {0:>5}   V: {1:>5}   I: {2:>4}   F: {3:>5}"\
            .format(msg.p_ac(1), msg.v_ac(1), msg.i_ac(1), msg.f_ac(1))
        print "L2    P: {0:>5}   V: {1:>5}   I: {2:>4}   F: {3:>5}"\
            .format(msg.p_ac(2), msg.v_ac(2), msg.i_ac(2), msg.f_ac(2))
        print "L3    P: {0:>5}   V: {1:>5}   I: {2:>4}   F: {3:>5}"\
            .format(msg.p_ac(3), msg.v_ac(3), msg.i_ac(3), msg.f_ac(3))
I've tried to add the e_today to the code, without any knowledge of Python and it seems that I missed something. I've added to the config.cfg file the line: 'idx_E_Today = 315 #nieuw'

config.cfg:

Code: Select all

################
### Settings ###
################

[general]
# General:enabled_plugins
# Choose which outputs to use
# Possible options: MysqlOutput,PVoutputOutput,ConsoleOutput,CSVOutput
enabled_plugins = DomoticzOutput

[domoticz]
domoticz_host      = 192.168.1.100
domoticz_port      = 8080
domoticz_url       = json.htm

# Provide IDX here of the specific devices was 23
idx_Temp      = 17
idx_PV1_U     = 18
idx_PV2_U     = 19
idx_PV1_A     = 20
idx_PV2_A     = 21
idx_AC_Output = 22
idx_E_Total   = 23
idx_E_Today   = 315 #nieuw
idx_E_Current = 24

[inverter]
# IP address of your Omnik inverter
ip = *********************
# Default for a Omnik with Wifi module
port = ***********************
# S/N of the wifi kit
wifi_sn = ************************
#use temperature of inverter for pvoutput
use_temperature = true

[mysql]
# Host where the mysql server is active
host = 127.0.0.1
user =
pass =
database =

[pvout]
# These two can be found at http://pvoutput.org/account.jsp
apikey = NOTAREALAPIKEY86e2258d4e29169fb79cf18b00
sysid  = 12345

[csv]
disable_header = false

[log]
# Log:Output
# Possible options: none,console,file (combinations are possible)
# Use none to disable logging
type = console

# Log:level
# Possible options: critical, error, warning, info, debug
level = debug

# Log:filename
# Output file for file logger
filename = omnik-export.log
In the file DomoticzOutput.py I've added this section:
#NIEUW today kWh generated
get_data = {
'svalue': msg.e_today,
'type': 'command',
'param': 'udevice',
'idx' : idx_E_Today
}
get_data_encoded = urllib.urlencode(get_data)
full_url = url + '?' + get_data_encoded
urllib.urlopen(full_url)

DomoticzOutput.py:

Code: Select all

#!/usr/bin/python

import PluginLoader
import urllib
import urllib2
import ConfigParser

config = ConfigParser.RawConfigParser()

#change to correct folder.
config.read(['/home/pi/Omnik-Data-Logger/config-default.cfg', '/home/pi/Omnik-Data-Logger/config.cfg'])

domoticz_host    = config.get('domoticz','domoticz_host')
domoticz_port    = config.get('domoticz','domoticz_port')
domoticz_url     = config.get('domoticz','domoticz_url')

idx_Temp = config.get('domoticz','idx_Temp')
idx_PV1_U = config.get('domoticz','idx_PV1_U')
idx_PV2_U = config.get('domoticz','idx_PV2_U')
idx_PV1_A = config.get('domoticz','idx_PV1_A')
idx_PV2_A = config.get('domoticz','idx_PV2_A')
idx_AC_Output = config.get('domoticz','idx_AC_Output')
idx_E_Total = config.get('domoticz','idx_E_Total')
idx_E_Today = config.get('domoticz','idx_E_Today') #nieuw
idx_E_Current = config.get('domoticz','idx_E_Current')
url = ("http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url)

class DomoticzOutput(PluginLoader.Plugin):
    """Outputs the data from the Omnik inverter to Domoticz"""

    def process_message(self, msg):
        """Output the information from the inverter to Domoticz.

        Args:
            msg (InverterMsg.InverterMsg): Message to process
        """


        #NIEUW today kWh generated
        get_data = {
                'svalue': msg.e_today,
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_E_Today
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)


        #Total AC energy generated by inverter in kWatt
        get_data = {
                'svalue': msg.e_total,
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_E_Total
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current AC power and today's total power
        get_data = {
                'svalue': str(msg.p_ac(1)) + ';' + str(msg.e_total * 1000),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_E_Current,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current inverter temperature
        if msg.temperature < 300: #inverter displays temperature of +/- 6352 degrees Celcius when not generating power
                get_data = {
                        'svalue': msg.temperature,
                        'type': 'command',
                        'param': 'udevice',
                        'idx' : idx_Temp,
                        'nvalue': '0'
                        }
                get_data_encoded = urllib.urlencode(get_data)
                full_url = url + '?' + get_data_encoded
                urllib.urlopen(full_url)

        #String 1 voltage
        get_data = {
                'svalue': msg.v_pv(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV1_U,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 2 voltage
        get_data = {
                'svalue': msg.v_pv(2),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV2_U,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 1 ampere
        get_data = {
                'svalue': msg.i_pv(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV1_A,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #String 2 ampere
        get_data = {
                'svalue': msg.i_pv(2),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_PV2_A,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)

        #Current AC current
        get_data = {
                'svalue': msg.i_ac(1),
                'type': 'command',
                'param': 'udevice',
                'idx' : idx_AC_Output,
                'nvalue': '0'
                }
        get_data_encoded = urllib.urlencode(get_data)
        full_url = url + '?' + get_data_encoded
        urllib.urlopen(full_url)
I have a General/custom sensor IDX 315 to which I try to export the data. This sensor is similar configured as the sensor that consumes the e_total (which part of the code I've tried to copy).

Any ideas what I missed?

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Friday 18 June 2021 15:35
by waltervl
I do not understand what you are trying to do.
As suggested you should use the Energy (Usage and Counter) device. It needs 2 values: POWER and Counter.
It also has history logging so you can compare the years.

But perhaps a lot easier is to use the real plugin.... Just install it and it will create everything for you. https://github.com/sincze/Domoticz-Omni ... Web-Plugin

Re: Calculate daily kWh based on a cumulative kWh device

Posted: Wednesday 23 June 2021 20:36
by riko
Just installed this plugin. Indeed very easy and with the result I was looking for. Thanks!