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()
50 width = tonumber(uci.get(config_name,"display","width"))
51 height = tonumber(uci.get(config_name,"display","height"))
52 charwidth = tonumber(uci.get(config_name,"display","charwidth"))
53 charheight = tonumber(uci.get(config_name,"display","charheight"))
54 cols = tonumber(uci.get(config_name,"display","columns"))
55 title = uci.get(config_name,"display","title")
56 col_width = math.floor(width/cols)
62 local page, def, line, col, pos
64 cur.foreach(config_name,"display", function(s)
66 local pagetitle = s["title"]
70 local pageduration = s["duration"]
71 if not (pagetitle=="") then
78 for k,v in pairs(s["parameter"]) do
86 def["scale"] = tonumber(v[5])
87 def["round"] = tonumber(v[6])
88 def["pos"] = tonumber(v[7])
99 pages[#pages+1] = page
100 pagetitles[#pages] = pagetitle
101 pagedurations[#pages] = pageduration
106 function connect_server()
107 local ip = uci.get(config_name,"display","server")
108 local port = uci.get(config_name,"display","port")
109 conn = socket.connect(ip,port)
113 function write_command(conn,command)
114 conn:send(command.."\n")
115 local str=conn:receive()
119 function setup_pages(conn)
120 write_command(conn,"hello")
121 write_command(conn,"client_set -name weathermon")
122 for i,page in pairs(pages) do
123 local pageid = "page"..trim(tostring(i))
124 write_command(conn,"screen_add "..pageid)
125 local pagetitle = pagetitles[i]
126 write_command(conn,"screen_set "..pageid.." -cursor off")
127 if not(pagetitle == "") then
128 write_command(conn,"screen_set "..pageid.." -name "..pagetitle)
129 write_command(conn,"widget_add "..pageid.." "..pageid..".title title")
130 write_command(conn,"widget_set "..pageid.." "..pageid..".title \"".. pagetitle.."\"")
132 local pageduration = pagedurations[i]
133 if pageduration and not(pageduration == "") then
134 write_command(conn,"screen_set "..pageid.." -duration "..pageduration)
136 for j,def in pairs(page) do
137 defid = def["sensor"].."."..def["param"]
138 write_command(conn,"widget_add "..pageid.." "..defid.." string")
142 for i,page in pairs(pages) do
143 for j,def in pairs(page) do
144 pageid = def["sensor"].."."..def["param"]
145 pagetitle = trim(def["label"])..", "..def["unit"]
146 write_command(conn,"screen_add "..pageid)
147 write_command(conn,"screen_set "..pageid.." -cursor off")
148 write_command(conn,"screen_set "..pageid.." -name "..pagetitle.." -duration "..graph_duration)
149 write_command(conn,"widget_add "..pageid.." "..pageid..".title title")
150 write_command(conn,"widget_set "..pageid.." "..pageid..".title \"".. pagetitle.."\"")
151 write_command(conn,"widget_add "..pageid.." "..pageid..".max string")
152 write_command(conn,"widget_add "..pageid.." "..pageid..".min string")
153 for k=1,width-def["pos"] do
154 write_command(conn,"widget_add "..pageid.." "..pageid..".bar"..trim(tostring(k)).." vbar")
161 function process_vals(vals)
162 for i,page in pairs(pages) do
163 local pageid = "page"..trim(tostring(i))
164 for j,def in pairs(page) do
165 val = vals[def["sensor"]][def["param"]]
167 val = round(val * def["scale"], def["round"])
169 defid = def["sensor"].."."..def["param"]
170 val = lpad(tostring(val),def["pos"]).." "..def["unit"]
171 if not(def["label"] == "") then
172 val = def["label"]..": "..val
174 write_command(conn,"widget_set "..pageid.." "..defid.." "..trim(tostring((def["col"]-1)*col_width+1)).." "..def["line"].." \""..val.."\"")
179 function process_graphs()
180 for i,page in pairs(pages) do
181 for j,def in pairs(page) do
182 local sensor = def["sensor"]
183 local param = def["param"]
184 local pageid = sensor.."."..param
185 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)))
186 local row = cur:fetch ({}, "a")
188 local maxval = -99999999
189 local minval = 99999999
190 for k=width-def["pos"],1,-1 do
193 row = cur:fetch ({}, "a")
198 if val and (val > maxval) then maxval = val; end
199 if val and (val < minval) then minval = val; end
201 minval = math.floor(minval)
202 minvalstr = trim(tostring(minval))
203 maxval = math.ceil(maxval)
204 maxvalstr = trim(tostring(maxval))
205 write_command(conn,"widget_set "..pageid.." "..pageid..".max "..trim(tostring(width-string.len(maxvalstr)+1)).." 2 "..maxvalstr)
206 write_command(conn,"widget_set "..pageid.." "..pageid..".min "..trim(tostring(width-string.len(minvalstr)+1)).." "..height.." "..minvalstr)
207 for k = 1,width-def["pos"] do
210 h = math.floor(0.5+(val-minval)/(maxval-minval)*(height-1)*charheight)
214 write_command(conn,"widget_set "..pageid.." "..pageid..".bar"..trim(tostring(k)).." "..k.." "..height.." "..h)
222 conn = connect_server()
228 vals = process_file()
235 os.execute("inotifywait -e MODIFY \""..weather_file.."\"")