Merge pull request #12093 from dashevchenko/alarmStatusCmdFix
Add new behavior "get alarm status"
This commit is contained in:
commit
eae6909be8
@ -15,21 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.subscription;
|
package org.thingsboard.server.service.subscription;
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
||||||
import org.thingsboard.server.common.data.query.AlarmCountQuery;
|
|
||||||
import org.thingsboard.server.common.data.query.OriginatorAlarmFilter;
|
import org.thingsboard.server.common.data.query.OriginatorAlarmFilter;
|
||||||
import org.thingsboard.server.dao.alarm.AlarmService;
|
import org.thingsboard.server.dao.alarm.AlarmService;
|
||||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
|
||||||
import org.thingsboard.server.dao.entity.EntityService;
|
|
||||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||||
import org.thingsboard.server.service.ws.WebSocketService;
|
import org.thingsboard.server.service.ws.WebSocketService;
|
||||||
import org.thingsboard.server.service.ws.WebSocketSessionRef;
|
import org.thingsboard.server.service.ws.WebSocketSessionRef;
|
||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmCountUpdate;
|
|
||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmStatusCmd;
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmStatusCmd;
|
||||||
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmStatusUpdate;
|
||||||
import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate;
|
import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -82,7 +77,10 @@ public class TbAlarmStatusSubCtx extends TbAbstractSubCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendUpdate() {
|
public void sendUpdate() {
|
||||||
sendWsMsg(subscription.createUpdate());
|
sendWsMsg(AlarmStatusUpdate.builder()
|
||||||
|
.cmdId(cmdId)
|
||||||
|
.active(subscription.hasAlarms())
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchActiveAlarms() {
|
public void fetchActiveAlarms() {
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
|
|||||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmStatusUpdate;
|
|
||||||
import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate;
|
import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -53,15 +52,12 @@ public class TbAlarmStatusSubscription extends TbSubscription<AlarmSubscriptionU
|
|||||||
this.severityList = severityList;
|
this.severityList = severityList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlarmStatusUpdate createUpdate() {
|
|
||||||
return AlarmStatusUpdate.builder()
|
|
||||||
.cmdId(getSubscriptionId())
|
|
||||||
.active(!alarmIds.isEmpty())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matches(AlarmInfo alarm) {
|
public boolean matches(AlarmInfo alarm) {
|
||||||
return !alarm.isCleared() && (this.typeList == null || this.typeList.contains(alarm.getType())) &&
|
return !alarm.isCleared() && (this.typeList == null || this.typeList.contains(alarm.getType())) &&
|
||||||
(this.severityList == null || this.severityList.contains(alarm.getSeverity()));
|
(this.severityList == null || this.severityList.contains(alarm.getSeverity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasAlarms() {
|
||||||
|
return !alarmIds.isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityCountCmd;
|
|||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityCountUnsubscribeCmd;
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityCountUnsubscribeCmd;
|
||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataCmd;
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataCmd;
|
||||||
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataUnsubscribeCmd;
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataUnsubscribeCmd;
|
||||||
|
import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmStatusUnsubscribeCmd;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ public class WsCommandsWrapper {
|
|||||||
@Type(name = "ENTITY_DATA_UNSUBSCRIBE", value = EntityDataUnsubscribeCmd.class),
|
@Type(name = "ENTITY_DATA_UNSUBSCRIBE", value = EntityDataUnsubscribeCmd.class),
|
||||||
@Type(name = "ENTITY_COUNT_UNSUBSCRIBE", value = EntityCountUnsubscribeCmd.class),
|
@Type(name = "ENTITY_COUNT_UNSUBSCRIBE", value = EntityCountUnsubscribeCmd.class),
|
||||||
@Type(name = "NOTIFICATIONS_UNSUBSCRIBE", value = NotificationsUnsubCmd.class),
|
@Type(name = "NOTIFICATIONS_UNSUBSCRIBE", value = NotificationsUnsubCmd.class),
|
||||||
|
@Type(name = "ALARM_STATUS_UNSUBSCRIBE", value = AlarmStatusUnsubscribeCmd.class),
|
||||||
})
|
})
|
||||||
private List<WsCmd> cmds;
|
private List<WsCmd> cmds;
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,9 @@ import {
|
|||||||
AlarmDataCmd,
|
AlarmDataCmd,
|
||||||
AlarmDataUnsubscribeCmd,
|
AlarmDataUnsubscribeCmd,
|
||||||
AlarmDataUpdate,
|
AlarmDataUpdate,
|
||||||
|
AlarmStatusCmd,
|
||||||
|
AlarmStatusUnsubscribeCmd,
|
||||||
|
AlarmStatusUpdate,
|
||||||
EntityCountCmd,
|
EntityCountCmd,
|
||||||
EntityCountUnsubscribeCmd,
|
EntityCountUnsubscribeCmd,
|
||||||
EntityCountUpdate,
|
EntityCountUpdate,
|
||||||
@ -30,6 +33,7 @@ import {
|
|||||||
EntityDataUpdate,
|
EntityDataUpdate,
|
||||||
isAlarmCountUpdateMsg,
|
isAlarmCountUpdateMsg,
|
||||||
isAlarmDataUpdateMsg,
|
isAlarmDataUpdateMsg,
|
||||||
|
isAlarmStatusUpdateMsg,
|
||||||
isEntityCountUpdateMsg,
|
isEntityCountUpdateMsg,
|
||||||
isEntityDataUpdateMsg,
|
isEntityDataUpdateMsg,
|
||||||
isNotificationCountUpdateMsg,
|
isNotificationCountUpdateMsg,
|
||||||
@ -121,6 +125,10 @@ export class TelemetryWebsocketService extends WebsocketService<TelemetrySubscri
|
|||||||
const alarmCountUnsubscribeCmd = new AlarmCountUnsubscribeCmd();
|
const alarmCountUnsubscribeCmd = new AlarmCountUnsubscribeCmd();
|
||||||
alarmCountUnsubscribeCmd.cmdId = subscriptionCommand.cmdId;
|
alarmCountUnsubscribeCmd.cmdId = subscriptionCommand.cmdId;
|
||||||
this.cmdWrapper.cmds.push(alarmCountUnsubscribeCmd);
|
this.cmdWrapper.cmds.push(alarmCountUnsubscribeCmd);
|
||||||
|
} else if (subscriptionCommand instanceof AlarmStatusCmd) {
|
||||||
|
const alarmCountUnsubscribeCmd = new AlarmStatusUnsubscribeCmd();
|
||||||
|
alarmCountUnsubscribeCmd.cmdId = subscriptionCommand.cmdId;
|
||||||
|
this.cmdWrapper.cmds.push(alarmCountUnsubscribeCmd);
|
||||||
} else if (subscriptionCommand instanceof UnreadCountSubCmd || subscriptionCommand instanceof UnreadSubCmd) {
|
} else if (subscriptionCommand instanceof UnreadCountSubCmd || subscriptionCommand instanceof UnreadSubCmd) {
|
||||||
const notificationsUnsubCmds = new UnsubscribeCmd();
|
const notificationsUnsubCmds = new UnsubscribeCmd();
|
||||||
notificationsUnsubCmds.cmdId = subscriptionCommand.cmdId;
|
notificationsUnsubCmds.cmdId = subscriptionCommand.cmdId;
|
||||||
@ -157,6 +165,8 @@ export class TelemetryWebsocketService extends WebsocketService<TelemetrySubscri
|
|||||||
subscriber.onEntityCount(new EntityCountUpdate(message));
|
subscriber.onEntityCount(new EntityCountUpdate(message));
|
||||||
} else if (isAlarmCountUpdateMsg(message)) {
|
} else if (isAlarmCountUpdateMsg(message)) {
|
||||||
subscriber.onAlarmCount(new AlarmCountUpdate(message));
|
subscriber.onAlarmCount(new AlarmCountUpdate(message));
|
||||||
|
} else if (isAlarmStatusUpdateMsg(message)) {
|
||||||
|
subscriber.onAlarmStatus(new AlarmStatusUpdate(message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('subscriptionId' in message && message.subscriptionId) {
|
} else if ('subscriptionId' in message && message.subscriptionId) {
|
||||||
|
|||||||
@ -242,6 +242,8 @@ export abstract class ValueGetter<V> extends ValueAction {
|
|||||||
return new AttributeValueGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
return new AttributeValueGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
||||||
case GetValueAction.GET_TIME_SERIES:
|
case GetValueAction.GET_TIME_SERIES:
|
||||||
return new TimeSeriesValueGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
return new TimeSeriesValueGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
||||||
|
case GetValueAction.GET_ALARM_STATUS:
|
||||||
|
return new AlarmStatusValueGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
||||||
case GetValueAction.GET_DASHBOARD_STATE:
|
case GetValueAction.GET_DASHBOARD_STATE:
|
||||||
return new DashboardStateGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
return new DashboardStateGetter<V>(ctx, settings, valueType, valueObserver, simulated);
|
||||||
}
|
}
|
||||||
@ -257,7 +259,7 @@ export abstract class ValueGetter<V> extends ValueAction {
|
|||||||
protected valueObserver: Partial<Observer<V>>,
|
protected valueObserver: Partial<Observer<V>>,
|
||||||
protected simulated: boolean) {
|
protected simulated: boolean) {
|
||||||
super(ctx, settings);
|
super(ctx, settings);
|
||||||
if (this.settings.action !== GetValueAction.DO_NOTHING) {
|
if (this.settings.action !== GetValueAction.DO_NOTHING && this.settings.action !== GetValueAction.GET_ALARM_STATUS) {
|
||||||
this.dataConverter = new DataToValueConverter<V>(settings.dataToValue, valueType);
|
this.dataConverter = new DataToValueConverter<V>(settings.dataToValue, valueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,6 +539,58 @@ export class TimeSeriesValueGetter<V> extends TelemetryValueGetter<V, TelemetryV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class AlarmStatusValueGetter<V> extends ValueGetter<V> {
|
||||||
|
|
||||||
|
protected targetEntityId: EntityId;
|
||||||
|
private telemetrySubscriber: SharedTelemetrySubscriber;
|
||||||
|
|
||||||
|
constructor(protected ctx: WidgetContext,
|
||||||
|
protected settings: GetValueSettings<V>,
|
||||||
|
protected valueType: ValueType,
|
||||||
|
protected valueObserver: Partial<Observer<V>>,
|
||||||
|
protected simulated: boolean) {
|
||||||
|
super(ctx, settings, valueType, valueObserver, simulated);
|
||||||
|
const entityInfo = this.ctx.defaultSubscription.getFirstEntityInfo();
|
||||||
|
this.targetEntityId = entityInfo?.entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected doGetValue(): Observable<boolean> {
|
||||||
|
if (this.simulated) {
|
||||||
|
return of(false).pipe(delay(100));
|
||||||
|
} else {
|
||||||
|
if (!this.targetEntityId && !this.ctx.defaultSubscription.rpcEnabled) {
|
||||||
|
return throwError(() => new Error(this.ctx.translate.instant('widgets.value-action.error.target-entity-is-not-set')));
|
||||||
|
}
|
||||||
|
if (this.targetEntityId) {
|
||||||
|
return this.subscribeForTelemetryValue();
|
||||||
|
} else {
|
||||||
|
return of(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private subscribeForTelemetryValue(): Observable<boolean> {
|
||||||
|
this.telemetrySubscriber =
|
||||||
|
SharedTelemetrySubscriber.createAlarmStatusSubscription(this.ctx.telemetryWsService, this.targetEntityId,
|
||||||
|
this.ctx.ngZone, this.settings.getAlarmStatus.severityList, this.settings.getAlarmStatus.typeList);
|
||||||
|
this.telemetrySubscriber.subscribe();
|
||||||
|
return this.telemetrySubscriber.alarmStatus$.pipe(
|
||||||
|
map((data) => {
|
||||||
|
return data.active;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
if (this.telemetrySubscriber) {
|
||||||
|
this.telemetrySubscriber.unsubscribe();
|
||||||
|
this.telemetrySubscriber = null;
|
||||||
|
}
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class DashboardStateGetter<V> extends ValueGetter<V> {
|
export class DashboardStateGetter<V> extends ValueGetter<V> {
|
||||||
constructor(protected ctx: WidgetContext,
|
constructor(protected ctx: WidgetContext,
|
||||||
protected settings: GetValueSettings<V>,
|
protected settings: GetValueSettings<V>,
|
||||||
|
|||||||
@ -38,6 +38,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -54,6 +58,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -62,6 +62,10 @@ export const commandButtonDefaultSettings: CommandButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -61,6 +61,10 @@ export const toggleButtonDefaultSettings: ToggleButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -77,6 +81,10 @@ export const toggleButtonDefaultSettings: ToggleButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -85,6 +85,10 @@ export const statusWidgetDefaultSettings: StatusWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -101,6 +105,10 @@ export const statusWidgetDefaultSettings: StatusWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -104,6 +104,10 @@ export const powerButtonDefaultSettings: PowerButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -120,6 +124,10 @@ export const powerButtonDefaultSettings: PowerButtonWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -100,6 +100,10 @@ export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -116,6 +120,10 @@ export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -101,6 +101,10 @@ export const sliderWidgetDefaultSettings: SliderWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
@ -117,6 +121,10 @@ export const sliderWidgetDefaultSettings: SliderWidgetSettings = {
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -415,6 +415,10 @@ export const defaultGetValueSettings = (valueType: ValueType): GetValueSettings<
|
|||||||
getTimeSeries: {
|
getTimeSeries: {
|
||||||
key: 'state'
|
key: 'state'
|
||||||
},
|
},
|
||||||
|
getAlarmStatus: {
|
||||||
|
severityList: null,
|
||||||
|
typeList: null
|
||||||
|
},
|
||||||
dataToValue: {
|
dataToValue: {
|
||||||
type: DataToValueType.NONE,
|
type: DataToValueType.NONE,
|
||||||
compareToValue: true,
|
compareToValue: true,
|
||||||
|
|||||||
@ -103,8 +103,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="getValueAction.GET_ALARM_STATUS">
|
||||||
|
<ng-container formGroupName="getAlarmStatus">
|
||||||
|
<div class="tb-form-row space-between column-xs">
|
||||||
|
<div class="fixed-title-width" translate>alarm.alarm-severity</div>
|
||||||
|
<mat-chip-listbox multiple formControlName="severityList">
|
||||||
|
<mat-chip-option *ngFor="let alarmSeverity of alarmSeverities" [value]="alarmSeverity">
|
||||||
|
{{ alarmSeverityTranslationMap.get(alarmSeverity) | translate }}
|
||||||
|
</mat-chip-option>
|
||||||
|
</mat-chip-listbox>
|
||||||
|
</div>
|
||||||
|
<div class="tb-form-row column-xs">
|
||||||
|
<div class="fixed-title-width" translate>alarm.alarm-types</div>
|
||||||
|
<tb-entity-subtype-list subscriptSizing="dynamic"
|
||||||
|
formControlName="typeList"
|
||||||
|
appearance="outline"
|
||||||
|
class="flex-1"
|
||||||
|
[additionalClasses]="['tb-chips', 'flex']"
|
||||||
|
[entityType]="entityType.ALARM">
|
||||||
|
</tb-entity-subtype-list>
|
||||||
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div *ngIf="getValueSettingsFormGroup.get('action').value !== getValueAction.DO_NOTHING"
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
<div *ngIf="getValueSettingsFormGroup.get('action').value !== getValueAction.DO_NOTHING &&
|
||||||
|
getValueSettingsFormGroup.get('action').value !== getValueAction.GET_ALARM_STATUS"
|
||||||
class="tb-form-panel stroked" formGroupName="dataToValue">
|
class="tb-form-panel stroked" formGroupName="dataToValue">
|
||||||
<div class="tb-form-row no-padding no-border column-xs">
|
<div class="tb-form-row no-padding no-border column-xs">
|
||||||
<div class="fixed-title-width" translate>widgets.value-action.action-result-converter</div>
|
<div class="fixed-title-width" translate>widgets.value-action.action-result-converter</div>
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import { TargetDevice, widgetType } from '@shared/models/widget.models';
|
|||||||
import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models';
|
import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models';
|
||||||
import { IAliasController } from '@core/api/widget-api.models';
|
import { IAliasController } from '@core/api/widget-api.models';
|
||||||
import { WidgetService } from '@core/http/widget.service';
|
import { WidgetService } from '@core/http/widget.service';
|
||||||
|
import { AlarmSeverity, alarmSeverityTranslations } from '@shared/models/alarm.models';
|
||||||
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-get-value-action-settings-panel',
|
selector: 'tb-get-value-action-settings-panel',
|
||||||
@ -96,6 +98,9 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
|
|||||||
|
|
||||||
getValueSettingsFormGroup: UntypedFormGroup;
|
getValueSettingsFormGroup: UntypedFormGroup;
|
||||||
|
|
||||||
|
alarmSeverities = Object.keys(AlarmSeverity) as AlarmSeverity[];
|
||||||
|
alarmSeverityTranslationMap = alarmSeverityTranslations;
|
||||||
|
|
||||||
constructor(private fb: UntypedFormBuilder,
|
constructor(private fb: UntypedFormBuilder,
|
||||||
private widgetService: WidgetService,
|
private widgetService: WidgetService,
|
||||||
protected store: Store<AppState>) {
|
protected store: Store<AppState>) {
|
||||||
@ -122,6 +127,10 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
|
|||||||
getTimeSeries: this.fb.group({
|
getTimeSeries: this.fb.group({
|
||||||
key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]]
|
key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]]
|
||||||
}),
|
}),
|
||||||
|
getAlarmStatus: this.fb.group({
|
||||||
|
severityList: [this.getValueSettings?.getAlarmStatus?.severityList],
|
||||||
|
typeList: [this.getValueSettings?.getAlarmStatus?.typeList]
|
||||||
|
}),
|
||||||
dataToValue: this.fb.group({
|
dataToValue: this.fb.group({
|
||||||
type: [this.getValueSettings?.dataToValue?.type, [Validators.required]],
|
type: [this.getValueSettings?.dataToValue?.type, [Validators.required]],
|
||||||
dataToValueFunction: [this.getValueSettings?.dataToValue?.dataToValueFunction, [Validators.required]],
|
dataToValueFunction: [this.getValueSettings?.dataToValue?.dataToValueFunction, [Validators.required]],
|
||||||
@ -159,6 +168,7 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
|
|||||||
this.getValueSettingsFormGroup.get('executeRpc').disable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('executeRpc').disable({emitEvent: false});
|
||||||
this.getValueSettingsFormGroup.get('getAttribute').disable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('getAttribute').disable({emitEvent: false});
|
||||||
this.getValueSettingsFormGroup.get('getTimeSeries').disable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('getTimeSeries').disable({emitEvent: false});
|
||||||
|
this.getValueSettingsFormGroup.get('getAlarmStatus').disable({emitEvent: false});
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case GetValueAction.DO_NOTHING:
|
case GetValueAction.DO_NOTHING:
|
||||||
this.getValueSettingsFormGroup.get('defaultValue').enable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('defaultValue').enable({emitEvent: false});
|
||||||
@ -178,8 +188,11 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
|
|||||||
case GetValueAction.GET_TIME_SERIES:
|
case GetValueAction.GET_TIME_SERIES:
|
||||||
this.getValueSettingsFormGroup.get('getTimeSeries').enable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('getTimeSeries').enable({emitEvent: false});
|
||||||
break;
|
break;
|
||||||
|
case GetValueAction.GET_ALARM_STATUS:
|
||||||
|
this.getValueSettingsFormGroup.get('getAlarmStatus').enable({emitEvent: false});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (action === GetValueAction.DO_NOTHING) {
|
if (action === GetValueAction.DO_NOTHING || action === GetValueAction.GET_ALARM_STATUS) {
|
||||||
this.getValueSettingsFormGroup.get('dataToValue').disable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('dataToValue').disable({emitEvent: false});
|
||||||
} else {
|
} else {
|
||||||
this.getValueSettingsFormGroup.get('dataToValue').enable({emitEvent: false});
|
this.getValueSettingsFormGroup.get('dataToValue').enable({emitEvent: false});
|
||||||
@ -190,4 +203,6 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly entityType = EntityType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -176,6 +176,9 @@ export class GetValueActionSettingsComponent implements OnInit, ControlValueAcce
|
|||||||
case GetValueAction.GET_TIME_SERIES:
|
case GetValueAction.GET_TIME_SERIES:
|
||||||
this.displayValue = this.translate.instant('widgets.value-action.get-time-series-text', {key: this.modelValue.getTimeSeries.key});
|
this.displayValue = this.translate.instant('widgets.value-action.get-time-series-text', {key: this.modelValue.getTimeSeries.key});
|
||||||
break;
|
break;
|
||||||
|
case GetValueAction.GET_ALARM_STATUS:
|
||||||
|
this.displayValue = this.translate.instant('widgets.value-action.get-alarm-status-text');
|
||||||
|
break;
|
||||||
case GetValueAction.GET_DASHBOARD_STATE:
|
case GetValueAction.GET_DASHBOARD_STATE:
|
||||||
if (this.valueType === ValueType.BOOLEAN) {
|
if (this.valueType === ValueType.BOOLEAN) {
|
||||||
const state = this.modelValue.dataToValue?.compareToValue;
|
const state = this.modelValue.dataToValue?.compareToValue;
|
||||||
|
|||||||
@ -16,12 +16,14 @@
|
|||||||
|
|
||||||
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||||
import { widgetType } from '@shared/models/widget.models';
|
import { widgetType } from '@shared/models/widget.models';
|
||||||
|
import { AlarmSeverity } from '@shared/models/alarm.models';
|
||||||
|
|
||||||
export enum GetValueAction {
|
export enum GetValueAction {
|
||||||
DO_NOTHING = 'DO_NOTHING',
|
DO_NOTHING = 'DO_NOTHING',
|
||||||
EXECUTE_RPC = 'EXECUTE_RPC',
|
EXECUTE_RPC = 'EXECUTE_RPC',
|
||||||
GET_ATTRIBUTE = 'GET_ATTRIBUTE',
|
GET_ATTRIBUTE = 'GET_ATTRIBUTE',
|
||||||
GET_TIME_SERIES = 'GET_TIME_SERIES',
|
GET_TIME_SERIES = 'GET_TIME_SERIES',
|
||||||
|
GET_ALARM_STATUS = 'GET_ALARM_STATUS',
|
||||||
GET_DASHBOARD_STATE = 'GET_DASHBOARD_STATE'
|
GET_DASHBOARD_STATE = 'GET_DASHBOARD_STATE'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ export const getValueActionTranslations = new Map<GetValueAction, string>(
|
|||||||
[GetValueAction.EXECUTE_RPC, 'widgets.value-action.execute-rpc'],
|
[GetValueAction.EXECUTE_RPC, 'widgets.value-action.execute-rpc'],
|
||||||
[GetValueAction.GET_ATTRIBUTE, 'widgets.value-action.get-attribute'],
|
[GetValueAction.GET_ATTRIBUTE, 'widgets.value-action.get-attribute'],
|
||||||
[GetValueAction.GET_TIME_SERIES, 'widgets.value-action.get-time-series'],
|
[GetValueAction.GET_TIME_SERIES, 'widgets.value-action.get-time-series'],
|
||||||
|
[GetValueAction.GET_ALARM_STATUS, 'widgets.value-action.get-alarm-status'],
|
||||||
[GetValueAction.GET_DASHBOARD_STATE, 'widgets.value-action.get-dashboard-state']
|
[GetValueAction.GET_DASHBOARD_STATE, 'widgets.value-action.get-dashboard-state']
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -52,6 +55,11 @@ export interface RpcSettings {
|
|||||||
persistentPollingInterval: number;
|
persistentPollingInterval: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AlarmStatusSettings {
|
||||||
|
severityList: Array<AlarmSeverity>;
|
||||||
|
typeList: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TelemetryValueSettings {
|
export interface TelemetryValueSettings {
|
||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
@ -85,6 +93,7 @@ export interface GetValueSettings<V> extends ValueActionSettings {
|
|||||||
executeRpc?: RpcSettings;
|
executeRpc?: RpcSettings;
|
||||||
getAttribute: GetAttributeValueSettings;
|
getAttribute: GetAttributeValueSettings;
|
||||||
getTimeSeries: TelemetryValueSettings;
|
getTimeSeries: TelemetryValueSettings;
|
||||||
|
getAlarmStatus: AlarmStatusSettings;
|
||||||
dataToValue: DataToValueSettings;
|
dataToValue: DataToValueSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,9 +33,9 @@ import {
|
|||||||
TsValue
|
TsValue
|
||||||
} from '@shared/models/query/query.models';
|
} from '@shared/models/query/query.models';
|
||||||
import { PageData } from '@shared/models/page/page-data';
|
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 { 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 { CmdWrapper, WsService, WsSubscriber } from '@shared/models/websocket/websocket.models';
|
||||||
import { TelemetryWebsocketService } from '@core/ws/telemetry-websocket.service';
|
import { TelemetryWebsocketService } from '@core/ws/telemetry-websocket.service';
|
||||||
import { Notification, NotificationType } from '@shared/models/notification.models';
|
import { Notification, NotificationType } from '@shared/models/notification.models';
|
||||||
@ -141,6 +141,7 @@ export enum WsCmdType {
|
|||||||
ENTITY_COUNT = 'ENTITY_COUNT',
|
ENTITY_COUNT = 'ENTITY_COUNT',
|
||||||
ALARM_DATA = 'ALARM_DATA',
|
ALARM_DATA = 'ALARM_DATA',
|
||||||
ALARM_COUNT = 'ALARM_COUNT',
|
ALARM_COUNT = 'ALARM_COUNT',
|
||||||
|
ALARM_STATUS = 'ALARM_STATUS',
|
||||||
|
|
||||||
NOTIFICATIONS = 'NOTIFICATIONS',
|
NOTIFICATIONS = 'NOTIFICATIONS',
|
||||||
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT',
|
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT',
|
||||||
@ -149,6 +150,7 @@ export enum WsCmdType {
|
|||||||
|
|
||||||
ALARM_DATA_UNSUBSCRIBE = 'ALARM_DATA_UNSUBSCRIBE',
|
ALARM_DATA_UNSUBSCRIBE = 'ALARM_DATA_UNSUBSCRIBE',
|
||||||
ALARM_COUNT_UNSUBSCRIBE = 'ALARM_COUNT_UNSUBSCRIBE',
|
ALARM_COUNT_UNSUBSCRIBE = 'ALARM_COUNT_UNSUBSCRIBE',
|
||||||
|
ALARM_STATUS_UNSUBSCRIBE = 'ALARM_STATUS_UNSUBSCRIBE',
|
||||||
ENTITY_DATA_UNSUBSCRIBE = 'ENTITY_DATA_UNSUBSCRIBE',
|
ENTITY_DATA_UNSUBSCRIBE = 'ENTITY_DATA_UNSUBSCRIBE',
|
||||||
ENTITY_COUNT_UNSUBSCRIBE = 'ENTITY_COUNT_UNSUBSCRIBE',
|
ENTITY_COUNT_UNSUBSCRIBE = 'ENTITY_COUNT_UNSUBSCRIBE',
|
||||||
NOTIFICATIONS_UNSUBSCRIBE = 'NOTIFICATIONS_UNSUBSCRIBE'
|
NOTIFICATIONS_UNSUBSCRIBE = 'NOTIFICATIONS_UNSUBSCRIBE'
|
||||||
@ -298,6 +300,14 @@ export class AlarmCountCmd implements WebsocketCmd {
|
|||||||
type = WsCmdType.ALARM_COUNT;
|
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 {
|
export class UnreadCountSubCmd implements WebsocketCmd {
|
||||||
cmdId: number;
|
cmdId: number;
|
||||||
type = WsCmdType.NOTIFICATIONS_COUNT;
|
type = WsCmdType.NOTIFICATIONS_COUNT;
|
||||||
@ -352,6 +362,11 @@ export class AlarmCountUnsubscribeCmd implements WebsocketCmd {
|
|||||||
type = WsCmdType.ALARM_COUNT_UNSUBSCRIBE;
|
type = WsCmdType.ALARM_COUNT_UNSUBSCRIBE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class AlarmStatusUnsubscribeCmd implements WebsocketCmd {
|
||||||
|
cmdId: number;
|
||||||
|
type = WsCmdType.ALARM_STATUS_UNSUBSCRIBE;
|
||||||
|
}
|
||||||
|
|
||||||
export class UnsubscribeCmd implements WebsocketCmd {
|
export class UnsubscribeCmd implements WebsocketCmd {
|
||||||
cmdId: number;
|
cmdId: number;
|
||||||
type = WsCmdType.NOTIFICATIONS_UNSUBSCRIBE;
|
type = WsCmdType.NOTIFICATIONS_UNSUBSCRIBE;
|
||||||
@ -432,6 +447,7 @@ export enum CmdUpdateType {
|
|||||||
ENTITY_DATA = 'ENTITY_DATA',
|
ENTITY_DATA = 'ENTITY_DATA',
|
||||||
ALARM_DATA = 'ALARM_DATA',
|
ALARM_DATA = 'ALARM_DATA',
|
||||||
ALARM_COUNT_DATA = 'ALARM_COUNT_DATA',
|
ALARM_COUNT_DATA = 'ALARM_COUNT_DATA',
|
||||||
|
ALARM_STATUS = 'ALARM_STATUS',
|
||||||
COUNT_DATA = 'COUNT_DATA',
|
COUNT_DATA = 'COUNT_DATA',
|
||||||
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT',
|
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT',
|
||||||
NOTIFICATIONS = 'NOTIFICATIONS'
|
NOTIFICATIONS = 'NOTIFICATIONS'
|
||||||
@ -469,6 +485,11 @@ export interface AlarmCountUpdateMsg extends CmdUpdateMsg {
|
|||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AlarmStatusUpdateMsg extends CmdUpdateMsg {
|
||||||
|
cmdUpdateType: CmdUpdateType.ALARM_STATUS;
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface NotificationCountUpdateMsg extends CmdUpdateMsg {
|
export interface NotificationCountUpdateMsg extends CmdUpdateMsg {
|
||||||
cmdUpdateType: CmdUpdateType.NOTIFICATIONS_COUNT;
|
cmdUpdateType: CmdUpdateType.NOTIFICATIONS_COUNT;
|
||||||
totalUnreadCount: number;
|
totalUnreadCount: number;
|
||||||
@ -506,6 +527,11 @@ export const isAlarmCountUpdateMsg = (message: WebsocketDataMsg): message is Ala
|
|||||||
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.ALARM_COUNT_DATA;
|
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 => {
|
export const isNotificationCountUpdateMsg = (message: WebsocketDataMsg): message is NotificationCountUpdateMsg => {
|
||||||
const updateMsg = (message as CmdUpdateMsg);
|
const updateMsg = (message as CmdUpdateMsg);
|
||||||
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.NOTIFICATIONS_COUNT;
|
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 {
|
export class NotificationCountUpdate extends CmdUpdate {
|
||||||
totalUnreadCount: number;
|
totalUnreadCount: number;
|
||||||
sequenceNumber: number;
|
sequenceNumber: number;
|
||||||
@ -750,14 +785,29 @@ export class SharedTelemetrySubscriber {
|
|||||||
return key;
|
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 subscribed = false;
|
||||||
|
|
||||||
private attributeDataSubject = connectable(this.sharedSubscriptionInfo.subscriber.attributeData$(),
|
private attributeDataSubject = connectable(this.sharedSubscriptionInfo.subscriber.attributeData$(),
|
||||||
{ connector: () => new ReplaySubject<Array<AttributeData>>(1)});
|
{ connector: () => new ReplaySubject<Array<AttributeData>>(1)});
|
||||||
|
|
||||||
|
private alarmStatusSubject = connectable(this.sharedSubscriptionInfo.subscriber.alarmStatus$,
|
||||||
|
{ connector: () => new ReplaySubject<AlarmStatusUpdate>()});
|
||||||
|
|
||||||
private subscriptions = new Array<Subscription>();
|
private subscriptions = new Array<Subscription>();
|
||||||
|
|
||||||
public attributeData$: Observable<Array<AttributeData>> = this.attributeDataSubject; //this.attributeDataSubject.asObservable();
|
public attributeData$: Observable<Array<AttributeData>> = this.attributeDataSubject; //this.attributeDataSubject.asObservable();
|
||||||
|
public alarmStatus$: Observable<AlarmStatusUpdate> = this.alarmStatusSubject;
|
||||||
|
|
||||||
public static createEntityAttributesSubscription(telemetryService: TelemetryWebsocketService,
|
public static createEntityAttributesSubscription(telemetryService: TelemetryWebsocketService,
|
||||||
entityId: EntityId, attributeScope: TelemetryType,
|
entityId: EntityId, attributeScope: TelemetryType,
|
||||||
@ -781,6 +831,28 @@ export class SharedTelemetrySubscriber {
|
|||||||
return sharedSubscriber;
|
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) {
|
private constructor(private sharedSubscriptionInfo: SharedSubscriptionInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,6 +860,7 @@ export class SharedTelemetrySubscriber {
|
|||||||
if (!this.subscribed) {
|
if (!this.subscribed) {
|
||||||
this.subscribed = true;
|
this.subscribed = true;
|
||||||
this.subscriptions.push(this.attributeDataSubject.connect());
|
this.subscriptions.push(this.attributeDataSubject.connect());
|
||||||
|
this.subscriptions.push(this.alarmStatusSubject.connect());
|
||||||
if (!this.sharedSubscriptionInfo.subscribed) {
|
if (!this.sharedSubscriptionInfo.subscribed) {
|
||||||
this.sharedSubscriptionInfo.subscriber.subscribe();
|
this.sharedSubscriptionInfo.subscriber.subscribe();
|
||||||
this.sharedSubscriptionInfo.subscribed = true;
|
this.sharedSubscriptionInfo.subscribed = true;
|
||||||
@ -823,6 +896,7 @@ export class TelemetrySubscriber extends WsSubscriber {
|
|||||||
private alarmDataSubject = new ReplaySubject<AlarmDataUpdate>(1);
|
private alarmDataSubject = new ReplaySubject<AlarmDataUpdate>(1);
|
||||||
private entityCountSubject = new ReplaySubject<EntityCountUpdate>(1);
|
private entityCountSubject = new ReplaySubject<EntityCountUpdate>(1);
|
||||||
private alarmCountSubject = new ReplaySubject<AlarmCountUpdate>(1);
|
private alarmCountSubject = new ReplaySubject<AlarmCountUpdate>(1);
|
||||||
|
private alarmStatusSubject = new ReplaySubject<AlarmStatusUpdate>(1);
|
||||||
private tsOffset = undefined;
|
private tsOffset = undefined;
|
||||||
|
|
||||||
public data$ = this.dataSubject.asObservable();
|
public data$ = this.dataSubject.asObservable();
|
||||||
@ -830,6 +904,7 @@ export class TelemetrySubscriber extends WsSubscriber {
|
|||||||
public alarmData$ = this.alarmDataSubject.asObservable();
|
public alarmData$ = this.alarmDataSubject.asObservable();
|
||||||
public entityCount$ = this.entityCountSubject.asObservable();
|
public entityCount$ = this.entityCountSubject.asObservable();
|
||||||
public alarmCount$ = this.alarmCountSubject.asObservable();
|
public alarmCount$ = this.alarmCountSubject.asObservable();
|
||||||
|
public alarmStatus$ = this.alarmStatusSubject.asObservable();
|
||||||
|
|
||||||
public static createEntityAttributesSubscription(telemetryService: TelemetryWebsocketService,
|
public static createEntityAttributesSubscription(telemetryService: TelemetryWebsocketService,
|
||||||
entityId: EntityId, attributeScope: TelemetryType,
|
entityId: EntityId, attributeScope: TelemetryType,
|
||||||
@ -851,6 +926,17 @@ export class TelemetrySubscriber extends WsSubscriber {
|
|||||||
return subscriber;
|
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,
|
public static createEntityFilterLatestSubscription(telemetryService: TelemetryWebsocketService,
|
||||||
entityFilter: EntityFilter, zone: NgZone,
|
entityFilter: EntityFilter, zone: NgZone,
|
||||||
latestKeys: EntityKey[] = null): TelemetrySubscriber {
|
latestKeys: EntityKey[] = null): TelemetrySubscriber {
|
||||||
@ -882,6 +968,7 @@ export class TelemetrySubscriber extends WsSubscriber {
|
|||||||
this.alarmDataSubject.complete();
|
this.alarmDataSubject.complete();
|
||||||
this.entityCountSubject.complete();
|
this.entityCountSubject.complete();
|
||||||
this.alarmCountSubject.complete();
|
this.alarmCountSubject.complete();
|
||||||
|
this.alarmStatusSubject.complete();
|
||||||
super.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>> {
|
public attributeData$(): Observable<Array<AttributeData>> {
|
||||||
const attributeData = new Array<AttributeData>();
|
const attributeData = new Array<AttributeData>();
|
||||||
return this.data$.pipe(
|
return this.data$.pipe(
|
||||||
|
|||||||
@ -596,6 +596,7 @@
|
|||||||
"ack-time": "Acknowledged time",
|
"ack-time": "Acknowledged time",
|
||||||
"clear-time": "Cleared time",
|
"clear-time": "Cleared time",
|
||||||
"duration": "Duration",
|
"duration": "Duration",
|
||||||
|
"alarm-severity": "Alarm severity",
|
||||||
"alarm-severity-list": "Alarm severity list",
|
"alarm-severity-list": "Alarm severity list",
|
||||||
"any-severity": "Any severity",
|
"any-severity": "Any severity",
|
||||||
"severity-critical": "Critical",
|
"severity-critical": "Critical",
|
||||||
@ -634,6 +635,7 @@
|
|||||||
"fetch-size": "Fetch size",
|
"fetch-size": "Fetch size",
|
||||||
"fetch-size-required": "Fetch size is required.",
|
"fetch-size-required": "Fetch size is required.",
|
||||||
"fetch-size-error-min": "Minimum value is 10.",
|
"fetch-size-error-min": "Minimum value is 10.",
|
||||||
|
"alarm-types": "Alarm types",
|
||||||
"alarm-type-list": "Alarm type list",
|
"alarm-type-list": "Alarm type list",
|
||||||
"any-type": "Any type",
|
"any-type": "Any type",
|
||||||
"assigned-to-current-user": "Assigned to current user",
|
"assigned-to-current-user": "Assigned to current user",
|
||||||
@ -7352,11 +7354,12 @@
|
|||||||
"get-attribute": "Get attribute",
|
"get-attribute": "Get attribute",
|
||||||
"set-attribute": "Set attribute",
|
"set-attribute": "Set attribute",
|
||||||
"get-time-series": "Get time series",
|
"get-time-series": "Get time series",
|
||||||
|
"get-alarm-status": "Get alarm status",
|
||||||
"get-dashboard-state": "Get dashboard state",
|
"get-dashboard-state": "Get dashboard state",
|
||||||
"add-time-series": "Add time series",
|
"add-time-series": "Add time series",
|
||||||
"execute-rpc-text": "Execute RPC method '{{methodName}}'",
|
"execute-rpc-text": "Execute RPC method '{{methodName}}'",
|
||||||
"get-attribute-text": "Use attribute '{{key}}'",
|
"get-attribute-text": "Use attribute '{{key}}'",
|
||||||
"get-time-series-text": "Use time series '{{key}}'",
|
"get-alarm-status-text": "Use alarm status",
|
||||||
"get-dashboard-state-text": "Use dashboard state",
|
"get-dashboard-state-text": "Use dashboard state",
|
||||||
"when-dashboard-state-is-text": "When dashboard state is '{{state}}'",
|
"when-dashboard-state-is-text": "When dashboard state is '{{state}}'",
|
||||||
"when-dashboard-state-function-is-text": "When f(dashboard state) is '{{state}}'",
|
"when-dashboard-state-function-is-text": "When f(dashboard state) is '{{state}}'",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user