2019-01-21 14:41:31 -07:00
|
|
|
#!/usr/bin/lua
|
|
|
|
--[[
|
|
|
|
|
|
|
|
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
|
|
|
Copyright (C) 2018 Darryl Quinn
|
|
|
|
See Contributors file for additional contributors
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation version 3 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Additional Terms:
|
|
|
|
|
|
|
|
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
|
|
|
See AREDNLicense.txt for more info.
|
|
|
|
|
|
|
|
Attributions to the AREDN Project must be retained in the source code.
|
|
|
|
If importing this code into a new or existing project attribution
|
|
|
|
to the AREDN project must be added to the source code.
|
|
|
|
|
|
|
|
You must not misrepresent the origin of the material contained within.
|
|
|
|
|
|
|
|
Modified versions must be modified to attribute to the original source
|
|
|
|
and be marked in reasonable ways as differentiate it from the original
|
|
|
|
version
|
|
|
|
|
|
|
|
--]]
|
|
|
|
|
|
|
|
require("uci")
|
|
|
|
require("aredn.uci")
|
|
|
|
require("aredn.utils")
|
|
|
|
require("aredn.http")
|
2019-03-26 00:04:33 -06:00
|
|
|
local aredn_olsr = require("aredn.olsr")
|
2019-01-21 14:41:31 -07:00
|
|
|
local aredn_info = require("aredn.info")
|
|
|
|
require("nixio")
|
|
|
|
local json = require("luci.jsonc")
|
2019-03-25 15:56:38 -06:00
|
|
|
require("iwinfo")
|
2019-01-21 14:41:31 -07:00
|
|
|
|
2022-07-19 19:27:44 -06:00
|
|
|
local API_VERSION="1.5"
|
2021-04-23 09:10:40 -06:00
|
|
|
|
2019-01-21 14:41:31 -07:00
|
|
|
-- Function extensions
|
|
|
|
os.capture = capture
|
|
|
|
|
|
|
|
|
|
|
|
function getSysinfo()
|
|
|
|
local info={}
|
2021-07-18 20:21:12 -06:00
|
|
|
info['api_version']=API_VERSION
|
2019-01-21 14:41:31 -07:00
|
|
|
info['node']=aredn_info.getNodeName()
|
2021-09-09 07:32:24 -06:00
|
|
|
info['tactical']=aredn_info.getTacticalName()
|
2019-01-21 14:41:31 -07:00
|
|
|
info['description']=aredn_info.getNodeDescription()
|
|
|
|
info['firmware_version']=aredn_info.getFirmwareVersion()
|
|
|
|
info['model']=aredn_info.getModel()
|
|
|
|
--
|
|
|
|
info['date']=aredn_info.getDate()
|
|
|
|
info['time']=aredn_info.getTime()
|
|
|
|
--
|
|
|
|
info['uptime']=aredn_info.getUptime()
|
|
|
|
info['loads']=aredn_info.getLoads()
|
2019-05-11 11:08:37 -06:00
|
|
|
info['first_boot']=aredn_info.getFirstBoot()
|
2021-04-23 09:10:40 -06:00
|
|
|
info['target_type']=aredn_info.getTargetType()
|
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
|
|
|
function getAlerts()
|
|
|
|
local info={}
|
|
|
|
info['aredn']=aredn_info.getArednAlert()
|
|
|
|
info['local']=aredn_info.getLocalAlert()
|
2019-01-21 14:41:31 -07:00
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
|
|
|
function getStatusMeshRF()
|
|
|
|
local info={}
|
2021-05-05 11:53:19 -06:00
|
|
|
local dev = aredn_info.getMeshRadioDevice()
|
|
|
|
if dev ~= "" then
|
|
|
|
info['device']= dev
|
|
|
|
info['ssid']=aredn_info.getSSID()
|
|
|
|
info['channel']=aredn_info.getChannel(info['device'])
|
|
|
|
info['chanbw']=aredn_info.getChannelBW(info['device'])
|
|
|
|
info['band']=aredn_info.getBand(info['device'])
|
|
|
|
info['frequency']=aredn_info.getFreq(info['device'])
|
|
|
|
end
|
2019-01-21 14:41:31 -07:00
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
|
|
|
function getStatusIp()
|
|
|
|
local info={}
|
|
|
|
info['gateway']=aredn_info.getDefaultGW()
|
|
|
|
info['wifi']=aredn_info.getInterfaceIPAddress('wifi')
|
|
|
|
info['lan']=aredn_info.getInterfaceIPAddress('lan')
|
|
|
|
info['wan']=aredn_info.getInterfaceIPAddress('wan')
|
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
|
|
|
function getLocationInfo()
|
|
|
|
local info={}
|
|
|
|
local lat, lon= aredn_info.getLatLon()
|
|
|
|
local gs= aredn_info.getGridSquare()
|
|
|
|
info['lat']=lat
|
|
|
|
info['lon']=lon
|
|
|
|
info['gridsquare']=gs
|
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
|
|
|
function getFreeMemory()
|
|
|
|
local info = aredn_info.getFreeMemory()
|
|
|
|
return info
|
|
|
|
end
|
|
|
|
|
2021-06-06 06:33:43 -06:00
|
|
|
|
|
|
|
function get_key_for_value( t, value )
|
|
|
|
for k,v in pairs(t) do
|
|
|
|
if v==value then return k end
|
|
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
function getRemoteNodes()
|
2022-04-05 18:30:36 -06:00
|
|
|
local info = {}
|
|
|
|
local neighbors = {}
|
|
|
|
for _, v in ipairs(aredn_olsr.getOLSRLinks())
|
|
|
|
do
|
|
|
|
local remoteIP = v.remoteIP
|
|
|
|
neighbors[remoteIP] = true
|
|
|
|
local name = nixio.getnameinfo(remoteIP)
|
|
|
|
if name then
|
|
|
|
local cname = name:match("^dtdlink%.(.*)$") or name:match("^mid%d+%.(.*)$")
|
|
|
|
if cname then
|
|
|
|
local addrs = nixio.getaddrinfo(cname)
|
|
|
|
if addrs then
|
|
|
|
neighbors[addrs[1].address] = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local routeetx = {}
|
|
|
|
for _, v in ipairs(aredn_olsr.getOLSRRoutes())
|
|
|
|
do
|
|
|
|
routeetx[v.destination] = string.format("%.2f", v.etx)
|
2021-06-06 06:33:43 -06:00
|
|
|
end
|
2022-04-05 18:30:36 -06:00
|
|
|
for line in io.lines("/var/run/hosts_olsr")
|
|
|
|
do
|
|
|
|
local ip, hostname = line:match("^(%d+%.%d+%.%d+%.%d+)%s+(%S+)%s+#.*$")
|
|
|
|
if ip and not neighbors[ip] and not (hostname:match("^dtdlink%.") or hostname:match("^mid%d+%.")) then
|
|
|
|
local etx = routeetx[ip]
|
|
|
|
if etx then
|
|
|
|
info[#info + 1] = {
|
|
|
|
name = hostname,
|
|
|
|
ip = ip,
|
|
|
|
etx = etx
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
table.sort(info, function(a,b) return tonumber(a.etx) < tonumber(b.etx) end)
|
|
|
|
return info
|
2021-06-06 06:33:43 -06:00
|
|
|
end
|
|
|
|
|
2019-04-16 20:08:45 -06:00
|
|
|
-- gets signal and noise data from either iwinfo (realtime = true) or the files archived in /tmp/snrlog (realtime = false)
|
|
|
|
-- the files in /tmp/snrlog are written once per minute by the script /usr/local/bin/snrlog
|
|
|
|
function getSignal(realtime)
|
2019-03-25 17:34:51 -06:00
|
|
|
local defnoise=-95
|
|
|
|
local dpa={} -- datapoint table/array
|
|
|
|
local dirname="/tmp/snrlog"
|
2019-04-16 20:08:45 -06:00
|
|
|
|
2019-03-25 17:34:51 -06:00
|
|
|
local datepattern="(%d+)/(%d+)/(%d+)%s(%d+):(%d+):(%d+)"
|
|
|
|
|
|
|
|
local parms={}
|
|
|
|
parms=parsecgi(nixio.getenv("QUERY_STRING") or "")
|
|
|
|
|
|
|
|
-- make sure snrlog dir is created
|
|
|
|
if dir_exists(dirname) then
|
|
|
|
nixio.fs.mkdir(dirname)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- get wifi ifname
|
|
|
|
local wifiiface=get_ifname("wifi")
|
|
|
|
|
|
|
|
-- get bandwidth
|
|
|
|
local radio=aredn_info.getMeshRadioDevice()
|
|
|
|
local bandwidth=aredn_info.getChannelBW(radio)
|
|
|
|
|
2019-04-16 20:08:45 -06:00
|
|
|
local timestamp_s=os.time()
|
|
|
|
local signal_dbm, noise_dbm, tx_rate_mbps, rx_rate_mbps, tx_rate_mcs_index, rx_rate_mcs_index
|
|
|
|
|
|
|
|
--[[
|
|
|
|
-- insertResult() transforms data from iwinfo (realtime) and snrlog (archive) so that the responses are always the same.
|
|
|
|
-- the front end expects data points that look like this:
|
|
|
|
{
|
|
|
|
timestamp: string;
|
|
|
|
signal_dbm: number;
|
|
|
|
noise_dbm: number;
|
|
|
|
tx_rate_mbps: number;
|
|
|
|
rx_rate_mbps: number;
|
|
|
|
tx_rate_mcs_index: number | undefined;
|
|
|
|
rx_rate_mcs_index: number | undefined;
|
|
|
|
}
|
|
|
|
]]--
|
|
|
|
|
|
|
|
function insertResult(timestamp_s_epoch, signal_dbm, noise_dbm, tx_rate_mbps, rx_rate_mbps, tx_rate_mcs_index, rx_rate_mcs_index)
|
2019-03-25 17:34:51 -06:00
|
|
|
local dp={} -- datapoint
|
2019-04-16 20:08:45 -06:00
|
|
|
local timestamp
|
|
|
|
|
|
|
|
-- snrlog sometimes has the string "null" for signal/noise, if so then assume they are zero
|
|
|
|
if signal_dbm=="null" then
|
2021-04-06 20:18:00 -06:00
|
|
|
signal_dbm = -95
|
2019-04-16 20:08:45 -06:00
|
|
|
end
|
|
|
|
if noise_dbm=="null" then
|
2021-04-06 20:18:00 -06:00
|
|
|
noise_dbm = -95
|
2019-04-16 20:08:45 -06:00
|
|
|
end
|
2019-03-25 17:34:51 -06:00
|
|
|
|
2019-04-16 20:08:45 -06:00
|
|
|
-- signal and noise might also be nil, so convert them to numbers
|
2021-04-06 20:18:00 -06:00
|
|
|
signal_dbm = tonumber(signal_dbm or -95)
|
|
|
|
noise_dbm = tonumber(noise_dbm or -95)
|
2019-04-16 20:08:45 -06:00
|
|
|
|
|
|
|
--snrlog sometimes has -1 for mcs indices, if so then make them undefined
|
|
|
|
if tx_rate_mcs_index == -1 or tx_rate_mcs_index == "-1" then
|
|
|
|
tx_rate_mcs_index = nil
|
|
|
|
end
|
|
|
|
if rx_rate_mcs_index == -1 or rx_rate_mcs_index == "-1" then
|
|
|
|
rx_rate_mcs_index = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
-- convert from seconds since epoch to iso 8601 format
|
|
|
|
timestamp=os.date("%Y-%m-%dT%H:%M:%SZ", timestamp_s_epoch)
|
|
|
|
|
|
|
|
dp.timestamp = timestamp
|
|
|
|
dp.signal_dbm=signal_dbm
|
|
|
|
dp.noise_dbm=noise_dbm
|
|
|
|
dp.tx_rate_mbps=tonumber(tx_rate_mbps or 0)
|
|
|
|
dp.rx_rate_mbps=tonumber(rx_rate_mbps or 0)
|
|
|
|
dp.tx_rate_mcs_index=tonumber(tx_rate_mcs_index)
|
|
|
|
dp.rx_rate_mcs_index=tonumber(rx_rate_mcs_index)
|
|
|
|
table.insert(dpa,dp)
|
|
|
|
end
|
|
|
|
|
|
|
|
if realtime then
|
|
|
|
-- REALTIME
|
2019-03-25 17:34:51 -06:00
|
|
|
if (parms.device=="strongest" or parms.device=="" or (not parms.device)) then
|
|
|
|
-- REALTIME/STRONGEST SIGNAL
|
2019-04-16 20:08:45 -06:00
|
|
|
signal_dbm=iwinfo["nl80211"].signal(wifiiface)
|
|
|
|
noise_dbm=iwinfo["nl80211"].noise(wifiiface)
|
2019-03-25 17:34:51 -06:00
|
|
|
else
|
|
|
|
-- REALTIME/SPECIFIC SIGNAL
|
|
|
|
-- split out device to mac-host
|
|
|
|
local mac,host=string.match(parms.device,"([^-]*)-(.*)")
|
|
|
|
local macinfo=iwinfo["nl80211"].assoclist(wifiiface)[mac:upper()]
|
|
|
|
|
2019-04-16 20:08:45 -06:00
|
|
|
signal_dbm=macinfo.signal
|
|
|
|
noise_dbm=macinfo.noise
|
|
|
|
tx_rate_mbps=macinfo.tx_rate/1000
|
|
|
|
tx_rate_mbps=adjust_rate(tx_rate_mbps,bandwidth)
|
|
|
|
rx_rate_mbps=macinfo.rx_rate/1000
|
|
|
|
rx_rate_mbps=adjust_rate(rx_rate_mbps,bandwidth)
|
|
|
|
tx_rate_mcs_index=macinfo.tx_mcs
|
|
|
|
rx_rate_mcs_index=macinfo.rx_mcs
|
2019-03-25 17:34:51 -06:00
|
|
|
end
|
2019-04-16 20:08:45 -06:00
|
|
|
insertResult(timestamp_s, signal_dbm, noise_dbm, tx_rate_mbps, rx_rate_mbps, tx_rate_mcs_index, rx_rate_mcs_index )
|
2019-03-25 17:34:51 -06:00
|
|
|
else
|
|
|
|
-- ARCHIVE
|
|
|
|
local filename
|
|
|
|
if not parms.device or parms.device=="" then
|
|
|
|
-- get the first file from dirlist
|
|
|
|
for maclist in nixio.fs.glob(dirname.."/".."*") do
|
|
|
|
filename=maclist
|
|
|
|
parms.device=maclist
|
|
|
|
break
|
|
|
|
end
|
|
|
|
else
|
|
|
|
filename=dirname.."/"..parms.device
|
|
|
|
end
|
|
|
|
|
|
|
|
if filename then
|
|
|
|
for line in io.lines(filename) do
|
2019-04-16 20:08:45 -06:00
|
|
|
local timestamp
|
|
|
|
timestamp,signal_dbm,noise_dbm,tx_rate_mcs_index,tx_rate_mbps,rx_rate_mcs_index,rx_rate_mbps=line:match("(.*)%,(.*)%,(.*),(.*),(.*),(.*),(.*)")
|
|
|
|
|
|
|
|
-- convert the timestamp to seconds since epoch
|
|
|
|
local dtm,dtd,dty,dth,dtmin,dts=timestamp:match(datepattern)
|
|
|
|
timestamp_s = os.time({month=dtm,day=dtd,year=dty,hour=dth,min=dtmin,sec=dts})
|
|
|
|
|
|
|
|
insertResult(timestamp_s, signal_dbm, noise_dbm, tx_rate_mbps, rx_rate_mbps, tx_rate_mcs_index, rx_rate_mcs_index)
|
2019-03-25 17:34:51 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-04-16 20:08:45 -06:00
|
|
|
return dpa
|
2019-03-25 17:34:51 -06:00
|
|
|
end
|
|
|
|
|
2019-03-25 15:56:38 -06:00
|
|
|
function getScanList()
|
|
|
|
local device = aredn_info.getMeshRadioDevice()
|
|
|
|
local scanlist = iwinfo["nl80211"].scanlist(device)
|
|
|
|
return scanlist
|
|
|
|
end
|
|
|
|
|
|
|
|
function getFreqList()
|
|
|
|
local device = aredn_info.getMeshRadioDevice()
|
|
|
|
local freqlist = iwinfo["nl80211"].freqlist(device)
|
|
|
|
return freqlist
|
|
|
|
end
|
2019-01-21 14:41:31 -07:00
|
|
|
|
|
|
|
-- ==== MAIN =====
|
|
|
|
ctx = uci.cursor()
|
|
|
|
if not ctx then
|
|
|
|
error("Failed to get uci cursor")
|
|
|
|
end
|
|
|
|
|
|
|
|
info={}
|
2021-04-23 09:10:40 -06:00
|
|
|
info['api_version'] = API_VERSION
|
2019-01-21 14:41:31 -07:00
|
|
|
|
|
|
|
-- get/process query string
|
|
|
|
local qsset={}
|
|
|
|
if (arg[1]==nil and arg[2]==nil) then
|
|
|
|
qs=nixio.getenv("QUERY_STRING")
|
|
|
|
if qs~="" then
|
|
|
|
qsset=parseQueryString(qs)
|
|
|
|
else
|
|
|
|
-- maybe default to a help page
|
|
|
|
qsset["api"]="help"
|
|
|
|
end
|
|
|
|
else
|
|
|
|
qsset[arg[1]]=arg[2]
|
|
|
|
end
|
|
|
|
|
|
|
|
info['pages']={}
|
|
|
|
|
|
|
|
for page, comps in pairs(qsset) do
|
|
|
|
-- ---------------- /mesh page
|
|
|
|
if not setContains(info['pages'],page) then
|
|
|
|
info['pages'][page]={}
|
|
|
|
end
|
|
|
|
|
|
|
|
if page=="api" then
|
|
|
|
info['pages'][page]=nil
|
|
|
|
info['api_help']="AREDN API. This API's primary function is to drive the Web UI."
|
2021-04-23 09:10:40 -06:00
|
|
|
elseif page=="common" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="sysinfo" then
|
|
|
|
info['pages'][page][comp]=getSysinfo()
|
|
|
|
elseif comp=="alerts" then
|
|
|
|
info['pages'][page][comp]=getAlerts()
|
|
|
|
end
|
|
|
|
end
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif page=="status" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="meshrf" then
|
|
|
|
info['pages'][page][comp]=getStatusMeshRF()
|
|
|
|
elseif comp=="ip" then
|
|
|
|
info['pages'][page][comp]=getStatusIp()
|
|
|
|
elseif comp=="sysinfo" then
|
|
|
|
info['pages'][page][comp]=getSysinfo()
|
|
|
|
elseif comp=="memory" then
|
|
|
|
info['pages'][page][comp]=getFreeMemory()
|
|
|
|
elseif comp=="storage" then
|
|
|
|
info['pages'][page][comp]=aredn_info.getFSFree()
|
|
|
|
elseif comp=="olsr" then
|
|
|
|
info['pages'][page][comp]=aredn_info.getOLSRInfo()
|
|
|
|
elseif comp=="location" then
|
|
|
|
info['pages'][page][comp]=getLocationInfo()
|
2019-03-25 15:56:38 -06:00
|
|
|
elseif comp=="freqlist" then
|
|
|
|
info['pages'][page][comp]=getFreqList()
|
2021-04-23 09:10:40 -06:00
|
|
|
elseif comp=="alerts" then
|
|
|
|
info['pages'][page][comp]=getAlerts()
|
2019-01-21 14:41:31 -07:00
|
|
|
end
|
|
|
|
end
|
2021-06-06 06:33:43 -06:00
|
|
|
elseif page=="traceroute" then
|
|
|
|
for i,tonode in pairs(comps:split(',')) do
|
2021-11-11 10:32:30 -07:00
|
|
|
-- Validate that input as ip or hostname inside the mesh
|
|
|
|
if tonode:match("^[%d%.]+$") or tonode:match("^[%d%a%-%.%_]+$") then
|
2021-06-06 06:33:43 -06:00
|
|
|
info['pages'][page][tonode]=getTraceroute(tonode)
|
2021-11-11 10:32:30 -07:00
|
|
|
else
|
|
|
|
info['pages'][page][tonode]="Invalid input!"
|
2021-06-06 06:33:43 -06:00
|
|
|
end
|
|
|
|
end
|
2022-07-19 19:27:44 -06:00
|
|
|
elseif page=="ping" then
|
|
|
|
for i,tonode in pairs(comps:split(',')) do
|
|
|
|
-- Validate that input as ip or hostname inside the mesh
|
|
|
|
if tonode:match("^[%d%.]+$") or tonode:match("^[%d%a%-%.%_]+$") then
|
|
|
|
info['pages'][page][tonode]=getPing(tonode)
|
|
|
|
else
|
|
|
|
info['pages'][page][tonode]="Invalid input!"
|
|
|
|
end
|
|
|
|
end
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif page=="mesh" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="sysinfo" then
|
|
|
|
info['pages'][page][comp]=getSysinfo()
|
2021-06-06 06:33:43 -06:00
|
|
|
elseif comp=="allhosts" then
|
|
|
|
info['pages'][page][comp]=aredn_info.all_hosts()
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif comp=="localhosts" then
|
2019-03-27 21:21:23 -06:00
|
|
|
info['pages'][page][comp]=aredn_info.getLocalHosts()
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif comp=="remotenodes" then
|
2021-06-06 06:33:43 -06:00
|
|
|
info['pages'][page][comp]=getRemoteNodes()
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif comp=="currentneighbors" then
|
2021-05-26 08:57:47 -06:00
|
|
|
info['pages'][page][comp]=aredn_olsr.getCurrentNeighbors(true)
|
|
|
|
elseif comp=="services" then
|
|
|
|
info['pages'][page][comp]=aredn_info.all_services()
|
2019-01-21 14:41:31 -07:00
|
|
|
elseif comp=="previousneighbors" then
|
|
|
|
info['pages'][page][comp]={}
|
2021-07-10 11:38:11 -06:00
|
|
|
elseif comp=="topology" then
|
|
|
|
info['pages'][page][comp]=fetch_json("http://127.0.0.1:9090/topology")
|
2019-01-21 14:41:31 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif page=="services" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="sysinfo" then
|
|
|
|
info['pages'][page][comp]=getSysinfo()
|
|
|
|
elseif comp=="bynode" then
|
|
|
|
info['pages'][page][comp]=getServicesByNode()
|
|
|
|
elseif comp=="byservice" then
|
|
|
|
info['pages'][page][comp]=getServicesByService()
|
|
|
|
end
|
|
|
|
end
|
2019-03-25 17:34:51 -06:00
|
|
|
elseif page=="chart" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="realtime" then
|
|
|
|
info['pages'][page][comp]=getSignal(true)
|
|
|
|
elseif comp=="archive" then
|
|
|
|
info['pages'][page][comp]=getSignal(false)
|
|
|
|
end
|
|
|
|
end
|
2019-03-25 15:56:38 -06:00
|
|
|
elseif page=="scan" then
|
|
|
|
for i,comp in pairs(comps:split(',')) do
|
|
|
|
if comp=="scanlist" then
|
|
|
|
info['pages'][page][comp]=getScanList()
|
|
|
|
end
|
|
|
|
end
|
2019-03-25 17:34:51 -06:00
|
|
|
end
|
2019-01-21 14:41:31 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Output the HTTP header for JSON
|
|
|
|
-- json_header()
|
|
|
|
json_header()
|
|
|
|
|
|
|
|
-- Output the info table as json
|
2019-05-01 20:07:30 -06:00
|
|
|
print(json.stringify(info,true))
|