@flexem/fc-gui 3.0.0-alpha.168 → 3.0.0-alpha.169

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ export interface VariableCommunicator {
10
10
  subscribeVariableState(variableName: string): Observable<VariableState>;
11
11
  subscribeVariableStates(variableNames: Array<string>): Observable<Array<VariableState>>;
12
12
  subscribeUserDeviceAlarms(appId: string): any;
13
+ subscribeUserOneDeviceAlarms(appId: string): any;
13
14
  registerSystemVariableHandler?(variableName: string, getValue: () => Promise<any>, setValue: (value: any) => Promise<void>): void;
14
15
  notifySystemVariableChange?(variableName: string, value: any): void;
15
16
  dispose(): any;
@@ -16,5 +16,6 @@ export declare class PerViewVariableCommunicator implements VariableCommunicator
16
16
  subscribeVariableState(variableName: string): Observable<VariableState>;
17
17
  subscribeVariableStates(variableNames: string[]): Observable<Array<VariableState>>;
18
18
  subscribeUserDeviceAlarms(appId?: string): Observable<any[]>;
19
+ subscribeUserOneDeviceAlarms(appId?: string): Observable<any>;
19
20
  dispose(): void;
20
21
  }
@@ -51,6 +51,12 @@ export class PerViewVariableCommunicator {
51
51
  this.alarmSubscription.push(subscription);
52
52
  });
53
53
  }
54
+ subscribeUserOneDeviceAlarms(appId = '') {
55
+ return new Observable(subscriber => {
56
+ const subscription = this._rawVariableCommunicator.subscribeUserOneDeviceAlarms(appId).subscribe((value) => subscriber.next(value), (error) => subscriber.error(error), () => subscriber.complete());
57
+ this.alarmSubscription.push(subscription);
58
+ });
59
+ }
54
60
  dispose() {
55
61
  forEach(this.variableValuesChangedSubscriptions, s => s.unsubscribe());
56
62
  forEach(this.variableStatesChangedSubscription, s => s.unsubscribe());
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"PerViewVariableCommunicator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../communication","name":"VariableCommunicator","line":15,"character":38}]}],"openVariable":[{"__symbolic":"method"}],"openVariables":[{"__symbolic":"method"}],"write":[{"__symbolic":"method"}],"writeWordByBit":[{"__symbolic":"method"}],"requestVirtualDeviceState":[{"__symbolic":"method"}],"subscribeVariableState":[{"__symbolic":"method"}],"subscribeVariableStates":[{"__symbolic":"method"}],"subscribeUserDeviceAlarms":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"PerViewVariableCommunicator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../communication","name":"VariableCommunicator","line":15,"character":38}]}],"openVariable":[{"__symbolic":"method"}],"openVariables":[{"__symbolic":"method"}],"write":[{"__symbolic":"method"}],"writeWordByBit":[{"__symbolic":"method"}],"requestVirtualDeviceState":[{"__symbolic":"method"}],"subscribeVariableState":[{"__symbolic":"method"}],"subscribeVariableStates":[{"__symbolic":"method"}],"subscribeUserDeviceAlarms":[{"__symbolic":"method"}],"subscribeUserOneDeviceAlarms":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
@@ -17,7 +17,9 @@ export declare class ScrollAlarmElement extends ConditionalDynamicDisplayElement
17
17
  private endTime;
18
18
  private getAlarmDataId;
19
19
  private alarmRefreshThrottleId;
20
- private isWaitingForAlarmRefresh;
20
+ private alarmRefreshSubscription;
21
+ private signalRSubscription;
22
+ private isReplacingContent;
21
23
  private isScrolling;
22
24
  private isDisposed;
23
25
  private isRefreshingCurrentPage;
@@ -36,12 +38,14 @@ export declare class ScrollAlarmElement extends ConditionalDynamicDisplayElement
36
38
  private headerFont;
37
39
  private hasTriedFirstPage;
38
40
  private isSimulateMode;
41
+ private _canvasCtx;
39
42
  constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, alarmsStore: AlarmsStore, signalRAppId: string);
40
43
  dispose(): void;
41
44
  private getAlarmData;
42
45
  private initDisplayContainer;
43
46
  private _buildFontAttrs;
44
47
  private _createSvgTextNode;
48
+ private _measureTextWithCanvas;
45
49
  private _getSvgTextWidth;
46
50
  private _updateUnderlineWidth;
47
51
  private renderNewPage;
@@ -1,4 +1,3 @@
1
- import * as d3 from 'd3';
2
1
  import { ConditionalDynamicDisplayElement } from '../base/conditional-dynamic-display-element';
3
2
  import { GetAlarmsArgs } from '../../config';
4
3
  import * as moment from 'moment';
@@ -15,7 +14,7 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
15
14
  this.alarmsStore = alarmsStore;
16
15
  this.elementStatus = ScrollAlarmElementStatus.Loading;
17
16
  this.alarmNames = [];
18
- this.isWaitingForAlarmRefresh = false; // 是否正在等待刷新(节流期间)
17
+ this.isReplacingContent = false; // 标记是否正在替换内容(防止并发执行)
19
18
  this.isScrolling = false;
20
19
  this.isDisposed = false;
21
20
  this.isRefreshingCurrentPage = false; // 标记是否正在刷新当前页(而不是加载新页)
@@ -31,6 +30,7 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
31
30
  this.isLoadingNextPage = false;
32
31
  this.hasTriedFirstPage = false; // 是否已经尝试加载过第一页
33
32
  this.isSimulateMode = false; // 是否是模拟运行模式
33
+ this._canvasCtx = null;
34
34
  this.rootElement.selectAll('*').remove();
35
35
  this.setStatusAsLoading();
36
36
  this.logger = injector.get(LOGGER_SERVICE_TOKEN);
@@ -54,26 +54,16 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
54
54
  else {
55
55
  // 真实运行模式:使用原有的数据查询逻辑
56
56
  this.updateQueryTimeRange();
57
- // 监听告警更新 (带节流,1秒内只执行一次)
58
- variableCommunicator.subscribeUserDeviceAlarms(signalRAppId).subscribe(alarms => {
59
- alarms.forEach(alarm => {
60
- if (this.alarmNames.indexOf(alarm.name) !== -1) {
61
- // 如果已经在等待刷新,直接返回,避免重复清理和创建定时器
62
- if (this.isWaitingForAlarmRefresh) {
63
- return;
64
- }
65
- // 标记为等待刷新状态
66
- this.isWaitingForAlarmRefresh = true;
67
- // 设置节流定时器,1秒后执行
68
- this.alarmRefreshThrottleId = setTimeout(() => {
69
- // 收到新告警消息,实时替换当前滚动内容,不影响滚动
70
- this.replaceCurrentScrollingContent();
71
- // 重置等待刷新标志
72
- this.isWaitingForAlarmRefresh = false;
73
- }, 1000);
74
- return;
75
- }
76
- });
57
+ // 监听单设备告警更新(防抖:连续推送只取最后一次)
58
+ // 保存订阅对象,dispose 时取消,防止组件销毁后仍触发回调
59
+ this.signalRSubscription = variableCommunicator.subscribeUserOneDeviceAlarms(signalRAppId).subscribe((alarmWithAppId) => {
60
+ const alarm = alarmWithAppId.alarm;
61
+ if (this.alarmNames.indexOf(alarm.name) !== -1) {
62
+ clearTimeout(this.alarmRefreshThrottleId);
63
+ this.alarmRefreshThrottleId = setTimeout(() => {
64
+ this.replaceCurrentScrollingContent();
65
+ }, 300);
66
+ }
77
67
  });
78
68
  // 初始化显示容器
79
69
  this.initDisplayContainer();
@@ -102,10 +92,19 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
102
92
  clearInterval(this.scrollIntervalId);
103
93
  clearTimeout(this.getAlarmDataId);
104
94
  clearTimeout(this.alarmRefreshThrottleId);
95
+ // 取消 HTTP 请求订阅,防止 dispose 后回调仍然操作已卸载的 DOM
96
+ if (this.alarmRefreshSubscription) {
97
+ this.alarmRefreshSubscription.unsubscribe();
98
+ this.alarmRefreshSubscription = null;
99
+ }
100
+ // 取消 SignalR 推送订阅,防止 dispose 后继续触发 replaceCurrentScrollingContent
101
+ if (this.signalRSubscription) {
102
+ this.signalRSubscription.unsubscribe();
103
+ this.signalRSubscription = null;
104
+ }
105
105
  if (this.element && this.element.tooltip) {
106
106
  this.element.tooltip.hidden(true);
107
107
  }
108
- this.logger.debug(`[GUI]Dispose Scroll Alarm Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
109
108
  // 重置所有状态
110
109
  this.isScrolling = false;
111
110
  }
@@ -323,14 +322,35 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
323
322
  }
324
323
  return g;
325
324
  }
325
+ _measureTextWithCanvas(textContent, fontSize, fontFamily, isBold, isItalic) {
326
+ if (!this._canvasCtx) {
327
+ const canvas = document.createElement('canvas');
328
+ this._canvasCtx = canvas.getContext('2d');
329
+ }
330
+ if (!this._canvasCtx) {
331
+ return 0;
332
+ }
333
+ const weight = isBold ? 'bold' : 'normal';
334
+ const style = isItalic ? 'italic' : 'normal';
335
+ this._canvasCtx.font = `${style} ${weight} ${fontSize}px ${fontFamily}`;
336
+ return this._canvasCtx.measureText(textContent).width;
337
+ }
326
338
  _getSvgTextWidth(g) {
339
+ var _a, _b, _c, _d;
327
340
  const text = g.querySelector('text');
328
341
  if (!text) {
329
342
  return 100;
330
343
  }
331
- return text.getComputedTextLength
332
- ? text.getComputedTextLength()
333
- : (text.getBBox ? text.getBBox().width : 100);
344
+ const len = (_b = (_a = text).getComputedTextLength) === null || _b === void 0 ? void 0 : _b.call(_a);
345
+ if (len > 0)
346
+ return len;
347
+ const bbox = (_d = (_c = text).getBBox) === null || _d === void 0 ? void 0 : _d.call(_c);
348
+ if ((bbox === null || bbox === void 0 ? void 0 : bbox.width) > 0)
349
+ return bbox.width;
350
+ // SVG 节点游离于 DOM 外时 getComputedTextLength/getBBox 均返回 0,
351
+ // 改用 Canvas measureText 离屏计算
352
+ const fa = this._buildFontAttrs();
353
+ return this._measureTextWithCanvas(text.textContent || '', fa.fontSize, fa.fontFamily, fa.isBold, fa.isItalic);
334
354
  }
335
355
  _updateUnderlineWidth(g, width) {
336
356
  const underline = g.querySelector('line.text-underline');
@@ -378,7 +398,7 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
378
398
  this.pageWidths.push(pageWidth);
379
399
  this.totalWidth += (this.totalWidth > 0 && pageWidth > 0 ? GAP : 0) + pageWidth;
380
400
  }
381
- _rebaseTextNodes() {
401
+ _rebaseTextNodes(onDone) {
382
402
  const GAP = 80;
383
403
  let x = 0;
384
404
  Array.from(this.allAlarmsContainer.children).forEach(node => {
@@ -390,6 +410,8 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
390
410
  const newTotal = x > 0 ? x - GAP : 0;
391
411
  this.totalWidth = newTotal;
392
412
  this.pageWidths = [newTotal];
413
+ if (onDone)
414
+ onDone();
393
415
  }
394
416
  removeOldestPage() {
395
417
  // 移除最旧的一页数据
@@ -447,8 +469,9 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
447
469
  }
448
470
  else {
449
471
  // 单页循环:重排 x 从 0 开始,currentLeft 重置到右侧
450
- this._rebaseTextNodes();
451
- this.currentLeft = this.model.size.width;
472
+ this._rebaseTextNodes(() => {
473
+ this.currentLeft = this.model.size.width;
474
+ });
452
475
  }
453
476
  }
454
477
  }
@@ -678,6 +701,17 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
678
701
  */
679
702
  replaceCurrentScrollingContent() {
680
703
  var _a, _b;
704
+ // 防止并发执行:如果正在替换内容,直接返回
705
+ if (this.isReplacingContent) {
706
+ return;
707
+ }
708
+ this.isReplacingContent = true;
709
+ // 暂停滚动定时器,防止在内容更新过程中 scrollContent 读取到中间状态导致重叠
710
+ clearInterval(this.scrollIntervalId);
711
+ if (this.alarmRefreshSubscription) {
712
+ this.alarmRefreshSubscription.unsubscribe();
713
+ this.alarmRefreshSubscription = null;
714
+ }
681
715
  // 更新查询时间范围
682
716
  this.updateQueryTimeRange();
683
717
  // 查询所有当前应该显示的数据(查询足够多的数据以确保包含所有新增/删除)
@@ -699,7 +733,7 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
699
733
  : undefined;
700
734
  const input = new GetAlarmsArgs(this.alarmNames, this.startTime, this.endTime, queryCount, 0, // skipCount
701
735
  stateFilter, sorting);
702
- this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
736
+ this.alarmRefreshSubscription = this.alarmsStore.getHistoryAlarms(input).subscribe(result => {
703
737
  if (!result.error && result.items) {
704
738
  const newItems = result.items;
705
739
  // 如果没有数据,清空显示
@@ -718,6 +752,9 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
718
752
  this.currentLeft = this.model.size.width;
719
753
  this.allAlarmsContainer.setAttribute('transform', `translate(${this.currentLeft}, 0)`);
720
754
  }
755
+ this.isReplacingContent = false;
756
+ // 无数据时停止滚动(scrollContent 会因 displayedItems.length === 0 直接返回)
757
+ this.isScrolling = false;
721
758
  return;
722
759
  }
723
760
  // 如果是首次加载或当前没有数据,直接渲染并启动滚动
@@ -734,10 +771,13 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
734
771
  this.currentLeft = this.model.size.width;
735
772
  this.allAlarmsContainer.setAttribute('transform', `translate(${this.currentLeft}, 0)`);
736
773
  this.renderNewPage(newItems);
737
- // 启动滚动
738
- if (!this.isScrolling) {
739
- this.initScrolling();
740
- }
774
+ requestAnimationFrame(() => {
775
+ this._rebaseTextNodes(() => {
776
+ this.isReplacingContent = false;
777
+ this.isScrolling = false;
778
+ this.initScrolling();
779
+ });
780
+ });
741
781
  return;
742
782
  }
743
783
  // 保存当前的滚动位置
@@ -752,10 +792,30 @@ export class ScrollAlarmElement extends ConditionalDynamicDisplayElement {
752
792
  // 更新状态
753
793
  this.displayedItems = newItems;
754
794
  this.hasMoreData = result.totalCount > newItems.length;
755
- // 保持滚动位置不变,继续滚动
756
- this.currentLeft = currentScrollPosition;
757
- this.allAlarmsContainer.setAttribute('transform', `translate(${this.currentLeft}, 0)`);
795
+ // renderNewPage 里 getComputedTextLength 在刚 append 时可能返回 0,
796
+ // 延迟一帧让浏览器完成布局后用 _rebaseTextNodes 修正所有节点位置
797
+ requestAnimationFrame(() => {
798
+ this._rebaseTextNodes(() => {
799
+ // 保持滚动位置不变,内容更新完成后重新启动滚动
800
+ this.currentLeft = currentScrollPosition;
801
+ this.allAlarmsContainer.setAttribute('transform', `translate(${this.currentLeft}, 0)`);
802
+ this.isReplacingContent = false;
803
+ this.isScrolling = false;
804
+ this.initScrolling();
805
+ });
806
+ });
807
+ return;
758
808
  }
809
+ // 重置标志,内容更新完成后重新启动滚动
810
+ this.isReplacingContent = false;
811
+ this.isScrolling = false;
812
+ this.initScrolling();
813
+ }, (error) => {
814
+ // 错误处理:重置标志,恢复滚动
815
+ this.isReplacingContent = false;
816
+ this.isScrolling = false;
817
+ this.initScrolling();
818
+ this.logger.error('Failed to replace scrolling content:', error);
759
819
  });
760
820
  }
761
821
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"ScrollAlarmElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-dynamic-display-element","name":"ConditionalDynamicDisplayElement","line":17,"character":40},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":52,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":53,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":54,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":55,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":56,"character":23},{"__symbolic":"reference","module":"../../config","name":"AlarmsStore","line":57,"character":38},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"getAlarmData":[{"__symbolic":"method"}],"initDisplayContainer":[{"__symbolic":"method"}],"_buildFontAttrs":[{"__symbolic":"method"}],"_createSvgTextNode":[{"__symbolic":"method"}],"_getSvgTextWidth":[{"__symbolic":"method"}],"_updateUnderlineWidth":[{"__symbolic":"method"}],"renderNewPage":[{"__symbolic":"method"}],"_rebaseTextNodes":[{"__symbolic":"method"}],"removeOldestPage":[{"__symbolic":"method"}],"scrollContent":[{"__symbolic":"method"}],"initScrolling":[{"__symbolic":"method"}],"resetToFirstPage":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"setStatusAsNormal":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}],"renderStaticDisplay":[{"__symbolic":"method"}],"initStaticScrolling":[{"__symbolic":"method"}],"scrollStaticContent":[{"__symbolic":"method"}],"replaceCurrentScrollingContent":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"ScrollAlarmElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-dynamic-display-element","name":"ConditionalDynamicDisplayElement","line":16,"character":40},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":54,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":55,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":56,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":57,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":58,"character":23},{"__symbolic":"reference","module":"../../config","name":"AlarmsStore","line":59,"character":38},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"getAlarmData":[{"__symbolic":"method"}],"initDisplayContainer":[{"__symbolic":"method"}],"_buildFontAttrs":[{"__symbolic":"method"}],"_createSvgTextNode":[{"__symbolic":"method"}],"_measureTextWithCanvas":[{"__symbolic":"method"}],"_getSvgTextWidth":[{"__symbolic":"method"}],"_updateUnderlineWidth":[{"__symbolic":"method"}],"renderNewPage":[{"__symbolic":"method"}],"_rebaseTextNodes":[{"__symbolic":"method"}],"removeOldestPage":[{"__symbolic":"method"}],"scrollContent":[{"__symbolic":"method"}],"initScrolling":[{"__symbolic":"method"}],"resetToFirstPage":[{"__symbolic":"method"}],"updateQueryTimeRange":[{"__symbolic":"method"}],"setStatusAsNormal":[{"__symbolic":"method"}],"setStatusAsLoading":[{"__symbolic":"method"}],"renderStatus":[{"__symbolic":"method"}],"clearStatus":[{"__symbolic":"method"}],"renderStaticDisplay":[{"__symbolic":"method"}],"initStaticScrolling":[{"__symbolic":"method"}],"scrollStaticContent":[{"__symbolic":"method"}],"replaceCurrentScrollingContent":[{"__symbolic":"method"}]}}}}]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "main": "bundles/fc-gui.umd.js",
3
- "version": "3.0.0-alpha.168",
3
+ "version": "3.0.0-alpha.169",
4
4
  "module": "public_api.js",
5
5
  "typings": "public_api.d.ts",
6
6
  "license": "UNLICENSED",
@@ -41,6 +41,7 @@ export declare class RemoteVariableCommunicator implements VariableCommunicator
41
41
  write(variableName: string, value: any): Observable<VariableValue>;
42
42
  writeWordByBit(variableName: string, index: number, value: number): Observable<VariableValue>;
43
43
  subscribeUserDeviceAlarms(appId?: string): Observable<any[]>;
44
+ subscribeUserOneDeviceAlarms(appId?: string): Observable<any>;
44
45
  /**
45
46
  * 注册系统变量处理器
46
47
  * @param variableName 变量名(如"当前语种ID")
@@ -351,6 +351,16 @@ export class RemoteVariableCommunicator {
351
351
  };
352
352
  });
353
353
  }
354
+ subscribeUserOneDeviceAlarms(appId = '') {
355
+ return new Observable(observer => {
356
+ const subscription = this.remoteVariableProtocol.historyAlarmChanged.subscribe(value => observer.next(value), error => observer.error(error), () => observer.complete());
357
+ this.remoteVariableProtocol.subscribeUserOneDeviceAlarms(appId);
358
+ return () => {
359
+ subscription.unsubscribe();
360
+ this.remoteVariableProtocol.unsubscribeUserOneDeviceAlarms(appId);
361
+ };
362
+ });
363
+ }
354
364
  /**
355
365
  * 注册系统变量处理器
356
366
  * @param variableName 变量名(如"当前语种ID")
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"RemoteVariableCommunicator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"./remote-variable-protocol","name":"RemoteVariableProtocol","line":38,"character":57},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":38,"character":106}]}],"doAlarmChanged":[{"__symbolic":"method"}],"doVariableValuesChanged":[{"__symbolic":"method"}],"doVirtualDeviceStatesChanged":[{"__symbolic":"method"}],"doVariableStatesChanged":[{"__symbolic":"method"}],"setOfflineValueCache":[{"__symbolic":"method"}],"subscribeVariableStates":[{"__symbolic":"method"}],"subscribeVariableState":[{"__symbolic":"method"}],"requestVirtualDeviceState":[{"__symbolic":"method"}],"openVariables":[{"__symbolic":"method"}],"openVariable":[{"__symbolic":"method"}],"write":[{"__symbolic":"method"}],"writeWordByBit":[{"__symbolic":"method"}],"subscribeUserDeviceAlarms":[{"__symbolic":"method"}],"registerSystemVariableHandler":[{"__symbolic":"method"}],"notifySystemVariableChange":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"RemoteVariableCommunicator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"./remote-variable-protocol","name":"RemoteVariableProtocol","line":38,"character":57},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":38,"character":106}]}],"doAlarmChanged":[{"__symbolic":"method"}],"doVariableValuesChanged":[{"__symbolic":"method"}],"doVirtualDeviceStatesChanged":[{"__symbolic":"method"}],"doVariableStatesChanged":[{"__symbolic":"method"}],"setOfflineValueCache":[{"__symbolic":"method"}],"subscribeVariableStates":[{"__symbolic":"method"}],"subscribeVariableState":[{"__symbolic":"method"}],"requestVirtualDeviceState":[{"__symbolic":"method"}],"openVariables":[{"__symbolic":"method"}],"openVariable":[{"__symbolic":"method"}],"write":[{"__symbolic":"method"}],"writeWordByBit":[{"__symbolic":"method"}],"subscribeUserDeviceAlarms":[{"__symbolic":"method"}],"subscribeUserOneDeviceAlarms":[{"__symbolic":"method"}],"registerSystemVariableHandler":[{"__symbolic":"method"}],"notifySystemVariableChange":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
@@ -15,4 +15,7 @@ export interface RemoteVariableProtocol {
15
15
  unsubscribeVariableStates(variableNames: string[]): Observable<void>;
16
16
  subscribeVirtualDeviceAlarms(appId: string): any;
17
17
  unsubscribeVirtualDeviceAlarms(appId: string): any;
18
+ subscribeUserOneDeviceAlarms(appId: string): any;
19
+ unsubscribeUserOneDeviceAlarms(appId: string): any;
20
+ historyAlarmChanged: Observable<any>;
18
21
  }