#!/usr/bin/lua require "uci" cur = uci.cursor() lfs = require "lfs" json = require "json" socket = require "socket" function split(str, pat) local t = {} -- NOTE: use {n = 0} in Lua-5.0 local fpat = "(.-)" .. pat local last_end = 1 local s, e, cap = str:find(fpat, 1) while s do if s ~= 1 or cap ~= "" then table.insert(t,cap) end last_end = e+1 s, e, cap = str:find(fpat, last_end) end if last_end <= #str then cap = str:sub(last_end) table.insert(t, cap) end return t end function trim(s) return (s:gsub("^%s*(.-)%s*$", "%1")) end function get_device_list(config_name) local devices devices = {} cur.foreach(config_name, "device", function(s) devices[#devices+1] = s[".name"] end) return devices end function get_device(config_name,device_name) local device device = {} cur.foreach(config_name, "device", function(s) if s[".name"] == device_name then device = s end end) return device end function get_file_content(name) local f = io.open(name,"r") if f ~= nil then local content = trim(f:read("*all")) io.close(f) return content else return false end end function find_device(name,subsystem) local search_base if subsystem == "iio" then search_base = "/sys/bus/iio/devices" for file in lfs.dir(search_base) do if get_file_content(search_base.."/"..file.."/name") == name then return search_base.."/"..file end end elseif subsystem == "hwmon" then search_base = "/sys/class/hwmon" for file in lfs.dir(search_base) do if get_file_content(search_base.."/"..file.."/device/name") == name then return search_base.."/"..file.."/device" end end end return nil end function init_device(device,parameters,i2c_bus) if not i2c_bus then i2c_bus = 0 end if device["module"] then os.execute("modprobe "..device["module"]) end if device["type"] then devtype = split(device["type"],":") bus = devtype[1] subsystem = devtype[2] if (bus == "i2c") and device["address"] and device["name"] then pcall(function () local f = io.open("/sys/class/i2c-dev/i2c-"..i2c_bus.."/device/new_device","w") io.output(f) io.write(device["name"].." "..device["address"]) io.close(f) end) end device_path=find_device(device["name"],subsystem) if device_path and device["set_param"] then for key,record in pairs(device["set_param"]) do setparam = split(record,":") setpath = device_path.."/"..setparam[1] pcall(function () local f = io.open(setpath,"w") io.output(f) io.write(setparam[2]) io.close(f) end) end end if device_path and device["parameter"] then for key,record in pairs(device["parameter"]) do getparam = split(record,":") getparameter = {} getparameter["path"] = device_path.."/"..getparam[1] getparameter["name"] = getparam[2] getscale = getparam[3] getcorrection = getparam[4] if not getscale then getscale = 1 end if not getcorrection then getcorrection = 0 end getparameter["scale"] = tonumber(getscale) getparameter["sensor"] = device["name"]:upper() getparameter["correction"] = tonumber(getcorrection) parameters[#parameters+1] = getparameter end end end end function init(config_name) local parameters= {} i2c_bus = uci.get(config_name,"hardware","i2c_bus") local devices = get_device_list(config_name) for key,devname in pairs(devices) do device = get_device(config_name,devname) if device then init_device(device,parameters,i2c_bus) end end return parameters end function get_parameter(parameter) return tonumber(get_file_content(parameter["path"])) * parameter["scale"] + parameter["correction"] end function get_parameters(parameters) local results = {} for key,record in pairs(parameters) do if not results[record["sensor"]] then results[record["sensor"]] = {} end results[record["sensor"]][record["name"]] = get_parameter(record) end return results end config_name = arg[1] if not config_name then config_name = "weathermon" end parameters = init(config_name) local delay = uci.get(config_name,"process","delay") local working_dir = uci.get(config_name,"process","working_dir") local dump_file = uci.get(config_name,"process","dump_file") if working_dir then lfs.mkdir(working_dir) end if not delay then delay = 60 end while true do values = get_parameters(parameters) for key,record in pairs(values) do dump = record dump["device"] = key print(json.encode(dump)) end if dump_file then local f = io.open(dump_file,"w") io.output(f) io.write(json.encode(values)) io.close(f) end socket.sleep(delay) end