@homebridge-plugins/homebridge-ewelink 12.3.3

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.
Files changed (113) hide show
  1. package/CHANGELOG.md +1363 -0
  2. package/LICENSE +21 -0
  3. package/README.md +68 -0
  4. package/config.schema.json +1757 -0
  5. package/eslint.config.js +15 -0
  6. package/lib/connection/api.js +508 -0
  7. package/lib/connection/http.js +304 -0
  8. package/lib/connection/lan.js +318 -0
  9. package/lib/connection/ws.js +414 -0
  10. package/lib/device/curtain.js +324 -0
  11. package/lib/device/diffuser.js +473 -0
  12. package/lib/device/fan.js +349 -0
  13. package/lib/device/group.js +106 -0
  14. package/lib/device/humidifier.js +199 -0
  15. package/lib/device/index.js +61 -0
  16. package/lib/device/light-cct.js +333 -0
  17. package/lib/device/light-dimmer.js +257 -0
  18. package/lib/device/light-rgb-cct.js +809 -0
  19. package/lib/device/light-rgb.js +272 -0
  20. package/lib/device/motor.js +363 -0
  21. package/lib/device/outlet-multi.js +417 -0
  22. package/lib/device/outlet-single-inched.js +409 -0
  23. package/lib/device/outlet-single.js +384 -0
  24. package/lib/device/panel.js +382 -0
  25. package/lib/device/rf-bridge.js +321 -0
  26. package/lib/device/rf-button.js +125 -0
  27. package/lib/device/rf-sensor.js +173 -0
  28. package/lib/device/sensor-ambient.js +311 -0
  29. package/lib/device/sensor-contact.js +140 -0
  30. package/lib/device/sensor-temp-humi.js +182 -0
  31. package/lib/device/simulation/blind.js +253 -0
  32. package/lib/device/simulation/cooler.js +312 -0
  33. package/lib/device/simulation/door.js +253 -0
  34. package/lib/device/simulation/doorbell.js +190 -0
  35. package/lib/device/simulation/garage-eachen.js +235 -0
  36. package/lib/device/simulation/garage-four.js +176 -0
  37. package/lib/device/simulation/garage-od-switch.js +36 -0
  38. package/lib/device/simulation/garage-one.js +395 -0
  39. package/lib/device/simulation/garage-two.js +394 -0
  40. package/lib/device/simulation/gate-one.js +327 -0
  41. package/lib/device/simulation/heater.js +389 -0
  42. package/lib/device/simulation/index.js +75 -0
  43. package/lib/device/simulation/light-fan.js +258 -0
  44. package/lib/device/simulation/lock-eachen.js +163 -0
  45. package/lib/device/simulation/lock-one.js +366 -0
  46. package/lib/device/simulation/p-button.js +223 -0
  47. package/lib/device/simulation/purifier.js +289 -0
  48. package/lib/device/simulation/rf-blind.js +192 -0
  49. package/lib/device/simulation/rf-door.js +180 -0
  50. package/lib/device/simulation/rf-window.js +180 -0
  51. package/lib/device/simulation/sensor-hidden.js +105 -0
  52. package/lib/device/simulation/sensor-leak.js +123 -0
  53. package/lib/device/simulation/sensor-visible.js +231 -0
  54. package/lib/device/simulation/sensor.js +300 -0
  55. package/lib/device/simulation/switch-valve.js +351 -0
  56. package/lib/device/simulation/tap-one.js +283 -0
  57. package/lib/device/simulation/tap-two.js +266 -0
  58. package/lib/device/simulation/th-cooler.js +443 -0
  59. package/lib/device/simulation/th-dehumidifier.js +424 -0
  60. package/lib/device/simulation/th-heater.js +449 -0
  61. package/lib/device/simulation/th-humidifier.js +424 -0
  62. package/lib/device/simulation/th-thermostat.js +611 -0
  63. package/lib/device/simulation/tv.js +252 -0
  64. package/lib/device/simulation/valve-four.js +232 -0
  65. package/lib/device/simulation/valve-one.js +345 -0
  66. package/lib/device/simulation/valve-two.js +340 -0
  67. package/lib/device/simulation/window.js +253 -0
  68. package/lib/device/switch-man.js +106 -0
  69. package/lib/device/switch-mate.js +82 -0
  70. package/lib/device/switch-multi.js +411 -0
  71. package/lib/device/switch-single-inched.js +332 -0
  72. package/lib/device/switch-single.js +307 -0
  73. package/lib/device/template.js +43 -0
  74. package/lib/device/thermostat.js +286 -0
  75. package/lib/device/zigbee/index.js +27 -0
  76. package/lib/device/zigbee/light-cct.js +263 -0
  77. package/lib/device/zigbee/light-dimmer.js +148 -0
  78. package/lib/device/zigbee/light-rgb-cct.js +400 -0
  79. package/lib/device/zigbee/motor.js +301 -0
  80. package/lib/device/zigbee/sensor-ambient.js +177 -0
  81. package/lib/device/zigbee/sensor-contact.js +137 -0
  82. package/lib/device/zigbee/sensor-leak.js +119 -0
  83. package/lib/device/zigbee/sensor-motion.js +119 -0
  84. package/lib/device/zigbee/sensor-occupancy.js +119 -0
  85. package/lib/device/zigbee/sensor-smoke.js +96 -0
  86. package/lib/device/zigbee/switch-stateless.js +104 -0
  87. package/lib/device/zigbee/thermostat.js +323 -0
  88. package/lib/fakegato/LICENSE +21 -0
  89. package/lib/fakegato/fakegato-history.js +813 -0
  90. package/lib/fakegato/fakegato-storage.js +108 -0
  91. package/lib/fakegato/fakegato-timer.js +125 -0
  92. package/lib/fakegato/uuid.js +27 -0
  93. package/lib/homebridge-ui/public/index.html +365 -0
  94. package/lib/homebridge-ui/server.js +46 -0
  95. package/lib/index.js +7 -0
  96. package/lib/node-dns-sd/LICENSE +21 -0
  97. package/lib/node-dns-sd/README.md +613 -0
  98. package/lib/node-dns-sd/lib/dns-sd-classes.json +6 -0
  99. package/lib/node-dns-sd/lib/dns-sd-composer.js +83 -0
  100. package/lib/node-dns-sd/lib/dns-sd-parser.js +344 -0
  101. package/lib/node-dns-sd/lib/dns-sd-types.json +52 -0
  102. package/lib/node-dns-sd/lib/dns-sd.js +580 -0
  103. package/lib/platform.js +2156 -0
  104. package/lib/utils/colour.js +552 -0
  105. package/lib/utils/constants.js +589 -0
  106. package/lib/utils/custom-chars.js +33 -0
  107. package/lib/utils/eve-chars.js +130 -0
  108. package/lib/utils/functions.js +42 -0
  109. package/lib/utils/lang-en.js +160 -0
  110. package/lib/utils/lang-fr.js +163 -0
  111. package/lib/utils/lang-th.js +160 -0
  112. package/lib/utils/lang.js +5 -0
  113. package/package.json +75 -0
@@ -0,0 +1,83 @@
1
+ import { Buffer } from 'node:buffer'
2
+ import { createRequire } from 'node:module'
3
+
4
+ /* ------------------------------------------------------------------
5
+ * node-dns-sd - dns-sd-composer.js
6
+ *
7
+ * Copyright (c) 2017, Futomi Hatano, All rights reserved.
8
+ * Released under the MIT license
9
+ * Date: 2018-10-25
10
+ * ---------------------------------------------------------------- */
11
+
12
+ /* ------------------------------------------------------------------
13
+ * Constructor: DnsSdComposer()
14
+ * ---------------------------------------------------------------- */
15
+
16
+ const require = createRequire(import.meta.url)
17
+
18
+ const DnsSdComposer = function () {
19
+ this._CLASSES = require('./dns-sd-classes.json')
20
+ this._TYPES = require('./dns-sd-types.json')
21
+ }
22
+
23
+ /* ------------------------------------------------------------------
24
+ * Method: compose(params)
25
+ * - params:
26
+ * - name | Array | Requred | Servcie name.(e.g., ["_googlecast._tcp.local"])
27
+ * - type | String | Optional | Query Type (e.g., "PTR"). The default value is "*"
28
+ * ---------------------------------------------------------------- */
29
+ DnsSdComposer.prototype.compose = function (params) {
30
+ const name_list = params.name
31
+ const type_name = params.type
32
+ let type_code = 0xFF
33
+ if (type_name) {
34
+ if (typeof (type_name) === 'string') {
35
+ if (this._TYPES[type_name]) {
36
+ type_code = this._TYPES[type_name]
37
+ } else {
38
+ throw new Error(`The specified query type name is unknown: ${type_name}`)
39
+ }
40
+ } else {
41
+ throw new TypeError('The specified query type is invalid.')
42
+ }
43
+ }
44
+
45
+ const hbuf = Buffer.from([ // Header
46
+ 0x00,
47
+ 0x00, // Transaction ID
48
+ 0x00,
49
+ 0x00, // Flags
50
+ 0x00,
51
+ name_list.length, // Questions
52
+ 0x00,
53
+ 0x00, // Answer PRs
54
+ 0x00,
55
+ 0x00, // Authority PRs
56
+ 0x00,
57
+ 0x00, // Additional PRs
58
+ ])
59
+
60
+ const qbuf_list = []
61
+ name_list.forEach((name) => {
62
+ (name.split('.')).forEach((part) => {
63
+ const part_buf = Buffer.from(part, 'utf8')
64
+ qbuf_list.push(Buffer.from([part_buf.length]))
65
+ qbuf_list.push(part_buf)
66
+ })
67
+ qbuf_list.push(Buffer.from([0x00])) // Null-terminated string for the domain name
68
+
69
+ const type_buf = Buffer.alloc(2)
70
+ type_buf.writeUInt16BE(type_code, 0)
71
+ qbuf_list.push(type_buf)
72
+
73
+ const class_buf = Buffer.alloc(2)
74
+ class_buf.writeUInt16BE(this._CLASSES.IN, 0)
75
+ qbuf_list.push(class_buf)
76
+ })
77
+ const qbuf = Buffer.concat(qbuf_list)
78
+
79
+ const buf = Buffer.concat([hbuf, qbuf])
80
+ return buf
81
+ }
82
+
83
+ export default new DnsSdComposer()
@@ -0,0 +1,344 @@
1
+ import { createRequire } from 'node:module'
2
+
3
+ /* ------------------------------------------------------------------
4
+ * node-dns-sd - dns-sd-parser.js
5
+ *
6
+ * Copyright (c) 2018-2019, Futomi Hatano, All rights reserved.
7
+ * Released under the MIT license
8
+ * Date: 2018-02-27
9
+
10
+ * Related specifications:
11
+ * - RFC 1035 (DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION)
12
+ * https://tools.ietf.org/html/rfc1035
13
+ * - RFC 6762 (Multicast DNS)
14
+ * https://tools.ietf.org/html/rfc6762
15
+ * - RFC 6763 (DNS-Based Service Discovery)
16
+ * https://tools.ietf.org/html/rfc6763
17
+ * - RFC 2782 (A DNS RR for specifying the location of services (DNS SRV))
18
+ * https://tools.ietf.org/html/rfc2782
19
+ * ---------------------------------------------------------------- */
20
+
21
+ const require = createRequire(import.meta.url)
22
+
23
+ /* ------------------------------------------------------------------
24
+ * Constructor: DnsSdParser()
25
+ * ---------------------------------------------------------------- */
26
+ const DnsSdParser = function () {
27
+ this._CLASSES = require('./dns-sd-classes.json')
28
+ this._CLASS_MAP = {}
29
+ Object.keys(this._CLASSES).forEach((k) => {
30
+ this._CLASS_MAP[this._CLASSES[k]] = k
31
+ })
32
+
33
+ this._TYPES = require('./dns-sd-types.json')
34
+ this._TYPE_MAP = {}
35
+ Object.keys(this._TYPES).forEach((k) => {
36
+ this._TYPE_MAP[this._TYPES[k]] = k
37
+ })
38
+ }
39
+
40
+ /* ------------------------------------------------------------------
41
+ * Method: parse(buf)
42
+ * ---------------------------------------------------------------- */
43
+ DnsSdParser.prototype.parse = function (buf) {
44
+ if (buf.length <= 12) {
45
+ return null
46
+ }
47
+ const header = {
48
+ id: buf.readUInt16BE(0),
49
+ qr: buf.readUInt8(2) >> 7, // 0: Query, 1: Response
50
+ op: (buf.readUInt8(2) & 0b01111000) >> 3, // 0: Normal query, 4: Notify, 5: Update
51
+ aa: (buf.readUInt8(2) & 0b00000100) >> 2,
52
+ tc: (buf.readUInt8(2) & 0b00000010) >> 1,
53
+ rd: (buf.readUInt8(2) & 0b00000001),
54
+ ra: (buf.readUInt8(3) & 0b10000000) >> 7,
55
+ z: (buf.readUInt8(3) & 0b01000000) >> 6,
56
+ ad: (buf.readUInt8(3) & 0b00100000) >> 6,
57
+ cd: (buf.readUInt8(3) & 0b00010000) >> 5,
58
+ rc: (buf.readUInt8(3) & 0b00001111),
59
+ questions: buf.readUInt16BE(4),
60
+ answers: buf.readUInt16BE(6),
61
+ authorities: buf.readUInt16BE(8),
62
+ additionals: buf.readUInt16BE(10),
63
+ }
64
+ if (header.tc !== 0 || header.rd !== 0 || header.ra !== 0 || header.z !== 0 || header.ad !== 0 || header.cd !== 0 || header.rc !== 0) {
65
+ return null
66
+ }
67
+ if (header.questions + header.answers + header.authorities + header.additionals === 0) {
68
+ return null
69
+ }
70
+ let offset = 12
71
+ const records = {
72
+ header,
73
+ questions: [],
74
+ answers: [],
75
+ authorities: [],
76
+ additionals: [],
77
+ }
78
+ const record_count_list = [];
79
+ ['questions', 'answers', 'authorities', 'additionals'].forEach((k) => {
80
+ const cnt = header[k]
81
+ if (cnt > 0) {
82
+ record_count_list.push({ name: k, count: cnt })
83
+ }
84
+ })
85
+ let invalid = false
86
+ while (true) {
87
+ const parsed = this._parseLabel(buf, offset)
88
+ let domain_name = ''
89
+ if (parsed) {
90
+ offset += parsed.length
91
+ domain_name = parsed.name
92
+ } else {
93
+ invalid = true
94
+ break
95
+ }
96
+
97
+ const record_key = record_count_list[0].name
98
+ if (record_key === 'questions') {
99
+ if (offset + 4 > buf.length) {
100
+ invalid = true
101
+ break
102
+ }
103
+ const type_value = buf.readUInt16BE(offset)
104
+ const type = this._TYPE_MAP[type_value]
105
+ offset += 2
106
+ const cls_value = buf.readUInt16BE(offset)
107
+ const cls = this._CLASS_MAP[cls_value]
108
+ offset += 2
109
+ records[record_key].push({
110
+ name: domain_name,
111
+ type: type || '',
112
+ class: cls || '',
113
+ })
114
+ } else {
115
+ if (offset + 10 > buf.length) {
116
+ invalid = true
117
+ break
118
+ }
119
+ const type_value = buf.readUInt16BE(offset)
120
+ const type = this._TYPE_MAP[type_value] || ''
121
+ offset += 2
122
+ const cls_value = buf.readUInt16BE(offset)
123
+ const cls = this._CLASS_MAP[cls_value & 0b0111111111111111]
124
+ const flash = !!((cls_value & 0b1000000000000000))
125
+ offset += 2
126
+ const ttl = buf.readUInt32BE(offset)
127
+ offset += 4
128
+ const rdlen = buf.readUInt16BE(offset)
129
+ offset += 2
130
+ if (offset + rdlen > buf.length) {
131
+ invalid = true
132
+ break
133
+ }
134
+ let rdata = ''
135
+ let rdata_txt_buffer = null
136
+ if (type === 'A') {
137
+ rdata = this._parseRdataA(buf, offset, rdlen)
138
+ } else if (type === 'AAAA') {
139
+ rdata = this._parseRdataAAAA(buf, offset, rdlen)
140
+ } else if (type === 'PTR') {
141
+ rdata = this._parseRdataPtr(buf, offset, rdlen)
142
+ } else if (type === 'TXT') {
143
+ rdata = this._parseRdataTxt(buf, offset, rdlen)
144
+ rdata_txt_buffer = this._parseRdataTxt(buf, offset, rdlen, true)
145
+ } else if (type === 'SRV') {
146
+ rdata = this._parseRdataSrv(buf, offset, rdlen)
147
+ } else if (type === 'HINFO') {
148
+ rdata = this._parseRdataHinfo(buf, offset, rdlen)
149
+ } else {
150
+ rdata = this._parseRdataOther(buf, offset, rdlen)
151
+ }
152
+ offset += rdlen
153
+
154
+ if (!rdata) {
155
+ invalid = true
156
+ break
157
+ }
158
+
159
+ const d = {
160
+ name: domain_name,
161
+ type: type || '',
162
+ class: cls || '',
163
+ flash,
164
+ ttl,
165
+ rdata,
166
+ }
167
+ if (rdata_txt_buffer) {
168
+ d.rdata_buffer = rdata_txt_buffer
169
+ }
170
+ records[record_key].push(d)
171
+ }
172
+
173
+ if (offset >= buf.length) {
174
+ break
175
+ }
176
+ record_count_list[0].count--
177
+ if (record_count_list[0].count <= 0) {
178
+ record_count_list.shift()
179
+ }
180
+ if (record_count_list.length === 0) {
181
+ break
182
+ }
183
+ }
184
+ if (invalid === true) {
185
+ return null
186
+ }
187
+ return records
188
+ }
189
+
190
+ DnsSdParser.prototype._parseLabel = function (buf, offset) {
191
+ try {
192
+ const labels = []
193
+ let length = 0
194
+ let invalid = false
195
+ while (true) {
196
+ const label_len = buf.readUInt8(offset + length)
197
+ if ((label_len & 0b11000000) === 0b11000000) {
198
+ const i = buf.readUInt16BE(offset + length) & 0b0011111111111111
199
+ const parsed = this._parseLabel(buf, i)
200
+ if (parsed) {
201
+ labels.push(parsed.name)
202
+ length += 2
203
+ break
204
+ } else {
205
+ invalid = true
206
+ break
207
+ }
208
+ } else if ((label_len & 0b11000000) === 0b00000000) {
209
+ length += 1
210
+ if (label_len === 0x00) {
211
+ break
212
+ } else if (offset + length + label_len <= buf.length) {
213
+ const label = buf.slice(offset + length, offset + length + label_len).toString('utf8')
214
+ labels.push(label)
215
+ length += label_len
216
+ } else {
217
+ invalid = true
218
+ break
219
+ }
220
+ } else {
221
+ invalid = true
222
+ break
223
+ }
224
+ }
225
+ if (invalid === true) {
226
+ return null
227
+ }
228
+ return {
229
+ name: labels.join('.'),
230
+ length,
231
+ }
232
+ } catch (err) {
233
+ return null
234
+ }
235
+ }
236
+
237
+ DnsSdParser.prototype._parseRdataA = function (buf, offset, len) {
238
+ const addr_parts = []
239
+ for (let i = 0; i < len; i += 1) {
240
+ addr_parts.push(buf.readUInt8(offset + i))
241
+ }
242
+ const addr = addr_parts.join('.')
243
+ return addr
244
+ }
245
+
246
+ DnsSdParser.prototype._parseRdataAAAA = function (buf, offset, len) {
247
+ const addr_parts = []
248
+ for (let i = 0; i < len; i += 2) {
249
+ addr_parts.push(buf.slice(offset + i, offset + i + 2).toString('hex'))
250
+ }
251
+ const addr = addr_parts.join(':')
252
+ return addr
253
+ }
254
+
255
+ DnsSdParser.prototype._parseRdataPtr = function (buf, offset) {
256
+ const parsed = this._parseLabel(buf, offset)
257
+ if (parsed) {
258
+ return parsed.name
259
+ }
260
+ return null
261
+ }
262
+
263
+ DnsSdParser.prototype._parseRdataTxt = function (buf, offset, len, buf_flag) {
264
+ const labels = {}
265
+ let i = 0
266
+ while (true) {
267
+ if (i >= len) {
268
+ break
269
+ }
270
+ const blen = buf.readUInt8(offset + i)
271
+ i += 1
272
+ if (i + blen <= len) {
273
+ const pair = buf.slice(offset + i, offset + i + blen).toString('utf8')
274
+ const m = pair.match(/^([^=]+)=(.*)/)
275
+ if (m) {
276
+ labels[m[1]] = m[2]
277
+ if (buf_flag) {
278
+ const s = offset + i + m[1].length + 1
279
+ const e = offset + i + blen
280
+ labels[m[1]] = buf.slice(s, e)
281
+ }
282
+ }
283
+ i += blen
284
+ } else {
285
+ break
286
+ }
287
+ }
288
+ return labels
289
+ }
290
+
291
+ DnsSdParser.prototype._parseRdataSrv = function (buf, offset, len) {
292
+ if (len <= 6) {
293
+ return null
294
+ }
295
+ let target = null
296
+ const parsed = this._parseLabel(buf, offset + 6)
297
+ if (parsed) {
298
+ target = parsed.name
299
+ }
300
+ return {
301
+ priority: buf.readUInt16BE(offset),
302
+ weight: buf.readUInt16BE(offset + 2),
303
+ port: buf.readUInt16BE(offset + 4),
304
+ target,
305
+ }
306
+ }
307
+
308
+ DnsSdParser.prototype._parseRdataHinfo = function (buf, offset, len) {
309
+ const txt_list = []
310
+ let i = 0
311
+ while (true) {
312
+ if (i >= len) {
313
+ break
314
+ }
315
+ const blen = buf.readUInt8(offset + i)
316
+ i += 1
317
+ if (i + blen <= len) {
318
+ const v = buf.slice(offset + i, offset + i + blen).toString('utf8')
319
+ txt_list.push(v)
320
+ i += blen
321
+ } else {
322
+ break
323
+ }
324
+ }
325
+ const info = {}
326
+ if (txt_list[0]) {
327
+ info.cpu = txt_list[0]
328
+ }
329
+ if (txt_list[1]) {
330
+ info.os = txt_list[1]
331
+ }
332
+ return info
333
+ }
334
+
335
+ DnsSdParser.prototype._parseRdataOther = function (buf, offset, len) {
336
+ const rdata_parts = []
337
+ for (let i = 0; i < len; i += 1) {
338
+ rdata_parts.push(buf.slice(offset + i, offset + i + 1).toString('hex'))
339
+ }
340
+ const rdata = rdata_parts.join(' ')
341
+ return rdata
342
+ }
343
+
344
+ export default new DnsSdParser()
@@ -0,0 +1,52 @@
1
+ {
2
+ "A": 1,
3
+ "NS": 2,
4
+ "MD": 3,
5
+ "MF": 4,
6
+ "CNAME": 5,
7
+ "SOA": 6,
8
+ "MB": 7,
9
+ "MG": 8,
10
+ "MR": 9,
11
+ "NULL": 10,
12
+ "WKS": 11,
13
+ "PTR": 12,
14
+ "HINFO": 13,
15
+ "MINFO": 14,
16
+ "MX": 15,
17
+ "TXT": 16,
18
+ "AAAA": 28,
19
+ "AFSDB": 18,
20
+ "APL": 42,
21
+ "CAA": 257,
22
+ "CDNSKEY": 60,
23
+ "CDS": 59,
24
+ "CERT": 37,
25
+ "DHCID": 49,
26
+ "DLV": 32769,
27
+ "DNAME": 39,
28
+ "DNSKEY": 48,
29
+ "DS": 43,
30
+ "HIP": 55,
31
+ "IPSECKEY": 45,
32
+ "KEY": 25,
33
+ "KX": 36,
34
+ "LOC": 29,
35
+ "NAPTR": 35,
36
+ "NSEC": 47,
37
+ "NSEC3": 50,
38
+ "NSEC3PARAM": 51,
39
+ "OPENPGPKEY": 61,
40
+ "RRSIG": 46,
41
+ "RP": 17,
42
+ "SIG": 24,
43
+ "SRV": 33,
44
+ "SSHFP": 44,
45
+ "TA": 32768,
46
+ "TKEY": 249,
47
+ "TLSA": 52,
48
+ "TSIG": 250,
49
+ "URI": 256,
50
+ "OPT": 41,
51
+ "*": 255
52
+ }