iobroker.iot 4.2.10 → 4.2.11
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 +2 -1
- package/admin/assets/{index-BlSWVNwK.js → index-B9lVoPrg.js} +3 -3
- package/admin/index_m.html +1 -1
- package/build/lib/AlexaSmartHomeV3/DeviceManager.js +21 -7
- package/build/lib/AlexaSmartHomeV3/DeviceManager.js.map +1 -1
- package/io-package.json +13 -13
- package/package.json +1 -1
package/admin/index_m.html
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
/>
|
|
22
22
|
<script type="text/javascript" onerror="setTimeout(function(){window.location.reload()}, 5000)" src="./lib/js/socket.io.js"></script>
|
|
23
23
|
<title>IoT Settings</title>
|
|
24
|
-
<script type="module" crossorigin src="./assets/index-
|
|
24
|
+
<script type="module" crossorigin src="./assets/index-B9lVoPrg.js"></script>
|
|
25
25
|
<link rel="stylesheet" crossorigin href="./assets/index-Bd3GtHgn.css">
|
|
26
26
|
</head>
|
|
27
27
|
<body>
|
|
@@ -211,8 +211,10 @@ class DeviceManager {
|
|
|
211
211
|
else {
|
|
212
212
|
this.log.debug(`Control of type [${control.type}] assigned to room [${this.getName(control.room.common.name)}] has no function. Skipped.`);
|
|
213
213
|
}
|
|
214
|
+
// delete it from detected controls to avoid endless loop
|
|
215
|
+
detectedControls.splice(0, 1);
|
|
214
216
|
}
|
|
215
|
-
else if (control.groupNames) {
|
|
217
|
+
else if (control.groupNames?.length) {
|
|
216
218
|
// no room, but smart name (not only one)
|
|
217
219
|
control.groupNames.forEach(groupName => {
|
|
218
220
|
if (!createdGroups.includes(groupName)) {
|
|
@@ -231,26 +233,38 @@ class DeviceManager {
|
|
|
231
233
|
}
|
|
232
234
|
usedFriendlyNames.push(friendlyName);
|
|
233
235
|
this.toDevice({
|
|
234
|
-
detectedControls: processedControls,
|
|
236
|
+
detectedControls: JSON.parse(JSON.stringify(processedControls)),
|
|
235
237
|
friendlyName,
|
|
236
238
|
autoDetected: false,
|
|
237
239
|
toggle: processedControls[0].object?.toggle ?? defaultToggle,
|
|
238
240
|
possibleTypes: processedControls[0].object?.possibleTypes || [],
|
|
239
241
|
typeWasDetected: processedControls[0].object?.typeWasDetected || false,
|
|
240
242
|
});
|
|
243
|
+
// Remove groupName from all controls to avoid processing it again
|
|
244
|
+
for (let c = detectedControls.length - 1; c >= 0; c--) {
|
|
245
|
+
const pos = detectedControls[c].groupNames?.indexOf(groupName);
|
|
246
|
+
if (pos !== -1) {
|
|
247
|
+
detectedControls[c].groupNames.splice(pos, 1);
|
|
248
|
+
if (!detectedControls[c].groupNames.length) {
|
|
249
|
+
detectedControls.splice(c, 1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
241
253
|
}
|
|
242
254
|
});
|
|
243
255
|
}
|
|
244
256
|
else {
|
|
257
|
+
// delete it from detected controls to avoid endless loop
|
|
258
|
+
detectedControls.splice(0, 1);
|
|
245
259
|
// neither room nor smart name
|
|
246
260
|
this.log.debug(`Control of type [${control.type}] has neither room no smart name. Skipped.`);
|
|
247
261
|
}
|
|
248
|
-
if (!processedControls.length) {
|
|
249
|
-
|
|
250
|
-
}
|
|
262
|
+
// if (!processedControls.length) {
|
|
263
|
+
// processedControls = [control];
|
|
264
|
+
// }
|
|
251
265
|
// remove processed controls
|
|
252
|
-
const objectIds = processedControls.map(item => item.object?.id);
|
|
253
|
-
detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));
|
|
266
|
+
// const objectIds = processedControls.map(item => item.object?.id);
|
|
267
|
+
// detectedControls = detectedControls.filter(item => item.object && !objectIds.includes(item.object.id));
|
|
254
268
|
}
|
|
255
269
|
// done
|
|
256
270
|
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 let 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 } else if (control.groupNames) {\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: 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 });\n } else {\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 let 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 const pos = detectedControls[c].groupNames?.indexOf(groupName);\n if (pos !== -1) {\n detectedControls[c].groupNames.splice(pos, 1);\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"]}
|
package/io-package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "iot",
|
|
4
|
-
"version": "4.2.
|
|
4
|
+
"version": "4.2.11",
|
|
5
5
|
"news": {
|
|
6
|
-
"4.2.
|
|
7
|
-
"en": "Added mireds<->kelvin conversion for color temperature\nIt is possible to edit a type",
|
|
8
|
-
"de": "Hinzugefügt mireds<->kelvin Umwandlung für Farbtemperatur\nEs ist möglich, einen Typ zu bearbeiten",
|
|
9
|
-
"ru": "Добавлено погрязшее преобразование <-> кельвина для цветовой температуры\nМожно редактировать
|
|
10
|
-
"pt": "Adicionado mireds<-> conversão de kelvin para temperatura de cor\nÉ possível editar um tipo",
|
|
11
|
-
"nl": "Toegevoegd mireds<->kelvin conversie voor kleurtemperatuur\nHet is mogelijk om een type te bewerken",
|
|
12
|
-
"fr": "Ajout de mireds <->kelvin conversion pour la température de couleur\nIl est possible de modifier un type",
|
|
13
|
-
"it": "Conversione di mireds su >kelvin aggiunto per temperatura di colore\nÈ possibile modificare un tipo",
|
|
14
|
-
"es": "Conversión agregada de microsiervos para la temperatura de color\nEs posible editar un tipo",
|
|
15
|
-
"pl": "Dodano miredy < - > konwersja kelwina dla temperatury barwy\nMożna edytować typ",
|
|
16
|
-
"uk": "Додано міреди <->kelvin перетворення для температури кольору\nМожна редагувати
|
|
17
|
-
"zh-cn": "添加嵌入点 <->kelvin 转换颜色温度\n
|
|
6
|
+
"4.2.11": {
|
|
7
|
+
"en": "Added mireds<->kelvin conversion for color temperature\nIt is possible to edit a type\nCorrecting creation of complex groups",
|
|
8
|
+
"de": "Hinzugefügt mireds<->kelvin Umwandlung für Farbtemperatur\nEs ist möglich, einen Typ zu bearbeiten\nKorrektur der Erstellung komplexer Gruppen",
|
|
9
|
+
"ru": "Добавлено погрязшее преобразование <-> кельвина для цветовой температуры\nМожно редактировать тип\nКоррекция создания сложных групп",
|
|
10
|
+
"pt": "Adicionado mireds<-> conversão de kelvin para temperatura de cor\nÉ possível editar um tipo\nCorrigindo a criação de grupos complexos",
|
|
11
|
+
"nl": "Toegevoegd mireds<->kelvin conversie voor kleurtemperatuur\nHet is mogelijk om een type te bewerken\nCorrigerende oprichting van complexe groepen",
|
|
12
|
+
"fr": "Ajout de mireds <->kelvin conversion pour la température de couleur\nIl est possible de modifier un type\nCorrection de la création de groupes complexes",
|
|
13
|
+
"it": "Conversione di mireds su >kelvin aggiunto per temperatura di colore\nÈ possibile modificare un tipo\nCorreggere la creazione di gruppi complessi",
|
|
14
|
+
"es": "Conversión agregada de microsiervos para la temperatura de color\nEs posible editar un tipo\nCreación correcta de grupos complejos",
|
|
15
|
+
"pl": "Dodano miredy < - > konwersja kelwina dla temperatury barwy\nMożna edytować typ\nKorekcja tworzenia grup złożonych",
|
|
16
|
+
"uk": "Додано міреди <->kelvin перетворення для температури кольору\nМожна редагувати тип\nПравильне створення складних груп",
|
|
17
|
+
"zh-cn": "添加嵌入点 <->kelvin 转换颜色温度\n可以编辑一个类型\n纠正复杂集团的产生"
|
|
18
18
|
},
|
|
19
19
|
"4.2.9": {
|
|
20
20
|
"en": "Do not control \"white\" by RGBW devices\nCorrected GUI error\nAvoid double entries in auto-detection",
|