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 -name "..pagetitle.." -duration "..graph_duration)
157 write_command(conn,"widget_add "..pageid.." "..pageid..".title title")
158 write_command(conn,"widget_add "..pageid.." "..pageid..".max string")
159 write_command(conn,"widget_add "..pageid.." "..pageid..".min string")
160 for k = 3,height-1 do
161 write_command(conn,"widget_add "..pageid.." "..pageid..".place"..trim(tostring(k)).." string")
164 write_command(conn,"widget_add "..pageid.." "..pageid..".bar"..trim(tostring(k)).." vbar")
166 write_command(conn,"widget_set "..pageid.." "..pageid..".title \"".. pagetitle.."\"")
172 function process_vals(vals)
173 for i,page in pairs(pages) do
174 col_width = pagecolwidth[i]
175 local pageid = "page"..trim(tostring(i))
176 for j,def in pairs(page) do
177 val = vals[def["sensor"]][def["param"]]
179 val = round(val * def["scale"], def["round"])
181 defid = def["sensor"].."."..def["param"]
182 val = lpad(tostring(val),def["pos"]).." "..def["unit"]
183 if not(def["label"] == "") then
184 val = def["label"]..": "..val
186 write_command(conn,"widget_set "..pageid.." "..defid.." "..trim(tostring((def["col"]-1)*col_width+1)).." "..def["line"].." \""..val.."\"")
191 function process_graphs()
192 for i,page in pairs(pages) do
193 for j,def in pairs(page) do
194 local sensor = def["sensor"]
195 local param = def["param"]
196 local pageid = sensor.."."..param
197 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)))
198 local row = cur:fetch ({}, "a")
200 local maxval = -99999999
201 local minval = 99999999
204 val = row["val"] * def["scale"]
205 row = cur:fetch ({}, "a")
210 if val and (val > maxval) then maxval = val; end
211 if val and (val < minval) then minval = val; end
213 minval = math.floor(minval)
214 local minvalstr = trim(tostring(minval))
215 maxval = math.ceil(maxval)
216 local maxvalstr = trim(tostring(maxval))
217 local len = math.max(string.len(minvalstr),string.len(maxvalstr))
218 write_command(conn,"widget_set "..pageid.." "..pageid..".max "..trim(tostring(width-string.len(maxvalstr)+1)).." 2 "..maxvalstr)
219 for k = 3,height-1 do
220 write_command(conn,"widget_set "..pageid.." "..pageid..".place"..trim(tostring(k)).." "..trim(tostring(width-len+1)).." "..k.." \" "..string.rep("-",len-1).."\"")
222 write_command(conn,"widget_set "..pageid.." "..pageid..".min "..trim(tostring(width-string.len(minvalstr)+1)).." "..height.." "..minvalstr)
224 for k = width-len,1,-1 do
227 h = math.floor(0.5+(val-minval)/(maxval-minval)*(height-1)*charheight)
231 write_command(conn,"widget_set "..pageid.." "..pageid..".bar"..trim(tostring(k)).." "..k.." "..height.." "..h)
235 write_command(conn,"widget_set "..pageid.." "..pageid..".bar"..trim(tostring(k)).." 0 0 0")
243 conn = connect_server()
249 vals = process_file()
256 os.execute("inotifywait -e MODIFY \""..weather_file.."\"")