@homebridge-plugins/homebridge-govee 10.12.1
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/CHANGELOG.md +1937 -0
- package/LICENSE +21 -0
- package/README.md +72 -0
- package/config.schema.json +1727 -0
- package/eslint.config.js +49 -0
- package/lib/connection/aws.js +174 -0
- package/lib/connection/ble.js +208 -0
- package/lib/connection/cert/AmazonRootCA1.pem +20 -0
- package/lib/connection/http.js +240 -0
- package/lib/connection/lan.js +284 -0
- package/lib/device/cooler-single.js +300 -0
- package/lib/device/dehumidifier-H7150.js +182 -0
- package/lib/device/dehumidifier-H7151.js +157 -0
- package/lib/device/diffuser-H7161.js +117 -0
- package/lib/device/diffuser-H7162.js +117 -0
- package/lib/device/fan-H7100.js +274 -0
- package/lib/device/fan-H7101.js +330 -0
- package/lib/device/fan-H7102.js +274 -0
- package/lib/device/fan-H7105.js +503 -0
- package/lib/device/fan-H7106.js +274 -0
- package/lib/device/fan-H7111.js +335 -0
- package/lib/device/heater-single.js +300 -0
- package/lib/device/heater1a.js +353 -0
- package/lib/device/heater1b.js +616 -0
- package/lib/device/heater2.js +838 -0
- package/lib/device/humidifier-H7140.js +224 -0
- package/lib/device/humidifier-H7141.js +257 -0
- package/lib/device/humidifier-H7142.js +522 -0
- package/lib/device/humidifier-H7143.js +157 -0
- package/lib/device/humidifier-H7148.js +157 -0
- package/lib/device/humidifier-H7160.js +446 -0
- package/lib/device/ice-maker-H7162.js +46 -0
- package/lib/device/index.js +105 -0
- package/lib/device/kettle.js +269 -0
- package/lib/device/light-switch.js +86 -0
- package/lib/device/light.js +617 -0
- package/lib/device/outlet-double.js +121 -0
- package/lib/device/outlet-single.js +172 -0
- package/lib/device/outlet-triple.js +160 -0
- package/lib/device/purifier-H7120.js +336 -0
- package/lib/device/purifier-H7121.js +336 -0
- package/lib/device/purifier-H7122.js +449 -0
- package/lib/device/purifier-H7123.js +411 -0
- package/lib/device/purifier-H7124.js +411 -0
- package/lib/device/purifier-H7126.js +296 -0
- package/lib/device/purifier-H7127.js +296 -0
- package/lib/device/purifier-H712C.js +296 -0
- package/lib/device/purifier-single.js +119 -0
- package/lib/device/sensor-button.js +22 -0
- package/lib/device/sensor-contact.js +22 -0
- package/lib/device/sensor-leak.js +87 -0
- package/lib/device/sensor-monitor.js +190 -0
- package/lib/device/sensor-presence.js +53 -0
- package/lib/device/sensor-thermo.js +144 -0
- package/lib/device/sensor-thermo4.js +55 -0
- package/lib/device/switch-double.js +121 -0
- package/lib/device/switch-single.js +95 -0
- package/lib/device/switch-triple.js +160 -0
- package/lib/device/tap-single.js +108 -0
- package/lib/device/template.js +43 -0
- package/lib/device/tv-single.js +84 -0
- package/lib/device/valve-single.js +155 -0
- package/lib/fakegato/LICENSE +21 -0
- package/lib/fakegato/fakegato-history.js +814 -0
- package/lib/fakegato/fakegato-storage.js +108 -0
- package/lib/fakegato/fakegato-timer.js +125 -0
- package/lib/fakegato/uuid.js +27 -0
- package/lib/homebridge-ui/public/index.html +433 -0
- package/lib/homebridge-ui/server.js +10 -0
- package/lib/index.js +8 -0
- package/lib/platform.js +1967 -0
- package/lib/utils/colour.js +564 -0
- package/lib/utils/constants.js +579 -0
- package/lib/utils/custom-chars.js +225 -0
- package/lib/utils/eve-chars.js +68 -0
- package/lib/utils/functions.js +117 -0
- package/lib/utils/lang-en.js +131 -0
- package/package.json +75 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import os from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
|
|
5
|
+
const hostname = os.hostname().split('.')[0]
|
|
6
|
+
|
|
7
|
+
export default class {
|
|
8
|
+
constructor(params) {
|
|
9
|
+
if (!params) {
|
|
10
|
+
params = {}
|
|
11
|
+
}
|
|
12
|
+
this.writers = []
|
|
13
|
+
this.log = params.log || {}
|
|
14
|
+
if (!this.log) {
|
|
15
|
+
this.log = () => {}
|
|
16
|
+
}
|
|
17
|
+
this.addingWriter = false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
addWriter(service, params) {
|
|
21
|
+
if (!this.addingWriter) {
|
|
22
|
+
this.addingWriter = true
|
|
23
|
+
if (!params) {
|
|
24
|
+
params = {}
|
|
25
|
+
}
|
|
26
|
+
this.log('[%s] FGS addWriter().', service.accessoryName)
|
|
27
|
+
const newWriter = {
|
|
28
|
+
service,
|
|
29
|
+
callback: params.callback,
|
|
30
|
+
fileName: `${hostname}_${service.accessoryName}_persist.json`,
|
|
31
|
+
}
|
|
32
|
+
const onReady = typeof params.onReady === 'function' ? params.onReady : () => {}
|
|
33
|
+
newWriter.storageHandler = fs
|
|
34
|
+
newWriter.path = params.path || path.join(os.homedir(), '.homebridge')
|
|
35
|
+
this.writers.push(newWriter)
|
|
36
|
+
this.addingWriter = false
|
|
37
|
+
onReady()
|
|
38
|
+
} else {
|
|
39
|
+
setTimeout(() => this.addWriter(service, params), 100)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getWriter(service) {
|
|
44
|
+
return this.writers.find(ele => ele.service === service)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_getWriterIndex(service) {
|
|
48
|
+
return this.writers.findIndex(ele => ele.service === service)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getWriters() {
|
|
52
|
+
return this.writers
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
delWriter(service) {
|
|
56
|
+
const index = this._getWriterIndex(service)
|
|
57
|
+
this.writers.splice(index, 1)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
write(params) {
|
|
61
|
+
if (!this.writing) {
|
|
62
|
+
this.writing = true
|
|
63
|
+
const writer = this.getWriter(params.service)
|
|
64
|
+
const callBack = typeof params.callback === 'function'
|
|
65
|
+
? params.callback
|
|
66
|
+
: typeof writer.callback === 'function'
|
|
67
|
+
? writer.callback
|
|
68
|
+
: () => {}
|
|
69
|
+
const fileLoc = path.join(writer.path, writer.fileName)
|
|
70
|
+
this.log(
|
|
71
|
+
'[%s] FGS write file [%s] [%s].',
|
|
72
|
+
params.service.accessoryName,
|
|
73
|
+
fileLoc,
|
|
74
|
+
params.data.substr(1, 80),
|
|
75
|
+
)
|
|
76
|
+
writer.storageHandler.writeFile(fileLoc, params.data, 'utf8', (...args) => {
|
|
77
|
+
this.writing = false
|
|
78
|
+
callBack(args)
|
|
79
|
+
})
|
|
80
|
+
} else {
|
|
81
|
+
setTimeout(() => this.write(params), 100)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
read(params) {
|
|
86
|
+
const writer = this.getWriter(params.service)
|
|
87
|
+
const callBack = typeof params.callback === 'function'
|
|
88
|
+
? params.callback
|
|
89
|
+
: typeof writer.callback === 'function'
|
|
90
|
+
? writer.callback
|
|
91
|
+
: () => {}
|
|
92
|
+
const fileLoc = path.join(writer.path, writer.fileName)
|
|
93
|
+
this.log('[%s] FGS read file [%s].', params.service.accessoryName, fileLoc)
|
|
94
|
+
writer.storageHandler.readFile(fileLoc, 'utf8', callBack)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
remove(params) {
|
|
98
|
+
const writer = this.getWriter(params.service)
|
|
99
|
+
const callBack = typeof params.callback === 'function'
|
|
100
|
+
? params.callback
|
|
101
|
+
: typeof writer.callback === 'function'
|
|
102
|
+
? writer.callback
|
|
103
|
+
: () => {}
|
|
104
|
+
const fileLoc = path.join(writer.path, writer.fileName)
|
|
105
|
+
this.log('[%s] FGS delete file [%s].', params.service.accessoryName, fileLoc)
|
|
106
|
+
writer.storageHandler.unlink(fileLoc, callBack)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export default class {
|
|
2
|
+
constructor(params) {
|
|
3
|
+
if (!params) {
|
|
4
|
+
params = {}
|
|
5
|
+
}
|
|
6
|
+
this.subscribedServices = []
|
|
7
|
+
this.minutes = params.minutes || 10
|
|
8
|
+
this.intervalID = null
|
|
9
|
+
this.running = false
|
|
10
|
+
this.log = params.log || {}
|
|
11
|
+
if (!this.log) {
|
|
12
|
+
this.log = () => {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
subscribe(service, callback) {
|
|
17
|
+
this.log('[%s] FGT new subscription.', service.accessoryName)
|
|
18
|
+
const newService = {
|
|
19
|
+
service,
|
|
20
|
+
callback,
|
|
21
|
+
backLog: [],
|
|
22
|
+
previousBackLog: [],
|
|
23
|
+
previousAvrg: {},
|
|
24
|
+
}
|
|
25
|
+
this.subscribedServices.push(newService)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getSubscriber(service) {
|
|
29
|
+
return this.subscribedServices.find(el => el.service === service)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_getSubscriberIndex(service) {
|
|
33
|
+
return this.subscribedServices.findIndex(el => el.service === service)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getSubscribers() {
|
|
37
|
+
return this.subscribedServices
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
unsubscribe(service) {
|
|
41
|
+
const index = this._getSubscriberIndex(service)
|
|
42
|
+
this.subscribedServices.splice(index, 1)
|
|
43
|
+
if (this.subscribedServices.length === 0 && this.running) {
|
|
44
|
+
this.stop()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
start() {
|
|
49
|
+
this.log('Starting global FGT [%s minutes].', this.minutes)
|
|
50
|
+
if (this.running) {
|
|
51
|
+
this.stop()
|
|
52
|
+
}
|
|
53
|
+
this.running = true
|
|
54
|
+
this.intervalID = setInterval(this.executeCallbacks.bind(this), this.minutes * 60 * 1000)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
stop() {
|
|
58
|
+
this.log('Stopping global FGT.')
|
|
59
|
+
clearInterval(this.intervalID)
|
|
60
|
+
this.running = false
|
|
61
|
+
this.intervalID = null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
executeCallbacks() {
|
|
65
|
+
this.log('FGT executeCallbacks().')
|
|
66
|
+
if (this.subscribedServices.length !== 0) {
|
|
67
|
+
for (const s in this.subscribedServices) {
|
|
68
|
+
if (Object.prototype.hasOwnProperty.call(this.subscribedServices, s)) {
|
|
69
|
+
const service = this.subscribedServices[s]
|
|
70
|
+
if (typeof service.callback === 'function') {
|
|
71
|
+
service.previousAvrg = service.callback({
|
|
72
|
+
backLog: service.backLog,
|
|
73
|
+
previousAvrg: service.previousAvrg,
|
|
74
|
+
timer: this,
|
|
75
|
+
immediate: false,
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
executeImmediateCallback(service) {
|
|
84
|
+
this.log('[%s] FGT executeImmediateCallback().', service.accessoryName)
|
|
85
|
+
if (typeof service.callback === 'function' && service.backLog.length) {
|
|
86
|
+
service.callback({
|
|
87
|
+
backLog: service.backLog,
|
|
88
|
+
timer: this,
|
|
89
|
+
immediate: true,
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
addData(params) {
|
|
95
|
+
const data = params.entry
|
|
96
|
+
const { service } = params
|
|
97
|
+
const immediateCallback = params.immediateCallback || false
|
|
98
|
+
this.log(
|
|
99
|
+
'[%s] FGT addData() [%s] immediate [%s].',
|
|
100
|
+
service.accessoryName,
|
|
101
|
+
data,
|
|
102
|
+
immediateCallback,
|
|
103
|
+
)
|
|
104
|
+
if (immediateCallback) {
|
|
105
|
+
this.getSubscriber(service).backLog[0] = data
|
|
106
|
+
} else {
|
|
107
|
+
this.getSubscriber(service).backLog.push(data)
|
|
108
|
+
}
|
|
109
|
+
if (immediateCallback) {
|
|
110
|
+
this.executeImmediateCallback(this.getSubscriber(service))
|
|
111
|
+
}
|
|
112
|
+
if (!this.running) {
|
|
113
|
+
this.start()
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
emptyData(service) {
|
|
118
|
+
this.log('[%s] FGT emptyData().', service.accessoryName)
|
|
119
|
+
const source = this.getSubscriber(service)
|
|
120
|
+
if (source.backLog.length) {
|
|
121
|
+
source.previousBackLog = source.backLog
|
|
122
|
+
}
|
|
123
|
+
source.backLog = []
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// https://github.com/homebridge/HAP-NodeJS/blob/master/src/lib/util/uuid.ts
|
|
2
|
+
|
|
3
|
+
function isValid(UUID) {
|
|
4
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
|
5
|
+
return uuidRegex.test(UUID)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function toLongFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
|
|
9
|
+
const shortRegex = /^[0-9a-f]{1,8}$/i
|
|
10
|
+
if (isValid(uuid)) {
|
|
11
|
+
return uuid.toUpperCase()
|
|
12
|
+
}
|
|
13
|
+
if (!shortRegex.test(uuid)) {
|
|
14
|
+
throw new TypeError('uuid was not a valid UUID or short form UUID')
|
|
15
|
+
}
|
|
16
|
+
if (!isValid(`00000000${base}`)) {
|
|
17
|
+
throw new TypeError('base was not a valid base UUID')
|
|
18
|
+
}
|
|
19
|
+
return ((`00000000${uuid}`).substr(-8) + base).toUpperCase()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function toShortFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
|
|
23
|
+
uuid = toLongFormUUID(uuid, base)
|
|
24
|
+
return uuid.substr(0, 8)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { toLongFormUUID, toShortFormUUID }
|