From 4500f92b1512ef02a2e89b90e62a8b46e3e51462 Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Tue, 11 Aug 2026 21:25:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(docs):=20=E6=B7=BB=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=BF=83=E8=B7=B3=E8=A1=A8SQL=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增TDengine超级表device_heartbeat的建表语句及EMQX规则引擎配置示例。 --- docs/sql/device_heartbeat.sql | 32 +++++++++++++++++++++++++ docs/sql/device_status_log.sql | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 docs/sql/device_heartbeat.sql create mode 100644 docs/sql/device_status_log.sql diff --git a/docs/sql/device_heartbeat.sql b/docs/sql/device_heartbeat.sql new file mode 100644 index 00000000..0b1ca019 --- /dev/null +++ b/docs/sql/device_heartbeat.sql @@ -0,0 +1,32 @@ +-- 1. 创建数据库 mqtt(如果不存在) +-- 建议指定时间精度为 ms(毫秒),与 EMQX 规则中的 now_timestamp('millisecond') 匹配 +CREATE DATABASE IF NOT EXISTS mqtt PRECISION 'ms' KEEP 3650; + +-- 2. 切换到 mqtt 数据库 +USE mqtt; + +-- 3. 创建超级表 device_heartbeat +CREATE STABLE IF NOT EXISTS device_heartbeat ( + ts TIMESTAMP, -- 必填,时间戳 (毫秒级),8字节 + online BOOL, -- 设备状态:true=online, false=offline,1字节 + ip VARCHAR(15), -- IPv4 地址,最多15字符,1字节/字符 + 1字节长度 + rssi SMALLINT, -- 信号强度 (-128 到 127/32767),2字节 + screen_on BOOL -- 屏幕开启状态 (true / false) 1字节 +) TAGS ( + sn VARCHAR(32) -- 设备SN码,可变长字符串,比NCHAR省一半以上空间 +); + +-- 4.emqx rules +SELECT + payload.sn AS sn, + payload.status AS status, + payload.ip AS ip, + payload.rssi AS rssi, + payload.screenOn AS screen_on, + now_timestamp('millisecond') AS ts +FROM "ttstd/device/status" +WHERE is_not_null(payload.sn) + +-- 5.emqx action 没有数据打开 "未定义变量作为 NULL" 开关 +INSERT INTO mqtt.`hb_${sn}` USING mqtt.device_heartbeat TAGS ('${sn}') +VALUES (${ts}, '${status}', '${ip}', ${rssi}, ${screen_on}) \ No newline at end of file diff --git a/docs/sql/device_status_log.sql b/docs/sql/device_status_log.sql new file mode 100644 index 00000000..a36069ff --- /dev/null +++ b/docs/sql/device_status_log.sql @@ -0,0 +1,43 @@ +USE iot_log; + +-- 创建同时记录上下线状态的超级表 +CREATE STABLE IF NOT EXISTS device_status_log ( + ts TIMESTAMP, -- 事件发生时间 + event VARCHAR(16), -- 事件类型: 'connected' 或 'disconnected' + reason VARCHAR(64), -- 下线原因(上线时填 'clean_start' 或 'none') + peername VARCHAR(64) -- 客户端 IP 及端口 +) TAGS ( + clientid VARCHAR(128), + username VARCHAR(128) +); + +-- emqx 设备离线 rules +SELECT + clientid, + username, + peername, + reason, + disconnected_at AS ts, + 'disconnected' AS event +FROM + "$events/client_disconnected" + +-- emqx 设备离线 action +INSERT INTO mqtt.device_${clientid} +USING mqtt.device_status_log TAGS ('${clientid}', '${username}') +VALUES (${ts}, '${event}', '${reason}', '${peername}'); + +-- emqx 设备上线 rules +SELECT + clientid, + username, + peername, + connected_at AS ts, + 'connected' AS event +FROM + "$events/client_connected" + +-- emqx 设备上线 action +INSERT INTO mqtt.device_${clientid} +USING mqtt.device_status_log TAGS ('${clientid}', '${username}') +VALUES (${ts}, '${event}', 'none', '${peername}'); \ No newline at end of file