IoT Devices · Super Screen

Super Screen API examples: LAN WebSocket

Query regions over the documented LAN WebSocket, correlate replies by mid and handle timeout before publishing content. Examples use the screen protocol, separate from the device API.

Before running the example

Use Node.js 24 or a runtime with a compatible WebSocket client on the same network as the player. Confirm the actual listener port with /ping and supply SCREEN_IP, SCREEN_PORT and SCREEN_CONTROL_CODE in the process environment. The control code must be the device’s enabled six-digit code; it is not an API key for /api/iot/v1.

The first request is read-only: it lists screen regions. The snippet has an example eight-second timeout, not a service guarantee. It prints the correlated reply without logging the connection URL or control code. Run it against a project test screen before adapting it for control actions.

Node.js: list regions and correlate the reply

Save this as screen-query.mjs and run node screen-query.mjs after setting the environment values. Keep the mid eight characters long and ts in milliseconds. Replies from other requests do not complete this request.

Protocol example
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);
  }
});

Publish content only after the region query

Use a region ID returned by the query. The following command data opens this website’s energy guide as a connectivity check; replace the URL with your project dashboard after testing. Wrap it with a fresh mid and ts for LAN, and with the project-supplied transport fields for cloud. Do not send screen commands to the device API.

Protocol example
{"web":{"area":"a1","url":"https://iotdevices.org/zh/solutions/energy-management","interval":60}}
{"web":{"area":"a1"}}

Handle errors without assuming execution

ret: error reports a failure such as invalid param, unsupported or device is in remote mode. A timeout leaves the result unknown. Query current content before retrying a state-changing action; do not blindly repeat speech or other actions with side effects. Retain the mid, device ID, time and sanitized response for diagnosis, and verify the physical screen separately.

Chat on WhatsApp