iobroker.govee-local 0.2.8 → 0.2.9
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 +7 -0
- package/build/main.js +86 -40
- package/build/main.js.map +2 -2
- package/build/tools/hexTool.js +1 -1
- package/build/tools/hexTool.js.map +2 -2
- package/io-package.json +14 -14
- package/package.json +14 -17
package/README.md
CHANGED
|
@@ -24,9 +24,16 @@ For **Windows** Users: Please go to the settings and make sure you choose the co
|
|
|
24
24
|
Placeholder for the next version (at the beginning of the line):
|
|
25
25
|
### **WORK IN PROGRESS**
|
|
26
26
|
-->
|
|
27
|
+
### 0.2.9 (2025-08-22)
|
|
28
|
+
|
|
29
|
+
- update dependencies
|
|
30
|
+
- add support for node 24
|
|
31
|
+
- update to ESlint 9
|
|
32
|
+
|
|
27
33
|
### 0.2.8 (2025-03-28)
|
|
28
34
|
|
|
29
35
|
- update dependencies
|
|
36
|
+
- avoid repeated overriding of states
|
|
30
37
|
|
|
31
38
|
### 0.2.7 (2024-08-18)
|
|
32
39
|
|
package/build/main.js
CHANGED
|
@@ -5,6 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
8
12
|
var __copyProps = (to, from, except, desc) => {
|
|
9
13
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
14
|
for (let key of __getOwnPropNames(from))
|
|
@@ -21,6 +25,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var main_exports = {};
|
|
30
|
+
__export(main_exports, {
|
|
31
|
+
GoveeLocal: () => GoveeLocal,
|
|
32
|
+
getDatapointDescription: () => getDatapointDescription
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(main_exports);
|
|
24
35
|
var utils = __toESM(require("@iobroker/adapter-core"));
|
|
25
36
|
var dgram = __toESM(require("node:dgram"));
|
|
26
37
|
var import_hexTool = require("./tools/hexTool");
|
|
@@ -49,7 +60,7 @@ class GoveeLocal extends utils.Adapter {
|
|
|
49
60
|
* Is called when databases are connected and adapter received configuration.
|
|
50
61
|
*/
|
|
51
62
|
async onReady() {
|
|
52
|
-
this.setObjectNotExists("info.connection", {
|
|
63
|
+
void this.setObjectNotExists("info.connection", {
|
|
53
64
|
type: "state",
|
|
54
65
|
common: {
|
|
55
66
|
name: "Device discovery running",
|
|
@@ -62,14 +73,15 @@ class GoveeLocal extends utils.Adapter {
|
|
|
62
73
|
});
|
|
63
74
|
socket.on("message", this.onUdpMessage.bind(this));
|
|
64
75
|
socket.on("error", (error) => {
|
|
65
|
-
this.log.error(
|
|
66
|
-
this.setStateChanged("info.connection", { val: false, ack: true });
|
|
76
|
+
this.log.error(`server bind error : ${error.message}`);
|
|
77
|
+
void this.setStateChanged("info.connection", { val: false, ack: true });
|
|
67
78
|
});
|
|
68
79
|
if (this.config.extendedLogging) {
|
|
69
80
|
this.log.debug("running with extended logging");
|
|
70
81
|
}
|
|
71
|
-
socket.bind({ address: this.config.interface, port: LOCAL_PORT }, this.serverBound.bind(this));
|
|
72
|
-
this.subscribeStates("*.devStatus.*");
|
|
82
|
+
void socket.bind({ address: this.config.interface, port: LOCAL_PORT }, this.serverBound.bind(this));
|
|
83
|
+
void this.subscribeStates("*.devStatus.*");
|
|
84
|
+
return Promise.resolve();
|
|
73
85
|
}
|
|
74
86
|
/**
|
|
75
87
|
* handles when udp socket is up
|
|
@@ -81,8 +93,8 @@ class GoveeLocal extends utils.Adapter {
|
|
|
81
93
|
socket.setMulticastTTL(128);
|
|
82
94
|
socket.setMulticastInterface(this.config.interface);
|
|
83
95
|
socket.addMembership(M_CAST);
|
|
84
|
-
this.setStateChanged("info.connection", { val: true, ack: true });
|
|
85
|
-
this.log.debug(
|
|
96
|
+
void this.setStateChanged("info.connection", { val: true, ack: true });
|
|
97
|
+
this.log.debug(`UDP listening on ${socket.address().address}:${socket.address().port}`);
|
|
86
98
|
const deviceSearchInterval = this.setInterval(this.sendScan.bind(this), this.config.searchInterval * 1e3);
|
|
87
99
|
if (deviceSearchInterval) {
|
|
88
100
|
searchInterval = deviceSearchInterval;
|
|
@@ -94,21 +106,23 @@ class GoveeLocal extends utils.Adapter {
|
|
|
94
106
|
if (deviceRefreshInterval) {
|
|
95
107
|
refreshInterval = deviceRefreshInterval;
|
|
96
108
|
}
|
|
109
|
+
return Promise.resolve();
|
|
97
110
|
}
|
|
98
111
|
/**
|
|
99
112
|
* handle icoming messages on the udp socket
|
|
113
|
+
*
|
|
100
114
|
* @param message the message itself
|
|
101
115
|
* @param remote the sender of the message
|
|
102
116
|
*/
|
|
103
117
|
async onUdpMessage(message, remote) {
|
|
104
118
|
const messageObject = JSON.parse(message.toString());
|
|
105
119
|
switch (messageObject.msg.cmd) {
|
|
106
|
-
case "scan":
|
|
120
|
+
case "scan": {
|
|
107
121
|
for (const key of Object.keys(messageObject.msg.data)) {
|
|
108
122
|
if (key != "device") {
|
|
109
123
|
const deviceName = messageObject.msg.data.device.replace(this.FORBIDDEN_CHARS, "_");
|
|
110
124
|
devices[remote.address] = deviceName;
|
|
111
|
-
this.setObjectNotExists(deviceName, {
|
|
125
|
+
void this.setObjectNotExists(deviceName, {
|
|
112
126
|
type: "device",
|
|
113
127
|
common: {
|
|
114
128
|
name: messageObject.msg.data.sku,
|
|
@@ -116,7 +130,7 @@ class GoveeLocal extends utils.Adapter {
|
|
|
116
130
|
},
|
|
117
131
|
native: {}
|
|
118
132
|
});
|
|
119
|
-
this.setObjectNotExists(`${deviceName}.deviceInfo.${key}`, {
|
|
133
|
+
void this.setObjectNotExists(`${deviceName}.deviceInfo.${key}`, {
|
|
120
134
|
type: "state",
|
|
121
135
|
common: {
|
|
122
136
|
name: getDatapointDescription(key),
|
|
@@ -127,11 +141,12 @@ class GoveeLocal extends utils.Adapter {
|
|
|
127
141
|
},
|
|
128
142
|
native: {}
|
|
129
143
|
});
|
|
130
|
-
|
|
144
|
+
void this.updateStateAsync(`${deviceName}.deviceInfo.${key}`, messageObject.msg.data[key]);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
break;
|
|
134
|
-
|
|
148
|
+
}
|
|
149
|
+
case "devStatus": {
|
|
135
150
|
const sendingDevice = devices[remote.address];
|
|
136
151
|
if (sendingDevice) {
|
|
137
152
|
if (this.config.extendedLogging && !loggedDevices.includes(remote.address.toString())) {
|
|
@@ -139,7 +154,7 @@ class GoveeLocal extends utils.Adapter {
|
|
|
139
154
|
loggedDevices.push(remote.address.toString());
|
|
140
155
|
}
|
|
141
156
|
const devStatusMessageObject = JSON.parse(message.toString());
|
|
142
|
-
this.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {
|
|
157
|
+
void this.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {
|
|
143
158
|
type: "state",
|
|
144
159
|
common: {
|
|
145
160
|
name: "On / Off state of the lamp",
|
|
@@ -150,11 +165,11 @@ class GoveeLocal extends utils.Adapter {
|
|
|
150
165
|
},
|
|
151
166
|
native: {}
|
|
152
167
|
});
|
|
153
|
-
|
|
168
|
+
void this.updateStateAsync(
|
|
154
169
|
`${sendingDevice}.devStatus.onOff`,
|
|
155
170
|
devStatusMessageObject.msg.data.onOff == 1
|
|
156
171
|
);
|
|
157
|
-
this.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {
|
|
172
|
+
void this.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {
|
|
158
173
|
type: "state",
|
|
159
174
|
common: {
|
|
160
175
|
name: "Brightness of the light",
|
|
@@ -165,11 +180,11 @@ class GoveeLocal extends utils.Adapter {
|
|
|
165
180
|
},
|
|
166
181
|
native: {}
|
|
167
182
|
});
|
|
168
|
-
|
|
183
|
+
void this.updateStateAsync(
|
|
169
184
|
`${sendingDevice}.devStatus.brightness`,
|
|
170
185
|
devStatusMessageObject.msg.data.brightness
|
|
171
186
|
);
|
|
172
|
-
this.setObjectNotExists(`${sendingDevice}.devStatus.color`, {
|
|
187
|
+
void this.setObjectNotExists(`${sendingDevice}.devStatus.color`, {
|
|
173
188
|
type: "state",
|
|
174
189
|
common: {
|
|
175
190
|
name: "Current showing color of the lamp",
|
|
@@ -180,15 +195,13 @@ class GoveeLocal extends utils.Adapter {
|
|
|
180
195
|
},
|
|
181
196
|
native: {}
|
|
182
197
|
});
|
|
183
|
-
|
|
184
|
-
|
|
198
|
+
const colorString = `#${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.r)}${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.g)}${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.b)}`;
|
|
199
|
+
void this.setState(`${sendingDevice}.devStatus.color`, {
|
|
200
|
+
val: colorString,
|
|
185
201
|
ack: true
|
|
186
202
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`#${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.r)}${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.g)}${(0, import_hexTool.componentToHex)(devStatusMessageObject.msg.data.color.b)}`
|
|
190
|
-
);
|
|
191
|
-
this.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {
|
|
203
|
+
void this.updateStateAsync(`${sendingDevice}.devStatus.color`, colorString);
|
|
204
|
+
void this.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {
|
|
192
205
|
type: "state",
|
|
193
206
|
common: {
|
|
194
207
|
name: "If staying in white light, the color temperature",
|
|
@@ -199,45 +212,53 @@ class GoveeLocal extends utils.Adapter {
|
|
|
199
212
|
},
|
|
200
213
|
native: {}
|
|
201
214
|
});
|
|
202
|
-
|
|
215
|
+
void this.updateStateAsync(
|
|
203
216
|
`${sendingDevice}.devStatus.colorTemInKelvin`,
|
|
204
217
|
devStatusMessageObject.msg.data.colorTemInKelvin
|
|
205
218
|
);
|
|
206
219
|
}
|
|
207
220
|
break;
|
|
208
|
-
|
|
209
|
-
|
|
221
|
+
}
|
|
222
|
+
default: {
|
|
223
|
+
this.log.error(`message from: ${remote.address}:${remote.port} - ${message.toString()}`);
|
|
224
|
+
}
|
|
210
225
|
}
|
|
226
|
+
return Promise.resolve();
|
|
211
227
|
}
|
|
212
228
|
async refreshAllDevices() {
|
|
213
229
|
for (const ip in devices) {
|
|
214
230
|
this.requestDeviceStatus(ip);
|
|
215
231
|
}
|
|
232
|
+
return Promise.resolve();
|
|
216
233
|
}
|
|
217
234
|
/**
|
|
218
235
|
* sends the device status request to one specific device
|
|
236
|
+
*
|
|
219
237
|
* @param receiver the ip ( / hsotname ) of the device that should be queried
|
|
220
238
|
*/
|
|
221
239
|
requestDeviceStatus(receiver) {
|
|
222
240
|
const requestDeviceStatusBuffer = Buffer.from(JSON.stringify(requestStatusMessage));
|
|
223
|
-
socket.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);
|
|
241
|
+
void socket.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);
|
|
224
242
|
}
|
|
225
243
|
/**
|
|
226
244
|
* send the scan message to the udp multicast address
|
|
227
245
|
*/
|
|
228
246
|
async sendScan() {
|
|
229
247
|
const scanMessageBuffer = Buffer.from(JSON.stringify(scanMessage));
|
|
230
|
-
socket.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);
|
|
248
|
+
void socket.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);
|
|
249
|
+
return Promise.resolve();
|
|
231
250
|
}
|
|
232
251
|
/**
|
|
233
252
|
* Is called when adapter shuts down - callback has to be called under any circumstances!
|
|
253
|
+
*
|
|
254
|
+
* @param callback Callback-Funktion, die nach Abschluss des Unload-Prozesses aufgerufen wird.
|
|
234
255
|
*/
|
|
235
256
|
onUnload(callback) {
|
|
236
257
|
try {
|
|
237
258
|
this.clearInterval(searchInterval);
|
|
238
259
|
this.clearInterval(refreshInterval);
|
|
239
260
|
socket.close();
|
|
240
|
-
this.updateStateAsync("info.connection", false);
|
|
261
|
+
void this.updateStateAsync("info.connection", false);
|
|
241
262
|
callback();
|
|
242
263
|
} catch (e) {
|
|
243
264
|
this.log.error(e.message);
|
|
@@ -246,25 +267,36 @@ class GoveeLocal extends utils.Adapter {
|
|
|
246
267
|
}
|
|
247
268
|
/**
|
|
248
269
|
* Is called if a subscribed state changes
|
|
270
|
+
*
|
|
271
|
+
* @param id Die ID des geänderten States.
|
|
272
|
+
* @param state Das neue State-Objekt oder null/undefined.
|
|
249
273
|
*/
|
|
250
274
|
async onStateChange(id, state) {
|
|
251
275
|
var _a, _b;
|
|
252
276
|
if (state && !state.ack) {
|
|
253
|
-
const ipOfDevice = await this.getStateAsync(id.split(".")[2]
|
|
277
|
+
const ipOfDevice = await this.getStateAsync(`${id.split(".")[2]}.deviceInfo.ip`);
|
|
254
278
|
if (ipOfDevice) {
|
|
255
279
|
const receiver = (_a = ipOfDevice.val) == null ? void 0 : _a.toString();
|
|
256
280
|
switch (id.split(".")[4]) {
|
|
257
|
-
case "onOff":
|
|
281
|
+
case "onOff": {
|
|
258
282
|
const turnMessage = { msg: { cmd: "turn", data: { value: state.val ? 1 : 0 } } };
|
|
259
283
|
const turnMessageBuffer = Buffer.from(JSON.stringify(turnMessage));
|
|
260
|
-
socket.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);
|
|
284
|
+
void socket.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);
|
|
261
285
|
break;
|
|
262
|
-
|
|
286
|
+
}
|
|
287
|
+
case "brightness": {
|
|
263
288
|
const brightnessMessage = { msg: { cmd: "brightness", data: { value: state.val } } };
|
|
264
289
|
const brightnessMessageBuffer = Buffer.from(JSON.stringify(brightnessMessage));
|
|
265
|
-
socket.send(
|
|
290
|
+
void socket.send(
|
|
291
|
+
brightnessMessageBuffer,
|
|
292
|
+
0,
|
|
293
|
+
brightnessMessageBuffer.length,
|
|
294
|
+
CONTROL_PORT,
|
|
295
|
+
receiver
|
|
296
|
+
);
|
|
266
297
|
break;
|
|
267
|
-
|
|
298
|
+
}
|
|
299
|
+
case "colorTemInKelvin": {
|
|
268
300
|
const colorTempMessageBuffer = Buffer.from(
|
|
269
301
|
JSON.stringify({
|
|
270
302
|
msg: {
|
|
@@ -273,27 +305,36 @@ class GoveeLocal extends utils.Adapter {
|
|
|
273
305
|
}
|
|
274
306
|
})
|
|
275
307
|
);
|
|
276
|
-
socket.send(
|
|
308
|
+
void socket.send(
|
|
309
|
+
colorTempMessageBuffer,
|
|
310
|
+
0,
|
|
311
|
+
colorTempMessageBuffer.length,
|
|
312
|
+
CONTROL_PORT,
|
|
313
|
+
receiver
|
|
314
|
+
);
|
|
277
315
|
break;
|
|
278
|
-
|
|
316
|
+
}
|
|
317
|
+
case "color": {
|
|
279
318
|
const colorValue = (_b = state.val) == null ? void 0 : _b.toString();
|
|
280
319
|
if (colorValue) {
|
|
281
320
|
const rgb = (0, import_hexTool.hexToRgb)(colorValue);
|
|
282
321
|
const colorMessage = { msg: { cmd: "colorwc", data: { color: rgb } } };
|
|
283
322
|
const colorMessageBuffer = Buffer.from(JSON.stringify(colorMessage));
|
|
284
|
-
socket.send(colorMessageBuffer, 0, colorMessageBuffer.length, CONTROL_PORT, receiver);
|
|
323
|
+
void socket.send(colorMessageBuffer, 0, colorMessageBuffer.length, CONTROL_PORT, receiver);
|
|
285
324
|
}
|
|
286
325
|
break;
|
|
326
|
+
}
|
|
287
327
|
}
|
|
288
328
|
} else {
|
|
289
329
|
this.log.error("device not found");
|
|
290
330
|
}
|
|
291
331
|
}
|
|
332
|
+
return Promise.resolve();
|
|
292
333
|
}
|
|
293
334
|
async updateStateAsync(fullName, state, acknowledged = true) {
|
|
294
335
|
const currentState = await this.getStateAsync(fullName);
|
|
295
336
|
if (currentState != state) {
|
|
296
|
-
this.setState(fullName, {
|
|
337
|
+
void this.setState(fullName, {
|
|
297
338
|
val: state,
|
|
298
339
|
ack: acknowledged
|
|
299
340
|
});
|
|
@@ -323,4 +364,9 @@ function getDatapointDescription(name) {
|
|
|
323
364
|
return "";
|
|
324
365
|
}
|
|
325
366
|
}
|
|
367
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
368
|
+
0 && (module.exports = {
|
|
369
|
+
GoveeLocal,
|
|
370
|
+
getDatapointDescription
|
|
371
|
+
});
|
|
326
372
|
//# sourceMappingURL=main.js.map
|
package/build/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.3.0\n */\n\n// The adapter-core module gives you access to the core ioBroker functions\n// you need to create an adapter\nimport * as utils from '@iobroker/adapter-core';\nimport * as dgram from 'node:dgram';\nimport { componentToHex, hexToRgb } from './tools/hexTool';\n\n// Load your modules here, e.g.:\n\nconst LOCAL_PORT = 4002;\nconst SEND_SCAN_PORT = 4001;\nconst CONTROL_PORT = 4003;\nconst M_CAST = '239.255.255.250';\n\nconst socket = dgram.createSocket({ type: 'udp4' });\n\nconst scanMessage = { msg: { cmd: 'scan', data: { account_topic: 'reserved' } } };\nconst requestStatusMessage = { msg: { cmd: 'devStatus', data: {} } };\n\nlet searchInterval: ioBroker.Interval;\nlet refreshInterval: ioBroker.Interval;\n\nconst devices: { [ip: string]: string } = {};\n\nconst loggedDevices = [] as string[];\n\nclass GoveeLocal extends utils.Adapter {\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: 'govee-local',\n\t\t});\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\t// this.on('objectChange', this.onObjectChange.bind(this));\n\t\t// this.on('message', this.onMessage.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t/**\n\t * Is called when databases are connected and adapter received configuration.\n\t */\n\tprivate async onReady(): Promise<void> {\n\t\tthis.setObjectNotExists('info.connection', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device discovery running',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'indicator.connected',\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tsocket.on('message', this.onUdpMessage.bind(this));\n\t\tsocket.on('error', (error) => {\n\t\t\tthis.log.error('server bind error : ' + error.message);\n\t\t\tthis.setStateChanged('info.connection', { val: false, ack: true });\n\t\t});\n\n\t\tif (this.config.extendedLogging) {\n\t\t\tthis.log.debug('running with extended logging');\n\t\t}\n\n\t\tsocket.bind({ address: this.config.interface, port: LOCAL_PORT }, this.serverBound.bind(this));\n\t\tthis.subscribeStates('*.devStatus.*');\n\t}\n\n\t/**\n\t * handles when udp socket is up\n\t * configure multicast membership\n\t * start periodic scan for devices\n\t */\n\tprivate async serverBound(): Promise<void> {\n\t\tsocket.setBroadcast(true);\n\t\tsocket.setMulticastTTL(128);\n\t\tsocket.setMulticastInterface(this.config.interface);\n\t\tsocket.addMembership(M_CAST);\n\t\tthis.setStateChanged('info.connection', { val: true, ack: true });\n\t\tthis.log.debug('UDP listening on ' + socket.address().address + ':' + socket.address().port);\n\n\t\tconst deviceSearchInterval = this.setInterval(this.sendScan.bind(this), this.config.searchInterval * 1000);\n\t\tif (deviceSearchInterval) {\n\t\t\tsearchInterval = deviceSearchInterval;\n\t\t}\n\n\t\tconst deviceRefreshInterval = this.setInterval(\n\t\t\tthis.refreshAllDevices.bind(this),\n\t\t\tthis.config.deviceStatusRefreshInterval * 1000,\n\t\t);\n\t\tif (deviceRefreshInterval) {\n\t\t\trefreshInterval = deviceRefreshInterval;\n\t\t}\n\t}\n\n\t/**\n\t * handle icoming messages on the udp socket\n\t * @param message the message itself\n\t * @param remote the sender of the message\n\t */\n\tprivate async onUdpMessage(message: Buffer, remote: dgram.RemoteInfo): Promise<void> {\n\t\tconst messageObject = JSON.parse(message.toString());\n\t\tswitch (messageObject.msg.cmd) {\n\t\t\tcase 'scan':\n\t\t\t\tfor (const key of Object.keys(messageObject.msg.data)) {\n\t\t\t\t\tif (key != 'device') {\n\t\t\t\t\t\tconst deviceName = messageObject.msg.data.device.replace(this.FORBIDDEN_CHARS, '_');\n\t\t\t\t\t\tdevices[remote.address] = deviceName;\n\t\t\t\t\t\tthis.setObjectNotExists(deviceName, {\n\t\t\t\t\t\t\ttype: 'device',\n\t\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\t\tname: messageObject.msg.data.sku,\n\t\t\t\t\t\t\t\trole: 'group',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnative: {},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthis.setObjectNotExists(`${deviceName}.deviceInfo.${key}`, {\n\t\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\t\tname: getDatapointDescription(key),\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnative: {},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait this.updateStateAsync(`${deviceName}.deviceInfo.${key}`, messageObject.msg.data[key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'devStatus':\n\t\t\t\tconst sendingDevice = devices[remote.address];\n\t\t\t\tif (sendingDevice) {\n\t\t\t\t\t// const devices = await this.getStatesAsync(`${this.name}.${this.instance}.*.deviceInfo.ip`);\n\t\t\t\t\tif (this.config.extendedLogging && !loggedDevices.includes(remote.address.toString())) {\n\t\t\t\t\t\tthis.log.info(`deivce status message data: ${JSON.stringify(messageObject)}`);\n\t\t\t\t\t\tloggedDevices.push(remote.address.toString());\n\t\t\t\t\t}\n\t\t\t\t\tconst devStatusMessageObject = JSON.parse(message.toString());\n\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'On / Off state of the lamp',\n\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\trole: 'switch',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tawait this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.onOff`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.onOff == 1,\n\t\t\t\t\t);\n\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Brightness of the light',\n\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\trole: 'level.dimmer',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tawait this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.brightness`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.brightness,\n\t\t\t\t\t);\n\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.color`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Current showing color of the lamp',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'level.color.rgb',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.color`, {\n\t\t\t\t\t\tval:\n\t\t\t\t\t\t\t'#' +\n\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.r) +\n\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.g) +\n\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.b),\n\t\t\t\t\t\tack: true,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.color`,\n\t\t\t\t\t\t`#${componentToHex(devStatusMessageObject.msg.data.color.r)}${componentToHex(devStatusMessageObject.msg.data.color.g)}${componentToHex(devStatusMessageObject.msg.data.color.b)}`,\n\t\t\t\t\t);\n\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'If staying in white light, the color temperature',\n\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\trole: 'level.color.temperature',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tawait this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.colorTemInKelvin`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.colorTemInKelvin,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.log.error('message from: ' + remote.address + ':' + remote.port + ' - ' + message);\n\t\t}\n\t}\n\n\tprivate async refreshAllDevices(): Promise<void> {\n\t\tfor (const ip in devices) {\n\t\t\tthis.requestDeviceStatus(ip);\n\t\t}\n\t}\n\n\t/**\n\t * sends the device status request to one specific device\n\t * @param receiver the ip ( / hsotname ) of the device that should be queried\n\t */\n\tprivate requestDeviceStatus(receiver: string): void {\n\t\tconst requestDeviceStatusBuffer = Buffer.from(JSON.stringify(requestStatusMessage));\n\t\tsocket.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);\n\t}\n\n\t/**\n\t * send the scan message to the udp multicast address\n\t */\n\tprivate async sendScan(): Promise<void> {\n\t\tconst scanMessageBuffer = Buffer.from(JSON.stringify(scanMessage));\n\t\tsocket.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);\n\t}\n\n\t/**\n\t * Is called when adapter shuts down - callback has to be called under any circumstances!\n\t */\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tthis.clearInterval(searchInterval);\n\t\t\tthis.clearInterval(refreshInterval);\n\t\t\tsocket.close();\n\t\t\tthis.updateStateAsync('info.connection', false);\n\t\t\tcallback();\n\t\t} catch (e: any) {\n\t\t\tthis.log.error(e.message);\n\t\t\tcallback();\n\t\t}\n\t}\n\n\t/**\n\t * Is called if a subscribed state changes\n\t */\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (state && !state.ack) {\n\t\t\tconst ipOfDevice = await this.getStateAsync(id.split('.')[2] + '.deviceInfo.ip');\n\t\t\tif (ipOfDevice) {\n\t\t\t\tconst receiver = ipOfDevice.val?.toString();\n\t\t\t\tswitch (id.split('.')[4]) {\n\t\t\t\t\tcase 'onOff':\n\t\t\t\t\t\tconst turnMessage = { msg: { cmd: 'turn', data: { value: state.val ? 1 : 0 } } };\n\t\t\t\t\t\tconst turnMessageBuffer = Buffer.from(JSON.stringify(turnMessage));\n\t\t\t\t\t\tsocket.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'brightness':\n\t\t\t\t\t\tconst brightnessMessage = { msg: { cmd: 'brightness', data: { value: state.val } } };\n\t\t\t\t\t\tconst brightnessMessageBuffer = Buffer.from(JSON.stringify(brightnessMessage));\n\t\t\t\t\t\tsocket.send(brightnessMessageBuffer, 0, brightnessMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'colorTemInKelvin':\n\t\t\t\t\t\tconst colorTempMessageBuffer = Buffer.from(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\tmsg: {\n\t\t\t\t\t\t\t\t\tcmd: 'colorwc',\n\t\t\t\t\t\t\t\t\tdata: { color: { r: '0', g: '0', b: '0' }, colorTemInKelvin: state.val },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsocket.send(colorTempMessageBuffer, 0, colorTempMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'color':\n\t\t\t\t\t\tconst colorValue = state.val?.toString();\n\t\t\t\t\t\tif (colorValue) {\n\t\t\t\t\t\t\tconst rgb = hexToRgb(colorValue);\n\t\t\t\t\t\t\tconst colorMessage = { msg: { cmd: 'colorwc', data: { color: rgb } } };\n\t\t\t\t\t\t\tconst colorMessageBuffer = Buffer.from(JSON.stringify(colorMessage));\n\t\t\t\t\t\t\tsocket.send(colorMessageBuffer, 0, colorMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.log.error('device not found');\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async updateStateAsync(fullName: string, state: any, acknowledged = true): Promise<void> {\n\t\tconst currentState = await this.getStateAsync(fullName);\n\t\tif (currentState != state) {\n\t\t\tthis.setState(fullName, {\n\t\t\t\tval: state,\n\t\t\t\tack: acknowledged,\n\t\t\t});\n\t\t}\n\t}\n}\n\nif (require.main !== module) {\n\t// Export the constructor in compact mode\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new GoveeLocal(options);\n} else {\n\t// otherwise start the instance directly\n\t(() => new GoveeLocal())();\n}\n\n/**\n * This method returns the description for device information datapoints\n * to unbloat the upper methods.\n * tanslations would be great here\n * @param name the name of the parameter retrieved from the device\n * @returns the description, that should be set to the datapoint\n */\nfunction getDatapointDescription(name: string): string {\n\tswitch (name) {\n\t\tcase 'model':\n\t\t\treturn 'Specific model of the Lamp';\n\t\tcase 'ip':\n\t\t\treturn 'IP address of the Lamp';\n\t\tcase 'bleVersionHard':\n\t\t\treturn 'Bluetooth Low Energy Hardware Version';\n\t\tcase 'bleVersionSoft':\n\t\t\treturn 'Bluetooth Low Energy Software Version';\n\t\tcase 'wifiVersionHard':\n\t\t\treturn 'WiFi Hardware Version';\n\t\tcase 'wifiVersionSoft':\n\t\t\treturn 'WiFi Software Version';\n\t\tdefault:\n\t\t\treturn '';\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.3.0\n */\n\n// The adapter-core module gives you access to the core ioBroker functions\n// you need to create an adapter\nimport * as utils from '@iobroker/adapter-core';\nimport * as dgram from 'node:dgram';\nimport { componentToHex, hexToRgb } from './tools/hexTool';\n\n// Load your modules here, e.g.:\n\nconst LOCAL_PORT = 4002;\nconst SEND_SCAN_PORT = 4001;\nconst CONTROL_PORT = 4003;\nconst M_CAST = '239.255.255.250';\n\nconst socket = dgram.createSocket({ type: 'udp4' });\n\nconst scanMessage = { msg: { cmd: 'scan', data: { account_topic: 'reserved' } } };\nconst requestStatusMessage = { msg: { cmd: 'devStatus', data: {} } };\n\nlet searchInterval: ioBroker.Interval;\nlet refreshInterval: ioBroker.Interval;\n\nconst devices: { [ip: string]: string } = {};\n\nconst loggedDevices = [] as string[];\n\nexport class GoveeLocal extends utils.Adapter {\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: 'govee-local',\n\t\t});\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\t// this.on('objectChange', this.onObjectChange.bind(this));\n\t\t// this.on('message', this.onMessage.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t/**\n\t * Is called when databases are connected and adapter received configuration.\n\t */\n\tprivate async onReady(): Promise<void> {\n\t\tvoid this.setObjectNotExists('info.connection', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device discovery running',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'indicator.connected',\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tsocket.on('message', this.onUdpMessage.bind(this));\n\t\tsocket.on('error', (error) => {\n\t\t\tthis.log.error(`server bind error : ${error.message}`);\n\t\t\tvoid this.setStateChanged('info.connection', { val: false, ack: true });\n\t\t});\n\n\t\tif (this.config.extendedLogging) {\n\t\t\tthis.log.debug('running with extended logging');\n\t\t}\n\n\t\tvoid socket.bind({ address: this.config.interface, port: LOCAL_PORT }, this.serverBound.bind(this));\n\t\tvoid this.subscribeStates('*.devStatus.*');\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * handles when udp socket is up\n\t * configure multicast membership\n\t * start periodic scan for devices\n\t */\n\tprivate async serverBound(): Promise<void> {\n\t\tsocket.setBroadcast(true);\n\t\tsocket.setMulticastTTL(128);\n\t\tsocket.setMulticastInterface(this.config.interface);\n\t\tsocket.addMembership(M_CAST);\n\t\tvoid this.setStateChanged('info.connection', { val: true, ack: true });\n\t\tthis.log.debug(`UDP listening on ${(socket.address() as any).address}:${(socket.address() as any).port}`);\n\n\t\tconst deviceSearchInterval = this.setInterval(this.sendScan.bind(this), this.config.searchInterval * 1000);\n\t\tif (deviceSearchInterval) {\n\t\t\tsearchInterval = deviceSearchInterval;\n\t\t}\n\n\t\tconst deviceRefreshInterval = this.setInterval(\n\t\t\tthis.refreshAllDevices.bind(this),\n\t\t\tthis.config.deviceStatusRefreshInterval * 1000,\n\t\t);\n\t\tif (deviceRefreshInterval) {\n\t\t\trefreshInterval = deviceRefreshInterval;\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * handle icoming messages on the udp socket\n\t *\n\t * @param message the message itself\n\t * @param remote the sender of the message\n\t */\n\tprivate async onUdpMessage(message: Buffer, remote: dgram.RemoteInfo): Promise<void> {\n\t\tconst messageObject = JSON.parse(message.toString());\n\t\tswitch (messageObject.msg.cmd) {\n\t\t\tcase 'scan': {\n\t\t\t\tfor (const key of Object.keys(messageObject.msg.data)) {\n\t\t\t\t\tif (key != 'device') {\n\t\t\t\t\t\tconst deviceName = messageObject.msg.data.device.replace(this.FORBIDDEN_CHARS, '_');\n\t\t\t\t\t\tdevices[remote.address] = deviceName;\n\t\t\t\t\t\tvoid this.setObjectNotExists(deviceName, {\n\t\t\t\t\t\t\ttype: 'device',\n\t\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\t\tname: messageObject.msg.data.sku,\n\t\t\t\t\t\t\t\trole: 'group',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnative: {},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tvoid this.setObjectNotExists(`${deviceName}.deviceInfo.${key}`, {\n\t\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\t\tname: getDatapointDescription(key),\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnative: {},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tvoid this.updateStateAsync(`${deviceName}.deviceInfo.${key}`, messageObject.msg.data[key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'devStatus': {\n\t\t\t\tconst sendingDevice = devices[remote.address];\n\t\t\t\tif (sendingDevice) {\n\t\t\t\t\tif (this.config.extendedLogging && !loggedDevices.includes(remote.address.toString())) {\n\t\t\t\t\t\tthis.log.info(`deivce status message data: ${JSON.stringify(messageObject)}`);\n\t\t\t\t\t\tloggedDevices.push(remote.address.toString());\n\t\t\t\t\t}\n\t\t\t\t\tconst devStatusMessageObject = JSON.parse(message.toString());\n\t\t\t\t\tvoid this.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'On / Off state of the lamp',\n\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\trole: 'switch',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tvoid this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.onOff`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.onOff == 1,\n\t\t\t\t\t);\n\t\t\t\t\tvoid this.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Brightness of the light',\n\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\trole: 'level.dimmer',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tvoid this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.brightness`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.brightness,\n\t\t\t\t\t);\n\t\t\t\t\tvoid this.setObjectNotExists(`${sendingDevice}.devStatus.color`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Current showing color of the lamp',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'level.color.rgb',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tconst colorString = `#${componentToHex(devStatusMessageObject.msg.data.color.r)}${componentToHex(devStatusMessageObject.msg.data.color.g)}${componentToHex(devStatusMessageObject.msg.data.color.b)}`;\n\t\t\t\t\tvoid this.setState(`${sendingDevice}.devStatus.color`, {\n\t\t\t\t\t\tval: colorString,\n\t\t\t\t\t\tack: true,\n\t\t\t\t\t});\n\t\t\t\t\tvoid this.updateStateAsync(`${sendingDevice}.devStatus.color`, colorString);\n\t\t\t\t\tvoid this.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'If staying in white light, the color temperature',\n\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\trole: 'level.color.temperature',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tvoid this.updateStateAsync(\n\t\t\t\t\t\t`${sendingDevice}.devStatus.colorTemInKelvin`,\n\t\t\t\t\t\tdevStatusMessageObject.msg.data.colorTemInKelvin,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthis.log.error(`message from: ${remote.address}:${remote.port} - ${message.toString()}`);\n\t\t\t}\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\n\tprivate async refreshAllDevices(): Promise<void> {\n\t\tfor (const ip in devices) {\n\t\t\tthis.requestDeviceStatus(ip);\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * sends the device status request to one specific device\n\t *\n\t * @param receiver the ip ( / hsotname ) of the device that should be queried\n\t */\n\tprivate requestDeviceStatus(receiver: string): void {\n\t\tconst requestDeviceStatusBuffer = Buffer.from(JSON.stringify(requestStatusMessage));\n\t\tvoid socket.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);\n\t}\n\n\t/**\n\t * send the scan message to the udp multicast address\n\t */\n\tprivate async sendScan(): Promise<void> {\n\t\tconst scanMessageBuffer = Buffer.from(JSON.stringify(scanMessage));\n\t\tvoid socket.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Is called when adapter shuts down - callback has to be called under any circumstances!\n\t *\n\t * @param callback Callback-Funktion, die nach Abschluss des Unload-Prozesses aufgerufen wird.\n\t */\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tthis.clearInterval(searchInterval);\n\t\t\tthis.clearInterval(refreshInterval);\n\t\t\tsocket.close();\n\t\t\tvoid this.updateStateAsync('info.connection', false);\n\t\t\tcallback();\n\t\t} catch (e: any) {\n\t\t\tthis.log.error(e.message);\n\t\t\tcallback();\n\t\t}\n\t}\n\n\t/**\n\t * Is called if a subscribed state changes\n\t *\n\t * @param id Die ID des ge\u00E4nderten States.\n\t * @param state Das neue State-Objekt oder null/undefined.\n\t */\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (state && !state.ack) {\n\t\t\tconst ipOfDevice = await this.getStateAsync(`${id.split('.')[2]}.deviceInfo.ip`);\n\t\t\tif (ipOfDevice) {\n\t\t\t\tconst receiver = ipOfDevice.val?.toString();\n\t\t\t\tswitch (id.split('.')[4]) {\n\t\t\t\t\tcase 'onOff': {\n\t\t\t\t\t\tconst turnMessage = { msg: { cmd: 'turn', data: { value: state.val ? 1 : 0 } } };\n\t\t\t\t\t\tconst turnMessageBuffer = Buffer.from(JSON.stringify(turnMessage));\n\t\t\t\t\t\tvoid socket.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'brightness': {\n\t\t\t\t\t\tconst brightnessMessage = { msg: { cmd: 'brightness', data: { value: state.val } } };\n\t\t\t\t\t\tconst brightnessMessageBuffer = Buffer.from(JSON.stringify(brightnessMessage));\n\t\t\t\t\t\tvoid socket.send(\n\t\t\t\t\t\t\tbrightnessMessageBuffer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tbrightnessMessageBuffer.length,\n\t\t\t\t\t\t\tCONTROL_PORT,\n\t\t\t\t\t\t\treceiver,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'colorTemInKelvin': {\n\t\t\t\t\t\tconst colorTempMessageBuffer = Buffer.from(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\tmsg: {\n\t\t\t\t\t\t\t\t\tcmd: 'colorwc',\n\t\t\t\t\t\t\t\t\tdata: { color: { r: '0', g: '0', b: '0' }, colorTemInKelvin: state.val },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tvoid socket.send(\n\t\t\t\t\t\t\tcolorTempMessageBuffer,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tcolorTempMessageBuffer.length,\n\t\t\t\t\t\t\tCONTROL_PORT,\n\t\t\t\t\t\t\treceiver,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'color': {\n\t\t\t\t\t\tconst colorValue = state.val?.toString();\n\t\t\t\t\t\tif (colorValue) {\n\t\t\t\t\t\t\tconst rgb = hexToRgb(colorValue);\n\t\t\t\t\t\t\tconst colorMessage = { msg: { cmd: 'colorwc', data: { color: rgb } } };\n\t\t\t\t\t\t\tconst colorMessageBuffer = Buffer.from(JSON.stringify(colorMessage));\n\t\t\t\t\t\t\tvoid socket.send(colorMessageBuffer, 0, colorMessageBuffer.length, CONTROL_PORT, receiver);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.log.error('device not found');\n\t\t\t}\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\n\tprivate async updateStateAsync(fullName: string, state: any, acknowledged = true): Promise<void> {\n\t\tconst currentState = await this.getStateAsync(fullName);\n\t\tif (currentState != state) {\n\t\t\tvoid this.setState(fullName, {\n\t\t\t\tval: state,\n\t\t\t\tack: acknowledged,\n\t\t\t});\n\t\t}\n\t}\n}\n\nif (require.main !== module) {\n\t// Exportiere eine Factory-Funktion f\u00FCr ioBroker, aber die Klasse ist jetzt auch als ES6-Export verf\u00FCgbar\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new GoveeLocal(options);\n} else {\n\t// otherwise start the instance directly\n\t(() => new GoveeLocal())();\n}\n\n/**\n * This method returns the description for device information datapoints\n * to unbloat the upper methods.\n * tanslations would be great here\n *\n * @param name the name of the parameter retrieved from the device\n * @returns the description, that should be set to the datapoint\n */\nexport function getDatapointDescription(name: string): string {\n\tswitch (name) {\n\t\tcase 'model':\n\t\t\treturn 'Specific model of the Lamp';\n\t\tcase 'ip':\n\t\t\treturn 'IP address of the Lamp';\n\t\tcase 'bleVersionHard':\n\t\t\treturn 'Bluetooth Low Energy Hardware Version';\n\t\tcase 'bleVersionSoft':\n\t\t\treturn 'Bluetooth Low Energy Software Version';\n\t\tcase 'wifiVersionHard':\n\t\t\treturn 'WiFi Hardware Version';\n\t\tcase 'wifiVersionSoft':\n\t\t\treturn 'WiFi Software Version';\n\t\tdefault:\n\t\t\treturn '';\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,YAAuB;AACvB,YAAuB;AACvB,qBAAyC;AAIzC,MAAM,aAAa;AACnB,MAAM,iBAAiB;AACvB,MAAM,eAAe;AACrB,MAAM,SAAS;AAEf,MAAM,SAAS,MAAM,aAAa,EAAE,MAAM,OAAO,CAAC;AAElD,MAAM,cAAc,EAAE,KAAK,EAAE,KAAK,QAAQ,MAAM,EAAE,eAAe,WAAW,EAAE,EAAE;AAChF,MAAM,uBAAuB,EAAE,KAAK,EAAE,KAAK,aAAa,MAAM,CAAC,EAAE,EAAE;AAEnE,IAAI;AACJ,IAAI;AAEJ,MAAM,UAAoC,CAAC;AAE3C,MAAM,gBAAgB,CAAC;AAEhB,MAAM,mBAAmB,MAAM,QAAQ;AAAA,EACtC,YAAY,UAAyC,CAAC,GAAG;AAC/D,UAAM;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACP,CAAC;AACD,SAAK,GAAG,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxC,SAAK,GAAG,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAGpD,SAAK,GAAG,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAyB;AACtC,SAAK,KAAK,mBAAmB,mBAAmB;AAAA,MAC/C,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AACD,WAAO,GAAG,WAAW,KAAK,aAAa,KAAK,IAAI,CAAC;AACjD,WAAO,GAAG,SAAS,CAAC,UAAU;AAC7B,WAAK,IAAI,MAAM,uBAAuB,MAAM,OAAO,EAAE;AACrD,WAAK,KAAK,gBAAgB,mBAAmB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,IACvE,CAAC;AAED,QAAI,KAAK,OAAO,iBAAiB;AAChC,WAAK,IAAI,MAAM,+BAA+B;AAAA,IAC/C;AAEA,SAAK,OAAO,KAAK,EAAE,SAAS,KAAK,OAAO,WAAW,MAAM,WAAW,GAAG,KAAK,YAAY,KAAK,IAAI,CAAC;AAClG,SAAK,KAAK,gBAAgB,eAAe;AACzC,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,cAA6B;AAC1C,WAAO,aAAa,IAAI;AACxB,WAAO,gBAAgB,GAAG;AAC1B,WAAO,sBAAsB,KAAK,OAAO,SAAS;AAClD,WAAO,cAAc,MAAM;AAC3B,SAAK,KAAK,gBAAgB,mBAAmB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AACrE,SAAK,IAAI,MAAM,oBAAqB,OAAO,QAAQ,EAAU,OAAO,IAAK,OAAO,QAAQ,EAAU,IAAI,EAAE;AAExG,UAAM,uBAAuB,KAAK,YAAY,KAAK,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,iBAAiB,GAAI;AACzG,QAAI,sBAAsB;AACzB,uBAAiB;AAAA,IAClB;AAEA,UAAM,wBAAwB,KAAK;AAAA,MAClC,KAAK,kBAAkB,KAAK,IAAI;AAAA,MAChC,KAAK,OAAO,8BAA8B;AAAA,IAC3C;AACA,QAAI,uBAAuB;AAC1B,wBAAkB;AAAA,IACnB;AACA,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,aAAa,SAAiB,QAAyC;AACpF,UAAM,gBAAgB,KAAK,MAAM,QAAQ,SAAS,CAAC;AACnD,YAAQ,cAAc,IAAI,KAAK;AAAA,MAC9B,KAAK,QAAQ;AACZ,mBAAW,OAAO,OAAO,KAAK,cAAc,IAAI,IAAI,GAAG;AACtD,cAAI,OAAO,UAAU;AACpB,kBAAM,aAAa,cAAc,IAAI,KAAK,OAAO,QAAQ,KAAK,iBAAiB,GAAG;AAClF,oBAAQ,OAAO,OAAO,IAAI;AAC1B,iBAAK,KAAK,mBAAmB,YAAY;AAAA,cACxC,MAAM;AAAA,cACN,QAAQ;AAAA,gBACP,MAAM,cAAc,IAAI,KAAK;AAAA,gBAC7B,MAAM;AAAA,cACP;AAAA,cACA,QAAQ,CAAC;AAAA,YACV,CAAC;AACD,iBAAK,KAAK,mBAAmB,GAAG,UAAU,eAAe,GAAG,IAAI;AAAA,cAC/D,MAAM;AAAA,cACN,QAAQ;AAAA,gBACP,MAAM,wBAAwB,GAAG;AAAA,gBACjC,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,OAAO;AAAA,cACR;AAAA,cACA,QAAQ,CAAC;AAAA,YACV,CAAC;AACD,iBAAK,KAAK,iBAAiB,GAAG,UAAU,eAAe,GAAG,IAAI,cAAc,IAAI,KAAK,GAAG,CAAC;AAAA,UAC1F;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,KAAK,aAAa;AACjB,cAAM,gBAAgB,QAAQ,OAAO,OAAO;AAC5C,YAAI,eAAe;AAClB,cAAI,KAAK,OAAO,mBAAmB,CAAC,cAAc,SAAS,OAAO,QAAQ,SAAS,CAAC,GAAG;AACtF,iBAAK,IAAI,KAAK,+BAA+B,KAAK,UAAU,aAAa,CAAC,EAAE;AAC5E,0BAAc,KAAK,OAAO,QAAQ,SAAS,CAAC;AAAA,UAC7C;AACA,gBAAM,yBAAyB,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC5D,eAAK,KAAK,mBAAmB,GAAG,aAAa,oBAAoB;AAAA,YAChE,MAAM;AAAA,YACN,QAAQ;AAAA,cACP,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA,QAAQ,CAAC;AAAA,UACV,CAAC;AACD,eAAK,KAAK;AAAA,YACT,GAAG,aAAa;AAAA,YAChB,uBAAuB,IAAI,KAAK,SAAS;AAAA,UAC1C;AACA,eAAK,KAAK,mBAAmB,GAAG,aAAa,yBAAyB;AAAA,YACrE,MAAM;AAAA,YACN,QAAQ;AAAA,cACP,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA,QAAQ,CAAC;AAAA,UACV,CAAC;AACD,eAAK,KAAK;AAAA,YACT,GAAG,aAAa;AAAA,YAChB,uBAAuB,IAAI,KAAK;AAAA,UACjC;AACA,eAAK,KAAK,mBAAmB,GAAG,aAAa,oBAAoB;AAAA,YAChE,MAAM;AAAA,YACN,QAAQ;AAAA,cACP,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA,QAAQ,CAAC;AAAA,UACV,CAAC;AACD,gBAAM,cAAc,QAAI,+BAAe,uBAAuB,IAAI,KAAK,MAAM,CAAC,CAAC,OAAG,+BAAe,uBAAuB,IAAI,KAAK,MAAM,CAAC,CAAC,OAAG,+BAAe,uBAAuB,IAAI,KAAK,MAAM,CAAC,CAAC;AACnM,eAAK,KAAK,SAAS,GAAG,aAAa,oBAAoB;AAAA,YACtD,KAAK;AAAA,YACL,KAAK;AAAA,UACN,CAAC;AACD,eAAK,KAAK,iBAAiB,GAAG,aAAa,oBAAoB,WAAW;AAC1E,eAAK,KAAK,mBAAmB,GAAG,aAAa,+BAA+B;AAAA,YAC3E,MAAM;AAAA,YACN,QAAQ;AAAA,cACP,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA,QAAQ,CAAC;AAAA,UACV,CAAC;AACD,eAAK,KAAK;AAAA,YACT,GAAG,aAAa;AAAA,YAChB,uBAAuB,IAAI,KAAK;AAAA,UACjC;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,SAAS;AACR,aAAK,IAAI,MAAM,iBAAiB,OAAO,OAAO,IAAI,OAAO,IAAI,MAAM,QAAQ,SAAS,CAAC,EAAE;AAAA,MACxF;AAAA,IACD;AACA,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA,EAEA,MAAc,oBAAmC;AAChD,eAAW,MAAM,SAAS;AACzB,WAAK,oBAAoB,EAAE;AAAA,IAC5B;AACA,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAoB,UAAwB;AACnD,UAAM,4BAA4B,OAAO,KAAK,KAAK,UAAU,oBAAoB,CAAC;AAClF,SAAK,OAAO,KAAK,2BAA2B,GAAG,0BAA0B,QAAQ,cAAc,QAAQ;AAAA,EACxG;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAA0B;AACvC,UAAM,oBAAoB,OAAO,KAAK,KAAK,UAAU,WAAW,CAAC;AACjE,SAAK,OAAO,KAAK,mBAAmB,GAAG,kBAAkB,QAAQ,gBAAgB,MAAM;AACvF,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,SAAS,UAA4B;AAC5C,QAAI;AACH,WAAK,cAAc,cAAc;AACjC,WAAK,cAAc,eAAe;AAClC,aAAO,MAAM;AACb,WAAK,KAAK,iBAAiB,mBAAmB,KAAK;AACnD,eAAS;AAAA,IACV,SAAS,GAAQ;AAChB,WAAK,IAAI,MAAM,EAAE,OAAO;AACxB,eAAS;AAAA,IACV;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,cAAc,IAAY,OAAyD;AA5QlG;AA6QE,QAAI,SAAS,CAAC,MAAM,KAAK;AACxB,YAAM,aAAa,MAAM,KAAK,cAAc,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC,gBAAgB;AAC/E,UAAI,YAAY;AACf,cAAM,YAAW,gBAAW,QAAX,mBAAgB;AACjC,gBAAQ,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG;AAAA,UACzB,KAAK,SAAS;AACb,kBAAM,cAAc,EAAE,KAAK,EAAE,KAAK,QAAQ,MAAM,EAAE,OAAO,MAAM,MAAM,IAAI,EAAE,EAAE,EAAE;AAC/E,kBAAM,oBAAoB,OAAO,KAAK,KAAK,UAAU,WAAW,CAAC;AACjE,iBAAK,OAAO,KAAK,mBAAmB,GAAG,kBAAkB,QAAQ,cAAc,QAAQ;AACvF;AAAA,UACD;AAAA,UACA,KAAK,cAAc;AAClB,kBAAM,oBAAoB,EAAE,KAAK,EAAE,KAAK,cAAc,MAAM,EAAE,OAAO,MAAM,IAAI,EAAE,EAAE;AACnF,kBAAM,0BAA0B,OAAO,KAAK,KAAK,UAAU,iBAAiB,CAAC;AAC7E,iBAAK,OAAO;AAAA,cACX;AAAA,cACA;AAAA,cACA,wBAAwB;AAAA,cACxB;AAAA,cACA;AAAA,YACD;AACA;AAAA,UACD;AAAA,UACA,KAAK,oBAAoB;AACxB,kBAAM,yBAAyB,OAAO;AAAA,cACrC,KAAK,UAAU;AAAA,gBACd,KAAK;AAAA,kBACJ,KAAK;AAAA,kBACL,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,kBAAkB,MAAM,IAAI;AAAA,gBACxE;AAAA,cACD,CAAC;AAAA,YACF;AACA,iBAAK,OAAO;AAAA,cACX;AAAA,cACA;AAAA,cACA,uBAAuB;AAAA,cACvB;AAAA,cACA;AAAA,YACD;AACA;AAAA,UACD;AAAA,UACA,KAAK,SAAS;AACb,kBAAM,cAAa,WAAM,QAAN,mBAAW;AAC9B,gBAAI,YAAY;AACf,oBAAM,UAAM,yBAAS,UAAU;AAC/B,oBAAM,eAAe,EAAE,KAAK,EAAE,KAAK,WAAW,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE;AACrE,oBAAM,qBAAqB,OAAO,KAAK,KAAK,UAAU,YAAY,CAAC;AACnE,mBAAK,OAAO,KAAK,oBAAoB,GAAG,mBAAmB,QAAQ,cAAc,QAAQ;AAAA,YAC1F;AACA;AAAA,UACD;AAAA,QACD;AAAA,MACD,OAAO;AACN,aAAK,IAAI,MAAM,kBAAkB;AAAA,MAClC;AAAA,IACD;AACA,WAAO,QAAQ,QAAQ;AAAA,EACxB;AAAA,EAEA,MAAc,iBAAiB,UAAkB,OAAY,eAAe,MAAqB;AAChG,UAAM,eAAe,MAAM,KAAK,cAAc,QAAQ;AACtD,QAAI,gBAAgB,OAAO;AAC1B,WAAK,KAAK,SAAS,UAAU;AAAA,QAC5B,KAAK;AAAA,QACL,KAAK;AAAA,MACN,CAAC;AAAA,IACF;AAAA,EACD;AACD;AAEA,IAAI,QAAQ,SAAS,QAAQ;AAE5B,SAAO,UAAU,CAAC,YAAuD,IAAI,WAAW,OAAO;AAChG,OAAO;AAEN,GAAC,MAAM,IAAI,WAAW,GAAG;AAC1B;AAUO,SAAS,wBAAwB,MAAsB;AAC7D,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/tools/hexTool.js
CHANGED
|
@@ -24,7 +24,7 @@ __export(hexTool_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(hexTool_exports);
|
|
25
25
|
function componentToHex(c) {
|
|
26
26
|
const hex = c.toString(16);
|
|
27
|
-
return hex.length == 1 ?
|
|
27
|
+
return hex.length == 1 ? `0${hex}` : hex;
|
|
28
28
|
}
|
|
29
29
|
function hexToRgb(hexString) {
|
|
30
30
|
if (!/^#[0-9a-fA-F]{6}$/i.test(hexString)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tools/hexTool.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n *
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * Konvertiert eine Zahl (<255) in einen zweistelligen Hex-String f\u00FCr Farbwerte.\n *\n * @param c Die Zahl, die konvertiert werden soll (0-255)\n * @returns Der Hex-Wert als String\n */\nexport function componentToHex(c: number): string {\n\tconst hex = c.toString(16);\n\treturn hex.length == 1 ? `0${hex}` : hex;\n}\n\n/**\n * Wandelt einen Hex-Farbstring (#RRGGBB) in ein Color-Objekt um.\n *\n * @param hexString Hex-Farbwert als String (Format: #RRGGBB)\n * @returns Ein Objekt mit den Farbwerten r, g und b\n */\nexport function hexToRgb(hexString: string): Color {\n\tif (!/^#[0-9a-fA-F]{6}$/i.test(hexString)) {\n\t\tthrow new Error('Invalid hex string');\n\t}\n\treturn {\n\t\tr: parseInt(hexString.slice(1, 3), 16),\n\t\tg: parseInt(hexString.slice(3, 5), 16),\n\t\tb: parseInt(hexString.slice(5, 7), 16),\n\t};\n}\n\n/**\n * Farbobjekt mit Werten f\u00FCr Rot, Gr\u00FCn und Blau\n */\ntype Color = {\n\tr: number;\n\tg: number;\n\tb: number;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,SAAS,eAAe,GAAmB;AACjD,QAAM,MAAM,EAAE,SAAS,EAAE;AACzB,SAAO,IAAI,UAAU,IAAI,IAAI,GAAG,KAAK;AACtC;AAQO,SAAS,SAAS,WAA0B;AAClD,MAAI,CAAC,qBAAqB,KAAK,SAAS,GAAG;AAC1C,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACrC;AACA,SAAO;AAAA,IACN,GAAG,SAAS,UAAU,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IACrC,GAAG,SAAS,UAAU,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IACrC,GAAG,SAAS,UAAU,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EACtC;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "govee-local",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.9",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.2.9": {
|
|
7
|
+
"en": "update dependencies\nadd support for node 24\nupdate to ESlint 9",
|
|
8
|
+
"de": "aktualisierung der abhängigkeiten\nunterstützung für knoten 24 hinzufügen\nupdate auf ESlint 9",
|
|
9
|
+
"ru": "обновление зависимостей\nдобавить поддержку node 24\nобновление для ESlint 9",
|
|
10
|
+
"pt": "atualizar dependências\nadicionar suporte para o nó 24\natualização para ESlint 9",
|
|
11
|
+
"nl": "afhankelijkheden bijwerken\nondersteuning voor node 24 toevoegen\nupdate naar ESlint 9",
|
|
12
|
+
"fr": "mettre à jour les dépendances\najouter un support pour le nœud 24\nmise à jour de ESlint 9",
|
|
13
|
+
"it": "aggiornamento dipendenze\naggiungere supporto per nodo 24\naggiornamento a ESlint 9",
|
|
14
|
+
"es": "dependencias de actualización\nañadir soporte para nodo 24\nactualización a ESlint 9",
|
|
15
|
+
"pl": "aktualizacji zależności\ndodaj obsługę węzła 24\naktualizacja do ESlint 9",
|
|
16
|
+
"uk": "оновлення залежності\nдодати підтримку для вузла 24\nоновлення до ESlint 9",
|
|
17
|
+
"zh-cn": "更新依赖关系\n添加节点24的支持\n更新到 Eslint 9"
|
|
18
|
+
},
|
|
6
19
|
"0.2.8": {
|
|
7
20
|
"en": "update dependencies",
|
|
8
21
|
"de": "aktualisierung der abhängigkeiten",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "remontowanie Off / wszystkie inne działania Fiksy #65\nusunąć z powodu dzikiej karty",
|
|
81
94
|
"uk": "ремонт наОфф / всі інші дії Виправлення: #65\nфіксація спамерування колод через дикийкарт",
|
|
82
95
|
"zh-cn": "b. 修理效率/所有其他行动 固定: #65\nfix 由于野生素卡的投机"
|
|
83
|
-
},
|
|
84
|
-
"0.2.0": {
|
|
85
|
-
"en": "support controlling the color\nextended logging mode",
|
|
86
|
-
"de": "unterstützung controlling der farbe\nerweiterter logging-modus",
|
|
87
|
-
"ru": "поддержка контролируя цвет\nрасширенный режим входа",
|
|
88
|
-
"pt": "suporte controlando a cor\nmodo de registro estendido",
|
|
89
|
-
"nl": "de kleur controleren\nverlengde logging mode",
|
|
90
|
-
"fr": "support de contrôle de la couleur\nmode d ' enregistrement élargi",
|
|
91
|
-
"it": "supporto che controlla il colore\nmodalità di registrazione estesa",
|
|
92
|
-
"es": "soporte controlando el color\nmodo de registro ampliado",
|
|
93
|
-
"pl": "kontrolować kolor\nrozszerzony tryb logowania",
|
|
94
|
-
"uk": "супровід управління кольором\nрозширений режим входу",
|
|
95
|
-
"zh-cn": "控制颜色的支助\n扩大的伐木模式"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.govee-local",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Control Govee devices via local access (no cloud)",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Børge Grunicke",
|
|
@@ -29,30 +29,27 @@
|
|
|
29
29
|
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
|
|
30
30
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
31
31
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
32
|
-
"@iobroker/adapter-dev": "^1.
|
|
33
|
-
"@iobroker/
|
|
34
|
-
"@
|
|
32
|
+
"@iobroker/adapter-dev": "^1.4.0",
|
|
33
|
+
"@iobroker/eslint-config": "^2.0.2",
|
|
34
|
+
"@iobroker/testing": "^5.0.4",
|
|
35
|
+
"@tsconfig/node14": "^14.1.3",
|
|
35
36
|
"@tsconfig/node18": "^18.2.4",
|
|
36
|
-
"@tsconfig/node20": "^20.1.
|
|
37
|
+
"@tsconfig/node20": "^20.1.6",
|
|
37
38
|
"@types/chai": "^4.1.1",
|
|
38
|
-
"@types/chai-as-promised": "^8.0.
|
|
39
|
-
"@types/mocha": "^10.0.
|
|
40
|
-
"@types/node": "^
|
|
39
|
+
"@types/chai-as-promised": "^8.0.2",
|
|
40
|
+
"@types/mocha": "^10.0.10",
|
|
41
|
+
"@types/node": "^24.0.8",
|
|
41
42
|
"@types/proxyquire": "^1.3.31",
|
|
42
|
-
"@types/sinon": "^17.0.
|
|
43
|
+
"@types/sinon": "^17.0.4",
|
|
43
44
|
"@types/sinon-chai": "^3.2.12",
|
|
44
|
-
"@typescript-eslint/eslint-plugin": "^8.12.2",
|
|
45
|
-
"@typescript-eslint/parser": "^8.12.2",
|
|
46
45
|
"chai": "^4.5.0",
|
|
47
|
-
"chai-as-promised": "^8.0.
|
|
48
|
-
"eslint": "^
|
|
49
|
-
"
|
|
50
|
-
"eslint-plugin-prettier": "^5.2.1",
|
|
51
|
-
"mocha": "^10.8.2",
|
|
46
|
+
"chai-as-promised": "^8.0.1",
|
|
47
|
+
"eslint": "^9.32.0",
|
|
48
|
+
"mocha": "^11.7.1",
|
|
52
49
|
"prettier": "^3.3.3",
|
|
53
50
|
"proxyquire": "^2.1.3",
|
|
54
51
|
"rimraf": "^6.0.1",
|
|
55
|
-
"sinon": "^
|
|
52
|
+
"sinon": "^21.0.0",
|
|
56
53
|
"sinon-chai": "^3.7.0",
|
|
57
54
|
"source-map-support": "^0.5.21",
|
|
58
55
|
"ts-node": "^10.9.2",
|