Energy prices are not really logged

Use this forum to discuss possible implementation of a new feature before opening a ticket.
A developer shall edit the topic title with "[xxx]" where xxx is the id of the accompanying tracker id.
Duplicate posts about the same id. +1 posts are not allowed.

Moderators: leecollings, remb0

Post Reply
Zuikkis
Posts: 43
Joined: Monday 20 February 2017 17:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Energy prices are not really logged

Post by Zuikkis »

Hi,

I know this has already been discussed earlier and solutions are already found, but still.

I have hourly electricity prices. I already have scripts to fetch current price from Nordpool and price is showed in Domoticz and a cronjob sets some timers to launch at cheapest hours.

Also I have a 20kWh battery which I charge at cheap hours (or from my solar plant) and then discharge during expensive hours.

All this makes me want to see exact daily/monthly/yearly costs and savings from the battery, but it's not really something Domoticz is able to do.

All electricity meters have the "cost" view in "report" page, there you can see yearly/monthly/daily quite easily and that would be quite enough for me. I figured that i could just modify the "T1 price" in settings page each hour. But it doesn't work like that! If I change the price, it will affect the Report page even in the past!

This seems really silly. Surely energy companies sometimes change their pricing even on fixed plans? Or you might change providers and get different price. If you update the price in Domoticz, it ruins all your price data from past years. Domoticz apparently is only really logging kwh and then uses price*kwh to show the cost.
willemd
Posts: 631
Joined: Saturday 21 September 2019 17:55
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.1
Location: The Netherlands
Contact:

Re: Energy prices are not really logged

Post by willemd »

I am storing the costs components of my contract in user variables and then use a dzvent script to calculate the actual costs. The results are stored in some custom devices. Could that work for you?

Note it does not take into account the daily low and high rate periods. Only uses high rate in the calculation.

Code: Select all

return {
	on = {
		devices = {
		    -- idx of the Electricity P1 meter
			1 
		}
	},
	logging = {
		level = domoticz.LOG_ERROR,
		marker = 'costcalc',
	},
	execute = function(domoticz)
		-- idx numbers need to be adjusted for new installation
		-- idx of devices
		local idxElectricityP1=1
		local idxGasP1=2
		local idxElectricityCosts=18
		local idxGasCosts=19
		local idxTaxCosts=20
		local idxTotalCosts=21

		-- idx of user variables
		local idxElDalTarief=1
		local idxElNormaalTarief=2
		local idxElTransportRatePerDay=3
		local idxElTaxkWh=4
		local idxGasTarief=5
		local idxGasTransportRatePerDay=6
		local idxGasTaxM3=7
		local idxDeliveryFixedPerMonth=8
		local idxTaxReductionPerDay=9

	    -- Input Devices --
	    local todayEl = domoticz.devices(idxElectricityP1).counterToday
	    local todayElreturn = domoticz.devices(idxElectricityP1).counterDeliveredToday	    
	    local todayGas = domoticz.devices(idxGasP1).counterToday
	    -- Output Devices --
		local El_costs = domoticz.devices(idxElectricityCosts)
	    local Gas_costs = domoticz.devices(idxGasCosts)
	    local Tax_costs = domoticz.devices(idxTaxCosts)
	    local Total_costs = domoticz.devices(idxTotalCosts)
	    
	    -- Variables --
	    local El_rate_dal = domoticz.variables(idxElDalTarief).value
	    local El_rate_normal = domoticz.variables(idxElNormaalTarief).value
	    local El_transport = domoticz.variables(idxElTransportRatePerDay).value
	    local El_tax = domoticz.variables(idxElTaxkWh).value
	    
	    local Gas_rate = domoticz.variables(idxGasTarief).value
	    local Gas_transport = domoticz.variables(idxGasTransportRatePerDay).value
	    local Gas_tax = domoticz.variables(idxGasTaxM3).value
	    
	    local Delivery_fixed = domoticz.variables(idxDeliveryFixedPerMonth).value	   	
	   	local Taxreduction = domoticz.variables(idxTaxReductionPerDay).value 
	    
	    local EURO_El = tonumber(domoticz.utils.round((El_rate_normal * (todayEl-todayElreturn) + Delivery_fixed/31 + El_transport),2))
	    local EURO_Gas = tonumber(domoticz.utils.round(((Gas_rate * todayGas) + Delivery_fixed/31 + Gas_transport),2))
	    local EURO_Tax = tonumber(domoticz.utils.round((El_tax * (todayEl-todayElreturn)) + (Gas_tax * todayGas),2)) + Taxreduction
	    local EURO_Total = EURO_El + EURO_Gas + EURO_Tax
	    
	    El_costs.updateCustomSensor(domoticz.utils.round(EURO_El,2))
	    Gas_costs.updateCustomSensor(domoticz.utils.round(EURO_Gas,2))
	    Tax_costs.updateCustomSensor(domoticz.utils.round(EURO_Tax,2))
	    Total_costs.updateCustomSensor(domoticz.utils.round(EURO_Total,2))
		
	end
}
Zuikkis
Posts: 43
Joined: Monday 20 February 2017 17:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Energy prices are not really logged

Post by Zuikkis »

Thanks! Yes I found something similar already from this forum. I will do it that way.

It's just sad that Domoticz already has cost calculation but it's useless with variable rates... :(
Zuikkis
Posts: 43
Joined: Monday 20 February 2017 17:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Energy prices are not really logged

Post by Zuikkis »

Ok everything is working now. :)

Instead of generic "custom" type for the price counter, I used "counter incremental":
Counter Incremental

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=1

will increment the counter value by 1. To reset an incremental counter, set the svalue to a negative integer equal to the current total of the counter
.

This seems to be working but we'll see until I actually have more data! I just have a cron job that gets last hours Wh from domoticz, calculates price, and feeds this incremental counter with the result. Domoticz then actually calculates daily/monthly/yearly automatically.

The units of "incremental counter" default to kWh but that can be changed: (sorry for the Finnish locale)
Kuvakaappaus 2022-11-23 14-39-32.png
Kuvakaappaus 2022-11-23 14-39-32.png (87.21 KiB) Viewed 773 times
Zuikkis
Posts: 43
Joined: Monday 20 February 2017 17:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Energy prices are not really logged

Post by Zuikkis »

Hmm, everything seems to be working, but daily graph is really messed up if there are negative numbers.
Screenshot_20221124-133757_Firefox.jpg
Screenshot_20221124-133757_Firefox.jpg (161.36 KiB) Viewed 758 times
This is the price of my battery use. The price is negative during cheap hours when it's charging, then positive during day when the battery is being used. Apparently the negative values wrap to unsigned integers?

It's only the 24h graph that's incorrect, week/month/year are correct and also the top level shows this which is correct:

Screenshot 2022-11-24 at 13-45-18 Kuva - Google Kuvat.png
Screenshot 2022-11-24 at 13-45-18 Kuva - Google Kuvat.png (313.37 KiB) Viewed 758 times
HennyN
Posts: 13
Joined: Friday 21 May 2021 21:42
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.7
Location: Achterhoek
Contact:

Re: Energy prices are not really logged

Post by HennyN »

willemd wrote: Wednesday 23 November 2022 10:56 I am storing the costs components of my contract in user variables and then use a dzvent script to calculate the actual costs. The results are stored in some custom devices. Could that work for you?

Note it does not take into account the daily low and high rate periods. Only uses high rate in the calculation.
This script I use and does take daily low and high rate periods into account. And uses both in calculation.

Code: Select all

return {
        on = { timer = { 'every 15 minutes' }}, 

        execute = function(domoticz, device, timer)

        local vandaagKwh      = domoticz.devices('Power').counterToday 
        local vandaagM3Gas    = domoticz.devices('Gas').counterToday 
               
        local StroomKosten  = domoticz.devices('StroomKosten')
        local GasKosten     = domoticz.devices('GasKosten')
        local TotaalKosten  = domoticz.devices('EnergieKosten')
        local KostenE       = domoticz.devices('KostenElektra')
        local KostenG       = domoticz.devices('KostenGas')
        local KostenET      = domoticz.devices('KostenEnergie')
        
       -- Eenheidsprijs in Euro's / Kwh - M3
        local kwhPrijs = 0.22903
        local gasM3Prijs = 0.74681
        

        if (domoticz.time == 'Between 23:00 and 07:00') or (domoticz.day == 'Saturday') or (domoticz.day == 'Sunday') then
            kwhPrijs = 0.21024 -- Daltarief
        else
            kwhPrijs = 0.22903 -- Normaal tarief
        end 
       
        -- Vaste kosten in Euro's per dag (zoals vastrecht) 
        local kwhPrijsVast = 0.70132
        local gasM3PrijsVast = 0.54740
        
        -- Kosten berekenen
        local KwhKosten = tonumber(domoticz.utils.round( (kwhPrijs * vandaagKwh) + kwhPrijsVast,2))   
        local GasM3Kosten = tonumber(domoticz.utils.round( (gasM3Prijs * vandaagM3Gas) + gasM3PrijsVast,2))
        local KostenTotaal = KwhKosten + GasM3Kosten
        local KwhKostenCount = 100 * KwhKosten
        local GasM3KostenCount = 100 * GasM3Kosten
	    local KostenTotaalCount = 100 * KostenTotaal
        
        -- Kosten updaten
        StroomKosten.updateCustomSensor(KwhKosten)
        GasKosten.updateCustomSensor(GasM3Kosten)
        TotaalKosten.updateCustomSensor(KostenTotaal)
        KostenE.updateCounter(KwhKostenCount)
        KostenG.updateCounter(GasM3KostenCount)
        KostenET.updateCounter(KostenTotaalCount)
        
    end
}
willemd
Posts: 631
Joined: Saturday 21 September 2019 17:55
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.1
Location: The Netherlands
Contact:

Re: Energy prices are not really logged

Post by willemd »

The problem with that script is that after 07:00 in the morning it starts to calculate with the normal rate and applies this to the full electricity usage of the day, not only to the usage after 07:00.

Here is my script, now also taking into account the low and high rate. It is only missing low rate of official public holiday's.

Note in my script the elctricity costs are stored in two devices (idx 18 and 105). This is for testing purposes, since I could not derive monthly data from device 18. I am now testing a counter device, to see also what happens when usage goes negative. In the end I will choose one of the two.

Code: Select all

-- this script calculates daily costs (update at every new measured value)
-- and adds them to the existing counter value of last midnight
-- it takes into account the periods of low and high rate
-- the rates in the user variables are including BTW/VAT

return {
	on = {
		devices = {
		    -- idx of the Electricity P1 meter
			1 
		},
		timer = {
		    'at 00:00'
		},    
	},
	data = {
	        -- persistent variables, values kept from one script run to the other, also after system reset
	        EndLowEl = { initial = 0 },
            EndHighEl = { initial = 0 },
            todayStartElCosts = { initial = 0 },
    },        
	logging = {
		level = domoticz.LOG_INFO,
		marker = 'new costcalc',
	},
	execute = function(domoticz,item)
	    
	    -- idx numbers need to be adjusted for new installation
		-- idx of devices
		local idxElectricityP1=1
		local idxGasP1=2
		local idxElectricityCosts=18
		local idxGasCosts=19
		local idxTaxCosts=20
		local idxTotalCosts=21
		local idxElCostsCounter=105

		-- idx of user variables
		local idxElDalTarief=1
		local idxElNormaalTarief=2
		local idxElTransportRatePerDay=3
		local idxElTaxkWh=4
		local idxGasTarief=5
		local idxGasTransportRatePerDay=6
		local idxGasTaxM3=7
		local idxDeliveryFixedPerMonth=8
		local idxTaxReductionPerDay=9

	    -- Input Devices --
	    local todayEl = domoticz.devices(idxElectricityP1).counterToday
	    local todayElreturn = domoticz.devices(idxElectricityP1).counterDeliveredToday	    
	    local todayGas = domoticz.devices(idxGasP1).counterToday
	    -- Output Devices --
		local El_costs = domoticz.devices(idxElectricityCosts)
	    local Gas_costs = domoticz.devices(idxGasCosts)
	    local Tax_costs = domoticz.devices(idxTaxCosts)
	    local Total_costs = domoticz.devices(idxTotalCosts)
	    
	    -- Variables --
	    local El_rate_dal = domoticz.variables(idxElDalTarief).value
	    local El_rate_normal = domoticz.variables(idxElNormaalTarief).value
	    local El_transport = domoticz.variables(idxElTransportRatePerDay).value
	    local El_tax = domoticz.variables(idxElTaxkWh).value
	    
	    local Gas_rate = domoticz.variables(idxGasTarief).value
	    local Gas_transport = domoticz.variables(idxGasTransportRatePerDay).value
	    local Gas_tax = domoticz.variables(idxGasTaxM3).value
	    
	    local Delivery_fixed = domoticz.variables(idxDeliveryFixedPerMonth).value	   	
	   	local Taxreduction = domoticz.variables(idxTaxReductionPerDay).value 
	    
	    local EURO_El = 0
	    local EURO_Gas = 0
	    local EURO_Tax = 0
	    local EURO_Total = 0
	    
    	if (item.isTimer) then
	        domoticz.data.todayStartElCosts=domoticz.devices(idxElCostsCounter).counter
	    else     
    	    if (tonumber(os.date("%H"))<7) or (tonumber(os.date("%w")))==0 or (tonumber(os.date("%w")))==6 then  -- day 0 or 6 is weekend
    	        domoticz.log('before 07:00 ' , domoticz.LOG_INFO)
    	        -- low El_rate 
    	        local NettLowEl=(todayEl-todayElreturn)
    	        EURO_El = tonumber(domoticz.utils.round((El_rate_dal * NettLowEl + Delivery_fixed/31 + El_transport),2))
    	        EURO_Gas = tonumber(domoticz.utils.round((Gas_rate * todayGas + Delivery_fixed/31 + Gas_transport),2))
    	        EURO_Tax = tonumber(domoticz.utils.round((El_tax * NettLowEl + Gas_tax * todayGas),2)) + Taxreduction
    	        EURO_Total = EURO_El + EURO_Gas + EURO_Tax
    	        domoticz.data.EndLowEl=NettLowEl
    	        
    	    else
    	        if (tonumber(os.date("%H"))==23) then
    	            domoticz.log('after 23:00 ' , domoticz.LOG_INFO)
    	        -- low rate
    	            local NettHighEl=domoticz.data.EndHighEl
    	            local NettLowEl=(todayEl-todayElreturn) - NettHighEl
    	            EURO_El = tonumber(domoticz.utils.round((El_rate_dal * NettLowEl + El_rate_normal * NettHighEl + Delivery_fixed/31 + El_transport),2))
    	            EURO_Gas = tonumber(domoticz.utils.round((Gas_rate * todayGas + Delivery_fixed/31 + Gas_transport),2))
    	            EURO_Tax = tonumber(domoticz.utils.round((El_tax * (NettLowEl+NettHighEl)  + Gas_tax * todayGas),2)) + Taxreduction
    	            EURO_Total = EURO_El + EURO_Gas + EURO_Tax
    	        
    	        else
    	        -- normal El_rate
    	            domoticz.log('between 07:00 and 23:00 ' , domoticz.LOG_INFO)
    	            local NettLowEl=domoticz.data.EndLowEl
    	            local NettHighEl=(todayEl-todayElreturn)-NettLowEl
    	            EURO_El = tonumber(domoticz.utils.round((El_rate_dal * NettLowEl + El_rate_normal * NettHighEl + Delivery_fixed/31 + El_transport),2))
    	            EURO_Gas = tonumber(domoticz.utils.round((Gas_rate * todayGas + Delivery_fixed/31 + Gas_transport),2))
    	            EURO_Tax = tonumber(domoticz.utils.round((El_tax * (NettLowEl+NettHighEl) + (Gas_tax * todayGas)),2)) + Taxreduction
    	            EURO_Total = EURO_El + EURO_Gas + EURO_Tax
    	            domoticz.data.EndHighEl=NettHighEl
    	        end
    	    end     
    	    El_costs.updateCustomSensor(domoticz.utils.round(EURO_El,2))
    	    Gas_costs.updateCustomSensor(domoticz.utils.round(EURO_Gas,2))
    	    Tax_costs.updateCustomSensor(domoticz.utils.round(EURO_Tax,2))
    	    Total_costs.updateCustomSensor(domoticz.utils.round(EURO_Total,2))
    	    
    	    domoticz.devices(idxElCostsCounter).updateCounter(domoticz.data.todayStartElCosts*100+EURO_El*100)
	    end    
		
	end
}
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests