IoT Devices · 超级大屏
Super Screen API 示例:局域网 WebSocket
通过已记录的局域网 WebSocket 查询区域,按 mid 匹配回复并处理超时,再发布内容。示例使用大屏协议,与设备 API 分开。
运行示例前
在与客户端相同网络使用 Node.js 24 或具有兼容 WebSocket 客户端的运行环境。先通过 /ping 确认监听端口,再通过进程环境提供 SCREEN_IP、SCREEN_PORT、SCREEN_CONTROL_CODE。控制码必须是该设备已启用的六位码,不是 /api/iot/v1 的 API Key。
第一个请求只读,查询显示区域列表。代码中八秒超时只是示例取值,不是服务时限承诺。示例只输出匹配的回复,不记录连接网址或控制码;应先在项目测试屏上运行,再扩展到控制动作。
Node.js:查询区域并匹配回复
将代码保存为 screen-query.mjs,设置环境变量后执行 node screen-query.mjs。mid 保持八个字符,ts 使用毫秒时间戳;其他请求的回复不会使本次请求完成。
import { randomBytes } from 'node:crypto';
const host = process.env.SCREEN_IP;
const port = Number(process.env.SCREEN_PORT);
const token = process.env.SCREEN_CONTROL_CODE ?? '';
if (!host || !/^[a-zA-Z0-9.-]+$/.test(host) ||
!Number.isInteger(port) || port < 1 || port > 65535 ||
!/^\d{6}$/.test(token)) {
throw new Error('Set SCREEN_IP, SCREEN_PORT and SCREEN_CONTROL_CODE');
}
const endpoint = new URL(`ws://${host}:${port}/order`);
endpoint.search = new URLSearchParams({ token, rid: 'energy-pilot', rname: 'Energy pilot' }).toString();
const mid = randomBytes(4).toString('hex');
const socket = new WebSocket(endpoint);
let done = false;
function finish(failed) {
if (done) return;
done = true;
clearTimeout(timer);
process.exitCode = failed ? 1 : 0;
socket.close();
}
const timer = setTimeout(() => {
console.error('Reply timeout; verify state before retrying a control action');
finish(true);
}, 8000);
socket.addEventListener('open', () => {
if (!done) socket.send(JSON.stringify({
mid, data: { screen: { action: 'list' } }, ts: Date.now(),
}));
});
socket.addEventListener('message', (event) => {
if (done) return;
let reply;
try { reply = JSON.parse(String(event.data)); } catch { return; }
if (!reply || typeof reply !== 'object' || reply.mid !== mid) return;
console.log(JSON.stringify(reply, null, 2));
finish(reply.ret === 'error');
});
socket.addEventListener('error', () => {
if (!done) console.error('Connection failed; check network, port and control code');
finish(true);
});
socket.addEventListener('close', () => {
if (!done) {
console.error('Connection closed before a correlated reply');
finish(true);
}
});查询区域后再发布内容
使用查询返回的实际区域 ID。以下命令数据以本站能源指南页面验证内容连通性,测试后再换成项目看板网址。局域网请求使用新的 mid 与 ts 封装,云端则按项目交付的传输字段封装;不要把大屏命令发到设备 API。
{"web":{"area":"a1","url":"https://iotdevices.org/zh/solutions/energy-management","interval":60}}
{"web":{"area":"a1"}}处理错误时不要假设动作已完成
ret: error 表示失败,例如 invalid param、unsupported 或 device is in remote mode。超时意味着结果未知;重试改变状态的动作前先查询当前内容,不要盲目重复语音等有副作用的动作。排查记录保留 mid、设备 ID、时间与脱敏回复,实体屏幕显示另行确认。