@flexem/fc-gui 3.0.0-alpha.18 → 3.0.0-alpha.181

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.
Files changed (194) hide show
  1. package/CHANGELOG.md +419 -1
  2. package/assets/img/black_first_page.png +0 -0
  3. package/assets/img/black_last_page.png +0 -0
  4. package/assets/img/black_next_page.png +0 -0
  5. package/assets/img/black_previous_page.png +0 -0
  6. package/assets/img/exclamation-outline-circle.png +0 -0
  7. package/bundles/@flexem/fc-gui.umd.js +37413 -32291
  8. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  9. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  10. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  11. package/communication/variable/variable-communicator.d.ts +5 -0
  12. package/communication/variable/variable-state-enum.d.ts +1 -0
  13. package/communication/variable/variable-state-enum.js +1 -0
  14. package/communication/variable/variable-state-enum.metadata.json +1 -1
  15. package/communication/variable/variable-value.d.ts +4 -1
  16. package/communication/variable/variable-value.js +4 -1
  17. package/communication/variable/variable-value.metadata.json +1 -1
  18. package/config/alarm/alarm.store.d.ts +6 -0
  19. package/config/alarm/alarm.store.js +0 -0
  20. package/config/alarm/alarm.store.metadata.json +1 -0
  21. package/config/alarm/get-alarms-args.d.ts +12 -0
  22. package/config/alarm/get-alarms-args.js +13 -0
  23. package/config/alarm/get-alarms-args.metadata.json +1 -0
  24. package/config/alarm/index.d.ts +2 -0
  25. package/config/alarm/index.js +1 -0
  26. package/config/alarm/index.metadata.json +1 -0
  27. package/config/config-store.d.ts +2 -0
  28. package/config/gui-feature-config.d.ts +3 -0
  29. package/config/gui-feature-config.js +3 -0
  30. package/config/gui-feature-config.metadata.json +1 -0
  31. package/config/index.d.ts +2 -0
  32. package/config/index.js +2 -0
  33. package/config/index.metadata.json +1 -1
  34. package/config/variable/variable-store.d.ts +1 -0
  35. package/elements/air-quality/air-quality-element.js +3 -4
  36. package/elements/alarm/alarm-element.d.ts +89 -0
  37. package/elements/alarm/alarm-element.js +739 -0
  38. package/elements/alarm/alarm-element.metadata.json +1 -0
  39. package/elements/bar-graph-element.d.ts +10 -2
  40. package/elements/bar-graph-element.js +135 -5
  41. package/elements/bar-graph-element.metadata.json +1 -1
  42. package/elements/base/readable-element.d.ts +6 -1
  43. package/elements/base/readable-element.js +69 -2
  44. package/elements/base/readable-element.metadata.json +1 -1
  45. package/elements/base/state-control-element.d.ts +13 -1
  46. package/elements/base/state-control-element.js +42 -8
  47. package/elements/base/state-control-element.metadata.json +1 -1
  48. package/elements/character-display/character-display-element.d.ts +9 -0
  49. package/elements/character-display/character-display-element.js +18 -2
  50. package/elements/character-display/character-display-element.metadata.json +1 -1
  51. package/elements/datetime-display/datetime-display-element.d.ts +1 -0
  52. package/elements/datetime-display/datetime-display-element.js +10 -2
  53. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  54. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  55. package/elements/datetime-display/time-zone-select-json.js +558 -0
  56. package/elements/historical-curve/historical-curve.element.d.ts +45 -3
  57. package/elements/historical-curve/historical-curve.element.js +722 -45
  58. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  59. package/elements/main-element.d.ts +1 -0
  60. package/elements/main-element.js +71 -9
  61. package/elements/main-element.metadata.json +1 -1
  62. package/elements/meter-element.d.ts +7 -1
  63. package/elements/meter-element.js +76 -7
  64. package/elements/meter-element.metadata.json +1 -1
  65. package/elements/numerical-display/numerical-display-element.d.ts +31 -3
  66. package/elements/numerical-display/numerical-display-element.js +160 -12
  67. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  68. package/elements/per-view-variable-communicator.d.ts +4 -0
  69. package/elements/per-view-variable-communicator.js +21 -1
  70. package/elements/per-view-variable-communicator.metadata.json +1 -1
  71. package/elements/ring-graph/ring-graph-element.d.ts +13 -1
  72. package/elements/ring-graph/ring-graph-element.js +164 -3
  73. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  74. package/elements/scroll-alarm/scroll-alarm-element.d.ts +79 -0
  75. package/elements/scroll-alarm/scroll-alarm-element.js +845 -0
  76. package/elements/scroll-alarm/scroll-alarm-element.metadata.json +1 -0
  77. package/elements/shared/graph/graph-state-element.d.ts +1 -0
  78. package/elements/shared/graph/graph-state-element.js +30 -1
  79. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  80. package/elements/shared/text/text-element.d.ts +14 -0
  81. package/elements/shared/text/text-element.js +42 -4
  82. package/elements/shared/text/text-element.metadata.json +1 -1
  83. package/elements/shared/text/text-state-element.d.ts +39 -2
  84. package/elements/shared/text/text-state-element.js +242 -67
  85. package/elements/shared/text/text-state-element.metadata.json +1 -1
  86. package/elements/static-elements/hyperlink-element.d.ts +28 -2
  87. package/elements/static-elements/hyperlink-element.js +153 -4
  88. package/elements/static-elements/hyperlink-element.metadata.json +1 -1
  89. package/elements/static-elements/text-element.d.ts +28 -2
  90. package/elements/static-elements/text-element.js +162 -12
  91. package/elements/static-elements/text-element.metadata.json +1 -1
  92. package/elements/switch-indicator-light/bit-indicator-light-operator.d.ts +1 -0
  93. package/elements/switch-indicator-light/bit-indicator-light-operator.js +10 -3
  94. package/elements/switch-indicator-light/bit-indicator-light-operator.metadata.json +1 -1
  95. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +20 -2
  96. package/elements/switch-indicator-light/switch-indicator-light-element.js +85 -12
  97. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  98. package/elements/switch-indicator-light/word-indicator-light-operator.d.ts +1 -0
  99. package/elements/switch-indicator-light/word-indicator-light-operator.js +10 -3
  100. package/elements/switch-indicator-light/word-indicator-light-operator.metadata.json +1 -1
  101. package/elements/video/video-element.d.ts +10 -0
  102. package/elements/video/video-element.js +139 -21
  103. package/elements/video/video-element.metadata.json +1 -1
  104. package/elements/view-operation/view-operation.element.d.ts +28 -2
  105. package/elements/view-operation/view-operation.element.js +165 -5
  106. package/elements/view-operation/view-operation.element.metadata.json +1 -1
  107. package/elements/weather/weater-element.js +0 -1
  108. package/gui/gui-context.d.ts +25 -2
  109. package/gui/gui-host.d.ts +1 -1
  110. package/gui/gui-view.d.ts +19 -2
  111. package/gui/gui-view.js +147 -12
  112. package/gui/gui-view.metadata.json +1 -1
  113. package/gui/gui.component.d.ts +3 -0
  114. package/gui/gui.component.js +15 -2
  115. package/gui/gui.component.metadata.json +1 -1
  116. package/localization/localization.service.d.ts +11 -0
  117. package/localization/localization.service.js +16 -5
  118. package/localization/localization.service.metadata.json +1 -1
  119. package/localization/localization.service.zh_CN.js +12 -1
  120. package/localization/localization.service.zh_CN.metadata.json +1 -1
  121. package/modal/write-character/write-character-modal.component.d.ts +3 -2
  122. package/modal/write-character/write-character-modal.component.html +4 -4
  123. package/modal/write-character/write-character-modal.component.js +7 -5
  124. package/modal/write-character/write-character-modal.component.less +15 -0
  125. package/modal/write-character/write-character-modal.component.metadata.json +1 -1
  126. package/modal/write-value/write-value-modal-args.d.ts +5 -1
  127. package/modal/write-value/write-value-modal-args.js +3 -1
  128. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  129. package/modal/write-value/write-value-modal.component.d.ts +15 -8
  130. package/modal/write-value/write-value-modal.component.html +10 -5
  131. package/modal/write-value/write-value-modal.component.js +99 -21
  132. package/modal/write-value/write-value-modal.component.less +16 -1
  133. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  134. package/model/alarm/alarm.model.d.ts +14 -0
  135. package/model/alarm/alarm.model.js +0 -0
  136. package/model/alarm/alarm.model.metadata.json +1 -0
  137. package/model/bar-graph/bar-graph.d.ts +4 -0
  138. package/model/base/font-setting-model.d.ts +22 -1
  139. package/model/base/font-setting-model.metadata.json +1 -1
  140. package/model/base/readable-model.d.ts +4 -0
  141. package/model/character-display/character-display.d.ts +1 -0
  142. package/model/datetime-display/datetime-display.d.ts +1 -0
  143. package/model/historical-curve/historical-curve-axis-settings.d.ts +11 -0
  144. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  145. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  146. package/model/historical-curve/historical-curve-chanel.model.d.ts +8 -0
  147. package/model/historical-curve/historical-curve.display-settings.d.ts +1 -0
  148. package/model/meter/meter.d.ts +4 -0
  149. package/model/numerical-display/numerical-display.d.ts +1 -0
  150. package/model/numerical-display/numerical-operation.d.ts +10 -2
  151. package/model/ring-graph/ring-graph.model.d.ts +8 -0
  152. package/model/scroll-alarm/scroll-alarm.model.d.ts +21 -0
  153. package/model/scroll-alarm/scroll-alarm.model.js +0 -0
  154. package/model/scroll-alarm/scroll-alarm.model.metadata.json +1 -0
  155. package/model/settings/popup/view-popup-location-type.d.ts +2 -1
  156. package/model/settings/popup/view-popup-location-type.js +1 -0
  157. package/model/settings/popup/view-popup-location-type.metadata.json +1 -1
  158. package/model/shared/state/state.d.ts +1 -0
  159. package/model/shared/state/state.js +1 -0
  160. package/model/shared/state/state.metadata.json +1 -1
  161. package/model/shared/text/font.d.ts +1 -1
  162. package/model/shared/text/text.d.ts +3 -0
  163. package/model/switch-indicator-light/switch-indicator-light.d.ts +3 -0
  164. package/model/view-operation/view-operation-element.model.d.ts +7 -1
  165. package/package.json +1 -1
  166. package/public_api.js +1 -0
  167. package/remote/communication/variable/remote-variable-communicator.d.ts +30 -0
  168. package/remote/communication/variable/remote-variable-communicator.js +193 -3
  169. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  170. package/remote/communication/variable/remote-variable-protocol.d.ts +8 -0
  171. package/service/index.d.ts +4 -0
  172. package/service/index.js +1 -0
  173. package/service/index.metadata.json +1 -1
  174. package/service/language.service.d.ts +37 -0
  175. package/service/language.service.js +0 -0
  176. package/service/language.service.metadata.json +1 -0
  177. package/service/released-variable/index.d.ts +1 -0
  178. package/service/released-variable/index.js +0 -0
  179. package/service/released-variable/index.metadata.json +1 -0
  180. package/service/released-variable/released-variable.service.d.ts +4 -0
  181. package/service/released-variable/released-variable.service.js +0 -0
  182. package/service/released-variable/released-variable.service.metadata.json +1 -0
  183. package/service/system-text-library.service.d.ts +77 -0
  184. package/service/system-text-library.service.js +29 -0
  185. package/service/system-text-library.service.metadata.json +1 -0
  186. package/service/text-library.service.d.ts +49 -0
  187. package/service/text-library.service.js +0 -0
  188. package/service/text-library.service.metadata.json +1 -0
  189. package/shared/gui-consts.d.ts +2 -0
  190. package/shared/gui-consts.js +3 -1
  191. package/shared/gui-consts.metadata.json +1 -1
  192. package/utils/data-type/fbox-data-type.service.js +40 -0
  193. package/utils/numerical-operation.service.js +28 -4
  194. package/view/popup-view.service.d.ts +1 -1
@@ -9,6 +9,7 @@ export declare class RemoteVariableCommunicator implements VariableCommunicator
9
9
  private appIdVariablesMap;
10
10
  private connectedSubscription;
11
11
  private variableValuesChangedSubscription;
12
+ private virtualDeviceStatesChangedSubscription;
12
13
  private variablesToBeOpened;
13
14
  private variablesToBeClosed;
14
15
  private variableValueCache;
@@ -17,14 +18,43 @@ export declare class RemoteVariableCommunicator implements VariableCommunicator
17
18
  private variableStateCache;
18
19
  private variableStatesToBeOpened;
19
20
  private variableStatesToBeClosed;
21
+ private alarmObservers;
22
+ private alarmChangedSubscription;
23
+ private systemVariableHandlers;
24
+ private offlineValueCache;
20
25
  constructor(remoteVariableProtocol: RemoteVariableProtocol, logger: LoggerService);
26
+ private doAlarmChanged;
21
27
  private doVariableValuesChanged;
28
+ private doVirtualDeviceStatesChanged;
22
29
  private doVariableStatesChanged;
30
+ /**
31
+ * 预填充离线变量值缓存,由 GuiContext 在组态加载时一次性调用。
32
+ * 若状态推送早于接口返回,变量已在 Offline 状态,则直接推送;
33
+ * 否则缓存等待状态事件到来时推送。
34
+ */
35
+ setOfflineValueCache(variableName: string, value: any): void;
23
36
  subscribeVariableStates(variableNames: string[]): Observable<VariableState[]>;
24
37
  subscribeVariableState(variableName: string): Observable<VariableState>;
38
+ requestVirtualDeviceState(): Observable<void>;
25
39
  openVariables(variableNames: string[], appId?: string): Observable<VariableValue[]>;
26
40
  openVariable(variableName: string, appId?: string): Observable<VariableValue>;
27
41
  write(variableName: string, value: any): Observable<VariableValue>;
28
42
  writeWordByBit(variableName: string, index: number, value: number): Observable<VariableValue>;
43
+ subscribeUserDeviceAlarms(appId?: string): Observable<any[]>;
44
+ subscribeUserOneDeviceAlarms(appId?: string): Observable<any>;
45
+ /**
46
+ * 注册系统变量处理器
47
+ * @param variableName 变量名(如"当前语种ID")
48
+ * @param getValue 获取值的函数
49
+ * @param setValue 设置值的函数
50
+ */
51
+ registerSystemVariableHandler(variableName: string, getValue: () => Promise<any>, setValue: (value: any) => Promise<void>): void;
52
+ /**
53
+ * 通知系统变量值变化
54
+ * 用于在系统变量值改变时通知所有订阅者
55
+ * @param variableName 变量名
56
+ * @param value 新值
57
+ */
58
+ notifySystemVariableChange(variableName: string, value: any): void;
29
59
  dispose(): void;
30
60
  }
@@ -1,7 +1,9 @@
1
1
  import { each, remove, uniq } from 'lodash';
2
2
  import { Observable } from 'rxjs';
3
3
  import { map } from 'rxjs/operators';
4
+ import { VariableStateEnum } from '../../../communication';
4
5
  import { StringifyingMap } from '../../../core';
6
+ import { GuiFeatureConfig } from '../../../config';
5
7
  export class RemoteVariableCommunicator {
6
8
  constructor(remoteVariableProtocol, logger) {
7
9
  this.remoteVariableProtocol = remoteVariableProtocol;
@@ -10,6 +12,11 @@ export class RemoteVariableCommunicator {
10
12
  this.appIdVariablesMap = new Map();
11
13
  this.variableStateObservers = new Map();
12
14
  this.variableStateCache = new Map();
15
+ this.alarmObservers = [];
16
+ // 系统变量处理器
17
+ this.systemVariableHandlers = new Map();
18
+ // 预加载的离线变量最新值缓存(组态加载时一次性填充,推送后即删除)
19
+ this.offlineValueCache = new Map();
13
20
  this.variableValueCache = new StringifyingMap(k => JSON.stringify(k));
14
21
  this.connectedSubscription = this.remoteVariableProtocol.connected.subscribe(() => {
15
22
  const variableNamesToStart = [];
@@ -23,6 +30,18 @@ export class RemoteVariableCommunicator {
23
30
  });
24
31
  this.doVariableStatesChanged();
25
32
  this.doVariableValuesChanged();
33
+ this.doVirtualDeviceStatesChanged();
34
+ this.doAlarmChanged();
35
+ }
36
+ doAlarmChanged() {
37
+ if (this.alarmChangedSubscription !== undefined) {
38
+ this.alarmChangedSubscription.unsubscribe();
39
+ }
40
+ this.alarmChangedSubscription = this.remoteVariableProtocol.virtualDeviceAlarmsChanged.subscribe((alarms) => {
41
+ each(this.alarmObservers, ob => {
42
+ ob.next(alarms);
43
+ });
44
+ });
26
45
  }
27
46
  doVariableValuesChanged() {
28
47
  if (this.variableValuesChangedSubscription !== undefined) {
@@ -42,6 +61,25 @@ export class RemoteVariableCommunicator {
42
61
  });
43
62
  });
44
63
  }
64
+ doVirtualDeviceStatesChanged() {
65
+ if (this.virtualDeviceStatesChangedSubscription !== undefined) {
66
+ this.virtualDeviceStatesChangedSubscription.unsubscribe();
67
+ }
68
+ this.virtualDeviceStatesChangedSubscription =
69
+ this.remoteVariableProtocol.virtualDeviceStatesChanged.subscribe((deviceStates) => {
70
+ each(deviceStates, deviceState => {
71
+ const variableName = '设备状态';
72
+ this.variableValueCache.set(variableName, deviceState);
73
+ const data = Object.assign(Object.assign({}, deviceState), { systemName: '设备状态' });
74
+ if (this.observers.has(variableName)) {
75
+ each(this.observers.get(variableName), ob => {
76
+ // TODO 同一个ob监听多个变量的情况,组合成数组一次推送。
77
+ ob.next([data]);
78
+ });
79
+ }
80
+ });
81
+ });
82
+ }
45
83
  doVariableStatesChanged() {
46
84
  if (this.variableStatesChangedSubscription !== undefined) {
47
85
  this.variableStatesChangedSubscription.unsubscribe();
@@ -53,13 +91,69 @@ export class RemoteVariableCommunicator {
53
91
  this.variableStateCache.set(variableName, state);
54
92
  if (this.variableStateObservers.has(variableName)) {
55
93
  each(this.variableStateObservers.get(variableName), ob => {
56
- // TODO 同一个ob监听多个变量的情况,组合成数组一次推送。
57
94
  ob.next([state]);
58
95
  });
59
96
  }
97
+ // 离线时推送最后已知值给值订阅者
98
+ if (GuiFeatureConfig.isOfflineDisplayEnabled && state.state === VariableStateEnum.Offline) {
99
+ let cachedValue;
100
+ // 优先用最后一次收到的值(可能是在线时推送的),覆盖所有切页/重连场景
101
+ if (this.variableValueCache.has(variableName)) {
102
+ cachedValue = this.variableValueCache.get(variableName).value;
103
+ }
104
+ else if (this.offlineValueCache.has(variableName)) {
105
+ // 兜底:变量从未收到过值,用预加载的离线值
106
+ cachedValue = this.offlineValueCache.get(variableName);
107
+ }
108
+ if (cachedValue !== null && cachedValue !== undefined) {
109
+ const variableValue = {
110
+ variableName,
111
+ value: cachedValue,
112
+ state: VariableStateEnum.Offline
113
+ };
114
+ this.variableValueCache.set(variableName, variableValue);
115
+ if (this.observers.has(variableName)) {
116
+ each(this.observers.get(variableName), ob => {
117
+ ob.next([variableValue]);
118
+ });
119
+ }
120
+ }
121
+ }
60
122
  });
61
123
  });
62
124
  }
125
+ /**
126
+ * 预填充离线变量值缓存,由 GuiContext 在组态加载时一次性调用。
127
+ * 若状态推送早于接口返回,变量已在 Offline 状态,则直接推送;
128
+ * 否则缓存等待状态事件到来时推送。
129
+ */
130
+ setOfflineValueCache(variableName, value) {
131
+ if (!GuiFeatureConfig.isOfflineDisplayEnabled) {
132
+ return;
133
+ }
134
+ if (value === null || value === undefined) {
135
+ return;
136
+ }
137
+ const cachedState = this.variableStateCache.get(variableName);
138
+ if (cachedState && cachedState.state === VariableStateEnum.Offline) {
139
+ // 状态已推送过,直接补推值给订阅者
140
+ const variableValue = {
141
+ variableName,
142
+ value,
143
+ state: VariableStateEnum.Offline
144
+ };
145
+ this.variableValueCache.set(variableName, variableValue);
146
+ if (this.observers.has(variableName)) {
147
+ each(this.observers.get(variableName), ob => {
148
+ ob.next([variableValue]);
149
+ });
150
+ }
151
+ }
152
+ else {
153
+ // 状态还未推送,先缓存,等待状态事件
154
+ this.offlineValueCache.set(variableName, value);
155
+ }
156
+ }
63
157
  subscribeVariableStates(variableNames) {
64
158
  return new Observable(observer => {
65
159
  let variableNamesToStart = [];
@@ -115,6 +209,9 @@ export class RemoteVariableCommunicator {
115
209
  subscribeVariableState(variableName) {
116
210
  return this.subscribeVariableStates([variableName]).pipe(map(values => values[0]));
117
211
  }
212
+ requestVirtualDeviceState() {
213
+ return this.remoteVariableProtocol.requestVirtualDeviceState();
214
+ }
118
215
  openVariables(variableNames, appId = '') {
119
216
  return new Observable(observer => {
120
217
  let variablesToStart = [];
@@ -140,7 +237,33 @@ export class RemoteVariableCommunicator {
140
237
  }
141
238
  }
142
239
  });
143
- variablesToStart = uniq(variablesToStart);
240
+ // 过滤掉系统变量,它们不需要通过SignalR订阅
241
+ const normalVariables = variablesToStart.filter(v => !this.systemVariableHandlers.has(v));
242
+ const systemVariables = variablesToStart.filter(v => this.systemVariableHandlers.has(v));
243
+ // 处理系统变量的初始值
244
+ systemVariables.forEach(variableName => {
245
+ const handler = this.systemVariableHandlers.get(variableName);
246
+ if (handler && handler.getValue) {
247
+ void handler.getValue().then(value => {
248
+ const variableValue = {
249
+ variableName: variableName,
250
+ value: value,
251
+ state: 1 // Normal state
252
+ };
253
+ this.variableValueCache.set(variableName, variableValue);
254
+ if (this.observers.has(variableName)) {
255
+ each(this.observers.get(variableName), ob => {
256
+ ob.next([variableValue]);
257
+ });
258
+ }
259
+ }).catch(error => {
260
+ if (this.logger) {
261
+ this.logger.error(`[RemoteVariableCommunicator] Failed to get system variable "${variableName}" value:`, error);
262
+ }
263
+ });
264
+ }
265
+ });
266
+ variablesToStart = uniq(normalVariables);
144
267
  if (variablesToStart && variablesToStart.length > 0) {
145
268
  if (!this.variablesToBeOpened) {
146
269
  this.variablesToBeOpened = [];
@@ -185,8 +308,24 @@ export class RemoteVariableCommunicator {
185
308
  }
186
309
  write(variableName, value) {
187
310
  if (!variableName) {
188
- return;
311
+ return new Observable(observer => {
312
+ observer.complete();
313
+ });
189
314
  }
315
+ // 检查是否为系统变量
316
+ if (this.systemVariableHandlers.has(variableName)) {
317
+ const handler = this.systemVariableHandlers.get(variableName);
318
+ // 调用系统变量的setValue处理器
319
+ void handler.setValue(value).catch(error => {
320
+ if (this.logger) {
321
+ this.logger.error('[RemoteVariableCommunicator] Failed to set system variable value:', error);
322
+ }
323
+ });
324
+ return new Observable(__ => {
325
+ /* 系统变量通过自己的机制通知变化 */
326
+ });
327
+ }
328
+ // 普通变量通过SignalR写入
190
329
  this.remoteVariableProtocol.writeVariable(variableName, value);
191
330
  return new Observable(__ => {
192
331
  /* do nothing right now, if want value change immediately, can use this code below:
@@ -203,11 +342,62 @@ export class RemoteVariableCommunicator {
203
342
  observer.next(new VariableValue(variable, VariableStateEnum.DataNormal, value))*/
204
343
  });
205
344
  }
345
+ subscribeUserDeviceAlarms(appId = '') {
346
+ return new Observable(observer => {
347
+ this.alarmObservers.push(observer);
348
+ this.remoteVariableProtocol.subscribeVirtualDeviceAlarms(appId);
349
+ return () => {
350
+ this.remoteVariableProtocol.unsubscribeVirtualDeviceAlarms(appId);
351
+ };
352
+ });
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
+ }
364
+ /**
365
+ * 注册系统变量处理器
366
+ * @param variableName 变量名(如"当前语种ID")
367
+ * @param getValue 获取值的函数
368
+ * @param setValue 设置值的函数
369
+ */
370
+ registerSystemVariableHandler(variableName, getValue, setValue) {
371
+ this.systemVariableHandlers.set(variableName, { getValue, setValue });
372
+ }
373
+ /**
374
+ * 通知系统变量值变化
375
+ * 用于在系统变量值改变时通知所有订阅者
376
+ * @param variableName 变量名
377
+ * @param value 新值
378
+ */
379
+ notifySystemVariableChange(variableName, value) {
380
+ const variableValue = {
381
+ variableName: variableName,
382
+ value: value,
383
+ state: 1 // Normal state
384
+ };
385
+ // 更新缓存
386
+ this.variableValueCache.set(variableName, variableValue);
387
+ // 通知所有订阅者
388
+ if (this.observers.has(variableName)) {
389
+ each(this.observers.get(variableName), ob => {
390
+ ob.next([variableValue]);
391
+ });
392
+ }
393
+ }
206
394
  dispose() {
207
395
  // TODO调用所有的ob.complete()。
208
396
  this.connectedSubscription.unsubscribe();
209
397
  this.variableStatesChangedSubscription.unsubscribe();
210
398
  this.variableValuesChangedSubscription.unsubscribe();
399
+ this.virtualDeviceStatesChangedSubscription.unsubscribe();
400
+ this.alarmChangedSubscription.unsubscribe();
211
401
  if (this.logger && this.logger.isDebugEnabled()) {
212
402
  this.logger.debug('[VariableCommunicator] RemoteVariableCommunicator disposed.');
213
403
  }
@@ -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":24,"character":57},{"__symbolic":"reference","module":"../../../logger","name":"LoggerService","line":24,"character":106}]}],"doVariableValuesChanged":[{"__symbolic":"method"}],"doVariableStatesChanged":[{"__symbolic":"method"}],"subscribeVariableStates":[{"__symbolic":"method"}],"subscribeVariableState":[{"__symbolic":"method"}],"openVariables":[{"__symbolic":"method"}],"openVariable":[{"__symbolic":"method"}],"write":[{"__symbolic":"method"}],"writeWordByBit":[{"__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"}]}}}}]
@@ -4,10 +4,18 @@ export interface RemoteVariableProtocol {
4
4
  connected: Observable<void>;
5
5
  variableStatesChanged: Observable<VariableValue[]>;
6
6
  variableValuesChanged: Observable<VariableValue[]>;
7
+ virtualDeviceAlarmsChanged: Observable<any>;
7
8
  tryOpenVariables(variableNames: string[], appId: string): Observable<void>;
8
9
  tryStopVariables(variableNames: string[], appId: string): Observable<void>;
9
10
  writeVariable(variableName: string, value: any): Observable<void>;
10
11
  writeVariableWordByBit(variableName: string, index: number, value: number): Observable<void>;
12
+ requestVirtualDeviceState(): Observable<void>;
13
+ virtualDeviceStatesChanged: Observable<any>;
11
14
  subscribeVariableStates(variableNames: string[]): Observable<void>;
12
15
  unsubscribeVariableStates(variableNames: string[]): Observable<void>;
16
+ subscribeVirtualDeviceAlarms(appId: string): any;
17
+ unsubscribeVirtualDeviceAlarms(appId: string): any;
18
+ subscribeUserOneDeviceAlarms(appId: string): any;
19
+ unsubscribeUserOneDeviceAlarms(appId: string): any;
20
+ historyAlarmChanged: Observable<any>;
13
21
  }
@@ -1,4 +1,8 @@
1
1
  export { WeatherService } from './weather.service';
2
2
  export { PermissionChecker } from './permission-checker';
3
+ export { ReleasedVariableService } from './released-variable';
3
4
  export * from './operation-record';
4
5
  export * from './video';
6
+ export * from './text-library.service';
7
+ export * from './language.service';
8
+ export * from './system-text-library.service';
package/service/index.js CHANGED
@@ -0,0 +1 @@
1
+ export * from './system-text-library.service';
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{},"exports":[{"from":"./weather.service","export":["WeatherService"]},{"from":"./permission-checker","export":["PermissionChecker"]},{"from":"./operation-record"},{"from":"./video"}]}]
1
+ [{"__symbolic":"module","version":4,"metadata":{},"exports":[{"from":"./weather.service","export":["WeatherService"]},{"from":"./permission-checker","export":["PermissionChecker"]},{"from":"./released-variable","export":["ReleasedVariableService"]},{"from":"./operation-record"},{"from":"./video"},{"from":"./text-library.service"},{"from":"./language.service"},{"from":"./system-text-library.service"}]}]
@@ -0,0 +1,37 @@
1
+ import { Observable } from 'rxjs';
2
+ /**
3
+ * 语种 DTO 接口 - 与 Designer 中的 API 返回格式保持一致
4
+ */
5
+ export interface ConfigureLanguageDto {
6
+ name: string;
7
+ displayName: string;
8
+ icon: string;
9
+ isDefault: boolean;
10
+ isSystem: boolean;
11
+ }
12
+ /**
13
+ * 语种服务接口
14
+ * 提供语种的查询能力,供 GUI 组件使用
15
+ */
16
+ export interface LanguageService {
17
+ /**
18
+ * 获取所有语种
19
+ */
20
+ getLanguages(): ConfigureLanguageDto[];
21
+ /**
22
+ * 获取默认语言代码
23
+ */
24
+ getDefaultLanguage(): string;
25
+ /**
26
+ * 根据语种代码获取语种信息
27
+ */
28
+ getLanguageByCode(code: string): ConfigureLanguageDto | null;
29
+ /**
30
+ * 检查是否有缓存数据
31
+ */
32
+ hasCache(): boolean;
33
+ /**
34
+ * 缓存更新事件 (可选)
35
+ */
36
+ readonly cacheUpdated?: Observable<void>;
37
+ }
File without changes
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"ConfigureLanguageDto":{"__symbolic":"interface"},"LanguageService":{"__symbolic":"interface"}}}]
@@ -0,0 +1 @@
1
+ export { ReleasedVariableService } from './released-variable.service';
File without changes
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{},"exports":[{"from":"./released-variable.service","export":["ReleasedVariableService"]}]}]
@@ -0,0 +1,4 @@
1
+ import { Observable } from 'rxjs';
2
+ export interface ReleasedVariableService {
3
+ getVariableWithValueTransform(variableName: any): Observable<any>;
4
+ }
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"ReleasedVariableService":{"__symbolic":"interface"}}}]
@@ -0,0 +1,77 @@
1
+ import { Observable } from 'rxjs';
2
+ /**
3
+ * 系统文本条目接口
4
+ */
5
+ export interface SystemTextEntry {
6
+ key: string;
7
+ value: string;
8
+ referenceLocation: string;
9
+ isKeyReadOnly: boolean;
10
+ cultures: {
11
+ [key: string]: string;
12
+ };
13
+ }
14
+ /**
15
+ * 系统文本库缓存数据接口
16
+ */
17
+ export interface SystemTextLibraryCacheData {
18
+ id: number;
19
+ name: string;
20
+ systemType: string;
21
+ data: SystemTextEntry[];
22
+ }
23
+ /**
24
+ * 系统文本库类型常量
25
+ */
26
+ export declare const SYSTEM_TEXT_LIBRARY_TYPES: {
27
+ COMPONENT_BUILTIN: string;
28
+ };
29
+ /**
30
+ * 告警表表头 key 常量
31
+ */
32
+ export declare const ALARM_TABLE_HEADER_KEYS: {
33
+ ALARM_NAME: string;
34
+ ALARM_MESSAGE: string;
35
+ ALARM_LEVEL: string;
36
+ TIME: string;
37
+ };
38
+ /**
39
+ * 时间段 key 常量(用于告警表和历史曲线下拉选择)
40
+ * 对应 localization 中的: lastThirtyMinutes, lastOneHour, lastEightHour, lastTwentyFourHours, lastSevenDays, lastThirtyDays, lastOneYear
41
+ */
42
+ export declare const TIME_PERIOD_KEYS: {
43
+ LAST_THIRTY_MINUTES: string;
44
+ LAST_ONE_HOUR: string;
45
+ LAST_EIGHT_HOURS: string;
46
+ LAST_TWENTY_FOUR_HOURS: string;
47
+ LAST_SEVEN_DAYS: string;
48
+ LAST_THIRTY_DAYS: string;
49
+ LAST_ONE_YEAR: string;
50
+ CUSTOM: string;
51
+ };
52
+ /**
53
+ * 系统文本库服务接口
54
+ * 提供系统文本库的查询能力,供 GUI 组件使用
55
+ */
56
+ export interface SystemTextLibraryService {
57
+ /**
58
+ * 根据 systemType 获取系统文本库
59
+ */
60
+ getSystemTextLibrary(systemType: string): SystemTextLibraryCacheData | null;
61
+ /**
62
+ * 根据 systemType 和 key 获取系统文本条目
63
+ */
64
+ getSystemTextEntry(systemType: string, entryKey: string): SystemTextEntry | null;
65
+ /**
66
+ * 根据 systemType、key 和语言获取系统文本值
67
+ */
68
+ getSystemTextValue(systemType: string, entryKey: string, culture?: string): string | null;
69
+ /**
70
+ * 检查系统文本库缓存是否存在
71
+ */
72
+ hasSystemTextLibraryCache(systemType: string): boolean;
73
+ /**
74
+ * 缓存更新事件 (可选)
75
+ */
76
+ readonly cacheUpdated?: Observable<void>;
77
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 系统文本库类型常量
3
+ */
4
+ export const SYSTEM_TEXT_LIBRARY_TYPES = {
5
+ COMPONENT_BUILTIN: 'ComponentBuiltIn'
6
+ };
7
+ /**
8
+ * 告警表表头 key 常量
9
+ */
10
+ export const ALARM_TABLE_HEADER_KEYS = {
11
+ ALARM_NAME: 'AlarmTable.Header.AlarmName',
12
+ ALARM_MESSAGE: 'AlarmTable.Header.AlarmMessage',
13
+ ALARM_LEVEL: 'AlarmTable.Header.AlarmLevel',
14
+ TIME: 'AlarmTable.Header.Time'
15
+ };
16
+ /**
17
+ * 时间段 key 常量(用于告警表和历史曲线下拉选择)
18
+ * 对应 localization 中的: lastThirtyMinutes, lastOneHour, lastEightHour, lastTwentyFourHours, lastSevenDays, lastThirtyDays, lastOneYear
19
+ */
20
+ export const TIME_PERIOD_KEYS = {
21
+ LAST_THIRTY_MINUTES: 'HistoricalCurve.TimeFilter.Last30Minutes',
22
+ LAST_ONE_HOUR: 'HistoricalCurve.TimeFilter.Last1Hour',
23
+ LAST_EIGHT_HOURS: 'HistoricalCurve.TimeFilter.Last8Hours',
24
+ LAST_TWENTY_FOUR_HOURS: 'HistoricalCurve.TimeFilter.Last24Hours',
25
+ LAST_SEVEN_DAYS: 'HistoricalCurve.TimeFilter.Last7Days',
26
+ LAST_THIRTY_DAYS: 'HistoricalCurve.TimeFilter.Last30Days',
27
+ LAST_ONE_YEAR: 'HistoricalCurve.TimeFilter.Last1Year',
28
+ CUSTOM: 'HistoricalCurve.TimeFilter.Custom'
29
+ };
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"SystemTextEntry":{"__symbolic":"interface"},"SystemTextLibraryCacheData":{"__symbolic":"interface"},"SYSTEM_TEXT_LIBRARY_TYPES":{"COMPONENT_BUILTIN":"ComponentBuiltIn"},"ALARM_TABLE_HEADER_KEYS":{"ALARM_NAME":"AlarmTable.Header.AlarmName","ALARM_MESSAGE":"AlarmTable.Header.AlarmMessage","ALARM_LEVEL":"AlarmTable.Header.AlarmLevel","TIME":"AlarmTable.Header.Time"},"TIME_PERIOD_KEYS":{"LAST_THIRTY_MINUTES":"HistoricalCurve.TimeFilter.Last30Minutes","LAST_ONE_HOUR":"HistoricalCurve.TimeFilter.Last1Hour","LAST_EIGHT_HOURS":"HistoricalCurve.TimeFilter.Last8Hours","LAST_TWENTY_FOUR_HOURS":"HistoricalCurve.TimeFilter.Last24Hours","LAST_SEVEN_DAYS":"HistoricalCurve.TimeFilter.Last7Days","LAST_THIRTY_DAYS":"HistoricalCurve.TimeFilter.Last30Days","LAST_ONE_YEAR":"HistoricalCurve.TimeFilter.Last1Year","CUSTOM":"HistoricalCurve.TimeFilter.Custom"},"SystemTextLibraryService":{"__symbolic":"interface"}}}]
@@ -0,0 +1,49 @@
1
+ import { Observable } from 'rxjs';
2
+ /**
3
+ * 文本条目接口
4
+ */
5
+ export interface TextEntry {
6
+ key: string;
7
+ value: string;
8
+ cultures: {
9
+ [key: string]: string;
10
+ };
11
+ }
12
+ /**
13
+ * 文本库缓存数据接口
14
+ */
15
+ export interface TextLibraryCacheData {
16
+ id: number;
17
+ name: string;
18
+ data: TextEntry[];
19
+ }
20
+ /**
21
+ * 文本库服务接口
22
+ * 提供文本库的查询能力,供 GUI 组件使用
23
+ */
24
+ export interface TextLibraryService {
25
+ /**
26
+ * 获取所有文本库
27
+ */
28
+ getAllTextLibraries(): TextLibraryCacheData[];
29
+ /**
30
+ * 根据ID获取文本库
31
+ */
32
+ getTextLibraryById(id: number): TextLibraryCacheData | null;
33
+ /**
34
+ * 根据文本库ID和条目key获取文本条目
35
+ */
36
+ getTextEntry(textLibraryId: number, entryKey: string): TextEntry | null;
37
+ /**
38
+ * 根据文本库ID、条目key和语言获取文本值
39
+ */
40
+ getTextValue(textLibraryId: number, entryKey: string, culture?: string): string | null;
41
+ /**
42
+ * 检查是否有缓存数据
43
+ */
44
+ hasCache(): boolean;
45
+ /**
46
+ * 缓存更新事件 (可选)
47
+ */
48
+ readonly cacheUpdated?: Observable<void>;
49
+ }
File without changes
@@ -0,0 +1 @@
1
+ [{"__symbolic":"module","version":4,"metadata":{"TextEntry":{"__symbolic":"interface"},"TextLibraryCacheData":{"__symbolic":"interface"},"TextLibraryService":{"__symbolic":"interface"}}}]
@@ -27,5 +27,7 @@ export declare class GuiConsts {
27
27
  tableKey: string;
28
28
  weatherKey: string;
29
29
  airQualityKey: string;
30
+ alarmKey: string;
31
+ scrollAlarmKey: string;
30
32
  };
31
33
  }
@@ -27,5 +27,7 @@ GuiConsts.components = {
27
27
  videokey: 'Video',
28
28
  tableKey: 'Table',
29
29
  weatherKey: 'Weather',
30
- airQualityKey: 'AirQualityIndex'
30
+ airQualityKey: 'AirQualityIndex',
31
+ alarmKey: 'Alarm',
32
+ scrollAlarmKey: 'ScrollAlarm'
31
33
  };
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"GuiConsts":{"__symbolic":"class","statics":{"components":{"imageKey":"Image","numericalDisplayKey":"NumericalDisplay","textKey":"Text","hyperlinkKey":"Hyperlink","meterKey":"Meter","pipeKey":"Pipe","switchIndicatorLightKey":"SwitchIndicatorLight","barGraphKey":"BarGraph","toggleViewKey":"ToggleView","characterKey":"Character","straightLineKey":"StraightLine","polyLineKey":"PolyLine","rectangleKey":"Rectangle","sectorkey":"Sector","ellipseKey":"Ellipse","datetimeDisplayKey":"DatetimeDisplay","historicalCurveKey":"HistoricalCurve","ringGraphKey":"RingGraph","viewOperationElement":"ViewOperation","polygonKey":"Polygon","videokey":"Video","tableKey":"Table","weatherKey":"Weather","airQualityKey":"AirQualityIndex"}}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"GuiConsts":{"__symbolic":"class","statics":{"components":{"imageKey":"Image","numericalDisplayKey":"NumericalDisplay","textKey":"Text","hyperlinkKey":"Hyperlink","meterKey":"Meter","pipeKey":"Pipe","switchIndicatorLightKey":"SwitchIndicatorLight","barGraphKey":"BarGraph","toggleViewKey":"ToggleView","characterKey":"Character","straightLineKey":"StraightLine","polyLineKey":"PolyLine","rectangleKey":"Rectangle","sectorkey":"Sector","ellipseKey":"Ellipse","datetimeDisplayKey":"DatetimeDisplay","historicalCurveKey":"HistoricalCurve","ringGraphKey":"RingGraph","viewOperationElement":"ViewOperation","polygonKey":"Polygon","videokey":"Video","tableKey":"Table","weatherKey":"Weather","airQualityKey":"AirQualityIndex","alarmKey":"Alarm","scrollAlarmKey":"ScrollAlarm"}}}}}]