I've a RFX-meter for my waterconsumption and a P1meter. I want to have for both the dailycosts in domoticx. I've downloaded a script and made some adjustments (water was first gas). The cost of my P1-meter (kwh) works well but the watercosts don't. I think the problem is that my watermeter is a RFX-meter, the script seems to work ponly with a custom sensor. I don't have a clue how I have to change this into the script. Is there someone who knows ho to do this?
--[[
put today's electricity and / or today's Water usage costs in custom virtual sensor
Collect information from a P1 device and /or a Water device
electricity takes different tariffs and returns (from solarpanels or the likes) into account.
]]--
local scriptVar = "dailyEnergyCost"
return {
on = { timer = { "every 5 minutes" }, -- using 6 minutes because Stroom and Water 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("Stroom") -- P1 device 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 waterCost = dz.devices("Waterkosten") -- 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 waterFixedMonth = 0.01
-- ********************************************************************** 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.waterFixedDay = (waterFixedMonth 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 makeTodaysWaterCosts()
local waterTodayCost
if waterCost then
waterTodaysCost = dz.data.energyCosts.waterFixedDay * 10000
waterTodaysCost = waterTodaysCost + water.counterToday * dz.data.energyCosts.CostWater
end
return dz.utils.round(waterTodaysCost / 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( waterCost, makeTodaysWaterCosts())
else
makeCostTable(item.json)
end
end
}
My log gives:
An error occurred when calling event handler scriptkosten
Error: dzVents: Error: (2.4.23) ...i/domoticz/scripts/dzVents/generated_scripts/kosten3.lua:85: attempt to perform arithmetic on field 'waterFixedDay' (a nil value)
remko2000 wrote: Friday 20 December 2019 17:56
The cost of my P1-meter (kwh) works well but the watercosts don't. I think the problem is that my watermeter is a RFX-meter, the script seems to work ponly with a custom sensor. I don't have a clue how I have to change this into the script. Is there someone who knows ho to do this?
This is the script I have running at my own production system. My watermeter is type: RFXMeter subtype: RFXMeter counter
--[[
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("Watermeter") -- 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
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
}
2019-12-22 10:45:00.744 Error: dzVents: Error: (2.4.23) dailyEnergyCost: There is no device with that name or id: Waterverbruik
2019-12-22 10:45:00.746 Error: dzVents: Error: (2.4.23) dailyEnergyCost: An error occurred when calling event handler kosten4
2019-12-22 10:45:00.746 Error: dzVents: Error: (2.4.23) dailyEnergyCost: ...i/domoticz/scripts/dzVents/generated_scripts/kosten4.lua:110: attempt to index upvalue 'water' (a nil value)
My ID 'Waterverbruik' is correct and I use this name also in your script so I don't understand this error.
I use a watersensor of the type RFXmeter - RFX meter Counter (so no water but counter).