matterbridge-ha-roborock 3.0.0
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/README.md +19 -0
- package/config.json +10 -0
- package/dist/src/ha-vacuum-controller.d.ts +111 -0
- package/dist/src/ha-vacuum-controller.js +289 -0
- package/dist/src/ha-vacuum-controller.js.map +1 -0
- package/dist/src/homeassistant-client.d.ts +30 -0
- package/dist/src/homeassistant-client.js +135 -0
- package/dist/src/homeassistant-client.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/platform-config.d.ts +45 -0
- package/dist/src/platform-config.js +43 -0
- package/dist/src/platform-config.js.map +1 -0
- package/dist/src/platform.d.ts +15 -0
- package/dist/src/platform.js +481 -0
- package/dist/src/platform.js.map +1 -0
- package/dist/test/test-connection.d.ts +1 -0
- package/dist/test/test-connection.js +43 -0
- package/dist/test/test-connection.js.map +1 -0
- package/package.json +34 -0
- package/src/ha-vacuum-controller.ts +334 -0
- package/src/homeassistant-client.ts +169 -0
- package/src/index.ts +16 -0
- package/src/platform-config.ts +109 -0
- package/src/platform.ts +601 -0
- package/test/test-connection.ts +53 -0
- package/tsconfig.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Matterbridge HA Roborock
|
|
2
|
+
|
|
3
|
+
桥接 Home Assistant 中的 Roborock 到 Matter。
|
|
4
|
+
|
|
5
|
+
## 配置
|
|
6
|
+
```json
|
|
7
|
+
{
|
|
8
|
+
"haUrl": "http://homeassistant.local:8123",
|
|
9
|
+
"haToken": "your-token",
|
|
10
|
+
"deviceWhitelist": ["vacuum.roborock_s7"]
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 开发
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
npm run build
|
|
18
|
+
npm test
|
|
19
|
+
```
|
package/config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "matterbridge-ha-roborock",
|
|
3
|
+
"type": "DynamicPlatform",
|
|
4
|
+
"haUrl": "10.10.10.175:8123",
|
|
5
|
+
"haToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI0NDY0ZmFmODY2Njc0ZDYzODZjN2I5OTNiZmNhNGM5YSIsImlhdCI6MTc1NDkyMjExNCwiZXhwIjoyMDcwMjgyMTE0fQ.qTGAd7yICd9AX5lSsw9KcXcKOr3GLnte7B6gEsTCE7o",
|
|
6
|
+
"deviceWhitelist": [
|
|
7
|
+
"vacuum.dreame_vacuum_r2254"
|
|
8
|
+
],
|
|
9
|
+
"debug": true
|
|
10
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { HomeAssistantClient } from './homeassistant-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* VacuumState - 吸尘器状态
|
|
5
|
+
*/
|
|
6
|
+
export interface VacuumState {
|
|
7
|
+
state: string;
|
|
8
|
+
batteryLevel: number;
|
|
9
|
+
isCharging: boolean;
|
|
10
|
+
fanSpeed?: string;
|
|
11
|
+
cleaningMode?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
errorMsg?: string;
|
|
14
|
+
rawAttributes?: any;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* CleanModeConfig - 清洁模式配置
|
|
18
|
+
*/
|
|
19
|
+
export interface CleanModeConfig {
|
|
20
|
+
cleaningMode: string;
|
|
21
|
+
fanSpeed: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* HAVacuumController - Home Assistant 吸尘器控制器
|
|
25
|
+
* 负责与 Home Assistant 交互,控制吸尘器并监听状态变化
|
|
26
|
+
*/
|
|
27
|
+
export declare class HAVacuumController extends EventEmitter {
|
|
28
|
+
private haClient;
|
|
29
|
+
private entityId;
|
|
30
|
+
private batterySensorId?;
|
|
31
|
+
private chargingSensorId?;
|
|
32
|
+
private cleaningModeEntityId?;
|
|
33
|
+
private errorSensorId?;
|
|
34
|
+
private currentState?;
|
|
35
|
+
private pollInterval?;
|
|
36
|
+
constructor(haClient: HomeAssistantClient, entityId: string, batterySensorId?: string, chargingSensorId?: string, cleaningModeEntityId?: string, errorSensorId?: string);
|
|
37
|
+
/**
|
|
38
|
+
* 初始化控制器 - 获取初始状态并设置监听
|
|
39
|
+
*/
|
|
40
|
+
initialize(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* 更新状态
|
|
43
|
+
*/
|
|
44
|
+
private updateState;
|
|
45
|
+
/**
|
|
46
|
+
* 处理状态变化
|
|
47
|
+
*/
|
|
48
|
+
private handleStateChange;
|
|
49
|
+
/**
|
|
50
|
+
* 启动轮询
|
|
51
|
+
*/
|
|
52
|
+
private startPolling;
|
|
53
|
+
/**
|
|
54
|
+
* 停止轮询
|
|
55
|
+
*/
|
|
56
|
+
private stopPolling;
|
|
57
|
+
/**
|
|
58
|
+
* 获取当前状态
|
|
59
|
+
*/
|
|
60
|
+
getState(): VacuumState | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* 强制刷新状态(用于主动更新)
|
|
63
|
+
*/
|
|
64
|
+
forceRefreshState(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* 开始清扫
|
|
67
|
+
*/
|
|
68
|
+
start(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* 暂停清扫
|
|
71
|
+
*/
|
|
72
|
+
pause(): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* 停止清扫
|
|
75
|
+
*/
|
|
76
|
+
stop(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* 返回充电座
|
|
79
|
+
*/
|
|
80
|
+
returnToBase(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* 定位扫地机(播放声音)
|
|
83
|
+
*/
|
|
84
|
+
locate(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* 设置风速
|
|
87
|
+
*/
|
|
88
|
+
setFanSpeed(speed: string): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* 设置清洁模式(使用 select 实体)
|
|
91
|
+
*/
|
|
92
|
+
setCleaningModeEntity(mode: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* 设置清洁模式和风速(组合设置)
|
|
95
|
+
*/
|
|
96
|
+
setCleaningModeAndFanSpeed(config: CleanModeConfig): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* 分区清扫 (Xiaomi Miot 特定)
|
|
99
|
+
* @param segments 区域ID数组
|
|
100
|
+
*/
|
|
101
|
+
/**
|
|
102
|
+
* 清扫指定区域
|
|
103
|
+
* @param segments Matter 区域 ID 数组 (1, 2, 3, 4)
|
|
104
|
+
* @param segmentMap Matter ID 到 Dreame ID 的映射
|
|
105
|
+
*/
|
|
106
|
+
cleanSegments(segments: number[], segmentMap?: Record<number, string>): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* 销毁控制器
|
|
109
|
+
*/
|
|
110
|
+
destroy(): void;
|
|
111
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
/**
|
|
3
|
+
* HAVacuumController - Home Assistant 吸尘器控制器
|
|
4
|
+
* 负责与 Home Assistant 交互,控制吸尘器并监听状态变化
|
|
5
|
+
*/
|
|
6
|
+
export class HAVacuumController extends EventEmitter {
|
|
7
|
+
haClient;
|
|
8
|
+
entityId;
|
|
9
|
+
batterySensorId;
|
|
10
|
+
chargingSensorId;
|
|
11
|
+
cleaningModeEntityId; // select.dreame_vacuum_r2254_cleaning_mode
|
|
12
|
+
errorSensorId; // 新增:sensor.dreame_vacuum_r2254_error
|
|
13
|
+
currentState;
|
|
14
|
+
pollInterval;
|
|
15
|
+
constructor(haClient, entityId, batterySensorId, chargingSensorId, cleaningModeEntityId, errorSensorId // 新增参数
|
|
16
|
+
) {
|
|
17
|
+
super();
|
|
18
|
+
this.haClient = haClient;
|
|
19
|
+
this.entityId = entityId;
|
|
20
|
+
this.batterySensorId = batterySensorId;
|
|
21
|
+
this.chargingSensorId = chargingSensorId;
|
|
22
|
+
this.cleaningModeEntityId = cleaningModeEntityId;
|
|
23
|
+
this.errorSensorId = errorSensorId; // 新增赋值
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 初始化控制器 - 获取初始状态并设置监听
|
|
27
|
+
*/
|
|
28
|
+
async initialize() {
|
|
29
|
+
// 获取初始状态
|
|
30
|
+
await this.updateState();
|
|
31
|
+
// 监听 WebSocket 状态变化
|
|
32
|
+
this.haClient.on('stateChanged', async (entityId, newState) => {
|
|
33
|
+
if (entityId === this.entityId) {
|
|
34
|
+
// vacuum 主实体状态变化
|
|
35
|
+
await this.handleStateChange(newState);
|
|
36
|
+
}
|
|
37
|
+
else if (entityId === this.batterySensorId) {
|
|
38
|
+
// 电池传感器状态变化
|
|
39
|
+
await this.updateState();
|
|
40
|
+
}
|
|
41
|
+
else if (entityId === this.chargingSensorId) {
|
|
42
|
+
// 充电状态传感器变化
|
|
43
|
+
await this.updateState();
|
|
44
|
+
}
|
|
45
|
+
else if (entityId === this.cleaningModeEntityId) {
|
|
46
|
+
// 清洁模式传感器变化
|
|
47
|
+
await this.updateState();
|
|
48
|
+
}
|
|
49
|
+
else if (entityId === this.errorSensorId) { // 新增:监听错误传感器
|
|
50
|
+
await this.updateState();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// 启动轮询作为备用
|
|
54
|
+
this.startPolling();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 更新状态
|
|
58
|
+
*/
|
|
59
|
+
async updateState() {
|
|
60
|
+
const entity = await this.haClient.getEntityState(this.entityId);
|
|
61
|
+
await this.handleStateChange(entity);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 处理状态变化
|
|
65
|
+
*/
|
|
66
|
+
async handleStateChange(entity) {
|
|
67
|
+
// 获取电池电量
|
|
68
|
+
let batteryLevel = 0;
|
|
69
|
+
if (this.batterySensorId) {
|
|
70
|
+
try {
|
|
71
|
+
const batterySensor = await this.haClient.getEntityState(this.batterySensorId);
|
|
72
|
+
batteryLevel = parseFloat(batterySensor.state) || 0;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(`[${this.entityId}] Failed to get battery sensor:`, error);
|
|
76
|
+
batteryLevel = entity.attributes.battery_level || 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
batteryLevel = entity.attributes.battery_level || 0;
|
|
81
|
+
}
|
|
82
|
+
// 获取充电状态
|
|
83
|
+
let isCharging = false;
|
|
84
|
+
if (this.chargingSensorId) {
|
|
85
|
+
try {
|
|
86
|
+
const chargingSensor = await this.haClient.getEntityState(this.chargingSensorId);
|
|
87
|
+
isCharging = chargingSensor.state.toLowerCase() === 'on';
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(`[${this.entityId}] Failed to get charging sensor:`, error);
|
|
91
|
+
// 回退:只信任 HA 的 charging 状态(不包括 docked)
|
|
92
|
+
isCharging = entity.state.toLowerCase() === 'charging';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// 如果没有充电传感器,只信任 HA 的 charging 状态
|
|
97
|
+
isCharging = entity.state.toLowerCase() === 'charging';
|
|
98
|
+
}
|
|
99
|
+
// 获取清洁模式
|
|
100
|
+
let cleaningMode = undefined;
|
|
101
|
+
if (this.cleaningModeEntityId) {
|
|
102
|
+
try {
|
|
103
|
+
const cleaningModeEntity = await this.haClient.getEntityState(this.cleaningModeEntityId);
|
|
104
|
+
cleaningMode = cleaningModeEntity.state;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error(`[${this.entityId}] Failed to get cleaning mode:`, error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// 新增:获取错误状态
|
|
111
|
+
let errorMsg = undefined;
|
|
112
|
+
if (this.errorSensorId) {
|
|
113
|
+
try {
|
|
114
|
+
const errorSensor = await this.haClient.getEntityState(this.errorSensorId);
|
|
115
|
+
errorMsg = errorSensor.state;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error(`[${this.entityId}] Failed to get error sensor:`, error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
this.currentState = {
|
|
122
|
+
state: entity.state,
|
|
123
|
+
batteryLevel: batteryLevel,
|
|
124
|
+
isCharging: isCharging,
|
|
125
|
+
fanSpeed: entity.attributes.fan_speed,
|
|
126
|
+
cleaningMode: cleaningMode,
|
|
127
|
+
error: entity.attributes.error,
|
|
128
|
+
errorMsg: errorMsg, // 新增:错误消息
|
|
129
|
+
rawAttributes: entity.attributes,
|
|
130
|
+
};
|
|
131
|
+
this.emit('stateChanged', this.currentState);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 启动轮询
|
|
135
|
+
*/
|
|
136
|
+
startPolling(intervalMs = 30000) {
|
|
137
|
+
this.pollInterval = setInterval(async () => {
|
|
138
|
+
try {
|
|
139
|
+
await this.updateState();
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error(`[${this.entityId}] Poll failed:`, error);
|
|
143
|
+
}
|
|
144
|
+
}, intervalMs);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 停止轮询
|
|
148
|
+
*/
|
|
149
|
+
stopPolling() {
|
|
150
|
+
if (this.pollInterval) {
|
|
151
|
+
clearInterval(this.pollInterval);
|
|
152
|
+
this.pollInterval = undefined;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 获取当前状态
|
|
157
|
+
*/
|
|
158
|
+
getState() {
|
|
159
|
+
return this.currentState;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 强制刷新状态(用于主动更新)
|
|
163
|
+
*/
|
|
164
|
+
async forceRefreshState() {
|
|
165
|
+
await this.updateState();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 开始清扫
|
|
169
|
+
*/
|
|
170
|
+
async start() {
|
|
171
|
+
await this.haClient.callService('vacuum', 'start', {
|
|
172
|
+
entity_id: this.entityId,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 暂停清扫
|
|
177
|
+
*/
|
|
178
|
+
async pause() {
|
|
179
|
+
await this.haClient.callService('vacuum', 'pause', {
|
|
180
|
+
entity_id: this.entityId,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 停止清扫
|
|
185
|
+
*/
|
|
186
|
+
async stop() {
|
|
187
|
+
await this.haClient.callService('vacuum', 'stop', {
|
|
188
|
+
entity_id: this.entityId,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 返回充电座
|
|
193
|
+
*/
|
|
194
|
+
async returnToBase() {
|
|
195
|
+
await this.haClient.callService('vacuum', 'return_to_base', {
|
|
196
|
+
entity_id: this.entityId,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 定位扫地机(播放声音)
|
|
201
|
+
*/
|
|
202
|
+
async locate() {
|
|
203
|
+
try {
|
|
204
|
+
await this.haClient.callService('vacuum', 'locate', {
|
|
205
|
+
entity_id: this.entityId,
|
|
206
|
+
});
|
|
207
|
+
console.log(`[${this.entityId}] 📍 定位命令已发送`);
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error(`[${this.entityId}] ❌ 定位失败:`, error);
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* 设置风速
|
|
216
|
+
*/
|
|
217
|
+
async setFanSpeed(speed) {
|
|
218
|
+
await this.haClient.callService('vacuum', 'set_fan_speed', {
|
|
219
|
+
entity_id: this.entityId,
|
|
220
|
+
fan_speed: speed,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 设置清洁模式(使用 select 实体)
|
|
225
|
+
*/
|
|
226
|
+
async setCleaningModeEntity(mode) {
|
|
227
|
+
if (!this.cleaningModeEntityId) {
|
|
228
|
+
throw new Error('Cleaning mode entity ID not configured');
|
|
229
|
+
}
|
|
230
|
+
await this.haClient.callService('select', 'select_option', {
|
|
231
|
+
entity_id: this.cleaningModeEntityId,
|
|
232
|
+
option: mode,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* 设置清洁模式和风速(组合设置)
|
|
237
|
+
*/
|
|
238
|
+
async setCleaningModeAndFanSpeed(config) {
|
|
239
|
+
// 先设置清洁模式
|
|
240
|
+
if (this.cleaningModeEntityId) {
|
|
241
|
+
await this.setCleaningModeEntity(config.cleaningMode);
|
|
242
|
+
// 等待一小段时间确保模式切换完成
|
|
243
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
244
|
+
}
|
|
245
|
+
// 再设置风速
|
|
246
|
+
await this.setFanSpeed(config.fanSpeed);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* 分区清扫 (Xiaomi Miot 特定)
|
|
250
|
+
* @param segments 区域ID数组
|
|
251
|
+
*/
|
|
252
|
+
/**
|
|
253
|
+
* 清扫指定区域
|
|
254
|
+
* @param segments Matter 区域 ID 数组 (1, 2, 3, 4)
|
|
255
|
+
* @param segmentMap Matter ID 到 Dreame ID 的映射
|
|
256
|
+
*/
|
|
257
|
+
async cleanSegments(segments, segmentMap) {
|
|
258
|
+
// 如果提供了映射,转换为 Dreame segment ID
|
|
259
|
+
if (segmentMap) {
|
|
260
|
+
const dreameSegments = segments
|
|
261
|
+
.map(id => segmentMap[id])
|
|
262
|
+
.filter(id => id !== undefined);
|
|
263
|
+
console.log(`[${this.entityId}] 🗺️ 清扫区域: Matter[${segments.join(',')}] → Dreame[${dreameSegments.join(',')}]`);
|
|
264
|
+
// 使用 Dreame 专用服务
|
|
265
|
+
await this.haClient.callService('dreame_vacuum', 'vacuum_clean_segment', {
|
|
266
|
+
entity_id: this.entityId,
|
|
267
|
+
segments: dreameSegments,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// 回退到 xiaomi_miot 服务
|
|
272
|
+
console.log(`[${this.entityId}] 🗺️ 清扫区域: ${segments.join(',')}`);
|
|
273
|
+
await this.haClient.callService('xiaomi_miot', 'call_action', {
|
|
274
|
+
entity_id: this.entityId,
|
|
275
|
+
siid: 18,
|
|
276
|
+
aiid: 1,
|
|
277
|
+
in: segments,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* 销毁控制器
|
|
283
|
+
*/
|
|
284
|
+
destroy() {
|
|
285
|
+
this.stopPolling();
|
|
286
|
+
this.removeAllListeners();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=ha-vacuum-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ha-vacuum-controller.js","sourceRoot":"","sources":["../../src/ha-vacuum-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface HAVacuumEntity {
|
|
3
|
+
entity_id: string;
|
|
4
|
+
state: string;
|
|
5
|
+
attributes: {
|
|
6
|
+
friendly_name: string;
|
|
7
|
+
battery_level?: number;
|
|
8
|
+
fan_speed?: string;
|
|
9
|
+
fan_speed_list?: string[];
|
|
10
|
+
error?: string;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
};
|
|
13
|
+
last_changed: string;
|
|
14
|
+
last_updated: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class HomeAssistantClient extends EventEmitter {
|
|
17
|
+
private baseUrl;
|
|
18
|
+
private token;
|
|
19
|
+
private ws?;
|
|
20
|
+
private messageId;
|
|
21
|
+
private isConnected;
|
|
22
|
+
constructor(url: string, token: string);
|
|
23
|
+
testConnection(): Promise<boolean>;
|
|
24
|
+
getVacuumEntities(): Promise<HAVacuumEntity[]>;
|
|
25
|
+
getEntityState(entityId: string): Promise<HAVacuumEntity>;
|
|
26
|
+
callService(domain: string, service: string, data?: any): Promise<any>;
|
|
27
|
+
connectWebSocket(): Promise<void>;
|
|
28
|
+
disconnect(): void;
|
|
29
|
+
isConnectedToWebSocket(): boolean;
|
|
30
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
import WebSocket from 'ws';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
export class HomeAssistantClient extends EventEmitter {
|
|
5
|
+
baseUrl;
|
|
6
|
+
token;
|
|
7
|
+
ws;
|
|
8
|
+
messageId = 1;
|
|
9
|
+
isConnected = false;
|
|
10
|
+
constructor(url, token) {
|
|
11
|
+
super();
|
|
12
|
+
this.baseUrl = url.replace(/\/$/, '');
|
|
13
|
+
this.token = token;
|
|
14
|
+
}
|
|
15
|
+
async testConnection() {
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch(`${this.baseUrl}/api/`, {
|
|
18
|
+
headers: {
|
|
19
|
+
'Authorization': `Bearer ${this.token}`,
|
|
20
|
+
'Content-Type': 'application/json'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(`Connection failed: ${response.statusText}`);
|
|
25
|
+
}
|
|
26
|
+
const data = await response.json();
|
|
27
|
+
console.log('✅ HA connection:', data.message);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('❌ HA connection failed:', error);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async getVacuumEntities() {
|
|
36
|
+
const response = await fetch(`${this.baseUrl}/api/states`, {
|
|
37
|
+
headers: {
|
|
38
|
+
'Authorization': `Bearer ${this.token}`,
|
|
39
|
+
'Content-Type': 'application/json'
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(`Failed to get states: ${response.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
const states = await response.json();
|
|
46
|
+
return states.filter((e) => e.entity_id.startsWith('vacuum.'));
|
|
47
|
+
}
|
|
48
|
+
async getEntityState(entityId) {
|
|
49
|
+
const response = await fetch(`${this.baseUrl}/api/states/${entityId}`, {
|
|
50
|
+
headers: {
|
|
51
|
+
'Authorization': `Bearer ${this.token}`,
|
|
52
|
+
'Content-Type': 'application/json'
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
throw new Error(`Failed to get state: ${response.statusText}`);
|
|
57
|
+
}
|
|
58
|
+
return await response.json();
|
|
59
|
+
}
|
|
60
|
+
async callService(domain, service, data = {}) {
|
|
61
|
+
const url = `${this.baseUrl}/api/services/${domain}/${service}`;
|
|
62
|
+
console.log(`[HA Client] Calling service:`);
|
|
63
|
+
console.log(` URL: ${url}`);
|
|
64
|
+
console.log(` Data: ${JSON.stringify(data)}`);
|
|
65
|
+
const response = await fetch(url, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: {
|
|
68
|
+
'Authorization': `Bearer ${this.token}`,
|
|
69
|
+
'Content-Type': 'application/json'
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(data)
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const errorText = await response.text();
|
|
75
|
+
console.error(`[HA Client] ❌ Service call failed: ${response.status} ${response.statusText}`);
|
|
76
|
+
console.error(` Response: ${errorText}`);
|
|
77
|
+
throw new Error(`Service call failed: ${response.statusText} - ${errorText}`);
|
|
78
|
+
}
|
|
79
|
+
const result = await response.json();
|
|
80
|
+
console.log(`[HA Client] ✅ Service call successful`);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
async connectWebSocket() {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const wsUrl = this.baseUrl
|
|
86
|
+
.replace('http://', 'ws://')
|
|
87
|
+
.replace('https://', 'wss://');
|
|
88
|
+
this.ws = new WebSocket(`${wsUrl}/api/websocket`);
|
|
89
|
+
const timeout = setTimeout(() => {
|
|
90
|
+
reject(new Error('WebSocket timeout'));
|
|
91
|
+
}, 10000);
|
|
92
|
+
this.ws.on('message', (data) => {
|
|
93
|
+
const msg = JSON.parse(data.toString());
|
|
94
|
+
if (msg.type === 'auth_required') {
|
|
95
|
+
this.ws.send(JSON.stringify({
|
|
96
|
+
type: 'auth',
|
|
97
|
+
access_token: this.token
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
else if (msg.type === 'auth_ok') {
|
|
101
|
+
clearTimeout(timeout);
|
|
102
|
+
this.isConnected = true;
|
|
103
|
+
this.ws.send(JSON.stringify({
|
|
104
|
+
id: this.messageId++,
|
|
105
|
+
type: 'subscribe_events',
|
|
106
|
+
event_type: 'state_changed'
|
|
107
|
+
}));
|
|
108
|
+
resolve();
|
|
109
|
+
}
|
|
110
|
+
else if (msg.type === 'event') {
|
|
111
|
+
const event = msg.event;
|
|
112
|
+
if (event.event_type === 'state_changed') {
|
|
113
|
+
const entityId = event.data.entity_id;
|
|
114
|
+
if (entityId.startsWith('vacuum.')) {
|
|
115
|
+
this.emit('stateChanged', entityId, event.data.new_state);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
this.ws.on('error', (error) => {
|
|
121
|
+
clearTimeout(timeout);
|
|
122
|
+
reject(error);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
disconnect() {
|
|
127
|
+
if (this.ws) {
|
|
128
|
+
this.ws.close();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
isConnectedToWebSocket() {
|
|
132
|
+
return this.isConnected;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=homeassistant-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"homeassistant-client.js","sourceRoot":"","sources":["../../src/homeassistant-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Matterbridge, PlatformConfig } from 'matterbridge';
|
|
2
|
+
import { RoborockHAPlatform } from './platform.js';
|
|
3
|
+
/**
|
|
4
|
+
* Matterbridge 会直接调用 default export(不是 new)
|
|
5
|
+
* 所以这里必须返回 new 出来的平台实例
|
|
6
|
+
*/
|
|
7
|
+
type RoborockArgs = [
|
|
8
|
+
matterbridge: Matterbridge,
|
|
9
|
+
log: any,
|
|
10
|
+
config: PlatformConfig
|
|
11
|
+
];
|
|
12
|
+
export default function (...args: RoborockArgs): RoborockHAPlatform;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAYnD,MAAM,CAAC,OAAO,WAAW,GAAG,IAAkB;IAC5C,OAAO,IAAI,kBAAkB,CAAC,GAAG,IAAI,CAAC,CAAC;AACzC,CAAC"}
|