From: Roman Bazalevsky Date: Tue, 31 Dec 2019 07:43:03 +0000 (+0300) Subject: Поддержка подключения устройств по последовательному интерфейсу. X-Git-Url: https://git.rvb.name/weathermon.git/commitdiff_plain/5f23c8a7c56799750221a9c2d8e904e154f8c515?ds=inline Поддержка подключения устройств по последовательному интерфейсу. Поддержка датчика углекислого газа MHZ-19. --- diff --git a/bin/weathermon-iio b/bin/weathermon-iio index f6e979f..9298f6f 100755 --- a/bin/weathermon-iio +++ b/bin/weathermon-iio @@ -9,6 +9,8 @@ socket = require "socket" require "wm_util" +io.stdout:setvbuf('no') + function get_device_list(config_name) local devices @@ -61,69 +63,134 @@ function find_device(name,subsystem) end -function init_device(device,parameters,i2c_bus) +function get_parameter(record) + return tonumber(get_file_content(record["path"])) * record["scale"] + record["correction"] +end + +function string.fromhex(str) + return (str:gsub('..', function (cc) + return string.char(tonumber(cc, 16)) + end)) +end + +function string.tohex(str) + return (str:gsub('.', function (c) + return string.format('%02X', string.byte(c)) + end)) +end + +function get_mhz(record) + local p = record["rs232"] + p:write(string.fromhex("ff0186000000000079")) + local e, s = p:read(9,1000) + return s:byte(3)*256+s:byte(4) +end + +function init_serial_device(device,subsystem,parameters) + + rs232 = require("luars232") + + pcall(function () + + local e, port = rs232.open(device["port"]) + + if subsystem == "mhz" then + + assert(port:set_baud_rate(rs232.RS232_BAUD_9600) == rs232.RS232_ERR_NOERROR) + assert(port:set_data_bits(rs232.RS232_DATA_8) == rs232.RS232_ERR_NOERROR) + assert(port:set_parity(rs232.RS232_PARITY_NONE) == rs232.RS232_ERR_NOERROR) + assert(port:set_stop_bits(rs232.RS232_STOP_1) == rs232.RS232_ERR_NOERROR) + assert(port:set_flow_control(rs232.RS232_FLOW_OFF) == rs232.RS232_ERR_NOERROR) + + getparameter = {} + + getparameter["rs232"] = port + getparameter["function"] = get_mhz + getparameter["name"] = "CO2_PPM" + getparameter["sensor"] = "MHZ19" + parameters[#parameters+1] = getparameter + + end + + end) + +end + +function init_i2c_device(device,subsystem,parameters) if not i2c_bus then i2c_bus = 0 end - if device["module"] then - os.execute("modprobe "..device["module"]) - end + 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) - if device["type"] then + device_path=find_device(device["name"],subsystem) - devtype = split(device["type"],":") - bus = devtype[1] - subsystem = devtype[2] - - if (bus == "i2c") and device["address"] and device["name"] then + 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("/sys/class/i2c-dev/i2c-"..i2c_bus.."/device/new_device","w") + local f = io.open(setpath,"w") io.output(f) - io.write(device["name"].." "..device["address"]) + io.write(setparam[2]) io.close(f) end) 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) + 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) + getparameter["function"] = get_parameter + parameters[#parameters+1] = getparameter + end + + end + +end + +function init_device(device,parameters) + + 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 device_path and device["parameter"] then + if (bus == "i2c") then + + init_i2c_device(device,subsystem,parameters) - 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) + elseif (bus == "serial") then - parameters[#parameters+1] = getparameter - - end + init_serial_device(device,subsystem,parameters) end @@ -144,7 +211,7 @@ function init(config_name) device = get_device(config_name,devname) if device then - init_device(device,parameters,i2c_bus) + init_device(device,parameters) end end @@ -153,18 +220,18 @@ function init(config_name) 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) + pcall(function () + results[record["sensor"]][record["name"]] = record["function"](record) + end) end + return results end @@ -188,10 +255,8 @@ if not delay then delay = 60 end -io.stdout:setvbuf('no') - while true do - if pcall(function () values = get_parameters(parameters) end) then + values = get_parameters(parameters) records = {} records[web_id] = {} for key,record in pairs(values) do @@ -202,7 +267,5 @@ while true do value["device"] = key print(json.encode(value)) end - end socket.sleep(delay) end - \ No newline at end of file