Page 1 of 1
Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 11:45
by DaanV
First of all, thank you for this great piece of software. I have been enjoying it a lot already.
At the moment I am trying to get a custom sensor to show my daily gas and energy costs. the complicating factor is that I have a double tariff meter and fixed daily costs.
I have used a script which I found at:
https://ehoco.nl/stroom-gas-en-waterkos ... -domoticz/
The standard script is for a single tariff meter, which is why I played around with the other script found in the comment section of the page.
The thing is, I don't get it to work. I don't get any errors, but I don't see any energy costs either. So, I have the following questions:
1. As Domoticz uses the T1 and T2 tariffs correctly, would it be possible to write a script that reads out the kwh usage of the usage1 and usage2 (i.e., T1 and T2), multiply it with the Costs from the Domoticz 'Meters/Counters' settings and show it in a Custom Sensor?
2. Given the script I have below, how could I add a rule that states that the 'khwPrijs' = 0.21 between 7.00 and 23.00 hours and that the KwhPrijs = 0.19 between 23.00 and 07.00 hours. Using the code from the website I mentioned, doesn't work.
I have spend a full day searching for solutions, but can't seem to find the answer. Your help is appreciated
Code: Select all
return {
-- on = { timer = { "every 5 minutes" }}, -- script draait iedere 5 minuten
on = { devices = { "Stroom","Gas","Waterverbruik" }}, -- Verwijder -- aan het begin van deze regel en plaats -- voor bovenstaande regel als
-- je het script wilt draaien zodra er een nieuw verbruik aan Domoticz is doorgegeven
execute = function(dz)
-- Devices
local vandaagKwh = dz.devices('Stroom').counterToday -- Stroommeter device
local vandaagM3Gas = dz.devices('Gas').counterToday -- Gasmeter device
local StroomKosten = dz.devices('Stroomkosten') -- Stroomkosten device
local GasKosten = dz.devices('Gaskosten') -- Gaskosten device
-- Eenheidsprijs in Euro's / Kwh - M3
local kwhPrijs = 0.21
local gasM3Prijs = 0.5836
-- Vaste kosten in Euro's per dag (zoals vastrecht)
local kwhPrijsVast = 0.89000
local gasM3PrijsVast = 0.79000
-- Kosten berekenen
local kwhKosten = tonumber(dz.utils.round( (kwhPrijs * vandaagKwh),2) + kwhPrijsVast)--)--:gsub("%.",",") -- rounded to two decimals and replace dot by comma
local GasM3Kosten = tonumber(dz.utils.round( (gasM3Prijs * vandaagM3Gas),2) + gasM3PrijsVast)--)--:gsub("%.",",")
-- Kosten updaten
StroomKosten.updateCustomSensor(kwhKosten)
GasKosten.updateCustomSensor(GasM3Kosten)
end
}
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 12:53
by waaren
DaanV wrote: ↑Thursday 02 May 2019 11:45
At the moment I am trying to get a custom sensor to show my daily gas and energy costs. the complicating factor is that I have a double tariff meter and fixed daily costs.
I have used a script which I found at:
https://ehoco.nl/stroom-gas-en-waterkos ... -domoticz/
Can you try this one ? If something is not clear please feel free to ask for clarification
Code: Select all
--[[
put today's electricity and / or today's Gas / and or todays Water usage costs in custom virtual sensor
Collect information from a P1 device and /or a Gas and /or water meter 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
local water = dz.devices("Water") -- Water 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
local waterCost = dz.devices("waterCost 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
local waterFixedMonth = 6.36
-- ********************************************************************** 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
local daysThisMonth = getDaysForMonth()
dz.data.energyCosts.electricityFixedDay = (electricityFixedMonth or 0 ) / daysThisMonth
dz.data.energyCosts.gasFixedDay = (gasFixedMonth or 0 ) / daysThisMonth
dz.data.energyCosts.waterFixedDay = (waterFixedMonth or 0 ) / daysThisMonth
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 makeTodaysWaterCosts()
local waterTodayCost
if waterCost then
waterTodaysCost = dz.data.energyCosts.waterFixedDay
dz.log("WaterFixed: " .. waterTodaysCost,dz.LOG_FORCED)
waterTodaysCost = waterTodaysCost + ( water.counterToday * dz.data.energyCosts.CostWater / ( dz.data.energyCosts.DividerWater * 100000))
dz.log("WaterToday: " .. waterTodaysCost,dz.LOG_FORCED)
end
return dz.utils.round(waterTodaysCost, 2)
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())
updateCustomSensor( waterCost, makeTodaysWaterCosts())
else
makeCostTable(item.json)
end
end
}
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 13:41
by DaanV
Thanks for your swift reply!
This is a familiar script. I have come across it and tested it before. The script seems to be working without errors.
There is just one problem: my fixed costs are calculated per day instead of on a monthly base. I tried to change that in the script, but it turns out my knowledge is not sufficient to change it.
If you could fix that, I would be very grateful.
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 14:28
by waaren
DaanV wrote: ↑Thursday 02 May 2019 13:41
There is just one problem: my fixed costs are calculated per day instead of on a monthly base. I tried to change that in the script, but it turns out my knowledge is not sufficient to change it.
If you could fix that, I would be very grateful.
What are your daily fixed costs for Gas, Power and Water ?
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 14:38
by DaanV
the fixed costs per day for electricity are -0,11286
the fixed costs per day for gas are 0,45619
I don't have a smart water meter
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 15:36
by waaren
DaanV wrote: ↑Thursday 02 May 2019 14:38
the fixed costs per day for electricity are -0,11286
the fixed costs per day for gas are 0,45619
I don't have a smart water meter
Please have a look at this one. If you use the same script-name make sure you delete <domoticz_dir>/scripts/dzVents/data/ __data_<scriptname.lua> before first run of this new script.
Code: Select all
--[[
put today's electricity and / or today's Gas / and or todays Water usage costs in custom virtual sensor
Collect information from a P1 device and /or a Gas and /or water meter 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 = scriptVar},
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
local water = dz.devices("Water") -- Water 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
local waterCost = dz.devices("waterCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
-- fixed Transport + contract costs per Year / Month or Day in Euro's
local electricityFixedMonth = 6.31 -- either electricityFixedyear, electricityFixedMonth or electricityFixedDay or comment this line
local gasFixedYear = 75.72 -- either gasFixedyear, gasFixedMonth or gasFixedDay or comment this line
local waterFixedDay = 0.2052 -- either waterFixedyear, waterFixedMonth or waterFixedDay or comment this line
-- ********************************************************************** 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 getDaysForYear(year) -- Returns number of days in given or current year
if year == nil then year = dz.time.year end
return (year%4==0 and (year%100~=0 or year%400==0) and 366 or 365)
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
local daysThisMonth = getDaysForMonth()
local daysThisYear = getDaysForYear()
dz.data.energyCosts = t
dz.data.energyCosts.electricityFixedDay = ( electricityFixedMonth and ( electricityFixedMonth / daysThisMonth )) or
( electricityFixedYear and ( electricityFixedYear / daysThisYear )) or
electricityFixedDay
dz.data.energyCosts.gasFixedDay = ( gasFixedMonth and ( gasFixedMonth / daysThisMonth )) or
( gasFixedYear and ( gasFixedYear / daysThisYear )) or
gasFixedDay
dz.data.energyCosts.waterFixedDay = ( waterFixedMonth and ( waterFixedMonth / daysThisMonth )) or
( waterFixedYear and ( waterFixedYear / daysThisYear )) or
waterFixedDay
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 makeTodaysWaterCosts()
local waterTodayCost
if waterCost then
waterTodaysCost = dz.data.energyCosts.waterFixedDay
dz.log("WaterFixed: " .. waterTodaysCost,dz.LOG_FORCED)
waterTodaysCost = waterTodaysCost + ( water.counterToday * dz.data.energyCosts.CostWater / ( dz.data.energyCosts.DividerWater * 100000))
dz.log("WaterToday: " .. waterTodaysCost,dz.LOG_FORCED)
end
return dz.utils.round(waterTodaysCost, 2)
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())
updateCustomSensor( waterCost, makeTodaysWaterCosts())
else
makeCostTable(item.json)
end
end
}
Re: Showing energy costs for double tarrif meter [Solved]
Posted: Thursday 02 May 2019 19:39
by DaanV
Thanks again. Thanks to your help, I've solved the puzzle. Turns out I was doing a couple of things wrong:
1. There is an option in the script to use the gasFixedDay/elecricityFixedDay command instead of yearly.
2. Apparently the T1 tariff in Domoticz is the nighttime tariff, whereas most energy supplier see T1 as the daytime tariff.
Just to be sure and for other people with similar questions, this is the script I used in the end:
Code: Select all
--[[
put today's electricity and / or today's Gas / and or todays Water usage costs in custom virtual sensor
Collect information from a P1 device and /or a Gas and /or water meter device
electricity takes different tariffs and returns (from solarpanels or the likes) into account.
]]--
local scriptVar = "dailyEnergyCost"
return {
on = { timer = { "every 1 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 = scriptVar},
data = { energyCosts = { initial = {} }
},
execute = function(dz, item)
-- ********************************************************************* Your changes below this line *************
-- input Devices
local electricity = dz.devices("Stroom") -- P1 device or comment this line
local gas = dz.devices("Gas") -- Gas meter or comment this line
-- local water = dz.devices("Water") -- Water meter or comment this line
-- outPut Devices
local electricityCost = dz.devices("Stroomkosten") -- define this virtual sensor as Custom sensor or comment this line when not used
local gasCost = dz.devices("Gaskosten") -- define this virtual sensor as Custom sensor or comment this line when not used
-- local waterCost = dz.devices("waterCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
-- fixed Transport + contract costs per Year / Month or Day in Euro's
local electricityFixedDay = -0.11286 -- either electricityFixedyear, electricityFixedMonth or electricityFixedDay or comment this line
local gasFixedDay = 0.45619 -- either gasFixedyear, gasFixedMonth or gasFixedDay or comment this line
-- local waterFixedDay = 0.2052 -- either waterFixedyear, waterFixedMonth or waterFixedDay or comment this line
-- ********************************************************************** 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 getDaysForYear(year) -- Returns number of days in given or current year
if year == nil then year = dz.time.year end
return (year%4==0 and (year%100~=0 or year%400==0) and 366 or 365)
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
local daysThisMonth = getDaysForMonth()
local daysThisYear = getDaysForYear()
dz.data.energyCosts = t
dz.data.energyCosts.electricityFixedDay = ( electricityFixedMonth and ( electricityFixedMonth / daysThisMonth )) or
( electricityFixedYear and ( electricityFixedYear / daysThisYear )) or
electricityFixedDay
dz.data.energyCosts.gasFixedDay = ( gasFixedMonth and ( gasFixedMonth / daysThisMonth )) or
( gasFixedYear and ( gasFixedYear / daysThisYear )) or
gasFixedDay
dz.data.energyCosts.waterFixedDay = ( waterFixedMonth and ( waterFixedMonth / daysThisMonth )) or
( waterFixedYear and ( waterFixedYear / daysThisYear )) or
waterFixedDay
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 makeTodaysWaterCosts()
-- local waterTodayCost
-- if waterCost then
-- waterTodaysCost = dz.data.energyCosts.waterFixedDay
-- dz.log("WaterFixed: " .. waterTodaysCost,dz.LOG_FORCED)
-- waterTodaysCost = waterTodaysCost + ( water.counterToday * dz.data.energyCosts.CostWater / ( dz.data.energyCosts.DividerWater * 100000))
-- dz.log("WaterToday: " .. waterTodaysCost,dz.LOG_FORCED)
-- end
-- return dz.utils.round(waterTodaysCost, 2)
-- 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())
-- updateCustomSensor( waterCost, makeTodaysWaterCosts())
else
makeCostTable(item.json)
end
end
}
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 19:49
by waaren
DaanV wrote: ↑Thursday 02 May 2019 19:39
I've solved the puzzle. Turns out I was doing a couple of things wrong:
Just to be sure and for other people with similar questions, this is the script I used in the end:
Your welcome. Please note that the only area you need to modify settings is between the lines
Code: Select all
-- ********************************************************************* Your changes below this line *************
-- ********************************************************************** No changes below this line **************
If you don't need one or two meters you can just remove or comment the lines there.
The logic in remaining part of the script takes care of the rest.
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 19:53
by EddyG
Nice script.
I get an error:
Code: Select all
2019-05-02 19:48:00.499 Status: dzVents: Error (2.4.18): dailyEnergyCost: An error occured when calling event handler utility_cost
2019-05-02 19:48:00.499 Status: dzVents: Error (2.4.18): dailyEnergyCost: /home/pi/domoticz/dzVents/runtime/Domoticz.lua:172: attempt to perform arithmetic on local 'x' (a nil value)
I have no "Water" yet. I commented 'Water' out.
Any idea?
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 20:15
by DaanV
waaren wrote: ↑Thursday 02 May 2019 19:49
DaanV wrote: ↑Thursday 02 May 2019 19:39
I've solved the puzzle. Turns out I was doing a couple of things wrong:
Just to be sure and for other people with similar questions, this is the script I used in the end:
Your welcome. Please note that the only area you need to modify settings is between the lines
Code: Select all
-- ********************************************************************* Your changes below this line *************
-- ********************************************************************** No changes below this line **************
If you don't need one or two meters you can just remove or comment the lines there.
The logic in remaining part of the script takes care of the rest.
Thanks. I had not realised that indeed. I'll correct that straight away.
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 21:13
by waaren
EddyG wrote: ↑Thursday 02 May 2019 19:53
Nice script.
I get an error:
Code: Select all
2019-05-02 19:48:00.499 Status: dzVents: Error (2.4.18): dailyEnergyCost: An error occured when calling event handler utility_cost
2019-05-02 19:48:00.499 Status: dzVents: Error (2.4.18): dailyEnergyCost: /home/pi/domoticz/dzVents/runtime/Domoticz.lua:172: attempt to perform arithmetic on local 'x' (a nil value)
I have no "Water" yet. I commented 'Water' out.
Any idea?
Sorry. A bit over enthusiastic so posted before finishing all tests. Can you try this one ?
Code: Select all
--[[
put today's electricity and (optional) today's Gas and (optional) todays Water usage costs in custom virtual sensor
Collect information from a P1 device and a Gas and water meter 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 = scriptVar},
data = { energyCosts = { initial = {} }
},
execute = function(dz, item)
-- ********************************************************************* Your changes below this line *************
-- When change anything between these lines make sure you remove
-- <domoticz_dir>/scripts/dzVents/data/ __data_<scriptname.lua> before next run of this script.
-- input Devices
local electricity = dz.devices("Power") -- P1 device (required)
local gas = dz.devices("Gas") -- Gas meter or comment this line
local water = dz.devices("Water") -- Water meter or comment this line
-- outPut Devices
local electricityCost = dz.devices("electricityCost today") -- define this virtual sensor as Custom sensor
local gasCost = dz.devices("gasCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
local waterCost = dz.devices("waterCost today") -- define this virtual sensor as Custom sensor or comment this line when not used
-- fixed Transport + contract costs per Year / Month or Day in Euro's
local electricityFixedMonth = 6.31 -- either electricityFixedyear, electricityFixedMonth or electricityFixedDay
local gasFixedYear = 75.72 -- either gasFixedyear, gasFixedMonth or gasFixedDay or comment this line
local waterFixedDay = 0.2052 -- either waterFixedyear, waterFixedMonth or waterFixedDay or comment this line
-- ********************************************************************** 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 getDaysForYear(year) -- Returns number of days in given or current year
if year == nil then year = dz.time.year end
return (year%4==0 and (year%100~=0 or year%400==0) and 366 or 365)
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
local daysThisMonth = getDaysForMonth()
local daysThisYear = getDaysForYear()
dz.data.energyCosts = t
dz.data.energyCosts.electricityFixedDay = ( electricityFixedMonth and ( electricityFixedMonth / daysThisMonth )) or
( electricityFixedYear and ( electricityFixedYear / daysThisYear )) or
electricityFixedDay
dz.data.energyCosts.gasFixedDay = ( gasFixedMonth and ( gasFixedMonth / daysThisMonth )) or
( gasFixedYear and ( gasFixedYear / daysThisYear )) or
gasFixedDay
dz.data.energyCosts.waterFixedDay = ( waterFixedMonth and ( waterFixedMonth / daysThisMonth )) or
( waterFixedYear and ( waterFixedYear / daysThisYear )) or
waterFixedDay
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 makeTodaysWaterCosts()
local waterTodayCost
if waterCost then
local waterTodaysCost = dz.data.energyCosts.waterFixedDay
waterTodaysCost = waterTodaysCost + ( water.counterToday * dz.data.energyCosts.CostWater / ( dz.data.energyCosts.DividerWater * 100000))
return dz.utils.round(waterTodaysCost, 2)
end
end
local function makeTodaysGasCosts()
local gasTodayCost
if gasCost then
gasTodaysCost = dz.data.energyCosts.gasFixedDay * 10000
gasTodaysCost = gasTodaysCost + gas.counterToday * dz.data.energyCosts.CostGas
return dz.utils.round(gasTodaysCost / 10000, 2)
end
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
return dz.utils.round(electricityTodaysCost / 10000,2)
end
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())
updateCustomSensor( waterCost, makeTodaysWaterCosts())
else
makeCostTable(item.json)
end
end
}
Re: Showing energy costs for double tarrif meter
Posted: Thursday 02 May 2019 22:28
by EddyG
Sorry, still same error. Now with debug on.
Code: Select all
2019-05-02 22:24:00.488 Status: dzVents: Debug: dailyEnergyCost: ElectricityCost today ==>> previous value: 1.2 ; new value 1.21
2019-05-02 22:24:00.489 Status: dzVents: Error (2.4.18): dailyEnergyCost: An error occured when calling event handler utility_costs
2019-05-02 22:24:00.489 Status: dzVents: Error (2.4.18): dailyEnergyCost: /home/pi/domoticz/scripts/dzVents/scripts/utility_costs.lua:110: attempt to index global 'water' (a nil value)
2019-05-02 22:24:00.489 Status: dzVents: Info: dailyEnergyCost: ------ Finished utility_costs.lua
I will try to disable all 'water' variables, I only did the first.
P.S. No error if all 'water' variables are disabled.