Больше не поддерживается вариант на python.
[weathermon.git] / weathermon-iio
diff --git a/weathermon-iio b/weathermon-iio
new file mode 100755 (executable)
index 0000000..93b9cb5
--- /dev/null
@@ -0,0 +1,237 @@
+#!/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