@ -33,9 +33,9 @@ import {
TsValue
} from '@shared/models/query/query.models' ;
import { PageData } from '@shared/models/page/page-data' ;
import { alarmFields } from '@shared/models/alarm.models' ;
import { alarmFields , AlarmSeverity } from '@shared/models/alarm.models' ;
import { entityFields } from '@shared/models/entity.models' ;
import { isDefinedAndNotNull , isUndefined } from '@core/utils' ;
import { deepClone , isDefinedAndNotNull , isUndefined } from '@core/utils' ;
import { CmdWrapper , WsService , WsSubscriber } from '@shared/models/websocket/websocket.models' ;
import { TelemetryWebsocketService } from '@core/ws/telemetry-websocket.service' ;
import { Notification , NotificationType } from '@shared/models/notification.models' ;
@ -141,6 +141,7 @@ export enum WsCmdType {
ENTITY_COUNT = 'ENTITY_COUNT' ,
ALARM_DATA = 'ALARM_DATA' ,
ALARM_COUNT = 'ALARM_COUNT' ,
ALARM_STATUS = 'ALARM_STATUS' ,
NOTIFICATIONS = 'NOTIFICATIONS' ,
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT' ,
@ -149,6 +150,7 @@ export enum WsCmdType {
ALARM_DATA_UNSUBSCRIBE = 'ALARM_DATA_UNSUBSCRIBE' ,
ALARM_COUNT_UNSUBSCRIBE = 'ALARM_COUNT_UNSUBSCRIBE' ,
ALARM_STATUS_UNSUBSCRIBE = 'ALARM_STATUS_UNSUBSCRIBE' ,
ENTITY_DATA_UNSUBSCRIBE = 'ENTITY_DATA_UNSUBSCRIBE' ,
ENTITY_COUNT_UNSUBSCRIBE = 'ENTITY_COUNT_UNSUBSCRIBE' ,
NOTIFICATIONS_UNSUBSCRIBE = 'NOTIFICATIONS_UNSUBSCRIBE'
@ -298,6 +300,14 @@ export class AlarmCountCmd implements WebsocketCmd {
type = WsCmdType . ALARM_COUNT ;
}
export class AlarmStatusCmd implements WebsocketCmd {
cmdId : number ;
originatorId : EntityId ;
severityList? : Array < AlarmSeverity > ;
typeList? : Array < string > ;
type = WsCmdType . ALARM_STATUS ;
}
export class UnreadCountSubCmd implements WebsocketCmd {
cmdId : number ;
type = WsCmdType . NOTIFICATIONS_COUNT ;
@ -352,6 +362,11 @@ export class AlarmCountUnsubscribeCmd implements WebsocketCmd {
type = WsCmdType . ALARM_COUNT_UNSUBSCRIBE ;
}
export class AlarmStatusUnsubscribeCmd implements WebsocketCmd {
cmdId : number ;
type = WsCmdType . ALARM_STATUS_UNSUBSCRIBE ;
}
export class UnsubscribeCmd implements WebsocketCmd {
cmdId : number ;
type = WsCmdType . NOTIFICATIONS_UNSUBSCRIBE ;
@ -432,6 +447,7 @@ export enum CmdUpdateType {
ENTITY_DATA = 'ENTITY_DATA' ,
ALARM_DATA = 'ALARM_DATA' ,
ALARM_COUNT_DATA = 'ALARM_COUNT_DATA' ,
ALARM_STATUS = 'ALARM_STATUS' ,
COUNT_DATA = 'COUNT_DATA' ,
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT' ,
NOTIFICATIONS = 'NOTIFICATIONS'
@ -469,6 +485,11 @@ export interface AlarmCountUpdateMsg extends CmdUpdateMsg {
count : number ;
}
export interface AlarmStatusUpdateMsg extends CmdUpdateMsg {
cmdUpdateType : CmdUpdateType.ALARM_STATUS ;
active : boolean ;
}
export interface NotificationCountUpdateMsg extends CmdUpdateMsg {
cmdUpdateType : CmdUpdateType.NOTIFICATIONS_COUNT ;
totalUnreadCount : number ;
@ -506,6 +527,11 @@ export const isAlarmCountUpdateMsg = (message: WebsocketDataMsg): message is Ala
return updateMsg . cmdId !== undefined && updateMsg . cmdUpdateType === CmdUpdateType . ALARM_COUNT_DATA ;
} ;
export const isAlarmStatusUpdateMsg = ( message : WebsocketDataMsg ) : message is AlarmCountUpdateMsg = > {
const updateMsg = ( message as CmdUpdateMsg ) ;
return updateMsg . cmdId !== undefined && updateMsg . cmdUpdateType === CmdUpdateType . ALARM_STATUS ;
} ;
export const isNotificationCountUpdateMsg = ( message : WebsocketDataMsg ) : message is NotificationCountUpdateMsg = > {
const updateMsg = ( message as CmdUpdateMsg ) ;
return updateMsg . cmdId !== undefined && updateMsg . cmdUpdateType === CmdUpdateType . NOTIFICATIONS_COUNT ;
@ -705,6 +731,15 @@ export class AlarmCountUpdate extends CmdUpdate {
}
}
export class AlarmStatusUpdate extends CmdUpdate {
active : boolean ;
constructor ( msg : AlarmStatusUpdateMsg ) {
super ( msg ) ;
this . active = msg . active ;
}
}
export class NotificationCountUpdate extends CmdUpdate {
totalUnreadCount : number ;
sequenceNumber : number ;
@ -750,14 +785,29 @@ export class SharedTelemetrySubscriber {
return key ;
}
private static createAlarmStatusSubscriberKey ( entityId : EntityId , severityList : AlarmSeverity [ ] = null , typeList : string [ ] = null ) : string {
let key = entityId . entityType + '_' + entityId . id ;
if ( severityList ) {
key += '_' + severityList . sort ( ) . join ( '_' ) ;
}
if ( typeList ) {
key += '_' + typeList . sort ( ) . join ( '_' ) ;
}
return key ;
}
private subscribed = false ;
private attributeDataSubject = connectable ( this . sharedSubscriptionInfo . subscriber . attributeData $ ( ) ,
{ connector : ( ) = > new ReplaySubject < Array < AttributeData > > ( 1 ) } ) ;
private alarmStatusSubject = connectable ( this . sharedSubscriptionInfo . subscriber . alarmStatus $ ,
{ connector : ( ) = > new ReplaySubject < AlarmStatusUpdate > ( ) } ) ;
private subscriptions = new Array < Subscription > ( ) ;
public attributeData$ : Observable < Array < AttributeData > > = this . attributeDataSubject ; //this.attributeDataSubject.asObservable();
public alarmStatus$ : Observable < AlarmStatusUpdate > = this . alarmStatusSubject ;
public static createEntityAttributesSubscription ( telemetryService : TelemetryWebsocketService ,
entityId : EntityId , attributeScope : TelemetryType ,
@ -781,6 +831,28 @@ export class SharedTelemetrySubscriber {
return sharedSubscriber ;
}
public static createAlarmStatusSubscription ( telemetryService : TelemetryWebsocketService ,
entityId : EntityId , zone : NgZone , severityList : AlarmSeverity [ ] = null ,
typeList : string [ ] = null ) : SharedTelemetrySubscriber {
const key = SharedTelemetrySubscriber . createAlarmStatusSubscriberKey ( entityId , severityList , typeList ) ;
let info = SharedTelemetrySubscriber . subscribersCache [ key ] ;
if ( ! info ) {
const subscriber = TelemetrySubscriber . createAlarmStatusSubscription (
telemetryService , entityId , zone , severityList , typeList
) ;
info = {
key ,
subscriber ,
subscribed : false ,
sharedSubscribers : new Set < SharedTelemetrySubscriber > ( )
} ;
SharedTelemetrySubscriber . subscribersCache [ key ] = info ;
}
const sharedSubscriber = new SharedTelemetrySubscriber ( info ) ;
info . sharedSubscribers . add ( sharedSubscriber ) ;
return sharedSubscriber ;
}
private constructor ( private sharedSubscriptionInfo : SharedSubscriptionInfo ) {
}
@ -788,6 +860,7 @@ export class SharedTelemetrySubscriber {
if ( ! this . subscribed ) {
this . subscribed = true ;
this . subscriptions . push ( this . attributeDataSubject . connect ( ) ) ;
this . subscriptions . push ( this . alarmStatusSubject . connect ( ) ) ;
if ( ! this . sharedSubscriptionInfo . subscribed ) {
this . sharedSubscriptionInfo . subscriber . subscribe ( ) ;
this . sharedSubscriptionInfo . subscribed = true ;
@ -823,6 +896,7 @@ export class TelemetrySubscriber extends WsSubscriber {
private alarmDataSubject = new ReplaySubject < AlarmDataUpdate > ( 1 ) ;
private entityCountSubject = new ReplaySubject < EntityCountUpdate > ( 1 ) ;
private alarmCountSubject = new ReplaySubject < AlarmCountUpdate > ( 1 ) ;
private alarmStatusSubject = new ReplaySubject < AlarmStatusUpdate > ( 1 ) ;
private tsOffset = undefined ;
public data $ = this . dataSubject . asObservable ( ) ;
@ -830,6 +904,7 @@ export class TelemetrySubscriber extends WsSubscriber {
public alarmData $ = this . alarmDataSubject . asObservable ( ) ;
public entityCount $ = this . entityCountSubject . asObservable ( ) ;
public alarmCount $ = this . alarmCountSubject . asObservable ( ) ;
public alarmStatus $ = this . alarmStatusSubject . asObservable ( ) ;
public static createEntityAttributesSubscription ( telemetryService : TelemetryWebsocketService ,
entityId : EntityId , attributeScope : TelemetryType ,
@ -851,6 +926,17 @@ export class TelemetrySubscriber extends WsSubscriber {
return subscriber ;
}
public static createAlarmStatusSubscription ( telemetryService : TelemetryWebsocketService , entityId : EntityId ,
zone : NgZone , severityList : AlarmSeverity [ ] = null , typeList : string [ ] = null ) : TelemetrySubscriber {
const subscriptionCommand = new AlarmStatusCmd ( ) ;
subscriptionCommand . originatorId = deepClone ( entityId ) ;
subscriptionCommand . severityList = severityList ;
subscriptionCommand . typeList = typeList ;
const subscriber = new TelemetrySubscriber ( telemetryService , zone ) ;
subscriber . subscriptionCommands . push ( subscriptionCommand ) ;
return subscriber ;
}
public static createEntityFilterLatestSubscription ( telemetryService : TelemetryWebsocketService ,
entityFilter : EntityFilter , zone : NgZone ,
latestKeys : EntityKey [ ] = null ) : TelemetrySubscriber {
@ -882,6 +968,7 @@ export class TelemetrySubscriber extends WsSubscriber {
this . alarmDataSubject . complete ( ) ;
this . entityCountSubject . complete ( ) ;
this . alarmCountSubject . complete ( ) ;
this . alarmStatusSubject . complete ( ) ;
super . complete ( ) ;
}
@ -971,6 +1058,18 @@ export class TelemetrySubscriber extends WsSubscriber {
}
}
public onAlarmStatus ( message : AlarmStatusUpdate ) {
if ( this . zone ) {
this . zone . run (
( ) = > {
this . alarmStatusSubject . next ( message ) ;
}
) ;
} else {
this . alarmStatusSubject . next ( message ) ;
}
}
public attributeData $ ( ) : Observable < Array < AttributeData > > {
const attributeData = new Array < AttributeData > ( ) ;
return this . data $ . pipe (