Air724 DTU数据上报json到v1/gateway/telemetry

发布于:2025-02-17 ⋅ 阅读:(113) ⋅ 点赞:(0)

Air724 DTU数据上报json到v1/gateway/telemetry

任务模板:

function
    sys.wait(10000)
	local taskname="userTask"
	log.info(taskname,"start")
	local nid =1
	local netmsg ="UART_DATA_TO_NET"..nid
	while true do
        local t={}
        t.params = {} -- 定义 params 为数组
        params_temperature = "25" -- 温度
        params_humidity = "50" -- 湿度
        params_getClock = misc.getClock() -- 获取时间
        params_getImei = misc.getImei() --获取IMEI
        params_getIccid = sim.getIccid() --获取卡号
        params_getRssi = net.getRssi() -- 获取信号强度
        table.insert(t.params, {temperature = params_temperature, humidity = params_humidity, getClock = params_getClock, getImei = params_getImei, getIccid = params_getIccid, getRssi = params_getRssi}) -- 插入一个对象
        local str=nil
        str = json.encode(t)
        log.info("temp str=",str)

        pronet.PronetInsertSendChache(nid,str)
        sys.publish(netmsg)
		sys.wait(3000)
	end
end

如果你想让 params 这个 JSON key 使用 IMEI 号作为名称,可以这样做:

function
    sys.wait(10000)
	local taskname="userTask"
	log.info(taskname,"start")
	local nid =1
	local netmsg ="UART_DATA_TO_NET"..nid
	while true do
        local t={}
        local imei = misc.getImei() or "unknown_imei" -- 避免 nil 错误
        t[imei] = {} -- 定义 params 为数组
        params_temperature = "25" -- 温度
        params_humidity = "50" -- 湿度
        params_getClock = misc.getClock() -- 获取时间
        params_getImei = misc.getImei() --获取IMEI
        params_getIccid = sim.getIccid() --获取卡号
        params_getRssi = net.getRssi() -- 获取信号强度
        table.insert(t[imei], {temperature = params_temperature, humidity = params_humidity, getClock = params_getClock, getImei = params_getImei, getIccid = params_getIccid, getRssi = params_getRssi}) -- 插入一个对象
        local str=nil
        str = json.encode(t)
        log.info("temp str=",str)

        pronet.PronetInsertSendChache(nid,str)
        sys.publish(netmsg)
		sys.wait(3000)
	end
end

DTU设备数据上报:

function
    sys.wait(10000)
	local taskname="userTask"
	log.info(taskname,"start")
	local nid =1
	local netmsg ="UART_DATA_TO_NET"..nid
	while true do
        local t={}
        local imei = "1#DTU" or "unknown_imei" -- 避免 nil 错误
        t[imei] = {} -- 定义 params 为数组
        params_getClock = misc.getClock() -- 获取时间
        params_getImei = misc.getImei() --获取IMEI
        params_getIccid = sim.getIccid() --获取卡号
        params_getRssi = net.getRssi() -- 获取信号强度
        table.insert(t[imei], {getClock = params_getClock, getImei = params_getImei, getIccid = params_getIccid, getRssi = params_getRssi}) -- 插入一个对象
        local str=nil
        str = json.encode(t)
        log.info("temp str=",str)

        pronet.PronetInsertSendChache(nid,str)
        sys.publish(netmsg)
		sys.wait(5000)
	end
end

RS485轮询HEX,采集温湿度数据,通过数据模板转换json转换上报MQTT。

 function
    local din = ... -- 从 DTU 传入的数据
    local function to_hex_string(data)
        local hex_str = ""
        for i = 1, #data do
            hex_str = hex_str .. string.format("%02X ", string.byte(data, i))
        end
        return hex_str
    end
    log.info("77777777:", to_hex_string(din))

    -- 定义十六进制数据(从 DTU 传入的数据)
    local hex_data =to_hex_string(din)
    log.info("99999999:", hex_data)
    -- 将十六进制字符串转换为字节数组
    local function hex_to_bytes(hex)
        local bytes = {}
        for b in hex:gmatch("%S+") do
            table.insert(bytes, tonumber(b, 16))
        end
        return bytes
    end

    -- 解析 Modbus 数据
    local function parse_modbus_data(data)
        local result = {}
        result.slave_address = data[1]
        result.function_code = data[2]
        result.byte_count = data[3]

        -- 解析温度值(寄存器 0)
        local temp_raw = data[4] * 256 + data[5]  -- 替代位操作符
        result.temperature_raw = temp_raw
        result.temperature = temp_raw * 0.1

        -- 解析湿度值(寄存器 1)
        local humidity_raw = data[6] * 256 + data[7]  -- 替代位操作符
        result.humidity_raw = humidity_raw
        result.humidity = humidity_raw * 0.1

        -- 解析 CRC 校验码
        result.crc = string.format("%02X%02X", data[8], data[9])

        return result
    end

    -- 将表转换为 JSON 格式
    local function table_to_json(tbl)
        local json = "{"
        for k, v in pairs(tbl) do
            if type(v) == "number" then
                json = json .. string.format('"%s":%s,', k, v)
            else
                json = json .. string.format('"%s":"%s",', k, v)
            end
        end
        json = json:sub(1, -2) .. "}"  -- 去掉最后一个逗号
        return json
    end

    -- 主程序
    local bytes = hex_to_bytes(hex_data)
    local parsed_data = parse_modbus_data(bytes)

    -- 将解析后的数据包装为指定格式
    local json_output = '{"dh34":[' .. table_to_json(parsed_data) .. ']}'
    log.info("88888888:", json_output)
    -- 返回处理后的数据
    return json_output
end

读取DTU数据以及轮询485设备数据,上传mqtt:

function
	local taskname = "userTask"
	log.info(taskname, "start")
	sys.wait(30000)  -- 初始等待,确保设备启动完成

	local netid = 1
	local netmsg = "UART_DATA_TO_NET" .. netid
	local uid = 1
	local uartmsg = "UART" .. uid .. "_NEED_SEND"
	local rd = nil

	-- Modbus RTU 读取温湿度命令(地址 0x0000, 读取 2 个寄存器 = 4字节)
	local cmd = {
		{0x01, 0x04, 0x00, 0x00, 0x00, 0x02, 0x71, 0xCB},  -- 读取地址 1 的温湿度
		{0x02, 0x04, 0x00, 0x00, 0x00, 0x02, 0xA1, 0xF8}   -- 读取地址 2 的温湿度
	}

	local ncmd = nil
	local crcr = nil

	-- 先清空串口和网络缓存
	prouart.ProuartStopProReciveCache(1)
	pronet.PronetStopProNetRecive(1)

	while true do
        local imei = "DTU-" .. (misc.getImei() or "unknown_imei") -- 避免 nil 错误
		-- 构造 DTU JSON 发送
		local dtu = {
			[imei] = {{
                params_getClock = misc.getClock(), -- 获取时间
                params_getImei = misc.getImei(), -- 获取IMEI
                params_getIccid = sim.getIccid(), -- 获取卡号
                params_getRssi = net.getRssi() -- 获取信号强度
			}}
		}
		local dtu_restr = json.encode(dtu)
		log.info("dtu.json", dtu_restr)

		-- 发送 DTU 数据到网络
		if dtu_restr and 1 == pronet.PronetGetNetState(netid) then
			pronet.PronetInsertSendChache(netid, dtu_restr)
			sys.publish(netmsg)
		end

		local temp1, hum1, temp2, hum2 = 0, 0, 0, 0

		-- 轮询 Modbus 设备,读取数据
		for i = 1, #cmd do
			ncmd = usertool.ToolTableToHexStr(cmd[i])
			prouart.ProuartSetSendChace(uid, ncmd)
			sys.publish(uartmsg)  -- 触发发送
			sys.wait(1000)  -- 等待返回数据

			rd = prouart.ProuartGetReciveChaceAndDel(uid)
			if rd then
				log.info(taskname, "cmd num=", i, "rd data=", string.toHex(rd))
				rd = usertool.ToolHexStrToTable(rd)

				if rd then
					crcr = usertool.ToolCheckModbusCRC16(rd, #rd, 0)
					if crcr == 1 and #rd >= 7 then
						local temp_raw = rd[4] * 256 + rd[5]
						local hum_raw = rd[6] * 256 + rd[7]

						if i == 1 then
							temp1 = temp_raw / 10.0
							hum1 = hum_raw / 10.0
						elseif i == 2 then
							temp2 = temp_raw / 10.0
							hum2 = hum_raw / 10.0
						end
					else
						log.warn(taskname, "CRC校验失败或数据长度不足")
					end
				end
			end
		end

		-- 构造 温湿度 JSON 发送
		local sensor_data = {
			["温湿度传感器"] = {{
                t = "3",
			    datatype = "1",
			    msgid = "123",
				temp1 = temp1,
				hum1 = hum1,
				temp2 = temp2,
				hum2 = hum2
			}}
		}
		local sensor_restr = json.encode(sensor_data)
		log.info("taskname.json", sensor_restr)

		-- 发送温湿度数据到网络
		if sensor_restr and 1 == pronet.PronetGetNetState(netid) then
			pronet.PronetInsertSendChache(netid, sensor_restr)
			sys.publish(netmsg)
		end

		sys.wait(5000)  -- 等待 5 秒后继续轮询
	end
end