"use strict" ; import { Velocity , ActuatorType , NodeVariation , PowerSaveMode , NodeOperatingState , ActuatorAlias } from "./KLF200-API/GW_SYSTEMTABLE_DATA" ; import { GW_GET_NODE_INFORMATION_NTF } from "./KLF200-API/GW_GET_NODE_INFORMATION_NTF" ; import { GW_GET_ALL_NODES_INFORMATION_NTF } from "./KLF200-API/GW_GET_ALL_NODES_INFORMATION_NTF" ; import { IConnection } from "./connection" ; import { GW_SET_NODE_NAME_CFM } from "./KLF200-API/GW_SET_NODE_NAME_CFM" ; import { GW_SET_NODE_NAME_REQ } from "./KLF200-API/GW_SET_NODE_NAME_REQ" ; import { GW_COMMON_STATUS , GatewayCommand , IGW_FRAME_RCV , GW_INVERSE_STATUS } from "./KLF200-API/common" ; import { GW_SET_NODE_VARIATION_CFM } from "./KLF200-API/GW_SET_NODE_VARIATION_CFM" ; import { GW_SET_NODE_VARIATION_REQ } from "./KLF200-API/GW_SET_NODE_VARIATION_REQ" ; import { GW_SET_NODE_ORDER_AND_PLACEMENT_CFM } from "./KLF200-API/GW_SET_NODE_ORDER_AND_PLACEMENT_CFM" ; import { GW_SET_NODE_ORDER_AND_PLACEMENT_REQ } from "./KLF200-API/GW_SET_NODE_ORDER_AND_PLACEMENT_REQ" ; import { TypedEvent , Listener , Disposable } from "./utils/TypedEvent" ; import { Component } from "./utils/PropertyChangedEvent" ; import { GW_NODE_INFORMATION_CHANGED_NTF } from "./KLF200-API/GW_NODE_INFORMATION_CHANGED_NTF" ; import { GW_NODE_STATE_POSITION_CHANGED_NTF } from "./KLF200-API/GW_NODE_STATE_POSITION_CHANGED_NTF" ; import { GW_COMMAND_SEND_REQ } from "./KLF200-API/GW_COMMAND_SEND_REQ" ; import { GW_COMMAND_SEND_CFM } from "./KLF200-API/GW_COMMAND_SEND_CFM" ; import { GW_GET_ALL_NODES_INFORMATION_REQ } from "./KLF200-API/GW_GET_ALL_NODES_INFORMATION_REQ" ; import { GW_GET_ALL_NODES_INFORMATION_FINISHED_NTF } from "./KLF200-API/GW_GET_ALL_NODES_INFORMATION_FINISHED_NTF" ; import { GW_CS_SYSTEM_TABLE_UPDATE_NTF } from "./KLF200-API/GW_CS_SYSTEM_TABLE_UPDATE_NTF" ; import { GW_GET_NODE_INFORMATION_REQ } from "./KLF200-API/GW_GET_NODE_INFORMATION_REQ" ; import { GW_WINK_SEND_CFM } from "./KLF200-API/GW_WINK_SEND_CFM" ; import { GW_WINK_SEND_REQ } from "./KLF200-API/GW_WINK_SEND_REQ" ; import { CommandStatus , RunStatus , StatusReply , ParameterActive , convertPositionRaw , convertPosition , FunctionalParameter , LimitationType , CommandOriginator , PriorityLevel , LockTime , PriorityLevelLock , PriorityLevelInformation } from "./KLF200-API/GW_COMMAND" ; import { GW_COMMAND_RUN_STATUS_NTF } from "./KLF200-API/GW_COMMAND_RUN_STATUS_NTF" ; import { GW_COMMAND_REMAINING_TIME_NTF } from "./KLF200-API/GW_COMMAND_REMAINING_TIME_NTF" ; import { GW_GET_ALL_NODES_INFORMATION_CFM } from "./KLF200-API/GW_GET_ALL_NODES_INFORMATION_CFM" ; import { GW_GET_NODE_INFORMATION_CFM } from "./KLF200-API/GW_GET_NODE_INFORMATION_CFM" ; import { GW_GET_LIMITATION_STATUS_CFM } from "./KLF200-API/GW_GET_LIMITATION_STATUS_CFM" ; import { GW_GET_LIMITATION_STATUS_REQ } from "./KLF200-API/GW_GET_LIMITATION_STATUS_REQ" ; import { GW_LIMITATION_STATUS_NTF } from "./KLF200-API/GW_LIMITATION_STATUS_NTF" ; import { GW_SESSION_FINISHED_NTF } from "./KLF200-API/GW_SESSION_FINISHED_NTF" ; import { GW_SET_LIMITATION_CFM } from "./KLF200-API/GW_SET_LIMITATION_CFM" ; import { GW_SET_LIMITATION_REQ } from "./KLF200-API/GW_SET_LIMITATION_REQ" ; export class export class Product extends Component { private _name : string ; type { number } memberof public readonly NodeID : number ; private _TypeID : ActuatorType ; readonly type { ActuatorType } memberof public get TypeID ( ) : ActuatorType { return this . _TypeID ; } private _SubType : number ; readonly type { number } memberof public get SubType ( ) : number { return this . _SubType ; } private _order : number ; private _placement : number ; private _velocity : Velocity ; readonly type { Velocity } memberof public get Velocity ( ) : Velocity { return this . _velocity ; } ; private _nodeVariation : NodeVariation ; private _PowerSaveMode : PowerSaveMode ; readonly type { PowerSaveMode } memberof public get PowerSaveMode ( ) : PowerSaveMode { return this . _PowerSaveMode ; } private _SerialNumber : Buffer ; readonly type { Buffer } memberof public get SerialNumber ( ) : Buffer { return this . _SerialNumber ; } private _ProductType : number ; readonly type { number } memberof public get ProductType ( ) : number { return this . _ProductType ; } private _state : NodeOperatingState ; private _currentPositionRaw : number ; private _targetPositionRaw : number ; private _fp1CurrentPositionRaw : number ; private _fp2CurrentPositionRaw : number ; private _fp3CurrentPositionRaw : number ; private _fp4CurrentPositionRaw : number ; private _remainingTime : number ; private _timeStamp : Date ; private _ProductAlias : ActuatorAlias [ ] ; type { ActuatorAlias [ ] } memberof public get ProductAlias ( ) : ActuatorAlias [ ] { return this . _ProductAlias ; } private _runStatus : RunStatus = RunStatus . ExecutionCompleted ; private _statusReply : StatusReply = StatusReply . Unknown ; param { IConnection } Connection param { ( GW_GET_NODE_INFORMATION_NTF | GW_GET_ALL_NODES_INFORMATION_NTF ) } frame memberof constructor ( readonly Connection , frame ) { super ( ) ; this . NodeID = frame . NodeID ; this . _name = frame . Name ; this . _TypeID = frame . ActuatorType ; this . _SubType = frame . ActuatorSubType ; this . _order = frame . Order ; this . _placement = frame . Placement ; this . _velocity = frame . Velocity ; this . _nodeVariation = frame . NodeVariation ; this . _PowerSaveMode = frame . PowerSaveMode ; this . _SerialNumber = frame . SerialNumber ; this . _ProductType = frame . ProductType ; this . _state = frame . OperatingState ; this . _currentPositionRaw = frame . CurrentPosition ; this . _targetPositionRaw = frame . TargetPosition ; this . _fp1CurrentPositionRaw = frame . FunctionalPosition1CurrentPosition ; this . _fp2CurrentPositionRaw = frame . FunctionalPosition2CurrentPosition ; this . _fp3CurrentPositionRaw = frame . FunctionalPosition3CurrentPosition ; this . _fp4CurrentPositionRaw = frame . FunctionalPosition4CurrentPosition ; this . _remainingTime = frame . RemainingTime ; this . _timeStamp = frame . TimeStamp ; this . _ProductAlias = frame . ActuatorAliases ; this . _limitationMinRaw = new Array < number > ( 17 ) . fill ( 0 ) ; this . _limitationMaxRaw = new Array < number > ( 17 ) . fill ( 0xC800 ) ; this . Connection . on ( frame => this . onNotificationHandler ( frame ) , [ GatewayCommand . GW_NODE_INFORMATION_CHANGED_NTF , GatewayCommand . GW_NODE_STATE_POSITION_CHANGED_NTF , GatewayCommand . GW_COMMAND_RUN_STATUS_NTF , GatewayCommand . GW_COMMAND_REMAINING_TIME_NTF , GatewayCommand . GW_GET_NODE_INFORMATION_NTF ] ) ; } readonly type { string } memberof public get Name ( ) : string { return this . _name ; } param { string } newName returns { Promise < void > } memberof public async setNameAsync ( newName ) { try { const confirmationFrame = < GW_SET_NODE_NAME_CFM > await this . Connection . sendFrameAsync ( new GW_SET_NODE_NAME_REQ ( this . NodeID , newName ) ) ; if ( confirmationFrame . Status === GW_COMMON_STATUS . SUCCESS ) { this . _name = newName ; return Promise . resolve ( ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } readonly type { string } memberof public get Category ( ) : string { switch ( this . TypeID ) { case ActuatorType . VenetianBlind : return "Interior venetian blind" ; case ActuatorType . RollerShutter : switch ( this . SubType ) { case 1 : return "Adjustable slats roller shutter" ; case 2 : return "Roller shutter with projection" ; default : return "Roller shutter" ; } case ActuatorType . Awning : return "Vertical exterior awning" ; case ActuatorType . WindowOpener : switch ( this . SubType ) { case 1 : return "Window opener with integrated rain sensor" ; default : return "Window opener" ; } case ActuatorType . GarageOpener : return "Garage door opener" ; case ActuatorType . Light : return "Light" ; case ActuatorType . GateOpener : return "Gate opener" ; case ActuatorType . Lock : switch ( this . SubType ) { case 1 : return "Window lock" ; default : return "Door lock" ; } case ActuatorType . Blind : return "Vertical interior blind" ; case ActuatorType . DualShutter : return "Dual roller shutter" ; case ActuatorType . OnOffSwitch : return "On/Off switch" ; case ActuatorType . HorizontalAwning : return "Horizontal awning" ; case ActuatorType . ExternalVentianBlind : return "Exterior venetion blind" ; case ActuatorType . LouvreBlind : return "Louvre blind" ; case ActuatorType . CurtainTrack : return "Curtain track" ; case ActuatorType . VentilationPoint : switch ( this . SubType ) { case 1 : return "Air inlet" ; case 2 : return "Air transfer" ; case 3 : return "Air outlet" ; default : return "Ventilation point" ; } case ActuatorType . ExteriorHeating : return "Exterior heating" ; case ActuatorType . SwingingShutter : switch ( this . SubType ) { case 1 : return "Swinging shutter with independent handling of the leaves" ; default : return "Swinging shutter" ; } default : return `${ this . TypeID . toString ( ) }.${ this . SubType . toString ( ) }` ; } } readonly type { NodeVariation } memberof public get NodeVariation ( ) : NodeVariation { return this . _nodeVariation ; } param { NodeVariation } newNodeVariation returns { Promise < void > } memberof public async setNodeVariationAsync ( newNodeVariation ) { try { const confirmationFrame = < GW_SET_NODE_VARIATION_CFM > await this . Connection . sendFrameAsync ( new GW_SET_NODE_VARIATION_REQ ( this . NodeID , newNodeVariation ) ) ; if ( confirmationFrame . Status === GW_COMMON_STATUS . SUCCESS ) { this . _nodeVariation = newNodeVariation ; return Promise . resolve ( ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param { number } newOrder param { number } newPlacement returns { Promise < void > } memberof public async setOrderAndPlacementAsync ( newOrder , newPlacement ) { try { const confirmationFrame = < GW_SET_NODE_ORDER_AND_PLACEMENT_CFM > await this . Connection . sendFrameAsync ( new GW_SET_NODE_ORDER_AND_PLACEMENT_REQ ( this . NodeID , newOrder , newPlacement ) ) ; if ( confirmationFrame . Status === GW_COMMON_STATUS . SUCCESS ) { this . _order = newOrder ; this . _placement = newPlacement ; return Promise . resolve ( ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } readonly type { number } memberof public get Order ( ) : number { return this . _order ; } param { number } newOrder returns { Promise < void > } memberof public async setOrderAsync ( newOrder ) { return this . setOrderAndPlacementAsync ( newOrder , this . _placement ) ; } readonly type { number } memberof public get Placement ( ) : number { return this . _placement ; } param { number } newPlacement returns { Promise < void > } memberof public async setPlacementAsync ( newPlacement ) { return this . setOrderAndPlacementAsync ( this . _order , newPlacement ) ; } readonly type { NodeOperatingState } memberof public get State ( ) : NodeOperatingState { return this . _state ; } readonly type { number } memberof public get CurrentPositionRaw ( ) : number { return this . _currentPositionRaw ; } readonly type { number } memberof public get TargetPositionRaw ( ) : number { return this . _targetPositionRaw ; } readonly type { number } memberof public get FP1CurrentPositionRaw ( ) : number { return this . _fp1CurrentPositionRaw ; } readonly type { number } memberof public get FP2CurrentPositionRaw ( ) : number { return this . _fp2CurrentPositionRaw ; } readonly type { number } memberof public get FP3CurrentPositionRaw ( ) : number { return this . _fp3CurrentPositionRaw ; } readonly type { number } memberof public get FP4CurrentPositionRaw ( ) : number { return this . _fp4CurrentPositionRaw ; } readonly type { number } memberof public get RemainingTime ( ) : number { return this . _remainingTime ; } readonly type { Date } memberof public get TimeStamp ( ) : Date { return this . _timeStamp ; } readonly type { RunStatus } memberof public get RunStatus ( ) : RunStatus { return this . _runStatus ; } readonly type { StatusReply } memberof public get StatusReply ( ) : StatusReply { return this . _statusReply ; } readonly type { number } memberof public get CurrentPosition ( ) : number { return convertPositionRaw ( this . _currentPositionRaw , this . TypeID ) ; } param { number } newPosition param PriorityLevel param CommandOriginator param ParameterActive param FunctionalParameters param PriorityLevelLock param PriorityLevels param LockTime returns { Promise < number > } memberof public async setTargetPositionAsync ( newPosition , PriorityLevel = 3 , CommandOriginator = 1 , ParameterActive = 0 , FunctionalParameters = [ ] , PriorityLevelLock = 0 , PriorityLevels = [ ] , LockTime = Infinity ) { try { const req = new GW_COMMAND_SEND_REQ ( this . NodeID , convertPosition ( newPosition , this . TypeID ) , PriorityLevel , CommandOriginator , ParameterActive , FunctionalParameters , PriorityLevelLock , PriorityLevels , LockTime ) ; const confirmationFrame = < GW_COMMAND_SEND_CFM > await this . Connection . sendFrameAsync ( req ) ; if ( confirmationFrame . CommandStatus === CommandStatus . CommandAccepted ) { return confirmationFrame . SessionID ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } readonly type { number } memberof public get TargetPosition ( ) : number { return convertPositionRaw ( this . _targetPositionRaw , this . TypeID ) ; } private _limitationMinRaw : number [ ] ; readonly type { number [ ] } memberof public get LimitationMinRaw ( ) : readonly number [ ] { return Array . from ( this . _limitationMinRaw ) ; } readonly param functionalParameter type { number } memberof public getLimitationMinRaw ( functionalParameter ) { return this . _limitationMinRaw [ functionalParameter ] ; } private _limitationMaxRaw : number [ ] ; readonly param functionalParameter type { number [ ] } memberof public get LimitationMaxRaw ( ) : readonly number [ ] { return Array . from ( this . _limitationMaxRaw ) ; } readonly type { number } memberof public getLimitationMaxRaw ( functionalParameter ) { return this . _limitationMaxRaw [ functionalParameter ] ; } param functionalParameter returns public getLimitations ( functionalParameter ) { const limitationMin = convertPositionRaw ( this . getLimitationMinRaw ( functionalParameter ) , this . TypeID ) ; const limitationMax = convertPositionRaw ( this . getLimitationMaxRaw ( functionalParameter ) , this . TypeID ) ; if ( limitationMin <= limitationMax ) { return [ limitationMin , limitationMax ] ; } else { return [ limitationMax , limitationMin ] ; } } readonly param functionalParameter type { number } memberof public getLimitationMin ( functionalParameter ) { return this . getLimitations ( functionalParameter ) [ 0 ] ; } readonly param functionalParameter type { number } memberof public getLimitationMax ( functionalParameter ) { return this . getLimitations ( functionalParameter ) [ 1 ] ; } param PriorityLevel param CommandOriginator param ParameterActive param FunctionalParameters param PriorityLevelLock param PriorityLevels param LockTime returns { Promise < number > } memberof public async stopAsync ( PriorityLevel = 3 , CommandOriginator = 1 , ParameterActive = 0 , FunctionalParameters = [ ] , PriorityLevelLock = 0 , PriorityLevels = [ ] , LockTime = Infinity ) { try { const confirmationFrame = < GW_COMMAND_SEND_CFM > await this . Connection . sendFrameAsync ( new GW_COMMAND_SEND_REQ ( this . NodeID , 0xD200 , PriorityLevel , CommandOriginator , ParameterActive , FunctionalParameters , PriorityLevelLock , PriorityLevels , LockTime ) ) ; if ( confirmationFrame . CommandStatus === CommandStatus . CommandAccepted ) { return confirmationFrame . SessionID ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param EnableWink param WinkTime param PriorityLevel param CommandOriginator returns { Promise < number > } memberof public async winkAsync ( EnableWink = true , WinkTime = 254 , PriorityLevel = 3 , CommandOriginator = 1 ) { try { const confirmationFrame = < GW_WINK_SEND_CFM > await this . Connection . sendFrameAsync ( new GW_WINK_SEND_REQ ( this . NodeID , EnableWink , WinkTime , PriorityLevel , CommandOriginator ) ) ; if ( confirmationFrame . Status === GW_INVERSE_STATUS . SUCCESS ) { return confirmationFrame . SessionID ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } returns { Promise < void > } memberof public async refreshAsync ( ) { try { const confirmationFrame = < GW_GET_NODE_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_NODE_INFORMATION_REQ ( this . NodeID ) ) ; 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 async waitForLimitationFinished ( sessionID , limitationType , parameterActive ) { const limitationTypes = [ ] ; if ( Array . isArray ( limitationType ) ) { limitationTypes . push ( ... limitationType ) ; } else { limitationTypes . push ( limitationType ) ; } return new Promise ( ( resolve , reject ) => { try { const dispose = this . Connection . on ( frame => { try { if ( frame instanceof GW_LIMITATION_STATUS_NTF && frame . SessionID === sessionID ) { if ( frame . NodeID !== this . NodeID ) { throw new Error ( `Unexpected node ID: ${ frame . NodeID }` ) ; } if ( frame . ParameterID !== parameterActive ) { throw new Error ( `Unexpected parameter ID: ${ frame . ParameterID }` ) ; } if ( limitationTypes . indexOf ( LimitationType . MinimumLimitation ) !== - 1 ) { if ( frame . LimitationValueMin !== this . _limitationMinRaw [ frame . ParameterID ] ) { this . _limitationMinRaw [ frame . ParameterID ] = frame . LimitationValueMin ; this . propertyChanged ( "LimitationMinRaw" ) ; } } if ( limitationTypes . indexOf ( LimitationType . MaximumLimitation ) !== - 1 ) { if ( frame . LimitationValueMax !== this . _limitationMaxRaw [ frame . ParameterID ] ) { this . _limitationMaxRaw [ frame . ParameterID ] = frame . LimitationValueMax ; this . propertyChanged ( "LimitationMaxRaw" ) ; } } } else if ( frame instanceof GW_SESSION_FINISHED_NTF && frame . SessionID === sessionID ) { dispose ?. dispose ( ) ; resolve ( ) ; } } catch ( error ) { dispose ?. dispose ( ) ; reject ( error ) ; } } , [ GatewayCommand . GW_LIMITATION_STATUS_NTF , GatewayCommand . GW_SESSION_FINISHED_NTF ] ) ; } catch ( error ) { reject ( error ) ; } } ) ; } param limitationType param parameterActive returns public async refreshLimitationAsync ( limitationType , parameterActive = ParameterActive . MP ) { try { const confirmationFrame = < GW_GET_LIMITATION_STATUS_CFM > await this . Connection . sendFrameAsync ( new GW_GET_LIMITATION_STATUS_REQ ( this . NodeID , limitationType , parameterActive ) ) ; if ( confirmationFrame . Status === GW_INVERSE_STATUS . SUCCESS ) { return this . waitForLimitationFinished ( confirmationFrame . SessionID , limitationType , parameterActive ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param minValue param maxValue param parameterActive param limitationTime param commandOriginator param priorityLevel returns public async setLimitationRawAsync ( minValue , maxValue , parameterActive = ParameterActive . MP , limitationTime = 253 , commandOriginator = CommandOriginator . SAAC , priorityLevel = PriorityLevel . ComfortLevel2 ) { try { const confirmationFrame = < GW_SET_LIMITATION_CFM > await this . Connection . sendFrameAsync ( new GW_SET_LIMITATION_REQ ( this . NodeID , minValue , maxValue , limitationTime , priorityLevel , commandOriginator , parameterActive ) ) ; if ( confirmationFrame . Status === GW_INVERSE_STATUS . SUCCESS ) { return this . waitForLimitationFinished ( confirmationFrame . SessionID , [ LimitationType . MinimumLimitation , LimitationType . MaximumLimitation ] , parameterActive ) ; } else { return Promise . reject ( new Error ( confirmationFrame . getError ( ) ) ) ; } } catch ( error ) { return Promise . reject ( error ) ; } } param minValue param maxValue param parameterActive param limitationTime param commandOriginator param priorityLevel returns public async setLimitationAsync ( minValue , maxValue , parameterActive = ParameterActive . MP , limitationTime = Infinity , commandOriginator = CommandOriginator . SAAC , priorityLevel = PriorityLevel . ComfortLevel2 ) { try { if ( minValue > maxValue ) { throw new Error ( `Parameter minValue (${ minValue }) must be less than or equal to parameter maxValue (${ maxValue }).` ) ; } if ( minValue < 0 || minValue > 1 ) { throw new Error ( "Parameter minValue must be between 0 and 1." ) ; } if ( maxValue < 0 || maxValue > 1 ) { throw new Error ( "Parameter maxValue must be between 0 and 1." ) ; } let rawMinValue = convertPosition ( minValue , this . TypeID ) ; let rawMaxValue = convertPosition ( maxValue , this . TypeID ) ; const rawLimitationTime = LockTime . lockTimeTolockTimeValueForLimitation ( limitationTime ) ; if ( rawMinValue > rawMaxValue ) { [ rawMinValue , rawMaxValue ] = [ rawMaxValue , rawMinValue ] ; } return this . setLimitationRawAsync ( rawMinValue , rawMaxValue , parameterActive , rawLimitationTime , commandOriginator , priorityLevel ) ; } catch ( error ) { return Promise . reject ( error ) ; } } param parameterActive param commandOriginator param priorityLevel returns public async clearLimitationAsync ( parameterActive = ParameterActive . MP , commandOriginator = CommandOriginator . SAAC , priorityLevel = PriorityLevel . ComfortLevel2 ) { return this . setLimitationRawAsync ( 0xD400 , 0xD400 , parameterActive , 255 , commandOriginator , priorityLevel ) ; } private onNotificationHandler ( frame ) { if ( typeof this === "undefined" ) return ; if ( frame instanceof GW_NODE_INFORMATION_CHANGED_NTF ) { this . onNodeInformationChanged ( frame ) ; } else if ( frame instanceof GW_NODE_STATE_POSITION_CHANGED_NTF ) { this . onNodeStatePositionChanged ( frame ) ; } else if ( frame instanceof GW_COMMAND_RUN_STATUS_NTF ) { this . onRunStatus ( frame ) ; } else if ( frame instanceof GW_COMMAND_REMAINING_TIME_NTF ) { this . onRemainingTime ( frame ) ; } else if ( frame instanceof GW_GET_NODE_INFORMATION_NTF ) { this . onGetNodeInformation ( frame ) ; } } private onNodeInformationChanged ( frame ) { if ( frame . NodeID === this . NodeID ) { if ( frame . Name !== this . _name ) { this . _name = frame . Name ; this . propertyChanged ( "Name" ) ; } if ( frame . NodeVariation !== this . _nodeVariation ) { this . _nodeVariation = frame . NodeVariation ; this . propertyChanged ( "NodeVariation" ) ; } if ( frame . Order !== this . _order ) { this . _order = frame . Order ; this . propertyChanged ( "Order" ) ; } if ( frame . Placement !== this . _placement ) { this . _placement = frame . Placement ; this . propertyChanged ( "Placement" ) ; } } } private onNodeStatePositionChanged ( frame ) { if ( frame . NodeID === this . NodeID ) { if ( frame . OperatingState !== this . _state ) { this . _state = frame . OperatingState ; this . propertyChanged ( "State" ) ; } if ( frame . CurrentPosition !== this . _currentPositionRaw ) { this . _currentPositionRaw = frame . CurrentPosition ; this . propertyChanged ( "CurrentPositionRaw" ) ; this . propertyChanged ( "CurrentPosition" ) ; } if ( frame . TargetPosition !== this . _targetPositionRaw ) { this . _targetPositionRaw = frame . TargetPosition ; this . propertyChanged ( "TargetPositionRaw" ) ; this . propertyChanged ( "TargetPosition" ) ; } if ( frame . FunctionalPosition1CurrentPosition !== this . _fp1CurrentPositionRaw ) { this . _fp1CurrentPositionRaw = frame . FunctionalPosition1CurrentPosition ; this . propertyChanged ( "FP1CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition2CurrentPosition !== this . _fp2CurrentPositionRaw ) { this . _fp2CurrentPositionRaw = frame . FunctionalPosition2CurrentPosition ; this . propertyChanged ( "FP2CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition3CurrentPosition !== this . _fp3CurrentPositionRaw ) { this . _fp3CurrentPositionRaw = frame . FunctionalPosition3CurrentPosition ; this . propertyChanged ( "FP3CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition4CurrentPosition !== this . _fp4CurrentPositionRaw ) { this . _fp4CurrentPositionRaw = frame . FunctionalPosition4CurrentPosition ; this . propertyChanged ( "FP4CurrentPositionRaw" ) ; } if ( frame . RemainingTime !== this . _remainingTime ) { this . _remainingTime = frame . RemainingTime ; this . propertyChanged ( "RemainingTime" ) ; } } } private onRunStatus ( frame ) { if ( frame . NodeID === this . NodeID ) { switch ( frame . NodeParameter ) { case ParameterActive . MP : if ( frame . ParameterValue !== this . _currentPositionRaw ) { this . _currentPositionRaw = frame . ParameterValue ; this . propertyChanged ( "CurrentPositionRaw" ) ; this . propertyChanged ( "CurrentPosition" ) ; } break ; case ParameterActive . FP1 : if ( frame . ParameterValue !== this . _fp1CurrentPositionRaw ) { this . _fp1CurrentPositionRaw = frame . ParameterValue ; this . propertyChanged ( "FP1CurrentPositionRaw" ) ; } break ; case ParameterActive . FP2 : if ( frame . ParameterValue !== this . _fp2CurrentPositionRaw ) { this . _fp2CurrentPositionRaw = frame . ParameterValue ; this . propertyChanged ( "FP2CurrentPositionRaw" ) ; } break ; case ParameterActive . FP3 : if ( frame . ParameterValue !== this . _fp3CurrentPositionRaw ) { this . _fp3CurrentPositionRaw = frame . ParameterValue ; this . propertyChanged ( "FP3CurrentPositionRaw" ) ; } break ; case ParameterActive . FP4 : if ( frame . ParameterValue !== this . _fp4CurrentPositionRaw ) { this . _fp4CurrentPositionRaw = frame . ParameterValue ; this . propertyChanged ( "FP4CurrentPositionRaw" ) ; } break ; default : break ; } if ( frame . RunStatus !== this . _runStatus ) { this . _runStatus = frame . RunStatus ; this . propertyChanged ( "RunStatus" ) ; } if ( frame . StatusReply !== this . _statusReply ) { this . _statusReply = frame . StatusReply ; this . propertyChanged ( "StatusReply" ) ; } } } private onRemainingTime ( frame ) { if ( frame . NodeID === this . NodeID && frame . NodeParameter === ParameterActive . MP && frame . RemainingTime !== this . _remainingTime ) { this . _remainingTime = frame . RemainingTime ; this . propertyChanged ( "RemainingTime" ) ; } } private onGetNodeInformation ( frame ) { if ( frame . NodeID === this . NodeID ) { 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 . ActuatorType !== this . _TypeID ) { this . _TypeID = frame . ActuatorType ; this . propertyChanged ( "TypeID" ) ; } if ( frame . ActuatorSubType !== this . _SubType ) { this . _SubType = frame . ActuatorSubType ; this . propertyChanged ( "SubType" ) ; } if ( frame . ProductType !== this . _ProductType ) { this . _ProductType = frame . ProductType ; this . propertyChanged ( "ProductType" ) ; } if ( frame . NodeVariation !== this . _nodeVariation ) { this . _nodeVariation = frame . NodeVariation ; this . propertyChanged ( "NodeVariation" ) ; } if ( frame . PowerSaveMode !== this . _PowerSaveMode ) { this . _PowerSaveMode = frame . PowerSaveMode ; this . propertyChanged ( "PowerSaveMode" ) ; } if ( ! frame . SerialNumber . equals ( this . _SerialNumber ) ) { this . _SerialNumber = frame . SerialNumber ; this . propertyChanged ( "SerialNumber" ) ; } if ( frame . OperatingState !== this . _state ) { this . _state = frame . OperatingState ; this . propertyChanged ( "State" ) ; } if ( frame . CurrentPosition !== this . _currentPositionRaw ) { this . _currentPositionRaw = frame . CurrentPosition ; this . propertyChanged ( "CurrentPositionRaw" ) ; this . propertyChanged ( "CurrentPosition" ) ; } if ( frame . TargetPosition !== this . _targetPositionRaw ) { this . _targetPositionRaw = frame . TargetPosition ; this . propertyChanged ( "TargetPositionRaw" ) ; this . propertyChanged ( "TargetPosition" ) ; } if ( frame . FunctionalPosition1CurrentPosition !== this . _fp1CurrentPositionRaw ) { this . _fp1CurrentPositionRaw = frame . FunctionalPosition1CurrentPosition ; this . propertyChanged ( "FP1CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition2CurrentPosition !== this . _fp2CurrentPositionRaw ) { this . _fp2CurrentPositionRaw = frame . FunctionalPosition2CurrentPosition ; this . propertyChanged ( "FP2CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition3CurrentPosition !== this . _fp3CurrentPositionRaw ) { this . _fp3CurrentPositionRaw = frame . FunctionalPosition3CurrentPosition ; this . propertyChanged ( "FP3CurrentPositionRaw" ) ; } if ( frame . FunctionalPosition4CurrentPosition !== this . _fp4CurrentPositionRaw ) { this . _fp4CurrentPositionRaw = frame . FunctionalPosition4CurrentPosition ; this . propertyChanged ( "FP4CurrentPositionRaw" ) ; } if ( frame . RemainingTime !== this . _remainingTime ) { this . _remainingTime = frame . RemainingTime ; this . propertyChanged ( "RemainingTime" ) ; } if ( frame . TimeStamp . valueOf ( ) !== this . _timeStamp . valueOf ( ) ) { this . _timeStamp = frame . TimeStamp ; this . propertyChanged ( "TimeStamp" ) ; } if ( this . _ProductAlias . length !== frame . ActuatorAliases . length || this . _ProductAlias . some ( v1 => ! frame . ActuatorAliases . some ( v2 => v1 . AliasType === v2 . AliasType && v1 . AliasValue === v2 . AliasValue ) ) || frame . ActuatorAliases . some ( v1 => ! this . _ProductAlias . some ( v2 => v1 . AliasType === v2 . AliasType && v1 . AliasValue === v2 . AliasValue ) ) ) { this . _ProductAlias = frame . ActuatorAliases ; this . propertyChanged ( "ProductAlias" ) ; } } } } /**
 * Use the products object to retrieve a list of products known to your KLF interface.
 * Products are e.g. windows, roller shutters, awnings.
 *
 * To create an instance of the Products class use the
 * static method [Products.createProductsAsync] Products .
 *
 *  export class export class Products { private _onNewProduct = new TypedEvent < number > ( ) ; private _onRemovedProduct = new TypedEvent < number > ( ) ; type { Product [ ] } memberof public readonly Products : Product [ ] = [ ] ; param { IConnection } Connection memberof private constructor ( readonly Connection ) { } private async initializeProductsAsync ( ) { let dispose ; try { const onNotificationHandler = new Promise < void > ( ( resolve , reject ) => { try { dispose = this . Connection . on ( frame => { if ( frame instanceof GW_GET_ALL_NODES_INFORMATION_NTF ) { const newProduct = new Product ( this . Connection , frame ) ; this . Products [ frame . NodeID ] = newProduct ; } else if ( frame instanceof GW_GET_ALL_NODES_INFORMATION_FINISHED_NTF ) { if ( dispose ) { dispose . dispose ( ) ; } this . Connection . on ( frame => this . onNotificationHandler ( frame ) , [ GatewayCommand . GW_CS_SYSTEM_TABLE_UPDATE_NTF ] ) ; resolve ( ) ; } } , [ GatewayCommand . GW_GET_ALL_NODES_INFORMATION_NTF , GatewayCommand . GW_GET_ALL_NODES_INFORMATION_FINISHED_NTF ] ) ; } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } reject ( error ) ; } } ) ; const getAllNodesInformation = < GW_GET_ALL_NODES_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_ALL_NODES_INFORMATION_REQ ( ) ) ; if ( getAllNodesInformation . Status !== GW_COMMON_STATUS . SUCCESS ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( new Error ( getAllNodesInformation . getError ( ) ) ) ; } if ( getAllNodesInformation . NumberOfNode > 0 ) { await onNotificationHandler ; for ( const product of this . Products ) { if ( product ) { await product . refreshLimitationAsync ( LimitationType . MinimumLimitation ) ; await product . refreshLimitationAsync ( LimitationType . MaximumLimitation ) ; } } } else { if ( dispose ) { dispose . dispose ( ) ; } } } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( error ) ; } } param { Listener < number > } handler returns { Disposable } memberof public onNewProduct ( handler ) { return this . _onNewProduct . on ( handler ) ; } param { Listener < number > } handler returns { Disposable } memberof public onRemovedProduct ( handler ) { return this . _onRemovedProduct . on ( handler ) ; } private notifyNewProduct ( nodeId ) { this . _onNewProduct . emit ( nodeId ) ; } private notifiyRemovedProduct ( nodeId ) { this . _onRemovedProduct . emit ( nodeId ) ; } private onNotificationHandler ( frame ) { if ( frame instanceof GW_CS_SYSTEM_TABLE_UPDATE_NTF ) { for ( const nodeID of frame . RemovedNodes ) { delete this . Products [ nodeID ] ; this . notifiyRemovedProduct ( nodeID ) ; } ( async ( ) => { for ( const nodeID of frame . AddedNodes ) { this . Products [ nodeID ] = await this . addNodeAsync ( nodeID ) ; this . notifyNewProduct ( nodeID ) ; } } ) ( ) . catch ( ( ) => { } ) ; } } private async addNodeAsync ( nodeID ) { let dispose ; try { const notificationHandler = new Promise < Product > ( ( resolve , reject ) => { try { dispose = this . Connection . on ( frame => { if ( dispose ) { dispose . dispose ( ) ; } resolve ( new Product ( this . Connection , frame as GW_GET_NODE_INFORMATION_NTF ) ) ; } , [ GatewayCommand . GW_GET_NODE_INFORMATION_NTF ] ) ; } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } reject ( error ) ; } } ) ; const getNodeInformation = < GW_GET_NODE_INFORMATION_CFM > await this . Connection . sendFrameAsync ( new GW_GET_NODE_INFORMATION_REQ ( nodeID ) ) ; if ( getNodeInformation . Status !== GW_COMMON_STATUS . SUCCESS ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( new Error ( getNodeInformation . getError ( ) ) ) ; } return notificationHandler ; } catch ( error ) { if ( dispose ) { dispose . dispose ( ) ; } return Promise . reject ( error ) ; } } static param { IConnection } Connection returns { Promise < Products > } memberof static async createProductsAsync ( Connection ) { try { const result = new Products ( Connection ) ; await result . initializeProductsAsync ( ) ; return result ; } catch ( error ) { return Promise . reject ( error ) ; } } param { string } productName returns { ( Product | undefined ) } memberof public findByName ( productName ) { return this . Products . find ( pr => typeof pr !== "undefined" && pr . Name === productName ) ; } }