Skip to content

[BIN]-data-10103 对接文档

传感器简介

Source file does not provide it

项目
项目名称_bin__data_10103
厂商Source file does not provide it
型号[BIN]-data-10103
业务代码Not applicable
对接模式Source file does not provide it
协议Source file does not provide it

模型清单

可使用下列名称或 ID 在 ThinkLink 中搜索对应模型。

模型类型名称id_name平台模型 ID
RPC[BIN]-参数配置-10103mt_set_trash_para_1010362184372278661125
Thing Model[BIN]-data-10103mt_bin_data_1010362183093347291141
Thing Model[MT-10103-TRANSH资产] 区域聚合mt_bin_data_asset_10103119677174411063304
Parameter Thing Model[BIN]-para-10103mt_transh_para_1010362183707154321413

产品特点与适用范围

本项目面向“Source file does not provide it”场景。能力边界、字段和可部署模型均以当前 descriptor、requirements 与模型源文件为准。

部署与采集信息

| DTU | Not applicable | | 供电 | Source file does not provide it | | LoRaWAN Class | Source file does not provide it | | 接口 | Source file does not provide it | | 波特率 | Not applicable |

遥测与寄存器定义

源文件未提供独立遥测字段表;请以模型清单中的当前物模型为准。

参数定义

无项目专用参数定义。

Requirements 证据

以下关键事实由 requirements 源文件提取;原始行号用于复核。

类别来源事实来源
部署- Power: Source file does not provide itrequirement/requirements.md:17
协议/数据- Protocol: Source file does not provide itrequirement/requirements.md:19
协议/数据- Interface: Source file does not provide itrequirement/requirements.md:20
协议/数据- Baud rate: Not applicablerequirement/requirements.md:21
部署Validate model IDs, identifiers, payload fields, RPC behavior, triggers, and templates against a real device or platform test asset before production deployment.requirement/requirements.md:75
部署- Power: source file does not provide itrequirement/requirements.md:83
协议/数据- Protocol: source file does not provide itrequirement/requirements.md:85
协议/数据- Interface: source file does not provide itrequirement/requirements.md:86
部署Every item above must be checked during deployment. No missing value is promoted to a confirmed fact.requirement/requirements.md:88

物模型与 RPC 代码

RPC: [BIN]-参数配置-10103

id_name: mt_set_trash_para_10103 · ID: 62184372278661125

javascript
import {RPCHelper, Utils} from '#tklHelper';
import {Buffer} from "buffer";

function rpc_script({ device, params, alarms, logger, org_params }) {
let classMode = (device && device.shared_attrs && device.shared_attrs.class_mode) || "ClassA";
    let sleepMs = classMode === "ClassA" ? 500 : 5000;
    let paraDef = {
        app_70:{
            name: "上行周期", fieldName: "periodDataUP", unit:"秒", dataType: "uint32le", coefficient: 1, decimal:0,
            optionList: {}
        },
        app_74:{
            name: "查询周期", fieldName: "periodDataQuery", unit:"秒", dataType: "uint32le", coefficient: 1, decimal:0,
            optionList: {}
        },
        app_110:{
            name: "重量阈值", fieldName: "covWeight", unit:"kg", dataType: "uint32be", coefficient: 1, decimal:0,
            optionList: {}
        },
        app_114:{
            name: "距离阈值", fieldName: "covDepth", unit:"mm", dataType: "uint16be", coefficient: 1, decimal:0,
            optionList: {}
        }
    }
    let frames=RPCHelper.buildFrame({
        paraDef:paraDef,
        params:params});
    let redoBuffer=RPCHelper.redo()
    let dnBuffer=Buffer.alloc(frames.writeBuffer.length+frames.readBuffer.length+redoBuffer.length);
    frames.writeBuffer.copy(dnBuffer,0)
    frames.readBuffer.copy(dnBuffer,frames.writeBuffer.length)
    redoBuffer.copy(dnBuffer,frames.writeBuffer.length+frames.readBuffer.length);
    console.log(dnBuffer.toString("hex"))
    let msg=RPCHelper.makeMSG({
        msgType:Utils.msgType.paras,
        device:device,
        dnBuffer:dnBuffer,
        sleepTime:sleepMs,
    })
    return [
        msg
    ]
}
rpc_script({
    device: { server_attrs: {}, shared_attrs: {} },
    params: {},
    alarms: [],
    logger: console,
    org_params: {}
})

Thing Model: [BIN]-data-10103

id_name: mt_bin_data_10103 · ID: 62183093347291141

javascript
import {PayloadParser, RPCHelper} from '#tklHelper';
import {Buffer} from "buffer";

function payload_parser(device, msg, thingModelId, noticeAttrs, org_params) {
let frameInfo={
        port:22, dataLen:16,
        tagList:[{   index:0, tag:0x83}, {   index:1, tag:0x23}]
    }
    let appInfo = [
        {
            name: "重量值", field_name: "weight", unit:"kg", index: 6, type: "int32be",
            coefficient: "precision", decimal:2,
            options: {},
            remark: "32位有符号整数,表示重量值(不含小数点)。需根据精度字段确定小数点位置。如精度为2(0.00),则1532表示15.32"
        }, {
            name: "精度",field_name: "precision", unit:"",
            index: 10, coefficient: 1, type: "uint16be",
            options: {0: 1, 1: 0.1, 2: 0.01, 3: 0.001},
            remark: "小数点精度设置,决定重量值的小数位数"
        }, {
            name: "状态",field_name: "weightStatus1",unit:"",
            index: 13, coefficient: 1, type: "bitBE0-0",
            options: {
                0:"称重不稳定" ,
                1:"称重稳定"
                //"bit0": "0:称重不稳定, 1:称重稳定",
                //"bit1": "0:非零点, 1:零点",
                //"bit2": "0:没有超重, 1:超重",
                //"bit3": "0:无按键, 1:有按键触发",
                //"bit4": "0:开机有零点, 1:开机无零点",
                //"bit5": "0:称重无效, 1:称重有效",
            },
            remark: "模块状态寄存器,bit0-bit5有特定含义,bit6-15保留"
        },
        {
            name: "状态",field_name: "weightStatus2",unit:"",
            index: 13, coefficient: 1, type: "bitBE5-5",
            options: {
                0:"称重无效",
                1:"称重有效"
            },
            remark: "模块状态寄存器,bit0-bit5有特定含义,bit6-15保留"
        },
        {
            name: "深度", field_name: "depth", unit:"mm",
            index: 14, type: "uint16be",
            options: {},
            remark: "垃圾距离垃圾盖的距离"
        }
    ]
  //  let payload = Buffer.from(msg?.userdata?.payload, "base64");
  //  let port = msg?.userdata?.port || null;
    let payParser=new PayloadParser({
        device:device,
        msg:msg,
        frameInfo:frameInfo,
        appInfo:appInfo,
    })
    let tdata= payParser.telemetry();
    if (tdata==undefined){ return null}
    if (tdata.precision!==undefined){
        if (tdata.precision===0xFFFF) {tdata.precision=0; tdata.weight=0}
    }
    let result = {
        telemetry_data: tdata,
        server_attrs: null,
        shared_attrs: {class_mode: msg?.userdata?.class},
    };
    // ── rpcHook (设备对接通用规则) ──
    if (typeof RPCHelper.buildRpcHookAction === "function") {
      const __a = RPCHelper.buildRpcHookAction({ device, msg, thingModelId, idName: "mt_bin_data_10103", name: "[BIN]-data-10103", parsed: { telemetry_data: result.telemetry_data, server_attrs: result.server_attrs, shared_attrs: result.shared_attrs } });
      if (__a) { result.actions = result.actions || []; result.actions.push(__a); }
    }
    return result;
}
console.log(payload_parser(
    { telemetry_data: {} },
    { userdata: { port: 11, payload: "" } },
    "1",
    { telemetry_data: true },
    {}
))

Thing Model: [MT-10103-TRANSH资产] 区域聚合

id_name: mt_bin_data_asset_10103 · ID: 119677174411063304

javascript
import {PayloadParser, RPCHelper} from '#tklHelper';

// 资产(VIRTUAL)聚合物模型 — 通用 agg_spec 驱动聚合器,见 docs/references/workflow/asset-aggregation-model.md
// device=资产, msg=源设备快照, thingModelId=本物模型ID, noticeAttrs=变更标记。
// 聚合规格在资产 server_attrs.agg_spec:zone_depth_avg=空间均值(depth);zone_weight_sum=时点累加(weight);online_count=在线数(—)
function payload_parser(device, msg, thingModelId, noticeAttrs) {
    if (!noticeAttrs || !noticeAttrs.telemetry_data) {
        return { telemetry_data: null, server_attrs: null, shared_attrs: null };
    }
    const sa      = device?.server_attrs || {};
    const spec    = sa.agg_spec || {};
    const members = { ...(sa.members || {}) };
    const staleMs = sa.stale_ms != null ? sa.stale_ms : 600000;
    const now     = (typeof Date !== "undefined" && Date.now) ? Date.now() : null;

    // 合并源设备各物模型的最新快照为一个扁平对象
    const srcTd = {};
    const all = msg?.telemetry_data || {};
    for (const k in all) { Object.assign(srcTd, all[k]); }

    // 收集 spec 引用到的全部源字段,把本帧带到的值并进该成员快照
    const want = {};
    for (const out in spec) { if (spec[out].src) want[spec[out].src] = true; }
    const got = {}; let touched = false;
    for (const f in want) { if (srcTd[f] !== undefined && srcTd[f] !== null) { got[f] = srcTd[f]; touched = true; } }
    if (touched && msg && msg.eui) {
        const prev = (members[msg.eui] && members[msg.eui].v) || {};
        const seq  = (members[msg.eui] && members[msg.eui].ts) || 0;
        members[msg.eui] = { v: Object.assign({}, prev, got), ts: now != null ? now : seq + 1 };
    }

    const euis = Object.keys(members);
    const fresh = euis.filter(function (e) {
        if (now == null || staleMs <= 0) return true;
        const ts = members[e].ts;
        return ts != null && ts <= now && (now - ts) <= staleMs;
    });
    const num = function (x) { return (x != null && !isNaN(x)) ? Number(x) : null; };

    const out = {};
    for (const field in spec) {
        const op = spec[field].op, src = spec[field].src;
        if (op === "count_online") { out[field] = fresh.length; continue; }
        const pool = (op === "sum_cumul") ? euis : fresh;
        const vals = pool.map(function (e) { return num(members[e].v && members[e].v[src]); }).filter(function (x) { return x != null; });
        if (op === "avg")        out[field] = vals.length ? Number((vals.reduce(function (a, b) { return a + b; }, 0) / vals.length).toFixed(2)) : null;
        else if (op === "sum_snap" || op === "sum_cumul") out[field] = vals.length ? Number(vals.reduce(function (a, b) { return a + b; }, 0).toFixed(3)) : null;
        else if (op === "max")   out[field] = vals.length ? Math.max.apply(null, vals) : null;
        else if (op === "min")   out[field] = vals.length ? Math.min.apply(null, vals) : null;
        else if (op === "or")    out[field] = pool.some(function (e) { const x = members[e].v && members[e].v[src]; return x != null && x != 0; }) ? 1 : 0;
        else if (op === "count_on") out[field] = pool.filter(function (e) { const x = members[e].v && members[e].v[src]; return x != null && x != 0; }).length;
        else out[field] = null;
    }
    let result = { telemetry_data: out, server_attrs: { members: members }, shared_attrs: null };
    // ── rpcHook (设备对接通用规则) ──
    if (typeof RPCHelper.buildRpcHookAction === "function") {
      const __a = RPCHelper.buildRpcHookAction({ device, msg, thingModelId, idName: "mt_bin_data_asset_10103", name: "[MT-10103-TRANSH资产] 区域聚合", parsed: { telemetry_data: result.telemetry_data, server_attrs: result.server_attrs, shared_attrs: result.shared_attrs } });
      if (__a) { result.actions = result.actions || []; result.actions.push(__a); }
    }
    return result;
}

// --- local debug ---(两台成员先后上报;平台会把返回的 members 持久化回 device,这里手动模拟)
const agg_spec = {
  "zone_depth_avg": {
    "op": "avg",
    "src": "depth"
  },
  "zone_weight_sum": {
    "op": "sum_snap",
    "src": "weight"
  },
  "online_count": {
    "op": "count_online",
    "src": ""
  }
};
const device = { name: "MT-10103-TRANSH资产-1", server_attrs: { agg_spec, stale_ms: 1800000, members: {} } };
const r1 = payload_parser(device, { eui: "MEMBER_A", telemetry_data: { m1: {"depth":1,"weight":1} } }, "tmid", { telemetry_data: true });
device.server_attrs.members = r1.server_attrs.members;            // 平台持久化
console.log("成员A上报后:", JSON.stringify(r1.telemetry_data));
const r2 = payload_parser(device, { eui: "MEMBER_B", telemetry_data: { m1: {"depth":2,"weight":2} } }, "tmid", { telemetry_data: true });
device.server_attrs.members = r2.server_attrs.members;
console.log("成员B上报后(2台聚合):", JSON.stringify(r2.telemetry_data));
void PayloadParser;

Parameter Thing Model: [BIN]-para-10103

id_name: mt_transh_para_10103 · ID: 62183707154321413

javascript
import {PayloadParser, RPCHelper} from '#tklHelper';

function payload_parser(device, msg, thingModelId, noticeAttrs, org_params) {
let paraInfo =  {
        app_70:{name: "上行周期", fieldName: "periodDataUP", unit:"秒", dataType: "uint32le", coefficient: 1, decimal:0},
        app_74:{name: "查询周期", fieldName: "periodDataQuery", unit:"秒", dataType: "uint32le", coefficient: 1, decimal:0},
        app_110:{name: "重量阈值", fieldName: "covWeight", unit:"kg", dataType: "uint32be", coefficient: 1, decimal:0},
        app_114:{name: "距离阈值", fieldName: "covDepth", unit:"mm", dataType: "uint16be", coefficient: 1, decimal:0}
    }
    let payParser=new PayloadParser({
        frameInfo:{},
        device:device,
        msg:msg,
        paraInfo:paraInfo,
    })
    const pdata= payParser.paras();
    let result = {
        telemetry_data: pdata,
        server_attrs: null,
        shared_attrs: {class_mode: msg?.userdata?.class},
    };
    // ── rpcHook (设备对接通用规则) ──
    if (typeof RPCHelper.buildRpcHookAction === "function") {
      const __a = RPCHelper.buildRpcHookAction({ device, msg, thingModelId, idName: "mt_transh_para_10103", name: "[BIN]-para-10103", parsed: { telemetry_data: result.telemetry_data, server_attrs: result.server_attrs, shared_attrs: result.shared_attrs } });
      if (__a) { result.actions = result.actions || []; result.actions.push(__a); }
    }
    return result;
}
console.log(payload_parser(
    { telemetry_data: {} },
    { userdata: { port: 11, payload: "" } },
    "1",
    { telemetry_data: true },
    {}
))

物模型字段定义

物模型字段类型单位名称
mt_bin_data_10103depthnumbermmDepth
mt_bin_data_10103weightnumberkgWeight
mt_bin_data_10103weightStatus1stringStability Status
mt_bin_data_10103weightStatus2stringWeighing Status
mt_bin_data_asset_10103zone_depth_avgnumbermmZone Depth
mt_bin_data_asset_10103zone_weight_sumnumberkgZone Weight
mt_bin_data_asset_10103online_countnumberZone Online Count
mt_transh_para_10103covDepthnumbermmDepth Change Threshold
mt_transh_para_10103covWeightnumberkgWeight Change Threshold
mt_transh_para_10103periodDataUPnumberUpload Period
mt_transh_para_10103periodDataQuerynumberQuery Period

RPC 参数定义

RPC参数类型说明默认值单位
mt_set_trash_para_10103covDepthnumberDepth Change Threshold300mm
mt_set_trash_para_10103covWeightnumberWeight Change Threshold1kg
mt_set_trash_para_10103periodDataUPnumberUpload Period900
mt_set_trash_para_10103periodDataQuerynumberQuery Period300

触发器定义

无项目专用触发器。

第三方平台数据订阅

MQTT Topic: /v32/{Organization Account}/tkl/up/telemetry/{eui}

json
{
  "eui": "6353012af10a9331",
  "active_time": "2026-07-13T08:35:48.000Z",
  "thingModelId": "Use the platform model ID from the model inventory",
  "thingModelIdName": "Use the current telemetry model id_name",
  "telemetry_data": {
    "snr": 13.5,
    "rssi": -51,
    "battery": 3.37
  }
}

模板选择与验证

在 ThinkLink 平台按项目名称、业务代码或模型清单中的 id_name、ID 搜索并绑定模型。部署后使用真实上行帧核对字段、单位、RPC 和触发器行为。

补充说明

需求与决策依据:requirement/requirements.md