tc-context
Version:
TwinCAT ADS Communication Library for creating an active TwinCAT Context, with automatic symbol and type mapping
423 lines • 17.4 kB
TypeScript
/**
* Module containing the main TcCom Class, responsible for establishing ADS Connection and managing communication
* between {@link TcContext} and the PLC
*
*
* Licensed under MIT License.
*
* Copyright (c) 2020 Dmitrij Trifanov <d.v.trifanov@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* @packageDocumentation
*/
/// <reference types="node" />
import { TcContext } from './tc-context';
import { TcEmitter, TcComConnectedEvent, TcComDisconnectedEvent, TcComSourceChangedEvent, TcComConnectionLostEvent, TcComReconnectedEvent } from './tc-event';
/**
* Class responsible for establishing connection and managing all communication and data transformation
* to and from the Target PLC over TwinCAT's ADS layer.
*
* Is used as a wrapper for the [ads-client](https://github.com/jisotalo/ads-client) library.
*
*/
export declare class TcCom extends TcEmitter {
/**
* Constructor, which stores the {@link TcComSettings} used for establishing communication, as well as
* the callback, which is triggered upon Code Change detection
*
* @param context - Parent {@link TcContext}, of whom `TcCom` is part of, and whom to propagate events to
* @param settings - Settings used for communicating over ADS. Definition of connection settings can be found at [ads-client](https://github.com/jisotalo/ads-client) library
* @param onChange - Callback, which is called when Code Changes are detected. This callback is called after the `sourceChanged` event is emitted
* @param debug - If enabled, will produce debug information
*/
constructor(context: TcContext, settings: TcComSettings, onChange?: () => void, debug?: boolean);
/**
* Access to the previously used {@link TcComSettings} for establishing connection to the TwinCAT PLC
*/
get settings(): TcComSettings;
/**
* Returns `true` if the current `TcCom` Object is in a valid state, and can be used for communication
*/
get isValid(): boolean;
/**
* Initializes the `TcCom` Object, by establishing a connection to the TwinCAT PLC, with the previously provided {@link TcComSettings}, as well as
* setting up Code Change monitoring, if the Source Code on the PLC Changes, during run-time
*
* @throws {@link TcComBusyException} - Connection has already been created previously
* @throws {@link TcComConnectException} - Failed to establish a connection to the TwinCAT PLC over ADS
* @throws {@link TcComChangeDetectionException} - Failed to set up Code Change monitoring
*
* @return - The initialized `TcCom` Object
*/
initialize(): Promise<TcCom>;
/**
* Disconnects the previously established connection to the TwinCAT PLC, and cleans up all subscription handles.
* The `TcCom` Object is no longer usable after this point, unless `TcCom.initialize()` is once again called, to
* reestablish the connection.
*
* @throws {@link TcComUnsubscribeException} - Failed to unsubscribe the Handles
* @throws {@link TcComDisconnectException} - Failed to disconnect from the TwinCAT PLC
*
*/
disconnect(): Promise<void>;
/**
* Converts a given Buffer of data to Javascript Data, based on the TwinCAT Type.
* **This conversion works for primitive types, and not structured**
*
* @param type - The TwinCAT Type, whose data is to be converted
* @param buffer - The Buffer of Raw Data, that is to be converted
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for conversion
* @throws {@link TcComFromRawException} - Failed to convert the Raw Data
*
* @return - The Javascript equivalent of `buffer` data converted from the TwinCAT `type`
*
*/
fromRaw(type: string, buffer: Buffer): Promise<boolean | number | bigint | string>;
/**
* Converts a primitive non-structured Javascript Value to a Buffer of Data, which can be
* passed to a TwinCAT Type, as specified by the `type` argument.
* **This conversion works for primitive types, and not structured**
*
* @param type - The TwinCAT Type, to whom the value is converted
* @param value - The Javascript value, which is converted to Raw Data
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for conversion
* @throws {@link TcComToRawException} - Failed to convert to Raw Data
*
* @return - The Data Buffer, which can be passed to a TwinCAT Symbol of Type `type`, representing the passed `value`
*
*/
toRaw(type: string, value: boolean | number | bigint | string): Promise<Buffer>;
/**
* Subscribes to a TwinCAT Symbol, with a callback, which is invoked, whenever the Symbol value changes.
* The detection of change speed can be set through the `sampling` argument, in case the value changes too fast
* and such detection is not needed
*
* @param sampling - The speed in `ms` of detecting change. Any change in this interval will not trigger change events
* @param pointer - The Symbol Pointer, to which to subscribe
* @param callback - The callback that is invoked, whenever Symbol change is detected
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComSubscribeException} - Failed to subscribe to the provided pointer
*
* @return - The Subscription Handle, that can be used to unsubscribe in the future
*/
subscribe(sampling: number, pointer: TcSymbolPointer, callback: () => void): Promise<TcSubscription>;
/**
* Unsubscribes the previously created TwinCAT Handle for value change event
*
* @param hndl - The previously create active subscription handle to a TwinCAT Symbol
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComUnsubscribeException} - Failed to unsubscribe the handle
*
*/
unsubscribe(hndl: TcSubscription): Promise<void>;
/**
* Performs a write operation over ADS to the TwinCAT PLC of the provided `TcDataPackages`.
* When sending more than 500+ packages at once, the packages will be split in groups of 500 due to a limitation of ADS
*
* @param dataPackages - The packages with symbol location and data to be send to the Target
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComDataWriteException} - Failed to write data packages
*
*/
write(dataPackages: TcDataPackage[]): Promise<void>;
/**
* Performs a read operation over ADS of the TwinCAT Symbol Pointers.
* When requesting more than 500+ packages at once, the pointers will be split in groups of 500 due to a limitation of ADS
*
* @param pointer - The symbol pointers, whose data to be queried
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComDataReadException} - Failed to read data pointers
*
* @return - The data packages which were queried by the Symbol Pointers
*/
read(pointer: TcSymbolPointer[]): Promise<TcDataPackage[]>;
/**
* Performs a call to a method of a specific variable over ADS
*
* @param variable - The variable name, whose method is called
* @param method - The name of the method that is to be called
* @param parameters - The parameters, which are passed to the method
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComMethodCallException} - Failed to call the Rpc Method on the PLC Side
*
* @return - The result of the method call
*/
callMethod(variable: string, method: string, parameters: any): Promise<{
result: any;
outputs?: any;
}>;
/**
* Queries the raw ADS Type Data from the Target PLC
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComTypeQueryException} - Failed to query Type Data
*
* @return - The map of all the ADS Types currently present in the TwinCAT PLC
*/
types(): Promise<TcTypeInfoMap>;
/**
* Queries the raw ADS Symbol Data from the Target PLC
*
* @throws {@link TcComIsInvalidException} - Attempted to use an Invalid `TcCom` Object for subscription
* @throws {@link TcComSymbolQueryException} - Failed to query Symbol Data
*
* @return - The map of all the ADS Symbols currently present in the TwinCAT PLC
*/
symbols(): Promise<TcSymbolInfoMap>;
/**
* Emitted when `TcCom` connects to the Target PLC
* @event connected
*/
on(event: 'connected', listener: (e: TcComConnectedEvent) => void): any;
/**
* Emitted when `TcCom` disconnects from the Target PLC
* @event disconnected
*/
on(event: 'disconnected', listener: (e: TcComDisconnectedEvent) => void): any;
/**
* Emitted when `TcCom` detects Code Changes in the Target PLC
* @event sourceChanged
*/
on(event: 'sourceChanged', listener: (e: TcComSourceChangedEvent) => void): any;
/**
* Emitted when `TcCom` looses connection to the Target PLC
* @event sourceChanged
*/
on(event: 'connectionLost', listener: (e: TcComConnectionLostEvent) => void): any;
/**
* Emitted when `TcCom` reconnects to the Target PLC
* @event sourceChanged
*/
on(event: 'reconnected', listener: (e: TcComReconnectedEvent) => void): any;
/**
* The Default settings, used for connecting to a TwinCAT PLC, located at localhost.
* These settings are merged in, with whatever custom settings are provided during construction
*/
static readonly defaultSettings: any;
/**
* Internal function, which is invoked whenever Code Changes are detected by the `TcCom` object.
* Will emit the `sourceChanged` event, as well as invoke a callback which was provided
*
* @param response - The current PLC Last code change stamp which is used to see if changes have happened
*
*/
private __callback;
/**
* Internal function, which splits SymbolPointers into groups of 500,
* due to a TwinCAT ADS limitation, used by the `TcCom.read()` function
*
* @param data - List of Symbol Pointers to split
*
* @return - Groups of 500 Symbol Pointers
*/
private __splitData;
/**
* The low-level ADS Communication Module
* @internal
*/
private __ads?;
/**
* The `TcContext`, which acts as a parent to the `TcCom` and to whom events are propagated
* @internal
*/
private __context;
/**
* Copy of the settings, which are used for establishing a connection to the PLC Target
* @internal
*/
private __settings;
/**
* Tracker of Code Changes. If a Change is detected, the new value is compared to this tracker
* to deduce if changes in the Source have happened
* @internal
*/
private __changeCounter?;
/**
* Subscription handle, for the Code Change Tracker
* @internal
*/
private __changeHndl;
/**
* Callback, which is called after the `sourceChanged` event is emitter, when Code Changes are detected
* @internal
*/
private __callOnChange;
/**
* Path to the PLC Symbol, used as the Code Change Tracker
* @internal
*/
private static CHANGE_COUNTER;
/**
* @internal
*/
private __log;
}
/**
* Expected structure schema, of all potential ADS Communication Settings, that can be passed to the {@link TcCom} Object.
* These settings are mirror of the settings for the [ads-client](https://github.com/jisotalo/ads-client) library.
*/
export interface TcComSettings {
targetAmsNetId: string;
targetAdsPort: number;
objectifyEnumerations: boolean;
convertDatesToJavascript: boolean;
readAndCacheSymbols: boolean;
readAndCacheDataTypes: boolean;
disableSymbolVersionMonitoring: boolean;
disableStructPackModeWarning: boolean;
routerTcpPort: number;
routerAddress: string;
localAddress: string;
localTcpPort: number;
localAmsNetId: string;
localAdsPort: number;
timeoutDelay: number;
hideConsoleWarnings: boolean;
autoReconnect: boolean;
reconnectInterval: number;
checkStateInterval: number;
connectionDownDelay: number;
allowHalfOpen: boolean;
}
/**
* Base information from the ADS about a TwinCAT Type
*/
export interface TcTypeBase {
attributes?: TcAttribute[];
adsDataType: number;
offset?: number;
name: string;
type: string;
size: number;
}
/**
* Represents the location in the PLC, where a given TwinCAT Symbol resides
*/
export interface TcSymbolIndex {
indexGroup: number;
indexOffset: number;
}
/**
* A Data Package, which can be send over ADS to the TwinCAT PLC with Symbol location
* and what Buffer of Data to write to it
*/
export interface TcDataPackage extends TcSymbolIndex {
data: Buffer;
}
/**
* Represents a pointer to a Symbol in the PLC, to fetch data from, given the size
*/
export interface TcSymbolPointer extends TcSymbolIndex {
size: number;
}
/**
* Data set of information from the ADS about a TwinCAT Symbol and its definition
*/
export interface TcSymbolInfo extends TcSymbolPointer, TcTypeBase {
adsDataTypeStr: string;
flags: number;
flagsStr: string[];
arrayDimension: number;
nameLength: number;
typeLength: number;
comment: string;
}
/**
* Map of all Symbol information, relative to it name.
* ***NOTE:*** In TwinCAT, the key represents the full path to the fetched Symbol
*/
export interface TcSymbolInfoMap {
[key: string]: TcSymbolInfo;
}
/**
* Stores the information from the ADS about the Attributes, which are applied to a Type/Symbol
*/
export interface TcAttribute {
name: string;
value: string;
}
/**
* Data set of information from the ADS about a TwinCAT Type and its definition
*/
export interface TcTypeInfo extends TcTypeBase {
adsDataTypeStr: string;
comment: string;
arrayData: TcArrayDimension[];
enumInfo?: TcEnumField[];
subItems: TcTypeInfo[];
rpcMethods: {
name: string;
}[];
}
/**
* Map of all Type information, relative to it name.
* ***NOTE:*** In TwinCAT, the key used for the name of Type is lowercase
*/
export interface TcTypeInfoMap {
[key: string]: TcTypeInfo;
}
/**
* Represents a single field in a TwinCAT Enumerator Type
*/
export interface TcEnumField {
name: string;
value: Buffer;
}
/**
* Represents the definition of a single dimension of a TwinCAT Array Type
*/
export interface TcArrayDimension {
startIndex: number;
length: number;
}
/**
* ADS Subscription Handle, which can be stored and later used to unsubscribe from
* detecting Symbol Changes in the PLC
*/
export interface TcSubscription {
notificationHandle: number;
unsubscribe(): Promise<void>;
}
/**
* List of constants, which provide information on what PLC Type the Type is.
* This list of constants can be found here, with more information: [ADSDATATYPEID](https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_utilities/9007199290071051.html&id=)
*/
export declare const ADST: {
VOID: number;
INT8: number;
UINT8: number;
INT16: number;
UINT16: number;
INT32: number;
UINT32: number;
INT64: number;
UINT64: number;
REAL32: number;
REAL64: number;
BIGTYPE: number;
STRING: number;
WSTRING: number;
REAL80: number;
BIT: number;
};
export interface TcEnumBuffers {
[key: string]: Buffer;
}
//# sourceMappingURL=tc-com.d.ts.map