iobroker.govee-local 0.4.2 → 0.4.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.
- package/README.md +6 -0
- package/admin/jsonConfig.json +5 -1
- package/build/main.js +1 -1
- package/build/main.js.map +2 -2
- package/io-package.json +14 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,6 +24,12 @@ 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.4.3 (2025-11-11)
|
|
28
|
+
|
|
29
|
+
- fix responsive design in the settings
|
|
30
|
+
- revert forbidden characters checking
|
|
31
|
+
- update dependencies
|
|
32
|
+
|
|
27
33
|
### 0.4.2 (2025-11-08)
|
|
28
34
|
|
|
29
35
|
- update dependencies
|
package/admin/jsonConfig.json
CHANGED
package/build/main.js
CHANGED
|
@@ -83,7 +83,7 @@ class GoveeLocal extends utils.Adapter {
|
|
|
83
83
|
searchInterval: this.config.searchInterval,
|
|
84
84
|
deviceStatusRefreshInterval: this.config.deviceStatusRefreshInterval,
|
|
85
85
|
extendedLogging: this.config.extendedLogging,
|
|
86
|
-
forbiddenChars:
|
|
86
|
+
forbiddenChars: this.FORBIDDEN_CHARS,
|
|
87
87
|
manualIpAddresses: this.config.manualIpTable,
|
|
88
88
|
disableAutoDiscovery: this.config.disableAutoDiscovery,
|
|
89
89
|
logger: {
|
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\nimport * as utils from '@iobroker/adapter-core';\nimport { GoveeService, type DeviceDiscoveryEvent, type DeviceStatusEvent } from './lib/goveeService';\n\n/**\n * Main adapter class for ioBroker Govee Local.\n * Handles initialization, event wiring, and communication with GoveeService.\n */\nexport class GoveeLocal extends utils.Adapter {\n\t/** Instance of GoveeService for device communication */\n\tprivate goveeService!: GoveeService;\n\t/**\n\t * Adapter constructor. Registers lifecycle event handlers.\n\t *\n\t * @param options Optional adapter options to override defaults.\n\t */\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\t// Register event handlers for adapter lifecycle\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\t// Uncomment if you want to handle object changes or messages:\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 * Called when databases are connected and adapter received configuration.\n\t * Initializes GoveeService and sets up event listeners for device events.\n\t */\n\tprivate async onReady(): Promise<void> {\n\t\t// Create connection indicator state if it doesn't exist\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\n\t\t// Create state for discovered devices\n\t\tvoid this.setObjectNotExists('info.discoveredDevices', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'List of discovered devices',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'json',\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tdesc: 'JSON object with IP addresses and device names of all discovered devices',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Initialize GoveeService with adapter config and logger\n\t\tthis.goveeService = new GoveeService({\n\t\t\tinterface: this.config.interface,\n\t\t\tsearchInterval: this.config.searchInterval,\n\t\t\tdeviceStatusRefreshInterval: this.config.deviceStatusRefreshInterval,\n\t\t\textendedLogging: this.config.extendedLogging,\n\t\t\tforbiddenChars: /[^a-zA-Z0-9_-]/g,\n\t\t\tmanualIpAddresses: this.config.manualIpTable,\n\t\t\tdisableAutoDiscovery: this.config.disableAutoDiscovery,\n\t\t\tlogger: {\n\t\t\t\tdebug: (msg) => this.log.debug(msg),\n\t\t\t\tinfo: (msg) => this.log.info(msg),\n\t\t\t\terror: (msg) => this.log.error(msg),\n\t\t\t},\n\t\t});\n\n\t\t// Listen for device discovery and status update events\n\t\tthis.goveeService.on('deviceDiscovered', (data) => {\n\t\t\tvoid this.handleDeviceDiscovered(data);\n\t\t});\n\n\t\tthis.goveeService.on('deviceStatusUpdate', (data) => {\n\t\t\tvoid this.handleDeviceStatusUpdate(data);\n\t\t});\n\n\t\t// Listen for serviceStarted event to set connection state to true\n\t\tthis.goveeService.on('serviceStarted', () => {\n\t\t\tvoid this.setState('info.connection', { val: true, ack: true });\n\t\t});\n\n\t\t// Start device discovery and status polling\n\t\tthis.goveeService.start();\n\n\t\tif (this.config.extendedLogging) {\n\t\t\tthis.log.debug('running with extended logging');\n\t\t}\n\n\t\t// Subscribe to all device status state changes\n\t\tvoid this.subscribeStates('*.devStatus.*');\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Called if a subscribed state changes (e.g. user toggles a switch in ioBroker UI).\n\t * Forwards the change to the GoveeService for device communication.\n\t *\n\t * @param id The ID of the changed state.\n\t * @param state The new state object or 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\t// Extract device name from state ID and get its IP address\n\t\t\tconst ipOfDevice = await this.getStateAsync(`${id.split('.')[2]}.deviceInfo.ip`);\n\t\t\tconst receiver = ipOfDevice?.val?.toString();\n\t\t\tif (typeof receiver === 'string') {\n\t\t\t\t// Forward the state change to the GoveeService\n\t\t\t\tthis.goveeService.handleStateChange(id, state, receiver);\n\t\t\t} else {\n\t\t\t\tthis.log.error('device not found or IP is not a string');\n\t\t\t}\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t * Called when the adapter shuts down. Cleans up resources and stops services.\n\t *\n\t * @param callback Callback function after unload process.\n\t */\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.goveeService) {\n\t\t\t\tthis.goveeService.removeAllListeners();\n\t\t\t\tthis.goveeService.stop();\n\t\t\t}\n\t\t\t// Set connection state to false\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 * Updates a state only if the value has changed.\n\t *\n\t * @param fullName Full object path\n\t * @param state New value\n\t * @param acknowledged Whether the value is acknowledged (default: true)\n\t */\n\tprivate async updateStateAsync(fullName: string, state: any, acknowledged = true): Promise<void> {\n\t\tconst currentState = await this.getStateAsync(fullName);\n\t\tif (currentState?.val !== 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\t/**\n\t * Handles device discovery event from GoveeService.\n\t * Creates all necessary objects and states for the new device.\n\t *\n\t * @param event The device discovery event data.\n\t */\n\tprivate async handleDeviceDiscovered(event: DeviceDiscoveryEvent): Promise<void> {\n\t\tconst { ip, deviceName, deviceModel } = event;\n\n\t\t// Create device folder\n\t\tawait this.setObjectNotExistsAsync(deviceName, {\n\t\t\ttype: 'device',\n\t\t\tcommon: {\n\t\t\t\tname: deviceModel,\n\t\t\t\trole: 'group',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Create deviceInfo folder\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.deviceInfo`, {\n\t\t\ttype: 'folder',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device Info',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Create IP address state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.deviceInfo.ip`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'IP address of the Lamp',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'info.ip',\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\tawait this.updateStateAsync(`${deviceName}.deviceInfo.ip`, ip);\n\n\t\t// Create devStatus folder\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus`, {\n\t\t\ttype: 'folder',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device Status',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tthis.log.info(`Device discovered: ${deviceName} at ${ip}`);\n\n\t\t// Update the list of discovered devices\n\t\tawait this.updateDiscoveredDevicesList();\n\t}\n\n\t/**\n\t * Updates the info.discoveredDevices state with the current list of all discovered devices.\n\t */\n\tprivate async updateDiscoveredDevicesList(): Promise<void> {\n\t\tconst devices = this.goveeService.getDevices();\n\t\tawait this.setStateAsync('info.discoveredDevices', {\n\t\t\tval: JSON.stringify(devices, null, 2),\n\t\t\tack: true,\n\t\t});\n\t}\n\n\t/**\n\t * Handles device status update event from GoveeService.\n\t * Creates and updates all relevant states for the device.\n\t *\n\t * @param event The device status update event data.\n\t */\n\tprivate async handleDeviceStatusUpdate(event: DeviceStatusEvent): Promise<void> {\n\t\tconst { deviceName, status } = event;\n\n\t\t// Create and update onOff state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.onOff`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'On / Off state of the lamp',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'switch',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.onOff`, status.onOff);\n\n\t\t// Create and update brightness state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.brightness`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Brightness of the light',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.dimmer',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.brightness`, status.brightness);\n\n\t\t// Create and update color state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.color`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Current showing color of the lamp',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'level.color.rgb',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.color`, status.color);\n\n\t\t// Create and update color temperature state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.colorTemInKelvin`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'If staying in white light, the color temperature',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.color.temperature',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.colorTemInKelvin`, status.colorTemInKelvin);\n\t}\n}\n\n// Export factory function for ioBroker or start instance directly\nif (require.main !== module) {\n\t// Export factory function for ioBroker, also available as ES6 export\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"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,YAAuB;AACvB,0BAAgF;AAMzE,MAAM,mBAAmB,MAAM,QAAQ;AAAA;AAAA,EAErC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,YAAY,UAAyC,CAAC,GAAG;AAC/D,UAAM;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACP,CAAC;AAED,SAAK,GAAG,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxC,SAAK,GAAG,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAIpD,SAAK,GAAG,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,UAAyB;AAEtC,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;AAGD,SAAK,KAAK,mBAAmB,0BAA0B;AAAA,MACtD,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACP;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAGD,SAAK,eAAe,IAAI,iCAAa;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,MACvB,gBAAgB,KAAK,OAAO;AAAA,MAC5B,6BAA6B,KAAK,OAAO;AAAA,MACzC,iBAAiB,KAAK,OAAO;AAAA,MAC7B,gBAAgB;AAAA,
|
|
4
|
+
"sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.3.0\n */\n\nimport * as utils from '@iobroker/adapter-core';\nimport { GoveeService, type DeviceDiscoveryEvent, type DeviceStatusEvent } from './lib/goveeService';\n\n/**\n * Main adapter class for ioBroker Govee Local.\n * Handles initialization, event wiring, and communication with GoveeService.\n */\nexport class GoveeLocal extends utils.Adapter {\n\t/** Instance of GoveeService for device communication */\n\tprivate goveeService!: GoveeService;\n\t/**\n\t * Adapter constructor. Registers lifecycle event handlers.\n\t *\n\t * @param options Optional adapter options to override defaults.\n\t */\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\t// Register event handlers for adapter lifecycle\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\t// Uncomment if you want to handle object changes or messages:\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 * Called when databases are connected and adapter received configuration.\n\t * Initializes GoveeService and sets up event listeners for device events.\n\t */\n\tprivate async onReady(): Promise<void> {\n\t\t// Create connection indicator state if it doesn't exist\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\n\t\t// Create state for discovered devices\n\t\tvoid this.setObjectNotExists('info.discoveredDevices', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'List of discovered devices',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'json',\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tdesc: 'JSON object with IP addresses and device names of all discovered devices',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Initialize GoveeService with adapter config and logger\n\t\tthis.goveeService = new GoveeService({\n\t\t\tinterface: this.config.interface,\n\t\t\tsearchInterval: this.config.searchInterval,\n\t\t\tdeviceStatusRefreshInterval: this.config.deviceStatusRefreshInterval,\n\t\t\textendedLogging: this.config.extendedLogging,\n\t\t\tforbiddenChars: this.FORBIDDEN_CHARS,\n\t\t\tmanualIpAddresses: this.config.manualIpTable,\n\t\t\tdisableAutoDiscovery: this.config.disableAutoDiscovery,\n\t\t\tlogger: {\n\t\t\t\tdebug: (msg) => this.log.debug(msg),\n\t\t\t\tinfo: (msg) => this.log.info(msg),\n\t\t\t\terror: (msg) => this.log.error(msg),\n\t\t\t},\n\t\t});\n\n\t\t// Listen for device discovery and status update events\n\t\tthis.goveeService.on('deviceDiscovered', (data) => {\n\t\t\tvoid this.handleDeviceDiscovered(data);\n\t\t});\n\n\t\tthis.goveeService.on('deviceStatusUpdate', (data) => {\n\t\t\tvoid this.handleDeviceStatusUpdate(data);\n\t\t});\n\n\t\t// Listen for serviceStarted event to set connection state to true\n\t\tthis.goveeService.on('serviceStarted', () => {\n\t\t\tvoid this.setState('info.connection', { val: true, ack: true });\n\t\t});\n\n\t\t// Start device discovery and status polling\n\t\tthis.goveeService.start();\n\n\t\tif (this.config.extendedLogging) {\n\t\t\tthis.log.debug('running with extended logging');\n\t\t}\n\n\t\t// Subscribe to all device status state changes\n\t\tvoid this.subscribeStates('*.devStatus.*');\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Called if a subscribed state changes (e.g. user toggles a switch in ioBroker UI).\n\t * Forwards the change to the GoveeService for device communication.\n\t *\n\t * @param id The ID of the changed state.\n\t * @param state The new state object or 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\t// Extract device name from state ID and get its IP address\n\t\t\tconst ipOfDevice = await this.getStateAsync(`${id.split('.')[2]}.deviceInfo.ip`);\n\t\t\tconst receiver = ipOfDevice?.val?.toString();\n\t\t\tif (typeof receiver === 'string') {\n\t\t\t\t// Forward the state change to the GoveeService\n\t\t\t\tthis.goveeService.handleStateChange(id, state, receiver);\n\t\t\t} else {\n\t\t\t\tthis.log.error('device not found or IP is not a string');\n\t\t\t}\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t * Called when the adapter shuts down. Cleans up resources and stops services.\n\t *\n\t * @param callback Callback function after unload process.\n\t */\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.goveeService) {\n\t\t\t\tthis.goveeService.removeAllListeners();\n\t\t\t\tthis.goveeService.stop();\n\t\t\t}\n\t\t\t// Set connection state to false\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 * Updates a state only if the value has changed.\n\t *\n\t * @param fullName Full object path\n\t * @param state New value\n\t * @param acknowledged Whether the value is acknowledged (default: true)\n\t */\n\tprivate async updateStateAsync(fullName: string, state: any, acknowledged = true): Promise<void> {\n\t\tconst currentState = await this.getStateAsync(fullName);\n\t\tif (currentState?.val !== 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\t/**\n\t * Handles device discovery event from GoveeService.\n\t * Creates all necessary objects and states for the new device.\n\t *\n\t * @param event The device discovery event data.\n\t */\n\tprivate async handleDeviceDiscovered(event: DeviceDiscoveryEvent): Promise<void> {\n\t\tconst { ip, deviceName, deviceModel } = event;\n\n\t\t// Create device folder\n\t\tawait this.setObjectNotExistsAsync(deviceName, {\n\t\t\ttype: 'device',\n\t\t\tcommon: {\n\t\t\t\tname: deviceModel,\n\t\t\t\trole: 'group',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Create deviceInfo folder\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.deviceInfo`, {\n\t\t\ttype: 'folder',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device Info',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\t// Create IP address state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.deviceInfo.ip`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'IP address of the Lamp',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'info.ip',\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\tawait this.updateStateAsync(`${deviceName}.deviceInfo.ip`, ip);\n\n\t\t// Create devStatus folder\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus`, {\n\t\t\ttype: 'folder',\n\t\t\tcommon: {\n\t\t\t\tname: 'Device Status',\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tthis.log.info(`Device discovered: ${deviceName} at ${ip}`);\n\n\t\t// Update the list of discovered devices\n\t\tawait this.updateDiscoveredDevicesList();\n\t}\n\n\t/**\n\t * Updates the info.discoveredDevices state with the current list of all discovered devices.\n\t */\n\tprivate async updateDiscoveredDevicesList(): Promise<void> {\n\t\tconst devices = this.goveeService.getDevices();\n\t\tawait this.setStateAsync('info.discoveredDevices', {\n\t\t\tval: JSON.stringify(devices, null, 2),\n\t\t\tack: true,\n\t\t});\n\t}\n\n\t/**\n\t * Handles device status update event from GoveeService.\n\t * Creates and updates all relevant states for the device.\n\t *\n\t * @param event The device status update event data.\n\t */\n\tprivate async handleDeviceStatusUpdate(event: DeviceStatusEvent): Promise<void> {\n\t\tconst { deviceName, status } = event;\n\n\t\t// Create and update onOff state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.onOff`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'On / Off state of the lamp',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'switch',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.onOff`, status.onOff);\n\n\t\t// Create and update brightness state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.brightness`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Brightness of the light',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.dimmer',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.brightness`, status.brightness);\n\n\t\t// Create and update color state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.color`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'Current showing color of the lamp',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'level.color.rgb',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.color`, status.color);\n\n\t\t// Create and update color temperature state\n\t\tawait this.setObjectNotExistsAsync(`${deviceName}.devStatus.colorTemInKelvin`, {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: 'If staying in white light, the color temperature',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.color.temperature',\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.updateStateAsync(`${deviceName}.devStatus.colorTemInKelvin`, status.colorTemInKelvin);\n\t}\n}\n\n// Export factory function for ioBroker or start instance directly\nif (require.main !== module) {\n\t// Export factory function for ioBroker, also available as ES6 export\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"],
|
|
5
|
+
"mappings": "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",
|
|
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.4.
|
|
4
|
+
"version": "0.4.3",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.4.3": {
|
|
7
|
+
"en": "fix responsive design in the settings\nrevert forbidden characters checking\nupdate dependencies",
|
|
8
|
+
"de": "reagierendes design in den einstellungen beheben\nzurücksetzen verbotene zeichen überprüfen\naktualisierung der abhängigkeiten",
|
|
9
|
+
"ru": "исправить отзывчивый дизайн в настройках\nпроверка запрещенных персонажей\nобновление зависимостей",
|
|
10
|
+
"pt": "corrigir o design responsivo nas configurações\nreverter a verificação de caracteres proibidos\natualizar dependências",
|
|
11
|
+
"nl": "repareren responsief ontwerp in de instellingen\n_verboden tekens controleren\nafhankelijkheden bijwerken",
|
|
12
|
+
"fr": "fixer la conception réactive dans les paramètres\nretourner la vérification des caractères interdits\nmettre à jour les dépendances",
|
|
13
|
+
"it": "fissare il design reattivo nelle impostazioni\nrevert i caratteri vietati controllando\naggiornamento dipendenze",
|
|
14
|
+
"es": "fijar diseño sensible en la configuración\nrevertir caracteres prohibidos\ndependencias de actualización",
|
|
15
|
+
"pl": "naprawić reagujący projekt w ustawieniach\nrevert zabronione sprawdzanie znaków\naktualizacji zależności",
|
|
16
|
+
"uk": "виправити адаптивний дизайн в налаштуваннях\nперевернути заборонені символи перевірки\nоновлення залежності",
|
|
17
|
+
"zh-cn": "在设置中固定响应性设计\n返回禁用字符检查\n更新依赖关系"
|
|
18
|
+
},
|
|
6
19
|
"0.4.2": {
|
|
7
20
|
"en": "update dependencies\nfix device name / model identifier in the objects",
|
|
8
21
|
"de": "aktualisierung der abhängigkeiten\ngerätename / modellkennung in den objekten fixieren",
|
|
@@ -43,19 +56,6 @@
|
|
|
43
56
|
"zh-cn": "更新所有支持语言的数据点描述翻译\n更新和现代化管理 UI: 更清晰的段落、 手动 IP 地址列表、 Windows 提示和禁用自动发现选项\n通过 IP- Address和选项手动添加设备以禁用自动发现的可能性\n在信息数据点中保存自动发现的设备, 并在 admin UI 中显示"
|
|
44
57
|
},
|
|
45
58
|
"0.3.1": {
|
|
46
|
-
"en": "updated release script run configuration",
|
|
47
|
-
"de": "aktualisierte versionsskriptlaufkonfiguration",
|
|
48
|
-
"ru": "обновленная конфигурация для запуска сценария",
|
|
49
|
-
"pt": "configuração de execução do script de versão atualizada",
|
|
50
|
-
"nl": "bijgewerkte versie script-run configuratie",
|
|
51
|
-
"fr": "mise à jour de la configuration du script de publication",
|
|
52
|
-
"it": "configurazione dell'esecuzione dello script di rilascio aggiornata",
|
|
53
|
-
"es": "configuración actualizada script script script run",
|
|
54
|
-
"pl": "zaktualizowana konfiguracja uruchamiania skryptu wydania",
|
|
55
|
-
"uk": "оновлена конфігурація запуску сценарію релізу",
|
|
56
|
-
"zh-cn": "更新发布脚本运行配置"
|
|
57
|
-
},
|
|
58
|
-
"0.3.0": {
|
|
59
59
|
"en": "Refactored: Moved all device logic to a dedicated GoveeService class, modularized utilities\nImproved test coverage\nDependencies updated",
|
|
60
60
|
"de": "Hergestellt: Alle Gerätelogik auf eine dedizierte GoveeService-Klasse verschoben, modularisierte Versorgungsprogramme\nVerbesserte Testabdeckung\nAusgaben aktualisiert",
|
|
61
61
|
"ru": "Рефакторированный: Перенес всю логику устройства в выделенный класс GoveeService, модульные утилиты\nУлучшенный охват испытаниями\nОбновленные зависимости",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.govee-local",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Control Govee devices via local access (no cloud)",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Børge Grunicke",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@alcalzone/release-script-plugin-manual-review": "^4.0.0",
|
|
32
32
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
33
33
|
"@iobroker/eslint-config": "^2.2.0",
|
|
34
|
-
"@iobroker/testing": "^5.
|
|
34
|
+
"@iobroker/testing": "^5.2.2",
|
|
35
35
|
"@tsconfig/node14": "^14.1.5",
|
|
36
36
|
"@tsconfig/node18": "^18.2.4",
|
|
37
37
|
"@tsconfig/node20": "^20.1.6",
|