3 socket = require "socket"
 
  10 if not config_name then
 
  11   config_name = "weathermon"
 
  14 weather_file = uci.get(config_name,"process","dump_file")
 
  15 weather_db = uci.get(config_name,"process","logdb")
 
  17 graph_duration = uci.get(config_name,"display","graph_duration")
 
  19 if graph_duration and not(weather_db == "") then
 
  21       local dbdriver = require "luasql.sqlite3"
 
  22       local env = assert(dbdriver.sqlite3())
 
  23       log_con = assert(env:connect(weather_db))
 
  27 function round(num, numDecimalPlaces)
 
  28   local mult = 10^(numDecimalPlaces or 0)
 
  29   return math.floor(num * mult + 0.5) / mult
 
  33   return (s:gsub("^%s*(.-)%s*$", "%1"))
 
  36 function lpad(s, l, c)
 
  37   local res = string.rep(c or ' ', l - #s) .. s
 
  41 function process_file()
 
  42   txt = get_file_content(weather_file)
 
  43   data = json.decode(txt)
 
  44   for k,v in pairs(data) do
 
  49 function get_display_config()
 
  51   width  = tonumber(uci.get(config_name,"display","width"))
 
  52   height = tonumber(uci.get(config_name,"display","height"))
 
  53   charwidth  = tonumber(uci.get(config_name,"display","charwidth"))
 
  54   charheight = tonumber(uci.get(config_name,"display","charheight"))
 
  55   title  = uci.get(config_name,"display","title")
 
  63   local page, def, line, col, pos
 
  65   cur.foreach(config_name,"display", function(s) 
 
  67       local columns = s["columns"]
 
  68       if not columns or columns == "" then
 
  71         columns = tonumber(columns)
 
  73       local pagetitle = s["title"]
 
  77       local pageduration = s["duration"]
 
  78       if not (pagetitle=="") then
 
  85       for k,v in pairs(s["parameter"]) do
 
  93           def["scale"] = tonumber(v[5])
 
  94           def["round"] = tonumber(v[6])
 
  95           def["pos"] = tonumber(v[7])
 
 101         if col > columns then
 
 106       pages[#pages+1] = page
 
 107       pagetitles[#pages] = pagetitle
 
 108       pagedurations[#pages] = pageduration
 
 109       pagecolumns[#pages] = columns
 
 110       pagecolwidth[#pages] = math.floor(width/columns)
 
 115 function connect_server()
 
 116   local ip = uci.get(config_name,"display","server")
 
 117   local port = uci.get(config_name,"display","port")
 
 118   conn = socket.connect(ip,port)
 
 122 function write_command(conn,command)
 
 123   conn:send(command.."\n")
 
 124   local str=conn:receive()
 
 128 function setup_pages(conn)
 
 129   write_command(conn,"hello")
 
 130   write_command(conn,"client_set -name weathermon")
 
 131   for i,page in pairs(pages) do
 
 132     local pageid = "page"..trim(tostring(i))
 
 133     write_command(conn,"screen_add "..pageid)
 
 134     local pagetitle = pagetitles[i]
 
 135     write_command(conn,"screen_set "..pageid.." -cursor off")
 
 136     if not(pagetitle == "") then
 
 137       write_command(conn,"screen_set "..pageid.." -name "..pagetitle)
 
 138       write_command(conn,"widget_add "..pageid.." "..pageid..".title title")
 
 139       write_command(conn,"widget_set "..pageid.." "..pageid..".title \"".. pagetitle.."\"")
 
 141     local pageduration = pagedurations[i]
 
 142     if pageduration and not(pageduration == "") then
 
 143       write_command(conn,"screen_set "..pageid.." -duration "..pageduration)
 
 145     for j,def in pairs(page) do
 
 146       defid = def["sensor"].."."..def["param"]
 
 147       write_command(conn,"widget_add "..pageid.." "..defid.." string")
 
 151     for i,page in pairs(pages) do
 
 152       for j,def in pairs(page) do
 
 153         pageid = def["sensor"].."."..def["param"]
 
 154         pagetitle = trim(def["label"])..", "..def["unit"]
 
 155         write_command(conn,"screen_add "..pageid)
 
 156         write_command(conn,"screen_set "..pageid.." -cursor off")
 
 157         write_command(conn,"screen_set "..pageid.." -name "..pagetitle.." -duration "..graph_duration)
 
 158         write_command(conn,"widget_add "..pageid.." "..pageid..".title title")
 
 159         write_command(conn,"widget_set "..pageid.." "..pageid..".title \"".. pagetitle.."\"")
 
 160         write_command(conn,"widget_add "..pageid.." "..pageid..".max string")
 
 161         write_command(conn,"widget_add "..pageid.." "..pageid..".min string")
 
 162         for k=1,width-def["pos"] do
 
 163           write_command(conn,"widget_add "..pageid.." "..pageid..".bar"..trim(tostring(k)).." vbar")
 
 170 function process_vals(vals)
 
 171   for i,page in pairs(pages) do
 
 172     col_width = pagecolwidth[i]
 
 173     local pageid = "page"..trim(tostring(i))
 
 174     for j,def in pairs(page) do
 
 175       val = vals[def["sensor"]][def["param"]]
 
 177         val = round(val * def["scale"], def["round"])
 
 179       defid = def["sensor"].."."..def["param"]
 
 180       val = lpad(tostring(val),def["pos"]).." "..def["unit"]
 
 181       if not(def["label"] == "") then
 
 182         val = def["label"]..": "..val
 
 184       write_command(conn,"widget_set "..pageid.." "..defid.." "..trim(tostring((def["col"]-1)*col_width+1)).." "..def["line"].." \""..val.."\"")
 
 189 function process_graphs()
 
 190   for i,page in pairs(pages) do
 
 191     for j,def in pairs(page) do
 
 192       local sensor = def["sensor"]
 
 193       local param  = def["param"]
 
 194       local pageid = sensor.."."..param
 
 195       local cur = assert (log_con:execute(string.format("select hour,avg(value) val from (select strftime('%%Y-%%m-%%d %%H',time_stamp)||':00' hour,value from log where sensor='%s' and param='%s') group by hour order by hour desc limit 24",sensor,param)))
 
 196       local row = cur:fetch ({}, "a")
 
 198       local maxval = -99999999
 
 199       local minval =  99999999
 
 200       for k=width-def["pos"],1,-1 do
 
 203           row = cur:fetch ({}, "a")
 
 208         if val and (val > maxval) then maxval = val; end
 
 209         if val and (val < minval) then minval = val; end
 
 211       minval = math.floor(minval)
 
 212       minvalstr = trim(tostring(minval))
 
 213       maxval = math.ceil(maxval)
 
 214       maxvalstr = trim(tostring(maxval))
 
 215       write_command(conn,"widget_set "..pageid.." "..pageid..".max "..trim(tostring(width-string.len(maxvalstr)+1)).." 2 "..maxvalstr)
 
 216       write_command(conn,"widget_set "..pageid.." "..pageid..".min "..trim(tostring(width-string.len(minvalstr)+1)).." "..height.." "..minvalstr)
 
 217       for k = 1,width-def["pos"] do
 
 220           h = math.floor(0.5+(val-minval)/(maxval-minval)*(height-1)*charheight)
 
 224         write_command(conn,"widget_set "..pageid.." "..pageid..".bar"..trim(tostring(k)).." "..k.." "..height.." "..h)
 
 232 conn = connect_server()
 
 238   vals = process_file()
 
 245   os.execute("inotifywait -e MODIFY \""..weather_file.."\"")