iobroker.sonoff 4.2.0 → 4.2.1

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.
@@ -214,9 +214,30 @@ class MQTTBase {
214
214
  this.processTasks().catch(err => this.adapter.log.error(err));
215
215
  }
216
216
  }
217
+ /**
218
+ * Finds the device channel (the `iobId` of its client) a state belongs to. That is not simply the
219
+ * first segment after "<namespace>.": the state can be nested (e.g. "STATE.POWER1" with "Create
220
+ * object tree" on), and a client ID may contain dots itself, as `FORBIDDEN_CHARS` keeps them. So
221
+ * the longest leading path that belongs to a known client wins - the first segment is only the
222
+ * fallback for a client that is not connected.
223
+ *
224
+ * @param id full state ID, e.g. "sonoff.0.DVES_123456.STATE.POWER1"
225
+ */
226
+ getChannelId(id) {
227
+ const parts = id.substring(this.adapter.namespace.length + 1).split('.');
228
+ // The last segment is the data point itself, never part of the channel
229
+ for (let i = parts.length - 1; i > 1; i--) {
230
+ const channelId = parts.slice(0, i).join('.');
231
+ if (this.mappingClients[channelId]) {
232
+ return channelId;
233
+ }
234
+ }
235
+ return parts[0];
236
+ }
217
237
  async onStateChangedColors(id, state, channelId, stateId) {
218
238
  if (!channelId) {
219
239
  const parts = id.split('.');
240
+ channelId = this.getChannelId(id);
220
241
  stateId = parts.pop() || '';
221
242
  if (stateId === 'level' ||
222
243
  stateId === 'state' ||
@@ -225,7 +246,6 @@ class MQTTBase {
225
246
  stateId === 'green') {
226
247
  stateId = `${parts.pop()}.${stateId}`;
227
248
  }
228
- channelId = parts.splice(2, parts.length).join('.');
229
249
  }
230
250
  const ledModeIdExor = `${this.adapter.namespace}.${channelId}.modeLedExor`;
231
251
  if (this.cachedModeExor[ledModeIdExor] === undefined) {
@@ -555,9 +575,8 @@ class MQTTBase {
555
575
  this.adapter.log.debug(`onStateChange ${id}: ${JSON.stringify(state)}`);
556
576
  if (state && !state.ack) {
557
577
  // find client.id
558
- const parts = id.split('.');
559
- const stateId = parts.pop() || '';
560
- const channelId = parts.splice(2, parts.length).join('.');
578
+ const channelId = this.getChannelId(id);
579
+ const stateId = id.split('.').pop() || '';
561
580
  // Check if this is a Zigbee device state change
562
581
  // Pattern: ZbReceived_DEVICEID_ATTRIBUTE (e.g., ZbReceived_0x0856_Power)
563
582
  const zbMatch = stateId.match(/^ZbReceived_([^_]+)_(Power|Dimmer)$/);