import { Component } from "./utils/PropertyChangedEvent" ; import { IConnection } from "./connection" ; import { GW_GET_GROUP_INFORMATION_NTF } from "./KLF200-API/GW_GET_GROUP_INFORMATION_NTF" ; import { GW_GET_ALL_GROUPS_INFORMATION_NTF } from "./KLF200-API/GW_GET_ALL_GROUPS_INFORMATION_NTF" ; import { Velocity , NodeVariation , ActuatorType } from "./KLF200-API/GW_SYSTEMTABLE_DATA" ; import { GroupType } from "./KLF200-API/GW_GROUPS" ; import { isArrayEqual } from "./utils/UtilityFunctions" ; import { GW_SET_GROUP_INFORMATION_CFM } from "./KLF200-API/GW_SET_GROUP_INFORMATION_CFM" ; import { GW_SET_GROUP_INFORMATION_REQ } from "./KLF200-API/GW_SET_GROUP_INFORMATION_REQ" ; import { GW_COMMON_STATUS , GatewayCommand , IGW_FRAME_RCV } from "./KLF200-API/common" ; import { TypedEvent , Listener , Disposable } from "./utils/TypedEvent" ; import { GW_GET_ALL_GROUPS_INFORMATION_FINISHED_NTF } from "./KLF200-API/GW_GET_ALL_GROUPS_INFORMATION_FINISHED_NTF" ; import { GW_GET_ALL_GROUPS_INFORMATION_REQ } from "./KLF200-API/GW_GET_ALL_GROUPS_INFORMATION_REQ" ; import { GW_GROUP_INFORMATION_CHANGED_NTF , ChangeType , GW_GROUP_INFORMATION_CHANGED_NTF_Modified } from "./KLF200-API/GW_GROUP_INFORMATION_CHANGED_NTF" ; import { GW_ACTIVATE_PRODUCTGROUP_CFM } from "./KLF200-API/GW_ACTIVATE_PRODUCTGROUP_CFM" ; import { GW_ACTIVATE_PRODUCTGROUP_REQ } from "./KLF200-API/GW_ACTIVATE_PRODUCTGROUP_REQ" ; import { convertPosition , ActivateProductGroupStatus , CommandOriginator , PriorityLevel , ParameterActive , PriorityLevelLock , PriorityLevelInformation } from "./KLF200-API/GW_COMMAND" ; import { GW_GET_NODE_INFORMATION_CFM } from "./KLF200-API/GW_GET_NODE_INFORMATION_CFM" ; import { GW_GET_NODE_INFORMATION_REQ } from "./KLF200-API/GW_GET_NODE_INFORMATION_REQ" ; import { GW_GET_NODE_INFORMATION_NTF } from "./KLF200-API/GW_GET_NODE_INFORMATION_NTF" ; import { GW_GET_ALL_GROUPS_INFORMATION_CFM } from "./KLF200-API/GW_GET_ALL_GROUPS_INFORMATION_CFM" ; import { GW_GET_GROUP_INFORMATION_CFM } from "./KLF200-API/GW_GET_GROUP_INFORMATION_CFM" ; import { GW_GET_GROUP_INFORMATION_REQ } from "./KLF200-API/GW_GET_GROUP_INFORMATION_REQ" ; "use strict" ; export class extends Component export class Group extends Component { type { number } memberof public readonly GroupID : number ; private _order : number ; private _placement : number ; private _name : string ; private _velocity : Velocity ; private _nodeVariation : NodeVariation ; private _groupType : GroupType ; type { number [ ] } memberof private readonly _Nodes : number [ ] = [ ] ; public get Nodes ( ) : number [ ] { return this . _Nodes ; } private _revision : number ; param { IConnection } Connection param { ( GW_GET_GROUP_INFORMATION_NTF | GW_GET_ALL_GROUPS_INFORMATION_NTF | GW_GROUP_INFORMATION_CHANGED_NTF ) } frame memberof constructor ( readonly Connection , frame ) { super ( ) ; this . GroupID = frame . GroupID ; this . _order = frame . Order ; this . _placement = frame . Placement ; this . _name = frame . Name ; this . _velocity = frame . Velocity ; this . _nodeVariation = frame . NodeVariation ; this . _groupType = frame . GroupType ; this . Nodes . push ( ... frame . Nodes ) ; this . _revision = frame . Revision ; this . Connection . on ( frame => this . onNotificationHandler ( frame ) , [ GatewayCommand . GW_GET_GROUP_INFORMATION_NTF ] ) ; } param { GW_GROUP_INFORMATION_CHANGED_NTF_Modified } frame memberof public changeFromNotification ( frame ) { if ( this . _order !== frame . Order ) { this . _order = frame . Order ; this . propertyChanged ( "Order" ) ; } if ( this . _placement !== frame . Placement ) { this . _placement = frame . Placement ; this . propertyChanged ( "Placement" ) ; } if ( this . _name !== frame . Name ) { this . _name = frame . Name ; this . propertyChanged ( "Name" ) ; } if ( this . _velocity !== frame . Velocity ) { this . _velocity = frame . Velocity ; this . propertyChanged ( "Velocity" ) ; } if ( this . _nodeVariation !== frame . NodeVariation ) { this . _nodeVariation = frame . NodeVariation ; this . propertyChanged ( "NodeVariation" ) ; } if ( this . _groupType !== frame . GroupType ) { this . _groupType = frame . GroupType ; this . propertyChanged ( "GroupType" ) ; } if ( ! isArrayEqual ( this . Nodes , frame . Nodes ) ) { this . Nodes . length = 0 ; this . Nodes . push ( ... frame . Nodes ) ; this . propertyChanged ( "Nodes" ) ; } this . _revision = frame . Revision ; } readonly type { number } memberof public get Order ( ) : number { return this . _order ; } readonly type { number } memberof public get Placement ( ) : number { return this . _placement ; } readonly type { string } memberof public get Name ( ) : string { return this . _name ; } readonly type { Velocity } memberof public get Velocity ( ) : Velocity { return this . _velocity ; } readonly type { NodeVariation } memberof public get NodeVariation ( ) : NodeVariation { return this . _nodeVariation ; } readonly type { GroupType } memberof public get GroupType ( ) : GroupType { return this . _groupType ; } param { number } order param { number } placement param { string } name param { Velocity } velocity param { NodeVariation } nodeVariation param { number [ ] } nodes returns { Promise < void > } memberof public async changeGroupAsync ( order , placement , name , velocity , nodeVariation , nodes ) { try { const changedProperties = [ ] ; if ( order !== this . _order ) changedProperties . push ( "Order" ) ; if ( placement !== this . _placement ) changedProperties . push ( "Placement" ) ; if ( name !== this . _name ) changedProperties . push ( "Name" ) ; if ( velocity !== this . _velocity ) changedProperties . push ( "Velocity" ) ; if ( nodeVariation !== this . _nodeVariation ) changedProperties . push ( "NodeVariation" ) ; if ( ! isArrayEqual ( nodes , this . Nodes ) ) changedProperties . push ( "Nodes" ) ; if ( changedProperties . length === 0 ) return Promise . resolve ( ) ; const confirmationFrame = < GW_SET_GROUP_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_SET_GROUP_INFORMATION_REQ ( this . GroupID , this . _revision , name , this . _groupType , nodes , order , placement , velocity , nodeVariation ) ) ; if ( confirmationFrame . Status === GW_COMMON_STATUS . SUCCESS ) { return Promise . resolve ( ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param { number } newOrder returns { Promise < void > } memberof public async setOrderAsync ( newOrder ) { return this . changeGroupAsync ( newOrder , this . _placement , this . _name , this . _velocity , this . _nodeVariation , this . Nodes ) ; } param { number } newPlacement returns { Promise < void > } memberof public async setPlacementAsync ( newPlacement ) { return this . changeGroupAsync ( this . _order , newPlacement , this . _name , this . _velocity , this . _nodeVariation , this . Nodes ) ; } param { string } newName returns { Promise < void > } memberof public async setNameAsync ( newName ) { return this . changeGroupAsync ( this . _order , this . _placement , newName , this . _velocity , this . _nodeVariation , this . Nodes ) ; } param { Velocity } newVelocity returns { Promise < void > } memberof public async setVelocityAsync ( newVelocity ) { return this . changeGroupAsync ( this . _order , this . _placement , this . _name , newVelocity , this . _nodeVariation , this . Nodes ) ; } param { NodeVariation } newNodeVariation returns { Promise < void > } memberof public async setNodeVariationAsync ( newNodeVariation ) { return this . changeGroupAsync ( this . _order , this . _placement , this . _name , this . _velocity , newNodeVariation , this . Nodes ) ; } param { number [ ] } newNodes returns { Promise < void > } memberof public async setNodesAsync ( newNodes ) { return this . changeGroupAsync ( this . _order , this . _placement , this . _name , this . _velocity , this . _nodeVariation , newNodes ) ; } param { number } newPositionRaw param Velocity param PriorityLevel param CommandOriginator param ParameterActive param PriorityLevelLock param PriorityLevels param LockTime returns { Promise < number > } memberof public async setTargetPositionRawAsync ( newPositionRaw , Velocity = 0 , PriorityLevel = 3 , CommandOriginator = 1 , ParameterActive = 0 , PriorityLevelLock = 0 , PriorityLevels = [ ] , LockTime = Infinity ) { try { const confirmationFrame = < GW_ACTIVATE_PRODUCTGROUP_CFM > await this . Connection . sendFrameAsync ( new GW_ACTIVATE_PRODUCTGROUP_REQ ( this . GroupID , newPositionRaw , PriorityLevel , CommandOriginator , ParameterActive , Velocity , PriorityLevelLock , PriorityLevels , LockTime ) ) ; if ( confirmationFrame . Status === ActivateProductGroupStatus . OK ) { return confirmationFrame . SessionID ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param { number } newPosition param Velocity param PriorityLevel param CommandOriginator param ParameterActive param PriorityLevelLock param PriorityLevels param LockTime returns { Promise < number > } memberof public async setTargetPositionAsync ( newPosition , Velocity = 0 , PriorityLevel = 3 , CommandOriginator = 1 , ParameterActive = 0 , PriorityLevelLock = 0 , PriorityLevels = [ ] , LockTime = Infinity ) { try { const nodeID = this . Nodes [ 0 ] ; let dispose ; const nodeTypeID = new Promise < ActuatorType > ( ( resolve , reject ) => { try { let nodeTypeID ; dispose = this . Connection . on ( frame => { try { if ( frame instanceof GW_GET_NODE_INFORMATION_NTF && frame . NodeID === nodeID ) { nodeTypeID = frame . ActuatorType ; if ( dispose ) { dispose . dispose ( ) ; } resolve ( nodeTypeID ) ; } } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } reject ( error ) ; } } , [ GatewayCommand . GW_GET_NODE_INFORMATION_NTF ] ) ; } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } reject ( error ) ; } } ) ; try { const productInformation = < GW_GET_NODE_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_NODE_INFORMATION_REQ ( nodeID ) ) ; if ( productInformation . Status !== GW_COMMON_STATUS . SUCCESS ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( new Error ( productInformation . getError ( ) ) ) ; } } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( error ) ; } return this . setTargetPositionRawAsync ( convertPosition ( newPosition , await nodeTypeID ) , Velocity , PriorityLevel , CommandOriginator , ParameterActive , PriorityLevelLock , PriorityLevels , LockTime ) ; } catch ( error ) { return Promise . reject ( error ) ; } } returns { Promise < void > } memberof public async refreshAsync ( ) { try { const confirmationFrame = < GW_GET_GROUP_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_GROUP_INFORMATION_REQ ( this . GroupID ) ) ; if ( confirmationFrame . Status === GW_COMMON_STATUS . SUCCESS ) { return Promise . resolve ( ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } private onNotificationHandler ( frame ) { if ( typeof this === "undefined" ) return ; if ( frame instanceof GW_GET_GROUP_INFORMATION_NTF ) { this . onGetGroupInformation ( frame ) ; } } private onGetGroupInformation ( frame ) { if ( frame . GroupID === this . GroupID ) { if ( frame . Order !== this . _order ) { this . _order = frame . Order ; this . propertyChanged ( "Order" ) ; } if ( frame . Placement !== this . _placement ) { this . _placement = frame . Placement ; this . propertyChanged ( "Placement" ) ; } if ( frame . Name !== this . _name ) { this . _name = frame . Name ; this . propertyChanged ( "Name" ) ; } if ( frame . Velocity !== this . _velocity ) { this . _velocity = frame . Velocity ; this . propertyChanged ( "Velocity" ) ; } if ( frame . NodeVariation !== this . _nodeVariation ) { this . _nodeVariation = frame . NodeVariation ; this . propertyChanged ( "NodeVariation" ) ; } if ( frame . GroupType !== this . _groupType ) { this . _groupType = frame . GroupType ; this . propertyChanged ( "GroupType" ) ; } const hasRemovedNodes = this . Nodes . every ( item => frame . Nodes . includes ( item ) ) ; const hasNewNodes = frame . Nodes . every ( item => this . Nodes . includes ( item ) ) ; if ( hasRemovedNodes || hasNewNodes ) { this . Nodes . length = 0 ; this . Nodes . push ( ... frame . Nodes ) ; this . propertyChanged ( "Nodes" ) ; } this . _revision = frame . Revision ; } } } export class export class Groups { private _onChangedGroup = new TypedEvent < number > ( ) ; private _onRemovedGroup = new TypedEvent < number > ( ) ; type { Group [ ] } memberof public readonly Groups : Group [ ] = [ ] ; private constructor ( readonly Connection ) { } private async initializeGroupsAsync ( ) { let dispose ; try { const notificationHandler = new Promise < void > ( ( resolve , reject ) => { try { dispose = this . Connection . on ( frame => { if ( frame instanceof GW_GET_ALL_GROUPS_INFORMATION_NTF || frame instanceof GW_GET_GROUP_INFORMATION_NTF ) { this . Groups [ frame . GroupID ] = new Group ( this . Connection , frame ) ; } else if ( frame instanceof GW_GET_ALL_GROUPS_INFORMATION_FINISHED_NTF ) { if ( dispose ) { dispose . dispose ( ) ; } this . Connection . on ( frame => this . onNotificationHandler ( frame ) , [ GatewayCommand . GW_GROUP_INFORMATION_CHANGED_NTF ] ) ; resolve ( ) ; } } , [ GatewayCommand . GW_GET_ALL_GROUPS_INFORMATION_NTF , GatewayCommand . GW_GET_ALL_GROUPS_INFORMATION_FINISHED_NTF , GatewayCommand . GW_GET_GROUP_INFORMATION_NTF ] ) ; } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } reject ( error ) ; } } ) ; const getAllGroupsInformation = < GW_GET_ALL_GROUPS_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_ALL_GROUPS_INFORMATION_REQ ( ) ) ; if ( getAllGroupsInformation . Status !== GW_COMMON_STATUS . SUCCESS ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( new Error ( getAllGroupsInformation . getError ( ) ) ) ; } if ( getAllGroupsInformation . NumberOfGroups > 0 ) { await notificationHandler ; } else { if ( dispose ) { dispose . dispose ( ) ; } } } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( error ) ; } } param { Listener < number > } handler returns { Disposable } memberof public onChangedGroup ( handler ) { return this . _onChangedGroup . on ( handler ) ; } param { Listener < number > } handler returns { Disposable } memberof public onRemovedGroup ( handler ) { return this . _onRemovedGroup . on ( handler ) ; } private notifyChangedGroup ( groupId ) { this . _onChangedGroup . emit ( groupId ) ; } private notifyRemovedGroup ( groupId ) { this . _onRemovedGroup . emit ( groupId ) ; } private onNotificationHandler ( frame ) { if ( frame instanceof GW_GROUP_INFORMATION_CHANGED_NTF ) { switch ( frame . ChangeType ) { case ChangeType . Deleted : delete this . Groups [ frame . GroupID ] ; this . notifyRemovedGroup ( frame . GroupID ) ; break ; case ChangeType . Modified : if ( typeof this . Groups [ frame . GroupID ] === "undefined" ) { this . Groups [ frame . GroupID ] = new Group ( this . Connection , frame as GW_GROUP_INFORMATION_CHANGED_NTF_Modified ) ; } else { this . Groups [ frame . GroupID ] . changeFromNotification ( frame as GW_GROUP_INFORMATION_CHANGED_NTF_Modified ) ; } this . notifyChangedGroup ( frame . GroupID ) ; default : break ; } } } static param { IConnection } Connection returns { Promise < Groups > } memberof static async createGroupsAsync ( Connection ) { try { const result = new Groups ( Connection ) ; await result . initializeGroupsAsync ( ) ; return result ; } catch ( error ) { return Promise . reject ( error ) ; } } param { string } groupName returns { ( Group | undefined ) } memberof public findByName ( groupName ) { return this . Groups . find ( grp => typeof grp !== "undefined" && grp . Name === groupName ) ; } }