Help wanted adapting "Capturing Energy Usage with Lua Script
Moderator: leecollings
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Help wanted adapting "Capturing Energy Usage with Lua Script
Hi there,
I've been trying to adapt https://www.domoticz.com/wiki/Capturing ... ua_Scripts to match my setup but keep getting error "bad argument #1 to 'match' (string expected, got nil)"
I have the EM6601 (recognised as NQ-92021) which is called Elec_meter and has idx 88
What I want is same as in the wikipage (or maybe write the output to a virtual meter, in order not to write any data to he actual -working-meter)
I've been trying to adapt https://www.domoticz.com/wiki/Capturing ... ua_Scripts to match my setup but keep getting error "bad argument #1 to 'match' (string expected, got nil)"
I have the EM6601 (recognised as NQ-92021) which is called Elec_meter and has idx 88
What I want is same as in the wikipage (or maybe write the output to a virtual meter, in order not to write any data to he actual -working-meter)
- jvdz
- Posts: 2267
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
It would help when you post the line you get the error on.
In general when a nil is returned it is likely that the devicename doesn't exists in case the is a line like this one:
The devicename has the be exact and is case sensitive.
Jos

In general when a nil is returned it is likely that the devicename doesn't exists in case the is a line like this one:
Code: Select all
nhousePower, houseEnergy = string.match(otherdevices_svalues['Household'], "(%d+%.*%d*);(%d+%.*%d*)")
Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
The error:
2015-12-21 19:20:12.183 LUA: elecmeter : 0.000;17346192.000
2015-12-21 19:20:12.183 Error: EventSystem: .../pi/domoticz/scripts/lua/script_device_elecmeter_log.lua:76: bad argument #1 to 'match' (string expected, got nil)
Hi, posting the info.
Would really appreciate the help
The devices (all virtual except elecmeter)
IDX Name Type SubType Data
-----------------------------------------------------------------------------
88 elecmeter General kWh 17346.206 kWh
109 Exported RFXMeter RFXMeter counter 0.000 kWh
108 Imported RFXMeter RFXMeter counter 0.000 kWh
107 Household General kWh 0.000 kWh
the script:
2015-12-21 19:20:12.183 LUA: elecmeter : 0.000;17346192.000
2015-12-21 19:20:12.183 Error: EventSystem: .../pi/domoticz/scripts/lua/script_device_elecmeter_log.lua:76: bad argument #1 to 'match' (string expected, got nil)
Hi, posting the info.
Would really appreciate the help
The devices (all virtual except elecmeter)
IDX Name Type SubType Data
-----------------------------------------------------------------------------
88 elecmeter General kWh 17346.206 kWh
109 Exported RFXMeter RFXMeter counter 0.000 kWh
108 Imported RFXMeter RFXMeter counter 0.000 kWh
107 Household General kWh 0.000 kWh
the script:
Code: Select all
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
function timeCount(numSec)
local nSeconds = numSec
if nSeconds == 0 then
return "0seconds"
else
local sTime = ""
local nHours = math.floor(nSeconds/3600)
local nMins = math.floor(nSeconds/60 - (nHours*60))
if(nHours > 0) then
sTime = sTime .. nHours
if(nHours == 1) then
sTime = sTime .. "hour "
else
sTime = sTime .. "hours "
end
end
if(nMins > 0) then
sTime = sTime .. nMins
if(nMins == 1) then
sTime = sTime .. "minute "
else
sTime = sTime .. "minutes "
end
end
local nSecs = math.floor(nSeconds - nHours*3600 - nMins *60)
if(nSecs > 0) then
sTime = sTime .. nSecs
if(nSecs == 1) then
sTime = sTime .. "second"
else
sTime = sTime .. "seconds"
end
end
return sTime
end
end
function update(device, id, power, energy, index)
if (index < 4) then
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
else
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. energy}
end
return
end
commandArray = {}
local voltage = 243
local houseid = 107
local usedid = 108
local generatedid = 109
if devicechanged['elecmeter'] then
elec = otherdevices_svalues['elecmeter']
print('elecmeter : '..elec)
words = {}
for w in string.gmatch(elec, "%d+%.?%d*") do
words[#words + 1] = w
end
nhousePower, houseEnergy = string.match(otherdevices_svalues['Household'], "(%d+%.*%d*);(%d+%.*%d*)")
usedEnergy = string.match(otherdevices_svalues['Imported'], "%d+%.*%d*")
interval = timedifference(otherdevices_lastupdate['elec_switch'])
-- convert interval in seconds into hours
interval = interval / 3600
-- calculate power (voltage * current) and cumulative energy (current energy + power * time)
-- for each monitored line
housePower = voltage * tonumber(words[1])
houseEnergy = tonumber(houseEnergy) + (housePower * interval)
currentPower = housePower
if (currentPower > 0) then
usedEnergy = tonumber(usedEnergy) + (interval * currentPower)
end
if (currentPower > 0) then
update("Imported", usedid, 0, usedEnergy, 4)
else
update("Exported", generatedid, 0, generatedEnergy, 4)
end
end
return commandArray
- jvdz
- Posts: 2267
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
The error is telling you that this part returns a nil: otherdevices_svalues['Household']
I don't have this in my setup but you could add these 2 lines above the line in error just to get some debug info:
Jos
I don't have this in my setup but you could add these 2 lines above the line in error just to get some debug info:
Code: Select all
print(" otherdevices['Household']:",otherdevices['Household'])
print(" otherdevices_svalues['Household']:",otherdevices_svalues['Household'])
nhousePower, houseEnergy = string.match(otherdevices_svalues['Household'], "(%d+%.*%d*);(%d+%.*%d*)")
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
Hi Jos,
Did that and also manually entered a 'starting value' -> the current reading of 'elecmeter' in Household in order not to have zero as a value.
Error logs now shows:
2015-12-21 20:30:13.403 LUA: elecmeter : 0.000;17346332.000
2015-12-21 20:30:13.403 LUA: otherdevices['Household']:
2015-12-21 20:30:13.403 LUA:
2015-12-21 20:30:13.404 LUA: otherdevices_svalues['Household']:
2015-12-21 20:30:13.404 LUA: 1;17346290
2015-12-21 20:30:13.404 Error: EventSystem: .../pi/domoticz/scripts/lua/script_device_elecmeter_log.lua:4: bad argument #1 to 'sub' (string expected, got nil)
---> line 4 is from the original script
Thanks for your help!
Did that and also manually entered a 'starting value' -> the current reading of 'elecmeter' in Household in order not to have zero as a value.
Error logs now shows:
2015-12-21 20:30:13.403 LUA: elecmeter : 0.000;17346332.000
2015-12-21 20:30:13.403 LUA: otherdevices['Household']:
2015-12-21 20:30:13.403 LUA:
2015-12-21 20:30:13.404 LUA: otherdevices_svalues['Household']:
2015-12-21 20:30:13.404 LUA: 1;17346290
2015-12-21 20:30:13.404 Error: EventSystem: .../pi/domoticz/scripts/lua/script_device_elecmeter_log.lua:4: bad argument #1 to 'sub' (string expected, got nil)
---> line 4 is from the original script
Thanks for your help!
- jvdz
- Posts: 2267
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc

Could it be this line is now causing the error?:
Code: Select all
interval = timedifference(otherdevices_lastupdate['elec_switch'])
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
Updated the script, basically working now.
Except: it triggers itself again and thus creating a zero value.
The log:
2015-12-22 18:34:54.509 LUA: elecmeter : 0.000;17348642.000
2015-12-22 18:34:54.510 LUA: houseEnergy : 17348642.000
2015-12-22 18:34:54.510 LUA: usedEnergy : 17348630.000
2015-12-22 18:34:54.510 LUA: diff : 12
2015-12-22 18:34:54.510 LUA: interval : 285
2015-12-22 18:34:54.510 LUA: rate : 151.57894736842
Until here quite ok, need some cleanup of the "rate" value.
But then it triggers again, while elecmeter has not been updated at this point and thus creating a zero difference between the readings and therefor calculating a Zero rate (--> calculate consumption per hour)
2015-12-22 18:34:54.514 EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_device_elecmeter_log.lua
2015-12-22 18:34:54.547 LUA: elecmeter : 0.000;17348642.000
2015-12-22 18:34:54.547 LUA: houseEnergy : 17348642.000
2015-12-22 18:34:54.547 LUA: usedEnergy : 17348642.000
2015-12-22 18:34:54.547 LUA: diff : 0
2015-12-22 18:34:54.547 LUA: interval : 285
2015-12-22 18:34:54.547 LUA: rate : 0
2015-12-22 18:34:54.550 EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_device_elecmeter_log.lua
Got the feeling I am almost there, but not completely.
Maybe I shouldn't have thrown myself in LUA just yet.
Any hint welcome.
Except: it triggers itself again and thus creating a zero value.
Code: Select all
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
function timeCount(numSec)
local nSeconds = numSec
if nSeconds == 0 then
return "0seconds"
else
local sTime = ""
local nHours = math.floor(nSeconds/3600)
local nMins = math.floor(nSeconds/60 - (nHours*60))
if(nHours > 0) then
sTime = sTime .. nHours
if(nHours == 1) then
sTime = sTime .. "hour "
else
sTime = sTime .. "hours "
end
end
if(nMins > 0) then
sTime = sTime .. nMins
if(nMins == 1) then
sTime = sTime .. "minute "
else
sTime = sTime .. "minutes "
end
end
local nSecs = math.floor(nSeconds - nHours*3600 - nMins *60)
if(nSecs > 0) then
sTime = sTime .. nSecs
if(nSecs == 1) then
sTime = sTime .. "second"
else
sTime = sTime .. "seconds"
end
end
return sTime
end
end
function update(device, id, power, energy, index)
if (index < 3) then
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
else
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. energy}
end
return
end
commandArray = {}
local houseid = 112
local usedid = 111
if devicechanged['elecmeter'] then
elec = otherdevices_svalues['elecmeter']
print('elecmeter : '..elec)
words = {}
for w in string.gmatch(elec, "%d+%.?%d*") do
words[#words + 1] = w
end
nhousePower, houseEnergy = string.match(otherdevices_svalues['elecmeter'], "(%d+%.*%d*);(%d+%.*%d*)")
updateuse = houseEnergy
usedEnergy = string.match(otherdevices_svalues['Household'], "%d+%.*%d*")
consumed = houseEnergy - usedEnergy
interval = timedifference(otherdevices_lastupdate['elec_switch'])
print ('houseEnergy : '..houseEnergy)
print ('usedEnergy : '..usedEnergy)
print ('diff : '..consumed)
print ('interval : '..interval)
rate = (consumed / interval) * 3600
print ('rate : '..rate)
commandArray['elec_switch'] = 'On'
update("Household", houseid, 0, updateuse, 3)
update("Imported", usedid, 0, rate, 4)
end
return commandArray
2015-12-22 18:34:54.509 LUA: elecmeter : 0.000;17348642.000
2015-12-22 18:34:54.510 LUA: houseEnergy : 17348642.000
2015-12-22 18:34:54.510 LUA: usedEnergy : 17348630.000
2015-12-22 18:34:54.510 LUA: diff : 12
2015-12-22 18:34:54.510 LUA: interval : 285
2015-12-22 18:34:54.510 LUA: rate : 151.57894736842
Until here quite ok, need some cleanup of the "rate" value.
But then it triggers again, while elecmeter has not been updated at this point and thus creating a zero difference between the readings and therefor calculating a Zero rate (--> calculate consumption per hour)
2015-12-22 18:34:54.514 EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_device_elecmeter_log.lua
2015-12-22 18:34:54.547 LUA: elecmeter : 0.000;17348642.000
2015-12-22 18:34:54.547 LUA: houseEnergy : 17348642.000
2015-12-22 18:34:54.547 LUA: usedEnergy : 17348642.000
2015-12-22 18:34:54.547 LUA: diff : 0
2015-12-22 18:34:54.547 LUA: interval : 285
2015-12-22 18:34:54.547 LUA: rate : 0
2015-12-22 18:34:54.550 EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_device_elecmeter_log.lua
Got the feeling I am almost there, but not completely.
Maybe I shouldn't have thrown myself in LUA just yet.
Any hint welcome.
- jvdz
- Posts: 2267
- Joined: Tuesday 30 December 2014 19:25
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.107
- Location: Netherlands
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
Could it be you have 2 devices called "elecmeter" and does it always runs 2 times?
You could simply test for consumed > 0 and only update when it contains a value greater than 0:
Jos
You could simply test for consumed > 0 and only update when it contains a value greater than 0:
Code: Select all
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
function timeCount(numSec)
local nSeconds = numSec
if nSeconds == 0 then
return "0seconds"
else
local sTime = ""
local nHours = math.floor(nSeconds/3600)
local nMins = math.floor(nSeconds/60 - (nHours*60))
if(nHours > 0) then
sTime = sTime .. nHours
if(nHours == 1) then
sTime = sTime .. "hour "
else
sTime = sTime .. "hours "
end
end
if(nMins > 0) then
sTime = sTime .. nMins
if(nMins == 1) then
sTime = sTime .. "minute "
else
sTime = sTime .. "minutes "
end
end
local nSecs = math.floor(nSeconds - nHours*3600 - nMins *60)
if(nSecs > 0) then
sTime = sTime .. nSecs
if(nSecs == 1) then
sTime = sTime .. "second"
else
sTime = sTime .. "seconds"
end
end
return sTime
end
end
function update(device, id, power, energy, index)
if (index < 3) then
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
else
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. energy}
end
return
end
commandArray = {}
local houseid = 112
local usedid = 111
if devicechanged['elecmeter'] then
elec = otherdevices_svalues['elecmeter']
print('elecmeter : '..elec)
words = {}
for w in string.gmatch(elec, "%d+%.?%d*") do
words[#words + 1] = w
end
nhousePower, houseEnergy = string.match(otherdevices_svalues['elecmeter'], "(%d+%.*%d*);(%d+%.*%d*)")
updateuse = houseEnergy
usedEnergy = string.match(otherdevices_svalues['Household'], "%d+%.*%d*")
consumed = houseEnergy - usedEnergy
interval = timedifference(otherdevices_lastupdate['elec_switch'])
rate = (consumed / interval) * 3600
print ('rate : '..rate)
if consumed > 0 then
print ('houseEnergy : '..houseEnergy)
print ('usedEnergy : '..usedEnergy)
print ('diff : '..consumed)
print ('interval : '..interval)
commandArray['elec_switch'] = 'On'
update("Household", houseid, 0, updateuse, 3)
update("Imported", usedid, 0, rate, 4)
end
end
return commandArray
Last edited by jvdz on Tuesday 22 December 2015 19:10, edited 1 time in total.
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Sc
Thanks Jos !
I was just about to edit my last post, after I've seen the light about the checking for consumed > 0
Now checking if by any chance I have a double elecmeter.
Update: no double "elecmeter". But not an issue for now, with the greater than zero check
Really appreciate your help.
update: found out why the script gets triggered twice everytime:
when the meter sends it's update, it sends it twice. No clue why that is or how to ignore the second one
2015-12-23 12:05:00.292 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:05:00.798 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:20:14.225 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:20:14.261 (RaZberry) General/kWh (elecmeter)
I was just about to edit my last post, after I've seen the light about the checking for consumed > 0
Now checking if by any chance I have a double elecmeter.
Update: no double "elecmeter". But not an issue for now, with the greater than zero check
Really appreciate your help.
update: found out why the script gets triggered twice everytime:
when the meter sends it's update, it sends it twice. No clue why that is or how to ignore the second one
2015-12-23 12:05:00.292 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:05:00.798 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:20:14.225 (RaZberry) General/kWh (elecmeter)
2015-12-23 12:20:14.261 (RaZberry) General/kWh (elecmeter)
-
- Posts: 11
- Joined: Tuesday 27 December 2016 16:19
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.6328
- Location: Ireland
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Script
Hi elmortero,
Sorry to drag up an old thread but I'm trying to achieve similar to you and it looks like this script fits the bill but I have a couple of questions!
The device to collect the usage is type Electric Instant + Counter?
In your script you have these devices elecmeter, elec_switch, Household and Imported.
elecmeter is the meter returning the current watts being used right?
elec_switch is a virtual switch to track when we last got an update from elecmeter.
Household is the device to collect the usage
I'm not sure what Imported is ?
thanks
Sorry to drag up an old thread but I'm trying to achieve similar to you and it looks like this script fits the bill but I have a couple of questions!
The device to collect the usage is type Electric Instant + Counter?
In your script you have these devices elecmeter, elec_switch, Household and Imported.
elecmeter is the meter returning the current watts being used right?
elec_switch is a virtual switch to track when we last got an update from elecmeter.
Household is the device to collect the usage
I'm not sure what Imported is ?
thanks
-
- Posts: 11
- Joined: Tuesday 27 December 2016 16:19
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.6328
- Location: Ireland
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Script
So I managed to cobble together a solution myself. I'm using an Electric Instant + Counter Device with the Energy Read option set to computed.
I'm using this script
I'd like to get commandArray['UpdateDevice'] working however if I use either of the examples above I loose the current power and used power from the device and I see "0,value of power" e.g. If power used is 430 watts the device no longer displays 430 watts in the title and is the body both counters loose their units and I see 0,430.0 . I guess I'm passing the values it the wrong order or type? Using commandArray['OpenURL'] line works everytime as expected.
I'm using this script
Code: Select all
commandArray = {}
if devicechanged['IT Demand'] then
power = otherdevices_svalues['IT Demand']
--commandArray['UpdateDevice'] = 31 .. "|0|" .. power --Not working
--commandArray['UpdateDevice'] = 31 .. "|" .. power -- Alternate format not working
commandArray['OpenURL'] = 'http://172.20.0.7/json.htm?type=command¶m=udevice&idx=31&svalue='..power..'' -- works as expected
end
return commandArray
-
- Posts: 247
- Joined: Sunday 29 November 2015 20:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 3.9639
- Location: Spain
- Contact:
Re: Help wanted adapting "Capturing Energy Usage with Lua Script
I think that it is related to the limitations mentioned in the last post of this topic: viewtopic.php?t=12628
Who is online
Users browsing this forum: No registered users and 0 guests