Page 1 of 1
(SOLVED) Convert LUA script into dzVents
Posted: Sunday 11 May 2025 22:19
by costo
New to dzVents, made a LUA script a few years ago to extract cpm, temperatue and uptime
this script works fine but I'm trying to convert this script into dzVents.
The uRadmonitor sensor on '192.168.178.26/j' generates this json format line
{"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":9,"temperature":29.31,"uptime": 1407157}}
My first try is to extract the cpm value , the sensorname is cpmCount
apparently the json decoding is not right becouse cpmCount is always zero
Code: Select all
local IP = '192.168.178.26' -- uRadmonitor sensor IP
return {
active = true,
on = {
timer = { 'every minute' },
httpResponses = { 'cpmRetrieved' } -- matches callback string below
},
execute = function(domoticz, item)
if (item.isTimer) then
domoticz.openURL({
url = 'http://' .. IP .. '/j',
method = 'GET',
callback = 'cpmRetrieved',
})
elseif (item.isHTTPResponse) then
if (item.ok) then -- and item.isJSON) then -- statusCode == 2xx
-- if (item.statusCode==0) then
local Count = item.data.cpm
domoticz.log('status = ',tonumber(Count))
domoticz.devices('cpmCount').updateCustomSensor(Count)
end
end
end
}
any suggestion can help me.
log output:
2025-05-11 21:57:00.216 dzVents: Handling httpResponse-events for: "cpmRetrieved"
2025-05-11 21:57:00.216 dzVents: ------ Start internal script: cpm_dzvents: HTTPResponse: "cpmRetrieved"
2025-05-11 21:57:00.216 dzVents: status =
2025-05-11 21:57:00.217 dzVents: ------ Finished cpm_dzvents
Re: Convert LUA script into dzVents
Posted: Sunday 11 May 2025 22:54
by waltervl
You can log the table item.data to see what is in it.
Also the log statement you are using is not correct, it should be
Code: Select all
domoticz.log('status = ' .. Count)
Re: Convert LUA script into dzVents
Posted: Sunday 11 May 2025 23:34
by costo
If I write 'domoticz.log('status = ' .. Count) ' then i see this error
2025-05-11 23:29:00.346 Error: dzVents: An error occurred when calling event handler cpm_dzvents
2025-05-11 23:29:00.346 Error: dzVents: ...moticz/scripts/dzVents/generated_scripts/cpm_dzvents.lua:26: attempt to concatenate a nil value
I tried to log the table but i was not succesfull
Re: Convert LUA script into dzVents
Posted: Sunday 11 May 2025 23:53
by waltervl
You should be able to see the complete data with log statement.
Code: Select all
domoticz.log(item.data,dz.LOG_FORCE)
It could be that you have to use data twice to get the count eg
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 0:22
by costo
negative, both lines give an Error : attempt to index a nil value (global 'dz') or (field 'data')
print (item.data) prints the line as seen in the browser,
{"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":9,"temperature":29.31,"uptime": 1407157}}
print (item.data.id),
print (item.data.cpm),
print (item.data.temperature),
print (item.data.uptime),
all are nil values.
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 10:28
by habahabahaba
costo wrote: ↑Monday 12 May 2025 0:22
negative, both lines give an Error : attempt to index a nil value (global 'dz') or (field 'data')
print (item.data) prints the line as seen in the browser,
{"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":9,"temperature":29.31,"uptime": 1407157}}
print (item.data.id),
print (item.data.cpm),
print (item.data.temperature),
print (item.data.uptime),
all are nil values.
According to
https://jsonparser.org/ you have some incorrect values. It should be
{"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":"9","temperature":"29.31","uptime": "1407157"}}
Try to put to Dzvents script this:
to check if Dz understandig incoming Json or not.
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 11:27
by waltervl
The error in the log line is my fault
It should be
Code: Select all
domoticz.log(item.data,domoticz.LOG_FORCE)
And if item.data shows data entry in the JSON I believe you should use data twice like
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 11:55
by costo
Using this:
Code: Select all
if (item.ok and item.isJSON) then -- statusCode == 2xx
domoticz.log(item.data,domoticz.LOG_FORCE)
print ('cpm = '..item.data.data.cpm)
end
which gives an error in the print() line so apparently the data is recognized as json .
In the link jparser.org I can put the data line and the parser makes this of it
data {6}
id : 12000059
type : 1
detector : SI29BG
cpm : 9
temperature : 29.31
uptime : 1407157
that looks very usefull but upto now I only get nil value errors
in the log this line:
!Info: {"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":9,"temperature":34.31,"uptime": 1462644}}
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 12:04
by costo
For completeness this is the LUA script that works fine for many years
Code: Select all
-- Script to calculate average CPM
local idxUptime = 14 -- idx of Uptime
local idxCpm = 15 -- idx of simpel cpm1
local idxWA = 16 -- idx of wAverage30
local idxTemp = 13 -- idx of Tempsensor
local cpm = " " -- counts in last minute
local uptime = " " -- in seconds
local temperature = " "
local cpmWalkAv = 'WAcpm' -- WAcpm user variable
local IPcpm = '192.168.178.26' -- change IP here
-- NOTE: Fetch data from external servers without locking the event system!
-- see https://www.domoticz.com/forum/viewtopic.php?t=19327
commandArray={}
json = (loadfile "/home/co/domoticz/scripts/lua/JSON.lua")() -- JSON library on user 'co'
local jsondata = assert(io.popen('curl http://' .. IPcpm .. '/j')) -- open URADmonitor
local jsondevices = jsondata:read('*all') -- read 'data'
jsondata:close() -- close URADmonitor
-- print ('devices =' .. jsondevices)
local jsonCPM = json:decode(jsondevices) -- decode json string
if (jsonCPM ~= nil) then -- jsonCPM is a table --
cpm = jsonCPM.data.cpm -- cpm
uptime = jsonCPM.data.uptime
temperature = math.floor(10*(jsonCPM.data.temperature + .05))/10 -- temp in tenth degrees
wAverage30 = tonumber(uservariables[cpmWalkAv]) -- load old WAcpm_uservar
wAverage30 = (29 * wAverage30 + cpm)/30 -- calculate new WAcpm_uservar
wAverage30 = tonumber(string.format("%." .. 2 .. "f", wAverage30)) -- format 2 digits after dot
commandArray['Variable:' .. cpmWalkAv] = tostring(wAverage30) -- update new WAcpm_uservar every minute
time = os.date("*t")
if (((time.min+1) % 1)==0) then -- update devices every 5 minutes. 1,6,11,16,21,26
uptime = math.floor(uptime/60)
commandArray[1] = {['UpdateDevice'] = idxUptime .. '|0|' .. uptime} -- in minutes
commandArray[2] = {['UpdateDevice'] = idxTemp .. '|0|' .. temperature} -- T
commandArray[4] = {['UpdateDevice'] = idxCpm .. '|0|' .. cpm} -- send cpm cnt/min
commandArray[5] = {['UpdateDevice'] = idxWA .. '|0|' .. wAverage30} -- send wAverage30
end
end
return commandArray
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 13:06
by habahabahaba
Fully working example with JSON:
Code: Select all
-- TEST
return {
on = {
timer = {
'every minute' -- just an example set as often as you need
},
httpResponses = {
'USGovWeathertrigger' -- must match with the callback passed to the openURL command
}
},
logging = {
level = domoticz.LOG_INFO,
marker = 'USGovWeathertrigger',
},
execute = function(domoticz, item)
local APIURL = 'https://api.weather.gov/points/39.7456,-97.0892'
if (item.isTimer) then
domoticz.openURL({
url = APIURL,
method = 'GET',
callback = 'USGovWeathertrigger', -- see httpResponses above.
}).afterSec(5)
end
if (item.isHTTPResponse) then
if (item.ok) then
if (item.isJSON) then
--domoticz.utils.dumpTable(item.json)
local city = item.json.properties.relativeLocation.properties.city
local state = item.json.properties.relativeLocation.properties.state
local coord1 = item.json.properties.relativeLocation.geometry.coordinates[1] -- 1 because in JSON elements start from 0 and in table it starts from 1
local coord2 = item.json.properties.relativeLocation.geometry.coordinates[2]
domoticz.log('City='.. city.. ' State='.. state .. '; Coordinates: '.. coord1..'; '.. coord2, domoticz.LOG_ERROR) -- los as ERROR just to mark it for easy find
end
else
domoticz.log('LOG_ERROR', domoticz.LOG_ERROR)
end
end
end
}
Try
Code: Select all
local Count = item.json.data.cpm
domoticz.log('status = ' .. Count, LOG_INFO)
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 13:16
by costo
YES !!!
That does the trick
thank you thank you thank you
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 16:14
by costo
So I got a basic working dzVents script
Code: Select all
local IP = '192.168.178.26' -- uRadmonitor sensor IP
return {
active = true,
on = {
timer = { 'every minute' },
httpResponses = { 'cpmRetrieved' } -- matches callback string below
},
execute = function(domoticz, item)
if (item.isTimer) then
domoticz.openURL({
url = 'http://' .. IP .. '/j',
method = 'GET',
callback = 'cpmRetrieved',
})
elseif (item.isHTTPResponse) then
if (item.ok and item.isJSON) then -- statusCode == 2xx
local Count = (item.json.data.cpm)
local Up = (item.json.data.uptime/60)
local Temp = (item.json.data.temperature)
print (item.data)
domoticz.devices('cpmCount').updateCustomSensor(Count)
domoticz.devices('cpmUp').updateCustomSensor(Up)
domoticz.devices('cpmT').updateTemperature(Temp)
end
end
end
}
Now I need to do some math, dzVents documentation for math functions seems non-existent.
The Temperature is displayed with 2 decimals, I need only 1
The Uptime in minutes needs to be rounded , no decimals.
Then I need to engineer some way to make a Cumulative Average of the last 30 readings
in LUA that needed one uservariable. and a few lines of code
Code: Select all
cpm = jsonCPM.data.cpm -- cpm
uptime = jsonCPM.data.uptime
temperature = math.floor(10*(jsonCPM.data.temperature + .05))/10 -- temp in tenth degrees
wAverage30 = tonumber(uservariables[cpmWalkAv]) -- load old WAcpm_uservar
wAverage30 = (29 * wAverage30 + cpm)/30 -- calculate new WAcpm_uservar
wAverage30 = tonumber(string.format("%." .. 2 .. "f", wAverage30)) -- format 2 digits after dot
commandArray['Variable:' .. cpmWalkAv] = tostring(wAverage30) -- update new WAcpm_uservar every minute
whatever I try in dzVents it ends in errors.
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 17:30
by habahabahaba
local temp = domoticz.utils.round(temperature , 1)
local Uptime = domoticz.utils.round(Uptime, 0)
local wAverage30 = domoticz.variables('cpmWalkAv').value
Re: Convert LUA script into dzVents
Posted: Monday 12 May 2025 22:43
by costo
thanks habahabahaba, your input is very helpfull.
Most of the things work.
I still use a uservariable, just as in the LUA script, maybe in dzVents there is a better way but for now the uservariable is ok.
reading from the uservariable is like this:
local wAverage30 = domoticz.variables('CAcpm').value -- uservariable
but writing a new value in the uservariables table is erronous.
I tried -- domoticz.variables.CAcpm.value = tostring(wAverage30)
and get this error 'attempt to index a function value (field 'variables')
this is part of my code:
Code: Select all
if (item.ok and item.isJSON) then -- statusCode == 2xx
print (item.data)
local Count = item.json.data.cpm
local Uptime = math.floor((item.json.data.uptime+0.5)/60)
local Temp = domoticz.utils.round(item.json.data.temperature,1)
local wAverage30 = domoticz.variables('CAcpm').value -- uservariable
wAverage30 = (29*wAverage30 + Count)/30
wAverage30 = tonumber(string.format("%." .. 2 .. "f", wAverage30))
domoticz.variables.CAcpm.value = tostring(wAverage30) -- this line gives the error
print (wAverage30)
domoticz.devices('cpmCount').updateCustomSensor(Count)
domoticz.devices('cpmUp').updateCustomSensor(Uptime)
domoticz.devices('cpmT').updateTemperature(Temp)
domoticz.devices('cpmCount30').updateCustomSensor(wAverage30)
end
Re: Convert LUA script into dzVents
Posted: Tuesday 13 May 2025 6:10
by habahabahaba
costo wrote: ↑Monday 12 May 2025 22:43
but writing a new value in the uservariables table is erronous.
I tried -- domoticz.variables.CAcpm.value = tostring(wAverage30)
and get this error 'attempt to index a function value (field 'variables')
domoticz.variables('Heating_123_floors').set('On') - example
I think you have to learn this -
https://wiki.domoticz.com/DzVents:_next ... _scripting
Re: Convert LUA script into dzVents
Posted: Tuesday 13 May 2025 21:28
by costo
Hi habahabahaba,
your example brought me to the solution
yes you are right, I have to learn dzVents, but its not easy to teach an old horse a new trick.
More than 50 years ago I learned coding using punchcards.
each card was a line and had max 80 characters, so variables needed short names.
in the evening a batch of cards was sent by a modem to a mainframe and the next day I got the result or error warning.
from algol>pascal>basic to C++ and then I stopped, never had interest in java or script language.
Now I have to if i want to do nice things in domoticz
I still feel the need to keep variable names short and get dizzy if I see a script with names like ('broodroosterventilator') or (response.data.value) , than I don't see the code anymore
