Published using Google Docs
InDriver Manual
Updated automatically every 5 minutes

InDriver Manual

inanalytics.io

last modification: 2026/06/11

InAnalytics Data Platform

Real-time analytics, reporting, simulations, forecasting  and data automation

Turn your industrial and business data into cost savings, operational control and deep visibility across your processes

InDriver Manual

InAnalytics Data Platform        1

Real-time analytics, reporting, simulations, forecasting  and data automation        1

Turn your industrial and business data into cost savings, operational control and deep visibility across your processes        1

Innovative Data Analytics        11

Introduction to InDriver        12

Getting started - download, installation, requirements        12

Installation        13

Launching InDriver        14

License        14

Setup        18

InDriver first steps        23

Features and examples        26

InDriver JS Tasks        27

Recommended coding rules (AI)        30

InDriver API        37

InDriver.configuration        37

InDriver.currentPath        38

InDriver.debug        39

InDriver.debugVariables        41

InDriver.driverName        41

InDriver.hooks        42

InDriver.hookTs        43

InDriver.hookMs        43

InDriver.import        44

InDriver.installExtensions        45

InDriver.installHook        47

InDriver.isHook        48

InDriver.isPrivateMessage // depreciated        49

InDriver.isLoopbackMessage()        49

InDriver.loadScript        50

InDriver.messageData        50

InDriver.messageSender        51

InDriver.messageTags        51

InDriver.messageTs        52

InDriver.msleep        52

InDriver.onHook        53

InDriver.restartTask        54

InDriver.sendMessage        55

InDriver.setFlag        56

InDriver.shutdown        57

InDriver.sleep        57

InDriver.sqlExecute        58

InDriver.sqlExecuteAll        60

InDriver.sqlIsSucceeded        61

InDriver.sqlLastError        62

InDriver.sqlReopen        63

InDriver.taskName        63

InDriver.systemCpuUsage        64

InDriver.systemProcessMemory        65

InDriver.systemProcessMemoryAll        66

InDriver.systemMemory        68

InDriver.systemSnapshot        69

InDriver.uninstallHook        70

InDriver.updateStatistics        70

HttpServerApi        72

HttpServerApi.debugMode        72

HttpServerApi.listen        73

address        73

port        74

HttpServerApi.route        75

HttpServerApi.setCorsHeaders        79

CryptographicHashAPI        82

Supported algorithms        82

CryptographicHashApi.addData        83

CryptographicHashApi.addDataUtf8        84

CryptographicHashApi.algorithm        84

CryptographicHashApi.algorithms        85

CryptographicHashApi.hash        86

CryptographicHashApi.hashHex        86

CryptographicHashApi.hashHexUtf8        87

CryptographicHashApi.hashUtf8        88

CryptographicHashApi.isSupported        89

CryptographicHashApi.reset        89

CryptographicHashApi.result        90

CryptographicHashApi.resultHex        91

CryptographicHashApi.setAlgorithm        91

OPCUPClientApi        94

OPCUAClientApi.browse        94

OPCUAClientApi.connect        96

OPCUAClientApi.disconnect        98

OPCUAClientApi.isConnected        99

OPCUAClientApi.lastError        100

OPCUAClientApi.readMultipleNodes        100

OPCUAClientApi.runIterate        102

OPCUAClientApi.writeMultipleNodes        103

OPCUPServerApi        106

OPCUAServerApi.addNodes        106

OPCUAServerApi.lastError        107

OPCUAServerApi.readMultipleNodes        108

OPCUAServerApi.start        109

OPCUAServerApi.stop        111

OPCUAServerApi.writeMultipleNodes        111

RestApi        114

RestApi.begin        114

RestApi.commit        115

RestApi.commitWait        116

RestApi.defineRequest        117

RestApi.getData        131

RestApi.getRawHeader        132

RestApi.getRawHeaderPairs        132

RestApi.isSucceeded        133

RestApi.sendRequest        134

RestApi.wait        137

ModbusApi        142

ModbusApi.begin        142

ModbusApi.commit        143

ModbusApi.commitWait        144

ModbusApi.connectDevice        144

ModbusApi.getAllData        147

ModbusApi.getDeviceData        148

ModbusApi.getDeviceRequestData        149

ModbusApi.getDeviceRequestValue        149

ModbusApi.isLastTransactionCompleted        151

ModbusApi.isSucceeded        152

ModbusApi.readDevice        152

ModbusApi.wait        154

ModbusApi.writeDevice        155

DeviceAPI        159

DeviceAPI.begin        159

DeviceAPI.commit        160

DeviceAPI.commitWait        160

DeviceAPI.debugModeEnabled        161

DeviceAPI.execute        162

DeviceAPI.getDeviceData        163

DeviceAPI.getStatistics        164

DeviceAPI.waitForDevices        164

MbusAPI        166

MbusAPI.exec        166

MbusAPI.receive        168

ModbusAPI        169

ModbusAPI.exec        169

ModbusAPI.receive        170

Device libraries        171

AR252 library        172

CMK03 library        173

Multical Modbus library        173

MacREJ5R library        174

M-Bus device libraries        175

SMTPApi        180

SmtpApi.begin        180

SmtpApi.commit        181

SmtpApi.configure        182

SmtpApi.send        184

SmtpApi.lastError        186

TsApi        189

Standard TSAPI database model        189

tsapiinstall        192

tsapiuninstall        192

tsapiversion        193

tsapicreatetable        194

tsapicreateaggregationtable        195

tsapideletetable        195

tsapiinsert        196

tsapiinsertvalues        197

tsapiinsertagg        199

tsapiselectdistinctsources        200

tsapiselect        201

tsapiselectfirst        203

tsapiselectlast        203

tsapiselectlastn        204

tsapiselectprevious        206

tsapiselectagg        207

tsapiselectaggdata        208

tsapiselectaggwheretsin        209

tsapiselectvariablefromagg        211

Time Series JSON Data Aggregation        214

TsApi.aggregate        215

TsApi.defineAggregator        216

TsApi.setAggregatorDebugMode        221

TsApi.setAggregatorStepSize        222

ProcessApi        225

ProcessApi.start        225

ProcessApi.close        226

ProcessApi.closeAll        227

ProcessApi.kill        227

ProcessApi.killAll        227

ProcessApi.waitForStarted        228

ProcessApi.waitForFinished        228

ProcessApi.waitAllForStarted        229

ProcessApi.waitAllForFinished        229

ProcessApi.setWorkingDirectory        229

ProcessApi.workingDirectory        230

ProcessApi.program        230

ProcessApi.pid        230

ProcessApi.state        231

ProcessApi.status        231

ProcessApi.remove        231

PdfApi        234

PdfApi.load        234

PdfApi.isLoaded        235

PdfApi.pageText        236

PdfApi.readText        237

PdfApi.pageLabel        238

PdfApi.allPageLabels        239

PdfApi.setCodec        239

PdfApi.pageCount        240

PdfApi.setPassword        241

PdfApi.password        241

PdfApi.status        242

PdfApi.metadata        243

PdfApi.asImageBase64        243

PdfApi.savePageAsImage        244

PdfApi.close        245

FileApi        248

FileApi.addFileSystemWatcherPath        248

FileApi.appendLine        248

FileApi.close        249

FileApi.closeAll        249

FileApi.copy        250

FileApi.dirGoTo        250

FileApi.dirGoToApplicationDirectory        250

FileApi.dirGoToPath        251

FileApi.dirGoUp        251

FileApi.dirList        251

FileApi.dirLoadFiles        252

FileApi.dirFindFiles        252

FileApi.dirSaveFiles        261

FileApi.fileExists        261

FileApi.fileSize        262

FileApi.isOpen        262

FileApi.open        262

FileApi.readAll        263

FileApi.readAllBase64        263

FileApi.readLines        264

FileApi.removeFile        264

FileApi.removeFileSystemWatcherPath        264

FileApi.write        265

SerialPortApi        267

SerialPortApi.availablePorts        267

SerialPortApi.close        267

SerialPortApi.closeAll        268

SerialPortApi.flush        268

SerialPortApi.isOpen        268

SerialPortApi.open        269

SerialPortApi.read        270

SerialPortApi.readAll        270

SerialPortApi.readLine        271

SerialPortApi.setTimeout        271

SerialPortApi.write        271

TcpSocketApi        274

TcpSocketApi.acceptRead        274

TcpSocketApi.connect        275

TcpSocketApi.disconnect        277

TcpSocketApi.disconnectAll        277

TcpSocketApi.isBusy        278

TcpSocketApi.write        279

TcpSocketApi.writeAndWait        280

TcpSocketApi.onMessage behavior        282

TcpServerApi        284

TcpSocketApi.close        284

TcpServerApi.listen        286

TcpServerApi.write        287

TcpServerApi.onMessage behavior        289

UdpSocketApi        292

UdpSocketApi.acceptRead        292

UdpSocketApi.bind        293

UdpSocketApi.isBusy        294

UdpSocketApi.write        295

UdpSocketApi.writeAndWait        297

WebSocketApi        300

WebSocketApi.abort        300

WebSocketApi.acceptRead        300

WebSocketApi.close        301

WebSocketApi.connect        302

WebSocketApi.disconnect        303

WebSocketApi.disconnectAll        303

WebSocketApi.errorString        303

WebSocketApi.isBusy        303

WebSocketApi.isValid        304

WebSocketApi.ping        304

WebSocketApi.state        304

WebSocketApi.write        305

WebSocketApi.writeAndWait        305

WebSocketApi.writeBinary        306

WebSocketApi.writeBinaryAndWait        306

Rules        307

WebSocketServerApi        308

WebSocketServerApi.clientCount        308

WebSocketServerApi.clients        308

WebSocketServerApi.close        309

WebSocketServerApi.disconnectAllClients        309

WebSocketServerApi.disconnectClient        309

WebSocketServerApi.hasClient        310

WebSocketServerApi.isListening        310

WebSocketServerApi.listen        311

WebSocketServerApi.serverAddress        312

WebSocketServerApi.serverPort        312

WebSocketServerApi.write        312

WebSocketServerApi.writeAll        313

WebSocketServerApi.writeBinary        314

WebSocketServerApi.writeBinaryAll        314

Rules        316

XmlReaderApi        317

XmlReaderApi.addData        317

XmlReaderApi.addExtraNamespaceDeclaration        318

XmlReaderApi.atEnd        318

XmlReaderApi.attribute        319

XmlReaderApi.characterOffset        319

XmlReaderApi.clear        320

XmlReaderApi.close        320

XmlReaderApi.columnNumber        321

XmlReaderApi.documentEncoding        321

XmlReaderApi.documentVersion        321

XmlReaderApi.dtdName        322

XmlReaderApi.dtdPublicId        322

XmlReaderApi.dtdSystemId        322

XmlReaderApi.entityDeclarations        323

XmlReaderApi.entityExpansionLimit        323

XmlReaderApi.hasError        324

XmlReaderApi.hasStandaloneDeclaration        324

XmlReaderApi.isCDATA        325

XmlReaderApi.isCharacters        325

XmlReaderApi.isComment        325

XmlReaderApi.isDTD        326

XmlReaderApi.isEndDocument        326

XmlReaderApi.isEndElement        326

XmlReaderApi.isEntityReference        327

XmlReaderApi.isProcessingInstruction        327

XmlReaderApi.isStandaloneDocument        328

XmlReaderApi.isStartDocument        328

XmlReaderApi.isStartElement        328

XmlReaderApi.isWhitespace        329

XmlReaderApi.lastError        329

XmlReaderApi.lineNumber        329

XmlReaderApi.name        330

XmlReaderApi.namespaceProcessing        330

XmlReaderApi.namespaceUri        331

XmlReaderApi.open        331

XmlReaderApi.prefix        332

XmlReaderApi.processingInstructionData        332

XmlReaderApi.processingInstructionTarget        333

XmlReaderApi.qualifiedName        333

XmlReaderApi.readElementText        333

XmlReaderApi.readNext        334

XmlReaderApi.readNextStartElement        335

XmlReaderApi.setEntityExpansionLimit        335

XmlReaderApi.setNamespaceProcessing        336

XmlReaderApi.skipCurrentElement        337

XmlReaderApi.text        337

XmlReaderApi.tokenString        337

XmlReaderApi.tokenType        338

XlsxApi        341

XlsxApi.open        341

XlsxApi.close        342

XlsxApi.closeAll        343

XlsxApi.isOpen        343

XlsxApi.sheets        344

XlsxApi.selectSheet        345

XlsxApi.currentSheet        346

XlsxApi.dimension        346

XlsxApi.metadata        348

XlsxApi.read        348

XlsxApi.readA1        349

XlsxApi.exists        350

XlsxApi.existsA1        351

XlsxApi.cell        352

XlsxApi.row        353

XlsxApi.range        354

XlsxApi.table        355

XlsxApi.toObject        357

XlsxApi.findColumn        359

XlsxApi.write        360

XlsxApi.writeA1        361

XlsxApi.save        362

XlsxApi.saveAs        363

XlsxApi.lastError        363



Innovative Data Analytics

www.inanalytics.io

Innovative Data Analytics is a recently established IT company located in Kraków, Poland, founded by programmer and automation engineer Andrzej Jarosz.

Leveraging his experience from his previous project, ANT Solutions, established in 2006, and maintaining a leading position in MES (Manufacturing Execution Systems), Andrzej has embarked on a new challenge with analytics.io.

The core idea driving Andrzej is to provide a smart data automation engine for engineers, developers, data analysts, and more, to build powerful systems using just a few lines of simple code.

The project is dedicated to both non-commercial users, who can use the software completely free, and commercial projects.

contact@inanalytics.io

www.linkedin.com/in/andrzej-jarosz-6b6ba96


Introduction to InDriver

InDriver is a versatile automation engine that executes multiple JavaScript tasks simultaneously, facilitating easy solution creation within minutes, even without programming experience.

Utilize the specialized API to support technologies such as REST API, SQL, Modbus, TCP Server, Socket, Serial Port, Files, JSON, and more, to create seamless custom data integration in just a few lines of code.

Distinguished from typical SaaS, InDriver is an application for straightforward installation on local machines or in the cloud, providing unlimited data processing capabilities without cost constraints.

InStudio allows remote configuration of InDrivers across multiple computers, enabling distributed solutions, with numerous copy-paste examples for quick integration.

Getting started - download, installation, requirements

InDriver can be freely downloaded from https://www.inanalytics.io/downloads.

InDriver is absolutely free for non-commercial use.

For commercial use, users are obligated to purchase an annual plan.

InDriver is provided as a zip archive containing the InSetup.exe installer, which installs both InDriver and InStudio.

Currently, there is an available version for Windows operating systems, such as:

Windows 10 and Windows Server 2016 and later.


Installation

Unpack InSetup.zip and run InSetup.exe

  1. Install for all users

  1. Select folder

  1. Create a desktop shortcut

  1. Confirm

  1. Select to install InStudio

  1. Installation complete

Launch InStudio and InDriver.


Launching InDriver

After the installation is completed, and both InDriver and InStudio are launched, InDriver starts as a console application, while InStudio starts as a window application, as shown in the screenshot below:

To start InDriver, run either indriver.exe or the recommended indriver.bat script.
The
indriver.bat script includes a loop that automatically restarts indriver.exe if it crashes unexpectedly, improving stability during execution.

InDriver also accepts several command-line arguments:

License

The system requires a license, even for non-commercial use, when a free license is provided. To set up the license, please follow these steps:

  1. Press MyDriver in the Connections table.

  1. Fill out the License Request Form, providing the following details: User name/email address, Company, License type (Commercial/Free), and license period. Commercial licenses can be purchased for one, two, or three years with one-month accuracy. Free licenses can be obtained for a fixed one-year period.

  1. Press 'Generate,' copy the generated license request, and send it to contact@inanalytics.io. Alternatively, you can click the 'mailto:contact@inalaytic.io' button, and your default mail app will open.

To expedite the license request, please provide us with your organization's data and describe your project. If you are requesting a free license, please explain why your project is non-commercial.

We prioritize all license requests with maximum urgency and commit to responding within 24 hours.

Remark:


  1. When you receive the license key, please copy it into the 'License Upgrade' text editor, then press the 'Upgrade' button.

  1. Wait a few seconds. In the 'Connection' table on the left, 'MyDriver' should switch from 'Invalid license' to 'Working'. You can also press the 'Reload' button. After InDriver restarts, you should see your license.


Setup

InStudio Setup allows you to configure SQL Servers, and user data, install InServer, and manage other APIs included in the InDriver package, as well as manage licenses.

InServer

InStudio communicates with InDriver, enabling their configuration, management, and programming of tasks using either a local machine connection or a database connection.

A local machine connection provides direct access to InDriver installed on the same machine. On the other hand, a database connection not only facilitates communication on the local machine but also enables the construction of a distributed system. In a distributed system, one or more InDrivers may run on various machines and be managed from a single InStudio.

Database communication becomes particularly valuable for system redundancy when configuring more than one database server. The schema below illustrates the database connection between InDrivers and InStudio.

One or more SQL Servers can serve as gateways by installing InServerAPI on them, a process easily facilitated through InStudio.

Configure SQL Servers

To configure SQL servers, open the 'Setup' menu and navigate to the 'InStudio' tab. By default, two servers are provided. Fill in the correct details:

Enter the 'Name' for the configured server in InStudio, remember to set 'Active' to true, and press the 'Save' button.

If valid data is provided, after a few seconds, the connection table on the left should display configured servers in the horizontal header, indicated in green for successful connections or red if the database connection failed.

The screenshot below illustrates a situation where the LocalPGSQL connection has failed, as indicated by the red status in the Connections table on the left.

To debug the reason for any error, click on the server name, which opens a server window with a table of errors. Click 'Refresh,' and the last 100 errors will be updated.

Install InServerAPI

When SQL Server(s) are configured correctly, the next step is to install InServerAPI. InServerAPI is a set of SQL functions and tables used by InDrivers and InStudio to communicate with each other, and store logs, configurations, messages, etc.

To install InServerAPI, open the 'InServer' tab, select the previously configured SQL server from the combo box, and press 'Install.'

If the installation is successful, the installed SQL tables should be listed in the table, and the status should be indicated in green.

Install the Additional API(s)

This step is not obligatory. The additional API may provide a set of SQL functions and tables to support the programming of various solutions.

Currently, TsApi (tsapi.sql) is available, which includes functions dedicated to JSON Time Series Processing. To install an additional API on the previously selected server, select the API by checking it and pressing the 'Install' button. If the installation is successful, the 'Installed API' table should display the installed API.


InDriver first steps

Configuring SQL Servers

To begin configuring InDriver, click on the selected row in the column corresponding to the server or local connector.

If you prefer to use a database connection between InDriver and InStudio (with InServerAPI previously installed), simply press 'Import servers from InStudio.' All previously configured servers will be copied to InDriver's configuration. After this, press the 'Send+Restart' button. InDriver will restart and should be connected to the servers.

It is possible to add more SQL server connections for InDriver, not only the servers that play the role of InServers. InDriver tasks can easily interact with databases. Once the database source is configured, the InDriver.sqlExecute() function may be used by providing the configured server name.

Configuring first task

To add a new task, click 'Insert' in the 'Tasks' context menu.

First ‘Hello world’ script

Open the task, select the 'Editor' tab, and write InDriver.debug('Hello world'); in the 'onStartup' script. Then, press the 'Save And Reload' button. Done! Your first JS task is being reloaded, and in a few seconds, you will see the debug log 'Hello world!' Great job!


Features and examples

To be done soon :)


InDriver JS Tasks

InDriver can simultaneously execute multiple tasks. To insert a new task, click 'Insert' on the tasks content menu and select either 'New task' or 'Load task from file.' The second option enables loading saved task configurations, including example tasks with names starting from '@...' provided with InDriver in the default folder 'SavedTasks'. InDriver configuration is stored as a JSON object in the 'driver.cfg' file.

Inserting a new task:

Task configuration:

"Default Task configuration items are displayed with bold font and consist of:

Additionally, the user can add other JSON Objects, Variables, or Arrays that will store user data. In this example ‘userData’ object is added with Number and String values.

Each InDriver Task functions as a distinct JavaScript Engine, executing four ‘pre-defined functions:

onStartup() and onShutdown() are called once when the Task starts and stops, respectively.

The onHook() function is continuously called at intervals defined in the Task configuration, or it can be declared using InDriver.installHook(hook) and removed using InDriver.uninstallHook(hook).

The above image shows the Task default configuration set.

Hooks are intervals defined in milliseconds (ms); for example, a hook of 10000 (equals 10s), executing every 10s synchronized with the computer clock where InDriver is running.


Recommended coding rules (AI)

When generating InDriver code, follow these rules:

1. Use only documented InDriver API.
 When generating an InDriver task, use only functions, modules, signatures, and behavior explicitly documented in the InDriver Manual. Do not invent APIs, helper methods, field names, or runtime behavior.

2. Generate complete importable JSON, not loose code snippets.
 Unless the user explicitly asks only for a script fragment, always return a complete JSON object representing exactly one InDriver task, ready to save as a .cfg file and import with Load task from file.

3. Match the InDriver task configuration model.
 The generated JSON must follow the InDriver task configuration structure and include the standard task properties used by InDriver tasks:
active, enableOnHook, enableOnMessage, hooks, listening, name, onHookScript, onMessageScript, onShutdownScript, onStartupScript, tags, and type.
The type for user tasks must be
"JS". Additional user configuration may be added as extra JSON properties when needed.

4. Put lifecycle code into script fields, not wrapper functions.
 InDriver evaluates the task as separate lifecycle script blocks. Therefore, code must be written directly into:

Do not wrap the task logic inside function onStartup() {}, function onHook() {}, etc.

5. Follow the official coding pattern.

After each SQL execution:

Prefer structured JSON in logs and messages.

6. Respect hook-based execution model.
 If the task is periodic:

If multiple hooks are used:

7. Keep the output strictly machine-importable.
 Return only the raw JSON file content unless the user explicitly asks for explanation.
Do not include:

All script fields must contain valid JSON strings with proper escaping.

8. Preserve example-compatible naming and style.
 Use camelCase naming consistent with InDriver examples:

9. Include optional configuration inside the task JSON.
 If the task requires parameters (e.g. connection names, thresholds, table names, signals), include them as additional JSON properties such as:

Access them using:
InDriver.configuration(...)

10. Generate production-ready task content.
 The generated task must be:

Do not include placeholders, mock logic, or invented behavior.

Execution Model & Script Structure Rules

11. Do not validate task configuration at runtime.
 If the script is executing, the task is already properly loaded and configured in InDriver.
Do not add checks for task existence, configuration presence, or initialization state.

12. Do not use top-level return statements in lifecycle scripts.
 The following are NOT function bodies:

Using return directly at the top level is invalid and must be avoided.

13. Use internal functions for control flow.
 If early exit or structured logic is required, wrap code inside a function and invoke it.

Recommended pattern:

function run() {

   if (condition) {

       return;

   }

   // main logic

}

run();

14. Keep lifecycle scripts as execution containers.
 Top-level script content should:

Avoid placing complex logic directly at the top level.

15. Use early returns only inside functions.
 Early return statements are allowed only inside user-defined functions, never at the script top level.

16. Maintain clean and deterministic execution structure.
 Each lifecycle block should follow a consistent pattern:

This ensures:

17. Separate initialization and processing logic.

Do not place heavy processing logic in onStartupScript unless explicitly required.

18. Follow production-grade structure.
 Generated code must reflect real-world engineering practices:

InDriver Task JSON Template

{

 "active": true,

 "enableOnHook": true,

 "enableOnMessage": false,

 "hooks": [

   60000

 ],

 "listening": [

   "*"

 ],

 "name": "TaskName",

 "onHookScript": "",

 "onMessageScript": "",

 "onShutdownScript": "",

 "onStartupScript": "",

 "tags": [

   "*"

 ],

 "type": "JS",

 "userData": {

 }

}


Field Description (for AI usage)


Important Rule for AI

When generating an InDriver task:


InDriver API

The InDriver object is the default global object available in every JavaScript task.

It provides functions for:

InDriver.configuration

Signature

InDriver.configuration(): Object

InDriver.configuration(path: String[]): Object

Description

Returns task configuration as a JSON value.

Two forms are available:

Arguments

path

Examples:

[]

["UserData"]

["UserData", "Number"]

["Sql", "Connections", "Main"]

Returns

Behavior

Example

let fullCfg = InDriver.configuration();

let userData = InDriver.configuration(["UserData"]);

let numberValue = InDriver.configuration(["UserData", "Number"]);

Notes for AI


InDriver.currentPath

Signature

InDriver.currentPath(): String

Description

Returns the directory containing the current InDriver.exe runtime.

Returns

Typical use

Example

InDriver.debug(InDriver.currentPath());


InDriver.debug

Signature

InDriver.debug(message: String|Object, msgType: String = "debug", cut: Boolean = true): void

InDriver.debugFull(message: String|Object): void

Description

Outputs a debug message to the Debug console.

This function is the primary mechanism for:

If message is not a string, it is internally converted to JSON representation.

Arguments

message

msgType

Maps internally to logging severity levels.

cut

Behavior:

Behavior

Returns

Examples

InDriver.debug("Task started");

InDriver.debug("Connection failed", "critical");

InDriver.debug({ step: "import", ok: true }, "info", false);

Edge cases

Rules


InDriver.debugVariables

Signature

InDriver.debugVariables(): String

Description

Returns a textual list of variables defined in the global scope of the current JavaScript task and also prints them to the Debug console.

Useful for:

Returns

Example

var i = 10;

var j = "variable";

var array = [1, 2, 3, j];

InDriver.debugVariables();

Behavior

Edge cases


InDriver.driverName

Signature

InDriver.driverName(): String

Description

Returns the name of the current InDriver instance.

Returns

Example

const name = InDriver.driverName();

InDriver.debug("Driver name: " + name);


InDriver.hooks

Signature

InDriver.hooks(): String

Description

Returns currently installed hook intervals.

Returns

Behavior

The value is returned as a string representation of installed hooks. In practice it should be treated as serialized data rather than a native JS array unless the runtime documentation explicitly states otherwise.

Example

InDriver.debug("Hooks: " + InDriver.hooks());

Rules


InDriver.hookTs

Signature

InDriver.hookTs(): Date

InDriver.hookTs(hook: Number): Date

Description

Returns DateTime of the currently executed hook.

Arguments

Behavior

Example

const ts = InDriver.hookTs();

if (InDriver.isHook(10000)) {

   const ts = InDriver.hookTs(10000);

}

Rules


InDriver.hookMs

Signature

InDriver.hookMs(): int64

Description

Returns the timestamp of the currently executed hook in milliseconds since epoch.

Example

const tsMs = InDriver.hookMs();

Rules


InDriver.import

Signature

InDriver.import(apiName: String): Boolean

Description

Creates a JavaScript object providing access to additional API.

Arguments

Available APIs

Behavior

Returns

Example

InDriver.import("ModbusApi");

Modbus.connectDevice(...);

Edge cases

Notes for AI


InDriver.installExtensions

Signature

InDriver.installExtensions(extension: String): void

Description

Installs additional JavaScript engine extensions provided by QJSEngine.

This function enables selected non-standard JS features in the current task runtime.

Supported extension names are mapped internally as follows:

If an unknown extension name is provided, the function does not throw an exception and does not return a status flag. Instead, it logs a debug message indicating that the extension is unknown and lists supported values.

Arguments

extension

Allowed values

Returns

Behavior

Internal fallback behavior for invalid value

Equivalent runtime behavior:

InDriver.debug(

 "InDriver.installExtensions('" + extension +

 "') - unknown extension, available: ConsoleExtension, GarbageCollectionExtension, TranslationExtension, AllExtensions"

);

Examples

InDriver.installExtensions("ConsoleExtension");

InDriver.installExtensions("AllExtensions");

Invalid example

InDriver.installExtensions("MyCustomExtension");

Expected effect:

Notes for developer

Because the function returns void, there is no direct success/failure flag.
If you need to validate input, you should ensure the extension name is one of the supported values before calling it.

Rules


InDriver.installHook

Signature

InDriver.installHook(hook: Number): void

Description

Registers periodic execution interval for onHook.

Arguments

Examples:

Behavior

Returns

Example

InDriver.installHook(10000);

InDriver.installHook(60000);

InDriver.installHook(3600000);

Rules


InDriver.isHook

Signature

InDriver.isHook(hook: Number): Boolean

Description

Checks whether the current onHook execution was triggered by the specified hook interval.

Arguments

hook

Returns

Example

if (InDriver.isHook(10000)) {

    let ts = InDriver.hookTs(10000);

}

Typical use


InDriver.isPrivateMessage // depreciated

InDriver.isLoopbackMessage()

Signature

InDriver.isPrivateMessage(): Boolean // depreciated

InDriver.isLoopbackMessage(): Boolean // depreciated

Description

Returns true if the current message was sent by the same task that is now processing it.

Returns

Equivalent logic

InDriver.taskName() === InDriver.messageSender()

Example

if (InDriver.isPrivateMessage()) {

   InDriver.debug("Received private/self message");

}


InDriver.loadScript

Signature

InDriver.loadScript(scriptPath: String): Boolean

Description

Loads an external JavaScript file.

Arguments

path

Returns

Example

InDriver.loadScript("scriptslibrary/script.js");

InDriver.loadScript("c:/program files/InDriver/scriptslibrary/script.js");


InDriver.messageData

Signature

InDriver.messageData(): String

Description

Returns payload data of the currently processed message.

Returns

Example

const msgData = InDriver.messageData();

Rules


InDriver.messageSender

Signature

InDriver.messageSender(): String

Description

Returns the name of the task that sent the current message.

Returns

Example

const sender = InDriver.messageSender();


InDriver.messageTags

Signature

InDriver.messageTags(): String

Description

Returns tags of the current message.

Returns

Behavior

The underlying C++ API returns QString, so tags should be treated as string/serialized tag representation rather than guaranteed String[].

Example

const tags = InDriver.messageTags();

InDriver.debug("Tags: " + tags);

Rules


InDriver.messageTs

Signature

InDriver.messageTs(): Date

Description

Returns timestamp of the current message.

Returns

Example

const msgTs = InDriver.messageTs();


InDriver.msleep

Signature

InDriver.msleep(msecs: Number): void

Description

Sleeps/blocks the current task for the specified number of milliseconds.

Arguments

msecs

Returns

Example

InDriver.msleep(500);

Rules


InDriver.onHook

Signature

InDriver.onHook(h: Number): void

InDriver.onHook(h: Number[]): void

Description

Triggers onHook immediately, simulating one or more hook events.

Main purpose:

Arguments

h

Returns

Example

InDriver.onHook(10000);

InDriver.onHook([1000, 10000]);

Notes


InDriver.restartTask

Signature

InDriver.restartTask(name: String = ""): void

Description

Stops and restarts a task.

Arguments

name

Behavior:

Returns

Typical use

Example

InDriver.restartTask();

InDriver.restartTask("ArchiveTask");


InDriver.sendMessage

Signature

InDriver.sendMessage(ts: Date, tags: String, data: String): void

InDriver.sendMessage(ts: Date, tags: String, data: JsonValue): void

Description

Sends a message to listening tasks.

Arguments

ts

tags

data

Returns

Behavior

Examples

let ts = new Date();

let rows = InDriver.sqlExecute("LocalDatabase", ["select * from public.table"]);

InDriver.sendMessage(ts, "archive", JSON.stringify(rows));

InDriver.sendMessage(ts, "archive", rows);

Rukes


InDriver.setFlag

Signature

InDriver.setFlag(flag: String, info: String = ""): void

Description

Sets a status flag for the current task.

Arguments

flag

info

Returns

Typical use

Example

InDriver.setFlag("busy", "calculations in progress");

InDriver.setFlag("ok", "archive completed");


InDriver.shutdown

Signature

InDriver.shutdown(): void

Description

Stops all running tasks and gracefully exits the InDriver application.

Returns

Behavior

Example

InDriver.shutdown();

Rules


InDriver.sleep

Signature

InDriver.sleep(secs: Number): void

Description

Sleeps/blocks the current task for the specified number of seconds.

Arguments

secs

Returns

Example

InDriver.sleep(2);

Notes


InDriver.sqlExecute

Signature

InDriver.sqlExecute(connectionName: String, sql: String[]): JsonArray

InDriver.sqlExecute(connectionName: String, sql: String[], bindings: Object): JsonArray

Description

Executes an SQL query on the selected configured server and returns result rows as JSON array.

Arguments

connectionName

sql

Examples:

["select * from public.table"]

["insert into ", "public.table", " (a) values (1)"]

bindings

Example:

{ data: json, ts: "2026-01-01T00:00:00Z" }

Returns

Each row is returned as JSON object:

[

 { "column1": "value1", "column2": 123 }

]

Behavior

Examples

let rows = InDriver.sqlExecute(

   "localserver",

   ["select * from public.table"]

);

let json = JSON.stringify(list);

InDriver.sqlExecute(

   "azureserver",

   ["insert into ", "<schema>", ".shelly (source, ts, data) values ('Shelly', :ts, :data);"],

   { ts: new Date().toISOString(), data: json }

);

Critical usage pattern

let rows = InDriver.sqlExecute("localserver", ["select * from public.table"]);

if (!InDriver.sqlIsSucceeded()) {

   InDriver.debug(InDriver.sqlLastError(), "critical");

   return;

}

Rules


InDriver.sqlExecuteAll

Signature

InDriver.sqlExecuteAll(sql: String[]): Boolean

Description

Executes the provided SQL on all configured database servers.

Arguments

sql

Returns

Behavior

Example

let ok = InDriver.sqlExecuteAll([

   "insert into public.table (ts, task) values (now(), '",

   InDriver.taskName(),

   "');"

]);

Rules


InDriver.sqlIsSucceeded

Signature

InDriver.sqlIsSucceeded(): Boolean

Description

Returns execution status of the last sqlExecute(...) or sqlExecuteAll(...).

Returns

Example

let rows = InDriver.sqlExecute("localserver", ["select * from public.table"]);

if (!InDriver.sqlIsSucceeded()) {

   InDriver.debug(InDriver.sqlLastError());

}


InDriver.sqlLastError

Signature

InDriver.sqlLastError(): String

Description

Returns the error text from the last failed SQL execution.

Returns

Example

if (!InDriver.sqlIsSucceeded()) {

   InDriver.debug(InDriver.sqlLastError(), "critical");

}


InDriver.sqlReopen

Signature

InDriver.sqlReopen(connectionName: String): Boolean

Description

Attempts to reopen the specified SQL connection.

Arguments

connectionName

Returns

Typical use

Example

if (!InDriver.sqlReopen("localserver")) {

   InDriver.debug("Could not reopen DB connection", "critical");

}


InDriver.taskName

Signature

InDriver.taskName(): String

Description

Returns the name of the current task.

Returns

Example

const taskName = InDriver.taskName();

InDriver.systemCpuUsage

Signature

InDriver.systemCpuUsage(): Number

Description

Returns the current CPU utilization of the operating system.

The value is calculated from consecutive system CPU samples and represents the percentage of total CPU time currently used by all processes.

Returns

Number

CPU utilization percentage in range:

0.0 - 100.0

Behavior

Example

const cpu = InDriver.systemCpuUsage();
InDriver.debug("CPU Usage: " + cpu.toFixed(1) + "%");


InDriver.systemProcessMemory

Signature

InDriver.systemProcessMemory(processName: String = ""): Object

Description

Returns memory statistics for a single process.

If no process name is provided, statistics for the current InDriver process are returned.

Arguments

processName

optional, default: ""

Name of the executable file, for example:

Returns

{

   ok: Boolean,

   process: String,

   pid: Number,

   workingSetMB: Number,

   privateUsageMB: Number,

   pagefileUsageMB: Number,

   peakWorkingSetMB: Number,

   peakPagefileUsageMB: Number,

   quotaPagedPoolUsageMB: Number,

   quotaNonPagedPoolUsageMB: Number,

   handleCount: Number

}

Behavior

Example

const mem = InDriver.systemProcessMemory();

InDriver.debug(

   "INDriver Memory: " +

   mem.privateUsageMB.toFixed(0) +

   " MB");

const pg = InDriver.systemProcessMemory("postgres.exe");

InDriver.debug(

   "PostgreSQL Memory: " +

   pg.privateUsageMB.toFixed(0) +

   " MB");


InDriver.systemProcessMemoryAll

Signature

InDriver.systemProcessMemoryAll(processName: String = ""): Object

Description

Returns aggregated memory statistics for all processes with the specified executable name.

If no process name is provided, statistics are aggregated for all running instances of the current InDriver executable.

Arguments

processName

optional, default: ""

Executable name to search for.

Examples:

Returns

{

   ok: Boolean,

   process: String,

   processCount: Number,

   workingSetMB: Number,

   privateUsageMB: Number,

   pagefileUsageMB: Number,

   peakWorkingSetMB: Number,

   peakPagefileUsageMB: Number,

   quotaPagedPoolUsageMB: Number,

   quotaNonPagedPoolUsageMB: Number,

   handleCount: Number,

   openFailedCount: Number,

   accessDeniedCount: Number,

   otherOpenErrorCount: Number,

   memoryReadFailedCount: Number

}

Behavior

Example

const pg = InDriver.systemProcessMemoryAll("postgres.exe");

InDriver.debug(

   "PostgreSQL Total Memory: " +

   pg.privateUsageMB.toFixed(0) +

   " MB (" +

   pg.processCount +

   " processes)");


InDriver.systemMemory

Signature

InDriver.systemMemory(): Object

Description

Returns memory statistics for the entire operating system.

Useful for monitoring physical memory usage, virtual memory usage, and memory pressure.

Returns

{

   ok: Boolean,

   memoryLoadPercent: Number,

   totalPhysMB: Number,

   availPhysMB: Number,

   usedPhysMB: Number,

   totalPageFileMB: Number,

   availPageFileMB: Number,

   usedPageFileMB: Number,

   totalVirtualMB: Number,

   availVirtualMB: Number,

   usedVirtualMB: Number

}

Behavior

Example

const mem = InDriver.systemMemory();

InDriver.debug(

   "RAM: " +

   mem.usedPhysMB.toFixed(0) +

   " / " +

   mem.totalPhysMB.toFixed(0) +

   " MB");


InDriver.systemSnapshot

Signature

InDriver.systemSnapshot(): Object

Description

Returns a combined snapshot of CPU usage, current process memory statistics, and system memory statistics.

Useful for periodic health monitoring and diagnostics.

Returns

{

   cpuUsagePercent: Number,

   processMemory: Object,

   systemMemory: Object

}

Behavior

Example

const s = InDriver.systemSnapshot();

InDriver.debug(

   "CPU=" + s.cpuUsagePercent.toFixed(1) +

   "% RAM=" + s.systemMemory.usedPhysMB.toFixed(0) +

   "/" + s.systemMemory.totalPhysMB.toFixed(0) +

   "MB");

Example

const s = InDriver.systemSnapshot();

InDriver.debug(JSON.stringify(s));


InDriver.uninstallHook

Signature

InDriver.uninstallHook(h: Number): void

Description

Removes a previously installed hook interval.

Arguments

h

Returns

Example

InDriver.uninstallHook(60000);

Typical use


InDriver.updateStatistics

Signature

InDriver.updateStatistics(stat: String): void

Description

Updates runtime statistics/debug information for the task.

Arguments

stat

Returns

Example

InDriver.updateStatistics(JSON.stringify({

   rowsProcessed: 1000,

   elapsedMs: 250

}));

Rules



HttpServerApi

HttpServerApi allows an InDriver task to start an embedded HTTP server, register endpoints, dispatch requests to JavaScript handler functions, and build HTTP responses from JavaScript return values. It is intended for lightweight REST endpoints, operator panels, local integration endpoints, and exposing task data over HTTP. The API is stateful: registered routes, debug mode, and CORS headers are stored inside the HttpServerApi instance.

HttpServerApi.debugMode

Signature

HttpServerApi.debugMode(mode: Boolean = true): void

Description

Enables or disables debug mode for the embedded HTTP server.

When debug mode is enabled:

When disabled:

Arguments

mode

Returns

Behavior

The function only updates internal flag mDebugMode. It does not start or stop the server and does not affect already registered routes except changing runtime logging/error verbosity.

Example

HttpServerApi.debugMode(true);

Rules


HttpServerApi.listen

Signature

HttpServerApi.listen(httpServerCfg: String): Number

HttpServerApi.listen(httpServerCfg: Object = {}): Number

Description

Starts the HTTP server and binds it to the configured address and port.

There are two overloads:

The object overload is internally converted to JSON text and then processed by the string overload.

Arguments

httpServerCfg

address

If omitted:

If invalid:

port

If omitted:

Manual text previously suggested random port may be chosen when omitted, but current implementation sets default port to 8080. The code should be treated as source of truth here.

Returns

Behavior

The server listens using QHttpServer::listen(address, port). After the bind attempt, a debug line is emitted showing the final address, returned port, and a textual classification such as:

Examples

let port = HttpServerApi.listen({

   address: "Any",

   port: 8080

});

let port = HttpServerApi.listen('{"address":"LocalHost","port":9000}');

Edge cases

Rules


HttpServerApi.route

Signature

HttpServerApi.route(path: String, method: String, functionName: String): Boolean

Description

Registers an HTTP endpoint and binds it to a JavaScript function in global scope.

Incoming requests matching the normalized path and parsed HTTP method will invoke the specified JS function. The handler function is looked up dynamically by name in the global JS object at request time, not at registration time.

Arguments

path

Behavior:

Examples:

"/orders"

"orders"        // normalized to "/orders"

""              // normalized to "/"

method

Supported values:

If invalid:

functionName

Requirements:

If missing/blank:

If route exists physically already:

Returns

Request object passed to handler

The JS function is called with one argument: req.

req contains fields documented in the manual:

Runtime behavior during request handling

When a request hits a registered route:

  1. If JS engine is missing → 500 Internal Server Error
  2. If the script is paused → 503 Service Unavailable
  3. If no handler name is configured for the endpoint → 404 Not Found
  4. If the named JS function does not exist or is not callable → 404 Not Found
  5. Otherwise:

Response handling from handler return value

Full response object

If handler returns object:

{

 status: 200,

 contentType: "application/json",

 body: { ok: true }

}

then:

Simplified return values

If handler returns:

Examples

HttpServerApi.route("/orders", "post", "createOrder");

function createOrder(req) {

   return {

       status: 200,

       contentType: "application/json",

       body: { ok: true }

   };

}

HttpServerApi.route("status", "get", "getStatus");

function getStatus(req) {

   return { message: "System OK" };

}

Edge cases

Rules


HttpServerApi.setCorsHeaders

Signature

HttpServerApi.setCorsHeaders(headers: Object): void

Description

Replaces the current set of custom CORS/response headers with a new JSON object.

Headers stored here are appended to every response generated by HttpServerApi, including normal responses and error responses. The function does not merge incrementally; it replaces the stored header object.

Arguments

headers

Typical examples:

Returns

Behavior

Example

HttpServerApi.setCorsHeaders({

   "Access-Control-Allow-Origin": "*",

   "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",

   "Access-Control-Allow-Headers": "Content-Type"

});

Edge cases

Rules


Recommended usage pattern

onStartup:

   InDriver.import("HttpServerApi");  

   HttpServerApi.debugMode(true);

   HttpServerApi.setCorsHeaders({

       "Access-Control-Allow-Origin": "*",

       "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",

       "Access-Control-Allow-Headers": "Content-Type"

   });

   HttpServerApi.route("/status", "get", "getStatus");

   HttpServerApi.route("/orders", "post", "createOrder");

   let port = HttpServerApi.listen({

       address: "Any",

       port: 8080

   });

   InDriver.debug("HTTP server started on port: " + port);

function getStatus(req) {

   return {

       status: 200,

       contentType: "application/json",

       body: { ok: true, path: req.path }

   };

}

function createOrder(req) {

   return { received: req.body };

}



CryptographicHashAPI

CryptographicHashApi allows an InDriver task to calculate cryptographic hashes for text and raw binary data.

The API supports two usage modes:

The API is stateful: the selected algorithm and the internal hashing context are stored inside the instance.

Default algorithm: SHA256

Supported algorithms

The following algorithms are available:

Classic

SHA-2

SHA-3

BLAKE2

Algorithm names are:

CryptographicHashApi.addData

Signature

CryptographicHashApi.addData(text: String): Boolean

Description

Adds text data to the current incremental hash.

The string is converted to UTF-8 before hashing.

Arguments

text

type: String

Text to append to the current hash input.

Returns

Boolean

Example

CryptographicHashApi.reset();

CryptographicHashApi.addData("Hello ");

CryptographicHashApi.addData("World");

Rules


CryptographicHashApi.addDataUtf8

Signature

CryptographicHashApi.addDataUtf8(data: QByteArray): Boolean

Description

Adds raw byte data to the current incremental hash.

No encoding or conversion is performed.

Arguments

data

type: QByteArray

Raw bytes.

Returns

Boolean

Example

let bytes = InDriver.toUtf8("abc");

CryptographicHashApi.addDataUtf8(bytes);

Rules

CryptographicHashApi.algorithm

Signature

CryptographicHashApi.algorithm(): String

Description

Returns the currently selected algorithm.

Returns

String

Normalized algorithm name.

Example

let algo = CryptographicHashApi.algorithm(); // "SHA256"

Rules

CryptographicHashApi.algorithms

Signature

CryptographicHashApi.algorithms(): Array

Description

Returns the list of all supported algorithms.

Returns

Array

Array of strings.

Example

let list = CryptographicHashApi.algorithms();

Rules


CryptographicHashApi.hash

Signature

CryptographicHashApi.hash(text: String): QByteArray

Description

Computes a one-shot hash for a string.

The string is converted to UTF-8 and hashed immediately.

Arguments

text

type: String

Input text.

Returns

QByteArray

Binary hash.

Example

let hash = CryptographicHashApi.hash("abc");

Rules

CryptographicHashApi.hashHex

Signature

CryptographicHashApi.hashHex(text: String): String

Description

Computes a one-shot hash and returns it as hexadecimal string.

Arguments

text

type: String

Input text.

Returns

String

Hex-encoded hash.

Example

let hex = CryptographicHashApi.hashHex("abc");

Rules

CryptographicHashApi.hashHexUtf8

Signature

CryptographicHashApi.hashHexUtf8(data: QByteArray): String

Description

Computes a one-shot hash for raw bytes and returns hex string.

Arguments

data

type: QByteArray

Input bytes.

Returns

String

Hex-encoded hash.

Example

let bytes = InDriver.toUtf8("abc");

let hex = CryptographicHashApi.hashHexUtf8(bytes);

Rules

CryptographicHashApi.hashUtf8

Signature

CryptographicHashApi.hashUtf8(data: QByteArray): QByteArray

Description

Computes a one-shot hash for raw bytes.

Arguments

data

type: QByteArray

Input bytes.

Returns

QByteArray

Binary hash.

Example

let bytes = InDriver.toUtf8("abc");

let hash = CryptographicHashApi.hashUtf8(bytes);

Rules

CryptographicHashApi.isSupported

Signature

CryptographicHashApi.isSupported(algorithm: String): Boolean

Description

Checks whether a given algorithm is supported.

Arguments

algorithm

type: String

Algorithm name.

Returns

Boolean

Example

if (CryptographicHashApi.isSupported("SHA3-256")) {

   CryptographicHashApi.setAlgorithm("SHA3-256");

}

Rules

CryptographicHashApi.reset

Signature

CryptographicHashApi.reset(): Boolean

Description

Clears current incremental hash state.

Returns

Boolean

Always true.

Behavior

Example

CryptographicHashApi.reset();

Rules

CryptographicHashApi.result

Signature

CryptographicHashApi.result(): QByteArray

Description

Returns binary hash for current incremental state.

Returns

QByteArray

Binary digest.

Example

let digest = CryptographicHashApi.result();

Rules

CryptographicHashApi.resultHex

Signature

CryptographicHashApi.resultHex(): String

Description

Returns current hash as hexadecimal string.

Returns

String

Hex-encoded digest.

Example

let hex = CryptographicHashApi.resultHex();

Rules

CryptographicHashApi.setAlgorithm

Signature

CryptographicHashApi.setAlgorithm(algorithm: String): Boolean

Description

Sets the active hashing algorithm.

Arguments

algorithm

type: String

Algorithm name.

Returns

Boolean

Behavior

Example

CryptographicHashApi.setAlgorithm("SHA512");

Rules

Recommended usage pattern

One-shot hashing

InDriver.import("CryptographicHashApi");

let hex = CryptographicHashApi.hashHex("Hello World");

Incremental hashing

InDriver.import("CryptographicHashApi");

CryptographicHashApi.setAlgorithm("SHA256");

CryptographicHashApi.reset();

CryptographicHashApi.addData("part1");

CryptographicHashApi.addData("part2");

let hex = CryptographicHashApi.resultHex();


OPCUPClientApi

OPCUAClientApi provides OPC UA client access from JavaScript tasks. It supports:

The API stores client instances by clientName, so the same logical client can be reconfigured and reconnected by calling connect(...) again with the same name.

OPCUAClientApi.browse

Signature

OPCUAClientApi.browse(

   clientName: String,

   nodeIdStr: String = "",

   filter: String = "",

   limit: Number = 100

): Array

Description

Browses the OPC UA address space starting from a selected node and returns discovered nodes as a JSON array.

Arguments

clientName

nodeIdStr

Supported special values in current implementation:

Behavior:

filter

From source, the filter object supports at least:

Because the exact JS filter grammar is implemented deeper in helper classes and is not fully documented in the visible snippet, this argument should be documented as an implementation-defined filter string rather than over-specified.

limit

Returns

Behavior

Example

InDriver.import("OPCUAClientApi");

OPCUAClientApi.connect(

   "Client1",

   '{"EndpointUrl":"opc.tcp://localhost:4840","Timeout":5000}'

);

let nodes = OPCUAClientApi.browse("Client1", "Objects", "", 50);

InDriver.debug(nodes);

Edge cases

Rules


OPCUAClientApi.connect

Signature

OPCUAClientApi.connect(clientName: String, cfg: Object): Boolean

OPCUAClientApi.connect(clientName: String, cfg: String = ""): Boolean

Description

Creates or reconfigures a named OPC UA client and attempts to connect it to a server.

Arguments

clientName

cfg

The object overload is internally serialized to JSON and passed to the string overload.

Known documented field:

Example:

{

 "EndpointUrl": "opc.tcp://localhost:4840",

 "Timeout": 5000

}

Returns

Behavior

Example

InDriver.import("OPCUAClientApi");

let ok = OPCUAClientApi.connect(
  "Client1",
  '{"EndpointUrl":"opc.tcp://localhost:4840","Timeout":5000}'
);

if (!ok) {
  InDriver.debug(OPCUAClientApi.lastError(), "critical");
}

Edge cases

Notes for AI


OPCUAClientApi.disconnect

Signature

OPCUAClientApi.disconnect(clientName: String): Boolean

Description

Disconnects a previously created OPC UA client.

Arguments

clientName

Returns

Behavior

Example

let ok = OPCUAClientApi.disconnect("Client1");

if (!ok) {
  InDriver.debug(OPCUAClientApi.lastError(), "critical");
}

Edge cases


OPCUAClientApi.isConnected

Signature

OPCUAClientApi.isConnected(clientName: String): Boolean

Description

Checks whether the named OPC UA client is currently connected.

Arguments

clientName

Returns

Example

if (OPCUAClientApi.isConnected("Client1")) {
  InDriver.debug("Client1 connected");

}

Rules


OPCUAClientApi.lastError

Signature

OPCUAClientApi.lastError(): String

Description

Returns the last error message stored by the client API.

Returns

Behavior

Example

let err = OPCUAClientApi.lastError();

if (err) InDriver.debug(err, "critical");


OPCUAClientApi.readMultipleNodes

Signature

OPCUAClientApi.readMultipleNodes(clientName: String, nodeCfg: String): Array

OPCUAClientApi.readMultipleNodes(clientName: String, nodeCfg: Array): Array

Description

Reads values from multiple OPC UA nodes and returns results as JSON array.

Arguments

clientName

nodeCfg

Minimal documented example:

[

 { "nodeId": "ns=2;s=Temperature" }

]

Returns

Behavior

The source follows the same pattern as other OPC methods: parse input JSON, perform operation, enrich same structure, return resulting QJsonArray.

Example

let data = OPCUAClientApi.readMultipleNodes(
  "Client1",
  '[{"nodeId":"ns=2;s=Temperature"}]'
);
InDriver.debug(data);

Edge cases

Notes for AI


OPCUAClientApi.runIterate

Signature

OPCUAClientApi.runIterate(clients: String[] = [], timeout: Number = 0): void

Description

Runs client iterate cycle for all clients or only selected clients.

Arguments

clients

timeout

Returns

Behavior

Iterates through internal client map and calls runIterateClient(timeout) on:

Example

OPCUAClientApi.runIterate();

OPCUAClientApi.runIterate(["Client1", "Client2"], 10);

Notes

This is a low-level helper. For many standard task flows, explicit connect/read/write is enough.


OPCUAClientApi.writeMultipleNodes

Signature

OPCUAClientApi.writeMultipleNodes(clientName: String, nodeCfg: String): Boolean

OPCUAClientApi.writeMultipleNodes(clientName: String, nodeCfg: Array): Boolean

Description

Writes values to multiple OPC UA nodes.

Arguments

clientName

nodeCfg

Documented example:

[

 { "nodeId": "ns=2;s=Temperature", "value": 25 }

]

Returns

Behavior

Example

let ok = OPCUAClientApi.writeMultipleNodes(
  "Client1",
  '[{"nodeId":"ns=2;s=Temperature","value":25}]'
);

if (!ok) {
  InDriver.debug(OPCUAClientApi.lastError(), "critical");
}

Rules

OPC UA client pattern

onStartup:

   InDriver.import("OPCUAClientApi");

   let ok = OPCUAClientApi.connect(

       "Client1",

       '{"EndpointUrl":"opc.tcp://localhost:4840","Timeout":5000}'

   );

   if (!ok) {

       InDriver.debug(OPCUAClientApi.lastError(), "critical");

   }

onHook:

   let values = OPCUAClientApi.readMultipleNodes(

       "Client1",

       '[{"nodeId":"ns=2;s=Temperature"}]'

   );

   if (OPCUAClientApi.lastError()) {

       InDriver.debug(OPCUAClientApi.lastError(), "critical");

       return;

   }

   InDriver.debug(values);



OPCUPServerApi

OPCUAServerApi provides an embedded OPC UA server inside an InDriver task. It supports:

The server is stored as a single internal mOPCServer instance. Most operations fail if start(...) has not been called first.

OPCUAServerApi.addNodes

Signature

OPCUAServerApi.addNodes(nodeCfg: String, folder: String = ""): Boolean

OPCUAServerApi.addNodes(nodeCfg: Array, folder: String = ""): Boolean

Description

Adds nodes to the running OPC UA server.

Arguments

nodeCfg

Documented example:

[

 { "nodeId": "ns=2;s=TemperatureSensor", "name": "Sensor" }

]

folder

Manual says default parent is "Objects", though the direct API default is empty string and underlying server logic determines how that is resolved.

Returns

Behavior

Example

InDriver.import("OPCUAServerApi");

OPCUAServerApi.start('{"EndpointUrl":"opc.tcp://localhost:4840"}');

let ok = OPCUAServerApi.addNodes(   '[{"nodeId":"ns=2;s=TemperatureSensor","name":"Sensor"}]',  
"Objects");

Edge cases


OPCUAServerApi.lastError

Signature

OPCUAServerApi.lastError(): String

Description

Returns the last stored server API error.

Returns

Example

let err = OPCUAServerApi.lastError();

if (err) InDriver.debug(err, "critical");


OPCUAServerApi.readMultipleNodes

Signature

OPCUAServerApi.readMultipleNodes(nodeCfg: String): Array

OPCUAServerApi.readMultipleNodes(nodeCfg: Array): Array

Description

Reads values from multiple nodes exposed by the embedded OPC UA server.

Arguments

nodeCfg

Documented example:

[

 { "nodeId": "ns=2;s=Temperature" }

]

Returns

Behavior

Example

let data = OPCUAServerApi.readMultipleNodes(

   '[{"nodeId":"ns=2;s=Temperature"}]'

);

InDriver.debug(data);

Edge cases

Rules


OPCUAServerApi.start

Signature

OPCUAServerApi.start(cfg: String = ""): void

Description

Starts the embedded OPC UA server using JSON configuration.

Arguments

cfg

Documented example:

{

 "EndpointUrl": "opc.tcp://localhost:4840"

}

Returns

Behavior

Important implication

Because start() returns void, success must be inferred by:

Example

InDriver.import("OPCUAServerApi");

OPCUAServerApi.start('{"EndpointUrl":"opc.tcp://localhost:4840"}');

Edge cases

Rules


OPCUAServerApi.stop

Signature

OPCUAServerApi.stop(): void

Description

Stops the embedded OPC UA server.

Returns

Example

onShutdown:

OPCUAServerApi.stop();

Notes


OPCUAServerApi.writeMultipleNodes

Signature

OPCUAServerApi.writeMultipleNodes(nodeCfg: String): Boolean

OPCUAServerApi.writeMultipleNodes(nodeCfg: Array): Boolean

Description

Writes values to multiple nodes hosted by the embedded OPC UA server.

Arguments

nodeCfg

Documented example:

[

 { "nodeId": "ns=2;s=Temperature", "value": 22.5 }

]

Returns

Behavior

Example

let ok = OPCUAServerApi.writeMultipleNodes( '[{"nodeId":"ns=2;s=Temperature","value":22.5}]' );

if (!ok) {
  InDriver.debug(OPCUAServerApi.lastError(), "critical");
}

Edge cases

OPC UA server pattern

onStartup:

   InDriver.import("OPCUAServerApi");

   OPCUAServerApi.start('{"EndpointUrl":"opc.tcp://localhost:4840"}');

   let ok = OPCUAServerApi.addNodes(

       '[{"nodeId":"ns=2;s=TemperatureSensor","name":"Sensor"}]',

       "Objects"

   );

   if (!ok) {

       InDriver.debug(OPCUAServerApi.lastError(), "critical");

   }

}

onHook:

   OPCUAServerApi.writeMultipleNodes(

       '[{"nodeId":"ns=2;s=Temperature","value":22.5}]'

   );

onShutdown:

   OPCUAServerApi.stop();


RestApi

RestApi provides HTTP client functionality for JavaScript tasks. It supports:

The API is stateful. It stores:

RestApi.begin

Signature

RestApi.begin(): void

Description

Starts a transaction block for collecting multiple REST requests before executing them together.

Behavior

After calling begin():

Returns

Example

RestApi.begin();

RestApi.sendRequest("Krakow");

RestApi.sendRequest("Chicago");

RestApi.commitWait();

Rules


RestApi.commit

Signature

RestApi.commit(): void

Description

Executes all queued requests collected after begin(), but does not wait for their completion.

Behavior

Returns

Important

After commit(), you usually need to call:

RestApi.wait();

or

RestApi.wait(timeout);

Example

RestApi.begin();

RestApi.sendRequest("Krakow");

RestApi.sendRequest("Chicago");

RestApi.commit();

RestApi.wait();

Rules


RestApi.commitWait

Signature

RestApi.commitWait(): void

Description

Executes all queued requests and waits until all are finished or timeout occurs.

Behavior

Internally equivalent to:

RestApi.commit();

RestApi.wait();

Returns

Example

RestApi.begin();

RestApi.sendRequest("Krakow");

RestApi.sendRequest("Chicago");

RestApi.commitWait();

Rules


RestApi.defineRequest

Signature

RestApi.defineRequest(reqName: String, cfg: String): void

RestApi.defineRequest(reqName: String, cfg: Object): void

Description

Defines a named REST request configuration that can later be executed using:

RestApi.sendRequest(reqName)

The request definition supports:

Arguments

reqName

type: String

Logical request name used later by:

RestApi.sendRequest(reqName)

RestApi.getData(reqName)

RestApi.getRawHeader(reqName, headerName)

RestApi.getRawHeaderPairs(reqName)

RestApi.isSucceeded(reqName)

Examples:

"Weather"

"PIWebApi"

"OrderSync"

"Mass1"

cfg

type: String | Object

JSON configuration describing the request.

Recommended form:

RestApi.defineRequest("Test", {

   ...

});

Supported configuration keys

url

type: String

Target request URL.

Example:

url: "https://api.example.com/data"

Example (PI Web API):

url: "https://ZGHTIMS1.TIMS.local/piwebapi/streams/.../value"

Required.

type

type: String

HTTP method.

Supported values:

"get"

"post"

"put"

Use lowercase.

If unsupported:

Example:

type: "get"

timeout

type: Number

Request timeout in milliseconds.

Default:

3000

Example:

timeout: 30000

Headers

headers

type: Object

Optional.

Custom HTTP headers.

Example:

headers: {

   Accept: "application/json",

   "User-Agent": "InDriver"

}

Supported Qt known headers:

ContentDispositionHeader

ContentTypeHeader

ContentLengthHeader

CookieHeader

SetCookieHeader

ETagHeader

IfMatchHeader

IfNoneMatchHeader

LastModifiedHeader

LocationHeader

ServerHeader

UserAgentHeader

Any other key is sent as raw HTTP header.

Example:

headers: {

   Authorization: "Bearer xxxxx",

   Accept: "application/json"

}

Request body

rawData

type: String | Object | Array

Optional.

Payload for:

post

put

Behavior:

If string: sent unchanged

If object/array: serialized to JSON

Example:

rawData: {

   id: 123,

   status: "new"

}

Authentication

auth

type: Object

Optional.

Challenge-based authentication using QAuthenticator.

Supported for:

Example:

auth: {

   mode: "authenticator",

   user: "inanalitics",

   password: "inanalitics"

}

auth.mode

type: String

Supported:

"authenticator"

Behavior:

If server returns: 401 Unauthorized WWW-Authenticate

RestApi responds using: Authenticator with configured credentials.

If auth exists but credentials missing:

authentication challenge is logged but authentication fails.

Manual Authorization header

Alternative authentication method.

Use explicit header:

headers: {

   Authorization: "Basic xxxxxxxxx"

}

Example:

headers: {

   Authorization: "Basic sjlksdjflkdjklsjfkl="

}

Useful for:

SSL

ssl

type: Object

Optional.

SSL/TLS behavior.

ssl.ignoreErrors

type: Boolean

If true:

SSL certificate validation errors are ignored.

Example:

ssl: {

   ignoreErrors: true

}

Useful for:

ssl.verifyPeer

type: Boolean

Default:

true

If false:

certificate validation disabled.

Example:

ssl: {

   verifyPeer: false

}

ssl.protocol

type: String

Supported:

"tls1.2"

"tls1.3"

"tls1.2+"

"tlsv1.2"

"tlsv1.3"

"tlsv1.2orlater"

Example:

ssl: {

   protocol: "tls1.2"

}

HTTP transport

disableHttp2

type: Boolean

Optional.

If true: HTTP/2 disabled.

Useful for compatibility with:

Example:

disableHttp2: true

dedicatedManager

type: Boolean

Optional.

If true: request uses a dedicated NetworkAccessManager.

Example:

dedicatedManager: true

Useful for problematic servers with:

Tradeoff:

slightly higher overhead due to manager creation/destruction.

Error handling

failOnHttpError

type: Boolean

Default:

true

If true:

HTTP errors mark request as failed.

Examples:

401

403

404

500

cause:

RestApi.isSucceeded(reqName) == false

If false: only timeout / transport failure matters.

Example:

failOnHttpError: false

Useful for debugging APIs returning useful error payloads.

Debug

debugMode

type: Boolean

Enables detailed logging.

Example:

debugMode: true

debugLevel

type: String

Supported:

"basic"

"headers"

"full"

basic

Logs:

headers

Adds:


full

Adds:

Success semantics

RestApi.isSucceeded(reqName)

Returns:

true

only if:

HTTP success:

200–299

If:

failOnHttpError: false

then HTTP error responses may still return success.

Examples

Public API

RestApi.defineRequest("Weather", {

   url: "https://danepubliczne.imgw.pl/api/data/synop",

   type: "get",

   timeout: 10000,

   headers: {

       Accept: "application/json"

   }

});

PI Web API

RestApi.defineRequest("Mass1", {

   url: "https://server/piwebapi/streams/.../value",

   type: "get",

   timeout: 30000,

   dedicatedManager: true,

   failOnHttpError: true,

   auth: {

       mode: "authenticator",

       user: "user",

       password: "pass"

   },

   ssl: {

       ignoreErrors: true,

       verifyPeer: false,

       protocol: "tls1.2"

   },

   disableHttp2: true,

   headers: {

       Accept: "application/json",

       "User-Agent": "InDriver"

   }

});

POST JSON

RestApi.defineRequest("CreateOrder", {

   url: "https://api.example.com/orders",

   type: "post",

   headers: {

       ContentTypeHeader: "application/json"

   },

   rawData: {

       id: 123,

       status: "new"

   }

});

Rules

Use:

type: "get"

type: "post"

type: "put"

Prefer:

RestApi.defineRequest("name", { ... })

Use:

auth

for challenge authentication.

Use:

Authorization

header for manual auth.

Use:

dedicatedManager: true

for problematic enterprise authentication servers.

Use:

debugMode: true

when troubleshooting integrations.

Use:

failOnHttpError: false

only for diagnostics.


RestApi.getData

Signature

RestApi.getData(reqName: String): String

Description

Returns the response body stored for the named request from the most recent completed REST execution.

Arguments

reqName

Returns

Example

const data = RestApi.getData("Krakow");

InDriver.debug(data);

Rules

let obj = JSON.parse(RestApi.getData("Krakow"));


RestApi.getRawHeader

Signature

RestApi.getRawHeader(reqName: String, headerName: String): String

Description

Returns a single response header value for the named request.

Arguments

reqName

headerName

Returns

Example

let contentType = RestApi.getRawHeader("Krakow", "Content-Type");


RestApi.getRawHeaderPairs

Signature

RestApi.getRawHeaderPairs(reqName: String): String

Description

Returns all raw response headers for the named request as serialized JSON text.

Arguments

reqName

Returns

Example

let headersJson = RestApi.getRawHeaderPairs("Krakow");

InDriver.debug(headersJson);


RestApi.isSucceeded

Signature

RestApi.isSucceeded(): Boolean

Description

Returns the success status of the last REST execution block.

Returns

Behavior

The value is backed by internal mTransactionSucceeded. It becomes true when wait(...) finishes before timeout, not necessarily only when every HTTP status code is “successful”. Network reply errors are logged as fatal, but isSucceeded() is not set directly from HTTP status codes.

Important nuance

isSucceeded() mainly indicates:

Example

if (RestApi.isSucceeded()) {

   let data = RestApi.getData("Krakow");

   InDriver.debug(data);

}

Rules


RestApi.sendRequest

Signature

RestApi.sendRequest(reqName: String): Boolean

RestApi.sendRequest(reqName: String, jsonPayload: Object): Boolean

RestApi.sendRequest(reqName: String, data: String): Boolean

Description

Sends a REST request using either:

Overloads

1. sendRequest(reqName)

Uses previously defined request configuration.

2. sendRequest(reqName, jsonPayload)

Serializes the object to JSON text and delegates to string overload.

3. sendRequest(reqName, data)

Uses string payload/config override.

Returns

Behavior for sendRequest(reqName)

Behavior for sendRequest(reqName, data)

Immediate vs batched execution

If begin() was not called:

If begin() was called:

Payload behavior

For POST/PUT:

Example: single immediate request

RestApi.defineRequest("Krakow", {

   url: "https://api.openweathermap.org/data/2.5/weather?appid=your_app_id&q=krakow",

   timeout: 5000,

   type: "get",

   headers: {

       ContentTypeHeader: "application/json"

   }

});

RestApi.sendRequest("Krakow");

RestApi.wait();

if (RestApi.isSucceeded()) {

   const data = RestApi.getData("Krakow");

   InDriver.debug(data);

}

Example: batched execution

RestApi.begin();

RestApi.sendRequest("Krakow");

RestApi.sendRequest("Chicago");

RestApi.commitWait();

Example: override payload

RestApi.defineRequest("CreateOrder", {

   url: "https://example.com/api/orders",

   timeout: 5000,

   type: "post",

   headers: {

       ContentTypeHeader: "application/json"

   }

});

RestApi.sendRequest("CreateOrder", {

   id: 123,

   status: "new"

});

Rules


RestApi.wait

Signature

RestApi.wait(): void

RestApi.wait(timeout: Number): void

Description

Waits until all replies from the last commit() finish or until timeout occurs.

Arguments

timeout

If omitted:

Returns

Behavior

If timeout occurs:

Example

RestApi.commit();

RestApi.wait();

RestApi.commit();

RestApi.wait(10000);

Important

This function does not return false on timeout.
Instead, it raises a JS error in the runtime.

Rules


Response and request internals worth documenting

Supported HTTP methods

From current source:

Default timeout

If timeout <= 0 or missing:

SSL errors

onsslErrors(...) deletes the reply object and ignores detailed SSL errors in the shown implementation.

Reply storage

On each finished reply, runtime stores:


Recommended usage patterns

Pattern 1 — one named request

onStartup:

   InDriver.import("RestApi");

   RestApi.defineRequest("Krakow", {

       url: "https://api.openweathermap.org/data/2.5/weather?appid=your_app_id&q=krakow",

       timeout: 5000,

       type: "get",

       headers: {

           ContentTypeHeader: "application/json"

       }

   });

   InDriver.installHook(60000);

}

onHook:

   RestApi.sendRequest("Krakow");

   RestApi.wait();

   if (RestApi.isSucceeded()) {

       const data = RestApi.getData("Krakow");

       InDriver.debug(data);

   }

Pattern 2 — parallel requests

RestApi.begin();

RestApi.sendRequest("Krakow");

RestApi.sendRequest("Chicago");

RestApi.commitWait();

if (RestApi.isSucceeded()) {

   const krakow = RestApi.getData("Krakow");

   const chicago = RestApi.getData("Chicago");

}

Pattern 3 — POST with payload

RestApi.defineRequest("CreateOrder", {

   url: "https://example.com/api/orders",

   timeout: 5000,

   type: "post",

   headers: {

       ContentTypeHeader: "application/json"

   }

});

RestApi.sendRequest("CreateOrder", {

   id: 123,

   status: "new"

});

RestApi.wait();


Rules

When generating code using RestApi, follow these rules:

  1. Import RestApi in onStartup().
  2. Use defineRequest(...) for reusable calls.
  3. Only assume support for get, post, and put.
  4. After immediate sendRequest(...), call wait().
  5. After begin(), call commit() + wait() or commitWait().
  6. Use getData(...) only after wait/commitWait has completed.
  7. Treat isSucceeded() as timeout/transaction completion status, not a full semantic HTTP success guarantee.


ModbusApi

ModbusApi provides Modbus device communication for JavaScript tasks. It supports:

The API is stateful. It stores:

ModbusApi.begin

Signature

ModbusApi.begin(): void

Description

Starts a Modbus transaction block.

After begin():

Returns

Example

ModbusApi.begin();

ModbusApi.readDevice("Moxa1", '{"name":"coils","type":"COILS","address":1,"size":8}');

ModbusApi.commitWait();

Rules


ModbusApi.commit

Signature

ModbusApi.commit(): void

Description

Executes all queued Modbus requests collected after begin(), but does not wait for completion.

Behavior

Returns

Important

After commit(), you normally call:

ModbusApi.wait();

or

ModbusApi.wait(timeout);

Example

ModbusApi.begin();

ModbusApi.readDevice("Moxa1", '{"name":"coils","type":"COILS","address":1,"size":8}');

ModbusApi.commit();

ModbusApi.wait();


ModbusApi.commitWait

Signature

ModbusApi.commitWait(): void

Description

Executes all queued requests and waits for their completion or timeout.

Behavior

Internally equivalent to:

ModbusApi.commit();

ModbusApi.wait();

Returns

Example

ModbusApi.begin();

ModbusApi.readDevice("Moxa1", '{"name":"coils","type":"COILS","address":1,"size":8}');

ModbusApi.commitWait();

Rules


ModbusApi.connectDevice

Signature

ModbusApi.connectDevice(deviceName: String, cfg: String): void

Description

Creates a named Modbus device connection definition.

If the device name does not already exist, a new JSModbusDevice instance is created and stored.
If the device name already exists, the current code does nothing — it does not overwrite or reconfigure the existing device.

Arguments

deviceName

cfg

Supported connection modes

TCP mode

Supported keys from manual:

Minimal TCP example:

{

 "mode": "TCP",

 "networkAddress": "192.168.0.22"

}

Full TCP example:

{

 "mode": "TCP",

 "networkAddress": "192.168.0.22",

 "networkPort": 502,

 "timeoutMs": 3000,

 "numberOfRetries": 3

}

RTU mode

Supported keys from manual:

Minimal RTU example:

{

 "mode": "RTU",

 "serialPortName": "COM1"

}

Full RTU example:

{

 "mode": "RTU",

 "serialPortName": "COM1",

 "baudRate": 9600,

 "parity": 2,

 "dataBits": 8,

 "stopBits": 1,

 "timeoutMs": 3000,

 "numberOfRetries": 3

}

Returns

Behavior

Example

ModbusApi.connectDevice(

   "IOLogic",

   '{"mode":"TCP","networkAddress":"192.168.0.22"}'

);

Edge cases

Rules


ModbusApi.getAllData

Signature

ModbusApi.getAllData(): String

Description

Returns the data collected in the last Modbus transaction for all devices and all requests, serialized as JSON string.

Returns

Behavior

Iterates over all requests in the last transaction and merges their result data into one JSON object.

Example output

{

 "Moxa1": {

   "Read": {

     "coilsA": {

       "1": true,

       "2": false

     }

   }

 }

}

Example

let dataJson = ModbusApi.getAllData();

let data = JSON.parse(dataJson);

Rules


ModbusApi.getDeviceData

Signature

ModbusApi.getDeviceData(deviceName: String): String

Description

Returns the last transaction data for one selected device, serialized as JSON string.

Arguments

deviceName

Returns

Behavior

Filters last transaction requests by deviceName and builds JSON only for that device.

Example

let deviceData = JSON.parse(ModbusApi.getDeviceData("Moxa1"));


ModbusApi.getDeviceRequestData

Signature

ModbusApi.getDeviceRequestData(deviceName: String, registerName: String): String

Description

Returns the last transaction data for one selected device and one selected request/register name, serialized as JSON string.

Arguments

deviceName

registerName

Returns

Behavior

Filters last transaction requests by both device name and request/register name.

Example

let coilsA = JSON.parse(ModbusApi.getDeviceRequestData("Moxa1", "coilsA"));


ModbusApi.getDeviceRequestValue

Signature

ModbusApi.getDeviceRequestValue(

   deviceName: String,

   registerName: String,

   addresses: Number[]

): Number

Description

Returns a numeric value composed from selected addresses of the result for the specified device and request.

Arguments

deviceName

registerName

addresses

Returns

Behavior

Example

let value = ModbusApi.getDeviceRequestValue("Moxa1", "coilsA", [1, 2, 3]);

Edge cases

Rules


ModbusApi.isLastTransactionCompleted

Signature

ModbusApi.isLastTransactionCompleted(deviceName: String): Boolean

ModbusApi.isLastTransactionCompleted(): Boolean

Description

Checks whether the last Modbus transaction completed without request-level error/timeout.

Arguments

deviceName

Returns

Behavior

Example

if (!ModbusApi.isLastTransactionCompleted("Moxa1")) {

   InDriver.debug("Moxa1 transaction incomplete", "critical");

}

Important nuance

This function checks request completion/error state, while isSucceeded() reflects whether the whole wait cycle completed before timeout. Both can be useful and are not exactly the same thing.


ModbusApi.isSucceeded

Signature

ModbusApi.isSucceeded(): Boolean

Description

Returns whether the last Modbus transaction completed before the wait timeout.

Returns

Behavior

mTransactionSucceeded becomes true only when wait(...) finishes because all requests completed before the timer expired. If timeout occurs, it remains false.

Example

if (ModbusApi.isSucceeded()) {

   let data = ModbusApi.getAllData();

}

Rules


ModbusApi.readDevice

Signature

ModbusApi.readDevice(deviceName: String, registerCfg: String): void

Description

Queues or executes a Modbus read request for the specified device.

Arguments

deviceName

registerCfg

Supported keys from manual:

Example:

{

 "name": "coils1",

 "deviceAddress": 1,

 "type": "COILS",

 "address": 1,

 "size": 8

}

Returns

Behavior

Example

ModbusApi.readDevice(

   "IOLogic",

   '{"name":"coils1","type":"COILS","address":1,"size":8}'

);

Rules


ModbusApi.wait

Signature

ModbusApi.wait(): void

ModbusApi.wait(maxTimeOut: Number): void

Description

Waits for completion of the last committed Modbus transaction.

Arguments

maxTimeOut

If omitted:

Returns

Behavior

Example

ModbusApi.commit();

ModbusApi.wait();

ModbusApi.commit();

ModbusApi.wait(10000);

Notes for AI


ModbusApi.writeDevice

Signature

ModbusApi.writeDevice(deviceName: String, registerCfg: String): void

Description

Queues or executes a Modbus write request for the specified device.

Arguments

deviceName

registerCfg

Supported keys from manual:

Example:

{

 "name": "coils1",

 "deviceAddress": 1,

 "type": "COILS",

 "address": 1,

 "data": [1, 1, 1]

}

Returns

Behavior

begin()

append request

commitWait()

Example

ModbusApi.writeDevice(

   "Moxa",

   '{"name":"coils1","type":"COILS","address":1,"data":[1,1,1]}'

);

Rules


Recommended usage patterns

Pattern 1 — one immediate read

onHook()

   ModbusApi.readDevice(

       "IOLogic",

       '{"name":"coils1","type":"COILS","address":1,"size":8}'

   );

   if (ModbusApi.isSucceeded()) {

       let data = JSON.parse(ModbusApi.getAllData());

       InDriver.debug(data);

   }

Pattern 2 — batched reads

ModbusApi.begin();

ModbusApi.readDevice("Moxa1", '{"name":"coilsA","type":"COILS","address":1,"size":4}');

ModbusApi.readDevice("Moxa1", '{"name":"coilsB","type":"COILS","address":5,"size":4}');

ModbusApi.readDevice("Moxa2", '{"name":"coils","type":"COILS","address":1,"size":8}');

ModbusApi.commitWait();

if (ModbusApi.isSucceeded()) {

   let all = JSON.parse(ModbusApi.getAllData());

}

Pattern 3 — mixed transaction with RestApi

ModbusApi.begin();

RestApi.begin();

RestApi.sendRequest("Krakow");

ModbusApi.readDevice("IOLogic", '{"name":"coils1","type":"COILS","address":1,"size":8}');

ModbusApi.commit();

RestApi.commit();

ModbusApi.wait();

RestApi.wait();

const weatherData = RestApi.getData("Krakow");

const modbusData = ModbusApi.getAllData();


Notes for code generation

When generating code with ModbusApi, follow these rules:

  1. Call InDriver.import("ModbusApi") in onStartup().
  2. Call connectDevice(...) once during initialization.
  3. Use begin()...commitWait() for multiple requests.
  4. After reading returned JSON text, use JSON.parse(...) if structured access is needed.
  5. Use isSucceeded() for overall transaction timeout success.
  6. Use isLastTransactionCompleted(...) for finer completion/error checks.
  7. Use getDeviceRequestValue(...) only when you know the requested addresses are within the register range.


DeviceAPI

DeviceAPI is a generic transaction layer for reading data from external devices connected through:

It provides:

DeviceAPI is intended to be used through derived classes such as:

DeviceAPI.begin

Signature

deviceApi.begin(): void

Description

Starts a grouped device transaction.

Behavior

Example

modbus.begin();
mbus.begin();

Rules


DeviceAPI.commit

Signature

deviceApi.commit(): void

Description

Starts execution of queued device requests without blocking until completion.

Behavior

Example

modbus.begin();

modbus.execute(req1);

modbus.execute(req2);

modbus.commit();

Rules


DeviceAPI.commitWait

Signature

deviceApi.commitWait(timeout: Number = 0): void

Description

Executes queued device requests and waits until they finish or the timeout is reached.

Arguments

timeout

Behavior

Example

ModbusApi.begin();

MacREJ5R_readVQTAsyncReq("BB_Pion2_Gaz", 1);

ModbusApi.commitWait();

Rules


DeviceAPI.debugModeEnabled

Signature

deviceApi.debugModeEnabled(enabled: Boolean): void

Description

Enables or disables verbose device debug logging.

Behavior

When enabled, the API logs:

Example

modbus.debugModeEnabled(false);

mbus.debugModeEnabled(false);

Rules


DeviceAPI.execute

Signature

deviceApi.execute(deviceConfig: Object): void

Description

Queues a device request for execution.

Arguments

deviceConfig

Required transport fields

Every request should provide:

Depending on protocol, it also needs:

Behavior

Example

modbus.execute(ar252_ValuesModbusRequest("ar252_1", 1, "socket_Pion2_Com1", "RTUoverTCP") );

Rules


DeviceAPI.getDeviceData

Signature

deviceApi.getDeviceData(device: String = ""): Object

Description

Returns collected device data.

Arguments

device

Returns

Object

Behavior

Example

let modbusJSON = modbus.getDeviceData();

let mbusJSON = mbus.getDeviceData();

Rules


DeviceAPI.getStatistics

Signature

deviceApi.getStatistics(): Object

Description

Returns execution statistics grouped by communication port and device name.

Returned fields

Typical statistics include:

Example

let stats = modbus.getStatistics();

InDriver.debug(stats);


DeviceAPI.waitForDevices

Signature

deviceApi.waitForDevices(otherDevices: Array = [], timeout: Number = 0): void

Description

Waits until the current API instance and optional additional API instances finish execution.

Arguments

otherDevices

timeout

Behavior

Example

modbus.commit();

mbus.commit();

modbus.waitForDevices([mbus]);

This matches your usage pattern.

Rules


DeviceAPI transport model

Description

DeviceAPI selects transport based on deviceConfig.mode:

Requests are sent through:

On timeout:

Rules


MbusAPI

MbusAPI is a device-level API for M-Bus meters. It extends DeviceAPI and adds:

Supported device types in the attached scripts:

MbusAPI.exec

Signature

mbusApi.exec(deviceConfig: Object): Boolean

Description

Creates the correct M-Bus device handler and starts the request sequence.

Arguments

deviceConfig

Required fields

Common M-Bus-specific fields:

Supported device values

Returns

Boolean

Example

mbus.execute({

   name: "BB_LakPion2_Woda",

   device: "KamstrupMultical",

   fnc: "readData",

   item: "values",

   deviceId: 0,

   address: 1,

   frameSendDelay: 100,

   commPort: "socket_Pion2_Com2",

   mode: "TCP"

});

This matches your current usage.

Rules


MbusAPI.receive

Signature

mbusApi.receive(data: Object): void

Description

Processes received transport data and forwards it to the correct device instance.

Behavior

Rules


M-Bus device flow

Description

The attached M-Bus device classes follow a common flow:

  1. send() creates and sends initial telegram
  2. if address is 0, device initialization telegram is sent first
  3. receive() validates the reply
  4. if the reply is correct:

Rules


ModbusAPI

ModbusAPI is a device-level API for Modbus communication. It extends DeviceAPI and supports:

ModbusAPI.exec

Signature

modbusApi.exec(deviceConfig: Object): Boolean

Description

Creates the correct Modbus request handler and starts the request.

Required fields

Additional fields depend on function:

Supported fnc values

Returns

Boolean

Example

modbus.execute({

   name: "BB_LakierniaPion2_Cieplo",

   item: "values",

   fnc: "ReadHoldingRegisters",

   slaveAddress: 94,

   startAddress: 0,

   quantity: 54,

   frameSendDelay: 20,

   commPort: "socket_Pion2_Com1",

   mode: "RTUoverTCP"

});

This matches the helper-generated requests used in your script.

Rules


ModbusAPI.receive

Signature

modbusApi.receive(data: Object): void

Description

Processes received Modbus data and forwards it to the correct request instance.

Behavior

Rules


ModbusAPI transport behavior

Description

For mode: "TCP", request frames are converted from RTU format into Modbus TCP format before sending. For RTU responses, CRC validation is performed; for TCP responses, the MBAP header is stripped before Modbus response parsing.

Rules


Device libraries

The attached device libraries build reusable device-specific logic on top of ModbusAPI or MbusAPI. They follow a consistent pattern:

This is the recommended level for AI-generated code, because protocol details stay separate from business logic.

AR252 library

Description

The apar.js helper provides support for the AR252 device. It includes:

Returned values

The parser returns:

Example

modbus.execute(

   ar252_ValuesModbusRequest("ar252_1", 1, "socket_Pion2_Com1", "RTUoverTCP")

);

let modbusJSON = modbus.getDeviceData();

if ("ar252_1" in modbusJSON) {

   let d = ar252_ParseValuesModbus(modbusJSON.ar252_1.values);

}

Rules


CMK03 library

Description

The common.js helper contains support for CMK03. It provides request builders such as:

and parsers such as:

Returned values

Typical parsed values:

Rules


Multical Modbus library

Description

The kamstrup.js helper includes:

Returned values

The parser returns a normalized object containing fields such as:

Example

modbus.execute(

   multical_KeyValuesModbusRequest(

       "BB_LakierniaPion2_Cieplo",

       94,

       "socket_Pion2_Com1",

       "RTUoverTCP"

   )

);

This matches your script.


MacREJ5R library

Description

The plum.js helper provides support for MacREJ5R. It includes:

Returned values

Typical parsed values:

Example

ModbusApi.begin();

MacREJ5R_readVQTAsyncReq("BB_Pion2_Gaz", 1);

ModbusApi.commitWait();

let data = JSON.stringify(MacREJ5R_readVQTAsyncProcess("BB_Pion2_Gaz"));

This matches your current pattern.

Rules


M-Bus device libraries

Description

The mbusAPI.js file contains three device classes:

Returned values

Example

mbus.execute({

   name: "BB_LakPion2_Woda",

   device: "KamstrupMultical",

   fnc: "readData",

   item: "values",

   deviceId: 0,

   address: 1,

   frameSendDelay: 100,

   commPort: "socket_Pion2_Com2",

   mode: "TCP"

});

Rules


Recommended usage patterns

Pattern 1 — startup initialization

onStartup:

   InDriver.import("SerialPortApi");

   InDriver.import("TcpSocketApi");

   InDriver.import("ModbusApi");

   InDriver.loadScript("deviceLibrary/deviceAPI.js");

   InDriver.loadScript("deviceLibrary/modbusAPI.js");

   InDriver.loadScript("deviceLibrary/mbusAPI.js");

   InDriver.loadScript("deviceLibrary/kamstrup.js");

   InDriver.loadScript("deviceLibrary/plum.js");

   InDriver.loadScript("deviceLibrary/apar.js");

   TcpSocketApi.connect("socket_Pion2_Com1", {

       address: "10.4.107.186",

       port: 4001,

       timeout: 5000,

       mode: "Buffer"

   });

   TcpSocketApi.connect("socket_Pion2_Com2", {

       address: "10.4.107.186",

       port: 4002,

       timeout: 5000,

       mode: "Buffer"

   });

   var modbus = new ModbusAPI();

   var mbus = new MbusAPI();

   modbus.debugModeEnabled(false);

   mbus.debugModeEnabled(false);


Pattern 2 — grouped Modbus and M-Bus execution

onHook:

   modbus.begin();

   mbus.begin();

   modbus.execute(

       multical_KeyValuesModbusRequest(

           "BB_LakierniaPion2_Cieplo",

           94,

           "socket_Pion2_Com1",

           "RTUoverTCP"

       )

   );

   modbus.execute(

       ar252_ValuesModbusRequest("ar252_1", 1, "socket_Pion2_Com1", "RTUoverTCP")

   );

   mbus.execute({

       name: "BB_LakPion2_Woda",

       device: "KamstrupMultical",

       fnc: "readData",

       item: "values",

       deviceId: 0,

       address: 1,

       frameSendDelay: 100,

       commPort: "socket_Pion2_Com2",

       mode: "TCP"

   });

   modbus.commit();

   mbus.commit();

   modbus.waitForDevices([mbus], 5000);

   let modbusJSON = modbus.getDeviceData();

   let mbusJSON = mbus.getDeviceData();


Pattern 3 — insert parsed data into TSAPI storage

if ("ar252_1" in modbusJSON) {

   let d = ar252_ParseValuesModbus(modbusJSON.ar252_1.values);

   InDriver.sqlExecute(

       "LocalPGSQL",

       `select tsapiinsert('public', 'measurements', 'BB_ar252_1', '${ts.toISOString()}', '${JSON.stringify(d)}')`

   );

}


Rules for code generation

When generating code with DeviceAPI, MbusAPI, ModbusAPI, and the device helper libraries, follow these rules:

1. Import and load everything explicitly

InDriver.import("SerialPortApi");

InDriver.import("TcpSocketApi");

InDriver.import("ModbusApi");

InDriver.loadScript("deviceLibrary/deviceAPI.js");

InDriver.loadScript("deviceLibrary/modbusAPI.js");

InDriver.loadScript("deviceLibrary/mbusAPI.js");

2. Use grouped execution for many devices

begin → execute → commit/commitWait → getDeviceData

3. For parallel Modbus + M-Bus cycles

modbus.commit();

mbus.commit();

modbus.waitForDevices([mbus]);

4. Always provide transport fields

5. For ModbusAPI, use exact fnc values

6. For MbusAPI, use exact device values

7. Prefer helper request builders and parsers

Use:

8. Keep protocol logic separate from business logic

9. Use getDeviceData() as the canonical result source


SMTPApi

SmtpApi provides SMTP email functionality for JavaScript tasks in InDriver.

It supports:

The API is stateful, similar to RestApi and ModbusApi.


Execution modes

1. Immediate mode

SmtpApi.send(...)

2. Transaction mode

SmtpApi.begin();

SmtpApi.send(...);

SmtpApi.send(...);

SmtpApi.commit();


SmtpApi.begin

Signature

SmtpApi.begin(): void

Description

Starts a new email transaction.

Behavior

Returns

Example

SmtpApi.begin();

Rules


SmtpApi.commit

Signature

SmtpApi.commit(): Boolean

Description

Sends all emails queued since the last begin() call.

Returns

Boolean

Meaning

Behavior

Example

SmtpApi.begin();

SmtpApi.send({...});

SmtpApi.send({...});

if (!SmtpApi.commit()) {

   InDriver.debug(SmtpApi.lastError(), "critical");

}

Rules


SmtpApi.configure

Signature

SmtpApi.configure(cfg: String): Boolean

SmtpApi.configure(cfg: Object): Boolean

Description

Configures SMTP server settings for subsequent send() operations.

Arguments

cfg

Supported fields

Field

Type

Required

Description

host

String

SMTP server hostname

port

Number

SMTP port

username

String

authentication username

password

String

authentication password

ssl

Boolean

enable SSL/TLS

Returns

Boolean

Behavior

Example

SmtpApi.configure({

   host: "smtp.company.com",

   port: 587,

   username: "user",

   password: "pass",

   ssl: true

});

Rules


SmtpApi.send

Signature

SmtpApi.send(mail: String): Boolean

SmtpApi.send(mail: Object): Boolean

Description

Adds an email to the queue or sends it immediately depending on execution mode.

Arguments

mail

Supported fields

Field

Type

Required

Description

from

String

sender email

to

String / Array

recipient(s)

subject

String

email subject

body

String

email body

attachments

Array

list of file paths

Returns

Boolean

Meaning

Behavior

Immediate mode

Transaction mode (begin() used)

Example — immediate

SmtpApi.send({

   from: "system@company.com",

   to: "admin@company.com",

   subject: "Alert",

   body: "Machine stopped"

});

Example — batch

SmtpApi.begin();

SmtpApi.send({

   from: "system@company.com",

   to: "a@company.com",

   subject: "Report A"

});

SmtpApi.send({

   from: "system@company.com",

   to: "b@company.com",

   subject: "Report B"

});

SmtpApi.commit();

Rules


SmtpApi.lastError

Signature

SmtpApi.lastError(): String

Description

Returns the last SMTP error message.

Returns

String

Example

if (!SmtpApi.commit()) {

   InDriver.debug(SmtpApi.lastError(), "critical");

}

Typical errors


Recommended usage patterns


Pattern 1 — simple alert

SmtpApi.configure({

   host: "smtp.company.com",

   from: "indriver@company.com"

});

SmtpApi.send({

   to: "maintenance@company.com",

   subject: "ALERT",

   body: "Machine stopped"

});


Pattern 2 — batch notifications

SmtpApi.configure({

   host: "smtp.company.com",

   from: "indriver@company.com"

});

SmtpApi.begin();

for (let user of users) {

   SmtpApi.send({

       to: user.email,

       subject: "Daily report",

       body: user.report

   });

}

if (!SmtpApi.commit()) {

   InDriver.debug(SmtpApi.lastError(), "critical");

}


Notes for code generation

When generating code using SmtpApi, follow these rules:

  1. Always configure SMTP first:

SmtpApi.configure(...)

  1. Use transaction mode for multiple emails:

begin → send → commit

  1. Always check for errors:

if (!SmtpApi.commit()) → lastError()

  1. Do not assume:



TsApi

TsApi provides time-series aggregation support for InDriver tasks. It is built around an internal aggregator engine defined in C++, while the SQL package (tsapi.sql) defines the standard database structures and helper SQL functions used by the engine. In practice, TsApi is responsible for creating and maintaining aggregation tables derived from a raw JSON time-series table.

Standard TSAPI database model

The SQL package installs a set of helper functions and standard table structures. The most important pieces are:

Raw time-series table

Created by tsapicreatetable(schema_, name_):

This is the base table for raw data collection. Each row represents one source at one timestamp with JSON payload in data.

Aggregation table

Created by tsapicreateaggregationtable(schema_, name_):

(source text, ts timestamp with time zone, data jsonb, extras jsonb)

This is the standard structure used by the aggregation engine. The extras column stores aggregation metadata/statistics. In the SQL package, helper functions such as tsapiselectaggdata expose extras->>'status', which confirms that extras is part of the standard aggregation contract.

Aggregation Table column

extras [JSON]

Aggregation Table column

data [JSON]

Installed helper SQL functions

The package also installs functions such as:

tsapiinstall

Signature

tsapiinstall(schema_ text) returns void

Description

Installs the TSAPI package in the selected schema. This function registers the API in inapi_installedapis and creates the TSAPI SQL functions such as table creation, inserts, and selects.

Arguments

schema_

Returns

Example

select tsapiinstall('public');

Rules


tsapiuninstall

Signature

tsapiuninstall(schema_ text) returns void

Description

Uninstalls TSAPI from the selected schema. It removes the TSAPI entry from inapi_installedapis and drops the installed TSAPI functions.

Arguments

schema_

Returns

Example

select tsapiuninstall('public');

Rules


tsapiversion

Signature

tsapiversion() returns table (ver text, dbtype text)

Description

Returns the installed TSAPI version and the target database type. In the attached script, the reported values are ver = '2.0' and dbtype = 'QPSQL'.

Returns

Example

select * from tsapiversion();

Rules


tsapicreatetable

Signature

tsapicreatetable(schema_ text, name_ text) returns void

Description

Creates a standard raw time-series table if it does not already exist. The created table contains columns source, ts, and data, and TSAPI also creates indexes for ts and source.

Arguments

schema_

name_

Returns

Example

select tsapicreatetable('public', 'measurements');

Rules


tsapicreateaggregationtable

Signature

tsapicreateaggregationtable(schema_ text, name_ text) returns void

Description

Creates a standard aggregation table if it does not already exist. The created table contains source, ts, data, and extras, and TSAPI also creates indexes for ts and source.

Arguments

schema_

name_

Returns

Example

select tsapicreateaggregationtable('public', 'measurements_1h');

Rules


tsapideletetable

Signature

tsapideletetable(schema_ text, name_ text) returns void

Description

Drops a table if it exists, using CASCADE.

Arguments

schema_

name_

Returns

Example

select tsapideletetable('public', 'measurements_old');

Rules


tsapiinsert

Signature

tsapiinsert(

   schema_ text,

   table_ text,

   source_ text,

   ts_ timestamp with time zone,

   data_ jsonb

) returns void

Description

Inserts a single raw time-series record into a TSAPI table. The inserted row contains the specified source, timestamp, and JSON payload in data.

Arguments

schema_

table_

source_

ts_

data_

Returns

Example

select tsapiinsert(

   'public',

   'measurements',

   'BB_ar252_1',

   now(),

   '{"t": 21.4, "rH": 45.0}'::jsonb

);

Rules


tsapiinsertvalues

Signature

tsapiinsertvalues(

   schema_ text,

   table_ text,

   source_ text,

   data_ json

) returns void

Description

Bulk inserts raw time-series values for one source from a JSON array. Before inserting, the function deletes existing rows for the same source starting from the minimum incoming timestamp used in the JSON array logic. The input array is expected to contain objects with ts and data.

Arguments

schema_

table_

source_

data_

Expected JSON element structure

[

 {

   "ts": "2026-04-21T10:00:00Z",

   "data": { "t": 21.4 }

 }

]

This structure is implied by the function reading i->>'ts' and i->>'data'.

Returns

Example

select tsapiinsertvalues(

   'public',

   'measurements',

   'BB_ar252_1',

   '[

      {"ts":"2026-04-21T10:00:00Z","data":{"t":21.4}},

      {"ts":"2026-04-21T10:01:00Z","data":{"t":21.5}}

    ]'::json

);

Rules


tsapiinsertagg

Signature

tsapiinsertagg(

   schema_ text,

   table_ text,

   source_ text,

   dataandextras_ json

) returns void

Description

Bulk inserts aggregated time-series rows into an aggregation table. Before inserting, it finds the minimum timestamp in the provided JSON array and deletes existing rows for that source from that timestamp onward. Then it inserts rows containing ts, data, and extras.

Arguments

schema_

table_

source_

dataandextras_

Expected JSON element structure

[

 {

   "ts": "2026-04-21T10:00:00Z",

   "data": { "avg": 21.4 },

   "extras": { "status": "ok" }

 }

]

This structure is required because the function reads ts, data, and extras from each JSON element.

Returns

Example

select tsapiinsertagg(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '[

      {

        "ts":"2026-04-21T10:00:00Z",

        "data":{"avg":21.4},

        "extras":{"status":"ok"}

      }

    ]'::json

);

Rules


tsapiselectdistinctsources

Signature

tsapiselectdistinctsources(schema_ text, table_ text)

Description

Returns the distinct source names present in the selected table.

Arguments

schema_

table_

Returns

Example

select * from tsapiselectdistinctsources('public', 'measurements');

Rules


tsapiselect

Signature

tsapiselect(

   schema_ text,

   table_ text,

   source_ text,

   tsfrom_ text,

   tsto_ text,

   limit_ integer

) returns table (ts timestamp with time zone, data jsonb)

Description

Returns raw time-series rows for one source, optionally filtered by start time, end time, and row limit. Results are ordered ascending by ts when a positive limit is used.

Arguments

schema_

table_

source_

tsfrom_

tsto_

limit_

Returns

Example

select * from tsapiselect(

   'public',

   'measurements',

   'BB_ar252_1',

   '2026-04-21T00:00:00Z',

   '2026-04-21T23:59:59Z',

   1000

);

Rules


tsapiselectfirst

Signature

tsapiselectfirst(schema_ text, table_ text, source_ text)

Description

Returns the earliest raw row for the selected source.

Arguments

schema_

table_

source_

Returns

Example

select * from tsapiselectfirst('public', 'measurements', 'BB_ar252_1');

Rules


tsapiselectlast

Signature

tsapiselectlast(schema_ text, table_ text, source_ text)

Description

Returns the latest raw row for the selected source.

Arguments

schema_

table_

source_

Returns

Example

select * from tsapiselectlast('public', 'measurements', 'BB_ar252_1');

Rules


tsapiselectlastn

Signature

tsapiselectlastn(

   schema_ text,

   table_ text,

   source_ text,

   n_ integer

)

Description

Returns the last n raw time-series samples for the selected source.

This function is intended for cases where the caller needs the most recent group of samples instead of only one latest row. Typical use cases include:

Arguments

schema_

table_

source_

n_

Returns

Behavior

Example

select * from tsapiselectlastn(

   'public',

   'measurements',

   'BB_ar252_1',

   100

);

Example use case

select * from tsapiselectlastn(

   'public',

   'measurements',

   'BB_Pion2_Gaz',

   10

);

This returns the 10 most recent samples for BB_Pion2_Gaz.

Rules

Recommended usage

Use tsapiselectlastn(...) for:


tsapiselectprevious

Signature

tsapiselectprevious(

   schema_ text,

   table_ text,

   source_ text,

   ts_ text

)

Description

Returns the latest raw row strictly earlier than the provided timestamp.

Arguments

schema_

table_

source_

ts_

Returns

Example

select * from tsapiselectprevious(

   'public',

   'measurements',

   'BB_ar252_1',

   '2026-04-21T10:00:00Z'

);

Rules


tsapiselectagg

Signature

tsapiselectagg(

   schema_ text,

   table_ text,

   source_ text,

   tsfrom_ text,

   tsto_ text,

   limit_ integer

)

Description

Returns aggregation rows for one source, including both aggregated data and extras. It supports optional time bounds and an optional limit.

Arguments

Same semantics as tsapiselect(...), but for aggregation tables.

Returns

Example

select * from tsapiselectagg(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '',

   '',

   100

);

Rules


tsapiselectaggdata

Signature

tsapiselectaggdata(

   schema_ text,

   table_ text,

   source_ text,

   tsfrom_ text,

   tsto_ text,

   limit_ integer

)

Description

Returns aggregation rows for one source, but instead of the full extras JSON it returns only extras->>'status' as status.

Arguments

Same semantics as tsapiselectagg(...).

Returns

Example

select * from tsapiselectaggdata(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '',

   '',

   100

);

Rules


tsapiselectaggwheretsin

Signature

tsapiselectaggwheretsin(

   schema_ text,

   table_ text,

   source_ text,

   tsin_ text,

   limit_ integer

)

Description

Returns aggregation rows whose timestamps are contained in the provided IN (...) expression text.

Arguments

schema_

table_

source_

tsin_

limit_

Returns

Example

select * from tsapiselectaggwheretsin(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '(''2026-04-21T10:00:00Z'',''2026-04-21T11:00:00Z'')',

   10

);

Rules


tsapiselectvariablefromagg

Signature

tsapiselectvariablefromagg(

   schema_ text,

   table_ text,

   source_ text,

   tsfrom_ text,

   tsto_ text,

   limit_ integer

) returns table (ts timestamp with time zone, data jsonb, extras jsonb)

Description

Returns aggregation rows using the same observable signature and query shape as tsapiselectagg(...) in the attached script. The visible SQL snippet shows it selecting ts, data, and extras for a source with optional time bounds and limit.

Arguments

Same semantics as tsapiselectagg(...).

Returns

Example

select * from tsapiselectvariablefromagg(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '',

   '',

   100

);

Rules


Recommended usage patterns

Pattern 1 — create and insert raw TS data

select tsapicreatetable('public', 'measurements');

select tsapiinsert(

   'public',

   'measurements',

   'BB_ar252_1',

   now(),

   '{"t":21.4,"rH":45.0}'::jsonb

);

This is the standard pattern for raw time-series storage.

Pattern 2 — query latest raw value

select * from tsapiselectlast('public', 'measurements', 'BB_ar252_1');

Use this for last-value panels and incremental processing checkpoints.

Pattern 3 — insert and query aggregation data

select tsapicreateaggregationtable('public', 'measurements_1h');

select tsapiinsertagg(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '[

      {

        "ts":"2026-04-21T10:00:00Z",

        "data":{"avg":21.4},

        "extras":{"status":"ok"}

      }

    ]'::json

);

select * from tsapiselectaggdata(

   'public',

   'measurements_1h',

   'BB_ar252_1',

   '',

   '',

   100

);

This is the standard aggregation-table workflow.

Rules for code generation

When generating SQL that uses TSAPI functions, follow these rules:

  1. Use tsapicreatetable(...) for raw data and tsapicreateaggregationtable(...) for aggregation output tables.
  2. Use tsapiinsert(...) for single-row raw inserts and tsapiinsertvalues(...) for bulk inserts for one source.
  3. Use tsapiinsertagg(...) only for aggregation tables, and always include both data and extras in the JSON array.
  4. Use tsapiselect(...), tsapiselectfirst(...), tsapiselectlast(...), and tsapiselectprevious(...) for raw-table retrieval.
  5. Use tsapiselectagg(...) or tsapiselectaggdata(...) for aggregation tables, depending on whether full extras or only status is needed.
  6. Pass empty string '' for optional time parameters when no lower or upper bound should be applied.
  7. Treat tsin_ in tsapiselectaggwheretsin(...) as raw SQL text and construct it carefully.


Time Series JSON Data Aggregation

Supported aggregation periods

The aggregator configuration parses period strings and maps them into three groups:

The defaults from JSAggregatorCfg are:

So the default aggregation cascade is equivalent to:

Aggregation table naming

The aggregator creates a cascade of aggregation tables derived from the source table. The manual states that table names are based on the source table plus interval suffixes such as:

The constructor of JSAggregator confirms that it automatically creates aggregation tables for every configured minute/hour/day interval and builds a cascade from the raw table into those derived tables.

Time zone handling

TsApi accepts a time zone string for the aggregator. In JSAggregatorCfg, the string is converted into QTimeZone. If the provided time zone is invalid, the runtime falls back to UTC. The time zone is especially relevant for day-based aggregation boundaries.

Step size

The aggregator uses stepSize to limit how much data is processed in one aggregation cycle. The manual describes this as the number of source rows handled per aggregation cycle, with the documented default of 10000. The C++ API also exposes setAggregatorStepSize(...) for runtime tuning.

Aggregator source filtering

An aggregator may process:

The config parser reads sourcesJsonArray into sourcesList. If the array is empty, aggregation is not restricted to named sources. If it contains values, only those sources are aggregated.

Aggregator debug mode

The manual says debug mode shows computation time and SQL insert time for each aggregated source and table. The C++ API exposes setAggregatorDebugMode(...), which toggles the internal mDebugMode flag of the selected aggregator.

TsApi.aggregate

Signature

TsApi.aggregate(aggregatorName: String): void

Description

Triggers one aggregation cycle for a previously defined aggregator.

This function is intended to be called from onHook(). It tells the internal aggregation engine to process the next portion of data for the named aggregator. In the C++ implementation, if the aggregator exists, aggregate() is executed on the corresponding JSAggregator instance. If the aggregator name is not defined, the engine throws a RangeError.

Arguments

aggregatorName

Returns

Behavior

Example

function onHook() {

   TsApi.aggregate("a");

}

Rules

TsApi.defineAggregator

Signature

TsApi.defineAggregator(

   aggregatorName: String,

   serverName: String,

   sourceTableName: String

): void

TsApi.defineAggregator(

   aggregatorName: String,

   serverName: String,

   sourceTableName: String,

   timeZone: String

): void

TsApi.defineAggregator(

   aggregatorName: String,

   serverName: String,

   sourceTableName: String,

   timeZone: String,

   sourcesJsonArray: String

): void

TsApi.defineAggregator(

   aggregatorName: String,

   serverName: String,

   sourceTableName: String,

   timeZone: String,

   sourcesJsonArray: String,

   periodsJsonArray: String

): void

TsApi.defineAggregator(

   aggregatorName: String,

   serverName: String,

   sourceTableName: String,

   timeZone: String,

   sourcesJsonArray: String,

   periodsJsonArray: String,

   stepSize: Number

): void

TsApi.defineAggregator(

   aggregatorName: String,

   cfg :JSonObject{

      "serverName":"sqlServer",

      "sourceTable":"raw_table",

      "aggregationTable":"aggtable",

      "timeZone":"Europe/Warsaw",

      "sources":["source"],

      "stepSize":10000,

      "debugMode":true

   }

): void

Description

Creates and registers a named aggregation engine.

This is the central TsApi configuration function. It binds an aggregator name to:

Arguments

aggregatorName

serverName

sourceTableName

"public.weather"

The source table is expected to follow the TSAPI raw table standard:

(source text, ts timestamp with time zone, data jsonb)

timeZone

Examples:

"UTC"

"Europe/Warsaw"

"America/Chicago"

If invalid:

sourcesJsonArray

Examples:

"[]"

'["SENSOR_1","SENSOR_2"]'

Behavior:

periodsJsonArray

Supported format:

Only strings ending with:

are parsed into minute/hour/day period buckets.

Default behavior from JSAggregatorCfg:

stepSize

The code exposes this field in the configuration object and manual documents default usage around 10000 rows per cycle.

Returns

Behavior

When an aggregator is defined:

Examples

Minimal definition

InDriver.import("TsApi");

TsApi.defineAggregator("a", "azureserver", "public.weather");

Explicit time zone

TsApi.defineAggregator(

   "weatherAgg",

   "azureserver",

   "public.weather",

   "Europe/Warsaw"

);

Specific sources only

TsApi.defineAggregator(

   "weatherAgg",

   "azureserver",

   "public.weather",

   "UTC",

   '["Krakow","Chicago"]'

);

Custom periods

TsApi.defineAggregator(

   "weatherAgg",

   "azureserver",

   "public.weather",

   "UTC",

   '["Krakow","Chicago"]',

   '["1m","5m","1h","1d"]'

);

Custom step size

TsApi.defineAggregator(

   "weatherAgg",

   "azureserver",

   "public.weather",

   "UTC",

   '["Krakow","Chicago"]',

   '["1m","5m","1h","1d"]',

   20000

);

Rules

TsApi.setAggregatorDebugMode

Signature

TsApi.setAggregatorDebugMode(aggregatorName: String, mode: Boolean): void

Description

Enables or disables debug mode for a selected aggregator.

The manual describes debug mode as exposing timing/debug information for calculations and SQL insert operations performed by the aggregator. The C++ implementation sets an internal mDebugMode flag on the matching aggregator if it exists. If the name is missing, nothing happens.

Arguments

aggregatorName

mode

Returns

Behavior

Example

TsApi.setAggregatorDebugMode("weatherAgg", true)

Rules

TsApi.setAggregatorStepSize

Signature

TsApi.setAggregatorStepSize(aggregatorName: String, stepSize: Number): void

Description

Updates the step size for an existing aggregator.

Step size controls how much data the aggregation engine processes during one TsApi.aggregate(...) cycle. This is useful for tuning throughput versus execution time. The C++ implementation updates the internal step size only if the aggregator exists.

Arguments

aggregatorName

stepSize

Returns

Behavior

Example

TsApi.setAggregatorStepSize("weatherAgg", 5000);

Rules

Recommended TSAPI usage pattern

onStartup:

   InDriver.import("TsApi");

   TsApi.defineAggregator(

       "weatherAgg",

       "azureserver",

       "public.weather",

       "UTC",

       "[]",

       '["1m","15m","1h","1d"]',

       10000

   );

   TsApi.setAggregatorDebugMode("weatherAgg", true);

   InDriver.installHook(60000);

onHook:

   TsApi.aggregate("weatherAgg");

This pattern matches the intended TsApi workflow: define once during startup, then trigger incremental aggregation from onHook().

Notes for code generation

When generating code using TsApi, follow these rules:

  1. Import TsApi in onStartup().
  2. Define aggregators in onStartup().
  3. Call TsApi.aggregate(...) in onHook().
  4. Use raw source tables with this standard structure:
  1. Assume aggregation tables use:
  1. Pass sourcesJsonArray and periodsJsonArray as JSON strings.
  2. Use valid period suffixes only: m, h, d.
  3. If time zone is uncertain, use "UTC" explicitly.

Important implementation insights

The code and SQL together show that TsApi is not just a wrapper around one SQL function. It is a coordinated system:

That structure is exactly why TsApi is well suited for AI-generated code: it has a stable data contract, a fixed aggregation model, and clearly defined configuration parameters.


ProcessApi

ProcessApi provides process lifecycle management for external programs in InDriver.

It allows:

The API is stateful — processes are stored internally under a unique name.

Execution model

Processes are managed by name:

ProcessApi.start("myProcess", "python", ["script.py"]);

Then controlled via:

ProcessApi.waitForFinished("myProcess");

ProcessApi.kill("myProcess");

ProcessApi.start

Signature

ProcessApi.start(name: String, program: String, args: Array): String

Description

Starts a new process and registers it under a given name.

Arguments

name

program

args

Returns

String

Meaning

Behavior

Example

ProcessApi.start("job1", "python", ["script.py"]);

ProcessApi.close

Signature

ProcessApi.close(name: String): void

Description

Gracefully closes a running process.

Behavior

Example

ProcessApi.close("job1");

ProcessApi.closeAll

Signature

ProcessApi.closeAll(): void

Description

Gracefully closes all managed processes.

ProcessApi.kill

Signature

ProcessApi.kill(name: String): void

Description

Forcefully terminates a process.

Behavior

Example

ProcessApi.kill("job1");

ProcessApi.killAll

Signature

ProcessApi.killAll(): void

Description

Forcefully terminates all processes.

ProcessApi.waitForStarted

Signature

ProcessApi.waitForStarted(name: String, msecs: Number = 30000): Boolean

Description

Waits until a process starts.

Arguments

name

msecs

Returns

Boolean

Example

ProcessApi.start("job1", "python", ["script.py"]);

if (!ProcessApi.waitForStarted("job1")) {

   InDriver.debug("Process failed to start", "critical");

}

ProcessApi.waitForFinished

Signature

ProcessApi.waitForFinished(name: String, msecs: Number = 30000): Boolean

Description

Waits until a process finishes.

Returns

Example

ProcessApi.waitForFinished("job1", 10000);

ProcessApi.waitAllForStarted

Signature

ProcessApi.waitAllForStarted(msecs: Number = 30000): Boolean

Description

Waits until all processes are started.

ProcessApi.waitAllForFinished

Signature

ProcessApi.waitAllForFinished(msecs: Number = 30000): Boolean

Description

Waits until all processes are finished.

ProcessApi.setWorkingDirectory

Signature

ProcessApi.setWorkingDirectory(name: String, dir: String): void

Description

Sets working directory for a process before start.

Example

ProcessApi.setWorkingDirectory("job1", "c:/scripts");

ProcessApi.workingDirectory

Signature

ProcessApi.workingDirectory(name: String): String

Description

Returns working directory of the process.

ProcessApi.program

Signature

ProcessApi.program(name: String): String

Description

Returns program path used to start the process.

ProcessApi.pid

Signature

ProcessApi.pid(name: String): Number

Description

Returns operating system process ID.

Example

let pid = ProcessApi.pid("job1");

ProcessApi.state

Signature

ProcessApi.state(name: String): String

Description

Returns current process state.

Possible values (typical)

NotRunning

Starting

Running

Finished

ProcessApi.status

Signature

ProcessApi.status(name: String): Object

Description

Returns detailed process status.

Returns

Object

Example structure

{

   state: "Running",

   pid: 1234,

   program: "python",

   workingDirectory: "c:/scripts"

}

ProcessApi.remove

Signature

ProcessApi.remove(name: String): void

Description

Removes process from internal registry.

Behavior

Recommended usage patterns

Pattern 1 — run and wait

ProcessApi.start("job1", "python", ["script.py"]);

if (ProcessApi.waitForFinished("job1")) {

   InDriver.debug("Done");

} else {

   InDriver.debug("Timeout", "critical");

}

Pattern 2 — multiple processes

ProcessApi.start("job1", "python", ["a.py"]);

ProcessApi.start("job2", "python", ["b.py"]);

ProcessApi.waitAllForFinished();

Pattern 3 — watchdog

if (ProcessApi.state("job1") !== "Running") {

   ProcessApi.start("job1", "service.exe", []);

}

Notes for AI code generation

When generating code using ProcessApi, follow these rules:

  1. Always use unique process names:

"job1", "collector", "analyzer"

  1. Wait for start when required:

waitForStarted()

  1. Use timeout protection:

waitForFinished(name, timeout)

  1. Use kill for hard failures:

kill(name)

  1. Clean registry:

remove(name)

Important behavior



PdfApi

PdfApi provides PDF reading and rendering functionality for JavaScript tasks in InDriver.

It allows:

The API is stateful: all functions operate on the currently loaded PDF document.

PdfApi.load

Signature

PdfApi.load(file: String): String

Description

Loads a PDF document from disk.

Arguments

file

Returns

String

Possible return values:

Behavior

Example

InDriver.import("PdfApi");

let status = PdfApi.load(InDriver.currentPath() + "/document.pdf");

InDriver.debug("Load status: " + status);

Rules

PdfApi.isLoaded

Signature

PdfApi.isLoaded(): Boolean

Description

Checks whether a PDF document is currently loaded and ready.

Returns

Boolean

Example

if (!PdfApi.isLoaded()) {

   InDriver.debug("PDF is not loaded", "critical");

}

Rules

PdfApi.pageText

Signature

PdfApi.pageText(page: Number): String

Description

Returns the extracted text of a single PDF page.

Arguments

page

Returns

String

Behavior

Example

let page0 = PdfApi.pageText(0);

InDriver.debug(page0);

Rules

PdfApi.readText

Signature

PdfApi.readText(from: Number = 0, count: Number = -1): String

Description

Returns concatenated text from a page range of the currently loaded PDF.

Arguments

from

count

Returns

String

Behavior

Examples

let allText = PdfApi.readText();

let fromPage5 = PdfApi.readText(5);

let intro = PdfApi.readText(0, 2);

Example

InDriver.import("PdfApi");

PdfApi.load(InDriver.currentPath() + "/manual.pdf");

let intro = PdfApi.readText(0, 2);

InDriver.debug("Intro text:\n" + intro);

Rules

PdfApi.pageLabel

Signature

PdfApi.pageLabel(page: Number): String

Description

Returns the label of a specific page.

Page labels may differ from numeric page indexes in PDFs that use custom numbering schemes.

Arguments

page

Returns

String

Example

let label = PdfApi.pageLabel(0);

InDriver.debug("Page Label: " + label);

Rules

PdfApi.allPageLabels

Signature

PdfApi.allPageLabels(): String[]

Description

Returns labels of all pages in the currently loaded PDF.

Returns

String[]

Behavior

Example

let labels = PdfApi.allPageLabels();

InDriver.debug(labels);

Rules

PdfApi.setCodec

Signature

PdfApi.setCodec(codec: String): Boolean

Description

Sets the codec used for text decoding during PDF text extraction.

Arguments

codec

Returns

Boolean

Example

PdfApi.setCodec("Utf8");

InDriver.debug("Codec set to Utf8");

Rules

PdfApi.pageCount

Signature

PdfApi.pageCount(): Number

Description

Returns the total number of pages in the loaded PDF document.

Returns

Number

Example

let count = PdfApi.pageCount();

InDriver.debug("Total Pages: " + count);

Rules

PdfApi.setPassword

Signature

PdfApi.setPassword(password: String): void

Description

Sets the password used to open a password-protected PDF.

Arguments

password

Returns

Behavior

Example

PdfApi.setPassword("securePassword123");

let status = PdfApi.load(InDriver.currentPath() + "/protected.pdf");

InDriver.debug("Load status: " + status);

Rules

PdfApi.password

Signature

PdfApi.password(): String

Description

Returns the password currently stored in the PDF session.

Returns

String

Example

let pwd = PdfApi.password();

InDriver.debug("Current Password: " + pwd);

Rules

PdfApi.status

Signature

PdfApi.status(): String

Description

Returns the current document status.

Returns

String

Possible values:

Example

let status = PdfApi.status();

InDriver.debug("Pdf status: " + status);

Rules

PdfApi.metadata

Signature

PdfApi.metadata(): String

Description

Returns document metadata as serialized JSON text.

Returns

String

The returned JSON includes at least:

Example

let meta = PdfApi.metadata();

InDriver.debug(meta);

Rules

let meta = JSON.parse(PdfApi.metadata());

PdfApi.asImageBase64

Signature

PdfApi.asImageBase64(page: Number, format: String = "PNG"): String

Description

Renders a PDF page as an image and returns it as a Base64 data URL.

Arguments

page

format

Returns

String

data:image/png;base64,...

Behavior

Example

let img = PdfApi.asImageBase64(0);

InDriver.debug(img);

Rules

PdfApi.savePageAsImage

Signature

PdfApi.savePageAsImage(page: Number, path: String): String

Description

Renders the specified PDF page and saves it as an image file.

Arguments

page

path

Returns

String

Behavior

Example

PdfApi.load(InDriver.currentPath() + "/report.pdf");

let out = PdfApi.savePageAsImage(0, InDriver.currentPath() + "/page0.png");

InDriver.debug("Saved image: " + out);

Rules

PdfApi.close

Signature

PdfApi.close(): void

Description

Closes the currently loaded PDF document.

Returns

Behavior

Example

PdfApi.close();

Rules

Recommended usage pattern

onStartup:

   InDriver.import("PdfApi");

   PdfApi.setCodec("Utf8");

   let status = PdfApi.load(InDriver.currentPath() + "/manual.pdf");

   if (status !== "OK") {

       InDriver.debug("PDF load failed: " + status, "critical");

       return;

   }

   InDriver.debug("Pages: " + PdfApi.pageCount());

   InDriver.debug("Metadata: " + PdfApi.metadata());

   let intro = PdfApi.readText(0, 2);

   InDriver.debug(intro);

   let img = PdfApi.savePageAsImage(0, InDriver.currentPath() + "/page0.png");

   InDriver.debug("Saved image: " + img);

   PdfApi.close();

Notes for AI code generation

When generating code using PdfApi, follow these rules:

  1. Import PdfApi in onStartup():

InDriver.import("PdfApi");

  1. Always load a PDF before reading text or metadata:

let status = PdfApi.load(path);

if (status !== "OK") { ... }

  1. Use PdfApi.isLoaded() or PdfApi.status() as readiness checks.
  2. Validate or infer page indexes from PdfApi.pageCount().
  3. Parse PdfApi.metadata() if structured access is needed.
  4. Use PdfApi.setPassword(...) before load(...) for protected documents.
  5. Use PdfApi.close() when finished.


FileApi

FileApi provides file and directory operations for JavaScript tasks in InDriver.

It supports:

Files are managed using a handle name (name), not directly by path after opening.

FileApi.addFileSystemWatcherPath

Signature

FileApi.addFileSystemWatcherPath(file: String): Boolean

Description

Adds a file or directory to the filesystem watcher.

Arguments

file

Returns

Example

FileApi.addFileSystemWatcherPath("c:/data/config.json");


FileApi.appendLine

Signature

FileApi.appendLine(name: String, line: String): Boolean

Description

Appends a single line to an opened file.

Arguments

name

line

Returns

Example

FileApi.open("log", "c:/log.txt", ["Append"]);

FileApi.appendLine("log", "New event");


FileApi.close

Signature

FileApi.close(name: String): void

Description

Closes an opened file.

Example

FileApi.close("log");


FileApi.closeAll

Signature

FileApi.closeAll(): void

Description

Closes all opened files.


FileApi.copy

Signature

FileApi.copy(from: String, to: String): Boolean

Description

Copies a file from one location to another.

Example

FileApi.copy("c:/a.txt", "c:/backup/a.txt");


FileApi.dirGoTo

Signature

FileApi.dirGoTo(dir: String): Boolean

Description

Changes current working directory to a subdirectory.


FileApi.dirGoToApplicationDirectory

Signature

FileApi.dirGoToApplicationDirectory(): Boolean

Description

Sets working directory to InDriver application directory.


FileApi.dirGoToPath

Signature

FileApi.dirGoToPath(path: String): Boolean

Description

Changes working directory to an absolute path.


FileApi.dirGoUp

Signature

FileApi.dirGoUp(): Boolean

Description

Moves working directory one level up.


FileApi.dirList

Signature

FileApi.dirList(fileTypeFilter: String = ""): String

Description

Returns directory content as serialized string.

Example

let list = FileApi.dirList("*.txt");

InDriver.debug(list);


FileApi.dirLoadFiles

Signature

FileApi.dirLoadFiles(files: String): String

Description

Loads multiple files based on input definition.

FileApi.dirFindFiles

Signature

FileApi.dirFindFiles(filter: Object): Object

Description

Searches for files in a directory using multiple filter conditions.

The function can filter files by:

The function returns a structured object containing matching files and search metadata.

This function is useful for automatic file processing tasks, for example:

Arguments

filter

filter definition object

Supported filter fields

path

optional

Directory path to search.

If not specified, the current FileApi browser directory is used.

Example

path: "C:/Data/Reports"

extensions

optional

List of allowed file extensions.

Extensions can be written with or without leading dot.

Example

extensions: ["xlsx", "csv"]

or

extensions: [".xlsx", ".csv"]

nameFilters

optional

List of wildcard file name filters.

Example

nameFilters: ["*.xlsx", "report_*.csv"]

namePattern

optional

Regular expression matched against the file name.

Example

namePattern: "report_.*\\.xlsx"

minSize

optional

Minimum file size in bytes.

Example

minSize: 1000

maxSize

optional

Maximum file size in bytes.

Example

maxSize: 10485760

createdFrom

optional

Minimum file creation date/time (Local Time).

Format: ISO date/time string.

Example

createdFrom: "2026-06-10T00:00:00"

createdTo

optional

Maximum file creation date/time (Local Time).

Format: ISO date/time string.

Example

createdTo: "2026-06-10T23:59:59"

modifiedFrom

optional

Minimum file modification date/time.

Format: ISO date/time string.

Example

modifiedFrom: "2026-06-10T00:00:00"

modifiedTo

optional

Maximum file modification date/time.

Format: ISO date/time string.

Example

modifiedTo: "2026-06-10T23:59:59"

recursive

optional

If true, subdirectories are scanned recursively.

Default: false

caseSensitive

optional

If true, extension and regular expression matching is case-sensitive.

Default: false

includeTextFlag

optional

If true, the API checks whether each matching file appears to be a text file.

Default: false

Remark:

This option opens and reads the first bytes of every matching file, so it should be disabled for very large searches unless needed.

limit

optional

Maximum number of matching files returned.

If the limit is less than or equal to 0, all matching files are returned.

Returns

Object

The returned object contains:

type

Always:

"FileFinderResult"

path

Searched directory path.

ok

true if search was executed successfully.

false if search failed.

error

Error message, if search failed.

count

Number of returned matching files.

scanned

Number of scanned directory entries.

limited

true if the result was stopped because the limit was reached.

files

Array of matching file objects.

Each file object contains:

name
fileName
path
filePath
absoluteFilePath
absolutePath
suffix
baseName
completeBaseName
size
created
modified
metadataChanged
lastRead
text

Example result

{

   "type": "FileFinderResult",

   "path": "C:/Data/Reports",

   "ok": true,

   "count": 2,

   "scanned": 125,

   "limited": false,

   "files": [

      {

         "name": "report_001.xlsx",

         "fileName": "report_001.xlsx",

         "path": "C:/Data/Reports",

         "filePath": "C:/Data/Reports/report_001.xlsx",

         "absoluteFilePath": "C:/Data/Reports/report_001.xlsx",

         "absolutePath": "C:/Data/Reports",

         "suffix": "xlsx",

         "baseName": "report_001",

         "completeBaseName": "report_001",

         "size": "34890",

         "created": "2026-06-10T08:15:00",

         "modified": "2026-06-10T08:16:10",

         "metadataChanged": "2026-06-10T08:16:10",

         "lastRead": "2026-06-10T08:20:00"

      }

   ]

}

Example

Find XLSX files modified today

let result = FileApi.dirFindFiles({

   path: "C:/Data/Reports",

   extensions: ["xlsx"],

   modifiedFrom: "2026-06-10T00:00:00",

   recursive: false,

   limit: 100

});

if (!result.ok) {

   InDriver.debug(result.error, "critical");

   return;

}

for (let i = 0; i < result.files.length; i++) {

   let file = result.files[i];

   InDriver.debug(file.absoluteFilePath);

}

Example

Find Excel reports by regular expression

let result = FileApi.dirFindFiles({

   path: "C:/Data/Reports",

   extensions: ["xlsx"],

   namePattern: "report_.*\\.xlsx",

   modifiedFrom: "2026-06-01T00:00:00",

   minSize: 1000,

   maxSize: 10485760,

   limit: 500

});

for (let i = 0; i < result.files.length; i++) {

   InDriver.debug(result.files[i].absoluteFilePath);

}

Example

Find files and parse XLSX reports

InDriver.import("FileApi");

InDriver.import("XlsxApi");

let found = FileApi.dirFindFiles({

   path: "C:/Data/Incoming",

   extensions: ["xlsx"],

   modifiedFrom: "2026-06-10T00:00:00",

   recursive: false,

   limit: 100

});

if (!found.ok) {

   InDriver.debug(found.error, "critical");

   return;

}

for (let i = 0; i < found.files.length; i++) {

   let file = found.files[i].absoluteFilePath;

   if (!XlsxApi.open("report", file)) {

      InDriver.debug("Cannot open XLSX: " + XlsxApi.lastError(), "critical");

      continue;

   }

   let rows = XlsxApi.table("report", "Sheet1", 1, 2);

   InDriver.debug("Rows: " + rows.length);

   XlsxApi.close("report");

}

Rules

This prevents the incoming directory from growing indefinitely.

Notes for AI code generation

When generating code using FileApi.dirFindFiles, follow these rules:


FileApi.dirSaveFiles

Signature

FileApi.dirSaveFiles(filesArray: String): String

Description

Saves multiple files based on structured input.


FileApi.fileExists

Signature

FileApi.fileExists(path: String): Boolean

Description

Checks whether a file exists.

Example

if (FileApi.fileExists("c:/data.txt")) {

   InDriver.debug("File exists");

}


FileApi.fileSize

Signature

FileApi.fileSize(name: String): Number

Description

Returns size of an opened file in bytes.


FileApi.isOpen

Signature

FileApi.isOpen(name: String): Boolean

Description

Checks whether a file handle is currently open.


FileApi.open

Signature

FileApi.open(name: String, file: String, modes: Array = ["ReadOnly"]): String

Description

Opens a file and assigns it to a handle.

Arguments

name

file

modes

Returns

Example

FileApi.open("f1", "c:/data.txt", ["ReadWrite"]);


FileApi.readAll

Signature

FileApi.readAll(name: String): String

Description

Reads entire content of an opened file.


FileApi.readAllBase64

Signature

FileApi.readAllBase64(name: String): String

Description

Reads file and returns Base64 encoded content.


FileApi.readLines

Signature

FileApi.readLines(name: String): Array

Description

Reads file and returns array of lines.

Example

let lines = FileApi.readLines("f1");


FileApi.removeFile

Signature

FileApi.removeFile(path: String): Boolean

Description

Deletes a file from disk.


FileApi.removeFileSystemWatcherPath

Signature

FileApi.removeFileSystemWatcherPath(file: String): Boolean

Description

Removes file or directory from watcher.


FileApi.write

Signature

FileApi.write(name: String, data: String): Number

Description

Writes data to an opened file.

Returns

Example

FileApi.write("f1", "Hello World");


Recommended usage patterns

Pattern 1 — logging

onStartup:

   InDriver.import("FileApi");

   FileApi.open("log", "c:/log.txt", ["Append"]);

   if (FileApi.isOpen("log")) {

       FileApi.appendLine("log", "Application started");

   }


Pattern 2 — read + process

FileApi.open("f1", "c:/data.txt", ["ReadOnly"]);

let content = FileApi.readAll("f1");

InDriver.debug(content);

FileApi.close("f1");


Pattern 3 — pipeline

let data = InDriver.sqlExecute("local", "select * from table");

FileApi.open("out", "c:/export.json", ["WriteOnly"]);

FileApi.write("out", JSON.stringify(data));

FileApi.close("out");

Rules for code generation

When generating code using FileApi, follow these rules:

1. Always open file first

FileApi.open(name, path, modes)

2. Always check if open

if (!FileApi.isOpen(name)) { ... }

3. Use correct mode

4. Close file after use

FileApi.close(name)

5. Prefer appendLine for logs

FileApi.appendLine(...)

6. Use Base64 for binary data

FileApi.readAllBase64(...)

7. Validate file existence when needed

FileApi.fileExists(path)

SerialPortApi

SerialPortApi provides serial communication (RS232 / RS485) for JavaScript tasks in InDriver.

It allows:

Ports are managed using a handle name (name).

SerialPortApi.availablePorts

Signature

SerialPortApi.availablePorts(): Array

Description

Returns a list of available serial ports on the system.

Returns

Array

Example

let ports = SerialPortApi.availablePorts();

InDriver.debug(ports);


SerialPortApi.close

Signature

SerialPortApi.close(name: String): void

Description

Closes an opened serial port.

Example

SerialPortApi.close("port1");


SerialPortApi.closeAll

Signature

SerialPortApi.closeAll(): void

Description

Closes all opened serial ports.


SerialPortApi.flush

Signature

SerialPortApi.flush(name: String): void

Description

Clears input and output buffers of the serial port.


SerialPortApi.isOpen

Signature

SerialPortApi.isOpen(name: String): Boolean

Description

Checks whether a serial port is open.

Returns


SerialPortApi.open

Signature

SerialPortApi.open(name: String, port: String, config: Object): Boolean

Description

Opens and configures a serial port.

Arguments

name

port

config

{

   baudRate: Number,

   dataBits: Number,

   parity: "None" | "Even" | "Odd",

   stopBits: Number,

   flowControl: "None" | "Hardware" | "Software"

}

Returns

Example

SerialPortApi.open("p1", "COM3", {

   baudRate: 9600,

   dataBits: 8,

   parity: "None",

   stopBits: 1,

   flowControl: "None"

});


SerialPortApi.read

Signature

SerialPortApi.read(name: String): String

Description

Reads available data from serial port buffer.

Returns


SerialPortApi.readAll

Signature

SerialPortApi.readAll(name: String): String

Description

Reads entire buffer content.

Behavior


SerialPortApi.readLine

Signature

SerialPortApi.readLine(name: String): String

Description

Reads a single line from the serial port.

Behavior


SerialPortApi.setTimeout

Signature

SerialPortApi.setTimeout(name: String, msecs: Number): void

Description

Sets read timeout.


SerialPortApi.write

Signature

SerialPortApi.write(name: String, data: String): Number

Description

Writes data to serial port.

Returns

Example

SerialPortApi.write("p1", "AT\r\n");


Recommended usage patterns


Pattern 1 — simple communication

onStartup:

   InDriver.import("SerialPortApi");

   SerialPortApi.open("p1", "COM3", {

       baudRate: 9600,

       dataBits: 8,

       parity: "None",

       stopBits: 1,

       flowControl: "None"

   });

Pattern 2 — polling device

onHook

   let response = SerialPortApi.readAll("p1");

   if (response) {

       InDriver.debug(response);

   }

Pattern 3 — request/response

SerialPortApi.write("p1", "READ\n");

let response = SerialPortApi.readLine("p1");

InDriver.debug(response);


Rules for code generation

When generating code using SerialPortApi:

1. Always open port first

SerialPortApi.open(name, port, config)

2. Always check state

SerialPortApi.isOpen(name)

3. Use correct read method

4. Handle timing (hooks)

5. Always close if not persistent

SerialPortApi.close(name)



TcpSocketApi

TcpSocketApi provides client-side TCP socket communication for JavaScript tasks in InDriver.

It allows:

Sockets are managed by a unique name.

TcpSocketApi.acceptRead

Signature

TcpSocketApi.acceptRead(name: String): void

Description

Confirms that received data should be treated as an accepted response and that waiting for data may stop.

This function is especially important when writeAndWait(...) is used. In the documented request/response pattern, incoming data arrives through onMessage, and acceptRead(...) is called after the user script decides that the received bytes constitute the expected answer.

Arguments

name

Returns

Example

function onMessage()

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (JSON.stringify(data.bytes) === "[1,2,3]") {

           TcpSocketApi.acceptRead(data.socketName);

       }

   }

Rules for AI


TcpSocketApi.connect

Signature

TcpSocketApi.connect(name: String, tcpCfg: String = ""): Boolean

TcpSocketApi.connect(name: String, tcpCfg: Object): Boolean

Description

Creates or recreates a named TCP client socket connection.

If a socket with the same name already exists, it is closed and opened again with the new configuration.

Arguments

name

tcpCfg

Supported configuration keys visible from the attached files and manual:

Supported mode values

Meaning of read modes

Default behavior

From the attached files, if fields are omitted:

Returns

Boolean

Example

InDriver.import("TcpSocketApi");

let ok = TcpSocketApi.connect("socket", {

   address: "127.0.0.1",

   port: 50000,

   mode: "Buffer",

   timeout: 5000,

   bufferSize: 256

});

if (!ok) {

   InDriver.debug("TCP socket connection failed", "critical");

}

Rules


TcpSocketApi.disconnect

Signature

TcpSocketApi.disconnect(name: String): void

Description

Disconnects the named TCP socket.

Arguments

name

Returns

Example

TcpSocketApi.disconnect("socket");

Rules


TcpSocketApi.disconnectAll

Signature

TcpSocketApi.disconnectAll(): void

Description

Disconnects all registered TCP sockets.

Returns

Example

TcpSocketApi.disconnectAll();


TcpSocketApi.isBusy

Signature

TcpSocketApi.isBusy(name: String): Boolean

Description

Returns whether the socket is currently busy, typically because a request is still being processed or waiting for completion.

Arguments

name

Returns

Boolean

Example

if (!TcpSocketApi.isBusy("socket")) {

   TcpSocketApi.write("socket", [0x01, 0x02, 0x03]);

}

Rules for AI


TcpSocketApi.write

Signature

TcpSocketApi.write(

   name: String,

   data: ByteArray,

   request: String = "",

   timeout: Number = 0

): Boolean

Description

Writes data to the specified TCP socket.

Arguments

name

data

Typical JavaScript usage:

[0x01, 0x02, 0x03]

request

timeout

Returns

Boolean

Example

TcpSocketApi.write("socket", [0x01, 0x02, 0x03]);

Rules


TcpSocketApi.writeAndWait

Signature

TcpSocketApi.writeAndWait(

   name: String,

   data: ByteArray,

   request: String = "",

   timeout: Number = 0

): Boolean

Description

Writes data to the specified TCP socket and waits for a response until timeout or until the incoming data is explicitly accepted.

This is a blocking request/response helper. The waiting ends when:

Arguments

name

data

request

timeout

Returns

Boolean

Example

onStartup:

InDriver.import("TcpSocketApi");

TcpSocketApi.connect("socket", '{"address":"127.0.0.1","port":50000}');

onHook:

   TcpSocketApi.writeAndWait("socket", [0x01, 0x02, 0x03], "req1", 5000);

onMessage:

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (JSON.stringify(data.bytes) === "[1,2,3]") {

           TcpSocketApi.acceptRead(data.socketName);

       }

   }

Rules


TcpSocketApi.onMessage behavior

Description

When data is received on a TCP socket, the task onMessage() handler is triggered.

In this case:

Example message payload

let d = JSON.parse(InDriver.messageData());

/*

d =

{

 "bytes": "[79,75]",

 "data": "OK",

 "request": "request name",

 "socketName": "name of socket"

}

*/

Rules

Recommended usage patterns

Pattern 1 — TCP client socket request/response

onStartup:

   InDriver.import("TcpSocketApi");

   TcpSocketApi.connect("socket", {

       address: "127.0.0.1",

       port: 50000,

       mode: "Buffer",

       timeout: 5000,

       bufferSize: 256

   });

onHook:

   TcpSocketApi.writeAndWait("socket", [0x01, 0x02, 0x03], "req1", 5000);

onMessage:

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (JSON.stringify(data.bytes) === "[1,2,3]") {

           TcpSocketApi.acceptRead(data.socketName);

       }

   }



TcpServerApi

TcpServerApi provides TCP server functionality for JavaScript tasks in InDriver.

It allows:

The current documented API surface contains:

TcpSocketApi.close

Signature

TcpSocketApi.close(name: String): void

Description

Closes and removes the TCP socket instance associated with the given name.

Unlike disconnect(...), which only closes the connection, close(...):

Arguments

name

Returns


Behavior

Example

TcpSocketApi.close("socket");

Example — safe lifecycle

onStartup:

   InDriver.import("TcpSocketApi");

   TcpSocketApi.connect("socket", {

       address: "127.0.0.1",

       port: 50000

   });

onShutdown:

TcpSocketApi.close("socket");

Difference: disconnect vs close

Function

Behavior

disconnect(name)

closes connection but keeps socket object

close(name)

closes connection AND removes socket


Rules

When generating code:

  1. Use disconnect(...) when:
  1. Use close(...) when:
  1. Prefer close(...) in:

onShutdown()

  1. Do NOT call write(...) or writeAndWait(...) after close(...)

TcpServerApi.listen

Signature

TcpServerApi.listen(tcpServerCfg: String): void

Description

Starts a TCP server and listens for incoming connections.

Arguments

tcpServerCfg

Supported configuration keys from the manual:

Supported mode values

Supported address values

port

bufferSize

Returns

Example

InDriver.import("TcpServerApi");

TcpServerApi.listen(

   '{"port":50000,"address":"Any","readMode":"Buffer","bufferSize":256}'

);

Rules


TcpServerApi.write

Signature

TcpServerApi.write(name: String, data: ByteArray, timeout: Number): Boolean

Description

Writes data to the TCP client socket associated with the given connection name.

The manual describes this as sending a reply to a connected socket and waiting until the answer is accepted or timeout occurs, with behavior depending on the configured server read mode.

Arguments

name

data

timeout

Returns

Boolean

Example

onMessage:

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (JSON.stringify(data.bytes) === "[1,2,3]") {

           TcpServerApi.write(data.socketName, "bytes accepted", 5000);

       }

       if (data.data === "text data") {

           TcpServerApi.write(data.socketName, "text data accepted", 5000);

       }

}

Rules for AI


TcpServerApi.onMessage behavior

Description

When the server receives data from a connected client, the task onMessage() handler is triggered.

The payload structure follows the same documented pattern as TCP socket reads:

let d = JSON.parse(InDriver.messageData());

/*

d =

{

 "bytes": "[79,75]",

 "data": "OK",

 "request": "request name",

 "socketName": "name of socket"

}

*/

Rules for AI


Recommended usage patterns

Pattern 1 — TCP client socket request/response

onStartup

   InDriver.import("TcpSocketApi");

   TcpSocketApi.connect("socket", {

       address: "127.0.0.1",

       port: 50000,

       mode: "Buffer",

       timeout: 5000,

       bufferSize: 256

   });

onHook

TcpSocketApi.writeAndWait("socket", [0x01, 0x02, 0x03], "req1", 5000);

onMessage

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (JSON.stringify(data.bytes) === "[1,2,3]") {

           TcpSocketApi.acceptRead(data.socketName);

       }

   }

Pattern 2 — TCP server echo/ack

onStartup

InDriver.import("TcpServerApi");

TcpServerApi.listen('{"port":50000,"address":"Any","mode":"Buffer","bufferSize":256}');

onMessage

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       TcpServerApi.write(data.socketName, "accepted", 5000);

   }

Rules for AI code generation

When generating code using TcpSocketApi and TcpServerApi, follow these rules:

  1. Import the correct module in onStartup():

InDriver.import("TcpSocketApi");

InDriver.import("TcpServerApi");

  1. For TCP client sockets:
  1. For TCP server:
  1. Always parse incoming socket data:

let data = JSON.parse(InDriver.messageData());

  1. Use "Flow" or "Buffer" depending on whether the protocol is chunk-based or whole-buffer based.
  2. Do not invent additional socket methods beyond the documented API surface. The current user-facing API from the attached files/manual is limited to the methods listed above.



UdpSocketApi

UdpSocketApi provides UDP socket communication for JavaScript tasks in InDriver.

It allows:

Sockets are managed by a unique name.

UdpSocketApi.acceptRead

Signature

UdpSocketApi.acceptRead(name: String): void

Description

Marks the current incoming datagram as accepted for the specified socket.

This function is mainly used together with UdpSocketApi.writeAndWait(...). The waiting operation can complete when the script decides that the received response is the expected one and explicitly calls acceptRead(...).

Arguments

name

Returns

Example

onMessage:

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (data.socketName === "udp1" && data.data === "OK") {

           UdpSocketApi.acceptRead("udp1");

       }

   }

Rules


UdpSocketApi.bind

Signature

UdpSocketApi.bind(name: String, udpCfg: String = ""): Boolean

UdpSocketApi.bind(name: String, udpCfg: Object): Boolean

Description

Creates or recreates a named UDP socket and binds it to a local address and port.

If a socket with the same name already exists, it is closed and reopened with the new configuration.

Arguments

name

udpCfg

Supported keys visible in the source:

Configuration fields

address

port

timeout

Returns

Boolean

Example

InDriver.import("UdpSocketApi");

let ok = UdpSocketApi.bind("udp1", {

   address: "0.0.0.0",

   port: 50000,

   timeout: 5000

});

if (!ok) {

   InDriver.debug("UDP bind failed", "critical");

}

Rules


UdpSocketApi.isBusy

Signature

UdpSocketApi.isBusy(name: String): Boolean

Description

Returns whether the specified UDP socket is currently busy.

Arguments

name

Returns

Boolean

Example

if (!UdpSocketApi.isBusy("udp1")) {

   UdpSocketApi.write("udp1", "192.168.0.10", 6000, [0x01, 0x02], "req1", 5000);

}

Rules


UdpSocketApi.write

Signature

UdpSocketApi.write(

   name: String,

   address: String,

   port: Number,

   data: ByteArray,

   request: String = "",

   timeout: Number = 0

): Boolean

Description

Sends a UDP datagram to the specified remote address and port.

Arguments

name

address

port

data

Typical JavaScript usage:

[0x01, 0x02, 0x03]

request

timeout

Returns

Boolean

Example

UdpSocketApi.write(

   "udp1",

   "192.168.0.10",

   6000,

   [0x01, 0x02, 0x03],

   "ping1",

   5000

);

Rules


UdpSocketApi.writeAndWait

Signature

UdpSocketApi.writeAndWait(

   name: String,

   address: String,

   port: Number,

   data: ByteArray,

   request: String = "",

   timeout: Number = 0

): Boolean

Description

Sends a UDP datagram and waits until a matching response is accepted or the timeout expires.

Arguments

name

address

port

data

request

timeout

Returns

Boolean

Example

onHook

   UdpSocketApi.writeAndWait(

       "udp1",

       "192.168.0.10",

       6000,

       [0x10, 0x20],

       "req1",

       5000

   );

onMessage

   if (InDriver.taskName() === InDriver.messageSender()) {

       let data = JSON.parse(InDriver.messageData());

       if (data.socketName === "udp1" && data.data === "OK") {

           UdpSocketApi.acceptRead("udp1");

       }

   }

Rules


UdpSocketApi.onMessage behavior

Description

When a UDP datagram is received, onMessage() is triggered. The source files show that the runtime sends a direct internal message with tag "SockedData" and inserts the last request id under key "request" if available.

The incoming payload should be treated as JSON text available through:

let data = JSON.parse(InDriver.messageData());

Typical fields include:

Rules


WebSocketApi

WebSocketApi provides client-side WebSocket communication for JavaScript tasks in InDriver.

It allows:
● opening named WebSocket connections
● sending text and binary messages
● synchronous request/response communication
● asynchronous message handling via onMessage
● connection state monitoring

WebSocketApi.abort

Signature

WebSocketApi.abort(name: String): void

Description

Immediately aborts the WebSocket connection.

Unlike close(), abort terminates the connection without a closing handshake.

Arguments

name
● type: String
● socket name

Returns

● void

WebSocketApi.acceptRead

Signature

WebSocketApi.acceptRead(name: String): void

Description

Marks the current incoming message as accepted.

Used in request/response patterns together with writeAndWait().

Arguments

name
 ● type: String

Returns

● void

WebSocketApi.close

Signature

WebSocketApi.close(name: String, closeCode: Number = 1000, reason: String = ""): void

Description

Closes the WebSocket connection with a proper closing handshake.

Arguments

name
 ● type: String

closeCode
 ● type: Number
● default: 1000

reason
 ● type: String

Returns

● void

WebSocketApi.connect

Signature

WebSocketApi.connect(name: String, wsCfg: String = ""): Boolean

WebSocketApi.connect(name: String, wsCfg: Object): Boolean

Description

Creates or recreates a named WebSocket connection.

Arguments

name
 ● type: String

wsCfg
 ● type: String | Object

Supported fields:

● url
● address / host
● port
● path
● ssl / secure
● origin
● protocol
● headers
● timeout
● waitForConnected

Returns

Boolean
● true → success
● false → failure

Example

WebSocketApi.connect("ws", {

   url: "ws://127.0.0.1:8081",

   waitForConnected: true

});

WebSocketApi.disconnect

Signature

WebSocketApi.disconnect(name: String): void

Description

Closes a specific WebSocket connection.

WebSocketApi.disconnectAll

Signature

WebSocketApi.disconnectAll(): void

Description

Closes all WebSocket connections.

WebSocketApi.errorString

Signature

WebSocketApi.errorString(name: String): String

Description

Returns last error message for the socket.

Returns

String

WebSocketApi.isBusy

Signature

WebSocketApi.isBusy(name: String): Boolean

Description

Returns whether the socket is currently busy.

Returns

Boolean

WebSocketApi.isValid

Signature

WebSocketApi.isValid(name: String): Boolean

Description

Returns whether the socket is valid.

Returns

Boolean

WebSocketApi.ping

Signature

WebSocketApi.ping(name: String, payload: String = ""): void

Description

Sends a ping frame.

Arguments

payload
 ● optional data

WebSocketApi.state

Signature

WebSocketApi.state(name: String): String

Description

Returns socket state.

Possible values

● UnconnectedState
● ConnectingState
● ConnectedState
● ClosingState

WebSocketApi.write

Signature

WebSocketApi.write(name: String, data: String, request: String = "", timeout: Number = 0): Boolean

Description

Sends a text message.

Returns

Boolean

Example

WebSocketApi.write("ws", "hello");

WebSocketApi.writeAndWait

Signature

WebSocketApi.writeAndWait(name: String, data: String, request: String = "", timeout: Number = 30000): Boolean

Description

Sends a message and waits for response.

Returns

Boolean
● true → response received
● false → timeout

WebSocketApi.writeBinary

Signature

WebSocketApi.writeBinary(name: String, data: ByteArray, request: String = "", timeout: Number = 0): Boolean

Description

Sends binary data.

WebSocketApi.writeBinaryAndWait

Signature

WebSocketApi.writeBinaryAndWait(name: String, data: ByteArray, request: String = "", timeout: Number = 30000): Boolean

Description

Sends binary data and waits for response.

WebSocketApi.onMessage behavior

Incoming messages:

type: "WebSocketData"

Structure:

data.socketName

data.type      // text | binary

data.data

data.base64

data.bytes

data.request

Events:

type: "WebSocketEvent"

connected

disconnected

error

pong

Rules

● Use write() for async communication
● Use writeAndWait() for request-response
● Use acceptRead() when matching response
● Always import API in onStartup
● Prefer JSON for structured data


WebSocketServerApi

WebSocketServerApi provides server-side WebSocket communication for JavaScript tasks in InDriver.

It allows:
● listening for incoming WebSocket connections
● managing multiple connected clients
● sending messages to specific clients
● broadcasting messages to all clients
● handling real-time bidirectional communication

Each client connection is identified by a unique socketName.


WebSocketServerApi.clientCount

Signature

WebSocketServerApi.clientCount(): Number

Description

Returns the number of currently connected clients.

Returns

Number

WebSocketServerApi.clients

Signature

WebSocketServerApi.clients(): String[]

Description

Returns a list of connected client socket names.

Returns

Array of String

WebSocketServerApi.close

Signature

WebSocketServerApi.close(): void

Description

Stops the WebSocket server and disconnects all clients.

Returns

● void

WebSocketServerApi.disconnectAllClients

Signature

WebSocketServerApi.disconnectAllClients(): void

Description

Disconnects all currently connected clients.

Returns

● void

WebSocketServerApi.disconnectClient

Signature

WebSocketServerApi.disconnectClient(socketName: String): Boolean

Description

Disconnects a specific client.

Arguments

socketName
 ● type: String

Returns

Boolean
● true → client disconnected
● false → client not found

WebSocketServerApi.hasClient

Signature

WebSocketServerApi.hasClient(socketName: String): Boolean

Description

Checks if a client with the given name exists.

Returns

Boolean

WebSocketServerApi.isListening

Signature

WebSocketServerApi.isListening(): Boolean

Description

Returns whether the WebSocket server is currently listening.

Returns

Boolean

WebSocketServerApi.listen

Signature

WebSocketServerApi.listen(cfg: String | Object): Boolean

Description

Starts the WebSocket server.

Arguments

cfg

Configuration object or JSON string.

Supported fields:

● address
● port

address

● type: String
● examples:
○ "Any"
○ "LocalHost"
○ "127.0.0.1"

Default: LocalHost

port

● type: Number
● default: 8081

Returns

Boolean
● true → server started
● false → failed to start

Example

WebSocketServerApi.listen({

   address: "Any",

   port: 8081

});

Rules

● Call listen() once during initialization
● Use "Any" to allow external connections
● Use LocalHost for local-only communication

WebSocketServerApi.serverAddress

Signature

WebSocketServerApi.serverAddress(): String

Description

Returns the address on which the server is listening.

Returns

String

WebSocketServerApi.serverPort

Signature

WebSocketServerApi.serverPort(): Number

Description

Returns the listening port.

Returns

Number

WebSocketServerApi.write

Signature

WebSocketServerApi.write(socketName: String, data: String): Boolean

Description

Sends a text message to a specific client.

Arguments

socketName
 ● type: String

data
 ● type: String

Returns

Boolean
● true → sent
● false → failed

Example

WebSocketServerApi.write("ws_1", "hello client");

WebSocketServerApi.writeAll

Signature

WebSocketServerApi.writeAll(data: String): Number

Description

Sends a text message to all connected clients.

Returns

Number
● number of clients that received the message

Example

WebSocketServerApi.writeAll("broadcast message");

WebSocketServerApi.writeBinary

Signature

WebSocketServerApi.writeBinary(socketName: String, data: ByteArray): Boolean

Description

Sends binary data to a specific client.

WebSocketServerApi.writeBinaryAll

Signature

WebSocketServerApi.writeBinaryAll(data: ByteArray): Number

Description

Sends binary data to all clients.

WebSocketServerApi.onMessage behavior

Incoming client messages are delivered via:

type: "WebSocketData"

Structure

data.socketName

data.data

data.type      // text | binary

data.base64

data.bytes

data.peerAddress

data.peerPort

data.localAddress

data.localPort

WebSocketServerApi.events

Connection events are delivered via:

type: "WebSocketEvent"

Possible events

connected

disconnected

error

pong

Example usage

onStartup:

InDriver.import("WebSocketServerApi");

WebSocketServerApi.listen({

   address: "Any",

   port: 8081

});

onMessage

if (InDriver.isLoopbackMessage()) {

    let tags = InDriver.messageTags();

    let data = JSON.parse(InDriver.messageData());

    InDriver.debug(":)" + InDriver.messageData() + " " + JSON.stringify(data.bytes));

    if (tags.indexOf("WebSocketEvent") >= 0) {

        InDriver.debug("Event: " + data.event + " " + data.socketName);

    }

    if (tags.indexOf("WebSocketData") >= 0) {

        if (data.type === "text") {

            let msg = JSON.parse(data.data);

            WebSocketServerApi.write(data.socketName, JSON.stringify({

                ok: true,

                echo: msg

            }));

        }

        if (data.type === "binary") {

            InDriver.debug("Binary data: " + JSON.stringify(data.bytes));

            WebSocketServerApi.writeBinary(data.socketName, [5, 6, 7]);

        }

    }

}

Rules

● Use WebSocketServerApi for browser/frontend communication
● Each client has unique socketName
● Use write() for response
● Use writeAll() for broadcast
● Always handle incoming messages in onMessage
● Prefer JSON format for communication


XmlReaderApi

XmlReaderApi provides streaming XML reading functionality for JavaScript tasks in InDriver.

It allows:

The API is stateful and operates on the currently loaded XML reader state.

XmlReaderApi.addData

Signature

XmlReaderApi.addData(data: String): void

Description

Adds XML text directly into the XML reader.

Arguments

data

Returns

Example

XmlReaderApi.clear();

XmlReaderApi.addData("<root><a>1</a></root>");

Rules


XmlReaderApi.addExtraNamespaceDeclaration

Signature

XmlReaderApi.addExtraNamespaceDeclaration(prefix: String, namespaceUri: String): void

Description

Adds an extra namespace declaration to the XML reader.

Arguments

prefix

namespaceUri

Returns

Example

XmlReaderApi.addExtraNamespaceDeclaration("x", "http://example.com/ns");


XmlReaderApi.atEnd

Signature

XmlReaderApi.atEnd(): Boolean

Description

Returns whether the XML reader is at the end of the stream.

Returns

Boolean

Example

while (!XmlReaderApi.atEnd()) {

   XmlReaderApi.readNext();

}


XmlReaderApi.attribute

Signature

XmlReaderApi.attribute(attr: String): String

Description

Returns the value of the specified attribute for the current element.

Arguments

attr

Returns

String

Example

if (XmlReaderApi.isStartElement()) {

   let id = XmlReaderApi.attribute("id");

}


XmlReaderApi.characterOffset

Signature

XmlReaderApi.characterOffset(): Number

Description

Returns the character offset of the current parser position.

Returns

Number


XmlReaderApi.clear

Signature

XmlReaderApi.clear(): void

Description

Clears the XML reader state.

Returns

Example

XmlReaderApi.clear();


XmlReaderApi.close

Signature

XmlReaderApi.close(): void

Description

Closes the currently opened XML file.

Returns

Example

XmlReaderApi.close();


XmlReaderApi.columnNumber

Signature

XmlReaderApi.columnNumber(): Number

Description

Returns the current parser column number.

Returns

Number


XmlReaderApi.documentEncoding

Signature

XmlReaderApi.documentEncoding(): String

Description

Returns the document encoding reported by the XML stream.

Returns

String


XmlReaderApi.documentVersion

Signature

XmlReaderApi.documentVersion(): String

Description

Returns the XML document version.

Returns

String


XmlReaderApi.dtdName

Signature

XmlReaderApi.dtdName(): String

Description

Returns the DTD name of the current document, if present.

Returns

String


XmlReaderApi.dtdPublicId

Signature

XmlReaderApi.dtdPublicId(): String

Description

Returns the DTD public identifier.

Returns

String


XmlReaderApi.dtdSystemId

Signature

XmlReaderApi.dtdSystemId(): String

Description

Returns the DTD system identifier.

Returns

String


XmlReaderApi.entityDeclarations

Signature

XmlReaderApi.entityDeclarations(): String

Description

Returns entity declarations as serialized JSON text.

Returns

String

The returned JSON contains objects with fields such as:

Example

let entities = JSON.parse(XmlReaderApi.entityDeclarations());

Rules


XmlReaderApi.entityExpansionLimit

Signature

XmlReaderApi.entityExpansionLimit(): Number

Description

Returns the current entity expansion limit.

Returns

Number


XmlReaderApi.hasError

Signature

XmlReaderApi.hasError(): Boolean

Description

Returns whether the XML reader is currently in an error state.

Returns

Boolean

Example

if (XmlReaderApi.hasError()) {

   InDriver.debug(XmlReaderApi.lastError(), "critical");

}


XmlReaderApi.hasStandaloneDeclaration

Signature

XmlReaderApi.hasStandaloneDeclaration(): Boolean

Description

Returns whether the XML document has a standalone declaration.

Returns

Boolean


XmlReaderApi.isCDATA

Signature

XmlReaderApi.isCDATA(): Boolean

Description

Returns whether the current token is CDATA.

Returns

Boolean


XmlReaderApi.isCharacters

Signature

XmlReaderApi.isCharacters(): Boolean

Description

Returns whether the current token is character data.

Returns

Boolean


XmlReaderApi.isComment

Signature

XmlReaderApi.isComment(): Boolean

Description

Returns whether the current token is a comment.

Returns

Boolean


XmlReaderApi.isDTD

Signature

XmlReaderApi.isDTD(): Boolean

Description

Returns whether the current token is a DTD token.

Returns

Boolean


XmlReaderApi.isEndDocument

Signature

XmlReaderApi.isEndDocument(): Boolean

Description

Returns whether the current token is end-of-document.

Returns

Boolean


XmlReaderApi.isEndElement

Signature

XmlReaderApi.isEndElement(): Boolean

Description

Returns whether the current token is an end element.

Returns

Boolean


XmlReaderApi.isEntityReference

Signature

XmlReaderApi.isEntityReference(): Boolean

Description

Returns whether the current token is an entity reference.

Returns

Boolean


XmlReaderApi.isProcessingInstruction

Signature

XmlReaderApi.isProcessingInstruction(): Boolean

Description

Returns whether the current token is a processing instruction.

Returns

Boolean


XmlReaderApi.isStandaloneDocument

Signature

XmlReaderApi.isStandaloneDocument(): Boolean

Description

Returns whether the XML document is standalone.

Returns

Boolean


XmlReaderApi.isStartDocument

Signature

XmlReaderApi.isStartDocument(): Boolean

Description

Returns whether the current token is the start of the document.

Returns

Boolean


XmlReaderApi.isStartElement

Signature

XmlReaderApi.isStartElement(): Boolean

Description

Returns whether the current token is a start element.

Returns

Boolean


XmlReaderApi.isWhitespace

Signature

XmlReaderApi.isWhitespace(): Boolean

Description

Returns whether the current token is whitespace.

Returns

Boolean


XmlReaderApi.lastError

Signature

XmlReaderApi.lastError(): String

Description

Returns the current XML parser error string.

Returns

String

Example

if (XmlReaderApi.hasError()) {

   InDriver.debug(XmlReaderApi.lastError(), "critical");

}


XmlReaderApi.lineNumber

Signature

XmlReaderApi.lineNumber(): Number

Description

Returns the current parser line number.

Returns

Number


XmlReaderApi.name

Signature

XmlReaderApi.name(): String

Description

Returns the current element or token name.

Returns

String

Example

if (XmlReaderApi.isStartElement()) {

   InDriver.debug(XmlReaderApi.name());

}


XmlReaderApi.namespaceProcessing

Signature

XmlReaderApi.namespaceProcessing(): Boolean

Description

Returns whether namespace processing is enabled.

Returns

Boolean


XmlReaderApi.namespaceUri

Signature

XmlReaderApi.namespaceUri(): String

Description

Returns the namespace URI of the current token.

Returns

String


XmlReaderApi.open

Signature

XmlReaderApi.open(file: String): String

Description

Opens an XML file for reading.

Arguments

file

Returns

String

Example

let err = XmlReaderApi.open("c:/data/config.xml");

if (err) {

   InDriver.debug(err, "critical");

}

Rules


XmlReaderApi.prefix

Signature

XmlReaderApi.prefix(): String

Description

Returns the namespace prefix of the current token.

Returns

String


XmlReaderApi.processingInstructionData

Signature

XmlReaderApi.processingInstructionData(): String

Description

Returns the data part of the current processing instruction.

Returns

String


XmlReaderApi.processingInstructionTarget

Signature

XmlReaderApi.processingInstructionTarget(): String

Description

Returns the target part of the current processing instruction.

Returns

String


XmlReaderApi.qualifiedName

Signature

XmlReaderApi.qualifiedName(): String

Description

Returns the qualified name of the current token.

Returns

String


XmlReaderApi.readElementText

Signature

XmlReaderApi.readElementText(

   behaviour: String = "ErrorOnUnexpectedElement"

): String

Description

Reads and returns the text content of the current element.

Arguments

behaviour

Returns

String

Example

if (XmlReaderApi.isStartElement() && XmlReaderApi.name() === "title") {

   let text = XmlReaderApi.readElementText("SkipChildElements");

   InDriver.debug(text);

}

Rules


XmlReaderApi.readNext

Signature

XmlReaderApi.readNext(): String

Description

Advances the XML reader to the next token and returns the token type as string.

Returns

String

Possible values include:

Example

while (!XmlReaderApi.atEnd()) {

   let token = XmlReaderApi.readNext();

   InDriver.debug(token);

}


XmlReaderApi.readNextStartElement

Signature

XmlReaderApi.readNextStartElement(): Boolean

Description

Advances the reader until the next start element is found.

Returns

Boolean

Example

while (XmlReaderApi.readNextStartElement()) {

   InDriver.debug(XmlReaderApi.name());

}


XmlReaderApi.setEntityExpansionLimit

Signature

XmlReaderApi.setEntityExpansionLimit(limit: Number): void

Description

Sets the entity expansion limit of the XML reader.

Arguments

limit

Returns


XmlReaderApi.setNamespaceProcessing

Signature

XmlReaderApi.setNamespaceProcessing(enabled: Boolean): void

Description

Enables or disables namespace processing.

Arguments

enabled

Returns

Example

XmlReaderApi.setNamespaceProcessing(true);


XmlReaderApi.skipCurrentElement

Signature

XmlReaderApi.skipCurrentElement(): void

Description

Skips the current element, including its child content.

Returns

Example

if (XmlReaderApi.isStartElement() && XmlReaderApi.name() === "ignore") {

   XmlReaderApi.skipCurrentElement();

}


XmlReaderApi.text

Signature

XmlReaderApi.text(): String

Description

Returns the text of the current token.

Returns

String

Example

if (XmlReaderApi.isCharacters()) {

   InDriver.debug(XmlReaderApi.text());

}


XmlReaderApi.tokenString

Signature

XmlReaderApi.tokenString(): String

Description

Returns the current token as a string representation provided by the XML reader.

Returns

String


XmlReaderApi.tokenType

Signature

XmlReaderApi.tokenType(): String

Description

Returns the current token type as a normalized token name.

Returns

String

Possible values include:


Recommended usage patterns

Pattern 1 — read XML file token by token

onStartup:

   InDriver.import("XmlReaderApi");

   let err = XmlReaderApi.open("c:/data/config.xml");

   if (err) {

       InDriver.debug(err, "critical");

       return;

   }

   while (!XmlReaderApi.atEnd()) {

       let token = XmlReaderApi.readNext();

       if (XmlReaderApi.isStartElement()) {

           InDriver.debug("Element: " + XmlReaderApi.name());

       }

       if (XmlReaderApi.isCharacters()) {

           InDriver.debug("Text: " + XmlReaderApi.text());

       }

   }

   if (XmlReaderApi.hasError()) {

       InDriver.debug(XmlReaderApi.lastError(), "critical");

   }

   XmlReaderApi.close();

Pattern 2 — read selected element text

while (XmlReaderApi.readNextStartElement()) {

   if (XmlReaderApi.name() === "title") {

       let title = XmlReaderApi.readElementText("SkipChildElements");

       InDriver.debug("Title: " + title);

   } else {

       XmlReaderApi.skipCurrentElement();

   }

}

Pattern 3 — parse XML from memory

XmlReaderApi.clear();

XmlReaderApi.addData("<root><item id='1'>A</item></root>");

while (!XmlReaderApi.atEnd()) {

   XmlReaderApi.readNext();

   if (XmlReaderApi.isStartElement()) {

       InDriver.debug(XmlReaderApi.name());

       InDriver.debug(XmlReaderApi.attribute("id"));

   }

}

Rules for AI code generation

When generating code using UdpSocketApi and XmlReaderApi, follow these rules:

  1. For UdpSocketApi:
  1. For XmlReaderApi:
  1. Do not invent additional methods beyond the attached source files. UdpSocketApi exposes only:


XlsxApi

XlsxApi provides Microsoft Excel XLSX reading and writing functionality for JavaScript tasks in InDriver.

It allows:

The API is stateful. A workbook is opened under a logical name, and all later functions operate on that workbook name.

XlsxApi supports modern Excel XLSX files.

Legacy XLS files are not supported.

XlsxApi.open

Signature

XlsxApi.open(name: String, file: String): Boolean

Description

Opens an XLSX workbook from disk and registers it under a logical name.

Arguments

name

logical workbook name used in later calls

file

full or relative path to XLSX file

Returns

Boolean

true → workbook was opened successfully

false → opening failed

Example

InDriver.import("XlsxApi");

let ok = XlsxApi.open("report", InDriver.currentPath() + "/report.xlsx");

if (!ok) {
        InDriver.debug(XlsxApi.lastError(), "critical");
        return;
}

Rules

Always check the returned value.

If open(...) returns false, use XlsxApi.lastError() to read the reason.

Use close(...) when the workbook is no longer needed.

XlsxApi.close

Signature

XlsxApi.close(name: String): void

Description

Closes one opened workbook.

Arguments

name

logical workbook name

Returns

void

Example

XlsxApi.close("report");

Rules

Call close(...) after processing the workbook, especially in long-running tasks.

XlsxApi.closeAll

Signature

XlsxApi.closeAll(): void

Description

Closes all opened workbooks.

Returns

void

Example

XlsxApi.closeAll();

Rules

Useful during task shutdown or when reloading many Excel files.

XlsxApi.isOpen

Signature

XlsxApi.isOpen(name: String): Boolean

Description

Checks whether a workbook is currently opened under the specified logical name.

Arguments

name

logical workbook name

Returns

Boolean

true → workbook is open

false → workbook is not open

Example

if (!XlsxApi.isOpen("report")) {
        InDriver.debug("Workbook is not open", "critical");
}

XlsxApi.sheets

Signature

XlsxApi.sheets(name: String): Array

Description

Returns the list of worksheet names from the opened workbook.

Arguments

name

logical workbook name

Returns

Array

array of worksheet names

Example

let sheets = XlsxApi.sheets("report");

InDriver.debug(JSON.stringify(sheets));

Example result

[
"Sheet1",
"Orders",
"Report"
]

Rules

Use sheets(...) before selectSheet(...) when the worksheet name may vary between files.

XlsxApi.selectSheet

Signature

XlsxApi.selectSheet(name: String, sheet: String): Boolean

Description

Selects the active worksheet in the opened workbook.

Arguments

name

logical workbook name

sheet

worksheet name

Returns

Boolean

true → worksheet was selected

false → worksheet was not found or workbook is not open


Example

if (!XlsxApi.selectSheet("report", "Orders")) {
        InDriver.debug("Sheet not found", "critical");
}

Rules

After selecting a worksheet, read(...), readA1(...), row(...), range(...) and table(...) operate on the selected worksheet unless a function accepts a sheet argument explicitly.

XlsxApi.currentSheet

Signature

XlsxApi.currentSheet(name: String): String

Description

Returns the name of the currently selected worksheet.

Arguments

name

logical workbook name

Returns

String

current worksheet name

empty string if workbook is not open or no worksheet is selected

Example

let sheet = XlsxApi.currentSheet("report");

InDriver.debug("Current sheet: " + sheet);

XlsxApi.dimension

Signature

XlsxApi.dimension(name: String, sheet: String = ""): Object

Description

Returns the used range of the selected or specified worksheet.

Arguments

name

logical workbook name

sheet

optional worksheet name

if empty, the current worksheet is used

Returns

Object

The returned object contains:

sheet

firstRow

lastRow

firstCol

lastCol

rowCount

colCount

Example

let dim = XlsxApi.dimension("report");

InDriver.debug(JSON.stringify(dim));

Example result

{
"sheet": "Orders",
"firstRow": 1,
"lastRow": 500,
"firstCol": 1,
"lastCol": 12,
"rowCount": 500,
"colCount": 12
}

Rules

Excel row and column indexes start from 1.

Use dimension(...) before manual loops over rows and columns.

XlsxApi.metadata

Signature

XlsxApi.metadata(name: String): Object

Description

Returns basic workbook and file metadata.

Arguments

name

logical workbook name

Returns

Object

The returned object may contain:

name

file

fileName

fileSize

lastModified

sheetCount

currentSheet

sheets

Example

let meta = XlsxApi.metadata("report");

InDriver.debug(JSON.stringify(meta));

Rules

Use metadata(...) for diagnostics, logging and validation before parsing a file.

XlsxApi.read

Signature

XlsxApi.read(name: String, row: Number, col: Number): Variant

Description

Reads a cell value by row and column index.

Arguments

name

logical workbook name

row

Excel row index, starting from 1

col

Excel column index, starting from 1

Returns

Variant

cell value

undefined/null-like value if workbook or cell is invalid

Example

let value = XlsxApi.read("report", 2, 5);

InDriver.debug("Value: " + value);

Rules

Indexes start from 1.

Use readA1(...) if Excel-style cell references are more convenient.

XlsxApi.readA1

Signature

XlsxApi.readA1(name: String, cell: String): Variant

Description

Reads a cell value using Excel A1 notation.

Arguments

name

logical workbook name

cell

Excel cell reference, for example "A1" or "E2"

Returns

Variant

cell value

Example

let value = XlsxApi.readA1("report", "E2");

InDriver.debug("Value: " + value);

XlsxApi.exists

Signature

XlsxApi.exists(name: String, row: Number, col: Number): Boolean

Description

Checks whether a cell has a non-empty value.

Arguments

name

logical workbook name

row

Excel row index, starting from 1

col

Excel column index, starting from 1

Returns

Boolean

true → cell contains a non-empty value

false → cell is empty or invalid

Example

if (XlsxApi.exists("report", 10, 3)) {
InDriver.debug("Cell contains data");
}

XlsxApi.existsA1

Signature

XlsxApi.existsA1(name: String, cell: String): Boolean

Description

Checks whether a cell identified by Excel A1 notation has a non-empty value.

Arguments

name

logical workbook name

cell

Excel cell reference, for example "A1"

Returns

Boolean

Example

if (XlsxApi.existsA1("report", "A10")) {
InDriver.debug("A10 contains data");
}

XlsxApi.cell

Signature

XlsxApi.cell(name: String, row: Number, col: Number): Object

Description

Returns one cell as an object containing cell metadata and value.

Arguments

name

logical workbook name

row

Excel row index, starting from 1

col

Excel column index, starting from 1

Returns

Object

The returned object contains:

row

col

ref

type

value

Example

let c = XlsxApi.cell("report", 2, 3);

InDriver.debug(JSON.stringify(c));

Example result

{
"row": 2,
"col": 3,
"ref": "C2",
"type": "number",
"value": 123.45
}

XlsxApi.row

Signature

XlsxApi.row(name: String, row: Number, firstCol: Number = 1, lastCol: Number = -1): Array

Description

Returns one worksheet row as an array of cell objects.

Arguments

name

logical workbook name

row

Excel row index, starting from 1

firstCol

optional

first column to read

lastCol

optional

last column to read

if lastCol is less than 1, the worksheet dimension is used

Returns

Array

array of cell objects

Example

let row = XlsxApi.row("report", 5);

InDriver.debug(row);

let selected = XlsxApi.row("report", 5, 1, 10);

InDriver.debug(selected);

Rules

Use row(...) for diagnostics or when the row layout is not known in advance.

For table-like data, prefer table(...).

XlsxApi.range

Signature

XlsxApi.range(name: String, firstRow: Number, firstCol: Number, lastRow: Number, lastCol: Number): Array

Description

Returns a rectangular worksheet range as a matrix array.

Arguments

name

logical workbook name

firstRow

first row index

firstCol

first column index

lastRow

last row index

lastCol

last column index

Returns

Array

array of arrays

Example

let data = XlsxApi.range("report", 1, 1, 10, 5);

InDriver.debug(JSON.stringify(data));

Example result

[
["Date", "Value"],
["2026-01-01", 123.45],
["2026-01-02", 140.10]
]

Rules

Use range(...) when data has no headers or when you want matrix-style access.

Use table(...) when the first row contains column names.

XlsxApi.table

Signature

XlsxApi.table(name: String,sheet: String = "",headerRow: Number = 1,firstDataRow: Number = 2,firstCol: Number = -1,lastCol: Number = -1,lastRow: Number = -1,skipEmptyRows:Boolean = true): Array

Description

Converts a worksheet table into an array of JavaScript objects.

The header row is used as object property names.

Each data row becomes one object.

Arguments

name

logical workbook name

sheet

optional

worksheet name

if empty, the current worksheet is used

headerRow

optional

row containing column headers

firstDataRow

optional

first row containing data

firstCol

optional

first column to read

if less than 1, the worksheet dimension is used

lastCol

optional

last column to read

if less than 1, the worksheet dimension is used

lastRow

optional

last row to read

if less than 1, the worksheet dimension is used

skipEmptyRows

optional

if true, empty rows are skipped

Returns

Array

array of row objects

Example

let rows = XlsxApi.table("report", "Orders", 1, 2);

for (let i = 0; i < rows.length; i++) {
let row = rows[i];
InDriver.debug(JSON.stringify(row));
}

Example result

[
{
"Order": 1001,
"Product": "A",
"Quantity": 10
},
{
"Order": 1002,
"Product": "B",
"Quantity": 20
}
]

Rules

This is the recommended function for parsing standard Excel reports.

Use clear and unique column headers in Excel files.

If a header cell is empty, the API uses the Excel column name such as "A", "B", "C".

XlsxApi.toObject

Signature

XlsxApi.toObject(name: String, options: Object = {}): Object

Description

Converts one worksheet, selected worksheets, or the entire workbook into a structured JavaScript object.

Arguments

name

logical workbook name

options

optional

conversion options

Options:

mode

supported values:

"table"

"matrix"

"cells"

default: "table"

sheet

worksheet name

allSheets

if true, all worksheets are converted

headerRow

row containing headers for table mode

firstDataRow

first data row for table mode

firstRow

first row to read

lastRow

last row to read

firstCol

first column to read

lastCol

last column to read

skipEmptyRows

if true, empty rows are skipped

includeRefs

if true, table rows include cell reference fields

Returns

Object

structured workbook object

Example

let obj = XlsxApi.toObject("report", {
mode: "table",
sheet: "Orders",
headerRow: 1,
firstDataRow: 2,
skipEmptyRows: true
});

InDriver.debug(JSON.stringify(obj));

//Other example

let all = XlsxApi.toObject("report", {
mode: "matrix",
allSheets: true
});

Rules

Use toObject(...) when you need a complete structured representation.

For large files, prefer table(...), range(...), or manual row processing.

XlsxApi.findColumn

Signature

XlsxApi.findColumn(name: String,header: String,headerRow: Number = 1,sheet: String = "",
caseSensitive: Boolean = false): Number

Description

Finds the column number by header text.

Arguments

name

logical workbook name

header

header text to search for

headerRow

optional

row containing headers

sheet

optional

worksheet name

if empty, current worksheet is used

caseSensitive

optional

if true, matching is case-sensitive

Returns

Number

column number if found

-1 if not found

Example

let col = XlsxApi.findColumn("report", "Value");

if (col < 0) {
        InDriver.debug("Column not found", "critical");
        return;
}

let value = XlsxApi.read("report", 2, col);

Rules

Use findColumn(...) when Excel reports may change column order.

XlsxApi.write

Signature

XlsxApi.write(name: String, row: Number, col: Number, value: Variant): Boolean

Description

Writes a value to a cell identified by row and column index.

Arguments

name

logical workbook name

row

Excel row index, starting from 1

col

Excel column index, starting from 1

value

value to write

Returns

Boolean

true → value was written

false → writing failed

Example

XlsxApi.write("report", 2, 5, 123.45);

Rules

Call save(...) or saveAs(...) to persist changes to disk.

XlsxApi.writeA1

Signature

XlsxApi.writeA1(name: String, cell: String, value: Variant): Boolean

Description

Writes a value to a cell identified by Excel A1 notation.

Arguments

name

logical workbook name

cell

Excel cell reference, for example "B2"

value

value to write

Returns

Boolean

Example

XlsxApi.writeA1("report", "B2", "Processed");

Rules

Call save(...) or saveAs(...) to persist changes to disk.

XlsxApi.save

Signature

XlsxApi.save(name: String): Boolean

Description

Saves the workbook to its original file.

Arguments

name

logical workbook name

Returns

Boolean

true → workbook was saved

false → saving failed

Example

if (!XlsxApi.save("report")) {
InDriver.debug("Save failed", "critical");
}

Rules

Use save(...) only when overwriting the original file is expected.

Use saveAs(...) when creating a modified copy.

XlsxApi.saveAs

Signature

XlsxApi.saveAs(name: String, file: String): Boolean

Description

Saves the workbook to a new XLSX file.

Arguments

name

logical workbook name

file

output XLSX file path

Returns

Boolean

true → workbook was saved

false → saving failed

Example

let out = InDriver.currentPath() + "/report_processed.xlsx";

if (!XlsxApi.saveAs("report", out)) {
InDriver.debug("SaveAs failed", "critical");
}

XlsxApi.lastError

Signature

XlsxApi.lastError(): String

Description

Returns the last error text reported by XlsxApi.

Returns

String

Example

if (!XlsxApi.open("report", "missing.xlsx")) {
InDriver.debug(XlsxApi.lastError(), "critical");
}

Rules

Use lastError() mainly after open(...) fails.

Recommended usage patterns

Pattern 1 — read XLSX table

onStartup:

InDriver.import("XlsxApi");

let file = InDriver.currentPath() + "/report.xlsx";

if (!XlsxApi.open("report", file)) {
        InDriver.debug(XlsxApi.lastError(), "critical");
        return;
}

let rows = XlsxApi.table("report", "Sheet1", 1, 2);

for (let i = 0; i < rows.length; i++) {
        let row = rows[i];

  InDriver.debug(JSON.stringify(row));

}

XlsxApi.close("report");

Pattern 2 — read selected columns by header name

onStartup:

InDriver.import("XlsxApi");

if (!XlsxApi.open("report", InDriver.currentPath() + "/report.xlsx")) {
        InDriver.debug(XlsxApi.lastError(), "critical");
        return;
}

let valueCol = XlsxApi.findColumn("report", "Value");
let timeCol = XlsxApi.findColumn("report", "Timestamp");

if (valueCol < 0 || timeCol < 0) {
InDriver.debug("Required column not found", "critical");
XlsxApi.close("report");
return;
}

let dim = XlsxApi.dimension("report");

for (let r = 2; r <= dim.lastRow; r++) {
        let ts = XlsxApi.read("report", r, timeCol);
        let value = XlsxApi.read("report", r, valueCol);

  InDriver.debug("ts=" + ts + ", value=" + value);

}

XlsxApi.close("report");

Pattern 3 — convert workbook to object

onStartup:

InDriver.import("XlsxApi");

if (!XlsxApi.open("report", InDriver.currentPath() + "/report.xlsx")) {
InDriver.debug(XlsxApi.lastError(), "critical");
return;
}

let obj = XlsxApi.toObject("report", {
mode: "table",
allSheets: true,
headerRow: 1,
firstDataRow: 2,
skipEmptyRows: true
});

InDriver.debug(JSON.stringify(obj));

XlsxApi.close("report");

Pattern 4 — modify XLSX file and save copy

onStartup:

InDriver.import("XlsxApi");

if (!XlsxApi.open("report", InDriver.currentPath() + "/report.xlsx")) {
InDriver.debug(XlsxApi.lastError(), "critical");
return;
}

XlsxApi.writeA1("report", "A1", "Processed by InDriver");
XlsxApi.writeA1("report", "B1", new Date().toISOString());

XlsxApi.saveAs("report", InDriver.currentPath() + "/report_processed.xlsx");

XlsxApi.close("report");

Rules for AI code generation

When generating code using XlsxApi, follow these rules:

InDriver.import("XlsxApi");

if (!XlsxApi.open("report", file)) {
InDriver.debug(XlsxApi.lastError(), "critical");
return;
}