3 local uci = require("uci")
4 local cur = uci.cursor()
5 local json = require "json"
13 print("no sqlite log defined!")
18 function shallowcopy(orig)
19 local orig_type = type(orig)
21 if orig_type == 'table' then
23 for orig_key, orig_value in pairs(orig) do
24 copy[orig_key] = orig_value
26 else -- number, string, boolean, etc
32 function median(dataset)
34 table.sort(shallowcopy(dataset))
35 return dataset[math.floor(#dataset/2)]
39 function filter_data(dataset,width)
45 if #dataset <= width then
51 local window_spread = math.floor(width/2)
54 for i = 1,window_spread do
55 window[#window+1] = dataset[i]["y"]
58 for key,value in pairs(dataset) do
59 nextelem = dataset[key+window_spread]
61 window[#window+1] = nextelem["y"]
63 if not nextelem or #window>width then
64 table.remove(window,1)
68 row["y"]=median(window)
69 result[#result+1] = row
76 function average_results(dataset,con)
77 local name = os.tmpname()
79 local tmpcon = assert(env:connect(name))
80 assert(tmpcon:execute("create table series(time_stamp datetime,value float)"))
81 for key,value in pairs(dataset) do
82 assert(tmpcon:execute(string.format("INSERT INTO series(time_stamp,value) VALUES ('%s','%s')",value["t"],value["y"])))
84 local sql = "select rounded as t,avg(value) as y from (select substr(strftime('%Y-%m-%dT%H:%M',time_stamp),1,15)||'5:00' rounded,value from series) group by rounded order by rounded"
85 results = run_sql(sql,tmpcon)
91 function run_sql(sql,con)
94 cursor = assert(con:execute(sql))
95 row = cursor:fetch ({}, "a")
97 result[#result+1] = row
98 row = cursor:fetch ({}, "a")
104 function get_list(day,con)
106 sql = string.format("SELECT DISTINCT sensor_id,sensor,param FROM log WHERE time_stamp>=datetime('now','-1 day','localtime') ORDER BY sensor_id,sensor,param")
108 sql = string.format("SELECT DISTINCT sensor_id,sensor,param FROM log WHERE time_stamp>='%s' and time_stamp<date('%s','+1 day') ORDER BY sensor_id,sensor,param",day,day)
110 return run_sql(sql,con)
113 function get_raw(day,con,sensor_id,sensor_type,param)
114 format = '%Y-%m-%dT%H:%M:%S'
116 sql = string.format("SELECT strftime('%s',time_stamp) as t,value as y FROM log WHERE time_stamp>=datetime('now','-1 day','localtime') and sensor_id='%s' and sensor='%s' and param='%s' ORDER BY time_stamp",format,sensor_id,sensor_type,param)
118 sql = string.format("SELECT strftime('%s',time_stamp) as t,value as y FROM log WHERE time_stamp>='%s' and time_stamp<date('%s','+1 day') and sensor_id='%s' and sensor='%s' and param='%s' ORDER BY time_stamp",format,day,day,sensor_id,sensor_type,param)
120 return run_sql(sql,con)
123 function get_filtered(day,con,sensor_id,sensor_type,param,width)
124 format = '%Y-%m-%dT%H:%M:%S'
126 sql = string.format("SELECT strftime('%s',time_stamp) as t,value as y FROM log WHERE time_stamp>=datetime('now','-1 day','localtime') and sensor_id='%s' and sensor='%s' and param='%s' ORDER BY time_stamp",format,sensor_id,sensor_type,param)
128 sql = string.format("SELECT strftime('%s',time_stamp) as t,value as y FROM log WHERE time_stamp>='%s' and time_stamp<date('%s','+1 day') and sensor_id='%s' and sensor='%s' and param='%s' ORDER BY time_stamp",format,day,day,sensor_id,sensor_type,param)
130 return filter_data(run_sql(sql,con),width)
133 function dump_json(dataset,file)
136 f = io.open(file,"w")
139 io.write(json.encode(dataset))
145 function dump_txt(dataset,file)
148 f = io.open(file,"w")
151 for key,row in pairs(dataset) do
152 io.write(row["t"].." "..row["y"].."\n")
159 function dump_list(dataset,file)
162 f = io.open(file,"w")
165 for key,row in pairs(dataset) do
166 io.write(row["sensor_id"].." "..row["sensor"].." "..row["param"].."\n")
173 local command = arg[2]
176 local dbdriver = require "luasql.sqlite3"
177 env = assert(dbdriver.sqlite3())
178 con = assert(env:connect(logdb))
180 if command == "list" then
182 dump_list(get_list(day,con))
184 elseif command == "get" then
190 dump_txt(get_raw(day,con,sensor_id,sensor_type,param))
192 elseif command == "get-filtered" then
203 dataset =get_filtered(day,con,sensor_id,sensor_type,param)
206 elseif command == "get-compacted" then
217 dataset =get_filtered(day,con,sensor_id,sensor_type,param)
218 dump_txt(average_results(dataset))
220 elseif command == "dump" then
222 local directory = arg[4]
223 if not directory then
227 list = get_list(day,con)
228 dump_json(list,directory.."/sensors.json")
229 for key,value in pairs(list) do
230 dump_json(get_filtered(day,con,value["sensor_id"],value["sensor"],value["param"]),directory.."/"..value["sensor_id"].."."..value["sensor"].."."..value["param"]..".json")
233 elseif command == "dump-compacted" then
235 local directory = arg[4]
236 if not directory then
240 list = get_list(day,con)
241 dump_json(list,directory.."/sensors.json")
242 for key,value in pairs(list) do
243 dump_json(average_results(get_filtered(day,con,value["sensor_id"],value["sensor"],value["param"])),directory.."/"..value["sensor_id"].."."..value["sensor"].."."..value["param"]..".json")