-
Notifications
You must be signed in to change notification settings - Fork 0
/
device.ts
154 lines (129 loc) · 3.77 KB
/
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { DateTime } from 'luxon'
import { UNIT } from '../constants.js'
import { syncDevices } from '../decorators/syncDevices.js'
import { updateDevice } from '../decorators/updateDevice.js'
import { DerogMode, Mode, type Switch } from '../enums.js'
import { DeviceModel } from '../models/device.js'
import type { API } from '../services/api.js'
import type { Attrs, BaseAttrs, DevicePostDataAny } from '../types.js'
import type { DerogSettings, IDeviceFacade } from './interfaces.js'
import type { FacadeManager } from './manager.js'
const getVacationEnd = (days: number): string =>
DateTime.now().plus({ days }).toLocaleString({
day: 'numeric',
hour: '2-digit',
hour12: false,
minute: '2-digit',
month: 'short',
})
const getBoostEnd = (minutes: number): string =>
DateTime.now().plus({ minutes }).toLocaleString(DateTime.TIME_24_SIMPLE)
export class DeviceFacade implements IDeviceFacade {
public readonly api: API
public readonly id: string
public readonly isFirstGen: boolean
public readonly isFirstPilot: boolean
public readonly isGlow: boolean
public constructor(manager: FacadeManager, instance: DeviceModel) {
;({ api: this.api } = manager)
;({
id: this.id,
isFirstGen: this.isFirstGen,
isFirstPilot: this.isFirstPilot,
isGlow: this.isGlow,
} = instance)
}
public get cftTempH(): number | undefined {
return this.data.cft_tempH
}
public get cftTempL(): number | undefined {
return this.data.cft_tempL
}
public get data(): Attrs {
return this.instance.data
}
public get derogMode(): DerogMode | undefined {
return this.data.derog_mode
}
public get derogSettings(): DerogSettings | undefined {
if (this.derogMode !== undefined && this.derogTime !== undefined) {
switch (this.derogMode) {
case DerogMode.boost:
return {
derogEnd: getBoostEnd(this.derogTime),
derogTimeBoost: this.derogTime,
derogTimeVacation: 0,
}
case DerogMode.off:
return {
derogEnd: null,
derogTimeBoost: 0,
derogTimeVacation: 0,
}
case DerogMode.vacation:
return {
derogEnd: getVacationEnd(this.derogTime),
derogTimeBoost: 0,
derogTimeVacation: this.derogTime,
}
default:
}
}
return undefined
}
public get derogTime(): number | undefined {
return this.data.derog_time
}
public get lockSwitch(): Switch | undefined {
return this.data.lock_switch
}
public get mode(): keyof typeof Mode {
const {
data: { mode },
} = this
return typeof mode === 'number' ? (Mode[mode] as keyof typeof Mode) : mode
}
public get name(): string {
return this.instance.name
}
public get timerSwitch(): Switch | undefined {
return this.data.timer_switch
}
protected get instance(): DeviceModel {
const instance = DeviceModel.getById(this.id)
if (!instance) {
throw new Error('Device not found')
}
return instance
}
@syncDevices
@updateDevice
public async get(): Promise<Attrs> {
return (await this.api.deviceData({ id: this.id })).data.attr
}
@syncDevices
@updateDevice
public async set(data: BaseAttrs): Promise<BaseAttrs> {
const postData = this.#handle(data)
if (postData) {
await this.api.control({
id: this.id,
postData,
})
}
return data
}
#handle(attrs: BaseAttrs): DevicePostDataAny | undefined {
if (Object.keys(attrs).length) {
if (this.isFirstGen) {
const { mode } = attrs
if (mode !== undefined) {
return {
raw: [UNIT, UNIT, typeof mode === 'string' ? Mode[mode] : mode],
}
}
}
return { attrs }
}
}
}