# 在线离线接口

# 主题：
 /productid/deviceid/status/post

# 原始http推送接口

http://121.41.45.13:8025/receive

abcdefghijkmlnopqrstuvwxyz


# 新的http推送接口
http://121.36.111.27:8080/bridge/get



# 消息格式：json格式，具体字段如下：（其中status取值：4：离线，3：在线）：
{"status":3,"isShadow":1,"rssi":-51}
# onenet平台上下线信息
{msg={"dev_name":"1","at":1742873510747,"pid":"JYr2f72uSJ","type":2,"status":1}, signature=25BcZvEQ+kk10rfB9gLnnQ==, time=1742873510772, id=5614fc489df3433f9891d6d4c7c3e5e7, nonce=b1R7hjgp}
"status":1上线 0下线
# 物模型推送接口： 将数据推送至FASTBEE端
/productid/deviceid/property/post
# 消息格式：json格式，具体字段如下：
[{
    "id": "co2",
    "value": "1",
    "remark": ""
}]


# 规则引擎仅作于设备状态更新
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;



Long productId = 136  // 固定 productId
String sysTopic = ""  // 系统主题
String sysPayload = ""  // 系统数据格式
// 1. 获取原始内容
String payload = msgContext.getPayload()
msgContext.logger.info("原始数据：" + payload)

// 2. ✅ 只提取 msg 内容
try {
    // ✅ 使用 Groovy 兼容的正则写法，提取 msg 内的数据
    String msgData = (payload =~ /msg=\{(.+?)\}/)[0][1]
    msgContext.logger.info("提取后的 msg 数据：" + msgData)

    // ✅ 解析提取后的数据
    JSONObject msgObj = JSONUtil.parseObj("{" + msgData + "}")

    // ✅ 提取 dev_name 作为 serialNumber
    String serialNumber = msgObj.getStr("dev_name", "unknown")

    // ✅ 解析 status 并进行转换
    Integer status = msgObj.getInt("status", -1)
    Integer convertedStatus = (status == 0) ? 4 : (status == 1) ? 3 : status

    // ✅ 构造转换后的 sysPayload
    JSONObject newObj = new JSONObject()
    newObj.put("status", convertedStatus)
    newObj.put("isShadow", 1)
    newObj.put("rssi", msgObj.getInt("rssi", -51))  // 默认 rssi = -51

    sysPayload = newObj.toString()
    sysTopic = "/" + productId + "/" + serialNumber + "/status/post"
} catch (Exception e) {
    msgContext.logger.error("数据解析失败：", e)
    sysPayload = "{}"
}

// 3. 打印调试信息
msgContext.logger.info("新主题：" + sysTopic)
msgContext.logger.info("新内容：" + sysPayload)
msgContext.logger.info("NewTopic 长度: " + sysTopic.length());

// 4. 设置新的数据
msgContext.setTopic(sysTopic)
msgContext.setPayload(sysPayload)
msgContext.logger.info("输出：" + msgContext.getTopic());
// 执行Action动作参数(脚本由系统自动生成)
msgContext.setData("mqttBridgeID", 8);


# 定制设备状态
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;




 
String sysTopic = "/special/device"  // 固定主题
String sysPayload = ""  // 系统数据格式
 
// 1. 获取原始内容 
String payload = msgContext.getPayload() 
msgContext.logger.info(" 原始数据：" + payload)
 
// 2. ✅ 只提取 msg 内容 
try {
    // ✅ 使用 Groovy 兼容的正则写法，提取 msg 内的数据
    String msgData = (payload =~ /msg=\{(.+?)\}/)[0][1]
    msgContext.logger.info(" 提取后的 msg 数据：" + msgData)
 
    // ✅ 解析提取后的数据
    JSONObject msgObj = JSONUtil.parseObj("{"  + msgData + "}")
 
    // ✅ 提取 dev_name 作为 serialNumber 
    String serialNumber = msgObj.getStr("dev_name",  "unknown")
 
    // ✅ 解析 status 并进行转换 (0=上线,1=下线)
    Integer status = msgObj.getInt("status",  -1)
    Integer convertedStatus = (status == 0) ? 0 : (status == 1) ? 1 : status
 
    // ✅ 构造转换后的 JSON payload 
    JSONObject newObj = new JSONObject()
    newObj.put("serialNumber",  serialNumber)
    newObj.put("status",  convertedStatus)
 
    sysPayload = newObj.toString() 
    
} catch (Exception e) {
    msgContext.logger.error(" 数据解析失败：", e)
    // 错误时返回默认 JSON
    JSONObject errorObj = new JSONObject()
    errorObj.put("serialNumber",  "error")
    errorObj.put("status",  -1)
    sysPayload = errorObj.toString() 
}
 
// 3. 打印调试信息
msgContext.logger.info(" 新主题：" + sysTopic)
msgContext.logger.info(" 新内容：" + sysPayload)
 
// 4. 设置新的数据 
msgContext.setTopic(sysTopic) 
msgContext.setPayload(sysPayload) 
msgContext.logger.info(" 输出：" + msgContext.getTopic()); 
// 执行Action动作参数(脚本由系统自动生成)
msgContext.setData("mqttBridgeID",  8);


# ONENET 物模型




# 物模型
{
	msg = {
		"notifyType": "property",
		"productId": "ebm1xlK9QJ",
		"messageType": "notify",
		"data": {
			"id": "1",
			"params": {
				"time": {
					"time": 1747031766274,
					"value": 3
				},
				"press": {
					"time": 1747031766273,
					"value": 4
				},
				"remove": {
					"time": 1747031766273,
					"value": 2
				}
			}
		},
		"deviceName": "D1231XS9KI9X"
	},
	signature = YoYfkfdyNiYfPmJPLzz5wg == ,
	time = 1747031766259,
	id = e20abecf848c408fb381bc03a23ebfd7,
	nonce = xQLnbAzQ
}





[
  {
    "id": "params",
    "remark": "",
    "value": "3"
  },
  {
    "id": "press",
    "remark": "",
    "value": "3"
  },
  {
    "id": "remove",
    "remark": "",
    "value": "3"
  }
]


[
  {
    "id": "press",
    "remark": "",
    "value": "3"
  }
]



{
	"id": "123",
	"version": "1.0",
	"params": {
		"time": {
			"value": 2,
			"time": 1706673129818 
		},
		"press": {
			"value": 3,
			"time": 1706673129818 
		},
		"remove": {
		  "value": 2
		  "time": 1747031766273
		}
	}
}




{
    "id": "1234567890123",
    "version": "1.0",
    "params": {
        "press": { "value": 4 },
        "remove": { "value": 2 },
        "time": { "value": 3 }
    }
}
# mqttfx





# 物模型规则脚本
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;



 
Long productId = 136 
String sysTopic = ""
String sysPayload = "[]"
 
try {
    // 1. 获取原始payload 
    String payload = msgContext.getPayload().trim() 
    
    // 2. 安全提取msg JSON（兼容各种格式）
    int msgStart = payload.indexOf('"msg":')  + 6 
    int jsonStart = payload.indexOf('{',  msgStart)
    int jsonEnd = payload.lastIndexOf('}') 
    
    String msgJsonStr = payload.substring(jsonStart,  jsonEnd + 1)
    msgContext.logger.info(" 提取的msg JSON: " + msgJsonStr)
    
    // 3. 解析JSON 
    JSONObject msgObj = JSONUtil.parseObj(msgJsonStr) 
    
    // 4. 获取设备名（确保字段名正确）
    String serialNumber = msgObj.getStr("deviceName",  "unknown")
    
    // 5. 处理物模型数据（完全兼容的遍历方式）
    JSONObject data = msgObj.getJSONObject("data") 
    JSONObject params = data.getJSONObject("params") 
    
    JSONArray propertyArray = new JSONArray()
    // 使用兼容的遍历方式替代each闭包 
    Set<String> keys = params.keySet() 
    keys.each  { key ->
        JSONObject valueObj = params.getJSONObject(key) 
        if (valueObj != null) {
            JSONObject prop = new JSONObject()
            prop.set("id",  key)
            prop.set("remark",  "")
            prop.set("value",  valueObj.getStr("value")) 
            propertyArray.add(prop) 
        }
    }
    
    // 6. 设置输出 
    sysPayload = propertyArray.toString() 
    sysTopic = "/${productId}/${serialNumber}/property/post"
    
} catch (Exception e) {
    msgContext.logger.error(" 处理异常: " + e.getMessage()) 
} finally {
    // 确保有效输出 
    msgContext.setTopic(sysTopic  ?: "/${productId}/unknown/property/post")
    msgContext.setPayload(sysPayload  ?: "[]")
    msgContext.setData("mqttBridgeID",  8)
    
    // 验证日志 
    msgContext.logger.info("===  最终结果验证 ===")
    msgContext.logger.info(" 设备名: " + (sysTopic.split("/")[2]  ?: "null"))
    msgContext.logger.info("Payload 内容: " + sysPayload)
}





# 2合1脚本
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;



 
// 公共配置
Long productId = 136 
String sysTopic = ""
String sysPayload = ""
 
try {
    // 1. 获取原始payload
    String payload = msgContext.getPayload().trim() 
    msgContext.logger.info(" 原始数据：" + payload)
 
    // 2. 提取msg内容
    String msgContent = payload 
    if (payload.startsWith("{"))  {
        // 尝试直接解析为JSON
        try {
            JSONObject payloadObj = JSONUtil.parseObj(payload) 
            if (payloadObj.containsKey("msg"))  {
                msgContent = payloadObj.getStr("msg") 
            }
        } catch (Exception e) {
            // 可能是msg={...}格式 
            if (payload.contains("msg={"))  {
                int start = payload.indexOf("msg={")  + 4
                int end = payload.lastIndexOf("}")  + 1
                msgContent = payload.substring(start,  end)
            }
        }
    } else if (payload.contains("msg={"))  {
        // 处理msg={"key":"value"}格式
        int start = payload.indexOf("msg={")  + 4
        int end = payload.lastIndexOf("}")  + 1
        msgContent = payload.substring(start,  end)
    } else if (payload.contains("msg="))  {
        // 处理msg=JSON格式（不带大括号）
        int start = payload.indexOf("msg=")  + 4 
        msgContent = payload.substring(start) 
    }
 
    // 3. 解析msg内容 
    JSONObject parsedObj = JSONUtil.parseObj(msgContent) 
    msgContext.logger.info(" 解析后的JSON对象：" + parsedObj)
 
    // 4. 判断数据类型并处理 
    if (parsedObj.containsKey("notifyType")  && "property".equals(parsedObj.getStr("notifyType")))  {
        // 物模型数据处理 ========================================= 
        msgContext.logger.info(" 检测到物模型数据格式")
        
        // 获取设备名 
        String serialNumber = parsedObj.getStr("deviceName",  "unknown")
        
        // 处理物模型数据
        JSONObject data = parsedObj.getJSONObject("data") 
        JSONObject params = data.getJSONObject("params") 
        
        JSONArray propertyArray = new JSONArray()
        params.keySet().each  { key ->
            JSONObject valueObj = params.getJSONObject(key) 
            if (valueObj != null) {
                JSONObject prop = new JSONObject()
                prop.set("id",  key)
                prop.set("remark",  "")
                prop.set("value",  valueObj.getStr("value")) 
                propertyArray.add(prop) 
            }
        }
        
        // 设置物模型输出 
        sysPayload = propertyArray.toString() 
        sysTopic = "/${productId}/${serialNumber}/property/post"
        
    } else if (parsedObj.containsKey("dev_name")  || parsedObj.containsKey("status"))  {
        // 设备状态处理 =========================================== 
        msgContext.logger.info(" 检测到设备状态数据格式")
        
        // 提取设备信息 
        String serialNumber = parsedObj.getStr("dev_name",  "unknown")
        Integer status = parsedObj.getInt("status",  -1)
        Integer convertedStatus = (status == 0) ? 0 : (status == 1) ? 1 : status
        
        // 构造状态JSON 
        JSONObject statusObj = new JSONObject()
        statusObj.put("serialNumber",  serialNumber)
        statusObj.put("status",  convertedStatus)
        
        // 设置状态输出
        sysPayload = statusObj.toString() 
        sysTopic = "/special/device"
        
    } else {
        throw new Exception("无法识别的数据格式")
    }
 
} catch (Exception e) {
    msgContext.logger.error(" 处理异常: " + e.getMessage()) 
    
    // 创建错误响应 
    JSONObject errorObj = new JSONObject()
    errorObj.put("error",  e.getMessage()) 
    errorObj.put("originalData",  msgContext.getPayload()) 
    
    sysPayload = errorObj.toString() 
    sysTopic = "/error/unknown"
} finally {
    // 确保有效输出
    msgContext.setTopic(sysTopic) 
    msgContext.setPayload(sysPayload) 
    msgContext.setData("mqttBridgeID",  8)
    
    // 记录最终结果
    msgContext.logger.info("===  处理结果 ===")
    msgContext.logger.info(" 主题: " + sysTopic)
    msgContext.logger.info("Payload:  " + sysPayload)
}







# 压力传感器的id

{msg={at=1747123666940, imei=868256050123875, type=1, ds_id=3323_0_5700, value=1538.0, dev_id=2415928615}, msg_signature=mpYC8EvR7lB14AzqteyjhA==, nonce=nPyzGpMV}

{"msg":{"at":1747142877978,"imei":"868256050017168","type":1,"ds_id":"3323_0_5700","value":-1.0,"dev_id":2442383559},"msg_signature":"MHjUOUPj0GGfpKpyBZ6BzQ==","nonce":"TdTKIcVq"}

# 上下线消息
{msg={at=1747126859912, login_type=10, imei=868256050123875, type=2, dev_id=2442383559, status=1}, msg_signature=Z/cRScM2TLOUeaptE1hllg==, nonce=BSy0fFIY}

{"msg":{"at":1747126859912,"login_type":10,"imei":"868256050123875","type":2,"dev_id":2442383559,"status":1},"msg_signature":"Z/cRScM2TLOUeaptE1hllg==","nonce":"BSy0fFIY"}
# 移动消息

{"msg":{"at":1747275785411,"imei":"868256050099802","type":1,"ds_id":"30100_0_6500","value":"01","dev_id":2442561775},"msg_signature":"2dRxxL4t9HDW1EmRwIGhfQ==","nonce":"hM31WR88"}




脚本



import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;





// 默认 topic
String sysTopic = "/special/device";
String sysPayload = "";

// 获取原始 payload
String payload = msgContext.getPayload();
msgContext.logger.info("原始 payload：" + payload);

try {
    // 提取 msg 内容
    def matcher = (payload =~ /"msg":\{(.+?)\}/);
    if (!matcher.find()) {
        throw new Exception("未找到 msg 字段");
    }

    String msgData = matcher[0][1];
    msgContext.logger.info("提取出的 msg 内容：" + msgData);

    // 将 msgData 转为 JSON 字符串（key=value → "key":"value"）
    String jsonLike = msgData.replaceAll(/(\w+)=([^,}]+)/) { all, k, v ->
        "\"${k}\":\"${v}\""
    };
    jsonLike = "{${jsonLike}}";
    msgContext.logger.info("转换为 JSON 格式字符串：" + jsonLike);

    JSONObject msgObj = JSONUtil.parseObj(jsonLike);

    // 判断是否是物模型数据（包含 ds_id 字段）
    if (msgObj.containsKey("ds_id")) {
        String dsid = msgObj.getStr("ds_id");
        if ("3323_0_5700" != dsid) {
            msgContext.logger.info("不处理的 ds_id：" + dsid);
            return; // 直接跳过不处理
        }

        // ✅ 物模型处理
        String imei = msgObj.getStr("imei", "unknown");
        String valueStr = msgObj.getStr("value", "0");
        Double valueNum = NumberUtil.parseNumber(msgObj.getStr("value", "0")).doubleValue();

        JSONArray array = new JSONArray();
        JSONObject data = new JSONObject();
        data.put("id", "press");
        data.put("remark", "");
        data.put("value", valueNum);
        array.add(data);

        sysPayload = array.toString();
        sysTopic = "/138/${imei}/property/post";

    } else {
        // ✅ 在线离线数据处理
        String imei = msgObj.getStr("imei", "unknown");
        Integer status = NumberUtil.parseInt(msgObj.getStr("status", "-1"));
        Integer loginType = NumberUtil.parseInt(msgObj.getStr("login_type", "-1"));
        Long timestamp = msgObj.getLong("at", 0);

        JSONObject newPayload = new JSONObject();
        newPayload.put("serialNumber", imei);
        newPayload.put("status", status);
        newPayload.put("loginType", loginType);
        newPayload.put("timestamp", timestamp);

        sysPayload = newPayload.toString();
        sysTopic = "/special/device";
    }

} catch (Exception e) {
    msgContext.logger.error("解析出错：", e);
    JSONObject errorPayload = new JSONObject();
    errorPayload.put("serialNumber", "error");
    errorPayload.put("status", -1);
    sysPayload = errorPayload.toString();
    sysTopic = "/special/device";
}

// 设置 topic 和 payload
msgContext.setTopic(sysTopic);
msgContext.setPayload(sysPayload);

// 打印调试信息
msgContext.logger.info("新主题：" + sysTopic);
msgContext.logger.info("新内容：" + sysPayload);
msgContext.logger.info("输出：" + msgContext.getTopic());

// 可选设置
// 执行Action动作参数(脚本由系统自动生成)
msgContext.setData("mqttBridgeID", 7);
// 执行Action动作参数(脚本由系统自动生成)







accesskey 
INMu6CDgMnaKH+wptmLtkhIxlPmVrjOTgfSyITqsC9A=



用户

dpx0z9T75vMN4ZbdreEEHdHLPDxm2S7gFnQqsIk2Sj+rYUbfSNIFCCSCYdsZFe9q




+q9aB+VvIIEGG2D8/psyhaYBn42AzV/ormU9bUPicNhHGz9SZPtNjjlvlnFXX2YvCrZSeq38VaxYw+Q3QyBMeg==

主用户的accesskey



token 
version=2022-05-01&res=userid%2F275606&et=1907391331&method=sha1&sign=TxfzLFdfzIPwCSw6e1P9tYh1udQ%3D