tc-context
Version:
TwinCAT ADS Communication Library for creating an active TwinCAT Context, with automatic symbol and type mapping
961 lines (960 loc) • 45.4 kB
JavaScript
"use strict";
// tc-symbol.ts
/**
* Module, which contains the definitions of all the `TcSymbols` and their derived types, through which data manipulation with the
* Target PLC is made. The `TcSymbols` act as the interface between the `TcContext` and the `TcBindings`, where the `TcBindings`
* manage all the data parsing, checking and Symbol memory location, while the `TcSymbol` itself, as a wrapper for those bindings
* and collection of children Symbols.
*
*
* 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
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TcNamespaceSymbol = exports.TcArraySymbol = exports.TcStructureSymbol = exports.TcEnumSymbol = exports.TcStringSymbol = exports.TcNumericSymbol = exports.TcBooleanSymbol = exports.TcSymbol = void 0;
//----IMPORTS...
const debug_1 = __importDefault(require("debug"));
const tc_event_1 = require("./tc-event");
const tc_binding_1 = require("./tc-binding");
/**
* Class representing an instance of a PLC Symbol, mapped to the `TcContext`. The `TcSymbol` itself
* acts as a bridge to the `TcBinding`, which has the responsibility of low-level ADS operations.
*
* ***NOTE:*** In order to avoid naming collisions with the Symbols declared in the Target PLC, all public
* methods of `TcSymbol` start with the '$' character.
*
* The `TcSymbol` should not be directly created, as it serves as a Template for the Derived `TcSymbols`
*
*/
class TcSymbol {
/**
* Constructs the foundation of a `TcSymbol` Object
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param readOnly - Flag which marks this `TcSymbol` as a ReadOnly symbol, and no operation of write-type can be issued to the `TcSymbol`
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, readOnly = false, debug = false) {
/**
* @internal
*/
//@ts-ignore
this.__log = debug_1.default(`TcContext::TcSymbol`);
this.__parent = parent;
this.__path = path;
this.__readOnly = (parent === null || parent === void 0 ? void 0 : parent.$readOnly) || readOnly;
this.__log.enabled = debug;
}
/**
* Access the potential parent of this `TcSymbol`
*/
//@ts-ignore
get $parent() { return this.__parent; }
/**
* Access the path of this `TcSymbol` from its origin point
*/
//@ts-ignore
get $path() { return this.__path; }
/**
* Returns true if this `TcSymbol` is ReadOnly
*/
//@ts-ignore
get $readOnly() { return this.__readOnly; }
;
/**
* Returns the value of this `TcSymbol` from the Target PLC Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value to a non-existent field
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
/**
* Clears the data of the Target PLC Symbol to their implicit default values, or the explicitly specified ones
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingReadOnlyException} - Attempted to clear a ReadOnly Symbol
*
*/
//@ts-ignore
async $clear() {
this.__log(`$clear() : Clearing ${this.$path}`);
await this.$binding.clear();
this.__log(`$clear() : Clearing successfully ${this.$path}`);
this.$binding.emitCleared(new tc_event_1.TcSymbolClearedEvent(this.$binding.context, this));
return;
}
/**
* Activates value change detection of the Target PLC Symbol. The sampling rate can be explicitly
* set, in case the value changes uneseceraly too fast.
*
* @param sampling - The speed at which change in the Target PLC Symbol value is detected
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComSubscribeException} - An error occurred when subscribing to the Symbol
*
*/
//@ts-ignore
async $subscribe(sampling = 10) {
this.__log(`$subscribe() : Subscribing to ${this.$path}`);
this.$binding.subscribe(sampling, (value) => {
this.__log(`$subscribe() : Change of ${this.$path}`);
this.$binding.emitChange(new tc_event_1.TcSymbolChangedEvent(this.$binding.context, this, value));
});
}
/**
* Deactivated value change detection of the Target PLC Symbol. Does not remove the event handlers
* though, they simply will not be invoked.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComUnsubscribeException} - An error occurred when unsubscribing for a Symbol
*/
//@ts-ignore
async $unsubscribe() {
this.__log(`$subscribe() : Unsubscribing from ${this.$path}`);
await this.$binding.unsubscribe();
}
/**
* Attached the provided callback, which will be called when the `TcSymbol becomes invalidated
*
* @param callback - The function, which is to be called upon invalidation
*/
//@ts-ignore
$onInvalidated(callback) {
this.__invalidateCallback = callback;
}
//@ts-ignore
$on(eventName, listener) {
this.__log(`$on() : Adding handler ${eventName} to ${this.$path}`);
this.$binding.on(eventName, listener);
return this;
}
/**
* Removes a listener from the specified event
*
* @param eventName - The event name, from which the listener is to be removed
* @param listener - The listener, which is to be removed from the specified event
*/
//@ts-ignore
$off(eventName, listener) {
this.__log(`$off() : Removing handler ${eventName} to ${this.$path}`);
this.$binding.off(eventName, listener);
return this;
}
/**
* Attached a listener to an event, which is only invoked once. For the full list
* of events, see `TcSymbol.$on()`
*
* @param eventName - The event name, which the listener will listen for
* @param listener - The listener, which is called when the event is emitted
*/
//@ts-ignore
$once(eventName, listener) {
this.__log(`$once() : Adding once handler ${eventName} to ${this.$path}`);
this.$binding.once(eventName, listener);
return this;
}
/**
* Internal function, for calling invalidation on the provided `TcSymbol
*
* @param symbol - `TcSymbol`, which is to be invalidated
* @internal
*/
static invalidate(symbol) {
symbol.__invalidate();
}
/**
* Invalidates the `TcBinding`of this symbol, as well as, if a callback as provided
* in case of invalidation - will invoke it
*/
//@ts-ignore
__invalidate() {
tc_binding_1.TcBinding.invalidate(this.$binding);
if (this.__invalidateCallback) {
this.__invalidateCallback(this);
}
}
}
exports.TcSymbol = TcSymbol;
/**
* Class representing an instance of a PLC Symbol of Type `BOOL`.
*/
class TcBooleanSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a `BOOL` Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this `BOOL` Symbol
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, debug = false) {
super(path, parent, params.readOnly, debug);
this.__binding = new tc_binding_1.TcBooleanBinding(this, pointer, params, parent.$binding, debug);
}
;
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Returns the boolean value of this `TcSymbol` from the Target PLC `BOOL` Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided boolean value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The boolean value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value to a non-existent field
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
}
exports.TcBooleanSymbol = TcBooleanSymbol;
/**
* Class representing an instance of a PLC Symbol of Numeric Type.
*/
class TcNumericSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a Numeric Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this Symbol
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, debug = false) {
super(path, parent, params.readOnly, debug);
this.__binding = new tc_binding_1.TcNumericBinding(this, pointer, params, parent.$binding, debug);
}
;
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Access the maximum value that can be written to this symbol
*/
//@ts-ignore
get $upperBorder() { return this.__binding.upperBorder; }
/**
* Access the minimum value that can be written to this symbol
*/
//@ts-ignore
get $lowerBorder() { return this.__binding.lowerBorder; }
/**
* Returns the numeric value of this `TcSymbol` from the Target PLC Numeric Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided numeric value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The numeric value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value which is out of range of this numeric type
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
}
exports.TcNumericSymbol = TcNumericSymbol;
/**
* Class representing an instance of a PLC Symbol of Type `STRING` or `WSTRING`.
*/
class TcStringSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a `STRING` or `WSTRING` Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this `STRING` or `WSTRING` Symbol
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, debug = false) {
super(path, parent, params.readOnly, debug);
this.__binding = new tc_binding_1.TcStringBinding(this, pointer, params, parent.$binding, debug);
}
;
/**
* The maximum length of a string, that can be written
*/
//@ts-ignore
get $length() { return this.__binding.length; }
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Returns the string value of this `TcSymbol` from the Target PLC `STRING` or `WSTRING` Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided string value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The string value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a string value longer than maximum length
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
}
exports.TcStringSymbol = TcStringSymbol;
/**
* Class representing an instance of a PLC Symbol of Type `ENUM`.
*/
class TcEnumSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a `ENUM` Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this `ENUM` Symbol
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, debug = false) {
super(path, parent, params.readOnly, debug);
this.__binding = new tc_binding_1.TcEnumBinding(this, pointer, params, parent.$binding, debug);
}
;
/**
* Access the fields of this enumerator, which can
* be written
*/
//@ts-ignore
get $fields() { return this.__binding.fields; }
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Returns the string enum value of this `TcSymbol` from the Target PLC `ENUM` Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided string enum value, which is part of the allowed fields to
* the Target PLC Symbol, and when completed returns what was written to the Target PLC Symbol
*
* @param value - The string enum value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value to a non-existent field
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
}
exports.TcEnumSymbol = TcEnumSymbol;
/**
* Class representing an instance of a PLC Symbol of `Structure`, `Function_Block` or `UNION` Type.
*/
class TcStructureSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a `Structure`, `Function_Block` or `UNION` Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this Symbol
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, debug = false) {
super(path, parent, params.readOnly, debug);
/**
* List of children of this `TcSymbol`
* @internal
*/
//@ts-ignore
this.__children = [];
this.__binding = new tc_binding_1.TcStructureBinding(this, pointer, params, parent.$binding, debug);
params.children.forEach(child => {
const childInfo = {
indexGroup: pointer.indexGroup,
indexOffset: pointer.indexOffset + child.type.offset,
size: child.type.size
};
const childSymbol = child.type.instance(`${path}.${child.key}`, this, childInfo, debug);
this.__addChild({ key: child.key, symbol: childSymbol });
});
params.rpcMethods.forEach(meth => {
this.__addMethod(meth);
});
}
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Returns the structured value of this `TcSymbol` from the Target PLC `Structure`, `Function_Block` or `UNION` Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided structured value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The structured value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value which is out of range of this type
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
/**
* Iterates over all the `TcSymbol` Children of this `TcSymbol, and
* passes each of them to the provided callback
*
* @param callback - Callback, to which each `TcSymbol` Child is passed
*/
//@ts-ignore
$each(callback) {
this.__children.forEach(child => callback(child.symbol, child.key, this));
}
/**
* Internal use function, which registers a `TcSymbol` Child as part of this `TcSymbol
* @param child - The Child that is to be registered
*/
//@ts-ignore
__addChild(child) {
this.__children.push({ key: child.key, symbol: child.symbol });
Object.defineProperty(this, child.key, { get() { return child.symbol; } });
tc_binding_1.TcStructureBinding.addChild(this.__binding, { key: child.key, binding: child.symbol.$binding });
}
/**
* Internal use function, which registers an Rpc Method to this Structure
* @param name - The name of the method to create
*/
//@ts-ignore
__addMethod(name) {
Object.defineProperty(this, name, {
get() {
return (args) => {
return this.__binding.callMethod(this.$path, name, args);
};
}
});
}
/**
* Invalidates all the `TcSymbol` Children, before invalidating itself
*/
//@ts-ignore
__invalidate() {
this.$each(symbol => TcSymbol.invalidate(symbol));
super.__invalidate();
}
}
exports.TcStructureSymbol = TcStructureSymbol;
/**
* Class representing an instance of a PLC Symbol of `ARRAY OF...` Type.
*/
class TcArraySymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface with a `ARRAY OF...` Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param parent - Potential parent of this `TcSymbol` and to whom events will propagate to
* @param pointer - The memory location of the Target PLC Symbol
* @param params - The Type parameters of this Symbol
* @param depth - The Depth of this array, relative to the number of Dimensions in total
* @param debug - If enabled, will produce debug information
*/
constructor(path, parent, pointer, params, depth, debug = false) {
super(path, parent, params.readOnly, debug);
/**
* List of children of this `TcSymbol`
* @internal
*/
//@ts-ignore
this.__children = [];
this.__binding = new tc_binding_1.TcArrayBinding(this, pointer, params, params.dimensions[depth], parent.$binding, debug);
this.__createChildren(depth, params);
}
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Access the starting index of this array, due to TwinCAT allowing arrays to
* start at any number
*/
//@ts-ignore
get $startIndex() { return this.__binding.startIndex; }
/**
* Access the total length of the array
*/
//@ts-ignore
get $length() { return this.__binding.length; }
/**
* Returns the array value of this `TcSymbol` from the Target PLC `ARRAY OF...` Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided array value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The array value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value which is out of range of this type
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
/**
* Internal use function, which registers a `TcSymbol` Child as part of this `TcSymbol
* @param child - The Child that is to be registered
*/
//@ts-ignore
__addChild(child) {
this.__children.push({ key: child.key, symbol: child.symbol });
Object.defineProperty(this, child.key, { get() { return child.symbol; } });
tc_binding_1.TcArrayBinding.addChild(this.__binding, { key: child.key, binding: child.symbol.$binding });
}
/**
* Iterates over all the `TcSymbol` Children of this `TcSymbol, and
* passes each of them to the provided callback
*
* @param callback - Callback, to which each `TcSymbol` Child is passed
*/
//@ts-ignore
$each(callback) {
this.__children.forEach(child => callback(child.symbol, child.key, this));
}
/**
* Invalidates all the `TcSymbol` Children, before invalidating itself
*/
//@ts-ignore
__invalidate() {
this.$each(symbol => TcSymbol.invalidate(symbol));
super.__invalidate();
}
/**
* Internal function, for creating the children of the Array Symbol.
* If the array is multidimensional, it will create proxy-arrays to house
* each dimension
*
* @param depth - The Depth of the current array relative to the amount of dimensions
* @param params - The Parameters of the Array, from which construction is made
*/
//@ts-ignore
__createChildren(depth, params) {
let path = this.$path;
if (depth === 0) {
path = path + '[';
}
else {
path = path.substr(0, path.length - 1) + ',';
}
if (depth + 1 === params.dimensions.length) {
for (let index = params.dimensions[depth].startIndex; index < params.dimensions[depth].startIndex + params.dimensions[depth].length; ++index) {
const childPointer = {
indexGroup: this.$binding.indexGroup,
indexOffset: this.$binding.indexOffset + (params.child.size * index),
size: params.child.size
};
const childSymbol = params.child.instance(`${path}${index}]`, this, childPointer, this.__log.enabled);
this.__addChild({ key: index, symbol: childSymbol });
}
}
else
this.__createProxyArrays(path, params.dimensions[depth].length, depth, params);
}
/**
* Internal function, for handling multidimensional arrays, where it splits the current `TcSymbolPointer`
* and creates proxy arrays, to house the different dimensions
*
* @param path - The modified path for multidimensional arrays reference
* @param segments - The number of splits for this dimension
* @param depth - The current dimension depth, relative to the total amount of dimensions
* @param params - The Parameters of the Array, from which construction is made
*/
//@ts-ignore
__createProxyArrays(path, segments, depth, params) {
const offset = this.$binding.size / segments;
for (let index = 0; index < segments; index++) {
const pointer = {
indexGroup: this.$binding.indexGroup,
indexOffset: this.$binding.indexOffset + (offset * index),
size: offset
};
const childSymbol = new TcArraySymbol(`${path}${params.dimensions[depth].startIndex + index}]`, this, pointer, params, depth + 1, this.__log.enabled);
this.__addChild({ key: params.dimensions[depth].startIndex + index, symbol: childSymbol });
}
}
}
exports.TcArraySymbol = TcArraySymbol;
/**
* Class representing an instance of a PLC Symbol, which is the initial entry point to the `TcSymbol` map.
* These namespaces are usually `PROGRAMS` and different Variable Lists.
*
* This `TcSymbol` deduces its IndexOffset, IndexGroup and Size, based on the provided children
*/
class TcNamespaceSymbol extends TcSymbol {
/**
* Constructs a `TcSymbol`, which is designed to interface a namespace Symbol on the Target
* PLC.
*
* @param path - The Path of this Symbol, relative to its origin point
* @param context - The `TcContext`, that this namespace is apart of
* @param parent - Parent Emitter, to whom errors are propagated to
* @param debug - If enabled, will produce debug information
*/
constructor(path, context, parent, debug = false) {
super(path, undefined, false, debug);
/**
* List of children of this `TcSymbol`
* @internal
*/
//@ts-ignore
this.__children = [];
this.__binding = new tc_binding_1.TcNamespaceBinding(context, this, parent, debug);
}
/**
* Access the `TcBinding` of this `TcSymbol`
*/
//@ts-ignore
get $binding() { return this.__binding; }
/**
* Iterates over all the `TcSymbol` Children of this `TcSymbol, and
* passes each of them to the provided callback
*
* @param callback - Callback, to which each `TcSymbol` Child is passed
*/
//@ts-ignore
$each(callback) {
this.__children.forEach(child => callback(child.symbol, child.key, this));
}
/**
* Returns the structured value of this `TcSymbol` from the Target PLC namespace Symbol,
* which the `TcSymbol.$binding` is linked to.
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComDataReadException} - An error occurred when fetching the Symbol Data
* @throws {@link TcComFromRawException} - An error occurred when parsing Data to values
* @throws {@link TcBindingOutOfRangeException} - Error occurred when parsing returned Data from the Target PLC Symbol
*
* @return - The value of the Target PLC Symbol
*/
//@ts-ignore
get $get() {
this.__log(`$get() : Getting ${this.$path}`);
return this.$binding.read().then(result => {
this.__log(`$get() : Getting successfully${this.$path}`);
this.$binding.emitGet(new tc_event_1.TcSymbolGetEvent(this.$binding.context, this, result));
return result;
});
}
/**
* Writes the provided structured value to the Target PLC Symbol, and when completed returns what was
* written to the Target PLC Symbol
*
* @param value - The structured value that is to be written to the Target PLC Symbol
*
* @throws {@link TcBindingIsInvalidException} - Attempting operation on an invalidated `TcBinding`
* @throws {@link TcComIsInvalidException} - Attempting operation on an invalidated `TcCom` Object
* @throws {@link TcComToRawException} - An error occurred when parsing values to Data
* @throws {@link TcComDataWriteException} - An error occurred when writing the Symbol Data
* @throws {@link TcBindingOutOfRangeException} - Attempted to write a value which is out of range of this type
* @throws {@link TcBindingInvalidTypeException} - Type-mismatch occurred when parsing Values to Data
* @throws {@link TcBindingReadOnlyException} - Attempted to write to a ReadOnly Symbol
*
* @return - The value which was written to the Target PLC Symbol
*/
//@ts-ignore
async $set(value) {
this.__log(`$set() : Setting ${this.$path}`);
await this.$binding.write(value);
this.__log(`$set() : Setting successfully ${this.$path}`);
this.$binding.emitSet(new tc_event_1.TcSymbolSetEvent(this.$binding.context, this, value));
return value;
}
/**
* Internal use function, which registers a `TcSymbol` Child as part of this `TcSymbol
* @param child - The Child that is to be registered
*/
//@ts-ignore
__addChild(child) {
this.__children.push({ key: child.key, symbol: child.symbol });
Object.defineProperty(this, child.key, { get() { return child.symbol; } });
tc_binding_1.TcNamespaceBinding.addChild(this.__binding, { key: child.key, binding: child.symbol.$binding });
}
/**
* Internal use function, to add a `TcSymbol` Child to this `TcNamespaceSymbol`.
* Should not be called outside the library
*
* @param namespace - The namespace, to which the `TcSymbol` Child is added
* @param child - The `TcSymbol` Child, that is to be added to the namespace
*
* @internal
*/
static addChild(namespace, child) {
namespace.__addChild(child);
}
/**
* Invalidates all the `TcSymbol` Children, before invalidating itself
*/
//@ts-ignore
__invalidate() {
this.$each(symbol => TcSymbol.invalidate(symbol));
super.__invalidate();
}
}
exports.TcNamespaceSymbol = TcNamespaceSymbol;