Page 1 of 2
Calculate daily energy cost
Posted: Tuesday 25 September 2018 22:28
by tristanp
I am trying to accomplish something really simple (but I have never used LUA, so I am really struggling....)
I have a USB P1 energy + gas meter I want to extract the "CounterToday" from the sensor called "Stroom" (energy) - I would like to multiply that by 0.20 (power cost per KwH) and update this to a dummy sensor "Stroomkosten vandaag" and the same thing for gas if possible so I can have these on a sweet little dashboard mounted on my livingroom wall.
I want the script to run everytime "CounterToday" updates.
Is there anyone who is willing to help me? Thanks in advance!
Re: Calculate daily energy cost
Posted: Tuesday 25 September 2018 23:52
by waaren
tristanp wrote: ↑Tuesday 25 September 2018 22:28
I am trying to accomplish something really simple (but I have never used LUA, so I am really struggling....)
I have a USB P1 energy + gas meter I want to extract the "CounterToday" from the sensor called "Stroom" (energy) - I would like to multiply that by 0.20 (power cost per KwH) and update this to a dummy sensor "Stroomkosten vandaag" and the same thing for gas if possible so I can have these on a sweet little dashboard mounted on my livingroom wall.
I want the script to run everytime "CounterToday" updates.
Is there anyone who is willing to help me? Thanks in advance!
in dzVents it would look like
Code: Select all
return {
on = { timer = { "every minute" }}, -- using every minute because Stroom and Gas are updated very frequently
-- on = { devices = { "Stroom","Gas" }}, -- Remove -- at the beginning of this line and place them the line above if
-- you want to trigger the script (much) more frequent
-- 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("Stroom").counterToday
local todayM3 = dz.devices("Gas").counterToday
local kwhTextdevice = dz.devices("Stroomkosten vandaag")
local m3Textdevice = dz.devices("Gaskosten vandaag")
-- Price in Euro's / Kwh - M3
local kwhPrice = 0.20
local gasM3Price = 0.44
-- Prepare text
local kwhText = "€ " .. tostring(dz.utils.round( (kwhPrice * todayKwh),2)):gsub("%.",",") -- rounded to two decimals and replace dot by comma
local m3Text = "€ " .. tostring(dz.utils.round( (gasM3Price * todayM3),2)):gsub("%.",",")
local function updateTextDeviceCheckFirst(device,text)
if text ~= device.text then -- Update only needed when new text is different fom previous text
dz.log(device.name .. " ==>> previous text: " .. device.text .. " ; new text " .. text,dz.LOG_DEBUG)
device.updateText(text)
end
end
-- call function
updateTextDeviceCheckFirst( kwhTextdevice, kwhText)
updateTextDeviceCheckFirst( m3Textdevice, m3Text)
end
}
When not familiar yet with Lua / dzVents), read
this Quickstart (only a couple of lines) and the "About dzVents .."just above this Quickstart section.
Re: Calculate daily energy cost
Posted: Monday 08 October 2018 12:11
by Thuis
Thank you very much, the script works like a charm
Re: Calculate daily energy cost
Posted: Wednesday 31 October 2018 11:43
by lodie
Hello,
I am getting an error, and don't know ow to fix it. I used te example and get this error
2018-10-31 11:42:00.574 Status: dzVents: Info: ------ Start external script: stroom.lua:, trigger: every minute
2018-10-31 11:42:00.603 Status: dzVents: Error (2.4.6): An error occured when calling event handler stroom
2018-10-31 11:42:00.603 Status: dzVents: Error (2.4.6): /home/pi/domoticz/scripts/dzVents/scripts/stroom.lua:26: attempt to concatenate field 'text' (a nil value)
2018-10-31 11:42:00.603 Status: dzVents: Info: ------ Finished stroom.lua
Re: Calculate daily energy cost
Posted: Thursday 01 November 2018 12:10
by MikeF
By making small changes to @waaren 's script, if you use custom sensors instead of text devices, then you can view graphs of your costs.
In the two lines under '--Prepare text', delete "€ " .. (these need to be numeric strings - add € as the axis label by editing the devices in the GUI).
In local function updateTextDeviceCheckFirst, change 'device.updateText(text)' to 'device.updateCustomSensor(text)'.
Here's an amended version of the script (I've changed the variable names for the costs, to show that these are custom sensors).
Code: Select all
return {
on = { timer = { "every minute" }}, -- using every minute because Stroom and Gas are updated very frequently
-- on = { devices = { "Stroom","Gas" }}, -- Remove -- at the beginning of this line and place them the line above if
-- you want to trigger the script (much) more frequent
-- 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("Stroom").counterToday
local todayM3 = dz.devices("Gas").counterToday
local kwhCustomdevice = dz.devices("Stroomkosten vandaag") -- custom sensor
local m3Customdevice = dz.devices("Gaskosten vandaag") -- custom sensor
-- Price in Euro's / Kwh - M3
local kwhPrice = 0.20
local gasM3Price = 0.44
-- Prepare text (add '€' as axis label by editing devices in GUI)
local kwhText = tostring(dz.utils.round( (kwhPrice * todayKwh),2)):gsub("%.",",") -- rounded to two decimals and replace dot by comma
local m3Text = tostring(dz.utils.round( (gasM3Price * todayM3),2)):gsub("%.",",")
local function updateTextDeviceCheckFirst(device,text)
if text ~= device.text then -- Update only needed when new text is different fom previous text
dz.log(device.name .. " ==>> previous text: " .. device.text .. " ; new text " .. text,dz.LOG_DEBUG)
device.updateCustomSensor(text)
end
end
-- call function
updateTextDeviceCheckFirst( kwhCustomdevice, kwhText)
updateTextDeviceCheckFirst( m3Customdevice, m3Text)
end
}
Re: Calculate daily energy cost
Posted: Thursday 01 November 2018 16:13
by Toulon7559
Did you look at Domoticz' Setup => Setup => Meters/Counters?
In that section you can set all tariffs you like to have .......
Thinking Out-of-the-box for alternative solution
If you upload your info for production & consumption to PVOutput.org, the answer becomes very simple:
under Settings just insert the information for the various tariffs and the times that they are applicable.
Then PVOutput calculates the yield respectively the cost.
Re: Calculate daily energy cost
Posted: Friday 30 November 2018 21:05
by Yardco
Im getting an error message as well, just like @lodie. Anyone who has an idea on how to fix this?
Re: Calculate daily energy cost
Posted: Tuesday 16 April 2019 13:10
by yazoo
Help i get an error
2019-04-16 12:57:00.640 Status: dzVents: Info: ------ Start internal script: Stroom:, trigger: every minute
2019-04-16 12:57:00.693 Status: dzVents: Error (2.4.16): An error occured when calling event handler Stroom
2019-04-16 12:57:00.693 Status: dzVents: Error (2.4.16): ...pi/domoticz/scripts/dzVents/generated_scripts/Stroom.lua:22: attempt to concatenate field 'text' (a nil value)
What i do wrong
script:
return {
on = { timer = { "every minute" }}, -- using every minute because Stroom and Gas are updated very frequently
-- on = { devices = { "Stroom" }}, -- Remove -- at the beginning of this line and place them the line above if
-- you want to trigger the script (much) more frequent
-- 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("Stroom").counterToday
local kwhCustomdevice = dz.devices("Stroomkosten vandaag") -- custom sensor
-- Price in Euro's / Kwh - M3
local kwhPrice = 0.22
-- Prepare text (add '€' as axis label by editing devices in GUI)
local kwhText = tostring(dz.utils.round( (kwhPrice * todayKwh),2)):gsub("%.",",") -- rounded to two decimals and replace dot by comma
local function updateTextDeviceCheckFirst(device,text)
if text ~= device.text then -- Update only needed when new text is different fom previous text
dz.log(device.name .. " ==>> previous text: " .. device.text .. " ; new text " .. text,dz.LOG_DEBUG)
device.updateCustomSensor(text)
end
end
-- call function
updateTextDeviceCheckFirst( kwhCustomdevice, kwhText)
end
}
Re: Calculate daily energy cost
Posted: Tuesday 16 April 2019 14:37
by EdwinK
Line 22 is:
Code: Select all
local m3Text = tostring(dz.utils.round( (gasM3Price * todayM3),2)):gsub("%.",",")
since you don't have
the script is unable to calculate it.
Re: Calculate daily energy cost
Posted: Tuesday 16 April 2019 14:48
by EdwinK
Now I have an error myself
Code: Select all
2019-04-16 14:44:00.226 Status: dzVents: Error (2.4.18): EnergyCost: ...pi/domoticz/scripts/dzVents/generated_scripts/Kosten.lua:25: attempt to index local 'device' (a nil value)
I know what it is supposed to do, but can't figure out why it isn't doing that.
Re: Calculate daily energy cost
Posted: Tuesday 16 April 2019 21:04
by waaren
yazoo wrote: ↑Tuesday 16 April 2019 13:10
Help i get an error
2019-04-16 12:57:00.640 Status: dzVents: Info: ------ Start internal script: Stroom:, trigger: every minute
2019-04-16 12:57:00.693 Status: dzVents: Error (2.4.16): An error occured when calling event handler Stroom
2019-04-16 12:57:00.693 Status: dzVents: Error (2.4.16): ...pi/domoticz/scripts/dzVents/generated_scripts/Stroom.lua:22: attempt to concatenate field 'text' (a nil value)
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
}
Re: Calculate daily energy cost
Posted: Wednesday 17 April 2019 9:47
by yazoo
Thanks @waaren this was the sulution its working now.
Re: Calculate daily energy cost
Posted: Wednesday 17 April 2019 10:37
by EdwinK
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.
Re: Calculate daily energy cost
Posted: Friday 19 April 2019 15:04
by smika
I'va got the following error in the log file after create this lua with the internal editor and add the dummy sensors.
2019-04-19 08:00:37.674 Error: EventSystem: in costs: [string "return {..."]:4: attempt to index global 'domoticz' (a nil value)
Can someone hint me to the right direction?
Thanks,
Smika
Re: Calculate daily energy cost
Posted: Friday 19 April 2019 16:37
by waaren
smika wrote: ↑Friday 19 April 2019 15:04
I'va got the following error in the log file after create this lua with the internal editor and add the dummy sensors.
2019-04-19 08:00:37.674 Error: EventSystem: in costs: [string "return {..."]:4: attempt to index global 'domoticz' (a nil value)
Can someone hint me to the right direction?
Thanks,
Smika
Try choosing dzVents in the internal editor.
Re: Calculate daily energy cost
Posted: Saturday 20 April 2019 0:37
by waaren
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
}
Re: Calculate daily energy cost
Posted: Saturday 20 April 2019 9:23
by EdwinK
Seems to work, but.. where does it get it tariffs from?
Re: Calculate daily energy cost
Posted: Saturday 20 April 2019 11:16
by waaren
EdwinK wrote: ↑Saturday 20 April 2019 9:23
Seems to work, but.. where does it get it tariffs from?
Tariffs for gas and electricity are from what you entered in the fields gas Costs, Costs T1,Costs T2,Costs R1 and Costs R2 in tab [setup][system][meters/counters]
fixed Transport + contract costs per month in Euro's are to be entered in the script between the *** lines
Re: Calculate daily energy cost
Posted: Saturday 20 April 2019 15:31
by EdwinK
Maybe I'm overlooking something but this is the part between those lines:
Code: Select all
-- 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 = 3,46
local gasFixedMonth = 3,46
I don't see any other lines to put those data.
Re: Calculate daily energy cost
Posted: Saturday 20 April 2019 15:34
by EdwinK
Nevermind... Found it