Calculating average on the run.

Moderator: leecollings

Post Reply
costo
Posts: 71
Joined: Tuesday 11 August 2015 17:35
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Calculating average on the run.

Post 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.
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Calculating average on the run.

Post 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.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
costo
Posts: 71
Joined: Tuesday 11 August 2015 17:35
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Calculating average on the run.

Post 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.
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Calculating average on the run.

Post by Westcott »

As I said, in a 'User variable'
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
costo
Posts: 71
Joined: Tuesday 11 August 2015 17:35
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Calculating average on the run.

Post 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 ?
costo
Posts: 71
Joined: Tuesday 11 August 2015 17:35
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Calculating average on the run.

Post 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 ?
costo
Posts: 71
Joined: Tuesday 11 August 2015 17:35
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Calculating average on the run.

Post 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.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest