Page 1 of 1

Calculating average on the run.

Posted: Sunday 08 May 2016 13:10
by costo
My Radiation-sensor (IP=192.168.178.20) sends every minute a JSON string like this :
{"data":{ "id":"12000059","type":"1","detector":"SI29BG","cpm":9,"temperature":27.75,"uptime": 1360190}}

I managed to decode the values and import them into Domoticz
I want to read 5 values for 5 minutes, sum the 5 values and divide the sum by 5, and import that average into Domoticz

This is the code i made.

Code: Select all

local idxCpm = 425   --idx of the CPM count
local idxUptime = 426 -- idx of Uptime
local cpm = " "
local uptime = " "
-- local cpmTot

commandArray={}
   json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
   local jsondata    = assert(io.popen('curl http://192.168.178.20/j'))
   local jsondevices = jsondata:read('*all')
   jsondata:close()
 
   local jsonCPM = json:decode(jsondevices)

   cpm = jsonCPM.data.cpm
   uptime = jsonCPM.data.uptime
   -- cpmTot = cpmTot + cpm
   time = os.date("*t")
   if ((time.min % 5)==0) then
	-- cpm = cpmTot/5
	commandArray[1] = {['UpdateDevice'] = idxCpm .. '|0|' .. cpm} 
	commandArray[2] = {['UpdateDevice'] = idxUptime .. '|0|' .. uptime/60}   -- uptime in minutes
	-- cpmTot = 0  
   end
return commandArray
I get errors so I commented out the lines that generate these errors. Errors like: a nil value.
The problem is in cpmTot which I cannot declare or use , it has to be a float I guess

I hope someone can tell me what I do wrong and how to correct it.

Re: Calculating average on the run.

Posted: Sunday 08 May 2016 13:28
by Westcott
The problem for you is that variables only exist for the duration of the Lua script.
The value is not persistent, so your cpmTot is always nil
You need to create a numeric 'User variable' using Setup->More options->User variables.

A better way to get a device idx is -
idx = otherdevices_idx[device_name]

This is safer in case your devices change.

Re: Calculating average on the run.

Posted: Sunday 08 May 2016 13:43
by costo
Hi Westcott,

Sure the idx can change which would mean that I have to edit the script.
On the other hand I can change the device_name too meaning the script will not work anymore and has to be edited.

About the average problem. I found functions that calculate the average but they work on an array of numbers. At the moment these functions are too complicated for me to implement.
I am a LUA noob so I can only change the code (like a monkey on a typewriter) until I have a small piece of working code.

I wonder if there is a way to temporary save the variable cpmTot.

Re: Calculating average on the run.

Posted: Sunday 08 May 2016 13:55
by Westcott
As I said, in a 'User variable'

Re: Calculating average on the run.

Posted: Sunday 08 May 2016 14:04
by costo
'User variable' that is completely new to me.
I just discovered this option in the settings but when I try to make a float variable I get the error: 'not a valid float' or integer whatever I select.
I do not understand how it interacts with the script I made.
I suppose I need to define the variable in the script somehow so that Domoticz will recognize it.

edit: working with user variable is so complicated , can anyone give me a clue ?

Re: Calculating average on the run.

Posted: Tuesday 10 May 2016 21:15
by costo
I suceeded in creating the 'User variable'
Variable Name : cpmTot
Variable Type : integer
Variable Value : '0'
When I use the script as shown in the first post with all the lines enabled I get this error message:
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_cpm_data.lua: /home/pi/domoticz/scripts/lua/script_time_cpm_data.lua:17: attempt to perform arithmetic on local 'cpmTot' (a string value)
line 17 is: cpmTot = cpmTot + cpm

If I comment out line 5: local cpmTot = " " then the errormessage is:
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_cpm_data.lua: /home/pi/domoticz/scripts/lua/script_time_cpm_data.lua:17: attempt to perform arithmetic on global 'cpmTot' (a nil value)

So how can I make this a working script ?

Re: Calculating average on the run.

Posted: Saturday 14 May 2016 19:56
by costo
I finally got the script working.

Code: Select all

local idxCpm = 425             --idx of the CPM counter
local idxUptime = 426          -- idx of Uptime 
local idxTemperature = 427     -- idx of GM-temperature
local cpm = " "                -- counts/minute
local uptime = " "             -- seconds
local temperature = " "        -- device_temp
local cpmTotal = 'cpm_uservar' -- integer user variable in  Domoticz

commandArray={}
   json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
   local jsondata    = assert(io.popen('curl http://192.168.178.20/j'))
   local jsondevices = jsondata:read('*all')
   jsondata:close()
   local jsonCPM = json:decode(jsondevices)
   cpm = jsonCPM.data.cpm
   uptime = jsonCPM.data.uptime
   temperature = jsonCPM.data.temperature
   total = tonumber(uservariables[cpmTotal])               -- load old uservar
   total = (total + cpm)                                   -- calculate new uservar
   commandArray['Variable:' .. cpmTotal] = tostring(total) -- update new uservar
   --print ('total: ' ..total)
   
time = os.date("*t")
   if ((time.min % 5)==0) then                                              -- every 5 minutes
	cpm = total/5
	--print ('CPM: '..cpm)  --
	commandArray[1] = {['UpdateDevice'] = idxCpm .. '|0|' .. cpm}            -- average cpm
	commandArray[2] = {['UpdateDevice'] = idxUptime .. '|0|' .. uptime/60}   --  minutes
	commandArray[3] = {['UpdateDevice'] = idxTemperature .. '|0|' .. temperature}
	total = 0                                                                -- zero user variable
	commandArray['Variable:' .. cpmTotal] = tostring(total)                  -- save user variable
   end
return commandArray
It is a bit weird that I created the user variable as an integer but it is handled and plotted by Domoticz as a float.
If someone sees any error or a way to simplify the script, please let me know.