Skip to content

Commit

Permalink
Merge pull request #2331 from asgothian/master
Browse files Browse the repository at this point in the history
Fix for Lumi Lamp
  • Loading branch information
asgothian authored Dec 29, 2024
2 parents 2eb3aab + 95c2e5a commit d4a0d95
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 37 deletions.
45 changes: 24 additions & 21 deletions lib/statescontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const fs = require('fs');
const axios = require('axios');

let savedDeviceNamesDB = {};
const knownUndefinedDevices = {};


class StatesController extends EventEmitter {
constructor(adapter) {
Expand Down Expand Up @@ -75,7 +75,6 @@ class StatesController extends EventEmitter {
}
});

this.adapter.setStateAsync(`info.undefinedDevices`, JSON.stringify(knownUndefinedDevices), true);
}

checkDebugDevice(dev) {
Expand All @@ -95,9 +94,6 @@ class StatesController extends EventEmitter {
if (!this.adapter.zbController || !this.adapter.zbController.connected()) {
return;
}
if (this.debugDevices === undefined) {
this.getDebugDevices();
}
if (state && !state.ack) {
if (id.endsWith('pairingCountdown') || id.endsWith('pairingMessage') || id.endsWith('connection')) {
return;
Expand All @@ -112,7 +108,8 @@ class StatesController extends EventEmitter {
return;
}

if (this.checkDebugDevice(id)) this.warn(`ELEVATED: User stateChange ${id} ${JSON.stringify(state)}`);
if (this.checkDebugDevice(id))
this.warn(`ELEVATED O1: User state change of state ${id} with value ${state.val} (ack: ${state.ack}) from ${state.from}`);

this.debug(`User stateChange ${id} ${JSON.stringify(state)}`);
const devId = getAdId(this.adapter, id); // iobroker device id
Expand Down Expand Up @@ -191,13 +188,7 @@ class StatesController extends EventEmitter {
} else {
stateModel = statesMapping.findModel(model);
if (!stateModel) {
if (knownUndefinedDevices[deviceId]) {
knownUndefinedDevices[deviceId]++;
} else {
knownUndefinedDevices[deviceId] = 1;
this.info(`Device ${deviceId} "${model}" not present in statesMapping - relying on exposes for device definition.`);
}
this.adapter.setStateAsync(`info.undefinedDevices`, JSON.stringify(knownUndefinedDevices), true);
this.info(`Device ${deviceId} "${model}" not present in statesMapping - relying on exposes for device definition.`);
states = statesMapping.commonStates;
} else {
states = stateModel.states;
Expand All @@ -217,15 +208,14 @@ class StatesController extends EventEmitter {
}

async publishFromState(deviceId, model, stateKey, state, options) {
if (this.debugDevices === undefined) this.getDebugDevices();
this.debug(`Change state '${stateKey}' at device ${deviceId} type '${model}'`);
const elevated = this.checkDebugDevice(deviceId);

if (elevated) this.warn(`ELEVATED Change state '${stateKey}' at device ${deviceId} type '${model}'`);
if (elevated) this.warn(`ELEVATED O2: Change state '${stateKey}' at device ${deviceId} type '${model}'`);

const devStates = await this.getDevStates(deviceId, model);
if (!devStates) {
if (elevated) this.error(`ELEVATED no device states for device ${deviceId} type '${model}'`);
if (elevated) this.error(`ELEVATED OE1: no device states for device ${deviceId} type '${model}'`);
return;
}
const commonStates = statesMapping.commonStates.find(statedesc => stateKey === statedesc.id);
Expand All @@ -238,7 +228,8 @@ class StatesController extends EventEmitter {

const value = state.val;
if (value === undefined || value === '') {
if (elevated) this.error(`ELEVATED no value for device ${deviceId} type '${model}'`);
if (elevated)
this.error(`ELEVATED OE2: no value for device ${deviceId} type '${model}'`);
return;
}
let stateList = [{stateDesc: stateDesc, value: value, index: 0, timeout: 0}];
Expand Down Expand Up @@ -608,19 +599,20 @@ class StatesController extends EventEmitter {
async publishToState(devId, model, payload) {
const devStates = await this.getDevStates(`0x${devId}`, model);
let has_debug = false;
if (this.debugDevices === undefined) this.getDebugDevices();
if (this.checkDebugDevice(devId))
{
if (!payload.hasOwnProperty('msg_from_zigbee')) {
this.warn(`ELEVATED publishToState: message received '${JSON.stringify(payload)}' from device ${devId} type '${model}'`);
this.warn(`ELEVATED I1: message received '${JSON.stringify(payload)}' from device ${devId} type '${model}'`);
has_debug = true;
}
}
if (!devStates) {
if (has_debug) this.error(`ELEVATED publishToState: no device states for device ${devId} type '${model}'`)
if (has_debug) this.error(`ELEVATED IE2: no device states for device ${devId} type '${model}'`)
return;
}
// find states for payload
let has_published = false;

if (devStates.states !== undefined) {
try {
const states = statesMapping.commonStates.concat(
Expand All @@ -643,7 +635,7 @@ class StatesController extends EventEmitter {
let stateID = statedesc.id;

if (has_debug && statedesc.id !== 'msg_from_zigbee') {
this.warn(`ELEVATED publishToState: value generated '${JSON.stringify(value)}' from device ${devId} for '${statedesc.name}'`);
this.warn(`ELEVATED I2: value generated '${JSON.stringify(value)}' from device ${devId} for '${statedesc.name}'`);
}

const common = {
Expand Down Expand Up @@ -681,10 +673,21 @@ class StatesController extends EventEmitter {
this.updateState(devId, stateID, value, common);
}
}
has_published = true;
}
} catch (e) {
this.debug(`No states in device ${devId} : payload ${JSON.stringify(payload)}`);
if (has_debug)
this.error(`ELEVATED IE3: error when enumerating states of ${devId} for payload ${JSON.stringify(payload)}, ${(e ? e.name : 'undefined')} (${(e ? e.message : '')}).`);
}
if (!has_published && has_debug) {
this.error(`ELEVATED IE4: No value published for device ${devId}`);

}
}
else {
if (has_debug)
this.error(`ELEVATED IE5: No states matching the payload ${JSON.stringify(payload)} for device ${devId}`);
}
}
}
Expand Down
33 changes: 17 additions & 16 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,17 @@ class Zigbee extends utils.Adapter {
const devId = device.ieeeAddr.substr(2);
const meta = {device};

if (this.stController.checkDebugDevice(devId)) {
const has_elevated_debug = this.stController.checkDebugDevice(devId);

if (has_elevated_debug) {
const shortMessage = {};
for(const propertyName in message) {
shortMessage[propertyName] = message[propertyName];
}
shortMessage.device = device.ieeeAddr;
shortMessage.meta = undefined;
shortMessage.endpoint = (message.endpoint.ID ? message.endpoint.ID: -1);
this.log.warn(`ELEVATED: Zigbee Event of Type ${type} from device ${safeJsonStringify(device.ieeeAddr)}, incoming event: ${safeJsonStringify(shortMessage)}`);
this.log.warn(`ELEVATED I0: Zigbee Event of Type ${type} from device ${safeJsonStringify(device.ieeeAddr)}, incoming event: ${safeJsonStringify(shortMessage)}`);
}
// this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
meta.logger = this.log;
Expand Down Expand Up @@ -558,6 +560,8 @@ class Zigbee extends utils.Adapter {
if (!converters.length) {
if (type !== 'readResponse') {
this.log.debug(`No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`);
if (has_elevated_debug)
this.log.warn(`ELEVATED IE0: No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`);
}
return;
}
Expand Down Expand Up @@ -639,7 +643,7 @@ class Zigbee extends utils.Adapter {

if (!mappedModel) {
this.log.debug(`No mapped model for ${model}`);
if (has_elevated_debug) this.log.warn(`ELEVATED: No mapped model for ${model}`)
if (has_elevated_debug) this.log.warn(`ELEVATED O2: No mapped model for ${model}`)
return;
}

Expand Down Expand Up @@ -721,20 +725,20 @@ class Zigbee extends utils.Adapter {
{
converter = c;

if (has_elevated_debug) this.log.warn(`ELEVATED: setting converter to keyless converter for ${deviceId} of type ${model}`)
if (has_elevated_debug) this.log.warn(`ELEVATED O3A: Setting converter to keyless converter for ${deviceId} of type ${model}`)
this.log.debug('setting converter to keyless converter')
}
else
{
if (has_elevated_debug) this.log.warn(`ELEVATED: ignoring keyless converter for ${deviceId} of type ${model}`)
if (has_elevated_debug) this.log.warn(`ELEVATED O3B: ignoring keyless converter for ${deviceId} of type ${model}`)
this.log.debug('ignoring keyless converter')
}
continue;
}
if (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id))
{
this.log.debug(`${(converter===undefined?'Setting':'Overriding')}' converter to converter with key(s)'${JSON.stringify(c.key)}}`)
if (has_elevated_debug) this.log.warn(`ELEVATED: ${(converter===undefined?'Setting':'Overriding')}' converter to converter with key(s)'${JSON.stringify(c.key)}}`)
if (has_elevated_debug) this.log.warn(`ELEVATED O3C: ${(converter===undefined?'Setting':'Overriding')}' converter to converter with key(s)'${JSON.stringify(c.key)}}`)
converter = c;
}

Expand Down Expand Up @@ -763,9 +767,9 @@ class Zigbee extends utils.Adapter {
}

const epName = stateDesc.epname !== undefined ? stateDesc.epname : (stateDesc.prop || stateDesc.id);
const key = stateDesc.prop || stateDesc.id || stateDesc.setattr;
const key = stateDesc.setattr || stateDesc.prop || stateDesc.id;
this.log.debug(`convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)}`);
if (has_elevated_debug) this.log.warn(`ELEVATED: convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)} for device ${deviceId}`);
if (has_elevated_debug) this.log.warn(`ELEVATED O4: convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)} for device ${deviceId} with Endpoint ${epName}`);

let target;
if (model === 'group') {
Expand Down Expand Up @@ -805,24 +809,21 @@ class Zigbee extends utils.Adapter {
try {
const result = await converter.convertSet(target, key, preparedValue, meta);
this.log.debug(`convert result ${safeJsonStringify(result)}`);
if (has_elevated_debug) this.log.warn(`ELEVATED: convert result ${safeJsonStringify(result)} for device ${deviceId}`);
if (has_elevated_debug) this.log.warn(`ELEVATED O5: convert result ${safeJsonStringify(result)} for device ${deviceId}`);
if (result !== undefined) {
if (stateModel && !isGroup) {
this.acknowledgeState(deviceId, model, stateDesc, value);
}
// process sync state list
this.processSyncStatesList(deviceId, model, syncStateList);

// if (isGroup) {
// await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
// this.acknowledgeState(deviceId, model, stateDesc, value);
// }
}
else
if (has_elevated_debug) this.log.warn(`Error convert result for ${key} with ${safeJsonStringify(preparedValue)} is undefined on device ${deviceId}.`);
if (has_elevated_debug)
this.log.error(`ELEVATED OE2: Error convert result for ${key} with ${safeJsonStringify(preparedValue)} is undefined on device ${deviceId}.`);

} catch (error) {
if (has_elevated_debug) this.log.warn(`caught error ${safeJsonStringify(error)} is undefined on device ${deviceId}.`);
if (has_elevated_debug)
this.log.error(`ELEVATED OE3: caught error ${safeJsonStringify(error)} when setting value for device ${deviceId}.`);
this.filterError(`Error ${error.code} on send command to ${deviceId}.` +
` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
}
Expand Down

0 comments on commit d4a0d95

Please sign in to comment.