/*-------------------------------------------------------------------------------------------------------------- * Copyright (c) insite-gmbh. All rights reserved. * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------------------------*/ import { Observable } from 'rxjs/Rx'; import { Injectable } from '@angular/core'; import { Http, Headers } from '@angular/http'; import { InaxConfiguration } from '../../../@inax/common'; import { InaxPlcService, DataChangeEvent } from '../../../@inax/plc'; import { InaxSqlService } from '../../../@inax/sql'; import { InaxScriptService } from '../../../@inax/script'; import { InaxLoggerService } from '../../../@inax/logger'; import { Subject } from "rxjs/Subject"; import { IMotionEx, UdtMotion, ViewMode, IFinalPositionEx, MovingDirection, MotionTextTable, LanguageEntryList } from './domain'; import { MethodPropertyChangeEvent } from './../../script/src/domain/propertyChangedEvent'; import { IPlcEventProxy } from '../../plc/src/domain/plcEventProxy'; @Injectable() /** * Service class to communicate with inax to handle plc motions * @class InaxMotionService */ export class InaxMotionService { private _tableName: string = "Motions"; private _tableQuery: string = "BlockNum = {}"; private _scriptUnitName: string = "MotionScripts"; private _inizializedPropertyName: string = "MotionDataInitialized"; private _groupName: string = "motion"; private _dataBlockName: string = "DB_InaxSafety" private _hmiId: number = -1; public get MappingName(): string { return this._dataBlockName; } public get HmiId(): number { return this._hmiId; } public set HmiId(value: number) { this._hmiId = value; } constructor(private _inaxPlc: InaxPlcService, private _inaxSql: InaxSqlService, private _inaxScript: InaxScriptService, private _logger: InaxLoggerService, private _configuration: InaxConfiguration) { } /** * Fetch the number of motions from the database. * @method getNumberOfMotionsForBlockAsync * @param {String} plcId * @param {Number} block */ public async getNumberOfMotionsForBlockAsync(plcId: string, block: number): Promise { return await this._inaxSql.count(this._tableName, this._tableQuery.replace("{}", String(block))).toPromise(); } /** * Fetch the motions from the database. * @method getMotionsForBlockAsync * @param {String} plcId * @param {Number} block */ public async getMotionsForBlockAsync(plcId: string, block: number): Promise> { let result = new Array(); let initialized = await this._inaxScript.getScriptPropertyValueInServerContext(this._scriptUnitName, this._inizializedPropertyName).toPromise(); if (initialized) { let motions = await this._inaxSql.query(this._tableName, "BlockNum=" + block, "pageNumber, RowNumber", "FinalPositions").toPromise(); for (let motion of motions) { motion.UdtModiondata = new UdtMotion(); motion.OtherHmiId = false; } return motions; } return result; } /** * create a proxy to subscribe to datachange callbacks from the safe plc block. * @method createSafeBlockHeaderProxy * @param {String} plcId * @param { Array}variables */ public createSafeBlockHeaderProxy(plcId: string, variables: Array): IPlcEventProxy { return this._inaxPlc.createEventProxy(this._groupName, plcId, this._dataBlockName, variables); } /** * create a proxy to subscribe to datachange callbacks of the given motion. * @method createMotionProxy * @param {IMotionEx} motion * @param {Array}variables */ public createMotionProxy(motion: IMotionEx, variables: Array): IPlcEventProxy { return this._inaxPlc.createEventProxy(this._groupName, motion.Plc, motion.MappingName, variables); } /** * This methods creates a proxy for the datachange mechanism of the operand values. * @method createOperandValueProxy * @param {String} plcId * @param {IFinalPositionEx} finalPosition */ private createOperandValueProxy(motion: IMotionEx): IPlcEventProxy { //TODO return null; } /** * Start a selection of a motion, if a selection is active you could start moving the selected motion. * @method selectMotion * @param {String} plcId * @param {IMotionEx} motion */ public selectMotion(motion: IMotionEx, info:string = ""): Observable { if (motion == null) throw "motion is null"; return this._inaxScript.invokeInClientContext(this._scriptUnitName, "StartSelection", [motion.Plc, motion.MappingName, this._hmiId, motion.SlotNumber, info]); } /** * Stop the selection of a motion. * @method selectMotion * @param {String} plcId * @param {IMotionEx} motion */ public deselectMotion(motion: IMotionEx): Observable { if (motion == null) throw "motion is null"; return this._inaxScript.invokeInClientContext(this._scriptUnitName, "StopSelection", [motion.Plc, motion.Id, this._hmiId, motion.SlotNumber]); } /** * Signals selection is going on. (if selected, this method should be called all n milliseconds) * @method signalOngoingSelection * @param {IMotionEx} motion * @param {MovingDirection} direction */ public signalOngoingSelection(motion: IMotionEx) { if (motion == null) throw "motion is null"; this._inaxScript.setScriptPropertyInClientContext(this._scriptUnitName, "SelectedSlotId", motion.SlotNumber); } /** * Start moving a motion. This is only available, if the motion is currently selected. * @method startMoving * @param {String} plcId * @param {IMotionEx} motion * @param {MovingDirection} direction */ public startMoving(motion: IMotionEx, direction: MovingDirection): Observable { if (motion == null) throw "motion is null"; if (direction == MovingDirection.None) throw "invalid direction"; return this._inaxScript.invokeInClientContext(this._scriptUnitName, "StartMoving", [motion.Plc, motion.MappingName, direction, this._hmiId, motion.SlotNumber]); } /** * Stops moving of the motion. * @method stopMoving * @param {String} plcId * @param {IMotionEx} motion * @param {MovingDirection} direction */ public stopMoving(motion: IMotionEx, direction: MovingDirection) { if (motion == null) throw "motion is null"; return this._inaxScript.invokeInClientContext(this._scriptUnitName, "StopMoving", [motion.Plc, motion.MappingName, direction, this._hmiId, motion.SlotNumber]); } /** * Signals moving is going on. (if moving is running this method should be called all n milliseconds) * @method signalOngoingMovement * @param {IMotionEx} motion * @param {MovingDirection} direction */ public signalOngoingMovement(motion: IMotionEx, direction: MovingDirection) { if (motion == null) throw "motion is null"; if (direction == MovingDirection.None) throw "invalid direction"; this._inaxScript.setScriptPropertyInClientContext(this._scriptUnitName, `PressedButton${Number(direction)}SlotId`, motion.SlotNumber); } /** * This method is called to permit a running takeover for the given motion. * @method stopMoving * @param {IMotionEx} motion */ public permitTakeover(motion: IMotionEx) { if (motion == null) throw "motion is null"; this._inaxScript.executeInClientContext(this._scriptUnitName, "TakeoverAction", [motion.Plc, motion.SlotNumber, true]); } /** * This method is called to refuse a running takeover for the given motion. * @method stopMoving * @param {IMotionEx} motion */ public refuseTakeover(motion: IMotionEx) { if (motion == null) throw "motion is null"; this._inaxScript.executeInClientContext(this._scriptUnitName, "TakeoverAction", [motion.Plc, motion.SlotNumber, false]); } }