local syslog=require("syslog") local math=require("math") local cjson=require("cjson") -------------------------[全局参数定义]------------------------- data_report_interv=60 --一次平均数 1小时,也是上报时间 default:3600 compare_interv=24 --一次比对计算 24小时 history_data=2*30 --存储 2 月历史记录 -------------------------[输入设备名称以及标识符]------------------------- device_a="210163000001" device_b="444222112" value_name_a="doValue" value_name_b="weiyi" -------------------------[输出标识符]------------------------- identifier="Event" event_value_name="level" -------------------------[事件参数]------------------------- warning_level_1=60 warning_level_2=70 warning_level_3=80 -------------------------[系统变量]------------------------ raw_data_cache_size=100 --缓存大小 fit_data_cache_size=10 --滤波器缓存大小 syslog.openlog("chenjiang syslog", syslog.LOG_PERROR + syslog.LOG_ODELAY, "LOG_USER") function write_cache_to_file(path,ojb) local file=io.open(path, 'w+') file:seek('set') file:write(cjson.encode(ojb)) file:flush() file:close() end function read_cache_from_file(path) local file=io.open(path, 'a+') local ojb={} file:seek('set') ojb = file:read() file:close() if(ojb == nil) then return nil end return cjson.decode(ojb) end function process_event(raw_data,avg_cache) local fit_data={} local sum=0.0 --复制到fit表,复制最近几条数据 for i=#raw_data.list,#raw_data.list-fit_data_cache_size,-1 do if raw_data.list[i] then table.insert( fit_data, raw_data.list[i]) end end local json_str=cjson.encode(fit_data) --排序去头去尾 table.sort( fit_data ) table.remove( fit_data,#fit_data) table.remove( fit_data,1) local json_str=cjson.encode(fit_data) print("fit_data",json_str, #json_str) for i=1,#fit_data,1 do sum = sum + fit_data[i] end local avg_value = sum/#fit_data local level=0 if avg_value >= warning_level_3 or avg_value <= 0-warning_level_3 then level =3 elseif avg_value >= warning_level_2 or avg_value <= 0-warning_level_2 then level =2 elseif avg_value >= warning_level_1 or avg_value <= 0-warning_level_1 then level =1 else end if (level ~= avg_cache.last_level ) then local new_data={} new_data['timestamp']=os.time() new_data['identifier']=identifier new_data[event_value_name]=level avg_cache.last_level = level; write_cache_to_file("/tmp/chenjiang_avg_24h.dat",avg_cache) local json_str=cjson.encode(new_data) syslog.syslog("LOG_WARNING", json_str .. #json_str) return 0,json_str,#json_str end return -1 end function process_data(raw_data) local curr_timestamp=os.time() local json_str=cjson.encode(raw_data) local cache = read_cache_from_file("/tmp/chenjiang_avg_24h.dat") if not cache then cache={} cache.list={} cache.timestamp_1h=0 cache.last_level=0 syslog.syslog("LOG_WARNING","table init") end err_code,out_str,out_len = process_event(raw_data,cache) --判断事件 if(err_code)==0 then return err_code,out_str,out_len end if curr_timestamp >= (cache.timestamp_1h + data_report_interv) then --数据平滑后上报 cache.timestamp_1h = curr_timestamp local sum=0.0 for i=1,#raw_data.list,1 do sum = sum + raw_data.list[i] end cache.avg_value = sum/#raw_data.list if #cache.list > compare_interv then table.remove( cache.list, 1 ) end table.insert(cache.list, cache.avg_value ) write_cache_to_file("/tmp/chenjiang_avg_24h.dat",cache) local json_str=cjson.encode(cache) print("avg_data_24h",json_str, #json_str) hist = read_cache_from_file("/app/chenjiang_history.dat") local date = os.date("*t", os.time()); if not hist then hist={} hist.list={} hist.timestamp=0 hist.date = os.date("*t", os.time()); hist.before_day_value=cache.list[#cache.list] hist.today_value=cache.list[#cache.list] syslog.syslog("LOG_WARNING","table init") end if date["data"] ~= hist.date["data"] and date["hour"] == 8 then -- 8 地方时区 hist.timestamp = curr_timestamp hist.date = os.date("*t", os.time()); hist.before_day_value = hist.today_value --DATA t-1 hist.today_value = cache.list[#cache.list] hist.value_diff = math.abs(hist.today_value - hist.before_day_value) if #hist.list > history_data then table.remove( hist.list, 1 ) end table.insert(hist.list, hist.value_diff ) local sum=0.0 for i=1,#hist.list,1 do sum = sum + hist.list[i] end hist.value_diff_add = sum write_cache_to_file("/app/chenjiang_history.dat",hist) end local new_data={} new_data['timestamp']=os.time() new_data['avg_value']=cache.avg_value new_data['avg_value_24']=hist.today_value new_data['diff_data_24']=hist.value_diff new_data['add_value_24_2M']=hist.value_diff_add local json_str=cjson.encode(new_data) syslog.syslog("LOG_WARNING", json_str .. #json_str) return 0,json_str,#json_str end return -1,nil,0 --中间计算结果不返回 end function udef_process(obj) local err_code=0 local cache = read_cache_from_file("/tmp/chenjiang_raw.dat") if not cache then cache={} cache.list={} end if #cache.list > raw_data_cache_size then table.remove( cache.list, 1 ) end table.insert(cache.list, obj.raw_diff ) write_cache_to_file("/tmp/chenjiang_raw.dat",cache) return process_data(cache) end function parser_input(obj) local source_a, source_b for i,v in pairs(obj["datas"]) do if(v["sn"] == device_a) then tag = v["tags"] if tag then source_a = tag[value_name_a] end elseif(v["sn"] == device_b) then tag = v["tags"] if tag then source_b = tag[value_name_b] end end end return source_a,source_b end function protocol_decode(input_str, len) --出参格式化-- local obj = cjson.decode(input_str) --获取输入变量-- local source_a, source_b = parser_input(obj) if source_a == nil or source_b == nil then print(source_a,source_b) syslog.syslog("LOG_WARNING","input args less than 2,one or more args missed") return -1,nil,0 end syslog.syslog("LOG_WARNING",string.format( "source data[%f,%f]",source_a,source_b)) local json_obj={} json_obj.raw_diff = source_a - source_b err_code,out_str,out_len=udef_process(json_obj) --用户自定义数据处理 -- status,err_code = pcall(udef_process, json_obj) -- if not status or not err_code then -- if not status then -- syslog.syslog("LOG_WARNING","err:FATAL") -- end -- return -3,nil,0 -- end -- syslog.syslog("LOG_WARNING", string.format( "return code:%d",err_code)) return err_code,out_str,out_len end -- protocol_decode('{"datas":[{"sn":"210163000001","time":1574933970,"state":0,"quality":0,"identifier":"post","tags":{"doValue":10}},{"sn":"444222112","time":1574933967,"state":0,"quality":0,"identifier":"post","tags":{"weiyi":100}}]}', 0) syslog.closelog()