iobroker.iot 5.0.2 → 5.0.6
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 +10 -6
- package/admin/assets/{index-CZlHvSGg.js → index-D9hse2qJ.js} +88 -88
- package/admin/index_m.html +1 -1
- package/build/lib/AlexaSmartHomeV3/Alexa/Capabilities/Base.js +0 -3
- package/build/lib/AlexaSmartHomeV3/Alexa/Capabilities/Base.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js +3 -0
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js +3 -0
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/PowerState.js +3 -2
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/PowerState.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/RelativeHumidity.js +3 -0
- package/build/lib/AlexaSmartHomeV3/Alexa/Properties/RelativeHumidity.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Controls/Control.js +1 -1
- package/build/lib/AlexaSmartHomeV3/Controls/Control.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Controls/Hue.js +35 -9
- package/build/lib/AlexaSmartHomeV3/Controls/Hue.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/DeviceManager.js +6 -6
- package/build/lib/AlexaSmartHomeV3/DeviceManager.js.map +1 -1
- package/build/lib/AlexaSmartHomeV3/Helpers/Utils.js +34 -0
- package/build/lib/AlexaSmartHomeV3/Helpers/Utils.js.map +1 -1
- package/build/main.js +1 -1
- package/build/main.js.map +1 -1
- package/io-package.json +27 -27
- package/package.json +6 -6
|
@@ -174,7 +174,9 @@ class DeviceManager {
|
|
|
174
174
|
// detectedControls = detectedControls.filter(c => ['light', 'dimmer'].includes(c.type));
|
|
175
175
|
const createdGroups = [];
|
|
176
176
|
const usedFriendlyNames = [];
|
|
177
|
+
let iteration = 0;
|
|
177
178
|
while (detectedControls.length) {
|
|
179
|
+
iteration++;
|
|
178
180
|
// take the next control
|
|
179
181
|
const control = detectedControls[0];
|
|
180
182
|
let processedControls = [];
|
|
@@ -261,12 +263,10 @@ class DeviceManager {
|
|
|
261
263
|
// neither room nor smart name
|
|
262
264
|
this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);
|
|
263
265
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// const objectIds = processedControls.map(item => item.object?.id);
|
|
269
|
-
// detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));
|
|
266
|
+
if (iteration > 1000) {
|
|
267
|
+
this.log.error(`too many iterations while collecting devices. Stopping to avoid endless loop: ${JSON.stringify(detectedControls)}`);
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
270
|
}
|
|
271
271
|
// done
|
|
272
272
|
this.log.debug(`finished collecting devices. there is/are ${this.devices.length} device(s) in total`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceManager.js","sourceRoot":"","sources":["../../../src/lib/AlexaSmartHomeV3/DeviceManager.ts"],"names":[],"mappings":"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","sourcesContent":["import Device from './Device';\nimport * as Utils from './Helpers/Utils';\nimport Directives from './Alexa/Directives';\nimport Controls from './Controls';\nimport type Control from './Controls/Control';\nimport Logger from './Helpers/Logger';\nimport AdapterProvider from './Helpers/AdapterProvider';\nimport AlexaResponse from './Alexa/AlexaResponse';\nimport IotProxy from './Helpers/IotProxy';\nimport RateLimiter from './Helpers/RateLimiter';\nimport OverallDailyRateLimitExceeded from './Exceptions/OverallDailyRateLimitExceeded';\nimport HourlyDeviceRateLimitExceeded from './Exceptions/HourlyDeviceRateLimitExceeded';\nimport type { AlexaV3EndpointID, AlexaV3Request, IotExternalPatternControl } from './types';\nimport ChangeReport from './Alexa/Directives/ChangeReport';\nimport Discovery from './Alexa/Directives/Discovery';\nimport ReportState from './Alexa/Directives/ReportState';\nimport { randomUUID } from 'node:crypto';\nimport type { Types } from '@iobroker/type-detector';\n\nconst GroupWord: { [lang: string]: string } = {\n en: 'Group',\n de: 'Gruppe',\n it: 'Gruppo',\n fr: 'Groupe',\n ru: 'Группа',\n es: 'Grupo',\n pl: 'Grupa',\n nl: 'Groep',\n};\nconst DeviceWord: { [lang: string]: string } = {\n en: 'Device',\n de: 'Gerät',\n it: 'Dispositivo',\n fr: 'Appareil',\n ru: 'Устройство',\n es: 'Dispositivo',\n pl: 'Urządzenie',\n nl: 'Dispositivo',\n};\n\nexport default class DeviceManager {\n private lang: ioBroker.Languages = 'en';\n private devices: Device[] = [];\n private subscribed: string[] = [];\n private log: Logger;\n private eventsPausedTill = 0; // timestamp\n\n private collecting = false;\n private recollect = false;\n\n /** Creates a Device Manager */\n constructor() {\n this.log = new Logger(this);\n }\n\n async informAboutStatesChange(): Promise<void> {\n await AdapterProvider.get().setStateAsync('smart.updates3', true, true);\n }\n\n get language(): ioBroker.Languages {\n return this.lang;\n }\n\n set language(value: ioBroker.Languages) {\n this.lang = value;\n }\n\n matchDirective(event: AlexaV3Request): ChangeReport | Discovery | ReportState | null {\n if (ChangeReport.matches(event)) {\n return new ChangeReport();\n }\n if (Discovery.matches(event)) {\n return new Discovery();\n }\n if (ReportState.matches(event)) {\n return new ReportState();\n }\n\n return null;\n }\n\n get endpoints(): Device[] {\n return this.devices;\n }\n\n endpointById(id: AlexaV3EndpointID): Device | undefined {\n return this.devices.find(device => device.id === id);\n }\n\n addDevice(device: Device): void {\n this.devices.push(device);\n }\n\n toDevice(options: {\n detectedControls: IotExternalPatternControl[];\n friendlyName: string;\n autoDetected: boolean;\n roomName?: string;\n funcName?: string;\n toggle?: boolean;\n possibleTypes: Types[];\n typeWasDetected: boolean;\n }): Device | undefined {\n const controls: Control[] = [];\n\n this.log.debug(`merging controls to a device with name ${options.friendlyName}`);\n\n options.detectedControls.forEach(item => {\n this.log.silly(`processing control: ${JSON.stringify(item)}`);\n const control = Controls.factory(item);\n\n if (control) {\n this.log.debug(`\"${item.type}\" added to \"${options.friendlyName}\"`);\n controls.push(control);\n } else {\n this.log.debug(`control of type \"${item.type}\" not supported yet. Skipped.`);\n }\n });\n\n if (!controls.length) {\n // the controls are not supported yet...\n return;\n }\n\n // create and add a new device to the collected devices\n this.addDevice(\n new Device({\n id: options.friendlyName,\n friendlyName: options.friendlyName,\n controls,\n autoDetected: options.autoDetected,\n roomName: options.roomName,\n funcName: options.funcName,\n toggle: options.toggle,\n possibleTypes: options.possibleTypes,\n typeWasDetected: options.typeWasDetected,\n }),\n );\n }\n\n getName(name: ioBroker.StringOrTranslated | undefined): string {\n if (!name) {\n return '';\n }\n if (typeof name === 'object') {\n return name[this.lang] || name.en || '';\n }\n return name;\n }\n\n async collectEndpoints(): Promise<void> {\n if (this.collecting) {\n this.log.debug(`collecting devices already in progress. Skipping...`);\n this.recollect = true;\n return;\n }\n this.collecting = true;\n this.log.debug(`(re)collecting devices...`);\n try {\n // const discoveryNeeded = this.devices.length > 0;\n\n this.devices = [];\n const defaultToggle = AdapterProvider.get().config.defaultToggle || false;\n\n // collect all iobroker controls in terms of iobroker type detector (https://github.com/ioBroker/ioBroker.type-detector)\n const detectedControls = await Utils.controls(AdapterProvider.get(), this.lang);\n\n this.log.debug(`type detector found ${detectedControls.length} controls`);\n\n // Normally, every control is a smart device. But due to the iobroker concept of 'rooms and functions'\n // multiple controls might be merged to a single device.\n\n // as long as not all controls mapped to a device...\n\n // detectedControls = detectedControls.filter(c => ['light', 'dimmer'].includes(c.type));\n const createdGroups: string[] = [];\n const usedFriendlyNames: string[] = [];\n\n while (detectedControls.length) {\n // take the next control\n const control = detectedControls[0];\n let processedControls: IotExternalPatternControl[] = [];\n\n if (control.room?.common?.name) {\n if (control.functionality?.common?.name) {\n // controls in the same room with the same functionality\n processedControls = detectedControls.filter(\n item =>\n control.room &&\n item.room?.id === control.room.id &&\n control.functionality &&\n item.functionality?.id === control.functionality.id,\n );\n let friendlyName = Utils.friendlyNameByRoomAndFunctionName(control, this.lang);\n // If a friendly name is already used, append Gruppe, Group, Gruppo, Groupe, etc.\n if (usedFriendlyNames.includes(friendlyName)) {\n let index = 0;\n let newFriendlyName = '';\n do {\n newFriendlyName = `${friendlyName} ${GroupWord[this.lang] || GroupWord.en}${index ? ` ${index}` : ''}`;\n index++;\n } while (usedFriendlyNames.includes(newFriendlyName));\n friendlyName = newFriendlyName;\n }\n usedFriendlyNames.push(friendlyName);\n\n this.toDevice({\n detectedControls: processedControls,\n friendlyName,\n autoDetected: true,\n roomName: this.getName(control.room?.common?.name),\n funcName: this.getName(control.functionality?.common?.name),\n toggle: processedControls[0].object?.toggle ?? defaultToggle,\n possibleTypes: processedControls[0].object?.possibleTypes || [],\n typeWasDetected: processedControls[0].object?.typeWasDetected || false,\n });\n } else {\n this.log.debug(\n `Control of type [${control.type}] assigned to room [${this.getName(control.room.common.name)}] has no function. Skipped.`,\n );\n }\n // delete it from detected controls to avoid endless loop\n detectedControls.splice(0, 1);\n } else if (control.groupNames?.length) {\n // no room, but smart name (not only one)\n control.groupNames.forEach(groupName => {\n if (!createdGroups.includes(groupName)) {\n createdGroups.push(groupName);\n processedControls = detectedControls.filter(item => item.groupNames?.includes(groupName));\n let friendlyName = this.getName(groupName);\n // If a friendly name is already used, append Device\n if (usedFriendlyNames.includes(friendlyName)) {\n let index = 0;\n let newFriendlyName = '';\n do {\n newFriendlyName = `${friendlyName} ${DeviceWord[this.lang] || DeviceWord.en}${index ? ` ${index}` : ''}`;\n index++;\n } while (usedFriendlyNames.includes(newFriendlyName));\n friendlyName = newFriendlyName;\n }\n usedFriendlyNames.push(friendlyName);\n\n this.toDevice({\n detectedControls: JSON.parse(JSON.stringify(processedControls)),\n friendlyName,\n autoDetected: false,\n toggle: processedControls[0].object?.toggle ?? defaultToggle,\n possibleTypes: processedControls[0].object?.possibleTypes || [],\n typeWasDetected: processedControls[0].object?.typeWasDetected || false,\n });\n\n // Remove groupName from all controls to avoid processing it again\n for (let c = detectedControls.length - 1; c >= 0; c--) {\n if (detectedControls[c].groupNames) {\n const pos = detectedControls[c].groupNames?.indexOf(groupName);\n if (pos !== -1) {\n detectedControls[c].groupNames.splice(pos, 1);\n }\n if (!detectedControls[c].groupNames.length) {\n detectedControls.splice(c, 1);\n }\n }\n }\n }\n });\n } else {\n // delete it from detected controls to avoid endless loop\n detectedControls.splice(0, 1);\n // neither room nor smart name\n this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);\n }\n\n // if (!processedControls.length) {\n // processedControls = [control];\n // }\n\n // remove processed controls\n // const objectIds = processedControls.map(item => item.object?.id);\n // detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));\n }\n\n // done\n this.log.debug(`finished collecting devices. there is/are ${this.devices.length} device(s) in total`);\n for (const device of this.devices) {\n this.log.debug(`${device.toString()}`);\n }\n\n // a new discovery process is needed in case we had already devices and device collection was\n // triggered again by, e.g., a change in room/function enums\n // if (discoveryNeeded) {\n // this.log.info(`Please delete all managed by ioBroker devices in your Alexa app and then start discovery`);\n // }\n\n // collect all relevant states to subscribe to updates\n const stateIds = new Set(\n this.devices\n .flatMap(d => d.controls)\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .map(item => item.getId)\n .filter(id => id),\n );\n this.log.debug(`registering for updates of total ${stateIds.size} states`);\n const newSubscribed = Array.from(stateIds);\n const subscribe: string[] = [];\n for (const id of newSubscribed) {\n this.log.silly(`subscribing to updates of ${id}`);\n if (!this.subscribed.includes(id)) {\n this.subscribed.push(id);\n if (!subscribe.includes(id)) {\n subscribe.push(id);\n }\n }\n }\n\n this.subscribed.sort();\n\n // wait till all promises are settled\n if (subscribe.length) {\n await AdapterProvider.subscribe(subscribe);\n }\n\n // unsubscribe from unused states\n const unsubscribe: string[] = [];\n for (let i = this.subscribed.length - 1; i >= 0; i--) {\n const id = this.subscribed[i];\n if (!newSubscribed.includes(id)) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n this.subscribed.splice(i, 1);\n if (!unsubscribe.includes(id)) {\n unsubscribe.push(id);\n }\n }\n }\n if (unsubscribe.length) {\n await AdapterProvider.unsubscribe(unsubscribe);\n }\n } catch (e) {\n this.log.error(`failed to collect devices: ${e}`);\n if (e.stack) {\n this.log.error(e.stack);\n }\n }\n\n this.collecting = false;\n\n // if during the collection a new collection was triggered, start collecting again\n if (this.recollect) {\n this.recollect = false;\n setTimeout(() => this.collectEndpoints(), 1000);\n }\n }\n\n async destroy(): Promise<void> {\n const promises = [];\n for (const id of this.subscribed) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n promises.push(AdapterProvider.subscribe(id));\n }\n await Promise.allSettled(promises);\n\n this.subscribed = [];\n }\n\n publishStateChange(stateChange: AlexaResponse): void {\n if (this.eventsPausedTill < Date.now()) {\n this.log.silly(`publishing ${JSON.stringify(stateChange)}`);\n IotProxy.publishStateChange(stateChange);\n }\n }\n\n pauseEvents(): void {\n this.eventsPausedTill = Date.now() + 30 * 60 * 1000; // 30 minutes\n }\n\n async executeWithinRateLimits(\n endpointId: AlexaV3EndpointID,\n awaitable: () => Promise<AlexaResponse>,\n errorResponse: AlexaResponse,\n ): Promise<AlexaResponse> {\n try {\n await RateLimiter.incrementAndGet(endpointId);\n return await awaitable();\n } catch (error) {\n if (error instanceof OverallDailyRateLimitExceeded || error instanceof HourlyDeviceRateLimitExceeded) {\n this.log.warn(error.message);\n } else {\n this.log.error(error.message);\n }\n\n return errorResponse;\n }\n }\n\n async handleAlexaEvent(event: AlexaV3Request): Promise<AlexaResponse> {\n this.log.debug(`incoming Alexa event`);\n this.log.silly(`${JSON.stringify(event)}`);\n if (!event?.directive?.header) {\n throw new Error('Alexa event header is missing');\n }\n\n let response: AlexaResponse;\n const directive = this.matchDirective(event);\n if (directive) {\n response = await directive.handle(event, this);\n } else {\n const endpointId = event?.directive?.endpoint?.endpointId;\n const device = endpointId ? this.endpointById(endpointId) : undefined;\n\n if (device) {\n if (device.supports(event)) {\n response = await this.executeWithinRateLimits(\n endpointId!,\n async () => {\n response = await device.handle(event);\n if (!AlexaResponse.isErrorResponse(response)) {\n // report state change via voice interaction\n const propertyName = response.context?.properties[0].name;\n const responseEvent = ChangeReport.get(\n device.id,\n propertyName || '',\n false,\n event.directive.header.messageId,\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n const stateChange = await directive.handle(responseEvent, this);\n // get device state (not just one control)\n const deviceState = await device.reportState();\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n // fire state change report to Alexa\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n if (process.env.TESTS_EXECUTION) {\n this.publishStateChange(stateChange);\n }\n await this.informAboutStatesChange();\n } else {\n this.log.debug(\n `ignoring state change event for ${endpointId} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n return response;\n },\n AlexaResponse.throttlingException(event.directive.header.messageId).get(),\n );\n } else {\n response = AlexaResponse.directiveNotSupportedByDevice(\n device.friendlyName,\n event.directive.header.namespace,\n event.directive.header.messageId,\n event.directive.header.payloadVersion,\n ).get();\n }\n } else {\n response = AlexaResponse.endpointUnreachable(event.directive.header.messageId).get();\n }\n }\n\n this.log.silly(`response: ${JSON.stringify(response)}`);\n return response;\n }\n\n async handleStateUpdate(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n // ignore updates not confirmed by a corresponding device\n if (!state?.ack) {\n this.log.silly(`ignoring state change event for ${id} due to state.ack == ${state?.ack}`);\n return;\n }\n if (id.startsWith(`${AdapterProvider.get().namespace}.`)) {\n // nop, this is just to inform Alexa app about changes\n return;\n }\n\n let notFound = true;\n\n for (const device of this.devices) {\n const property = device.controls\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .find(item => item.getId === id);\n\n if (property) {\n notFound = false;\n if (property.currentValue === state.val) {\n this.log.debug(`ignoring state change event for ${id} due to the same value [${state.val}]`);\n } else {\n property.currentValue = state.val;\n\n const responseEvent = Directives.ChangeReport.get(\n device.id,\n property.propertyName,\n true,\n randomUUID(),\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n const stateChange = await directive.handle(responseEvent, this);\n\n // get device state (not just one control)\n const deviceState = await device.reportState();\n\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n await this.informAboutStatesChange();\n // fire state change report to Alexa\n\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n if (process.env.TESTS_EXECUTION) {\n await this.executeWithinRateLimits(\n device.id,\n () => {\n this.publishStateChange(stateChange);\n return Promise.resolve(stateChange);\n },\n AlexaResponse.throttlingException(responseEvent.directive.header.messageId).get(),\n );\n }\n } else {\n this.log.debug(\n `ignoring state change event for ${id} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n\n // should be the only device having the id => stop processing here\n break;\n }\n }\n\n // this should never happen\n if (notFound) {\n this.log.debug(`state id ${id} doesn't belong to any device`);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DeviceManager.js","sourceRoot":"","sources":["../../../src/lib/AlexaSmartHomeV3/DeviceManager.ts"],"names":[],"mappings":"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","sourcesContent":["import Device from './Device';\nimport * as Utils from './Helpers/Utils';\nimport Directives from './Alexa/Directives';\nimport Controls from './Controls';\nimport type Control from './Controls/Control';\nimport Logger from './Helpers/Logger';\nimport AdapterProvider from './Helpers/AdapterProvider';\nimport AlexaResponse from './Alexa/AlexaResponse';\nimport IotProxy from './Helpers/IotProxy';\nimport RateLimiter from './Helpers/RateLimiter';\nimport OverallDailyRateLimitExceeded from './Exceptions/OverallDailyRateLimitExceeded';\nimport HourlyDeviceRateLimitExceeded from './Exceptions/HourlyDeviceRateLimitExceeded';\nimport type { AlexaV3EndpointID, AlexaV3Request, IotExternalPatternControl } from './types';\nimport ChangeReport from './Alexa/Directives/ChangeReport';\nimport Discovery from './Alexa/Directives/Discovery';\nimport ReportState from './Alexa/Directives/ReportState';\nimport { randomUUID } from 'node:crypto';\nimport type { Types } from '@iobroker/type-detector';\n\nconst GroupWord: { [lang: string]: string } = {\n en: 'Group',\n de: 'Gruppe',\n it: 'Gruppo',\n fr: 'Groupe',\n ru: 'Группа',\n es: 'Grupo',\n pl: 'Grupa',\n nl: 'Groep',\n};\nconst DeviceWord: { [lang: string]: string } = {\n en: 'Device',\n de: 'Gerät',\n it: 'Dispositivo',\n fr: 'Appareil',\n ru: 'Устройство',\n es: 'Dispositivo',\n pl: 'Urządzenie',\n nl: 'Dispositivo',\n};\n\nexport default class DeviceManager {\n private lang: ioBroker.Languages = 'en';\n private devices: Device[] = [];\n private subscribed: string[] = [];\n private log: Logger;\n private eventsPausedTill = 0; // timestamp\n\n private collecting = false;\n private recollect = false;\n\n /** Creates a Device Manager */\n constructor() {\n this.log = new Logger(this);\n }\n\n async informAboutStatesChange(): Promise<void> {\n await AdapterProvider.get().setStateAsync('smart.updates3', true, true);\n }\n\n get language(): ioBroker.Languages {\n return this.lang;\n }\n\n set language(value: ioBroker.Languages) {\n this.lang = value;\n }\n\n matchDirective(event: AlexaV3Request): ChangeReport | Discovery | ReportState | null {\n if (ChangeReport.matches(event)) {\n return new ChangeReport();\n }\n if (Discovery.matches(event)) {\n return new Discovery();\n }\n if (ReportState.matches(event)) {\n return new ReportState();\n }\n\n return null;\n }\n\n get endpoints(): Device[] {\n return this.devices;\n }\n\n endpointById(id: AlexaV3EndpointID): Device | undefined {\n return this.devices.find(device => device.id === id);\n }\n\n addDevice(device: Device): void {\n this.devices.push(device);\n }\n\n toDevice(options: {\n detectedControls: IotExternalPatternControl[];\n friendlyName: string;\n autoDetected: boolean;\n roomName?: string;\n funcName?: string;\n toggle?: boolean;\n possibleTypes: Types[];\n typeWasDetected: boolean;\n }): Device | undefined {\n const controls: Control[] = [];\n\n this.log.debug(`merging controls to a device with name ${options.friendlyName}`);\n\n options.detectedControls.forEach(item => {\n this.log.silly(`processing control: ${JSON.stringify(item)}`);\n const control = Controls.factory(item);\n\n if (control) {\n this.log.debug(`\"${item.type}\" added to \"${options.friendlyName}\"`);\n controls.push(control);\n } else {\n this.log.debug(`control of type \"${item.type}\" not supported yet. Skipped.`);\n }\n });\n\n if (!controls.length) {\n // the controls are not supported yet...\n return;\n }\n\n // create and add a new device to the collected devices\n this.addDevice(\n new Device({\n id: options.friendlyName,\n friendlyName: options.friendlyName,\n controls,\n autoDetected: options.autoDetected,\n roomName: options.roomName,\n funcName: options.funcName,\n toggle: options.toggle,\n possibleTypes: options.possibleTypes,\n typeWasDetected: options.typeWasDetected,\n }),\n );\n }\n\n getName(name: ioBroker.StringOrTranslated | undefined): string {\n if (!name) {\n return '';\n }\n if (typeof name === 'object') {\n return name[this.lang] || name.en || '';\n }\n return name;\n }\n\n async collectEndpoints(): Promise<void> {\n if (this.collecting) {\n this.log.debug(`collecting devices already in progress. Skipping...`);\n this.recollect = true;\n return;\n }\n this.collecting = true;\n this.log.debug(`(re)collecting devices...`);\n try {\n // const discoveryNeeded = this.devices.length > 0;\n\n this.devices = [];\n const defaultToggle = AdapterProvider.get().config.defaultToggle || false;\n\n // collect all iobroker controls in terms of iobroker type detector (https://github.com/ioBroker/ioBroker.type-detector)\n const detectedControls = await Utils.controls(AdapterProvider.get(), this.lang);\n\n this.log.debug(`type detector found ${detectedControls.length} controls`);\n\n // Normally, every control is a smart device. But due to the iobroker concept of 'rooms and functions'\n // multiple controls might be merged to a single device.\n\n // as long as not all controls mapped to a device...\n\n // detectedControls = detectedControls.filter(c => ['light', 'dimmer'].includes(c.type));\n const createdGroups: string[] = [];\n const usedFriendlyNames: string[] = [];\n let iteration = 0;\n\n while (detectedControls.length) {\n iteration++;\n // take the next control\n const control = detectedControls[0];\n let processedControls: IotExternalPatternControl[] = [];\n\n if (control.room?.common?.name) {\n if (control.functionality?.common?.name) {\n // controls in the same room with the same functionality\n processedControls = detectedControls.filter(\n item =>\n control.room &&\n item.room?.id === control.room.id &&\n control.functionality &&\n item.functionality?.id === control.functionality.id,\n );\n let friendlyName = Utils.friendlyNameByRoomAndFunctionName(control, this.lang);\n // If a friendly name is already used, append Gruppe, Group, Gruppo, Groupe, etc.\n if (usedFriendlyNames.includes(friendlyName)) {\n let index = 0;\n let newFriendlyName = '';\n do {\n newFriendlyName = `${friendlyName} ${GroupWord[this.lang] || GroupWord.en}${index ? ` ${index}` : ''}`;\n index++;\n } while (usedFriendlyNames.includes(newFriendlyName));\n friendlyName = newFriendlyName;\n }\n usedFriendlyNames.push(friendlyName);\n\n this.toDevice({\n detectedControls: processedControls,\n friendlyName,\n autoDetected: true,\n roomName: this.getName(control.room?.common?.name),\n funcName: this.getName(control.functionality?.common?.name),\n toggle: processedControls[0].object?.toggle ?? defaultToggle,\n possibleTypes: processedControls[0].object?.possibleTypes || [],\n typeWasDetected: processedControls[0].object?.typeWasDetected || false,\n });\n } else {\n this.log.debug(\n `Control of type [${control.type}] assigned to room [${this.getName(control.room.common.name)}] has no function. Skipped.`,\n );\n }\n // delete it from detected controls to avoid endless loop\n detectedControls.splice(0, 1);\n } else if (control.groupNames?.length) {\n // no room, but smart name (not only one)\n control.groupNames.forEach(groupName => {\n if (!createdGroups.includes(groupName)) {\n createdGroups.push(groupName);\n processedControls = detectedControls.filter(item => item.groupNames?.includes(groupName));\n let friendlyName = this.getName(groupName);\n // If a friendly name is already used, append Device\n if (usedFriendlyNames.includes(friendlyName)) {\n let index = 0;\n let newFriendlyName = '';\n do {\n newFriendlyName = `${friendlyName} ${DeviceWord[this.lang] || DeviceWord.en}${index ? ` ${index}` : ''}`;\n index++;\n } while (usedFriendlyNames.includes(newFriendlyName));\n friendlyName = newFriendlyName;\n }\n usedFriendlyNames.push(friendlyName);\n\n this.toDevice({\n detectedControls: JSON.parse(JSON.stringify(processedControls)),\n friendlyName,\n autoDetected: false,\n toggle: processedControls[0].object?.toggle ?? defaultToggle,\n possibleTypes: processedControls[0].object?.possibleTypes || [],\n typeWasDetected: processedControls[0].object?.typeWasDetected || false,\n });\n\n // Remove groupName from all controls to avoid processing it again\n for (let c = detectedControls.length - 1; c >= 0; c--) {\n if (detectedControls[c].groupNames) {\n const pos = detectedControls[c].groupNames?.indexOf(groupName);\n if (pos !== -1) {\n detectedControls[c].groupNames.splice(pos, 1);\n }\n if (!detectedControls[c].groupNames.length) {\n detectedControls.splice(c, 1);\n }\n }\n }\n }\n });\n } else {\n // delete it from detected controls to avoid endless loop\n detectedControls.splice(0, 1);\n // neither room nor smart name\n this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);\n }\n\n if (iteration > 1000) {\n this.log.error(\n `too many iterations while collecting devices. Stopping to avoid endless loop: ${JSON.stringify(detectedControls)}`,\n );\n break;\n }\n }\n\n // done\n this.log.debug(`finished collecting devices. there is/are ${this.devices.length} device(s) in total`);\n for (const device of this.devices) {\n this.log.debug(`${device.toString()}`);\n }\n\n // a new discovery process is needed in case we had already devices and device collection was\n // triggered again by, e.g., a change in room/function enums\n // if (discoveryNeeded) {\n // this.log.info(`Please delete all managed by ioBroker devices in your Alexa app and then start discovery`);\n // }\n\n // collect all relevant states to subscribe to updates\n const stateIds = new Set(\n this.devices\n .flatMap(d => d.controls)\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .map(item => item.getId)\n .filter(id => id),\n );\n this.log.debug(`registering for updates of total ${stateIds.size} states`);\n const newSubscribed = Array.from(stateIds);\n const subscribe: string[] = [];\n for (const id of newSubscribed) {\n this.log.silly(`subscribing to updates of ${id}`);\n if (!this.subscribed.includes(id)) {\n this.subscribed.push(id);\n if (!subscribe.includes(id)) {\n subscribe.push(id);\n }\n }\n }\n\n this.subscribed.sort();\n\n // wait till all promises are settled\n if (subscribe.length) {\n await AdapterProvider.subscribe(subscribe);\n }\n\n // unsubscribe from unused states\n const unsubscribe: string[] = [];\n for (let i = this.subscribed.length - 1; i >= 0; i--) {\n const id = this.subscribed[i];\n if (!newSubscribed.includes(id)) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n this.subscribed.splice(i, 1);\n if (!unsubscribe.includes(id)) {\n unsubscribe.push(id);\n }\n }\n }\n if (unsubscribe.length) {\n await AdapterProvider.unsubscribe(unsubscribe);\n }\n } catch (e) {\n this.log.error(`failed to collect devices: ${e}`);\n if (e.stack) {\n this.log.error(e.stack);\n }\n }\n\n this.collecting = false;\n\n // if during the collection a new collection was triggered, start collecting again\n if (this.recollect) {\n this.recollect = false;\n setTimeout(() => this.collectEndpoints(), 1000);\n }\n }\n\n async destroy(): Promise<void> {\n const promises = [];\n for (const id of this.subscribed) {\n this.log.silly(`unsubscribing from updates of ${id}`);\n promises.push(AdapterProvider.subscribe(id));\n }\n await Promise.allSettled(promises);\n\n this.subscribed = [];\n }\n\n publishStateChange(stateChange: AlexaResponse): void {\n if (this.eventsPausedTill < Date.now()) {\n this.log.silly(`publishing ${JSON.stringify(stateChange)}`);\n IotProxy.publishStateChange(stateChange);\n }\n }\n\n pauseEvents(): void {\n this.eventsPausedTill = Date.now() + 30 * 60 * 1000; // 30 minutes\n }\n\n async executeWithinRateLimits(\n endpointId: AlexaV3EndpointID,\n awaitable: () => Promise<AlexaResponse>,\n errorResponse: AlexaResponse,\n ): Promise<AlexaResponse> {\n try {\n await RateLimiter.incrementAndGet(endpointId);\n return await awaitable();\n } catch (error) {\n if (error instanceof OverallDailyRateLimitExceeded || error instanceof HourlyDeviceRateLimitExceeded) {\n this.log.warn(error.message);\n } else {\n this.log.error(error.message);\n }\n\n return errorResponse;\n }\n }\n\n async handleAlexaEvent(event: AlexaV3Request): Promise<AlexaResponse> {\n this.log.debug(`incoming Alexa event`);\n this.log.silly(`${JSON.stringify(event)}`);\n if (!event?.directive?.header) {\n throw new Error('Alexa event header is missing');\n }\n\n let response: AlexaResponse;\n const directive = this.matchDirective(event);\n if (directive) {\n response = await directive.handle(event, this);\n } else {\n const endpointId = event?.directive?.endpoint?.endpointId;\n const device = endpointId ? this.endpointById(endpointId) : undefined;\n\n if (device) {\n if (device.supports(event)) {\n response = await this.executeWithinRateLimits(\n endpointId!,\n async () => {\n response = await device.handle(event);\n if (!AlexaResponse.isErrorResponse(response)) {\n // report state change via voice interaction\n const propertyName = response.context?.properties[0].name;\n const responseEvent = ChangeReport.get(\n device.id,\n propertyName || '',\n false,\n event.directive.header.messageId,\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n const stateChange = await directive.handle(responseEvent, this);\n // get device state (not just one control)\n const deviceState = await device.reportState();\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n // fire state change report to Alexa\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n if (process.env.TESTS_EXECUTION) {\n this.publishStateChange(stateChange);\n }\n await this.informAboutStatesChange();\n } else {\n this.log.debug(\n `ignoring state change event for ${endpointId} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n return response;\n },\n AlexaResponse.throttlingException(event.directive.header.messageId).get(),\n );\n } else {\n response = AlexaResponse.directiveNotSupportedByDevice(\n device.friendlyName,\n event.directive.header.namespace,\n event.directive.header.messageId,\n event.directive.header.payloadVersion,\n ).get();\n }\n } else {\n response = AlexaResponse.endpointUnreachable(event.directive.header.messageId).get();\n }\n }\n\n this.log.silly(`response: ${JSON.stringify(response)}`);\n return response;\n }\n\n async handleStateUpdate(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n // ignore updates not confirmed by a corresponding device\n if (!state?.ack) {\n this.log.silly(`ignoring state change event for ${id} due to state.ack == ${state?.ack}`);\n return;\n }\n if (id.startsWith(`${AdapterProvider.get().namespace}.`)) {\n // nop, this is just to inform Alexa app about changes\n return;\n }\n\n let notFound = true;\n\n for (const device of this.devices) {\n const property = device.controls\n .flatMap(item => item.supported)\n .flatMap(item => item.properties)\n .find(item => item.getId === id);\n\n if (property) {\n notFound = false;\n if (property.currentValue === state.val) {\n this.log.debug(`ignoring state change event for ${id} due to the same value [${state.val}]`);\n } else {\n property.currentValue = state.val;\n\n const responseEvent = Directives.ChangeReport.get(\n device.id,\n property.propertyName,\n true,\n randomUUID(),\n );\n const directive = this.matchDirective(responseEvent);\n if (directive) {\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n const stateChange = await directive.handle(responseEvent, this);\n\n // get device state (not just one control)\n const deviceState = await device.reportState();\n\n if (JSON.stringify(device.lastReportedState) !== JSON.stringify(deviceState)) {\n device.lastReportedState = deviceState;\n await this.informAboutStatesChange();\n // fire state change report to Alexa\n\n // BF[2024.02.04]: temporarily disabled as produced a huge number of events\n if (process.env.TESTS_EXECUTION) {\n await this.executeWithinRateLimits(\n device.id,\n () => {\n this.publishStateChange(stateChange);\n return Promise.resolve(stateChange);\n },\n AlexaResponse.throttlingException(responseEvent.directive.header.messageId).get(),\n );\n }\n } else {\n this.log.debug(\n `ignoring state change event for ${id} due to the same_ value [${JSON.stringify(deviceState)}]`,\n );\n }\n }\n }\n\n // should be the only device having the id => stop processing here\n break;\n }\n }\n\n // this should never happen\n if (notFound) {\n this.log.debug(`state id ${id} doesn't belong to any device`);\n }\n }\n}\n"]}
|
|
@@ -49,7 +49,9 @@ exports.isValidSmartName = isValidSmartName;
|
|
|
49
49
|
exports.defaultIfNullOrEmpty = defaultIfNullOrEmpty;
|
|
50
50
|
exports.controls = controls;
|
|
51
51
|
exports.normalize_0_100 = normalize_0_100;
|
|
52
|
+
exports.normalize_0_1 = normalize_0_1;
|
|
52
53
|
exports.denormalize_0_100 = denormalize_0_100;
|
|
54
|
+
exports.denormalize_0_1 = denormalize_0_1;
|
|
53
55
|
exports.distinctByPropertyName = distinctByPropertyName;
|
|
54
56
|
exports.className = className;
|
|
55
57
|
exports.ensureValueInRange_0_100 = ensureValueInRange_0_100;
|
|
@@ -323,8 +325,10 @@ async function controls(adapter, lang) {
|
|
|
323
325
|
const list = [];
|
|
324
326
|
// fetch all objects (states, channels and devices in terms of iobroker)
|
|
325
327
|
const devicesObject = await allObjects(adapter);
|
|
328
|
+
adapter.log.debug(`[ALEXA3] Starting control detection with ${Object.keys(devicesObject).length} objects...`);
|
|
326
329
|
// fetch all defined rooms and functions (enumerations)
|
|
327
330
|
const [functionalities, rooms] = await functionalitiesAndRooms(adapter);
|
|
331
|
+
adapter.log.debug(`[ALEXA3] Found ${functionalities.length} functionalities and ${rooms.length} rooms...`);
|
|
328
332
|
// every member of a function enumeration is added to the list of ids to inspect
|
|
329
333
|
functionalities.forEach(functionEnumItem => {
|
|
330
334
|
functionEnumItem?.common?.members?.forEach(id => {
|
|
@@ -394,6 +398,7 @@ async function controls(adapter, lang) {
|
|
|
394
398
|
});
|
|
395
399
|
// all ids, i.e. ids of all iobroker states/channels/devices
|
|
396
400
|
const keys = Object.keys(devicesObject).sort();
|
|
401
|
+
adapter.log.debug(`[ALEXA3] collected ${keys.length} states from categories...`);
|
|
397
402
|
const idsWithSmartName = [];
|
|
398
403
|
// if a state has got a smart name directly assigned and neither itself nor its channel is in the list, add its id to the inspection list
|
|
399
404
|
// and process it first
|
|
@@ -407,6 +412,7 @@ async function controls(adapter, lang) {
|
|
|
407
412
|
idsWithSmartName.push(id);
|
|
408
413
|
}
|
|
409
414
|
});
|
|
415
|
+
adapter.log.debug(`[ALEXA3] collected ${keys.length} smart names...`);
|
|
410
416
|
// collect first all smart names and remove them from the auto-groups
|
|
411
417
|
const detectedControls = [];
|
|
412
418
|
const detector = new type_detector_1.default();
|
|
@@ -659,6 +665,7 @@ async function controls(adapter, lang) {
|
|
|
659
665
|
}
|
|
660
666
|
options.ignoreEnums = false;
|
|
661
667
|
options.detectAllPossibleDevices = false;
|
|
668
|
+
adapter.log.debug(`[ALEXA3] collected ${detectedControls.length} controls`);
|
|
662
669
|
// go other the list of IDs to inspect and collect the detected controls
|
|
663
670
|
list.forEach(id => {
|
|
664
671
|
options.id = id;
|
|
@@ -735,6 +742,7 @@ async function controls(adapter, lang) {
|
|
|
735
742
|
}
|
|
736
743
|
});
|
|
737
744
|
});
|
|
745
|
+
adapter.log.debug(`[ALEXA3] sorted ${detectedControls.length} controls`);
|
|
738
746
|
return detectedControls;
|
|
739
747
|
}
|
|
740
748
|
/**
|
|
@@ -752,6 +760,17 @@ function normalize_0_100(value, min, max, noRound) {
|
|
|
752
760
|
}
|
|
753
761
|
return min >= max || value < min || value > max ? undefined : Math.round(((value - min) / (max - min)) * 100);
|
|
754
762
|
}
|
|
763
|
+
/**
|
|
764
|
+
* Normalizes any provided value with observed min and max to the range 0..1
|
|
765
|
+
*
|
|
766
|
+
* @param value value to be normalized
|
|
767
|
+
* @param min min observed (possible) value
|
|
768
|
+
* @param max max observed (possible) value
|
|
769
|
+
* @returns Normalized value in the range 0..100 or undefined on invalid input
|
|
770
|
+
*/
|
|
771
|
+
function normalize_0_1(value, min, max) {
|
|
772
|
+
return min >= max || value < min || value > max ? undefined : (value - min) / (max - min);
|
|
773
|
+
}
|
|
755
774
|
/**
|
|
756
775
|
* Denormalizes any provided value from range 0..100 to the min..max range
|
|
757
776
|
*
|
|
@@ -769,6 +788,21 @@ function denormalize_0_100(normalized, min, max, noRound) {
|
|
|
769
788
|
? undefined
|
|
770
789
|
: Math.round((normalized / 100) * (max - min) + min);
|
|
771
790
|
}
|
|
791
|
+
/**
|
|
792
|
+
* Denormalizes any provided value from range 0..1 to the min..max range
|
|
793
|
+
*
|
|
794
|
+
* @param normalized normalized value
|
|
795
|
+
* @param min min observed (possible) value
|
|
796
|
+
* @param max max observed (possible) value
|
|
797
|
+
* @param noRound do not round the result
|
|
798
|
+
* @returns Denormalized value in the range min-max
|
|
799
|
+
*/
|
|
800
|
+
function denormalize_0_1(normalized, min, max, noRound) {
|
|
801
|
+
if (noRound) {
|
|
802
|
+
return min >= max || normalized < 0 || normalized > 1 ? undefined : normalized * (max - min) + min;
|
|
803
|
+
}
|
|
804
|
+
return min >= max || normalized < 0 || normalized > 1 ? undefined : Math.round(normalized * (max - min) + min);
|
|
805
|
+
}
|
|
772
806
|
/**
|
|
773
807
|
* Returns distinct objects in a list based on values of the provided property name
|
|
774
808
|
*
|