-- lpack=require("lua_pack") -- require("bit") -- cjson=require("cjson") ----------------------[MODBUS read data]-------------------------- local function read_multi_register(obj,id) return bpack("CC",0x01,0x33) end ----------------------[MODBUS write data]-------------------------- local function write_multi_register(obj,id,data) return bpack("CC",0x01,0x11) end local function response_distance(raw_data, len) obj={} local _,id,data= bunpack(raw_data,"CC") if data == 0x00 then obj.open = 0 elseif data == 0x11 then obj.open = 1 else obj.open = 2 end return obj end ----------------------[test control demo]-------------------------- local function response_test_demo(raw_data, len) local obj={} obj.error = 0 return obj end global_identifier_func_tab = { { identifier="fetchFeedback", create_bin_func=read_multi_register, create_bin_args={0X80,1}, parser_bin_func=response_distance }, { identifier="Control", create_bin_func=write_multi_register, create_bin_args={0X8A,1}, parser_bin_func=response_test_demo } } local function crc8(data) local crc=0x0; for k=1, #data do crc = bit.bxor(crc, string.byte(data,k)) end return tonumber(string.format("%u", bit.band(crc,0xFF) )) end function protocol_encode(json_str, len) local err_code=0 --取出入参-- local obj=cjson.decode(json_str) local id=obj.identifier local addr=tonumber(obj.term_addr,16) --编码-- -- print(json_str) if id == "null" then return 0, "", 0 end local raw_data=nil for i,v in pairs(global_identifier_func_tab) do if v.identifier == id then local call_func = v.create_bin_func local data = call_func(obj,v.create_bin_args[2]) local bin=nil raw_data = bpack("CC",v.create_bin_args[1],addr) for i = 1, #data do raw_data = raw_data .. bpack("C",data:byte(i)) end local bcc = crc8(raw_data) raw_data = raw_data .. bpack("C",bcc) local t_str='' for i=1, #raw_data do t_str=t_str .. (string.format("%02X", string.byte(string.sub(raw_data, i, i)))) end print(t_str,#t_str) return err_code, t_str, #t_str end end return -1, nil, 0 end function protocol_decode(input_str, len) local err_code=0 -- print(input_str) --取出入参-- local obj={} local input_obj=cjson.decode(input_str) local bin_str=input_obj.raw_data local id=input_obj.identifier --入参中的raw_data的二进制转换-- if not bin_str or #bin_str < 5 then print(string.format( "Input args failed,args:%s",input_str)) return nil end local t_str='' for i=1,#bin_str,2 do t_str=t_str .. string.char(tonumber(string.sub(bin_str, i, i+1),16)) end raw_data=t_str local crc = crc8(string.sub(raw_data,1,#raw_data - 1)) _,_,crc_pack = bunpack(raw_data,"IC") if (crc ~= crc_pack) then print(string.format( "Data crc check failed cal:%02X packet:%02X",crc,crc_pack)) return nil end _,head,addr = bunpack(raw_data,"CC") if addr ~= 0x01 then print(string.format( "Data addr check failed cal:%02X",addr)) return nil end for i,v in pairs(global_identifier_func_tab) do if v.identifier == id then local call_func = v.parser_bin_func local data,data_len = nil,0 data = string.sub(raw_data,3,4) local json_obj = call_func(data,#data)-- 调用不同的函数执行解析数据 json_obj.identifier=id -- 返回调用标识 json_obj.term_addr=string.format("%02X",addr) local json_str=cjson.encode(json_obj) print(err_code, json_str, #json_str) return err_code,json_str,#json_str end end return nil end -- raw_data = bpack("CCCC",0X8A,1,1,0x11) -- local bcc = crc8(raw_data) -- print(string.format("BCC %X",bcc)) -- raw_data = raw_data .. bpack("C",bcc) -- local t_str='' -- for i=1, #raw_data do -- t_str=t_str .. (string.format("%02X", string.byte(string.sub(raw_data, i, i)))) -- end -- print(t_str,#t_str) -- protocol_decode('{"raw_data":"8001011191","identifier":"fetchFeedback"}')