Skip to content

Commit

Permalink
version 1.8.4
Browse files Browse the repository at this point in the history
Signed-off-by: Markus Graube <[email protected]>
  • Loading branch information
markusgraube committed Jun 13, 2019
1 parent ce62b48 commit 481df41
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 119 deletions.
6 changes: 5 additions & 1 deletion assets/modules/module_testserver_1.0.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"parameters": [
{
"name": "Parameter001",
"interface_class": "ExtAnaOp",
"interface_class": "ExtIntAnaOp",
"communication": {
"V": {
"namespace_index": "urn:NodeOPCUA-Server-default",
Expand Down Expand Up @@ -86,6 +86,10 @@
"OSLevel": {
"namespace_index": "urn:NodeOPCUA-Server-default",
"node_id": "Service1.Parameter1.OSLevel"
},
"OpMode": {
"namespace_index": "urn:NodeOPCUA-Server-default",
"node_id": "Service1.Parameter1.OpMode"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@p2olab/polaris-backend",
"version": "1.8.3",
"version": "1.8.4",
"main": "./build/src/index.js",
"types": "./build/src/index.d.ts",
"description": "Server backend for POL recipe execution engine",
Expand Down
4 changes: 2 additions & 2 deletions src/model/core/Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ export class Service extends (EventEmitter as new() => ServiceEmitter) {
max,
min,
unit,
readonly: param.interface_class === 'StrView',
type: interfaceClassToType[param.interface_class]
readonly: param.interfaceClass === 'StrView',
type: interfaceClassToType[param.interfaceClass]
};
});
}
Expand Down
100 changes: 55 additions & 45 deletions src/model/dataAssembly/DataAssembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
* SOFTWARE.
*/

import {OpcUaNodeOptions} from '../core/Interfaces';
import {catParameter, catService} from '../../config/logging';
import {EventEmitter} from 'events';
import {DataType, Variant, VariantArrayType} from 'node-opcua';
import {Module} from '../core/Module';
import {catParameter, catService} from '../../config/logging';
import {isAutomaticState, isExtSource, isManualState, isOffState, OpMode} from '../core/enum';
import {EventEmitter} from 'events';
import {OpcUaNodeOptions} from '../core/Interfaces';
import {Module} from '../core/Module';

export interface DataAssemblyOptions {
name: string;
Expand All @@ -37,21 +37,16 @@ export interface DataAssemblyOptions {
}

export class DataAssembly extends EventEmitter {
name: string;
interface_class: string;
communication: OpcUaNodeOptions[];

get OSLevel() { return this.communication['OSLevel']}
get WQC() { return this.communication['WQC']}


private module: Module;
protected subscribedNodes: string[] = [];
public name: string;
public interfaceClass: string;
public communication: OpcUaNodeOptions[];
protected module: Module;

constructor(options: DataAssemblyOptions, module: Module) {
super();
this.name = options.name;
this.interface_class = options.interface_class;
this.interfaceClass = options.interface_class;
this.communication = options.communication;

this.subscribedNodes.push('WQC', 'OSLevel');
Expand All @@ -61,11 +56,23 @@ export class DataAssembly extends EventEmitter {
}
}

public subscribe(samplingInterval=1000){
protected subscribedNodes: string[] = [];

get OSLevel() {
return this.communication['OSLevel'];
}

get WQC() {
return this.communication['WQC'];
}

public subscribe(samplingInterval = 1000) {
catParameter.debug(`DataAssembly ${this.name} subscribe to ${JSON.stringify(this.subscribedNodes)}`);
this.subscribedNodes
.filter(node => this.communication[node] && this.communication[node].node_id && this.communication[node].namespace_index)
.forEach(node => {
.filter((node) => this.communication[node] &&
this.communication[node].node_id &&
this.communication[node].namespace_index)
.forEach((node) => {
try {
this.module.listenToOpcUaNode(this.communication[node], samplingInterval)
.on('changed', () => {
Expand All @@ -79,7 +86,12 @@ export class DataAssembly extends EventEmitter {
return this;
}


/**
* Set parameter on module
* @param paramValue
* @param {string} variable
* @returns {Promise<any>}
*/
public async setParameter(paramValue: any, variable: string = 'VExt'): Promise<any> {
const opcUaNode = this.communication[variable];
const value = await this.module.readVariableNode(opcUaNode);
Expand All @@ -102,35 +114,12 @@ export class DataAssembly extends EventEmitter {
public async getOpMode(): Promise<OpMode> {
if (this.communication['OpMode']) {
const result = await this.module.readVariableNode(this.communication['OpMode']);
return <OpMode> result.value.value;
return result.value.value as OpMode;
} else {
return null;
}
}

/**
* Write OpMode to service
* @param {OpMode} opMode
* @returns {boolean}
*/
private async writeOpMode(opMode: OpMode): Promise<void> {
catParameter.debug(`[${this.name}] Write opMode: ${<number> opMode}`);
const result = await this.module.writeNode(this.communication['OpMode'],
{
dataType: DataType.UInt32,
value: opMode,
arrayType: VariantArrayType.Scalar,
dimensions: null
});
catParameter.debug(`[${this.name}] Setting opMode ${JSON.stringify(result)}`);
if (result.value !== 0) {
catParameter.warn(`[${this.name}] Error while setting opMode to ${opMode}: ${JSON.stringify(result)}`);
return Promise.reject();
} else {
return Promise.resolve();
}
}

public async waitForOpModeToPassSpecificTest(testFunction: (opMode: OpMode) => boolean) {
return new Promise((resolve) => {
const event = this.module.listenToOpcUaNode(this.communication['OpMode']);
Expand All @@ -148,7 +137,7 @@ export class DataAssembly extends EventEmitter {
* @returns {Promise<void>}
*/
public async setToAutomaticOperationMode(): Promise<void> {
let opMode: OpMode = await this.getOpMode();
const opMode: OpMode = await this.getOpMode();
catParameter.info(`[${this.name}] Current opMode = ${opMode}`);
if (opMode && isOffState(opMode)) {
catParameter.trace('First go to Manual state');
Expand All @@ -168,12 +157,33 @@ export class DataAssembly extends EventEmitter {
}

public async setToManualOperationMode(): Promise<void> {
let opMode = await this.getOpMode();
const opMode = await this.getOpMode();
if (opMode && !isManualState(opMode)) {
this.writeOpMode(OpMode.stateManOp);
await this.waitForOpModeToPassSpecificTest(isManualState);
}
}


/**
* Write OpMode to service
* @param {OpMode} opMode
* @returns {boolean}
*/
private async writeOpMode(opMode: OpMode): Promise<void> {
catParameter.debug(`[${this.name}] Write opMode: ${opMode as number}`);
const result = await this.module.writeNode(this.communication['OpMode'],
{
dataType: DataType.UInt32,
value: opMode,
arrayType: VariantArrayType.Scalar,
dimensions: null
});
catParameter.debug(`[${this.name}] Setting opMode ${JSON.stringify(result)}`);
if (result.value !== 0) {
catParameter.warn(`[${this.name}] Error while setting opMode to ${opMode}: ${JSON.stringify(result)}`);
return Promise.reject();
} else {
return Promise.resolve();
}
}
}
88 changes: 43 additions & 45 deletions src/model/dataAssembly/DataAssemblyFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,22 @@
* SOFTWARE.
*/


import {DataAssembly, DataAssemblyOptions} from './DataAssembly';
import {AnaMon, AnaView} from './AnaView';
import {catModule} from '../../config/logging';
import {Module} from '../core/Module';
import {AdvAnaOp, AnaServParam, ExtAnaOp, ExtIntAnaOp} from './AnaOp';
import {DigMon, DigView} from './DigView';
import {AdvDigOp, DigServParam, ExtDigOp, ExtIntDigOp} from './DigOp';
import {BinMon, BinView} from './BinView';
import {AnaMon, AnaView} from './AnaView';
import {AdvBinOp, BinServParam, ExtBinOp, ExtIntBinOp} from './BinOp';
import {catModule} from '../../config/logging';
import {AnaVlv, BinVlv, MonAnaVlv, MonBinVlv} from './Vlv';
import {BinMon, BinView} from './BinView';
import {DataAssembly, DataAssemblyOptions} from './DataAssembly';
import {AdvDigOp, DigServParam, ExtDigOp, ExtIntDigOp} from './DigOp';
import {DigMon, DigView} from './DigView';
import {AnaDrv, MonAnaDrv} from './Drv';
import {StrView} from './Str';
import {AnaVlv, BinVlv, MonAnaVlv, MonBinVlv} from './Vlv';

export class DataAssemblyFactory {
static create(variableOptions: DataAssemblyOptions, module: Module): DataAssembly {
catModule.info(`Create DataAssembly ${variableOptions.name} (${variableOptions.interface_class})`);
public static create(variableOptions: DataAssemblyOptions, module: Module): DataAssembly {
catModule.debug(`Create DataAssembly ${variableOptions.name} (${variableOptions.interface_class})`);

const types = {
'AnaView': AnaView,
Expand Down Expand Up @@ -75,76 +74,75 @@ export class DataAssemblyFactory {
};
let type = types[variableOptions.interface_class];
if (!type) {
if (variableOptions.interface_class) {
catModule.warn(`No data assembly implemented for ${variableOptions.interface_class} of ${variableOptions.name}. Use standard DataAssembly.`);
}
catModule.warn(`No data assembly implemented for ${variableOptions.interface_class} ` +
`of ${variableOptions.name}. Use standard DataAssembly.`);
type = DataAssembly;
}

return new type(variableOptions, module);
}

static isAnaView(dataAssembly: DataAssembly): dataAssembly is AnaView {
return dataAssembly.interface_class == 'AnaView';
public static isAnaView(dataAssembly: DataAssembly): dataAssembly is AnaView {
return dataAssembly.interfaceClass === 'AnaView';
}

static isExtAnaOp(dataAssembly: DataAssembly): dataAssembly is ExtAnaOp {
return this.isExtIntAnaOp(dataAssembly) || dataAssembly.interface_class == 'ExtAnaOp';
public static isExtAnaOp(dataAssembly: DataAssembly): dataAssembly is ExtAnaOp {
return this.isExtIntAnaOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtAnaOp';
}

static isExtIntAnaOp(dataAssembly: DataAssembly): dataAssembly is ExtIntAnaOp {
return this.isAdvAnaOp(dataAssembly) || dataAssembly.interface_class == 'ExtIntAnaOp';
public static isExtIntAnaOp(dataAssembly: DataAssembly): dataAssembly is ExtIntAnaOp {
return this.isAdvAnaOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtIntAnaOp';
}

static isAdvAnaOp(dataAssembly: DataAssembly): dataAssembly is AdvAnaOp {
return this.isAnaServParam(dataAssembly) || dataAssembly.interface_class == 'AdvAnaOp';
public static isAdvAnaOp(dataAssembly: DataAssembly): dataAssembly is AdvAnaOp {
return this.isAnaServParam(dataAssembly) || dataAssembly.interfaceClass === 'AdvAnaOp';
}

static isAnaServParam(dataAssembly: DataAssembly): dataAssembly is AnaServParam {
return dataAssembly.interface_class == 'AnaServParam';
public static isAnaServParam(dataAssembly: DataAssembly): dataAssembly is AnaServParam {
return dataAssembly.interfaceClass === 'AnaServParam';
}

static isDigView(dataAssembly: DataAssembly): dataAssembly is DigView {
return dataAssembly.interface_class == 'DigView';
public static isDigView(dataAssembly: DataAssembly): dataAssembly is DigView {
return dataAssembly.interfaceClass === 'DigView';
}

static isExtDigOp(dataAssembly: DataAssembly): dataAssembly is ExtDigOp {
return this.isExtIntDigOp(dataAssembly) || dataAssembly.interface_class == 'ExtDigOp';
public static isExtDigOp(dataAssembly: DataAssembly): dataAssembly is ExtDigOp {
return this.isExtIntDigOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtDigOp';
}

static isExtIntDigOp(dataAssembly: DataAssembly): dataAssembly is ExtIntDigOp {
return this.isAdvDigOp(dataAssembly) || dataAssembly.interface_class == 'ExtIntDigOp';
public static isExtIntDigOp(dataAssembly: DataAssembly): dataAssembly is ExtIntDigOp {
return this.isAdvDigOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtIntDigOp';
}

static isAdvDigOp(dataAssembly: DataAssembly): dataAssembly is AdvDigOp {
return this.isDigServParam(dataAssembly) || dataAssembly.interface_class == 'AdvDigOp';
public static isAdvDigOp(dataAssembly: DataAssembly): dataAssembly is AdvDigOp {
return this.isDigServParam(dataAssembly) || dataAssembly.interfaceClass === 'AdvDigOp';
}

static isDigServParam(dataAssembly: DataAssembly): dataAssembly is DigServParam {
return dataAssembly.interface_class == 'DigServParam';
public static isDigServParam(dataAssembly: DataAssembly): dataAssembly is DigServParam {
return dataAssembly.interfaceClass === 'DigServParam';
}

static isBinView(dataAssembly: DataAssembly): dataAssembly is BinView {
return dataAssembly.interface_class == 'BinView';
public static isBinView(dataAssembly: DataAssembly): dataAssembly is BinView {
return dataAssembly.interfaceClass === 'BinView';
}

static isExtBinOp(dataAssembly: DataAssembly): dataAssembly is ExtBinOp {
return this.isExtIntBinOp(dataAssembly) || dataAssembly.interface_class == 'ExtBinOp';
public static isExtBinOp(dataAssembly: DataAssembly): dataAssembly is ExtBinOp {
return this.isExtIntBinOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtBinOp';
}

static isExtIntBinOp(dataAssembly: DataAssembly): dataAssembly is ExtIntBinOp {
return this.isAdvBinOp(dataAssembly) || dataAssembly.interface_class == 'ExtIntBinOp';
public static isExtIntBinOp(dataAssembly: DataAssembly): dataAssembly is ExtIntBinOp {
return this.isAdvBinOp(dataAssembly) || dataAssembly.interfaceClass === 'ExtIntBinOp';
}

static isAdvBinOp(dataAssembly: DataAssembly): dataAssembly is AdvBinOp {
return this.isBinServParam(dataAssembly) || dataAssembly.interface_class == 'AdvBinOp';
public static isAdvBinOp(dataAssembly: DataAssembly): dataAssembly is AdvBinOp {
return this.isBinServParam(dataAssembly) || dataAssembly.interfaceClass === 'AdvBinOp';
}

static isBinServParam(dataAssembly: DataAssembly): dataAssembly is BinServParam {
return dataAssembly.interface_class == 'BinServParam';
public static isBinServParam(dataAssembly: DataAssembly): dataAssembly is BinServParam {
return dataAssembly.interfaceClass === 'BinServParam';
}

static isStrView(dataAssembly: DataAssembly): dataAssembly is StrView {
return dataAssembly.interface_class == 'StrView';
public static isStrView(dataAssembly: DataAssembly): dataAssembly is StrView {
return dataAssembly.interfaceClass === 'StrView';
}
}
10 changes: 5 additions & 5 deletions src/model/recipe/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ export class Player extends (EventEmitter as new() => PlayerEmitter) {
catPlayer.info('Stop player');
if (this.status === RecipeState.running) {
this._status = RecipeState.stopped;
return this.getCurrentRecipe().stop();
await this.currentRecipeRun.stop();
this.currentRecipeRun = null;
}
}

Expand Down Expand Up @@ -250,14 +251,13 @@ export class Player extends (EventEmitter as new() => PlayerEmitter) {
catPlayer.info(`Start recipe ${this.getCurrentRecipe().name}`);
this.currentRecipeRun = new RecipeRun(this.getCurrentRecipe());
this.recipeRuns.push(this.currentRecipeRun);
return new Promise(async (resolve) => {
this.currentRecipeRun.recipe
return new Promise((resolve) => {
this.currentRecipeRun
.on('stepFinished', (finishedStep) => this.emit('stepFinished', finishedStep))
.once('started', () => this.emit('recipeStarted', this.currentRecipeRun.recipe))
.on('started', () => this.emit('recipeStarted', this.currentRecipeRun.recipe))
.once('completed', () => {
this.emit('recipeFinished', this.currentRecipeRun.recipe);
catPlayer.info(`recipe finished ${this.currentItem + 1}/${this._playlist.length} (${this.status})`);
this.currentRecipeRun.recipe.removeAllListeners('stepFinished');
resolve();
});
this.currentRecipeRun.start();
Expand Down
Loading

0 comments on commit 481df41

Please sign in to comment.