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")