+#!/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
+
\ No newline at end of file