@honor-claw/yoyo 0.0.1-beta.2 → 0.0.1-beta.21
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.
- package/index.ts +2 -2
- package/openclaw.plugin.json +7 -0
- package/package.json +20 -20
- package/skills/search/SKILL.md +182 -0
- package/skills/search/scripts/search.sh +69 -0
- package/skills/yoyo-control/SKILL.md +105 -120
- package/skills/yoyo-control/references/alarm-create.md +473 -0
- package/skills/yoyo-control/references/app-close.md +183 -0
- package/skills/yoyo-control/references/app-open.md +178 -0
- package/skills/yoyo-control/references/call-phone.md +250 -0
- package/skills/yoyo-control/references/capture-screenshot.md +205 -54
- package/skills/yoyo-control/references/contact-search.md +235 -0
- package/skills/yoyo-control/references/hotspot.md +208 -0
- package/skills/yoyo-control/references/local-search.md +224 -15
- package/skills/yoyo-control/references/message-send.md +246 -0
- package/skills/yoyo-control/references/mobile-data.md +248 -0
- package/skills/yoyo-control/references/no-disturb.md +239 -0
- package/skills/yoyo-control/references/quiet-mode.md +228 -0
- package/skills/yoyo-control/references/ringing-mode.md +223 -0
- package/skills/yoyo-control/references/screen-record.md +220 -0
- package/skills/yoyo-control/references/vibration-mode.md +235 -0
- package/skills/yoyo-control/references/volume-operate.md +274 -0
- package/skills/yoyo-control/scripts/invoke.js +33 -111
- package/src/agent/copy-templates.ts +56 -0
- package/src/agent/index.ts +3 -0
- package/src/agent/templates/AGENTS.md +223 -0
- package/src/apis/claw-cloud.ts +70 -23
- package/src/apis/honor-auth.ts +20 -10
- package/src/apis/types.ts +24 -1
- package/src/cloud-channel/channel.ts +245 -58
- package/src/cloud-channel/client.ts +87 -12
- package/src/cloud-channel/types.ts +30 -0
- package/src/commands/env/impl.ts +58 -0
- package/src/commands/env/index.ts +1 -0
- package/src/commands/index.ts +11 -1
- package/src/commands/login/impl.ts +17 -8
- package/src/commands/logout/impl.ts +23 -0
- package/src/commands/logout/index.ts +1 -53
- package/src/commands/status/index.ts +172 -42
- package/src/gateway-client/client.deprecated.ts +1 -1
- package/src/gateway-client/client.ts +15 -20
- package/src/gateway-client/types.ts +2 -2
- package/src/honor-auth/browser.ts +12 -15
- package/src/honor-auth/callback-server.ts +3 -6
- package/src/honor-auth/cloud.ts +65 -12
- package/src/honor-auth/config.ts +25 -17
- package/src/honor-auth/index.ts +1 -0
- package/src/honor-auth/token-manager.ts +24 -14
- package/src/modules/claw-configs/config-manager.ts +211 -11
- package/src/modules/claw-configs/hosts.ts +48 -0
- package/src/modules/claw-configs/index.ts +1 -0
- package/src/modules/claw-configs/types.ts +4 -0
- package/src/modules/device/device-info.ts +20 -9
- package/src/modules/device/providers/linux.ts +128 -0
- package/src/modules/device/providers/macos.ts +123 -0
- package/src/modules/device/providers/pad.ts +0 -16
- package/src/modules/device/registry.ts +12 -3
- package/src/modules/login/impl.ts +38 -16
- package/src/runtime.ts +44 -0
- package/src/schemas.ts +4 -1
- package/src/services/connection/impl.ts +89 -9
- package/src/services/connection/status-tracker/events.ts +127 -0
- package/src/services/connection/status-tracker/index.ts +31 -0
- package/src/services/connection/status-tracker/storage.ts +133 -0
- package/src/services/connection/status-tracker/tracker.ts +370 -0
- package/src/services/connection/status-tracker/types.ts +131 -0
- package/src/types.ts +0 -4
- package/src/utils/fs-safe.ts +544 -0
- package/src/utils/version.ts +29 -0
- package/src/utils/ws.ts +21 -0
- package/skills/yoyo-control/references/open-app.md +0 -54
- package/skills/yoyo-control/references/phone-call.md +0 -217
- package/skills/yoyo-control/references/schedule.md +0 -107
- package/skills/yoyo-control/references/screen-recorder.md +0 -67
- package/skills/yoyo-control/references/search-contact.md +0 -37
- package/skills/yoyo-control/references/send-message.md +0 -155
- package/skills/yoyo-control/references/volume.md +0 -536
- package/skills/yoyo-control/scripts/README.md +0 -103
- package/skills/yoyo-control/scripts/volume-up.json +0 -7
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 状态跟踪器
|
|
3
|
+
* 核心状态跟踪逻辑,处理所有状态事件并维护状态数据
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
ConnectionStatusData,
|
|
8
|
+
GatewayConnectionInfo,
|
|
9
|
+
} from './types.js';
|
|
10
|
+
import { createEmptyStatusData } from './types.js';
|
|
11
|
+
import { StatusStorage } from './storage.js';
|
|
12
|
+
import {
|
|
13
|
+
StatusEventType,
|
|
14
|
+
type StatusEvent,
|
|
15
|
+
type CloudSocketConnectedData,
|
|
16
|
+
type CloudSocketDisconnectedData,
|
|
17
|
+
type CloudSocketErrorData,
|
|
18
|
+
type CloudSocketRetryData,
|
|
19
|
+
type GatewayClientConnectedData,
|
|
20
|
+
type GatewayClientDisconnectedData,
|
|
21
|
+
type DevicePairingData,
|
|
22
|
+
type DeviceUnpairingData,
|
|
23
|
+
type ConnectionStatusChangedData,
|
|
24
|
+
} from './events.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 状态跟踪器类
|
|
28
|
+
*/
|
|
29
|
+
export class StatusTracker {
|
|
30
|
+
private currentStatus: ConnectionStatusData;
|
|
31
|
+
private storage: StatusStorage;
|
|
32
|
+
private autoSave: boolean;
|
|
33
|
+
private saveTimer: NodeJS.Timeout | null;
|
|
34
|
+
|
|
35
|
+
constructor(autoSave = true) {
|
|
36
|
+
this.currentStatus = createEmptyStatusData();
|
|
37
|
+
this.storage = new StatusStorage();
|
|
38
|
+
this.autoSave = autoSave;
|
|
39
|
+
this.saveTimer = null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 处理状态事件
|
|
44
|
+
*/
|
|
45
|
+
async handleEvent(event: StatusEvent): Promise<void> {
|
|
46
|
+
const { type, timestamp, data } = event;
|
|
47
|
+
|
|
48
|
+
switch (type) {
|
|
49
|
+
case StatusEventType.CLOUD_SOCKET_CONNECTING:
|
|
50
|
+
this.handleCloudSocketConnecting(data, timestamp);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case StatusEventType.CLOUD_SOCKET_CONNECTED:
|
|
54
|
+
this.handleCloudSocketConnected(data, timestamp);
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
case StatusEventType.CLOUD_SOCKET_DISCONNECTED:
|
|
58
|
+
this.handleCloudSocketDisconnected(data, timestamp);
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case StatusEventType.CLOUD_SOCKET_ERROR:
|
|
62
|
+
this.handleCloudSocketError(data, timestamp);
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
case StatusEventType.CLOUD_SOCKET_RETRY:
|
|
66
|
+
this.handleCloudSocketRetry(data, timestamp);
|
|
67
|
+
break;
|
|
68
|
+
|
|
69
|
+
case StatusEventType.GATEWAY_CLIENT_CONNECTED:
|
|
70
|
+
this.handleGatewayClientConnected(data, timestamp);
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case StatusEventType.GATEWAY_CLIENT_DISCONNECTED:
|
|
74
|
+
this.handleGatewayClientDisconnected(data, timestamp);
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case StatusEventType.DEVICE_PAIRING:
|
|
78
|
+
this.handleDevicePairing(data, timestamp);
|
|
79
|
+
break;
|
|
80
|
+
|
|
81
|
+
case StatusEventType.DEVICE_UNPAIRING:
|
|
82
|
+
this.handleDeviceUnpairing(data, timestamp);
|
|
83
|
+
break;
|
|
84
|
+
|
|
85
|
+
case StatusEventType.CONNECTION_STATUS_CHANGED:
|
|
86
|
+
this.handleConnectionStatusChanged(data, timestamp);
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
default:
|
|
90
|
+
console.warn(`[StatusTracker] Unknown event type: ${type}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 更新时间戳
|
|
94
|
+
this.currentStatus.updatedAt = new Date(timestamp).toISOString();
|
|
95
|
+
|
|
96
|
+
// 自动保存
|
|
97
|
+
if (this.autoSave) {
|
|
98
|
+
this.scheduleSave();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 获取当前状态
|
|
104
|
+
*/
|
|
105
|
+
getStatus(): ConnectionStatusData {
|
|
106
|
+
return { ...this.currentStatus };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 加载已保存的状态
|
|
111
|
+
*/
|
|
112
|
+
async loadStatus(): Promise<ConnectionStatusData> {
|
|
113
|
+
const savedStatus = await this.storage.load();
|
|
114
|
+
if (savedStatus) {
|
|
115
|
+
this.currentStatus = savedStatus;
|
|
116
|
+
}
|
|
117
|
+
return this.getStatus();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 加载并清理状态
|
|
122
|
+
* 在服务启动时调用,清除临时的连接状态(gateway连接和物理设备)
|
|
123
|
+
* 保留持久化的状态(云socket状态和连接历史)
|
|
124
|
+
*/
|
|
125
|
+
async loadAndCleanStatus(): Promise<ConnectionStatusData> {
|
|
126
|
+
const savedStatus = await this.storage.load();
|
|
127
|
+
if (savedStatus) {
|
|
128
|
+
// 保留云socket状态和连接历史
|
|
129
|
+
const cloudSocketStatus = savedStatus.cloudSocket;
|
|
130
|
+
const connectionHistory = savedStatus.history;
|
|
131
|
+
|
|
132
|
+
// 创建新的空状态
|
|
133
|
+
this.currentStatus = createEmptyStatusData();
|
|
134
|
+
|
|
135
|
+
// 恢复云socket状态
|
|
136
|
+
this.currentStatus.cloudSocket = cloudSocketStatus;
|
|
137
|
+
|
|
138
|
+
// 恢复连接历史
|
|
139
|
+
this.currentStatus.history = connectionHistory;
|
|
140
|
+
|
|
141
|
+
// 重置云socket的连接状态(因为重启后连接会断开)
|
|
142
|
+
this.currentStatus.cloudSocket.connected = false;
|
|
143
|
+
this.currentStatus.cloudSocket.readyState = 3; // WebSocket.CLOSED
|
|
144
|
+
|
|
145
|
+
// 保存清理后的状态
|
|
146
|
+
await this.saveStatus();
|
|
147
|
+
}
|
|
148
|
+
return this.getStatus();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 保存当前状态
|
|
153
|
+
*/
|
|
154
|
+
async saveStatus(): Promise<void> {
|
|
155
|
+
await this.storage.save(this.currentStatus);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 清除状态
|
|
160
|
+
*/
|
|
161
|
+
async clearStatus(): Promise<void> {
|
|
162
|
+
this.currentStatus = createEmptyStatusData();
|
|
163
|
+
await this.storage.clear();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ==================== 事件处理方法 ====================
|
|
167
|
+
|
|
168
|
+
private handleCloudSocketConnecting(data: any, timestamp: number): void {
|
|
169
|
+
this.currentStatus.cloudSocket.url = data.url || '';
|
|
170
|
+
this.currentStatus.cloudSocket.connected = false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private handleCloudSocketConnected(
|
|
174
|
+
data: CloudSocketConnectedData,
|
|
175
|
+
timestamp: number
|
|
176
|
+
): void {
|
|
177
|
+
this.currentStatus.cloudSocket.connected = true;
|
|
178
|
+
this.currentStatus.cloudSocket.connectedAt = data.connectedAt;
|
|
179
|
+
this.currentStatus.cloudSocket.readyState = 1; // WebSocket.OPEN
|
|
180
|
+
this.currentStatus.cloudSocket.url = data.url;
|
|
181
|
+
this.currentStatus.cloudSocket.retryCount = 0;
|
|
182
|
+
this.currentStatus.cloudSocket.lastError = null;
|
|
183
|
+
|
|
184
|
+
// 更新连接历史
|
|
185
|
+
this.currentStatus.history.connectionCount++;
|
|
186
|
+
this.currentStatus.history.lastConnectionAt = data.connectedAt;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private handleCloudSocketDisconnected(
|
|
190
|
+
data: CloudSocketDisconnectedData,
|
|
191
|
+
timestamp: number
|
|
192
|
+
): void {
|
|
193
|
+
this.currentStatus.cloudSocket.connected = false;
|
|
194
|
+
this.currentStatus.cloudSocket.lastDisconnectedAt = data.disconnectedAt;
|
|
195
|
+
this.currentStatus.cloudSocket.readyState = 3; // WebSocket.CLOSED
|
|
196
|
+
|
|
197
|
+
// 更新连接历史
|
|
198
|
+
this.currentStatus.history.disconnectionCount++;
|
|
199
|
+
this.currentStatus.history.lastDisconnectionAt = data.disconnectedAt;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private handleCloudSocketError(
|
|
203
|
+
data: CloudSocketErrorData,
|
|
204
|
+
timestamp: number
|
|
205
|
+
): void {
|
|
206
|
+
this.currentStatus.cloudSocket.lastError = data.error;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private handleCloudSocketRetry(
|
|
210
|
+
data: CloudSocketRetryData,
|
|
211
|
+
timestamp: number
|
|
212
|
+
): void {
|
|
213
|
+
this.currentStatus.cloudSocket.retryCount = data.retryCount;
|
|
214
|
+
if (data.lastError) {
|
|
215
|
+
this.currentStatus.cloudSocket.lastError = data.lastError;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private handleGatewayClientConnected(
|
|
220
|
+
data: GatewayClientConnectedData,
|
|
221
|
+
timestamp: number
|
|
222
|
+
): void {
|
|
223
|
+
const connectionInfo: GatewayConnectionInfo = {
|
|
224
|
+
sessionId: data.sessionId,
|
|
225
|
+
hardwareDeviceId: data.hardwareDeviceId,
|
|
226
|
+
connectedAt: data.connectedAt,
|
|
227
|
+
deviceInfo: data.deviceInfo,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// 添加到连接列表
|
|
231
|
+
this.currentStatus.gateway.connections.push(connectionInfo);
|
|
232
|
+
this.currentStatus.gateway.totalConnections++;
|
|
233
|
+
this.currentStatus.gateway.activeConnections++;
|
|
234
|
+
|
|
235
|
+
// 更新设备信息
|
|
236
|
+
this.updateDeviceInfo(data.hardwareDeviceId, data.deviceInfo, timestamp);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private handleGatewayClientDisconnected(
|
|
240
|
+
data: GatewayClientDisconnectedData,
|
|
241
|
+
timestamp: number
|
|
242
|
+
): void {
|
|
243
|
+
// 从连接列表中移除
|
|
244
|
+
const index = this.currentStatus.gateway.connections.findIndex(
|
|
245
|
+
(c) => c.sessionId === data.sessionId
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
if (index !== -1) {
|
|
249
|
+
this.currentStatus.gateway.connections.splice(index, 1);
|
|
250
|
+
this.currentStatus.gateway.activeConnections--;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// 更新设备信息
|
|
254
|
+
this.updateDeviceInfo(data.hardwareDeviceId, null, timestamp);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private handleDevicePairing(data: DevicePairingData, timestamp: number): void {
|
|
258
|
+
// 设备配对时更新设备信息
|
|
259
|
+
this.updateDeviceInfo(data.hardwareDeviceId, data.deviceInfo, timestamp);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private handleDeviceUnpairing(
|
|
263
|
+
data: DeviceUnpairingData,
|
|
264
|
+
timestamp: number
|
|
265
|
+
): void {
|
|
266
|
+
// 设备取消配对时从设备列表中移除
|
|
267
|
+
const index = this.currentStatus.devices.devices.findIndex(
|
|
268
|
+
(d) => d.hardwareDeviceId === data.hardwareDeviceId
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
if (index !== -1) {
|
|
272
|
+
this.currentStatus.devices.devices.splice(index, 1);
|
|
273
|
+
this.recalculateDeviceStats();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private handleConnectionStatusChanged(
|
|
278
|
+
data: ConnectionStatusChangedData,
|
|
279
|
+
timestamp: number
|
|
280
|
+
): void {
|
|
281
|
+
this.currentStatus.status = data.status;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ==================== 辅助方法 ====================
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 更新设备信息
|
|
288
|
+
*/
|
|
289
|
+
private updateDeviceInfo(
|
|
290
|
+
hardwareDeviceId: string,
|
|
291
|
+
deviceInfo: any,
|
|
292
|
+
timestamp: number
|
|
293
|
+
): void {
|
|
294
|
+
let device = this.currentStatus.devices.devices.find(
|
|
295
|
+
(d) => d.hardwareDeviceId === hardwareDeviceId
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
if (!device) {
|
|
299
|
+
// 创建新设备记录
|
|
300
|
+
device = {
|
|
301
|
+
hardwareDeviceId,
|
|
302
|
+
sessions: 0,
|
|
303
|
+
lastActiveAt: new Date(timestamp).toISOString(),
|
|
304
|
+
deviceInfo,
|
|
305
|
+
};
|
|
306
|
+
this.currentStatus.devices.devices.push(device);
|
|
307
|
+
} else {
|
|
308
|
+
// 更新现有设备记录
|
|
309
|
+
device.lastActiveAt = new Date(timestamp).toISOString();
|
|
310
|
+
if (deviceInfo) {
|
|
311
|
+
device.deviceInfo = deviceInfo;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 重新计算设备统计
|
|
316
|
+
this.recalculateDeviceStats();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* 重新计算设备统计信息
|
|
321
|
+
*/
|
|
322
|
+
private recalculateDeviceStats(): void {
|
|
323
|
+
this.currentStatus.devices.totalDevices =
|
|
324
|
+
this.currentStatus.devices.devices.length;
|
|
325
|
+
this.currentStatus.devices.uniqueHardwareDevices =
|
|
326
|
+
this.currentStatus.devices.devices.length;
|
|
327
|
+
|
|
328
|
+
// 更新每个设备的会话数
|
|
329
|
+
for (const device of this.currentStatus.devices.devices) {
|
|
330
|
+
const sessionCount = this.currentStatus.gateway.connections.filter(
|
|
331
|
+
(c) => c.hardwareDeviceId === device.hardwareDeviceId
|
|
332
|
+
).length;
|
|
333
|
+
device.sessions = sessionCount;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* 调度保存(防抖)
|
|
339
|
+
*/
|
|
340
|
+
private scheduleSave(): void {
|
|
341
|
+
if (this.saveTimer) {
|
|
342
|
+
clearTimeout(this.saveTimer);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
this.saveTimer = setTimeout(async () => {
|
|
346
|
+
try {
|
|
347
|
+
await this.saveStatus();
|
|
348
|
+
} catch (error) {
|
|
349
|
+
console.error(
|
|
350
|
+
`[StatusTracker] Failed to save status: ${
|
|
351
|
+
error instanceof Error ? error.message : String(error)
|
|
352
|
+
}`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
}, 100); // 100ms 防抖
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* 销毁跟踪器
|
|
360
|
+
*/
|
|
361
|
+
async destroy(): Promise<void> {
|
|
362
|
+
if (this.saveTimer) {
|
|
363
|
+
clearTimeout(this.saveTimer);
|
|
364
|
+
this.saveTimer = null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// 最后保存一次
|
|
368
|
+
await this.saveStatus();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 状态跟踪类型定义
|
|
3
|
+
* 定义连接状态的完整数据结构
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 连接状态类型
|
|
8
|
+
*/
|
|
9
|
+
export type ConnectionStatus = 'idle' | 'connecting' | 'connected';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Gateway连接信息
|
|
13
|
+
*/
|
|
14
|
+
export interface GatewayConnectionInfo {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
hardwareDeviceId: string;
|
|
17
|
+
connectedAt: string;
|
|
18
|
+
deviceInfo: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 物理设备信息
|
|
23
|
+
*/
|
|
24
|
+
export interface PhysicalDeviceInfo {
|
|
25
|
+
hardwareDeviceId: string;
|
|
26
|
+
sessions: number;
|
|
27
|
+
lastActiveAt: string;
|
|
28
|
+
deviceInfo?: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 云侧Socket状态信息
|
|
33
|
+
*/
|
|
34
|
+
export interface CloudSocketStatus {
|
|
35
|
+
connected: boolean;
|
|
36
|
+
connectedAt: string | null;
|
|
37
|
+
lastDisconnectedAt: string | null;
|
|
38
|
+
retryCount: number;
|
|
39
|
+
lastError: string | null;
|
|
40
|
+
url: string;
|
|
41
|
+
readyState: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gateway连接统计
|
|
46
|
+
*/
|
|
47
|
+
export interface GatewayStatus {
|
|
48
|
+
totalConnections: number;
|
|
49
|
+
activeConnections: number;
|
|
50
|
+
connections: GatewayConnectionInfo[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 物理设备统计
|
|
55
|
+
*/
|
|
56
|
+
export interface DevicesStatus {
|
|
57
|
+
totalDevices: number;
|
|
58
|
+
uniqueHardwareDevices: number;
|
|
59
|
+
devices: PhysicalDeviceInfo[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 连接历史统计
|
|
64
|
+
*/
|
|
65
|
+
export interface ConnectionHistory {
|
|
66
|
+
connectionCount: number;
|
|
67
|
+
disconnectionCount: number;
|
|
68
|
+
lastConnectionAt: string | null;
|
|
69
|
+
lastDisconnectionAt: string | null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 完整的连接状态数据
|
|
74
|
+
*/
|
|
75
|
+
export interface ConnectionStatusData {
|
|
76
|
+
// 基础状态
|
|
77
|
+
status: ConnectionStatus;
|
|
78
|
+
updatedAt: string;
|
|
79
|
+
|
|
80
|
+
// 云侧Socket
|
|
81
|
+
cloudSocket: CloudSocketStatus;
|
|
82
|
+
|
|
83
|
+
// Gateway连接
|
|
84
|
+
gateway: GatewayStatus;
|
|
85
|
+
|
|
86
|
+
// 物理设备
|
|
87
|
+
devices: DevicesStatus;
|
|
88
|
+
|
|
89
|
+
// 连接历史
|
|
90
|
+
history: ConnectionHistory;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 空的连接状态数据(初始化用)
|
|
95
|
+
*/
|
|
96
|
+
export function createEmptyStatusData(): ConnectionStatusData {
|
|
97
|
+
const now = new Date().toISOString();
|
|
98
|
+
return {
|
|
99
|
+
status: 'idle',
|
|
100
|
+
updatedAt: now,
|
|
101
|
+
|
|
102
|
+
cloudSocket: {
|
|
103
|
+
connected: false,
|
|
104
|
+
connectedAt: null,
|
|
105
|
+
lastDisconnectedAt: null,
|
|
106
|
+
retryCount: 0,
|
|
107
|
+
lastError: null,
|
|
108
|
+
url: '',
|
|
109
|
+
readyState: 3, // WebSocket.CLOSED
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
gateway: {
|
|
113
|
+
totalConnections: 0,
|
|
114
|
+
activeConnections: 0,
|
|
115
|
+
connections: [],
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
devices: {
|
|
119
|
+
totalDevices: 0,
|
|
120
|
+
uniqueHardwareDevices: 0,
|
|
121
|
+
devices: [],
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
history: {
|
|
125
|
+
connectionCount: 0,
|
|
126
|
+
disconnectionCount: 0,
|
|
127
|
+
lastConnectionAt: null,
|
|
128
|
+
lastDisconnectionAt: null,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|