MT-Gateway Integration Guide
Capability Overview
MT-Gateway is integrated with ThinkLink through gateway-raw in lorawan-native mode. This guide documents the current deployable artifacts and their source-traceable versions.
| Item | Value |
|---|---|
| Project | mt-gateway |
| Vendor | MT |
| Model | MT-Gateway |
| Business Code | Not applicable |
| Integration Mode | lorawan-native |
| Protocol | gateway-raw |
Model catalog
Search for these models in ThinkLink by name or ID.
| Model type | Name | id_name | Platform model ID |
|---|---|---|---|
| RPC | [GW SET] geo config | mt_gw_geo_set_config | 119427355042017280 |
| RPC | [GW ACT] his get | mt_gw_his_get | 120041209778302976 |
| RPC | [GW ACT] history get | mt_gw_history_get | 120039711216398337 |
| RPC | [GW ACT] locate | mt_gw_locate | 119427355042017281 |
| RPC | [GW ACT] wifi list get | mt_gw_wifi_list_get | 119403377514672128 |
| Template | MT-Gateway | 120034832892719104 | |
| Thing Model | [GW HEART] | mt_gw_heart | 95121332907282437 |
| Thing Model | [GW WIFI] scan result | mt_gw_wifi | 119474792070803456 |
| Trigger | [GW LOCATE] on wifi scan | mt_gw_locate_on_wifi | 119474793920491520 |
mt_gw_his_get is the current template-bound history RPC; mt_gw_history_get remains only for recognizing and migrating legacy bindings.
Operations Skill
Use create-gateway to deploy or debug history queries, Wi-Fi scans, Tencent location, the reinjection forwarder, and scheduled scans. It traces NMS uplink, AS reinjection, trigger dispatch, and attribute readback as separate boundaries.
Features and Application Scope
This project covers MT-Gateway through gateway-raw. Its capability boundary, fields, and deployable models follow the current descriptor, requirements, and model sources.
Deployment and Data Acquisition
| DTU | Not applicable | | Power | ac | | LoRaWAN Class | C | | Interface | LoRaWAN | | Baud Rate | Not applicable |
Telemetry and Register Definitions
| Field | Name | Type | Unit | Address/Source | Description |
|---|---|---|---|---|---|
| handle | handle | string | — | Source field: handle | |
| hwVersion | hwVersion | string | — | Source field: hwVersion | |
| fwVersion | fwVersion | string | — | Source field: fwVersion | |
| netType | netType | string | — | Source field: netType | |
| validIP | validIP | string | — | Source field: validIP | |
| nsConnect | nsConnect | boolean | — | Source field: nsConnect | |
| nmsConnect | nmsConnect | boolean | — | Source field: nmsConnect | |
| pmcConnect1 | pmcConnect1 | boolean | — | Source field: pmcConnect1 | |
| wifi_ap_count | wifi_ap_count | number | — | Source field: wifi_ap_count |
Parameter Definitions
No project-specific parameters are defined.
Requirements Evidence
The following key facts were extracted from the requirements source; line references support verification.
| Category | Source Fact | Source |
|---|---|---|
| Protocol/Data | - mt_gw_heart NMS deviceHandle/ /IP/ns/nms/pmc → + shared_attrs | requirement/requirements.md:15 |
| Protocol/Data | → [ mt_gw_wifi (CUSTOMER)] AS | requirement/requirements.md:41 |
| Protocol/Data | · telemetry_data.wifi_ap_count = AP | requirement/requirements.md:42 |
| Protocol/Data | → [ mt_gw_locate_on_wifi] mt_gw_wifi wifi_ap_count>0 → dispatch mt_gw_locate | requirement/requirements.md:44 |
| Protocol/Data | shared_attrs.gw_latitude/gw_longitude/gw_accuracy/gw_address/gw_city/geo_source/geo_fetched_at | requirement/requirements.md:46 |
| Protocol/Data | thinklink/thingModel/mt_gw_wifi.{js,json} CUSTOMER AS → wifi_ap_count( ) + wifi_list(shared_attrs) 119474792070803456 | requirement/requirements.md:53 |
| Protocol/Data | forwarder/mt-gw-wifilist-to-as.js nms/up/gw/+ → wifiList → AP → AS paste-ready, import — id | requirement/requirements.md:55 |
| Deployment | descriptor.yaml scheduled_task 24h mt_gw_wifi_list_get — | requirement/requirements.md:56 |
| Protocol/Data | gw_address / gw_city shared_attrs mt_gw_locate / | requirement/requirements.md:68 |
| Protocol/Data | - mt_gw_wifi parser performs no HTTP requests; mt_gw_locate RPC handles HTTP location requests | requirement/requirements.md:73 |
| Protocol/Data | - wifi_ap_count KB-30 _modelName | requirement/requirements.md:75 |
| Protocol/Data | - heart(NMS, msg.data ) wifi(AS, msg.userdata.payload ) parser parser null | requirement/requirements.md:78 |
| Unresolved | - TBD-1 nms/up/gw AP data AP ssid/bssid/rssi vs ESSID/Address/Signal bssid mac Address rssi signal ssid essid | requirement/requirements.md:84 |
| Unresolved | - TBD-2 broker nms/up/gw as/up/data broker from/to emqx type broker | requirement/requirements.md:85 |
| Unresolved | - TBD-3 mt_gw_heart mt_gw_wifi mt_gw_locate_on_wifi AS | requirement/requirements.md:86 |
| Protocol/Data | 1. 4 PUBLIC SYSADMIN /thinklink/system/... _commitMessage mt_gw_wifi( ) + mt_gw_locate_on_wifi( ) | requirement/requirements.md:92 |
| Unresolved | 3. from /v32/{tenant}/nms/up/gw/+ → to /v32/{tenant}/as/up/data/{eui} = forwarder/mt-gw-wifilist-to-as.js broker TBD-2 | requirement/requirements.md:94 |
| Unresolved | 6. → shared_attrs.wifi_list telemetry wifi_ap_count >0 shared_attrs.gw_latitude/gw_longitude nms/up/gw TBD-1 | requirement/requirements.md:97 |
| Protocol/Data | 2026-06-16 wifi AP shared_attrs wifi_ap_count gate (device.telemetry_data[id]) + KB-30 AP shared_attrs " telemetry" ( ) mt_gw_wifi | requirement/requirements.md:107 |
| Deployment | 2026-06-16 = 24h cron_task scheduled_task | requirement/requirements.md:108 |
| Protocol/Data | 2026-06-16 complete-js-local.sh glob over-match /thinklink/.js → thingModel/rpc/trigger thinklink/ glob .js paste-ready forwarder/ import scripts/complete-js-local.sh | requirement/requirements.md:109 |
Thing Model and RPC Code
RPC: [GW SET] geo config
id_name: mt_gw_geo_set_config · ID: 119427355042017280
import {BufferTKL, RPCHelper, Utils} from "#tklHelper";
import {Buffer} from "buffer";
// 配置网关定位服务(腾讯位置服务)的 apikey 与 base_url,写入网关设备 server_attrs。
// 供 mt_gw_locate 调用腾讯 WiFi 定位 API 时读取(key 必填;base_url 默认 https://apis.map.qq.com)。
// 腾讯定位 API: POST {base_url}/ws/location/v1/network body {key, device_id, wifiinfo:[{mac,rssi}]}
// 文档 https://lbs.qq.com/service/webService/webServiceGuide/position/location
function rpc_script({ device, params, alarms, logger, org_params }) {
const sa = {};
if (params.tencent_lbs_key != null) sa.tencent_lbs_key = params.tencent_lbs_key;
if (params.tencent_lbs_base_url != null) sa.tencent_lbs_base_url = params.tencent_lbs_base_url;
if (Object.keys(sa).length === 0) return null; // 无有效配置项不下发
return [{ sleepTimeMs: 0, type: "modifyAttrs", dnMsg: { server_attrs: sa } }];
}
rpc_script({
device: { eui: "5a53012a000002e9", server_attrs: {} },
params: { tencent_lbs_key: "TEST_KEY", tencent_lbs_base_url: "https://apis.map.qq.com" },
logger: console,
org_params: {}
})RPC: [GW ACT] his get
id_name: mt_gw_his_get · ID: 120041209778302976
import {BufferTKL, RPCHelper, Utils} from "#tklHelper";
import {Buffer} from "buffer";
function rpc_script({ device, params, alarms, logger, org_params }) {
logger.info("read history")
if (params.start==undefined||params.end==undefined) return null
if (params.start.length<=8 || params.end.length<=8) return null
let whereInfo = `pgsql://creat >= '${params.start}' AND creat <= '${params.end}'`;
let msg={
type:"nsDnGwc",
sleepTimeMs: 0,
target:device.eui,
dnMsg: {
version: "2",
EUI: device.eui,
token: new Date().getTime(),
action:"gwHis",
mode:"rxdataRead",
data: {
whereInfo: whereInfo,
gwToken: Date.now()%(0xFFFF),
intervalms:10
}
}
}
return [msg]
}
if (process.env.TKL_SELF_TEST === "1") {
rpc_script({
device: { eui: "5a53012a000002e9" },
params: {
start: "2026-07-29 00:00:00",
end: "2026-07-29 01:00:00"
},
logger: console,
org_params: {}
})
}RPC: [GW ACT] locate
id_name: mt_gw_locate · ID: 119427355042017281
import {BufferTKL, RPCHelper, Utils} from "#tklHelper";
import {Buffer} from "buffer";
// 网关定位(输出位置信息到 shared_attrs)。来源优先级:① GPS(网关 GPS 模块直接给经纬度,最准);
// ② 取不到 GPS 时用 WiFi——把 wifiList 扫到的 AP(bssid/rssi)送腾讯位置服务 WiFi 定位换经纬度。
// 腾讯 API: POST {base_url}/ws/location/v1/network body {key, device_id, wifiinfo:[{mac,rssi}]}
// → {status:0, result:{location:{latitude,longitude,accuracy}, address, ad_info:{city}}}
// 文档 https://lbs.qq.com/service/webService/webServiceGuide/position/location
// key / base_url 经 mt_gw_geo_set_config 写入 server_attrs(base_url 默认 https://apis.map.qq.com)。
//
// 数据来源(按「对应方式」就位即可,二者皆从 shared_attrs 读,缺则用入参兜底测试):
// GPS ← device.shared_attrs.gps = {lat, lon, accuracy?, valid?}(网关 GPS 经 DMS geoGet 上报落库后)
// WiFi ← device.shared_attrs.wifi_list = [{bssid|mac, rssi, essid?}](wifiList 响应落库后)
async function rpc_script({ device, params, alarms, logger, org_params }) {
const sa = device?.server_attrs || {};
const sh = device?.shared_attrs || {};
const num = (v) => (v == null || isNaN(Number(v)) ? null : Number(v));
// ── ① GPS 优先 ──────────────────────────────────────────────
const gps = params?.gps || sh.gps || null;
const gLat = gps ? num(gps.lat != null ? gps.lat : gps.latitude) : null;
const gLon = gps ? num(gps.lon != null ? gps.lon : gps.longitude) : null;
const gpsValid = gps && (gps.valid !== false) && gLat != null && gLon != null && !(gLat === 0 && gLon === 0);
if (gpsValid) {
return [{ sleepTimeMs: 0, type: "modifyAttrs", dnMsg: { shared_attrs: {
gw_latitude: gLat, gw_longitude: gLon,
gw_accuracy: num(gps.accuracy) != null ? num(gps.accuracy) : 1,
gw_address: null, gw_city: null,
geo_source: "gps", geo_fetched_at: new Date().toISOString()
} } }];
}
// ── ② WiFi 兜底(腾讯 WiFi 定位)─────────────────────────────
const key = params?.tencent_lbs_key || sa.tencent_lbs_key;
if (!key) { logger && logger.systemWarn && logger.systemWarn("mt_gw_locate: no GPS fix and missing tencent_lbs_key"); return null; }
const baseUrl = (params?.tencent_lbs_base_url || sa.tencent_lbs_base_url || "https://apis.map.qq.com").replace(/\/+$/, "");
let wifiinfo = Array.isArray(params?.wifiinfo) ? params.wifiinfo : null;
if (!wifiinfo) {
const wl = sh.wifi_list;
if (Array.isArray(wl)) wifiinfo = wl.map((a) => ({ mac: a.mac || a.bssid, rssi: a.rssi }));
}
wifiinfo = (wifiinfo || []).map((a) => ({ mac: String(a.mac), rssi: num(a.rssi) })).filter((a) => a.mac && a.mac !== "null");
if (!wifiinfo.length) { logger && logger.systemWarn && logger.systemWarn("mt_gw_locate: no GPS and no wifi list"); return null; }
const body = { key, device_id: device.eui, wifiinfo };
let resp;
try {
resp = await axios.post(`${baseUrl}/ws/location/v1/network`, body, { headers: { "Content-Type": "application/json" } });
} catch (e) {
logger && logger.systemError && logger.systemError(`mt_gw_locate tencent http error: ${e && e.message}`);
return null; // 取数失败/超时 → 不写脏数据
}
const d = resp && resp.data;
if (!d || d.status !== 0 || !d.result || !d.result.location) {
logger && logger.systemWarn && logger.systemWarn(`mt_gw_locate tencent status=${d && d.status} msg=${d && d.message}`);
return null;
}
const loc = d.result.location;
const adi = d.result.ad_info || {};
return [{ sleepTimeMs: 0, type: "modifyAttrs", dnMsg: { shared_attrs: {
gw_latitude: num(loc.latitude), gw_longitude: num(loc.longitude), gw_accuracy: num(loc.accuracy),
gw_address: d.result.address != null ? d.result.address : null,
gw_city: adi.city != null ? adi.city : null,
geo_source: "tencent_wifi", geo_fetched_at: new Date().toISOString()
} } }];
}
// 本地测试:无 GPS、无 key、无 wifi → 早返回 null(不触达 axios,node 可直接跑通)
rpc_script({
device: { eui: "5a53012a000002e9", server_attrs: {}, shared_attrs: {} },
params: {},
logger: console,
org_params: {}
})RPC: [GW ACT] wifi list get
id_name: mt_gw_wifi_list_get · ID: 119403377514672128
import {BufferTKL, RPCHelper, Utils} from "#tklHelper";
import {Buffer} from "buffer";
// 获取网关周围的 WiFi 列表(SSID/BSSID/RSSI)。
// 走 NMS 下行通道:平台据 type:"nmsDnGw" 把 dnMsg 原样发到
// /v32/<tenant>/nms/dn/gw/<eui> (NMS gateway downlink topic)
// 网关执行 `iwlist <wlan0> scan`,结果异步回到上行 topic
// /v32/<tenant>/nms/up/gw/<eui> 并用 token 回显匹配本次请求。
// 注意:①网关需启用 WiFi 接口(boardInfo.Wifi0.Enable)否则 data 返回 "";
// ②扫描底层超时 30s,响应可能延迟数秒到数十秒。
function rpc_script({ device, params, alarms, logger, org_params }) {
logger.info("wifiList scan")
let msg = {
type: "nmsDnGw",
sleepTimeMs: 0,
target: device.eui,
dnMsg: {
version: "3.0",
eui: device.eui,
action: "wifiList",
token: Date.now(), // 任意 uint64,原样回显在响应里用于匹配请求
mode: "read", // wifiList 不校验 mode/data,填上更规范
data: null
}
}
return [msg]
}
rpc_script({
device: { eui: "5a53012501030066" },
params: {},
logger: console,
org_params: {}
})Thing Model: [GW HEART]
id_name: mt_gw_heart · ID: 95121332907282437
import {Buffer} from "buffer";
import {BufferTKL, PayloadParser, RPCHelper, Utils} from "#tklHelper";
// 网关心跳物模型 [GW HEART] —— 平台 id_name: mt_gw_heart(与线上一致)。
// 解析网关经 NMS 上行的心跳帧(msg.data:deviceHandle/hwVersion/fwVersion/netType/
// validIP/nsConnect/nmsConnect/pmcConnect1),写入遥测 + shared_attrs。
// 心跳间隔 > 5min 时,顺带触发 mt_gw_his_get 补拉断档期间的历史数据。
// 配套 RPC(同一套网关模型):mt_gw_his_get(历史查询)、mt_gw_wifi_list_get(周边 WiFi 扫描)。
function payload_parser(device, msg, thingModelId, noticeAttrs, org_params) {
if (msg?.data == undefined) return null;
let data = msg.data;
let pdata = {};
let changed = false;
let lasttime = device.shared_attrs?.updatems;
let action = [];
if (lasttime != undefined) {
const diff = Date.now() - lasttime;
if (diff > 300000) {
action.push({
method: "mt_gw_his_get",
params: {
start: device.shared_attrs?.update_time,
end: new Date().toLocaleTimeString()
},
});
}
}
pdata.updatems = Date.now();
pdata.handle = data.deviceHandle;
pdata.hwVersion = data.hwVersion;
pdata.fwVersion = data.fwVersion;
pdata.netType = data.netType;
pdata.validIP = data.validIP;
pdata.nsConnect = data.nsConnect;
pdata.nmsConnect = data.nmsConnect;
pdata.pmcConnect1 = data.pmcConnect1;
if (pdata.handle !== device.shared_attrs?.handle) changed = true;
if (pdata.hwVersion !== data.hwVersion) changed = true;
if (pdata.fwVersion !== data.fwVersion) changed = true;
if (pdata.netType !== data.netType) changed = true;
if (pdata.validIP !== data.validIP) changed = true;
if (pdata.nsConnect !== data.nsConnect) changed = true;
if (pdata.nmsConnect !== data.nmsConnect) changed = true;
if (pdata.pmcConnect1 !== data.pmcConnect1) changed = true;
let result = {
telemetry_data: changed ? pdata : null,
server_attrs: null,
shared_attrs: pdata,
action: action,
};
// ── rpcHook (设备对接通用规则) ──
if (typeof RPCHelper.buildRpcHookAction === "function") {
const __a = RPCHelper.buildRpcHookAction({ device, msg, thingModelId, idName: "mt_gw_heart", name: "[GW HEART]", 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;
}
payload_parser(
{ eui: "5a53012a000002e9", shared_attrs: {} },
{
action: "heart",
data: {
deviceHandle: "GDI514-AGCN470-G-2",
hwVersion: "3.1.3",
fwVersion: "3.2.01",
netType: "mteth0",
validIP: "192.168.1.72",
nsConnect: true,
nmsConnect: true,
pmcConnect1: true
}
},
"95121332907282437",
{ telemetry_data: true }
)Thing Model: [GW WIFI] scan result
id_name: mt_gw_wifi · ID: 119474792070803456
import {Buffer} from "buffer";
import {BufferTKL, PayloadParser, RPCHelper, Utils} from "#tklHelper";
// 网关周边 WiFi 扫描结果物模型 [GW WIFI] —— 平台 id_name: mt_gw_wifi。
// 数据来源:mt_gw_wifi_list_get(nmsDnGw) 触发网关 iwlist 扫描,回复落 /v32/<tenant>/nms/up/gw/<eui>;
// 平台 tkl-main 仅落库 heart 分支(不落 wifiList,BUG-048),故由转发器 mt-gw-wifilist-to-as 订阅 nms/up/gw、
// 把 AP 列表重封装成 AS 上行(/v32/<tenant>/as/up/data/<eui>, userdata.payload=base64(JSON {w:[...]})),
// 本 CUSTOMER 解析器解 AS 帧 → 遥测 wifi_ap_count(本帧标量,供触发器判别+观测) + shared_attrs.wifi_list(供腾讯定位) + wifi_scanned_at。
// AP 列表只进 shared_attrs(每次扫描整体刷新、不入历史趋势);遥测只留计数标量。
function payload_parser(device, msg, thingModelId, noticeAttrs, org_params) {
let o;
try {
const raw = msg && msg.userdata && msg.userdata.payload;
if (raw == null) return null; // 非 AS 注入帧(如 heart 经 NMS 上行)→ 让位
o = typeof raw === "string" ? JSON.parse(Buffer.from(raw, "base64").toString("utf8")) : raw;
} catch (e) {
return null; // 解析失败不写脏数据
}
if (!o || typeof o !== "object" || !Array.isArray(o.w)) return null; // 非 wifi 帧(无 w 数组)→ 让位
const num = (v) => (v == null || isNaN(Number(v)) ? null : Number(v));
const aps = o.w
.map((a) => ({
bssid: a.bssid != null ? String(a.bssid) : null,
rssi: num(a.rssi),
essid: a.essid != null ? String(a.essid) : null
}))
.filter((a) => a.bssid); // 丢弃无 bssid 的项(腾讯定位以 bssid/mac 为键)
if (!aps.length) return null; // 无有效 AP 不写脏数据
let result = {
telemetry_data: { wifi_ap_count: aps.length },
server_attrs: null,
shared_attrs: { wifi_list: aps, wifi_scanned_at: o.ts != null ? o.ts : new Date().toISOString() }
};
// ── rpcHook (设备对接通用规则) ──
if (typeof RPCHelper.buildRpcHookAction === "function") {
const __a = RPCHelper.buildRpcHookAction({ device, msg, thingModelId, idName: "mt_gw_wifi", name: "[GW WIFI] scan result", 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;
}
// 本地测试:转发器注入的 AS 帧(base64 JSON {w:[...]}) → 期望 telemetry wifi_ap_count + shared_attrs.wifi_list
payload_parser(
{ eui: "5a53012a000002e9", shared_attrs: {} },
{
userdata: {
port: 2,
payload: Buffer.from(JSON.stringify({
w: [
{ bssid: "34:ce:00:11:22:33", rssi: -45, essid: "GDI514-AGCN470" },
{ bssid: "9c:21:6a:aa:bb:cc", rssi: -67, essid: "office-2.4G" }
]
})).toString("base64")
}
},
"119474792070803456",
{ telemetry_data: true }
)Trigger: [GW LOCATE] on wifi scan
id_name: mt_gw_locate_on_wifi · ID: 119474793920491520
import {Utils} from "#tklHelper";
// 网关定位触发器 [GW LOCATE] —— 平台 id_name: mt_gw_locate_on_wifi。
// 绑定到 mt_gw_wifi 物模型:每次 wifiList 扫描结果经转发器回灌 AS、被 mt_gw_wifi 解析出
// telemetry wifi_ap_count(>0) + shared_attrs.wifi_list 后,本触发器派发 mt_gw_locate,
// 由其读 shared_attrs.wifi_list → 调腾讯 WiFi 定位 → 写经纬度到 shared_attrs。
function trigger_script(device, thingModelId) {
const td = device?.telemetry_data?.[thingModelId];
if (!td) return null;
if (td.wifi_ap_count == null || td.wifi_ap_count <= 0) return null; // 无有效扫描结果不定位(KB-30:业务字段判别,非_modelName)
return {
should_dispatch: true, // 相同 AP 计数的相邻扫描仍重新定位
delayms: 1000, // 给 shared_attrs.wifi_list 落库留余量后再派发 locate
abort_previous_timer: true,
actions: [
{ method: "mt_gw_locate", params: { _eui: device.eui } }
]
};
}
// 用例:扫到 2 个 AP → 期望派发 mt_gw_locate 带 _eui
console.log(JSON.stringify(trigger_script(
{ eui: "5a53012a000002e9", telemetry_data: { "119474792070803456": { wifi_ap_count: 2 } } },
"119474792070803456"
)));
// 反例:无 AP(wifi_ap_count=0) → 期望 null
console.log(JSON.stringify(trigger_script(
{ eui: "5a53012a000002e9", telemetry_data: { "119474792070803456": { wifi_ap_count: 0 } } },
"119474792070803456"
)));Thing Model Field Definitions
| Thing Model | Field | Type | Unit | Name |
|---|---|---|---|---|
| mt_gw_heart | handle | string | Device Handle | |
| mt_gw_heart | hwVersion | string | Hardware Version | |
| mt_gw_heart | fwVersion | string | Firmware Version | |
| mt_gw_heart | netType | string | Network Type | |
| mt_gw_heart | validIP | string | Valid IP | |
| mt_gw_heart | nsConnect | boolean | NS Connection | |
| mt_gw_heart | nmsConnect | boolean | NMS Connection | |
| mt_gw_heart | pmcConnect1 | boolean | PMC Connection | |
| mt_gw_wifi | wifi_ap_count | number | WiFi AP Count |
RPC Parameter Definitions
| RPC | Parameter | Type | Description | Default | Unit |
|---|---|---|---|---|---|
| mt_gw_geo_set_config | tencent_lbs_key | string | Tencent LBS Key | — | |
| mt_gw_geo_set_config | tencent_lbs_base_url | string | Tencent LBS Base URL | https://apis.map.qq.com |
Trigger Definitions
| Trigger | Condition Signals | Delay Expression | RPC Actions | Abort Previous Timer |
|---|---|---|---|---|
| mt_gw_locate_on_wifi | — | 1000 | mt_gw_locate | true |
Third-Party Platform Subscription
MQTT Topic: /v32/{Organization Account}/tkl/up/telemetry/{eui}
{
"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,
"handle": "sample-1",
"hwVersion": "sample-2",
"fwVersion": "sample-3",
"netType": "sample-4",
"validIP": "sample-5",
"nsConnect": true,
"nmsConnect": true,
"pmcConnect1": true
}
}Template Selection and Verification
Search ThinkLink by project name, business code, or the id_name and ID values in the model inventory. After deployment, use real uplinks to verify fields, units, RPCs, and trigger behavior.
Supplementary Notes
Requirements and decisions: requirement/requirements.md.