-
-
Notifications
You must be signed in to change notification settings - Fork 173
/
Copy pathring-device.ts
119 lines (103 loc) · 2.46 KB
/
ring-device.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { BehaviorSubject } from 'rxjs'
import type { RingDeviceData } from './ring-types.ts'
import { deviceTypesWithVolume } from './ring-types.ts'
import { filter, map } from 'rxjs/operators'
import type { Location } from './location.ts'
import { Subscribed } from './subscribed.ts'
import { logError } from './util.ts'
export class RingDevice extends Subscribed {
onData
zid
id
deviceType
categoryId
onComponentDevices
constructor(
private initialData: RingDeviceData,
public location: Location,
public assetId: string,
) {
super()
this.onData = new BehaviorSubject(this.initialData)
this.zid = this.initialData.zid
this.id = this.zid
this.deviceType = this.initialData.deviceType
this.categoryId = this.initialData.categoryId
this.onComponentDevices = this.location.onDevices.pipe(
map((devices) =>
devices.filter(({ data }) => data.parentZid === this.id),
),
)
this.addSubscriptions(
location.onDeviceDataUpdate
.pipe(filter((update) => update.zid === this.zid))
.subscribe((update) => this.updateData(update)),
)
}
updateData(update: Partial<RingDeviceData>) {
this.onData.next(Object.assign({}, this.data, update))
}
get data() {
return this.onData.getValue()
}
get name() {
return this.data.name
}
get supportsVolume() {
return (
deviceTypesWithVolume.includes(this.data.deviceType) &&
this.data.volume !== undefined
)
}
setVolume(volume: number) {
if (isNaN(volume) || volume < 0 || volume > 1) {
throw new Error('Volume must be between 0 and 1')
}
if (!this.supportsVolume) {
throw new Error(
`Volume can only be set on ${deviceTypesWithVolume.join(', ')}`,
)
}
return this.setInfo({ device: { v1: { volume } } })
}
setInfo(body: any) {
return this.location.sendMessage({
msg: 'DeviceInfoSet',
datatype: 'DeviceInfoSetType',
dst: this.assetId,
body: [
{
zid: this.zid,
...body,
},
],
})
}
sendCommand(commandType: string, data = {}) {
this.setInfo({
command: {
v1: [
{
commandType,
data,
},
],
},
}).catch(logError)
}
toString() {
return this.toJSON()
}
toJSON() {
return JSON.stringify(
{
data: this.data,
},
null,
2,
)
}
disconnect() {
this.unsubscribe()
}
}