Define computed device parameters using custom JavaScript scripts.
Virtual parameters are user-defined parameters whose values are generated by a custom JavaScript script. They behave like regular parameters and appear in the device data model under the VirtualParameters. path. Virtual parameter names cannot contain a period (.).The execution environment for virtual parameter scripts is almost identical to that of provisions — the same built-in functions (declare, clear, commit, ext, log) are available.
Like a regular parameter, creating a virtual parameter does not automatically
add it to the parameter list for a device. It must be fetched (manually or via
a preset) before it appears in the device data model.
Virtual parameter scripts differ from provision scripts in two ways:1. The args variable has a different structure.Instead of holding preset arguments, args contains the declared and current timestamps and values for the parameter itself:
args[1] — declared attribute values (what the caller wants to set)
args[2] — current attribute timestamps
args[3] — current attribute values
2. The script must return a value.Virtual parameter scripts must return an object containing the attributes of the parameter, at minimum writable and value:
This virtual parameter exposes a single MACAddress regardless of whether the device uses the Device.* or InternetGatewayDevice.* data model.
// Example: Unified MAC parameter across different device modelslet m = "00:00:00:00:00:00";let d = declare("Device.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.MACAddress", {value: Date.now()});let igd = declare("InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANPPPConnection.*.MACAddress", {value: Date.now()});if (d.size) { for (let p of d) { if (p.value[0]) { m = p.value[0]; break; } } }else if (igd.size) { for (let p of igd) { if (p.value[0]) { m = p.value[0]; break; } } }return {writable: false, value: [m, "xsd:string"]};
Expose an external value as a virtual parameter
This virtual parameter reads from and writes to an external data store via an extension script. When a new value is declared, it is persisted externally and returned; otherwise the current external value is fetched and returned.
// Example: Expose an external value as a virtual parameterlet serial = declare("DeviceID.SerialNumber", {value: 1});if (args[1].value) { ext("example-ext", "set", serial.value[0], args[1].value[0]); return {writable: true, value: [args[1].value[0], "xsd:string"]};}else { let v = ext("example-ext", "get", serial.value[0]); return {writable: true, value: [v, "xsd:string"]};}
Editable virtual parameter for WPA passphrase
This virtual parameter provides a single writable interface for the WPA passphrase, abstracting over both the Device.* and InternetGatewayDevice.* data model paths.
// Example: Create an editable virtual parameter for WPA passphraselet m = "";if (args[1].value) { m = args[1].value[0]; declare("Device.WiFi.AccessPoint.1.Security.KeyPassphrase", null, {value: m}); declare("InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.KeyPassphrase", null, {value: m});}else { let d = declare("Device.WiFi.AccessPoint.1.Security.KeyPassphrase", {value: Date.now()}); let igd = declare("InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.KeyPassphrase", {value: Date.now()}); if (d.size) { m = d.value[0]; } else if (igd.size) { m = igd.value[0]; }}return {writable: true, value: [m, "xsd:string"]};