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 ?
--[[
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!
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:
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:
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
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: