Skip to content

RPC Device Control Protocol

1. Purpose of this document

This document is intended for developers of third-party central control systems, integration platforms, and operation tools. It explains the two device control methods currently supported by this system:

  • Server-forwarded RPC: the Admin End sends commands through the cloud server or a private deployment server, which then forwards them to the target device
  • UDP direct control: a third-party controller sends UDP commands directly to the device's LAN address

This document only describes protocol capabilities that are already implemented and can be confirmed in the current codebase. It does not extend to control methods that have not been implemented.

2. Protocol overview

2.1 Two transport paths

This system currently supports two device control paths:

  1. Server-forwarded RPC
    The Admin End first calls the server API, and the server then forwards the command to the device.

  2. UDP direct control
    A third-party controller sends commands directly to the device's locally exposed UDP port without going through the server.

These two methods share the same business-level command payload. The difference is only in the transport layer:

  • HTTP RPC goes through the server or the device's local HTTP service
  • UDP goes through the device's local UDP port

2.2 Unified business payload

All device control commands use the same RpcCmd JSON payload:

json
{
  "method": "getPlayerStatus",
  "params": {
    "t": "q",
    "idx": 1,
    "p": null,
    "v": null
  }
}

Field description:

  • method: command name
  • params.t: message type
  • params.idx: optional request sequence number, useful for matching requests and responses
  • params.p: deprecated and not recommended
  • params.v: business parameter or business return value

Current meanings of params.t:

  • q: request
  • s: success response
  • se: business failure response
  • sd: processed response, mainly used for internal forwarding confirmation and usually not needed by third parties

Third-party integrations are recommended to rely only on these core fields:

  • method
  • params.t
  • params.idx
  • params.v

3. Server-forwarded RPC

3.1 Cloud two-way RPC

This is suitable for cloud publishing or cloud-based private deployment scenarios.

  • Endpoint: POST https://api.example.com:9292/api/rpc/twoway/{deviceId}
  • Authentication: X-Authorization: Bearer <jwt>
  • Description: the Admin End sends the command to the server, the server forwards it to the target device, and then waits for the device to return the business result

Best for:

  • Querying device status
  • Taking screenshots
  • Getting logs
  • Modifying settings

3.2 Cloud one-way RPC

  • Endpoint: POST https://api.example.com:9292/api/rpc/oneway/{deviceId}
  • Authentication: X-Authorization: Bearer <jwt>
  • Description: sends the command only and does not wait for a business response from the device

Best for:

  • Batch refresh operations
  • Best-effort central control commands

3.3 Private deployment / LAN HTTP direct access

This is suitable when the Admin End and the device are in the same LAN, or in a private deployment environment where the device's local HTTP service can be reached directly.

  • Login endpoint: POST http://192.168.1.100:9393/api/nauth/login
  • RPC endpoint: POST http://192.168.1.100:9393/api/device/rpc/{deviceId}
  • Authentication: X-Authorization: Bearer <token>

Notes:

  • The default port of the device's local HTTP service is 9393
  • After a successful LAN login, the device returns a local JWT
  • All later /api/* requests must carry that JWT

3.4 Authentication methods

Cloud / private-deployment Admin End

Cloud RPC uses the Admin End JWT. Example request header:

http
X-Authorization: Bearer eyJhbGciOi...

Notes:

  • X-Authorization is the header currently used by the client by default
  • The server is also compatible with Authorization
  • JWT acquisition follows the same login system as the Admin End, and the login flow itself is not expanded in this document

Device local HTTP service

The LAN service provides a login endpoint without a prior auth token:

http
POST http://192.168.1.100:9393/api/nauth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "your-local-password"
}

Success example:

json
{
  "token": "eyJhbGciOi..."
}

Example of the later request header:

http
X-Authorization: Bearer eyJhbGciOi...

3.5 Common HTTP responses

Cloud RPC

  • 200 OK: the request was delivered successfully, and the two-way RPC already received the device response
  • 401 Unauthorized: not logged in, or the token is invalid
  • 403 Forbidden: logged in, but not allowed to operate this device
  • 504 Gateway Timeout: the device is offline, timed out, or did not return in time

Device local HTTP RPC

  • 200 OK: the HTTP layer call succeeded; business success should still be determined by params.t
  • 401 Unauthorized: a valid JWT was not provided

Recommendation for business result checks

When integrating, do not look only at the HTTP status code. Also check:

  • params.t == "s": business succeeded
  • params.t == "se": business failed

3.6 About additional server-side fields

Cloud /api/rpc/twoway/* and /api/rpc/oneway/* server-forwarded RPC implementations may also support top-level fields such as timeout, persistent, expirationTime, retries, and additionalInfo.

However, to stay compatible with both cloud mode and LAN mode, third parties should by default send only the business payload described in this document:

  • method
  • params

Unless the deployment side has explicitly confirmed that the environment is cloud-only, it is not recommended to depend on cloud-specific persistent RPC fields.

4. UDP direct control

4.1 When to use it

UDP is a device-local control entry point exposed directly by the device, without going through the cloud server or a private deployment server.

A third-party controller can send UDP datagrams directly to the device's LAN address, for example:

  • 192.168.1.120:9393

This is more suitable for central control devices, control hosts, or LAN automation systems.

4.2 Listening port

The device's local UDP service uses the same port as the local HTTP service:

  • 9393

So a third-party controller only needs the device's LAN IP and port to start control.

4.3 UDP packet format

The business content transmitted through UDP is still the same RpcCmd JSON.

Example:

json
{
  "method": "ping",
  "params": {
    "t": "q",
    "idx": 1001,
    "p": null,
    "v": null
  }
}

Notes:

  • The UDP request payload is exactly the same as the data content used by HTTP RPC
  • The UDP response payload is still RpcCmd JSON
  • The device sends the response back to the sender's source address and source port
  • UDP mode does not require a deviceId URL and does not go through server routing

4.4 Security boundary

The current UDP receiving path does not show an extra HTTP/JWT authentication layer, so it should only be treated as a trusted LAN internal protocol.

Strong recommendations:

  • Use it only inside a trusted local network
  • Do not expose it to the public Internet
  • Do not expose this port through public network penetration tools

For third-party central control integration, UDP direct control is the preferred option.

Recommended small-payload, low-latency commands over UDP:

  • ping
  • remoter
  • update_cast
  • getPlayerStatus

Recommended larger-payload or more response-dependent capabilities over HTTP RPC:

  • getScreenshot
  • getLog

Notes:

  • These are recommendations, not implementation limits
  • Some commands may also work over UDP in theory, but from an engineering stability perspective, it is not recommended to rely on UDP long term for large responses

5. Unified command reference

Only commands that are clearly implemented on the device side and are suitable for third-party use are listed below.

5.1 Basic connectivity

MethodRequest params.vResponse params.vDescription
pingnull"pong"Connectivity check

5.2 Status and diagnostics

MethodRequest params.vResponse params.vDescription
getPlayerStatusnullMapQuery the current device status
getScreenshotnull or intStringReturns a Base64 screenshot; if an integer is passed, it means the maximum target size in bytes, with a default around 49000
getLog{"count": 100, "textSearch": "error"}{"log": "..."}Get device logs, supporting line count and keyword filtering
clearLognull"OK"Clear device logs
getAuthLocnull{"authToken": "..."}Get local device authorization information, mainly for LAN-related capabilities

Common fields in the getPlayerStatus response:

  • ver: app version on the device side
  • info: device summary information
  • curTs: current device timestamp
  • curMHCast: current program summary
  • curPlay: current playback relation information
  • taskLen: current schedule length
  • playTaskList: first several items in the current schedule
  • httpServerInfo: information about the device's local HTTP service

5.3 User interaction / central control keys

MethodRequest params.vResponse params.vDescription
remoterStringtrueInject a remote-control or key event into the device

Currently recommended stable remoter key values:

  • Direction keys: up down left right
  • Confirm / back: select back
  • Number keys: 0 to 9
  • Fast forward / rewind: forward backward

Notes:

  • These values are converted on the device side into standard keyboard semantics such as direction keys, back key, and number keys
  • Other custom strings may also be accepted by the event pipeline, but third parties should not depend on undocumented custom key values

5.4 Settings and execution

MethodRequest params.vResponse params.vDescription
getSettings"key"Any typeRead a single setting item
setSettings{"key": value}true/falseWrite one or more setting items in batch
execCmd{"method": "xxx", "params": ...}Any typeCall a registered execution command exposed by the device-side settings module

Notes:

  • getSettings usually receives a single key name in params.v
  • setSettings supports submitting multiple key-value pairs at once
  • execCmd is suitable for action-style commands exposed by the settings module; the exact method value should be confirmed by the deployment side

5.5 Playback refresh and upgrade

MethodRequest params.vResponse params.vDescription
update_castnull, {"force": true}, or "updateAuth""OK"Refresh the program schedule and support forced refresh
updateDevicenull"OK"Refresh device information
installApp{"url": "...", "desc": "..."}"OK"Trigger package download and installation on the device, usually for Android terminals

Notes:

  • The most common usage of update_cast is null or {"force": true}
  • installApp only starts the installation flow; final success still depends on the device platform, download URL, and installation permissions

5.6 Advanced editing commands

MethodRequest params.vResponse params.vDescription
editCastProgram JSON or patch JSONtrueModify program content remotely
editMediaMedia patch JSONtrueModify parameters of a specific media item inside a program remotely

Notes:

  • These two commands directly modify program data
  • editCast supports full overwrite and also a recursive patch mode with editMode = "patch"
  • editMedia depends on the internal media structure of the program and usually requires an accurate eid or target program context
  • These two commands are recommended only for deep integrations and are not recommended as the base capability of a general central control protocol

6. Reserved / internal commands

The following constants exist in the code, but are currently not recommended as public stable interfaces for third parties:

  • getDeviceSelf
  • getMHCastRelationList
  • postAttrs
  • lanAuth
  • jumpTo
  • mhtRpc
  • sync
  • deleteDeviceBySelf
  • postSyncInfo

Common reasons include:

  • They are only used by internal device-side flows or debug flows
  • Their parameter structure is tightly coupled to internal implementation
  • They are more likely to change in the future and are not suitable as a stable commitment for a third-party central control protocol

7. Call examples

7.1 Query device status through cloud RPC

bash
curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getPlayerStatus",
    "params": {
      "t": "q",
      "idx": 1,
      "p": null,
      "v": null
    }
  }'

Example response:

json
{
  "method": "getPlayerStatus",
  "params": {
    "t": "s",
    "idx": 1,
    "p": null,
    "v": {
      "ver": "1.2.3",
      "info": "Device-A / Android",
      "curTs": 1775179200000,
      "taskLen": 6,
      "httpServerInfo": {
        "state": 1,
        "localAddr": "http://192.168.1.120:9393"
      }
    }
  }
}

7.2 Send a back key through cloud RPC

bash
curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "remoter",
    "params": {
      "t": "q",
      "idx": 2,
      "p": null,
      "v": "back"
    }
  }'

7.3 Get a screenshot through cloud RPC

bash
curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getScreenshot",
    "params": {
      "t": "q",
      "idx": 3,
      "p": null,
      "v": 49000
    }
  }'

If successful, params.v contains a Base64 image string.

7.4 Get logs through cloud RPC with keyword filtering

bash
curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "getLog",
    "params": {
      "t": "q",
      "idx": 4,
      "p": null,
      "v": {
        "count": 100,
        "textSearch": "error"
      }
    }
  }'

7.5 Modify settings through cloud RPC

bash
curl -X POST "https://api.example.com:9292/api/rpc/twoway/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <jwt>" \
  -d '{
    "method": "setSettings",
    "params": {
      "t": "q",
      "idx": 5,
      "p": null,
      "v": {
        "debugMode": 1,
        "httpServerEnable": true
      }
    }
  }'

7.6 Log in over LAN and call device HTTP RPC

Log in first:

bash
curl -X POST "http://192.168.1.100:9393/api/nauth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "your-local-password"
  }'

Then call the RPC:

bash
curl -X POST "http://192.168.1.100:9393/api/device/rpc/11111111-2222-3333-4444-555555555555" \
  -H "Content-Type: application/json" \
  -H "X-Authorization: Bearer <token>" \
  -d '{
    "method": "ping",
    "params": {
      "t": "q",
      "idx": 6,
      "p": null,
      "v": null
    }
  }'

7.7 Send ping over UDP direct control

Send a UDP datagram to the device, for example 192.168.1.120:9393, with this payload:

json
{
  "method": "ping",
  "params": {
    "t": "q",
    "idx": 1001,
    "p": null,
    "v": null
  }
}

Example response:

json
{
  "method": "ping",
  "params": {
    "t": "s",
    "idx": 1001,
    "p": null,
    "v": "pong"
  }
}

7.8 Send a back key over UDP direct control

Example payload sent to 192.168.1.120:9393:

json
{
  "method": "remoter",
  "params": {
    "t": "q",
    "idx": 1002,
    "p": null,
    "v": "back"
  }
}

7.9 Query device status over UDP direct control

Example payload sent to 192.168.1.120:9393:

json
{
  "method": "getPlayerStatus",
  "params": {
    "t": "q",
    "idx": 1003,
    "p": null,
    "v": null
  }
}

8. Optional one-way batch broadcast

If a third-party platform needs to broadcast the same command to a group of devices, it can use the extended interfaces provided by the Admin End.

Supported endpoints:

  • POST https://api.example.com:9292/api/mht/oneway/device/ids?ids=<id1>,<id2>
  • POST https://api.example.com:9292/api/mht/oneway/asset/ids?ids=<assetId1>,<assetId2>
  • POST https://api.example.com:9292/api/mht/oneway/customer/ids?ids=<customerId1>,<customerId2>
  • POST https://api.example.com:9292/api/mht/oneway/tenant

Notes:

  • The request body is still the same RpcCmd JSON
  • These interfaces are one-way broadcasts and do not return a business result for each device
  • They are suitable for batch triggering update_cast, refreshing status, or sending simple control commands

9. Recommendations for third-party integration

  1. For third-party central control, prefer UDP direct control
  2. For device status queries, prefer getPlayerStatus
  3. For central control key events, prefer remoter
  4. For schedule refresh, prefer update_cast
  5. For screenshots and logs, prefer HTTP RPC

9.2 Stability recommendations

  • Include idx in every request to make logs and callbacks easier to reconcile
  • Treat params.t == "s" as the business success condition; do not rely only on HTTP 200
  • Use only the stable remoter key values listed in this document
  • Open editCast and editMedia only after joint debugging and verification
  • In cloud mode, prefer twoway so the caller can receive explicit feedback
  • Do not rely on UDP long term for large response payloads

9.3 Security recommendations

  • Do not store high-privilege JWTs in plain text in third-party systems for long periods
  • If only part of the devices need control, use an account with the minimum required permissions
  • Device installation and program editing commands should be covered by operation auditing
  • The UDP port should only be exposed inside a trusted LAN

10. Version note

This document is compiled based on the actual implementation of the current management side, device side, and local HTTP / UDP services in this repository.

If you need to integrate commands not listed here, confirm the target version and available scope with the deployment side first, and then proceed with joint debugging.