From e73d07b0cc992f93cf6ab0b8d48f6b7e18c37c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=B8rge=20Grunicke?= Date: Tue, 8 Aug 2023 21:11:22 +0200 Subject: [PATCH] remove unnecessary logging --- build/main.js | 1 - build/main.js.map | 4 ++-- src/main.ts | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build/main.js b/build/main.js index 608ee45..fe93187 100644 --- a/build/main.js +++ b/build/main.js @@ -214,7 +214,6 @@ class GoveeLocal extends utils.Adapter { async onStateChange(id, state) { var _a; if (state && !state.ack) { - this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`); const ipOfDevice = await this.getStateAsync(id.split(".")[2] + ".deviceInfo.ip"); if (ipOfDevice) { this.log.info("should send to ip : " + ipOfDevice.val); diff --git a/build/main.js.map b/build/main.js.map index 67a93ad..6360b23 100644 --- a/build/main.js.map +++ b/build/main.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/main.ts"], - "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.3.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from '@iobroker/adapter-core';\r\nimport * as dgram from 'node:dgram';\r\n\r\n// Load your modules here, e.g.:\r\n// import * as fs from \"fs\";\r\n\r\nconst LOCAL_PORT = 4002;\r\nconst SEND_SCAN_PORT = 4001;\r\nconst CONTROL_PORT = 4003;\r\nconst M_CAST = '239.255.255.250';\r\n\r\nconst server = dgram.createSocket('udp4');\r\nconst client = dgram.createSocket('udp4');\r\n\r\nconst scanMessage = { msg: { cmd: 'scan', data: { account_topic: 'reserved' } } };\r\nconst requestStatusMessage = { msg: { cmd: 'devStatus', data: {} } };\r\n\r\nlet searchInterval: NodeJS.Timeout;\r\n\r\nconst intervals: { [device: string]: NodeJS.Timeout } = {};\r\n\r\nclass GoveeLocal extends utils.Adapter {\r\n\tpublic constructor(options: Partial = {}) {\r\n\t\tsuper({\r\n\t\t\t...options,\r\n\t\t\tname: 'govee-local',\r\n\t\t});\r\n\t\tthis.on('ready', this.onReady.bind(this));\r\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\r\n\t\t// this.on('objectChange', this.onObjectChange.bind(this));\r\n\t\t// this.on('message', this.onMessage.bind(this));\r\n\t\tthis.on('unload', this.onUnload.bind(this));\r\n\t}\r\n\r\n\t/**\r\n\t * Is called when databases are connected and adapter received configuration.\r\n\t */\r\n\tprivate async onReady(): Promise {\r\n\t\tthis.setObjectNotExists('info.connection', {\r\n\t\t\ttype: 'state',\r\n\t\t\tcommon: {\r\n\t\t\t\tname: 'Device discovery running',\r\n\t\t\t\ttype: 'boolean',\r\n\t\t\t\trole: 'indicator.connected',\r\n\t\t\t\tread: true,\r\n\t\t\t\twrite: false,\r\n\t\t\t},\r\n\t\t\tnative: {},\r\n\t\t});\r\n\t\tserver.on('message', this.onUdpMessage.bind(this));\r\n\t\tserver.on('error', (error) => {\r\n\t\t\tthis.log.error('server bind error : ' + error.message);\r\n\t\t\tthis.setState('info.connection', { val: false, ack: true });\r\n\t\t});\r\n\r\n\t\tserver.bind(LOCAL_PORT, this.serverBound.bind(this));\r\n\r\n\t\tthis.subscribeStates('*.devStatus.*');\r\n\t}\r\n\r\n\t/**\r\n\t * handles when udp socket is up\r\n\t * configure multicast membership\r\n\t * start periodic scan for devices\r\n\t */\r\n\tprivate async serverBound(): Promise {\r\n\t\tserver.setBroadcast(true);\r\n\t\tserver.setMulticastTTL(128);\r\n\t\tserver.addMembership(M_CAST);\r\n\t\tthis.setState('info.connection', { val: true, ack: true });\r\n\t\tthis.log.info('UDP listening on ' + server.address().address + ':' + server.address().port);\r\n\r\n\t\tif (this.config.searchInterval == undefined) {\r\n\t\t\tthis.config.searchInterval = 10000;\r\n\t\t}\r\n\t\tif (this.config.deviceStatusRefreshInterval == undefined) {\r\n\t\t\tthis.config.deviceStatusRefreshInterval = 1000;\r\n\t\t}\r\n\r\n\t\tconst result = this.setInterval(this.sendScan.bind(this), this.config.searchInterval);\r\n\t\tif (result !== void 0) {\r\n\t\t\tsearchInterval = result;\r\n\t\t}\r\n\t\t// this.sendScan();\r\n\t}\r\n\r\n\t/**\r\n\t * handle icoming messages on the udp socket\r\n\t * @param message the message itself\r\n\t * @param remote the sender of the message\r\n\t */\r\n\tprivate async onUdpMessage(message: Buffer, remote: dgram.RemoteInfo): Promise {\r\n\t\tconst messageObject = JSON.parse(message.toString());\r\n\t\tswitch (messageObject.msg.cmd) {\r\n\t\t\tcase 'scan':\r\n\t\t\t\tfor (const key of Object.keys(messageObject.msg.data)) {\r\n\t\t\t\t\tif (key != 'device') {\r\n\t\t\t\t\t\tthis.setObjectNotExists(messageObject.msg.data.device, {\r\n\t\t\t\t\t\t\ttype: 'device',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: messageObject.msg.data.sku,\r\n\t\t\t\t\t\t\t\trole: 'group',\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${messageObject.msg.data.device}.deviceInfo.${key}`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: getDatapointDescription(key),\r\n\t\t\t\t\t\t\t\ttype: 'string',\r\n\t\t\t\t\t\t\t\trole: 'state',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${messageObject.msg.data.device}.deviceInfo.${key}`, {\r\n\t\t\t\t\t\t\tval: messageObject.msg.data[key],\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!(messageObject.msg.data.device in intervals)) {\r\n\t\t\t\t\tconst result = this.setInterval(\r\n\t\t\t\t\t\t() => this.requestDeviceStatus(messageObject.msg.data.ip),\r\n\t\t\t\t\t\tthis.config.deviceStatusRefreshInterval,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (result !== void 0) {\r\n\t\t\t\t\t\tintervals[messageObject.msg.data.device] = result;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// this.requestDeviceStatus(remote.address);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'devStatus':\r\n\t\t\t\tconst devices = await this.getStatesAsync(this.name + '.' + this.instance + '.*.deviceInfo.ip');\r\n\t\t\t\tfor (const key in devices) {\r\n\t\t\t\t\tif (devices[key as keyof typeof devices].val == remote.address) {\r\n\t\t\t\t\t\tconst sendingDevice = key.split('.')[2];\r\n\t\t\t\t\t\tconst devStatusMessageObject = JSON.parse(message.toString());\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'On / Off state of the lamp',\r\n\t\t\t\t\t\t\t\ttype: 'boolean',\r\n\t\t\t\t\t\t\t\trole: 'switch',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.onOff`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.onOff == 1,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'Brightness of the light',\r\n\t\t\t\t\t\t\t\ttype: 'number',\r\n\t\t\t\t\t\t\t\trole: 'level.dimmer',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.brightness`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.brightness,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.color`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'Current showing color of the lamp',\r\n\t\t\t\t\t\t\t\ttype: 'string',\r\n\t\t\t\t\t\t\t\trole: 'level.color.rgb',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.color`, {\r\n\t\t\t\t\t\t\tval:\r\n\t\t\t\t\t\t\t\t'#' +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.r) +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.g) +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.b),\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'If staying in white light, the color temperature',\r\n\t\t\t\t\t\t\t\ttype: 'number',\r\n\t\t\t\t\t\t\t\trole: 'level.color.temperature',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.colorTemInKelvin`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.colorTemInKelvin,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthis.log.info('message from: ' + remote.address + ':' + remote.port + ' - ' + message);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * sends the device status request to one specific device\r\n\t * @param receiver the ip ( / hsotname ) of the device that should be queried\r\n\t */\r\n\tprivate requestDeviceStatus(receiver: string): void {\r\n\t\tconsole.log('request device status ' + receiver);\r\n\t\tconst requestDeviceStatusBuffer = Buffer.from(JSON.stringify(requestStatusMessage));\r\n\t\tclient.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);\r\n\t}\r\n\r\n\t/**\r\n\t * send the scan message to the udp multicast address\r\n\t */\r\n\tprivate async sendScan(): Promise {\r\n\t\tconst scanMessageBuffer = Buffer.from(JSON.stringify(scanMessage));\r\n\t\tclient.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);\r\n\t\t//this.log.info('send message ' + scanMessageBuffer);\r\n\t}\r\n\r\n\t/**\r\n\t * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n\t */\r\n\tprivate onUnload(callback: () => void): void {\r\n\t\ttry {\r\n\t\t\tthis.clearInterval(searchInterval);\r\n\t\t\tObject.entries(intervals).forEach(([_, interval]) => this.clearInterval(interval));\r\n\t\t\tclient.close();\r\n\t\t\tserver.close();\r\n\t\t\tthis.setState('info.connection', { val: false, ack: true });\r\n\t\t\tcallback();\r\n\t\t} catch (e) {\r\n\t\t\tcallback();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Is called if a subscribed state changes\r\n\t */\r\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n\t\tif (state && !state.ack) {\r\n\t\t\tthis.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\t\t\tconst ipOfDevice = await this.getStateAsync(id.split('.')[2] + '.deviceInfo.ip');\r\n\t\t\tif (ipOfDevice) {\r\n\t\t\t\tthis.log.info('should send to ip : ' + ipOfDevice.val);\r\n\t\t\t\tconst receiver = ipOfDevice.val?.toString();\r\n\t\t\t\tswitch (id.split('.')[4]) {\r\n\t\t\t\t\tcase 'onOff':\r\n\t\t\t\t\t\tconst turnMessage = { msg: { cmd: 'turn', data: { value: state.val ? 1 : 0 } } };\r\n\t\t\t\t\t\tconst turnMessageBuffer = Buffer.from(JSON.stringify(turnMessage));\r\n\t\t\t\t\t\tclient.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'brightness':\r\n\t\t\t\t\t\tconst brightnessMessage = { msg: { cmd: 'brightness', data: { value: state.val } } };\r\n\t\t\t\t\t\tconst brightnessMessageBuffer = Buffer.from(JSON.stringify(brightnessMessage));\r\n\t\t\t\t\t\tclient.send(brightnessMessageBuffer, 0, brightnessMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'colorTemInKelvin':\r\n\t\t\t\t\t\tconst colorTempMessage = { msg: { cmd: 'colorTemInKelvin', data: { value: state.val } } };\r\n\t\t\t\t\t\tconst colorTempMessageBuffer = Buffer.from(JSON.stringify(colorTempMessage));\r\n\t\t\t\t\t\tclient.send(colorTempMessageBuffer, 0, colorTempMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tthis.log.error('device not found');\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\nif (require.main !== module) {\r\n\t// Export the constructor in compact mode\r\n\tmodule.exports = (options: Partial | undefined) => new GoveeLocal(options);\r\n} else {\r\n\t// otherwise start the instance directly\r\n\t(() => new GoveeLocal())();\r\n}\r\n\r\n/**\r\n * This method returns the description for device information datapoints\r\n * to unbloat the upper methods.\r\n * tanslations would be great here\r\n * @param name the name of the parameter retrieved from the device\r\n * @returns the description, that should be set to the datapoint\r\n */\r\nfunction getDatapointDescription(name: string): string {\r\n\tswitch (name) {\r\n\t\tcase 'model':\r\n\t\t\treturn 'Specific model of the Lamp';\r\n\t\tcase 'ip':\r\n\t\t\treturn 'IP address of the Lamp';\r\n\t\tcase 'bleVersionHard':\r\n\t\t\treturn 'Bluetooth Low Energy Hardware Version';\r\n\t\tcase 'bleVersionSoft':\r\n\t\t\treturn 'Bluetooth Low Energy Software Version';\r\n\t\tcase 'wifiVersionHard':\r\n\t\t\treturn 'WiFi Hardware Version';\r\n\t\tcase 'wifiVersionSoft':\r\n\t\t\treturn 'WiFi Software Version';\r\n\t\tdefault:\r\n\t\t\treturn '';\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert number (<255) to two digit hex for colorcode\r\n * @param the int value, should me < 255\r\n * @returns the hex value as string\r\n */\r\nfunction componentToHex(c: number): string {\r\n\tconst hex = c.toString(16);\r\n\treturn hex.length == 1 ? '0' + hex : hex;\r\n}\r\n"], - "mappings": "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", + "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.3.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from '@iobroker/adapter-core';\r\nimport * as dgram from 'node:dgram';\r\n\r\n// Load your modules here, e.g.:\r\n// import * as fs from \"fs\";\r\n\r\nconst LOCAL_PORT = 4002;\r\nconst SEND_SCAN_PORT = 4001;\r\nconst CONTROL_PORT = 4003;\r\nconst M_CAST = '239.255.255.250';\r\n\r\nconst server = dgram.createSocket('udp4');\r\nconst client = dgram.createSocket('udp4');\r\n\r\nconst scanMessage = { msg: { cmd: 'scan', data: { account_topic: 'reserved' } } };\r\nconst requestStatusMessage = { msg: { cmd: 'devStatus', data: {} } };\r\n\r\nlet searchInterval: NodeJS.Timeout;\r\n\r\nconst intervals: { [device: string]: NodeJS.Timeout } = {};\r\n\r\nclass GoveeLocal extends utils.Adapter {\r\n\tpublic constructor(options: Partial = {}) {\r\n\t\tsuper({\r\n\t\t\t...options,\r\n\t\t\tname: 'govee-local',\r\n\t\t});\r\n\t\tthis.on('ready', this.onReady.bind(this));\r\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\r\n\t\t// this.on('objectChange', this.onObjectChange.bind(this));\r\n\t\t// this.on('message', this.onMessage.bind(this));\r\n\t\tthis.on('unload', this.onUnload.bind(this));\r\n\t}\r\n\r\n\t/**\r\n\t * Is called when databases are connected and adapter received configuration.\r\n\t */\r\n\tprivate async onReady(): Promise {\r\n\t\tthis.setObjectNotExists('info.connection', {\r\n\t\t\ttype: 'state',\r\n\t\t\tcommon: {\r\n\t\t\t\tname: 'Device discovery running',\r\n\t\t\t\ttype: 'boolean',\r\n\t\t\t\trole: 'indicator.connected',\r\n\t\t\t\tread: true,\r\n\t\t\t\twrite: false,\r\n\t\t\t},\r\n\t\t\tnative: {},\r\n\t\t});\r\n\t\tserver.on('message', this.onUdpMessage.bind(this));\r\n\t\tserver.on('error', (error) => {\r\n\t\t\tthis.log.error('server bind error : ' + error.message);\r\n\t\t\tthis.setState('info.connection', { val: false, ack: true });\r\n\t\t});\r\n\r\n\t\tserver.bind(LOCAL_PORT, this.serverBound.bind(this));\r\n\r\n\t\tthis.subscribeStates('*.devStatus.*');\r\n\t}\r\n\r\n\t/**\r\n\t * handles when udp socket is up\r\n\t * configure multicast membership\r\n\t * start periodic scan for devices\r\n\t */\r\n\tprivate async serverBound(): Promise {\r\n\t\tserver.setBroadcast(true);\r\n\t\tserver.setMulticastTTL(128);\r\n\t\tserver.addMembership(M_CAST);\r\n\t\tthis.setState('info.connection', { val: true, ack: true });\r\n\t\tthis.log.info('UDP listening on ' + server.address().address + ':' + server.address().port);\r\n\r\n\t\tif (this.config.searchInterval == undefined) {\r\n\t\t\tthis.config.searchInterval = 10000;\r\n\t\t}\r\n\t\tif (this.config.deviceStatusRefreshInterval == undefined) {\r\n\t\t\tthis.config.deviceStatusRefreshInterval = 1000;\r\n\t\t}\r\n\r\n\t\tconst result = this.setInterval(this.sendScan.bind(this), this.config.searchInterval);\r\n\t\tif (result !== void 0) {\r\n\t\t\tsearchInterval = result;\r\n\t\t}\r\n\t\t// this.sendScan();\r\n\t}\r\n\r\n\t/**\r\n\t * handle icoming messages on the udp socket\r\n\t * @param message the message itself\r\n\t * @param remote the sender of the message\r\n\t */\r\n\tprivate async onUdpMessage(message: Buffer, remote: dgram.RemoteInfo): Promise {\r\n\t\tconst messageObject = JSON.parse(message.toString());\r\n\t\tswitch (messageObject.msg.cmd) {\r\n\t\t\tcase 'scan':\r\n\t\t\t\tfor (const key of Object.keys(messageObject.msg.data)) {\r\n\t\t\t\t\tif (key != 'device') {\r\n\t\t\t\t\t\tthis.setObjectNotExists(messageObject.msg.data.device, {\r\n\t\t\t\t\t\t\ttype: 'device',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: messageObject.msg.data.sku,\r\n\t\t\t\t\t\t\t\trole: 'group',\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${messageObject.msg.data.device}.deviceInfo.${key}`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: getDatapointDescription(key),\r\n\t\t\t\t\t\t\t\ttype: 'string',\r\n\t\t\t\t\t\t\t\trole: 'state',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${messageObject.msg.data.device}.deviceInfo.${key}`, {\r\n\t\t\t\t\t\t\tval: messageObject.msg.data[key],\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!(messageObject.msg.data.device in intervals)) {\r\n\t\t\t\t\tconst result = this.setInterval(\r\n\t\t\t\t\t\t() => this.requestDeviceStatus(messageObject.msg.data.ip),\r\n\t\t\t\t\t\tthis.config.deviceStatusRefreshInterval,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (result !== void 0) {\r\n\t\t\t\t\t\tintervals[messageObject.msg.data.device] = result;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// this.requestDeviceStatus(remote.address);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'devStatus':\r\n\t\t\t\tconst devices = await this.getStatesAsync(this.name + '.' + this.instance + '.*.deviceInfo.ip');\r\n\t\t\t\tfor (const key in devices) {\r\n\t\t\t\t\tif (devices[key as keyof typeof devices].val == remote.address) {\r\n\t\t\t\t\t\tconst sendingDevice = key.split('.')[2];\r\n\t\t\t\t\t\tconst devStatusMessageObject = JSON.parse(message.toString());\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.onOff`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'On / Off state of the lamp',\r\n\t\t\t\t\t\t\t\ttype: 'boolean',\r\n\t\t\t\t\t\t\t\trole: 'switch',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.onOff`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.onOff == 1,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.brightness`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'Brightness of the light',\r\n\t\t\t\t\t\t\t\ttype: 'number',\r\n\t\t\t\t\t\t\t\trole: 'level.dimmer',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.brightness`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.brightness,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.color`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'Current showing color of the lamp',\r\n\t\t\t\t\t\t\t\ttype: 'string',\r\n\t\t\t\t\t\t\t\trole: 'level.color.rgb',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.color`, {\r\n\t\t\t\t\t\t\tval:\r\n\t\t\t\t\t\t\t\t'#' +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.r) +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.g) +\r\n\t\t\t\t\t\t\t\tcomponentToHex(devStatusMessageObject.msg.data.color.b),\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setObjectNotExists(`${sendingDevice}.devStatus.colorTemInKelvin`, {\r\n\t\t\t\t\t\t\ttype: 'state',\r\n\t\t\t\t\t\t\tcommon: {\r\n\t\t\t\t\t\t\t\tname: 'If staying in white light, the color temperature',\r\n\t\t\t\t\t\t\t\ttype: 'number',\r\n\t\t\t\t\t\t\t\trole: 'level.color.temperature',\r\n\t\t\t\t\t\t\t\tread: true,\r\n\t\t\t\t\t\t\t\twrite: true,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tnative: {},\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tthis.setState(`${sendingDevice}.devStatus.colorTemInKelvin`, {\r\n\t\t\t\t\t\t\tval: devStatusMessageObject.msg.data.colorTemInKelvin,\r\n\t\t\t\t\t\t\tack: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthis.log.info('message from: ' + remote.address + ':' + remote.port + ' - ' + message);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * sends the device status request to one specific device\r\n\t * @param receiver the ip ( / hsotname ) of the device that should be queried\r\n\t */\r\n\tprivate requestDeviceStatus(receiver: string): void {\r\n\t\tconsole.log('request device status ' + receiver);\r\n\t\tconst requestDeviceStatusBuffer = Buffer.from(JSON.stringify(requestStatusMessage));\r\n\t\tclient.send(requestDeviceStatusBuffer, 0, requestDeviceStatusBuffer.length, CONTROL_PORT, receiver);\r\n\t}\r\n\r\n\t/**\r\n\t * send the scan message to the udp multicast address\r\n\t */\r\n\tprivate async sendScan(): Promise {\r\n\t\tconst scanMessageBuffer = Buffer.from(JSON.stringify(scanMessage));\r\n\t\tclient.send(scanMessageBuffer, 0, scanMessageBuffer.length, SEND_SCAN_PORT, M_CAST);\r\n\t\t//this.log.info('send message ' + scanMessageBuffer);\r\n\t}\r\n\r\n\t/**\r\n\t * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n\t */\r\n\tprivate onUnload(callback: () => void): void {\r\n\t\ttry {\r\n\t\t\tthis.clearInterval(searchInterval);\r\n\t\t\tObject.entries(intervals).forEach(([_, interval]) => this.clearInterval(interval));\r\n\t\t\tclient.close();\r\n\t\t\tserver.close();\r\n\t\t\tthis.setState('info.connection', { val: false, ack: true });\r\n\t\t\tcallback();\r\n\t\t} catch (e) {\r\n\t\t\tcallback();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Is called if a subscribed state changes\r\n\t */\r\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n\t\tif (state && !state.ack) {\r\n\t\t\tconst ipOfDevice = await this.getStateAsync(id.split('.')[2] + '.deviceInfo.ip');\r\n\t\t\tif (ipOfDevice) {\r\n\t\t\t\tthis.log.info('should send to ip : ' + ipOfDevice.val);\r\n\t\t\t\tconst receiver = ipOfDevice.val?.toString();\r\n\t\t\t\tswitch (id.split('.')[4]) {\r\n\t\t\t\t\tcase 'onOff':\r\n\t\t\t\t\t\tconst turnMessage = { msg: { cmd: 'turn', data: { value: state.val ? 1 : 0 } } };\r\n\t\t\t\t\t\tconst turnMessageBuffer = Buffer.from(JSON.stringify(turnMessage));\r\n\t\t\t\t\t\tclient.send(turnMessageBuffer, 0, turnMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'brightness':\r\n\t\t\t\t\t\tconst brightnessMessage = { msg: { cmd: 'brightness', data: { value: state.val } } };\r\n\t\t\t\t\t\tconst brightnessMessageBuffer = Buffer.from(JSON.stringify(brightnessMessage));\r\n\t\t\t\t\t\tclient.send(brightnessMessageBuffer, 0, brightnessMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'colorTemInKelvin':\r\n\t\t\t\t\t\tconst colorTempMessage = { msg: { cmd: 'colorTemInKelvin', data: { value: state.val } } };\r\n\t\t\t\t\t\tconst colorTempMessageBuffer = Buffer.from(JSON.stringify(colorTempMessage));\r\n\t\t\t\t\t\tclient.send(colorTempMessageBuffer, 0, colorTempMessageBuffer.length, CONTROL_PORT, receiver);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tthis.log.error('device not found');\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\nif (require.main !== module) {\r\n\t// Export the constructor in compact mode\r\n\tmodule.exports = (options: Partial | undefined) => new GoveeLocal(options);\r\n} else {\r\n\t// otherwise start the instance directly\r\n\t(() => new GoveeLocal())();\r\n}\r\n\r\n/**\r\n * This method returns the description for device information datapoints\r\n * to unbloat the upper methods.\r\n * tanslations would be great here\r\n * @param name the name of the parameter retrieved from the device\r\n * @returns the description, that should be set to the datapoint\r\n */\r\nfunction getDatapointDescription(name: string): string {\r\n\tswitch (name) {\r\n\t\tcase 'model':\r\n\t\t\treturn 'Specific model of the Lamp';\r\n\t\tcase 'ip':\r\n\t\t\treturn 'IP address of the Lamp';\r\n\t\tcase 'bleVersionHard':\r\n\t\t\treturn 'Bluetooth Low Energy Hardware Version';\r\n\t\tcase 'bleVersionSoft':\r\n\t\t\treturn 'Bluetooth Low Energy Software Version';\r\n\t\tcase 'wifiVersionHard':\r\n\t\t\treturn 'WiFi Hardware Version';\r\n\t\tcase 'wifiVersionSoft':\r\n\t\t\treturn 'WiFi Software Version';\r\n\t\tdefault:\r\n\t\t\treturn '';\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert number (<255) to two digit hex for colorcode\r\n * @param the int value, should me < 255\r\n * @returns the hex value as string\r\n */\r\nfunction componentToHex(c: number): string {\r\n\tconst hex = c.toString(16);\r\n\treturn hex.length == 1 ? '0' + hex : hex;\r\n}\r\n"], + "mappings": "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", "names": [] } diff --git a/src/main.ts b/src/main.ts index 55f2aef..2b8798f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -255,7 +255,6 @@ class GoveeLocal extends utils.Adapter { */ private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise { if (state && !state.ack) { - this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`); const ipOfDevice = await this.getStateAsync(id.split('.')[2] + '.deviceInfo.ip'); if (ipOfDevice) { this.log.info('should send to ip : ' + ipOfDevice.val);