#!/usr/bin/lua

require "uci"
cur = uci.cursor()

lfs = require "lfs"
json = require "json"
socket = require "socket"

require "wm_util"

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 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  

web_id = get_devid(config_name)

parameters = init(config_name)

local delay = uci.get(config_name,"process","delay")

local working_dir = uci.get(config_name,"process","working_dir")
if working_dir then
  lfs.mkdir(working_dir)
end

if not delay then
  delay = 60
end

io.stdout:setvbuf('no')

while true do
  if pcall(function () values = get_parameters(parameters) end) then
    records = {}
    records[web_id] = {}
    for key,record in pairs(values) do
      records[web_id][key] = record
      records[web_id]["timestamp"] = os.date("%Y-%m-%dT%H:%M:%S")
    end
    for key,value in pairs(values) do
      value["device"] = key
      print(json.encode(value))
    end
  end  
  socket.sleep(delay)
end