@ternion/opc-link-client
v0.1.2
Published
A lightweight TypeScript client library for interacting with the TERNION-OPC-REST-API
Maintainers
Readme
@ternion/opc-link-client
A lightweight TypeScript client library for interacting with the QNetLinks OPC REST API. This library provides a type-safe interface for reading and writing OPC UA node values through a RESTful API.
Features
- Fully type-safe API client with comprehensive TypeScript support and proper return types
- Class-based API with
TernionOpcLinkClientfor easy instantiation - Read operations: Query cached values, read specific nodes, and retrieve aliases with typed responses
- Write operations: Write Boolean, Int16, and Float values to OPC nodes
- Alias support: Convenient access to predefined alias channels (bool, int16, float)
- Convenience methods: Helper methods for reading channels and vectors with proper typing
- Error handling: Comprehensive error handling with descriptive messages
- ESM modules: Modern ES module syntax with native Node.js support
- Zero dependencies: Uses native
fetchAPI (Node.js 18+)
Prerequisites
- Node.js 18+ (required for native
fetchAPI) - QNetLinks OPC REST API running at
http://localhost:9990(default, configurable)
Installation
npm install @ternion/opc-link-clientQuick Start
import { TernionOpcLinkClient } from '@ternion/opc-link-client';
// Create a client instance (uses default URL: http://localhost:9990/opc/api/v1)
const client = new TernionOpcLinkClient();
// Or specify a custom API URL
const client = new TernionOpcLinkClient('http://your-api-host:port/opc/api/v1');
// Get API information
const info = await client.getApiInfo();
console.log(info);
// Check API health
const health = await client.getHealth();
console.log(health);Usage
Basic Example
import { TernionOpcLinkClient } from '@ternion/opc-link-client';
const client = new TernionOpcLinkClient();
// Get all cached values
const values = await client.getValues();
console.log(values);Reading Values
import { TernionOpcLinkClient } from '@ternion/opc-link-client';
const client = new TernionOpcLinkClient();
// Read a specific node by ID
const value = await client.getValue('ns=1;s=Boolean.0');
// Read by alias (channel 0 of bool type)
const aliasValue = await client.getAlias('bool', 0);
// Get all aliases of a type
const allBools = await client.getAllAliases('bool');
// Force a fresh read (bypass cache)
const freshValue = await client.readNode({
nodeId: 'ns=1;s=Boolean.0',
forceRefresh: true
});Writing Values
import { TernionOpcLinkClient } from '@ternion/opc-link-client';
const client = new TernionOpcLinkClient();
// Write using convenience helpers
await client.writeBoolean(0, true); // Write to Boolean.0
await client.writeInt16(1, 42); // Write to Int16.1
await client.writeFloat(2, 3.14159); // Write to Float.2
// Write using generic writeNode method
await client.writeNode({
nodeId: 'ns=1;s=CustomNode',
dataType: 'Boolean',
value: true,
refreshCache: true
});Error Handling
All methods throw errors on failure. Always wrap calls in try-catch:
try {
await client.writeBoolean(0, true);
} catch (error) {
console.error('Write failed:', error);
// Handle error appropriately
}API Reference
TernionOpcLinkClient Class
Constructor
new TernionOpcLinkClient(apiBaseUrl?: string)Creates a new client instance. The apiBaseUrl parameter is optional and defaults to "http://localhost:9990/opc/api/v1".
Methods
Information & Health
getApiInfo(): Promise<ApiInfo>- Get API metadata and available endpointsgetHealth(): Promise<HealthStatus>- Get current health status of the bridge
Reading Values
getValues(): Promise<NodeValue[]>- Get all cached node valuesgetValue(nodeId: string): Promise<NodeValue>- Get cached value for a specific nodegetAlias(type: AliasType, channel: number): Promise<NodeValue>- Get value by alias and channelgetAllAliases(type: AliasType): Promise<AliasCollection>- Get all channels for an alias typereadNode(request: ReadRequest): Promise<NodeValue>- Read a node (optionally force refresh)readBoolean(channel: number, forceRefresh?: boolean): Promise<NodeValue>- Read Boolean channelreadInt16(channel: number, forceRefresh?: boolean): Promise<NodeValue>- Read Int16 channelreadFloat(channel: number, forceRefresh?: boolean): Promise<NodeValue>- Read Float channelreadBooleanVector(forceRefresh?: boolean): Promise<NodeValue>- Read BooleanVector nodereadInt16Vector(forceRefresh?: boolean): Promise<NodeValue>- Read Int16Vector nodereadFloatVector(forceRefresh?: boolean): Promise<NodeValue>- Read FloatVector node
Writing Values
writeNode(request: WriteRequest): Promise<WriteResponse>- Generic write functionwriteBoolean(channel: number, data: boolean): Promise<WriteResponse>- Write boolean valuewriteInt16(channel: number, data: number): Promise<WriteResponse>- Write 16-bit integer (-32768 to 32767)writeFloat(channel: number, data: number): Promise<WriteResponse>- Write floating-point value
Static Validation Methods
TernionOpcLinkClient.validateChannel(channel: number): void- Validate channel indexTernionOpcLinkClient.validateAliasType(type: string): asserts type is AliasType- Validate alias type
Types
AliasType
type AliasType = 'bool' | 'int16' | 'float';ReadRequest
interface ReadRequest {
nodeId: string;
forceRefresh?: boolean;
}WriteRequest
interface WriteRequest {
nodeId: string;
dataType: 'Boolean' | 'Int16' | 'Float' | string | number;
value: unknown;
arrayType?: string | number;
refreshCache?: boolean;
}WriteResponse
interface WriteResponse {
status: string;
nodeId: string;
result: NodeValue;
}NodeValue
interface NodeValue {
nodeId: string;
value: unknown;
dataType: string;
arrayType: string;
statusCode: string;
sourceTimestamp: string;
serverTimestamp: string;
updatedAt: string;
}ApiInfo
interface ApiInfo {
[key: string]: unknown;
}API metadata information returned by the root endpoint.
HealthStatus
interface HealthStatus {
[key: string]: unknown;
}Health status information returned by the health endpoint.
AliasCollection
type AliasCollection = NodeValue[];Collection of alias values returned by getAllAliases().
Examples
See the examples/ directory for complete usage examples.
Run the demo example:
npm startOr directly:
npx tsx examples/demo.tsDevelopment
Building
npm run buildThis compiles TypeScript to the dist/ directory.
Type Checking
npx tsc --noEmitCleaning
npm run cleanRemoves the dist/ directory.
Project Structure
@ternion/opc-link-client/
├── src/
│ ├── index.ts # Main entry point
│ └── ternion-opc-link-client/
│ └── ternion-opc-link-client.ts # Client implementation
├── dist/ # Compiled output (generated)
├── examples/ # Example code
│ └── demo.ts
├── package.json
├── tsconfig.json
└── README.mdLicense
MIT
Changelog
[Unreleased]
Improved
- Type Safety: Replaced all
Promise<unknown>return types with proper TypeScript interfacesgetApiInfo()now returnsPromise<ApiInfo>getHealth()now returnsPromise<HealthStatus>getValues()now returnsPromise<NodeValue[]>getValue(),getAlias(),readNode(), and all convenience read methods now returnPromise<NodeValue>getAllAliases()now returnsPromise<AliasCollection>
- Added new exported types:
ApiInfo,HealthStatus, andAliasCollection - Enhanced type safety throughout the library for better IDE autocomplete and compile-time error checking
