Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Lumi Lamp #2331

Merged
merged 2 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 axios = require('axios');

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


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

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

checkDebugDevice(dev) {
Expand All @@ -95,9 +94,6 @@
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 @@
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 @@
} 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 @@
}

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 @@

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 @@
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}'`)

Check notice

Code scanning / CodeQL

Semicolon insertion Note

Avoid automated semicolon insertion (96% of all statements in
the enclosing function
have an explicit semicolon).
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 @@
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 @@
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
Loading