JavaScript for HTTP Integration
This document introduces how to add HTTP devices and function points as well as their parsing methods in Aqara Studio using JavaScript scripts.
Script Introduction
The script usually involves the following 9 functions. Implement them according to device capabilities. For static devices or static point lists, the corresponding build*Request functions may return null or an empty object.
| Function | Description |
|---|---|
| buildDiscoveryRequest | Builds the request message used to discover devices. |
| parseDiscoveryResponse | Parses the response message returned from device discovery. |
| buildDiscoverPointsRequest | Builds the request message used to query device point information. |
| parseDiscoverPointsResponse | Parses the response message for device point information and returns detailed point definitions. |
| buildReadRequest | Builds the request message used to read device point data. |
| parseReadResponse | Parses the response message for reading point data and returns point values. |
| buildWriteRequest | Builds the request message used to write device point data. |
| parseWriteResponse | Parses the response message for writing point data and returns whether the write succeeded. |
| parseReportRequest | Parses device-reported messages and extracts the device ID, point IDs, point values, and related data. |
Please do not modify the function names or parameters.
Script Global Variables
A protocol script can use globalThis.studioScriptState to share a small amount of temporary state between multiple function calls in the same Context. This variable is initialized as an empty object by default:
globalThis.studioScriptState = {
requestCount: 0,
lastValue: null
};
Keep this variable as a plain object. Its properties may contain strings, finite numbers, booleans, null, plain objects, and arrays, including nested combinations of those types. Convert dates to strings first. Do not store undefined, functions, Symbol, BigInt, NaN, Infinity, circular references, Map, Set, Java/host objects, or custom class instances; such values may be ignored, lose information, or cause serialization failures.
State size is measured by the serialized UTF-8 JSON byte length. The warning threshold is 2 MiB. Studio performs a rate-limited check after script calls. When the state first exceeds the threshold, Studio writes one [warn] entry to both the service log and Console Content on the protocol configuration page. Repeated overflow does not produce periodic warnings, does not delete the state automatically, and does not terminate the current call. Keep this variable below 2 MiB during normal development and operation.
globalThis.studioScriptState is reinitialized after idle Context reclamation, memory-pressure reclamation, script updates, or execution timeouts. Do not use it for durable device state, credentials, or an unbounded history of messages.
Prerequisites
Before writing the script, make sure you fully understand the following HTTP interfaces of the target device, including but not limited to the request path, request method, request headers, request parameters, and response data structure. Focus especially on:
- Device discovery interface
- Function point query interface
- Function point data read interface
- Function point data write interface
- Function point data reporting interface
Only by thoroughly understanding the interfaces above can you ensure that your JavaScript script correctly integrates with the HTTP protocol according to the device specification and parses data properly.
buildDiscoveryRequest
Return a request configuration object in this function to tell Aqara Studio how to discover devices through the HTTP API.
Parameter Description
It is recommended that this function have no parameters.
Return Value
To ensure Aqara Studio can successfully send the request, make sure buildDiscoveryRequest returns data in the following format:
{
"path": "/report/discoveryDevices",
"method": "POST",
"headers": "{\"Content-Type\":\"application/json\"}",
"postParams": "{\"appId\":\"V0001\"}"
}
Field descriptions:
| Field | Type | Description |
|---|---|---|
| path | String | Request path. Specifies the device discovery endpoint, for example /report/discoveryDevices.If method is GET and includes parameters, you can append them directly to path, for example /discoveryDevices?channel=1. |
| method | String | HTTP request method. Supports GET and POST. |
| headers | String | Request headers, in JSON string format (for example, {"Content-Type":"application/json"}). |
| postParams | String | POST request body parameters, in JSON string format (for example, {"appId":"V0001"}). |
Please consult the device's official technical documentation or contact technical support to obtain the correct values for path, method, headers, and postParams.
Function Example
function buildDiscoveryRequest() {
return {
path: "/report/discoveryDevices",
method: "POST",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: JSON.stringify({
"appId": "V0001"
})
};
}
parseDiscoveryResponse
Parse the device discovery response in this function and return an array of device objects that contains the device ID (deviceId) and device name (deviceName) for Aqara Studio to use.
Parameter Description
It is recommended that this function accept only one string parameter, which is the response returned by the device discovery request.
Return Value
To ensure Aqara Studio can successfully obtain device information, make sure parseDiscoveryResponse returns data in the following format:
[
{
"deviceId": "123456",
"deviceName": "Temperature Sensor"
}
]
Function Example
Assume the device discovery API returns data like this:
{
"reply": {
"data": {
"meta": {
"limit": 10,
"offset": 0
},
"list": [
{
"deviceId": "123456",
"deviceName": "test1",
"ip": "127.0.0.1",
"createTime": "qwerasd"
}
]
},
"returnCode": {
"type": "S",
"code": "AAAAA",
"domain": null
}
}
}
To handle the data above, you can design the function like this:
function parseDiscoveryResponse(responseString) {
if (!responseString) return [];
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return [];
}
const list = obj?.reply?.data?.list;
if (!Array.isArray(list)) return [];
// Return an array. Each element contains deviceId and deviceName.
return list.map(item => ({
deviceId: item.deviceId,
deviceName: item.deviceName
}));
}
buildDiscoverPointsRequest
Return a request configuration object in this function to tell Aqara Studio how to query the function points (points) of the specified device through the HTTP API. If this function returns null, an empty object, or an object without a path field, the platform does not send an HTTP request and directly calls parseDiscoverPointsResponse().
Parameter Description
It is recommended that this function accept only one string parameter, which is the target device ID.
Return Value
To ensure Aqara Studio can successfully send the request, make sure buildDiscoverPointsRequest returns data in the following format:
{
"path": "/device/points?deviceId=123456",
"method": "GET",
"headers": "{\"Content-Type\":\"application/json\"}",
"postParams": "{\"deviceId\":\"123456\"}"
}
Field descriptions:
| Field | Type | Description |
|---|---|---|
| path | String | Request path. Specifies the endpoint used to query device function points. If method is GET and includes parameters, you can append them directly to path, for example /device/points?deviceId=xxx. |
| method | String | HTTP request method. Supports GET and POST. |
| headers | String | Request headers, in JSON string format (for example, {"Content-Type":"application/json"}). |
| postParams | String | POST request body parameters, in JSON string format (for example, {"deviceId":"123456"}). |
Please consult the device's official technical documentation or contact technical support to obtain the correct values for path, method, headers, and postParams.
Function Example
function buildDiscoverPointsRequest(deviceId) {
return {
path: `/device/points?deviceId=${deviceId}`,
method: "GET",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: ""
};
}
parseDiscoverPointsResponse
Parse the function point discovery response in this function and return an array containing all function point information.
Aqara Studio automatically calls this function. You need to fill in the detailed structure of each function point in the returned array, such as pointId and pointName. For details, see Point Object Structure.
Only by implementing this function correctly can Aqara Studio recognize and access all function points supported by the device, enabling automatic discovery and control.
Parameter Description
It is recommended that this function accept only one string parameter, which is the response returned by the function point discovery request.
Return Value
To ensure Aqara Studio can successfully obtain function point information, make sure parseDiscoverPointsResponse returns an array of Point Object Structure.
Point Object Structure
| Field Name | Required | Description |
|---|---|---|
| pointId | Required | Function point ID. Please consult the device manufacturer to obtain the actual ID so Aqara Studio can discover the point. |
| pointName | Required | A custom function point name defined by you. |
| devType | Conditionally required | Corresponds to deviceType in the Aqara data model specification. Fill this in when defining a point based on Aqara Spec. For available values, see Device Types. |
| functionCode | Conditionally required | Corresponds to functionCode in the Aqara data model specification. Fill this in when defining a point based on Aqara Spec. For available values, see Function Codes. |
| traitCode | Conditionally required | Corresponds to traitCode in the Aqara data model specification. Fill this in when defining a point based on Aqara Spec. For available values, see Trait Codes. |
| dataType | Conditionally required | Required for general function points. Supported values are:
|
| enumRange | Conditionally required | An array of enumeration options. Required only when the general function point uses dataType: "enum". The array must not be empty. Each item must contain an integer value and a string label. Both value and label must be unique, and label must not be empty. |
| trueText / falseText | Optional | Display labels for a general Boolean function point. Effective only when dataType is bool / boolean. If not configured, trueText defaults to On and falseText defaults to Off. Configure them only when you need custom labels such as Enabled / Disabled. You can also use activeText / onText and inactiveText / offText as aliases. |
| min | Optional | Minimum value for a general numeric function point. Effective only when dataType is numerical / number. minimum can also be used as an alias. |
| max | Optional | Maximum value for a general numeric function point. Effective only when dataType is numerical / number. maximum can also be used as an alias. |
| step | Optional | Step value for a general numeric function point. It must be greater than 0. Effective only when dataType is numerical / number. resolution can also be used as an alias. |
| precision | Optional | Precision value for a general numeric function point. It must be greater than or equal to 0. Effective only when dataType is numerical / number. |
| decimals | Optional | Number of decimal places for a general numeric function point. It must be an integer greater than or equal to 0. Effective only when dataType is numerical / number. |
| unit / units | Optional | Unit for a general numeric function point. Effective only when dataType is numerical / number. Use a registered unit name such as kilowatt hour, watt, volt, ampere, celsius, or percent. Studio shows the corresponding symbol, such as kWh, W, V, A, °C, or %. For the full mapping, see Unit Names and Symbols Supported by Scripts. The system can also match registered unit symbols. |
| access | Conditionally required | Required for general function points. Access mode:
|
For numerical / number points, when Aqara Studio calls buildWriteRequest, it formats the write value by decimals first. If decimals is not configured, it infers the number of decimal places from step / resolution. To avoid binary floating-point artifacts such as 0.30000030249357224, explicitly configure decimals or step for points that write fractional values. precision only describes precision and is not used as the decimal-place truncation rule for outgoing write payloads.
If a numeric point is used by energy statistics or other unit-dependent features, configure unit or units. For example, use kilowatt hour (displayed as kWh) for accumulated energy, watt (W) for current power, volt (V) for voltage, ampere (A) for current, and celsius (°C) for temperature. Enter unit names exactly as shown in Unit Names and Symbols Supported by Scripts, including case and spaces.
You can choose either of the following approaches to define function points according to your scenario:
- Based on Aqara Spec: Fill in fields such as
devType,functionCode, andtraitCodeto map the device point to the corresponding point in Aqara Spec. - General approach: Fill in the basic fields such as
dataTypeandaccess.
Examples
To ensure Aqara Studio can successfully obtain function point information, make sure parseDiscoverPointsResponse returns data in one of the following formats:
-
Based on Aqara Spec:
[
{
"pointId": "temperature",
"pointName": "Temperature",
"devType": "TemperatureSensor",
"functionCode": "Temperature",
"traitCode": "CurrentTemperature"
}
] -
General approach:
[
{
"pointId": "temperature",
"pointName": "Temperature",
"dataType": "numerical",
"min": -20,
"max": 50,
"step": 0.1,
"precision": 0.1,
"decimals": 1,
"unit": "celsius",
"access": "1"
},
{
"pointId": "mode",
"pointName": "Operating Mode",
"dataType": "enum",
"enumRange": [
{ "value": 0, "label": "Off" },
{ "value": 1, "label": "Auto" }
],
"access": "2"
}
]
Function Example
function parseDiscoverPointsResponse(responseString) {
if (!responseString) return [];
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return [];
}
const list = obj?.reply?.data?.points;
if (!Array.isArray(list)) return [];
return list.map(item => ({
pointId: item.pointId,
pointName: item.pointName,
devType: item.devType,
functionCode: item.functionCode,
traitCode: item.traitCode
}));
}
buildReadRequest
When Aqara Studio needs to obtain device status data such as switch state, temperature, or mode, it calls this function with the target device ID (deviceId) and the single function point ID (pointId) to read.
Return a request configuration object in this function to tell Aqara Studio how to query the value of the specified device point through the HTTP API.
Parameter Description
It is recommended that this function accept two string parameters for the device ID and point ID.
Return Value
To ensure Aqara Studio can successfully obtain function point information, make sure buildReadRequest returns data in the following format:
{
"path": "/device/read/temperature",
"method": "GET",
"headers": "",
"postParams": ""
}
The current implementation calls this function one point at a time. The second parameter is pointId, and the return value is a single request object.
Field descriptions:
| Field | Type | Description |
|---|---|---|
| path | String | Request path. Specifies the endpoint used to query the device point. If method is GET and includes parameters, you can append them directly to path. |
| method | String | HTTP request method. Supports GET and POST. |
| headers | String | Request headers, in JSON string format (for example, {"Content-Type":"application/json"}). |
| postParams | String | POST request body parameters, in JSON string format (for example, {"deviceId":"123456"}). |
Please consult the device's official technical documentation or contact technical support to obtain the correct values for path, method, headers, and postParams.
Function Example
function buildReadRequest(deviceId, pointId) {
if (!deviceId || !pointId) return {};
return {
path: `/device/read/${deviceId}/${pointId}`,
method: "GET",
headers: "",
postParams: ""
};
}
parseReadResponse
This function is used to parse the response from a point read request.
Convert the raw data returned by the device into the function point data format that Aqara Studio can recognize.
Parameter Description
It is recommended that this function accept two string parameters for the device ID and HTTP response string.
Return Value
To ensure Aqara Studio can correctly obtain point data, make sure parseReadResponse returns data in the following format:
{
"temperature": "22.5",
"humidity": "60"
}
Field description: each key represents a function point, and the corresponding value is the point value, always as a string.
Function Example
function parseReadResponse(deviceId, responseString) {
if (!responseString) return {};
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return {};
}
const result = {};
if (obj.data && Array.isArray(obj.data)) {
obj.data.forEach(item => {
for (const key in item) {
if (Object.prototype.hasOwnProperty.call(item, key)) {
result[key] = String(item[key]);
}
}
});
}
return result;
}
buildWriteRequest
When you control a device point such as a switch, temperature, or mode in Aqara Studio, Aqara Studio calls this function and passes in the target device ID (deviceId), the point ID to control (pointId), and the target value to set (value).
Return a request configuration object in this function to tell Aqara Studio how to send the control command to the device through the HTTP API.
Parameter Description
It is recommended that this function accept three string parameters for the device ID, point ID, and point value.
Return Value
To ensure Aqara Studio can successfully control the point, make sure buildWriteRequest returns data in the following format:
{
"path": "/device/write/temperature",
"method": "POST",
"headers": "",
"postParams": "{\"value\":22.5}"
}
Field descriptions:
| Field | Type | Description |
|---|---|---|
| path | String | Request path. Specifies the endpoint used to write the device point. If method is GET and includes parameters, you can append them directly to path. |
| method | String | HTTP request method. Supports GET and POST. |
| headers | String | Request headers, in JSON string format (for example, {"Content-Type":"application/json"}). |
| postParams | String | POST request body parameters, in JSON string format (for example, {"value":22.5}). |
Please consult the device's official technical documentation or contact technical support to obtain the correct values for path, method, headers, and postParams.
Function Example
function buildWriteRequest(deviceId, pointId, value) {
if (!deviceId || !pointId) return {};
return {
path: `/device/write/${deviceId}/${pointId}`,
method: "POST",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: JSON.stringify({ value: value })
};
}
parseWriteResponse
This function is used to parse the response from the point write request and determine whether the device executed the control command successfully.
When Aqara Studio sends a write request to the device, such as turning a device on or off or adjusting temperature, and receives the device response, it calls this function and determines whether the control succeeded according to the return value.
Parse the device response in this function and convert the result to a Boolean value so Aqara Studio can determine whether the control command was executed successfully.
Parameter Description
It is recommended that this function accept two string parameters for the point ID and the response returned by the point write request.
Return Value
Make sure the function returns a Boolean value:
true: The point write succeeded.false: The point write failed or the device returned an abnormal result.
Function Example
function parseWriteResponse(pointId, responseString) {
if (!responseString) return false;
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return false;
}
return obj.result === "success";
}
parseReportRequest
When the device actively reports data to Aqara Studio, for example after a device status change or a sensor report, Aqara Studio calls this function to extract the device ID and point data from the reported payload and update device status. Each HTTP report request calls this function only once, and all point values in the request are returned together through the points array.
Convert the raw device report data into the function point data format that Aqara Studio can recognize.
Prerequisites
Make sure the device reports data to Aqara Studio according to the following endpoint, method, and request body requirements:
- Endpoint:
http://{ip}:8000/report/data - Request method:
POST - Request body: You may define this yourself, as long as parseReportRequest can parse the request and extract the required return fields, namely
deviceIdandpoints.
Parameter Description
It is recommended that this function accept two string parameters:
- The first parameter is the endpoint used by Aqara Studio to receive device data, namely
http://{ip}:8000/report/data. - The second parameter is the request body of the device report.
Please keep the parameter names and order correct so Aqara Studio can accurately identify and process device report data for the specified path.
Return Value
The return value should contain the following three fields:
| Field | Type | Description |
|---|---|---|
| deviceId | String | Device ID used to identify which device the current data belongs to. |
| points | List<Map<String, String>> | A list of point data. Each point is a Map containing:
|
| responseMsg | String | Response message used to tell the device whether Aqara Studio received the data successfully. |
To ensure Aqara Studio can correctly obtain point data, make sure parseReportRequest returns data in the following format:
{
"deviceId": "123456",
"points": [
{
"pointId": "temperature",
"value": "22.5"
}
],
"responseMsg": ""
}
Function Example
function parseReportRequest(path, requestString) {
if (!requestString) return { deviceId: "", points: [], responseMsg: "" };
let obj;
try {
obj = JSON.parse(requestString);
} catch (e) {
return { deviceId: "", points: [], responseMsg: "" };
}
const deviceId = obj.deviceld || obj.deviceId || "";
const points = [];
const parans = obj.data && obj.data.parans ? obj.data.parans : {};
for (const pointId in parans) {
if (Object.prototype.hasOwnProperty.call(parans, pointId)) {
const item = parans[pointId];
points.push({
pointId: pointId,
value: String(item.value)
});
}
}
return { deviceId: deviceId, points: points, responseMsg: "" };
}
Complete Example
The following code covers examples of the 9 functions above. Adjust and optimize it according to the actual interfaces and data formats of your device. Do not copy it directly without modification.
The globalThis registrations in the example are dynamic: register only the functions you actually implement. Functions you do not implement do not need to be registered.
(function(){
// Store only JSON-serializable temporary state. It is cleared after the Context is rebuilt.
const scriptState = globalThis.studioScriptState;
scriptState.reportCount = 0;
scriptState.lastReportAt = null;
function buildDiscoveryRequest() {
return {
path: "/report/discoveryDevices",
method: "POST",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: JSON.stringify({
"appId": "V0001"
})
};
}
function parseDiscoveryResponse(responseString) {
if (!responseString) return [];
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return [];
}
const list = obj?.reply?.data?.list;
if (!Array.isArray(list)) return [];
// Return an array. Each element contains deviceId and deviceName.
return list.map(item => ({
deviceId: item.deviceId,
deviceName: item.deviceName
}));
}
function buildDiscoverPointsRequest(deviceId) {
return {
path: `/device/points?deviceId=${deviceId}`,
method: "GET",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: ""
};
}
function parseDiscoverPointsResponse(responseString) {
if (!responseString) return [];
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return [];
}
const list = obj?.reply?.data?.points;
if (!Array.isArray(list)) return [];
return list.map(item => ({
pointId: item.pointId,
pointName: item.pointName,
devType: item.devType,
functionCode: item.functionCode,
traitCode: item.traitCode
}));
}
function buildReadRequest(deviceId, pointId) {
if (!deviceId || !pointId) return {};
return {
path: `/device/read/${deviceId}/${pointId}`,
method: "GET",
headers: "",
postParams: ""
};
}
function parseReadResponse(deviceId, responseString) {
if (!responseString) return {};
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return {};
}
const result = {};
if (obj.data && Array.isArray(obj.data)) {
obj.data.forEach(item => {
for (const key in item) {
if (Object.prototype.hasOwnProperty.call(item, key)) {
result[key] = String(item[key]);
}
}
});
}
return result;
}
function buildWriteRequest(deviceId, pointId, value) {
if (!deviceId || !pointId) return {};
return {
path: `/device/write/${deviceId}/${pointId}`,
method: "POST",
headers: JSON.stringify({
"Content-Type": "application/json"
}),
postParams: JSON.stringify({ value: value })
};
}
function parseWriteResponse(pointId, responseString) {
if (!responseString) return false;
let obj;
try {
obj = JSON.parse(responseString);
} catch (e) {
return false;
}
return obj.result === "success";
}
function parseReportRequest(path, requestString) {
scriptState.reportCount += 1;
scriptState.lastReportAt = new Date().toISOString();
if (!requestString) return { deviceId: "", points: [], responseMsg: "" };
let obj;
try {
obj = JSON.parse(requestString);
} catch (e) {
return { deviceId: "", points: [], responseMsg: "" };
}
const deviceId = obj.deviceld || obj.deviceId || "";
const points = [];
const parans = obj.data && obj.data.parans ? obj.data.parans : {};
for (const pointId in parans) {
if (Object.prototype.hasOwnProperty.call(parans, pointId)) {
const item = parans[pointId];
points.push({
pointId: pointId,
value: String(item.value)
});
}
}
return { deviceId: deviceId, points: points, responseMsg: "" };
}
globalThis.buildDiscoveryRequest = buildDiscoveryRequest;
globalThis.parseDiscoveryResponse = parseDiscoveryResponse;
globalThis.buildDiscoverPointsRequest = buildDiscoverPointsRequest;
globalThis.parseDiscoverPointsResponse = parseDiscoverPointsResponse;
globalThis.buildReadRequest = buildReadRequest;
globalThis.parseReadResponse = parseReadResponse;
globalThis.buildWriteRequest = buildWriteRequest;
globalThis.parseWriteResponse = parseWriteResponse;
globalThis.parseReportRequest = parseReportRequest;
})()
Troubleshooting Script Issues
After you finish developing the script, if Aqara Studio still cannot discover devices or function points, use the following steps to check whether the script is working correctly:
- Use Console Logging to verify whether each method in the script is being called as expected.
- Review Script Checklist and check each item against Aqara Studio's validation rules.
- If the issue still cannot be resolved, it may be related to Aqara Studio's Runtime Resource Limits.
Console Logging
-
To debug and troubleshoot script methods such as
parseDiscoveryResponseandparseDiscoverPointsResponse, you can add any of the following console logging methods anywhere inside a function:console.logconsole.infoconsole.debugconsole.warnconsole.error
tipDo not print logs unconditionally inside loops or high-frequency message handlers. Use conditional switches or sampled logging during debugging.
Example:
function parseDiscoveryResponse() {
console.info("Start parsing discovery response", arguments);
return [
{
deviceName: "xxx",
// ...
}
];
}tip- When multiple arguments are passed, the log output joins them with spaces.
- Output from
console.warnandconsole.errorincludes the[warn]and[error]prefixes respectively.
-
Run the related action again in Aqara Studio, such as device discovery, point discovery, point read, point write, or report handling, to trigger the method that contains logs.
-
Open the HTTP protocol configuration page and check whether the
Console Contentfield contains log output:- If logs appear correctly, the method has been integrated successfully.
- If no logs appear, check whether the method implementation is incorrect.
tipConsole Contentkeeps at most 2048 characters. When the limit is exceeded, older content is replaced.- Each script parser accepts at most 20 log entries per second. Excess logs are ignored and summarized in the next time window.
- Each log entry keeps at most 512 characters and converts only the first 16 arguments.
Script Checklist
It is recommended that you review the script item by item according to the validation flow of each Aqara Studio business node so all key checks pass and the script remains reliable and compatible.
| Business node | Called function | Main validation |
|---|---|---|
| Script loading | Complete script | The script must not exceed 1,048,576 characters and must be executable by the JavaScript engine. Whether each business function exists and is callable is checked again when it is actually invoked. |
| Device discovery | buildDiscoveryRequest() / parseDiscoveryResponse(response) | The request function may be omitted or return an empty value. A non-empty result must be convertible to an HTTP request configuration. The discovery result must be an array. At most 128 devices are processed in a single call, and device information is validated item by item. |
| Point discovery | buildDiscoverPointsRequest(deviceId) / parseDiscoverPointsResponse(deviceId, response) | The UTF-8 response must not exceed 256 KiB. The discovery result must be an array. At most 512 points are processed in a single call, and each point structure is validated item by item. |
| Point read and write | buildReadRequest / parseReadResponse / buildWriteRequest / parseWriteResponse | The request result must be convertible to an HTTP request configuration. The response must not exceed 256 KiB. The parsed result must contain recognizable point IDs and values. |
| Active device report | parseReportRequest(path, requestString) | The UTF-8 request body must not exceed 256 KiB. The return value must contain deviceId and a points array. At most 512 items are processed in a single call, and each item's pointId and value are validated. |
Runtime Resource Limits
- A single HTTP response or report request body passed to JavaScript must not exceed 256 KiB when encoded as UTF-8. Oversized data is not passed to JavaScript, and oversized report requests return HTTP
413. - A single device discovery call processes at most 128 devices, and a single point discovery call processes at most 512 points. Additional entries are ignored.
- A single HTTP active report request processes at most 512 point values. Additional entries are ignored.
- A script Context may be reclaimed after a long idle period or when the system is under memory pressure, and it is rebuilt on the next call. Do not rely on global variables to permanently store device state. Durable state should be stored on the device or in Studio function points.
- A script call may be rejected when the execution queue is full or system memory pressure is high. Active device reports should support reasonable retries or later full-state resubmission.