Page 2 of 2
Re: Calculate daily energy cost
Posted: Thursday 24 October 2019 22:13
by Piacco
Hello,
I'am want to calculate the total daily energycost.
But i'am struggling with the P1 data, i can read the total daily used energy with the following code
Code: Select all
local todayKwh= dz.devices('Power').counterToday -- Used energy today
But how can i read the counter Return today the code below is not working
Code: Select all
local ReturntodayKwh= dz.devices('Power').counterTodayReturn -- Delivered energy today
Re: Calculate daily energy cost
Posted: Thursday 24 October 2019 22:45
by waaren
Piacco wrote: ↑Thursday 24 October 2019 22:13
How can i read the counter Return today ?
If you look at the
wiki P1 subject you will find the correct attribute.
Try
Code: Select all
local ReturntodayKwh= dz.devices('Power').counterDeliveredToday
Re: Calculate daily energy cost
Posted: Sunday 27 October 2019 17:25
by Piacco
Thanks @waaren, next time i will have a better look in the wiki
Re: Calculate daily energy cost
Posted: Friday 05 June 2020 13:27
by plugge
waaren wrote: ↑Saturday 20 April 2019 0:37
EdwinK wrote: ↑Wednesday 17 April 2019 10:37
Working for me too
Just something else.. I have two tariffs for electricity, (High and low (11pm-07am). How can I add those, and I guess that the other settings are for transportation costs.
Working with tariffs and returning energy to the grid (solar panels) need a different approach.
Can you try below script ?
Code: Select all
--[[
put today's electricity and / or today's Gas usage costs in custom virtual sensor
Collect information from a P1 device and /or a Gas device
electricity takes different tariffs and returns (from solarpanels or the likes) into account.
]]--
local scriptVar = "dailyEnergyCost"
return {
on = { timer = { "every 6 minutes" }, -- using 6 minutes because Stroom and Gas are updated very frequently
httpResponses = { scriptVar .. "*" },
},
logging = { level = domoticz.LOG_DEBUG, -- change to LOG_ERROR when script executes OK
marker = sciptVar},
data = { energyCosts = { initial = {} }
},
execute = function(dz, item)
-- ********************************************************************* Your changes below this line *************
-- input Devices
local electricity = dz.devices("Power") -- P1 device or comment this line
local gas = dz.devices("Gas") -- Gas meter or comment this line
-- outPut Devices
local electricityCost = dz.devices("electricityCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
local gasCost = dz.devices("gasCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
-- fixed Transport + contract costs per month in Euro's
local electricityFixedMonth = 6.31
local gasFixedMonth = 6.31
-- ********************************************************************** No changes below this line **************
local function getDaysForMonth(month, year) -- Returns number of days in given or current month
if month == nil then month = dz.time.month end
if year == nil then year = dz.time.year end
return os.date('*t',os.time{year=year,month=month+1,day=0}).day
end
local function triggerJSON(url, response, delay)
local delay = delay or 0
dz.openURL({ url = url,
method = "GET",
callback = response}).afterSec(delay)
end
local function getCosts(id) -- these costs should be set in domoticz settings
if next(dz.data.energyCosts) == nil or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
local costURL = dz.settings['Domoticz url'] .. "/json.htm?param=getcosts&type=command&idx=" .. id
triggerJSON(costURL, scriptVar .. "_cost")
end
return ( next(dz.data.energyCosts) ~= nil )
end
local function makeCostTable(t) -- (re)Create costTable if not existing yet; Refreshed at least once a day
if next( dz.data.energyCosts ) == nil or dz.data.energyCosts.creationTime < ( dz.time.dDate - dz.time.secondsSinceMidnight ) then
dz.data.energyCosts = t
dz.data.energyCosts.electricityFixedDay = (electricityFixedMonth or 0 ) / getDaysForMonth()
dz.data.energyCosts.gasFixedDay = (gasFixedMonth or 0 ) / getDaysForMonth()
dz.data.energyCosts.creationTime = dz.time.dDate
dz.data.energyCosts.humanReadableCreationTime = dz.time.raw
end
end
local function updateCustomSensor(device, value)
local currentValue = device.rawData[1]
if value ~= tonumber(currentValue) then -- Update only needed when new value is different fom previous one
dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
device.updateCustomSensor(value)
end
end
local function getEnergy(id)
local energyURL = dz.settings['Domoticz url'] .. "/json.htm?range=month&sensor=counter&type=graph" ..
"&actmonth=" .. dz.time.month ..
"&idx=" .. id
triggerJSON(energyURL, scriptVar .. "_energy")
end
local function makeTodaysGasCosts()
local gasTodayCost
if gasCost then
gasTodaysCost = dz.data.energyCosts.gasFixedDay * 10000
gasTodaysCost = gasTodaysCost + gas.counterToday * dz.data.energyCosts.CostGas
end
return dz.utils.round(gasTodaysCost / 10000, 2)
end
local function makeTodaysElectricityCosts(t)
local today
for i, record in ipairs(t) do
if record.d == dz.time.rawDate then
today = i
end
end
local electricityTodaysCost
if electricityCost then
electricityTodaysCost = dz.data.energyCosts.electricityFixedDay * 10000
if today then
electricityTodaysCost = electricityTodaysCost + t[today].v * dz.data.energyCosts.CostEnergy
electricityTodaysCost = electricityTodaysCost + t[today].v2 * dz.data.energyCosts.CostEnergyT2
electricityTodaysCost = electricityTodaysCost - t[today].r1 * dz.data.energyCosts.CostEnergyR1
electricityTodaysCost = electricityTodaysCost - t[today].r2 * dz.data.energyCosts.CostEnergyR2
end
end
return dz.utils.round(electricityTodaysCost / 10000,2)
end
local function updateCustomSensor(device, value)
if device == nil or value == nil then
return
end
local currentValue = device.rawData[1]
if value ~= tonumber(currentValue) then -- Update only needed when new value is different fom previous one
dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
device.updateCustomSensor(value)
end
end
if not ( item.isHTTPResponse ) then
if not ( getCosts(electricity.id) ) then
-- logWrite("No or outdated costs. Next time the costs will be there")
return
end
-- logWrite("-- costs are there; get energy data")
getEnergy(electricity.id)
elseif item.trigger == ( scriptVar .. "_energy" ) then
updateCustomSensor( electricityCost, makeTodaysElectricityCosts(item.json.result))
updateCustomSensor( gasCost, makeTodaysGasCosts())
else
makeCostTable(item.json)
end
end
}
@waaren. Thank you for this script, it's works fine for me. I am new to Domoticz, still learning.
I have added a user variable to gather the accumulated costs for gas and electricity for each day during a contract period (i.e., a year).
However, I could not find the moment in the script where the final daily costs are ready (to be intercepted by me, to be added to my user variable) and a new counter for the day starts. I know that it is around midnight and involves the fixed costs for the day. But where in your script could I intercept the final daily costs? (If I setup a test based on a guess, I'll have to wait a day to see if it works. :-/ )
Thank you for any help!
Re: Calculate daily energy cost
Posted: Friday 05 June 2020 17:19
by waaren
plugge wrote: ↑Friday 05 June 2020 13:27Where in your script could I intercept the final daily costs?
If you retrieve the values from the energyCost and gasCost devices just below line 135
You should find the final daily costs. This part of the script will execute shortly after midnight so the costs are from yesterday
Re: Calculate daily energy cost
Posted: Saturday 06 June 2020 2:12
by plugge
Thank you waaren!
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 15:13
by plugge
waaren wrote: ↑Tuesday 16 April 2019 21:04
the method text is not available for device type custom sensor. You need another function to do that. Try this:
Code: Select all
return {
on = { timer = { "every 6 minutes" }}, -- using 6 minutes because Stroom and Gas are updated very frequently
logging = { level = domoticz.LOG_DEBUG, -- Remove -- on these two lines if you want debug logging
marker = "EnergyCost" },
execute = function(dz)
-- Devices
local todayKwh = dz.devices("Power").counterToday
local todayM3 = dz.devices("Gas").counterToday
local energyCost = dz.devices("energyCost today") -- define this virtual sensor as Custom sensor
local gasCost = dz.devices("gasCost today") -- define this virtual sensor as Custom sensor
-- Price in Euro's / Kwh - M3
local kwhPrice = 0.20
local gasM3Price = 0.62
local kwHFixedDay = 6.99 / 31
local m3FixedDay = 6.99 / 31
-- calculations
local kwhValue = dz.utils.round( (kwhPrice * todayKwh + kwHFixedDay),2) -- rounded to two decimals
local m3Value = dz.utils.round( (gasM3Price * todayM3 + m3FixedDay),2)
local function updateCustomSensor(device, value)
local currentValue = device.rawData[1]
if value ~= tonumber(currentValue) then -- Update only needed when new value is different fom previous one
dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
device.updateCustomSensor(value)
end
end
-- call function
updateCustomSensor(energyCost, kwhValue)
updateCustomSensor(gasCost, m3Value)
end
}
Hi,
In the above code, the following function - updateCustomSensor(device, value) - turns out to be always true, even when currentValue and value are equal:
Code: Select all
local function updateCustomSensor(device, value)
if device == nil or value == nil then
return
end
local currentValue = device.rawData[1]
if value ~= tonumber(currentValue) then -- Update only needed when new value is different fom previous one
dz.log(device.name .. " ==>> previous value: " .. currentValue .. " ; new value " .. value,dz.LOG_DEBUG)
device.updateCustomSensor(value)
end
end
See my log snippet:
Code: Select all
2020-06-26 15:00:00.462 Status: dzVents: Info: ------ Start internal script: DailyEnergyCosts: HTTPResponse: "dailyEnergyCosts_energy"
2020-06-26 15:00:00.488 Status: dzVents: Info: Power costs today ==>> previous value: -1.01 ; new value -1.01
2020-06-26 15:00:00.488 Status: dzVents: Info: Gas costs today ==>> previous value: 1.04 ; new value 1.04
2020-06-26 15:00:00.488 Status: dzVents: Info: Energy costs today ==>> previous value: 0.03 ; new value 0.03
2020-06-26 15:00:00.490 Status: dzVents: Info: ------ Finished DailyEnergyCosts
This should never enter the log since both values are the same.
Any idea what could be wrong?
TIA
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 16:20
by waaren
plugge wrote: ↑Friday 26 June 2020 15:13
..... This should never enter the log since both values are the same.
Any idea what could be wrong?
TIA
Maybe value is not a numbertype in
Code: Select all
if value ~= tonumber(currentValue) then
Try changing this in
Code: Select all
if tonumber(value) ~= tonumber(currentValue) then
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 16:49
by plugge
waaren wrote: ↑Friday 26 June 2020 16:20
plugge wrote: ↑Friday 26 June 2020 15:13
..... This should never enter the log since both values are the same.
Any idea what could be wrong?
TIA
Maybe value is not a numbertype in
Code: Select all
if value ~= tonumber(currentValue) then
Try changing this in
Code: Select all
if tonumber(value) ~= tonumber(currentValue) then
Hi waaren, that was my first thought, but that didn't make any difference. The rule keeps firing with equal tonumber() values, but shouldn't:
Code: Select all
2020-06-26 16:20:00.086 Status: EventSystem: Script event triggered: D:\Program Files (x86)\Domoticz\dzVents\runtime\dzVents.lua
2020-06-26 16:20:00.200 Status: dzVents: Info: ------ Start internal script: DailyEnergyCosts: HTTPResponse: "dailyEnergyCosts_energy"
2020-06-26 16:20:00.226 Status: dzVents: Info: Energy costs today ==>> previous value: -0.18 ; new value -0.18
2020-06-26 16:20:00.227 Status: dzVents: Info: ------ Finished DailyEnergyCosts
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 17:18
by plugge
Maybe lua doesn't like the following function call?
Code: Select all
updateCustomSensor( energyCost, gascosts + powercosts)
Changed it by moving the addition to a local
Code: Select all
local sum = tonumber(gascosts) + tonumber(powercosts)
updateCustomSensor( energyCost, sum)
That seems to do the trick.
Still puzzled about the behavior though.
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 17:43
by plugge
plugge wrote: ↑Friday 26 June 2020 17:18
That seems to do the trick.
Still puzzled about the behavior though.
No, it doesn't. The rule still fires with (seemingly) equal values:
Code: Select all
2020-06-26 17:30:00.673 Status: dzVents: Info: Energy costs today ==>> previous value: -0.38 ; new value -0.38
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 18:34
by waaren
plugge wrote: ↑Friday 26 June 2020 17:43
No, it doesn't. The rule still fires with (seemingly) equal values:
what about ?
Code: Select all
if dz.utils.round(tonumber(value),2) ~= dz.utils.round(tonumber(currentValue),2) then
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 19:15
by plugge
Nope.
Code: Select all
2020-06-26 18:45:00.230 Status: dzVents: Info: Energy costs today ==>> previous value: -0.42 ; new value -0.43
2020-06-26 18:50:00.541 Status: dzVents: Info: Energy costs today ==>> previous value: -0.43 ; new value -0.43
2020-06-26 18:55:00.477 Status: dzVents: Info: Energy costs today ==>> previous value: -0.43 ; new value -0.43
2020-06-26 19:00:01.204 Status: dzVents: Info: Energy costs today ==>> previous value: -0.43 ; new value -0.41
Interestingly it only occurs with the custom sensor that I added. Same type as the custom gas and power sensors. But apparently something is different with the value stored.
Now trying to see what happens when:
Code: Select all
local currentValue = dz.utils.round(tonumber(device.rawData[1],2)
Re: Calculate daily energy cost
Posted: Friday 26 June 2020 19:25
by plugge
plugge wrote: ↑Friday 26 June 2020 19:15
Now trying to see what happens when:
Code: Select all
local currentValue = dz.utils.round(tonumber(device.rawData[1],2)
That did the trick!
No more equal value entries in the log, so the rule works.
Apparently the print() in the log truncates values?
Thanx