2019-08-19 20:09:41 +03:00
|
|
|
///
|
2023-01-31 10:43:56 +02:00
|
|
|
/// Copyright © 2016-2023 The Thingsboard Authors
|
2019-08-19 20:09:41 +03:00
|
|
|
///
|
|
|
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
/// you may not use this file except in compliance with the License.
|
|
|
|
|
/// You may obtain a copy of the License at
|
|
|
|
|
///
|
|
|
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
///
|
|
|
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
/// See the License for the specific language governing permissions and
|
|
|
|
|
/// limitations under the License.
|
|
|
|
|
///
|
|
|
|
|
|
|
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
import { EntityType } from '@shared/models/entity-type.models';
|
|
|
|
|
import { AggregationType } from '../time/time.models';
|
2023-02-16 12:59:43 +02:00
|
|
|
import { Observable, ReplaySubject } from 'rxjs';
|
2019-08-30 19:19:45 +03:00
|
|
|
import { EntityId } from '@shared/models/id/entity-id';
|
|
|
|
|
import { map } from 'rxjs/operators';
|
2019-11-15 12:22:14 +02:00
|
|
|
import { NgZone } from '@angular/core';
|
2020-11-09 15:54:05 +02:00
|
|
|
import {
|
2023-04-21 18:00:56 +03:00
|
|
|
AlarmCountQuery,
|
2020-11-09 15:54:05 +02:00
|
|
|
AlarmData,
|
2023-12-07 15:11:41 +02:00
|
|
|
AlarmDataQuery,
|
|
|
|
|
EntityCountQuery,
|
2020-11-09 15:54:05 +02:00
|
|
|
EntityData,
|
2023-12-07 15:11:41 +02:00
|
|
|
EntityDataQuery,
|
|
|
|
|
EntityFilter,
|
2020-11-09 15:54:05 +02:00
|
|
|
EntityKey,
|
|
|
|
|
TsValue
|
|
|
|
|
} from '@shared/models/query/query.models';
|
2020-06-19 18:13:57 +03:00
|
|
|
import { PageData } from '@shared/models/page/page-data';
|
2021-03-18 13:51:46 +02:00
|
|
|
import { alarmFields } from '@shared/models/alarm.models';
|
|
|
|
|
import { entityFields } from '@shared/models/entity.models';
|
|
|
|
|
import { isUndefined } from '@core/utils';
|
2023-02-16 12:59:43 +02:00
|
|
|
import { CmdWrapper, WsSubscriber } from '@shared/models/websocket/websocket.models';
|
|
|
|
|
import { TelemetryWebsocketService } from '@core/ws/telemetry-websocket.service';
|
2023-12-07 15:11:41 +02:00
|
|
|
import {
|
|
|
|
|
MarkAllAsReadCmd,
|
|
|
|
|
MarkAsReadCmd,
|
|
|
|
|
NotificationCountUpdateMsg,
|
|
|
|
|
NotificationsUpdateMsg,
|
|
|
|
|
UnreadCountSubCmd,
|
|
|
|
|
UnreadSubCmd,
|
|
|
|
|
UnsubscribeCmd
|
|
|
|
|
} from '@shared/models/websocket/notification-ws.models';
|
|
|
|
|
import { Notification } from '@shared/models/notification.models';
|
2019-08-29 20:04:59 +03:00
|
|
|
|
2023-08-25 15:59:58 +03:00
|
|
|
export const NOT_SUPPORTED = 'Not supported!';
|
|
|
|
|
|
2019-08-19 20:09:41 +03:00
|
|
|
export enum DataKeyType {
|
|
|
|
|
timeseries = 'timeseries',
|
|
|
|
|
attribute = 'attribute',
|
|
|
|
|
function = 'function',
|
2020-02-21 19:04:49 +02:00
|
|
|
alarm = 'alarm',
|
2021-03-02 12:04:45 +02:00
|
|
|
entityField = 'entityField',
|
|
|
|
|
count = 'count'
|
2019-08-19 20:09:41 +03:00
|
|
|
}
|
2019-08-29 20:04:59 +03:00
|
|
|
|
|
|
|
|
export enum LatestTelemetry {
|
|
|
|
|
LATEST_TELEMETRY = 'LATEST_TELEMETRY'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export enum AttributeScope {
|
|
|
|
|
CLIENT_SCOPE = 'CLIENT_SCOPE',
|
|
|
|
|
SERVER_SCOPE = 'SERVER_SCOPE',
|
|
|
|
|
SHARED_SCOPE = 'SHARED_SCOPE'
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
export enum TelemetryFeature {
|
|
|
|
|
ATTRIBUTES = 'ATTRIBUTES',
|
|
|
|
|
TIMESERIES = 'TIMESERIES'
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-13 15:24:45 +03:00
|
|
|
export enum TimeseriesDeleteStrategy {
|
2023-07-17 23:46:06 +03:00
|
|
|
DELETE_ALL_DATA = 'DELETE_ALL_DATA',
|
|
|
|
|
DELETE_ALL_DATA_EXCEPT_LATEST_VALUE = 'DELETE_ALL_DATA_EXCEPT_LATEST_VALUE',
|
2023-07-13 15:24:45 +03:00
|
|
|
DELETE_LATEST_VALUE = 'DELETE_LATEST_VALUE',
|
2023-07-17 23:46:06 +03:00
|
|
|
DELETE_ALL_DATA_FOR_TIME_PERIOD = 'DELETE_ALL_DATA_FOR_TIME_PERIOD'
|
2023-07-13 15:24:45 +03:00
|
|
|
}
|
|
|
|
|
|
2019-08-29 20:04:59 +03:00
|
|
|
export type TelemetryType = LatestTelemetry | AttributeScope;
|
|
|
|
|
|
2023-02-06 13:09:43 +02:00
|
|
|
export const toTelemetryType = (val: string): TelemetryType => {
|
2020-02-04 15:14:17 +02:00
|
|
|
if (LatestTelemetry[val]) {
|
|
|
|
|
return LatestTelemetry[val];
|
|
|
|
|
} else {
|
|
|
|
|
return AttributeScope[val];
|
|
|
|
|
}
|
2023-02-06 13:09:43 +02:00
|
|
|
};
|
2020-02-04 15:14:17 +02:00
|
|
|
|
2019-08-29 20:04:59 +03:00
|
|
|
export const telemetryTypeTranslations = new Map<TelemetryType, string>(
|
|
|
|
|
[
|
2023-07-13 15:24:45 +03:00
|
|
|
[LatestTelemetry.LATEST_TELEMETRY, 'attribute.scope-telemetry'],
|
2019-08-29 20:04:59 +03:00
|
|
|
[AttributeScope.CLIENT_SCOPE, 'attribute.scope-client'],
|
|
|
|
|
[AttributeScope.SERVER_SCOPE, 'attribute.scope-server'],
|
|
|
|
|
[AttributeScope.SHARED_SCOPE, 'attribute.scope-shared']
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export const isClientSideTelemetryType = new Map<TelemetryType, boolean>(
|
|
|
|
|
[
|
|
|
|
|
[LatestTelemetry.LATEST_TELEMETRY, true],
|
|
|
|
|
[AttributeScope.CLIENT_SCOPE, true],
|
|
|
|
|
[AttributeScope.SERVER_SCOPE, false],
|
|
|
|
|
[AttributeScope.SHARED_SCOPE, false]
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
|
2023-07-13 15:24:45 +03:00
|
|
|
export const timeseriesDeleteStrategyTranslations = new Map<TimeseriesDeleteStrategy, string>(
|
|
|
|
|
[
|
2023-07-17 23:46:06 +03:00
|
|
|
[TimeseriesDeleteStrategy.DELETE_ALL_DATA, 'attribute.delete-timeseries.all-data'],
|
|
|
|
|
[TimeseriesDeleteStrategy.DELETE_ALL_DATA_EXCEPT_LATEST_VALUE, 'attribute.delete-timeseries.all-data-except-latest-value'],
|
2023-07-13 15:24:45 +03:00
|
|
|
[TimeseriesDeleteStrategy.DELETE_LATEST_VALUE, 'attribute.delete-timeseries.latest-value'],
|
2023-07-17 23:46:06 +03:00
|
|
|
[TimeseriesDeleteStrategy.DELETE_ALL_DATA_FOR_TIME_PERIOD, 'attribute.delete-timeseries.all-data-for-time-period']
|
2023-07-13 15:24:45 +03:00
|
|
|
]
|
2023-12-07 15:11:41 +02:00
|
|
|
);
|
2023-07-13 15:24:45 +03:00
|
|
|
|
2019-08-29 20:04:59 +03:00
|
|
|
export interface AttributeData {
|
2019-11-15 12:22:14 +02:00
|
|
|
lastUpdateTs?: number;
|
2019-08-29 20:04:59 +03:00
|
|
|
key: string;
|
|
|
|
|
value: any;
|
|
|
|
|
}
|
2019-08-30 19:19:45 +03:00
|
|
|
|
2020-11-09 15:18:37 +02:00
|
|
|
export interface TimeseriesData {
|
2020-11-09 15:54:05 +02:00
|
|
|
[key: string]: Array<TsValue>;
|
2020-11-09 15:18:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export enum DataSortOrder {
|
|
|
|
|
ASC = 'ASC',
|
|
|
|
|
DESC = 'DESC'
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 18:13:57 +03:00
|
|
|
export interface WebsocketCmd {
|
2019-08-30 19:19:45 +03:00
|
|
|
cmdId: number;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TelemetryPluginCmd extends WebsocketCmd {
|
2019-08-30 19:19:45 +03:00
|
|
|
keys: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export abstract class SubscriptionCmd implements TelemetryPluginCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
keys: string;
|
|
|
|
|
entityType: EntityType;
|
|
|
|
|
entityId: string;
|
|
|
|
|
scope?: AttributeScope;
|
|
|
|
|
unsubscribe: boolean;
|
|
|
|
|
abstract getType(): TelemetryFeature;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AttributesSubscriptionCmd extends SubscriptionCmd {
|
|
|
|
|
getType() {
|
|
|
|
|
return TelemetryFeature.ATTRIBUTES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class TimeseriesSubscriptionCmd extends SubscriptionCmd {
|
|
|
|
|
startTs: number;
|
|
|
|
|
timeWindow: number;
|
|
|
|
|
interval: number;
|
|
|
|
|
limit: number;
|
|
|
|
|
agg: AggregationType;
|
|
|
|
|
|
|
|
|
|
getType() {
|
|
|
|
|
return TelemetryFeature.TIMESERIES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class GetHistoryCmd implements TelemetryPluginCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
keys: string;
|
|
|
|
|
entityType: EntityType;
|
|
|
|
|
entityId: string;
|
|
|
|
|
startTs: number;
|
|
|
|
|
endTs: number;
|
|
|
|
|
interval: number;
|
|
|
|
|
limit: number;
|
|
|
|
|
agg: AggregationType;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 18:13:57 +03:00
|
|
|
export interface EntityHistoryCmd {
|
|
|
|
|
keys: Array<string>;
|
|
|
|
|
startTs: number;
|
|
|
|
|
endTs: number;
|
|
|
|
|
interval: number;
|
|
|
|
|
limit: number;
|
|
|
|
|
agg: AggregationType;
|
2020-06-24 18:07:47 +03:00
|
|
|
fetchLatestPreviousPoint?: boolean;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LatestValueCmd {
|
2020-06-22 18:55:15 +03:00
|
|
|
keys: Array<EntityKey>;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TimeSeriesCmd {
|
|
|
|
|
keys: Array<string>;
|
|
|
|
|
startTs: number;
|
|
|
|
|
timeWindow: number;
|
|
|
|
|
interval: number;
|
|
|
|
|
limit: number;
|
|
|
|
|
agg: AggregationType;
|
2020-06-24 18:07:47 +03:00
|
|
|
fetchLatestPreviousPoint?: boolean;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
2022-09-08 18:51:13 +03:00
|
|
|
export interface AggKey {
|
2022-09-14 17:49:37 +03:00
|
|
|
id: number;
|
2022-09-08 18:51:13 +03:00
|
|
|
key: string;
|
|
|
|
|
agg: AggregationType;
|
2022-09-14 17:49:37 +03:00
|
|
|
previousStartTs?: number;
|
|
|
|
|
previousEndTs?: number;
|
|
|
|
|
previousValueOnly?: boolean;
|
2022-09-08 18:51:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AggEntityHistoryCmd {
|
|
|
|
|
keys: Array<AggKey>;
|
|
|
|
|
startTs: number;
|
|
|
|
|
endTs: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AggTimeSeriesCmd {
|
|
|
|
|
keys: Array<AggKey>;
|
|
|
|
|
startTs: number;
|
|
|
|
|
timeWindow: number;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 18:13:57 +03:00
|
|
|
export class EntityDataCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
2020-06-22 18:55:15 +03:00
|
|
|
query?: EntityDataQuery;
|
2020-06-19 18:13:57 +03:00
|
|
|
historyCmd?: EntityHistoryCmd;
|
|
|
|
|
latestCmd?: LatestValueCmd;
|
|
|
|
|
tsCmd?: TimeSeriesCmd;
|
2022-09-08 18:51:13 +03:00
|
|
|
aggHistoryCmd?: AggEntityHistoryCmd;
|
|
|
|
|
aggTsCmd?: AggTimeSeriesCmd;
|
2020-06-23 20:56:44 +03:00
|
|
|
|
|
|
|
|
public isEmpty(): boolean {
|
2022-09-23 17:15:24 +03:00
|
|
|
return !this.query && !this.historyCmd && !this.latestCmd && !this.tsCmd && !this.aggTsCmd && !this.aggHistoryCmd;
|
2020-06-23 20:56:44 +03:00
|
|
|
}
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export class EntityCountCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
query?: EntityCountQuery;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 18:33:06 +03:00
|
|
|
export class AlarmDataCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
query?: AlarmDataQuery;
|
|
|
|
|
|
|
|
|
|
public isEmpty(): boolean {
|
|
|
|
|
return !this.query;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
export class AlarmCountCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
query?: AlarmCountQuery;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 18:13:57 +03:00
|
|
|
export class EntityDataUnsubscribeCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export class EntityCountUnsubscribeCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 18:33:06 +03:00
|
|
|
export class AlarmDataUnsubscribeCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
export class AlarmCountUnsubscribeCmd implements WebsocketCmd {
|
|
|
|
|
cmdId: number;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 12:59:43 +02:00
|
|
|
export class TelemetryPluginCmdsWrapper implements CmdWrapper {
|
2019-08-30 19:19:45 +03:00
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
|
this.attrSubCmds = [];
|
|
|
|
|
this.tsSubCmds = [];
|
|
|
|
|
this.historyCmds = [];
|
2020-06-19 18:13:57 +03:00
|
|
|
this.entityDataCmds = [];
|
|
|
|
|
this.entityDataUnsubscribeCmds = [];
|
2020-07-03 18:33:06 +03:00
|
|
|
this.alarmDataCmds = [];
|
|
|
|
|
this.alarmDataUnsubscribeCmds = [];
|
2021-03-02 12:04:45 +02:00
|
|
|
this.entityCountCmds = [];
|
|
|
|
|
this.entityCountUnsubscribeCmds = [];
|
2023-04-21 18:00:56 +03:00
|
|
|
this.alarmCountCmds = [];
|
|
|
|
|
this.alarmCountUnsubscribeCmds = [];
|
2023-12-07 15:11:41 +02:00
|
|
|
this.unreadNotificationsCountSubCmds = [];
|
|
|
|
|
this.unreadNotificationsSubCmds = [];
|
|
|
|
|
this.notificationsUnsubCmds = [];
|
|
|
|
|
this.markNotificationAsReadCmds = [];
|
|
|
|
|
this.markAllNotificationsAsReadCmds = [];
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
2022-09-12 16:20:37 +03:00
|
|
|
attrSubCmds: Array<AttributesSubscriptionCmd>;
|
|
|
|
|
tsSubCmds: Array<TimeseriesSubscriptionCmd>;
|
|
|
|
|
historyCmds: Array<GetHistoryCmd>;
|
|
|
|
|
entityDataCmds: Array<EntityDataCmd>;
|
|
|
|
|
entityDataUnsubscribeCmds: Array<EntityDataUnsubscribeCmd>;
|
|
|
|
|
alarmDataCmds: Array<AlarmDataCmd>;
|
|
|
|
|
alarmDataUnsubscribeCmds: Array<AlarmDataUnsubscribeCmd>;
|
|
|
|
|
entityCountCmds: Array<EntityCountCmd>;
|
|
|
|
|
entityCountUnsubscribeCmds: Array<EntityCountUnsubscribeCmd>;
|
2023-04-21 18:00:56 +03:00
|
|
|
alarmCountCmds: Array<AlarmCountCmd>;
|
|
|
|
|
alarmCountUnsubscribeCmds: Array<AlarmCountUnsubscribeCmd>;
|
2023-12-07 15:11:41 +02:00
|
|
|
unreadNotificationsCountSubCmds: Array<UnreadCountSubCmd>;
|
|
|
|
|
unreadNotificationsSubCmds: Array<UnreadSubCmd>;
|
|
|
|
|
notificationsUnsubCmds: Array<UnsubscribeCmd>;
|
|
|
|
|
markNotificationAsReadCmds: Array<MarkAsReadCmd>;
|
|
|
|
|
markAllNotificationsAsReadCmds: Array<MarkAllAsReadCmd>;
|
2022-09-12 16:20:37 +03:00
|
|
|
|
|
|
|
|
private static popCmds<T>(cmds: Array<T>, leftCount: number): Array<T> {
|
|
|
|
|
const toPublish = Math.min(cmds.length, leftCount);
|
|
|
|
|
if (toPublish > 0) {
|
|
|
|
|
return cmds.splice(0, toPublish);
|
|
|
|
|
} else {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-30 19:19:45 +03:00
|
|
|
|
|
|
|
|
public hasCommands(): boolean {
|
|
|
|
|
return this.tsSubCmds.length > 0 ||
|
|
|
|
|
this.historyCmds.length > 0 ||
|
2020-06-19 18:13:57 +03:00
|
|
|
this.attrSubCmds.length > 0 ||
|
|
|
|
|
this.entityDataCmds.length > 0 ||
|
2020-07-03 18:33:06 +03:00
|
|
|
this.entityDataUnsubscribeCmds.length > 0 ||
|
|
|
|
|
this.alarmDataCmds.length > 0 ||
|
2021-03-02 12:04:45 +02:00
|
|
|
this.alarmDataUnsubscribeCmds.length > 0 ||
|
|
|
|
|
this.entityCountCmds.length > 0 ||
|
2023-04-21 18:00:56 +03:00
|
|
|
this.entityCountUnsubscribeCmds.length > 0 ||
|
|
|
|
|
this.alarmCountCmds.length > 0 ||
|
2023-12-07 15:11:41 +02:00
|
|
|
this.alarmCountUnsubscribeCmds.length > 0 ||
|
|
|
|
|
this.unreadNotificationsCountSubCmds.length > 0 ||
|
|
|
|
|
this.unreadNotificationsSubCmds.length > 0 ||
|
|
|
|
|
this.notificationsUnsubCmds.length > 0 ||
|
|
|
|
|
this.markNotificationAsReadCmds.length > 0 ||
|
|
|
|
|
this.markAllNotificationsAsReadCmds.length > 0;
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public clear() {
|
|
|
|
|
this.attrSubCmds.length = 0;
|
|
|
|
|
this.tsSubCmds.length = 0;
|
|
|
|
|
this.historyCmds.length = 0;
|
2020-06-19 18:13:57 +03:00
|
|
|
this.entityDataCmds.length = 0;
|
|
|
|
|
this.entityDataUnsubscribeCmds.length = 0;
|
2020-07-03 18:33:06 +03:00
|
|
|
this.alarmDataCmds.length = 0;
|
|
|
|
|
this.alarmDataUnsubscribeCmds.length = 0;
|
2021-03-02 12:04:45 +02:00
|
|
|
this.entityCountCmds.length = 0;
|
|
|
|
|
this.entityCountUnsubscribeCmds.length = 0;
|
2023-04-21 18:00:56 +03:00
|
|
|
this.alarmCountCmds.length = 0;
|
|
|
|
|
this.alarmCountUnsubscribeCmds.length = 0;
|
2023-12-07 15:11:41 +02:00
|
|
|
this.unreadNotificationsSubCmds.length = 0;
|
|
|
|
|
this.unreadNotificationsCountSubCmds.length = 0;
|
|
|
|
|
this.notificationsUnsubCmds.length = 0;
|
|
|
|
|
this.markNotificationAsReadCmds.length = 0;
|
|
|
|
|
this.markAllNotificationsAsReadCmds.length = 0;
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public preparePublishCommands(maxCommands: number): TelemetryPluginCmdsWrapper {
|
|
|
|
|
const preparedWrapper = new TelemetryPluginCmdsWrapper();
|
|
|
|
|
let leftCount = maxCommands;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.tsSubCmds = TelemetryPluginCmdsWrapper.popCmds(this.tsSubCmds, leftCount);
|
2019-08-30 19:19:45 +03:00
|
|
|
leftCount -= preparedWrapper.tsSubCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.historyCmds = TelemetryPluginCmdsWrapper.popCmds(this.historyCmds, leftCount);
|
2019-08-30 19:19:45 +03:00
|
|
|
leftCount -= preparedWrapper.historyCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.attrSubCmds = TelemetryPluginCmdsWrapper.popCmds(this.attrSubCmds, leftCount);
|
2020-06-19 18:13:57 +03:00
|
|
|
leftCount -= preparedWrapper.attrSubCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.entityDataCmds = TelemetryPluginCmdsWrapper.popCmds(this.entityDataCmds, leftCount);
|
2020-06-19 18:13:57 +03:00
|
|
|
leftCount -= preparedWrapper.entityDataCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.entityDataUnsubscribeCmds = TelemetryPluginCmdsWrapper.popCmds(this.entityDataUnsubscribeCmds, leftCount);
|
2020-07-03 18:33:06 +03:00
|
|
|
leftCount -= preparedWrapper.entityDataUnsubscribeCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.alarmDataCmds = TelemetryPluginCmdsWrapper.popCmds(this.alarmDataCmds, leftCount);
|
2020-07-03 18:33:06 +03:00
|
|
|
leftCount -= preparedWrapper.alarmDataCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.alarmDataUnsubscribeCmds = TelemetryPluginCmdsWrapper.popCmds(this.alarmDataUnsubscribeCmds, leftCount);
|
2021-03-02 12:04:45 +02:00
|
|
|
leftCount -= preparedWrapper.alarmDataUnsubscribeCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.entityCountCmds = TelemetryPluginCmdsWrapper.popCmds(this.entityCountCmds, leftCount);
|
2021-03-02 12:04:45 +02:00
|
|
|
leftCount -= preparedWrapper.entityCountCmds.length;
|
2022-09-12 16:20:37 +03:00
|
|
|
preparedWrapper.entityCountUnsubscribeCmds = TelemetryPluginCmdsWrapper.popCmds(this.entityCountUnsubscribeCmds, leftCount);
|
2023-04-21 18:00:56 +03:00
|
|
|
leftCount -= preparedWrapper.entityCountUnsubscribeCmds.length;
|
|
|
|
|
preparedWrapper.alarmCountCmds = TelemetryPluginCmdsWrapper.popCmds(this.alarmCountCmds, leftCount);
|
|
|
|
|
leftCount -= preparedWrapper.alarmCountCmds.length;
|
|
|
|
|
preparedWrapper.alarmCountUnsubscribeCmds = TelemetryPluginCmdsWrapper.popCmds(this.alarmCountUnsubscribeCmds, leftCount);
|
2023-12-07 15:11:41 +02:00
|
|
|
leftCount -= preparedWrapper.unreadNotificationsSubCmds.length;
|
|
|
|
|
preparedWrapper.unreadNotificationsSubCmds = TelemetryPluginCmdsWrapper.popCmds(this.unreadNotificationsSubCmds, leftCount);
|
|
|
|
|
leftCount -= preparedWrapper.unreadNotificationsCountSubCmds.length;
|
|
|
|
|
preparedWrapper.unreadNotificationsCountSubCmds = TelemetryPluginCmdsWrapper.popCmds(this.unreadNotificationsCountSubCmds, leftCount);
|
|
|
|
|
leftCount -= preparedWrapper.notificationsUnsubCmds.length;
|
|
|
|
|
preparedWrapper.notificationsUnsubCmds = TelemetryPluginCmdsWrapper.popCmds(this.notificationsUnsubCmds, leftCount);
|
|
|
|
|
leftCount -= preparedWrapper.markNotificationAsReadCmds.length;
|
|
|
|
|
preparedWrapper.markNotificationAsReadCmds = TelemetryPluginCmdsWrapper.popCmds(this.markNotificationAsReadCmds, leftCount);
|
|
|
|
|
leftCount -= preparedWrapper.markAllNotificationsAsReadCmds.length;
|
|
|
|
|
preparedWrapper.markAllNotificationsAsReadCmds = TelemetryPluginCmdsWrapper.popCmds(this.markAllNotificationsAsReadCmds, leftCount);
|
2019-08-30 19:19:45 +03:00
|
|
|
return preparedWrapper;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-12 19:58:42 +03:00
|
|
|
export interface SubscriptionData {
|
2022-09-12 16:20:37 +03:00
|
|
|
[key: string]: [number, any, number?][];
|
2019-09-12 19:58:42 +03:00
|
|
|
}
|
|
|
|
|
|
2022-09-14 17:49:37 +03:00
|
|
|
export interface IndexedSubscriptionData {
|
|
|
|
|
[id: number]: [number, any, number?][];
|
2022-09-13 14:07:56 +03:00
|
|
|
}
|
|
|
|
|
|
2019-09-12 19:58:42 +03:00
|
|
|
export interface SubscriptionDataHolder {
|
|
|
|
|
data: SubscriptionData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SubscriptionUpdateMsg extends SubscriptionDataHolder {
|
2019-08-30 19:19:45 +03:00
|
|
|
subscriptionId: number;
|
|
|
|
|
errorCode: number;
|
|
|
|
|
errorMsg: string;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export enum CmdUpdateType {
|
2020-07-03 18:33:06 +03:00
|
|
|
ENTITY_DATA = 'ENTITY_DATA',
|
2021-03-02 12:04:45 +02:00
|
|
|
ALARM_DATA = 'ALARM_DATA',
|
2023-04-21 18:00:56 +03:00
|
|
|
ALARM_COUNT_DATA = 'ALARM_COUNT_DATA',
|
2023-01-20 15:08:44 +02:00
|
|
|
COUNT_DATA = 'COUNT_DATA',
|
|
|
|
|
NOTIFICATIONS_COUNT = 'NOTIFICATIONS_COUNT',
|
|
|
|
|
NOTIFICATIONS = 'NOTIFICATIONS'
|
2020-07-03 18:33:06 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export interface CmdUpdateMsg {
|
2020-06-19 18:13:57 +03:00
|
|
|
cmdId: number;
|
|
|
|
|
errorCode: number;
|
|
|
|
|
errorMsg: string;
|
2021-03-02 12:04:45 +02:00
|
|
|
cmdUpdateType: CmdUpdateType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DataUpdateMsg<T> extends CmdUpdateMsg {
|
|
|
|
|
data?: PageData<T>;
|
|
|
|
|
update?: Array<T>;
|
2020-07-03 18:33:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface EntityDataUpdateMsg extends DataUpdateMsg<EntityData> {
|
2021-03-02 12:04:45 +02:00
|
|
|
cmdUpdateType: CmdUpdateType.ENTITY_DATA;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
2020-07-03 18:33:06 +03:00
|
|
|
export interface AlarmDataUpdateMsg extends DataUpdateMsg<AlarmData> {
|
2021-03-02 12:04:45 +02:00
|
|
|
cmdUpdateType: CmdUpdateType.ALARM_DATA;
|
2020-07-10 18:04:48 +03:00
|
|
|
allowedEntities: number;
|
|
|
|
|
totalEntities: number;
|
2020-07-03 18:33:06 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export interface EntityCountUpdateMsg extends CmdUpdateMsg {
|
|
|
|
|
cmdUpdateType: CmdUpdateType.COUNT_DATA;
|
|
|
|
|
count: number;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
export interface AlarmCountUpdateMsg extends CmdUpdateMsg {
|
|
|
|
|
cmdUpdateType: CmdUpdateType.ALARM_COUNT_DATA;
|
|
|
|
|
count: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type WebsocketDataMsg = AlarmDataUpdateMsg | AlarmCountUpdateMsg |
|
2023-12-07 15:11:41 +02:00
|
|
|
EntityDataUpdateMsg | EntityCountUpdateMsg | SubscriptionUpdateMsg | NotificationCountUpdateMsg | NotificationsUpdateMsg;
|
2020-06-19 18:13:57 +03:00
|
|
|
|
2023-02-06 13:09:43 +02:00
|
|
|
export const isEntityDataUpdateMsg = (message: WebsocketDataMsg): message is EntityDataUpdateMsg => {
|
2021-03-02 12:04:45 +02:00
|
|
|
const updateMsg = (message as CmdUpdateMsg);
|
|
|
|
|
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.ENTITY_DATA;
|
2023-02-06 13:09:43 +02:00
|
|
|
};
|
2020-07-03 18:33:06 +03:00
|
|
|
|
2023-02-06 13:09:43 +02:00
|
|
|
export const isAlarmDataUpdateMsg = (message: WebsocketDataMsg): message is AlarmDataUpdateMsg => {
|
2021-03-02 12:04:45 +02:00
|
|
|
const updateMsg = (message as CmdUpdateMsg);
|
|
|
|
|
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.ALARM_DATA;
|
2023-02-06 13:09:43 +02:00
|
|
|
};
|
2021-03-02 12:04:45 +02:00
|
|
|
|
2023-02-06 13:09:43 +02:00
|
|
|
export const isEntityCountUpdateMsg = (message: WebsocketDataMsg): message is EntityCountUpdateMsg => {
|
2021-03-02 12:04:45 +02:00
|
|
|
const updateMsg = (message as CmdUpdateMsg);
|
|
|
|
|
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.COUNT_DATA;
|
2023-02-06 13:09:43 +02:00
|
|
|
};
|
2020-06-19 18:13:57 +03:00
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
export const isAlarmCountUpdateMsg = (message: WebsocketDataMsg): message is AlarmCountUpdateMsg => {
|
|
|
|
|
const updateMsg = (message as CmdUpdateMsg);
|
|
|
|
|
return updateMsg.cmdId !== undefined && updateMsg.cmdUpdateType === CmdUpdateType.ALARM_COUNT_DATA;
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
export class SubscriptionUpdate implements SubscriptionUpdateMsg {
|
|
|
|
|
subscriptionId: number;
|
|
|
|
|
errorCode: number;
|
|
|
|
|
errorMsg: string;
|
2019-09-12 19:58:42 +03:00
|
|
|
data: SubscriptionData;
|
2019-08-30 19:19:45 +03:00
|
|
|
|
|
|
|
|
constructor(msg: SubscriptionUpdateMsg) {
|
|
|
|
|
this.subscriptionId = msg.subscriptionId;
|
|
|
|
|
this.errorCode = msg.errorCode;
|
|
|
|
|
this.errorMsg = msg.errorMsg;
|
|
|
|
|
this.data = msg.data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public prepareData(keys: string[]) {
|
|
|
|
|
if (!this.data) {
|
|
|
|
|
this.data = {};
|
|
|
|
|
}
|
|
|
|
|
if (keys) {
|
|
|
|
|
keys.forEach((key) => {
|
|
|
|
|
if (!this.data[key]) {
|
|
|
|
|
this.data[key] = [];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public updateAttributeData(origData: Array<AttributeData>): Array<AttributeData> {
|
|
|
|
|
for (const key of Object.keys(this.data)) {
|
|
|
|
|
const keyData = this.data[key];
|
|
|
|
|
if (keyData.length) {
|
|
|
|
|
const existing = origData.find((data) => data.key === key);
|
|
|
|
|
if (existing) {
|
|
|
|
|
existing.lastUpdateTs = keyData[0][0];
|
|
|
|
|
existing.value = keyData[0][1];
|
|
|
|
|
} else {
|
|
|
|
|
origData.push(
|
|
|
|
|
{
|
|
|
|
|
key,
|
|
|
|
|
lastUpdateTs: keyData[0][0],
|
|
|
|
|
value: keyData[0][1]
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return origData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export class CmdUpdate implements CmdUpdateMsg {
|
2020-06-19 18:13:57 +03:00
|
|
|
cmdId: number;
|
|
|
|
|
errorCode: number;
|
|
|
|
|
errorMsg: string;
|
2021-03-02 12:04:45 +02:00
|
|
|
cmdUpdateType: CmdUpdateType;
|
2020-06-19 18:13:57 +03:00
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
constructor(msg: CmdUpdateMsg) {
|
2020-06-19 18:13:57 +03:00
|
|
|
this.cmdId = msg.cmdId;
|
|
|
|
|
this.errorCode = msg.errorCode;
|
|
|
|
|
this.errorMsg = msg.errorMsg;
|
2021-03-02 12:04:45 +02:00
|
|
|
this.cmdUpdateType = msg.cmdUpdateType;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class DataUpdate<T> extends CmdUpdate implements DataUpdateMsg<T> {
|
|
|
|
|
data?: PageData<T>;
|
|
|
|
|
update?: Array<T>;
|
|
|
|
|
|
|
|
|
|
constructor(msg: DataUpdateMsg<T>) {
|
|
|
|
|
super(msg);
|
2020-06-19 18:13:57 +03:00
|
|
|
this.data = msg.data;
|
|
|
|
|
this.update = msg.update;
|
2020-07-03 18:33:06 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class EntityDataUpdate extends DataUpdate<EntityData> {
|
|
|
|
|
constructor(msg: EntityDataUpdateMsg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
}
|
2021-03-17 18:38:57 +02:00
|
|
|
|
2022-09-12 16:20:37 +03:00
|
|
|
private static processEntityData(data: Array<EntityData>, tsOffset: number) {
|
2021-03-17 18:38:57 +02:00
|
|
|
for (const entityData of data) {
|
|
|
|
|
if (entityData.timeseries) {
|
|
|
|
|
for (const key of Object.keys(entityData.timeseries)) {
|
|
|
|
|
const tsValues = entityData.timeseries[key];
|
|
|
|
|
for (const tsValue of tsValues) {
|
2021-03-18 13:51:46 +02:00
|
|
|
if (tsValue.ts) {
|
|
|
|
|
tsValue.ts += tsOffset;
|
|
|
|
|
}
|
2021-03-17 18:38:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (entityData.latest) {
|
|
|
|
|
for (const entityKeyType of Object.keys(entityData.latest)) {
|
|
|
|
|
const keyTypeValues = entityData.latest[entityKeyType];
|
|
|
|
|
for (const key of Object.keys(keyTypeValues)) {
|
|
|
|
|
const tsValue = keyTypeValues[key];
|
2021-03-18 13:51:46 +02:00
|
|
|
if (tsValue.ts) {
|
|
|
|
|
tsValue.ts += tsOffset;
|
|
|
|
|
}
|
|
|
|
|
if (key === entityFields.createdTime.keyName && tsValue.value) {
|
|
|
|
|
tsValue.value = (Number(tsValue.value) + tsOffset) + '';
|
|
|
|
|
}
|
2021-03-17 18:38:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-12 16:20:37 +03:00
|
|
|
|
|
|
|
|
public prepareData(tsOffset: number) {
|
|
|
|
|
if (this.data) {
|
|
|
|
|
EntityDataUpdate.processEntityData(this.data.data, tsOffset);
|
|
|
|
|
}
|
|
|
|
|
if (this.update) {
|
|
|
|
|
EntityDataUpdate.processEntityData(this.update, tsOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-03 18:33:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AlarmDataUpdate extends DataUpdate<AlarmData> {
|
2020-07-10 18:04:48 +03:00
|
|
|
|
2020-07-03 18:33:06 +03:00
|
|
|
constructor(msg: AlarmDataUpdateMsg) {
|
|
|
|
|
super(msg);
|
2020-07-10 18:04:48 +03:00
|
|
|
this.allowedEntities = msg.allowedEntities;
|
|
|
|
|
this.totalEntities = msg.totalEntities;
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
2022-09-12 16:20:37 +03:00
|
|
|
allowedEntities: number;
|
|
|
|
|
totalEntities: number;
|
2021-03-18 13:51:46 +02:00
|
|
|
|
2022-09-12 16:20:37 +03:00
|
|
|
private static processAlarmData(data: Array<AlarmData>, tsOffset: number) {
|
2021-03-18 13:51:46 +02:00
|
|
|
for (const alarmData of data) {
|
|
|
|
|
alarmData.createdTime += tsOffset;
|
|
|
|
|
if (alarmData.ackTs) {
|
|
|
|
|
alarmData.ackTs += tsOffset;
|
|
|
|
|
}
|
|
|
|
|
if (alarmData.clearTs) {
|
|
|
|
|
alarmData.clearTs += tsOffset;
|
|
|
|
|
}
|
|
|
|
|
if (alarmData.endTs) {
|
|
|
|
|
alarmData.endTs += tsOffset;
|
|
|
|
|
}
|
|
|
|
|
if (alarmData.latest) {
|
|
|
|
|
for (const entityKeyType of Object.keys(alarmData.latest)) {
|
|
|
|
|
const keyTypeValues = alarmData.latest[entityKeyType];
|
|
|
|
|
for (const key of Object.keys(keyTypeValues)) {
|
|
|
|
|
const tsValue = keyTypeValues[key];
|
|
|
|
|
if (tsValue.ts) {
|
|
|
|
|
tsValue.ts += tsOffset;
|
|
|
|
|
}
|
|
|
|
|
if (key in [entityFields.createdTime.keyName,
|
|
|
|
|
alarmFields.startTime.keyName,
|
|
|
|
|
alarmFields.endTime.keyName,
|
|
|
|
|
alarmFields.ackTime.keyName,
|
|
|
|
|
alarmFields.clearTime.keyName] && tsValue.value) {
|
|
|
|
|
tsValue.value = (Number(tsValue.value) + tsOffset) + '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-12 16:20:37 +03:00
|
|
|
|
|
|
|
|
public prepareData(tsOffset: number) {
|
|
|
|
|
if (this.data) {
|
|
|
|
|
AlarmDataUpdate.processAlarmData(this.data.data, tsOffset);
|
|
|
|
|
}
|
|
|
|
|
if (this.update) {
|
|
|
|
|
AlarmDataUpdate.processAlarmData(this.update, tsOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-06-19 18:13:57 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
export class EntityCountUpdate extends CmdUpdate {
|
|
|
|
|
count: number;
|
|
|
|
|
|
|
|
|
|
constructor(msg: EntityCountUpdateMsg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
this.count = msg.count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
export class AlarmCountUpdate extends CmdUpdate {
|
|
|
|
|
count: number;
|
|
|
|
|
|
|
|
|
|
constructor(msg: AlarmCountUpdateMsg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
this.count = msg.count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-07 15:11:41 +02:00
|
|
|
export class NotificationCountUpdate extends CmdUpdate {
|
|
|
|
|
totalUnreadCount: number;
|
|
|
|
|
|
|
|
|
|
constructor(msg: NotificationCountUpdateMsg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
this.totalUnreadCount = msg.totalUnreadCount;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class NotificationsUpdate extends CmdUpdate {
|
|
|
|
|
totalUnreadCount: number;
|
|
|
|
|
update?: Notification;
|
|
|
|
|
notifications?: Notification[];
|
|
|
|
|
|
|
|
|
|
constructor(msg: NotificationsUpdateMsg) {
|
|
|
|
|
super(msg);
|
|
|
|
|
this.totalUnreadCount = msg.totalUnreadCount;
|
|
|
|
|
this.update = msg.update;
|
|
|
|
|
this.notifications = msg.notifications;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 12:59:43 +02:00
|
|
|
export class TelemetrySubscriber extends WsSubscriber {
|
2019-08-30 19:19:45 +03:00
|
|
|
|
2020-01-22 20:05:30 +02:00
|
|
|
private dataSubject = new ReplaySubject<SubscriptionUpdate>(1);
|
2020-06-19 18:13:57 +03:00
|
|
|
private entityDataSubject = new ReplaySubject<EntityDataUpdate>(1);
|
2020-07-03 18:33:06 +03:00
|
|
|
private alarmDataSubject = new ReplaySubject<AlarmDataUpdate>(1);
|
2021-03-02 12:04:45 +02:00
|
|
|
private entityCountSubject = new ReplaySubject<EntityCountUpdate>(1);
|
2023-04-21 18:00:56 +03:00
|
|
|
private alarmCountSubject = new ReplaySubject<AlarmCountUpdate>(1);
|
2021-03-18 13:51:46 +02:00
|
|
|
private tsOffset = undefined;
|
2021-03-17 18:38:57 +02:00
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
public data$ = this.dataSubject.asObservable();
|
2020-06-19 18:13:57 +03:00
|
|
|
public entityData$ = this.entityDataSubject.asObservable();
|
2020-07-03 18:33:06 +03:00
|
|
|
public alarmData$ = this.alarmDataSubject.asObservable();
|
2021-03-02 12:04:45 +02:00
|
|
|
public entityCount$ = this.entityCountSubject.asObservable();
|
2023-04-21 18:00:56 +03:00
|
|
|
public alarmCount$ = this.alarmCountSubject.asObservable();
|
2019-08-30 19:19:45 +03:00
|
|
|
|
2023-02-16 12:59:43 +02:00
|
|
|
public static createEntityAttributesSubscription(telemetryService: TelemetryWebsocketService,
|
2019-08-30 19:19:45 +03:00
|
|
|
entityId: EntityId, attributeScope: TelemetryType,
|
2019-11-15 12:22:14 +02:00
|
|
|
zone: NgZone, keys: string[] = null): TelemetrySubscriber {
|
2019-08-30 19:19:45 +03:00
|
|
|
let subscriptionCommand: SubscriptionCmd;
|
|
|
|
|
if (attributeScope === LatestTelemetry.LATEST_TELEMETRY) {
|
|
|
|
|
subscriptionCommand = new TimeseriesSubscriptionCmd();
|
|
|
|
|
} else {
|
|
|
|
|
subscriptionCommand = new AttributesSubscriptionCmd();
|
|
|
|
|
}
|
|
|
|
|
subscriptionCommand.entityType = entityId.entityType as EntityType;
|
|
|
|
|
subscriptionCommand.entityId = entityId.id;
|
|
|
|
|
subscriptionCommand.scope = attributeScope as AttributeScope;
|
|
|
|
|
if (keys) {
|
|
|
|
|
subscriptionCommand.keys = keys.join(',');
|
|
|
|
|
}
|
2021-03-19 11:01:28 +02:00
|
|
|
const subscriber = new TelemetrySubscriber(telemetryService, zone);
|
2019-08-30 19:19:45 +03:00
|
|
|
subscriber.subscriptionCommands.push(subscriptionCommand);
|
|
|
|
|
return subscriber;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-04 17:27:00 +03:00
|
|
|
public static createEntityFilterLatestSubscription(telemetryService: TelemetryWebsocketService,
|
|
|
|
|
entityFilter: EntityFilter, zone: NgZone,
|
|
|
|
|
latestKeys: EntityKey[] = null): TelemetrySubscriber {
|
|
|
|
|
const entityDataQuery: EntityDataQuery = {
|
|
|
|
|
entityFilter,
|
|
|
|
|
pageLink: {
|
|
|
|
|
pageSize: 1,
|
|
|
|
|
page: 0
|
|
|
|
|
},
|
|
|
|
|
latestValues: latestKeys || []
|
|
|
|
|
};
|
|
|
|
|
const cmd = new EntityDataCmd();
|
|
|
|
|
cmd.query = entityDataQuery;
|
|
|
|
|
cmd.latestCmd = {
|
|
|
|
|
keys: latestKeys || []
|
|
|
|
|
};
|
|
|
|
|
const subscriber = new TelemetrySubscriber(telemetryService, zone);
|
|
|
|
|
subscriber.subscriptionCommands.push(cmd);
|
|
|
|
|
return subscriber;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 12:59:43 +02:00
|
|
|
constructor(private telemetryService: TelemetryWebsocketService, protected zone?: NgZone) {
|
|
|
|
|
super(telemetryService, zone);
|
2020-04-09 17:48:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public complete() {
|
2019-08-30 19:19:45 +03:00
|
|
|
this.dataSubject.complete();
|
2020-06-19 18:13:57 +03:00
|
|
|
this.entityDataSubject.complete();
|
2020-07-03 18:33:06 +03:00
|
|
|
this.alarmDataSubject.complete();
|
2021-03-02 12:04:45 +02:00
|
|
|
this.entityCountSubject.complete();
|
2023-04-21 18:00:56 +03:00
|
|
|
this.alarmCountSubject.complete();
|
2023-02-16 12:59:43 +02:00
|
|
|
super.complete();
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-18 13:51:46 +02:00
|
|
|
public setTsOffset(tsOffset: number): boolean {
|
|
|
|
|
if (this.tsOffset !== tsOffset) {
|
|
|
|
|
const changed = !isUndefined(this.tsOffset);
|
|
|
|
|
this.tsOffset = tsOffset;
|
|
|
|
|
return changed;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-03-17 18:38:57 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
public onData(message: SubscriptionUpdate) {
|
|
|
|
|
const cmdId = message.subscriptionId;
|
|
|
|
|
let keys: string[];
|
|
|
|
|
const cmd = this.subscriptionCommands.find((command) => command.cmdId === cmdId);
|
|
|
|
|
if (cmd) {
|
2020-06-19 18:13:57 +03:00
|
|
|
const telemetryPluginCmd = cmd as TelemetryPluginCmd;
|
|
|
|
|
if (telemetryPluginCmd.keys && telemetryPluginCmd.keys.length) {
|
|
|
|
|
keys = telemetryPluginCmd.keys.split(',');
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
message.prepareData(keys);
|
2019-11-15 12:22:14 +02:00
|
|
|
if (this.zone) {
|
|
|
|
|
this.zone.run(
|
|
|
|
|
() => {
|
|
|
|
|
this.dataSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.dataSubject.next(message);
|
|
|
|
|
}
|
2019-08-30 19:19:45 +03:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 18:13:57 +03:00
|
|
|
public onEntityData(message: EntityDataUpdate) {
|
2021-03-17 18:38:57 +02:00
|
|
|
if (this.tsOffset) {
|
|
|
|
|
message.prepareData(this.tsOffset);
|
|
|
|
|
}
|
2020-06-19 18:13:57 +03:00
|
|
|
if (this.zone) {
|
|
|
|
|
this.zone.run(
|
|
|
|
|
() => {
|
|
|
|
|
this.entityDataSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.entityDataSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 18:33:06 +03:00
|
|
|
public onAlarmData(message: AlarmDataUpdate) {
|
2021-03-18 13:51:46 +02:00
|
|
|
if (this.tsOffset) {
|
|
|
|
|
message.prepareData(this.tsOffset);
|
|
|
|
|
}
|
2020-07-03 18:33:06 +03:00
|
|
|
if (this.zone) {
|
|
|
|
|
this.zone.run(
|
|
|
|
|
() => {
|
|
|
|
|
this.alarmDataSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.alarmDataSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:04:45 +02:00
|
|
|
public onEntityCount(message: EntityCountUpdate) {
|
|
|
|
|
if (this.zone) {
|
|
|
|
|
this.zone.run(
|
|
|
|
|
() => {
|
|
|
|
|
this.entityCountSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.entityCountSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 18:00:56 +03:00
|
|
|
public onAlarmCount(message: AlarmCountUpdate) {
|
|
|
|
|
if (this.zone) {
|
|
|
|
|
this.zone.run(
|
|
|
|
|
() => {
|
|
|
|
|
this.alarmCountSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.alarmCountSubject.next(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-30 19:19:45 +03:00
|
|
|
public attributeData$(): Observable<Array<AttributeData>> {
|
|
|
|
|
const attributeData = new Array<AttributeData>();
|
|
|
|
|
return this.data$.pipe(
|
|
|
|
|
map((message) => message.updateAttributeData(attributeData))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|