diff --git a/lib/binding.js b/lib/binding.js index d38e9c9b..e956b133 100644 --- a/lib/binding.js +++ b/lib/binding.js @@ -238,7 +238,7 @@ class Binding { await this.doBindUnbind(type, bind_source, bind_source_ep, 'coordinator', '1'); this.debug('Successfully ' + (type === 'bind' ? 'bound' : 'unbound') + ' Coordinator from ' + bind_source); } catch (e) { - this.error(`Could not ${type} Coordinator from ${bind_source}: ${JSON.stringify(e)}`); + this.error(`Could not ${type} Coordinator from ${bind_source}: ${(e && e.message ? e.message : 'no error message')} ${(e && e.stack ? e.stack : 'no call stack')}`); } } } catch (error) { diff --git a/lib/groups.js b/lib/groups.js index 410b2cef..d56cde37 100644 --- a/lib/groups.js +++ b/lib/groups.js @@ -138,7 +138,7 @@ class Groups { for (const gpid of groups[epid]) { const gpidn = parseInt(gpid); if (gpidn < 0) { - this.warn(`calling removeDevFromGroup with ${sysid}, ${-gpidn}, ${epid}` ); + this.debug(`calling removeDevFromGroup with ${sysid}, ${-gpidn}, ${epid}` ); const response = await this.zbController.removeDevFromGroup(sysid, (-gpidn), epid); if (response && response.error) { errors.push(response.error); @@ -146,7 +146,7 @@ class Groups { } } else if (gpidn > 0) { - this.warn(`calling addDevToGroup with ${sysid}, ${gpidn}, ${epid}` ); + this.debug(`calling addDevToGroup with ${sysid}, ${gpidn}, ${epid}` ); const response = await this.zbController.addDevToGroup(sysid, (gpidn), epid); if (response && response.error) { errors.push(response.error); @@ -158,7 +158,7 @@ class Groups { } } } catch (e) { - this.warn('caught error ' + JSON.stringify(e) + ' in updateGroupMembership'); + this.warn('caught error ' + (e && e.message ? e.message : 'no error message') + ' in updateGroupMembership'); this.adapter.sendTo(from, command, {error: e}, callback); return; } diff --git a/lib/zbDeviceAvailability.js b/lib/zbDeviceAvailability.js index 70389589..f9cc3fcf 100644 --- a/lib/zbDeviceAvailability.js +++ b/lib/zbDeviceAvailability.js @@ -181,7 +181,7 @@ class DeviceAvailability extends BaseExtension { } } catch (error) { this.sendError(error); - this.debug(`Exception in readState of '${device.ieeeAddr}' - error : '${error}'`); + this.debug(`Exception in readState of '${device.ieeeAddr}' - error : '${(error && error.message ? error.message : 'no error message')}'`); // intentionally empty: Just present to ensure we cause no harm // when reading the state fails. => fall back on standard Ping function } diff --git a/lib/zigbeecontroller.js b/lib/zigbeecontroller.js index 36e4f09b..0de3be55 100644 --- a/lib/zigbeecontroller.js +++ b/lib/zigbeecontroller.js @@ -322,24 +322,34 @@ class ZigbeeController extends EventEmitter { } async verifyGroupExists(id) { - const nid = typeof id === 'number' ? id : parseInt(id); - let group = await this.herdsman.getGroupByID(nid); - if (!group) { - group = await this.herdsman.createGroup(nid); - group.toZigbee = groupConverters; - group.model = 'group'; - this.debug(`verifyGroupExists: created group ${nid}`); - } else { - this.debug(`verifyGroupExists: group ${nid} exists`); + try { + const nid = typeof id === 'number' ? id : parseInt(id); + let group = await this.herdsman.getGroupByID(nid); + if (!group) { + group = await this.herdsman.createGroup(nid); + group.toZigbee = groupConverters; + group.model = 'group'; + this.debug(`verifyGroupExists: created group ${nid}`); + } else { + this.debug(`verifyGroupExists: group ${nid} exists`); + } + } + catch (error) { + this.error(`verifyGroupExists: ${error && error.message ? error.message : 'unspecified error'}`); } } async addPairingCode(code) { this.debug(`calling addPairingCode with ${code}`); if (code) { - await this.herdsman.addInstallCode(code); - this.info(`added code ${code} for pairing`); - return true; + try { + await this.herdsman.addInstallCode(code); + this.info(`added code ${code} for pairing`); + return true; + } + catch (error) { + this.error(`addPairingCode: ${error && error.message ? error.message : 'unspecified error'}`); + } } return false; } @@ -378,100 +388,125 @@ class ZigbeeController extends EventEmitter { } getDevice(key) { - return this.herdsman.getDeviceByIeeeAddr(key); + try { + return this.herdsman.getDeviceByIeeeAddr(key); + } + catch { + return undefined; + } } getDevicesByType(type) { - return this.herdsman.getDevicesByType(type); + try { + return this.herdsman.getDevicesByType(type); + } + catch { + return undefined; + } } getDeviceByNetworkAddress(networkAddress) { - return this.herdsman.getDeviceByNetworkAddress(networkAddress); + try { + return this.herdsman.getDeviceByNetworkAddress(networkAddress); + } + catch { + return undefined; + } } async resolveEntity(key, ep) { // assert(typeof key === 'string' || key.constructor.name === 'Device', `Wrong type '${typeof key}'`); - - if (typeof key === 'string') { - if (key === 'coordinator') { - const coordinator = this.herdsman.getDevicesByType('Coordinator')[0]; - return { - type: 'device', - device: coordinator, - endpoint: coordinator.getEndpoint(1), - name: 'Coordinator', - }; - } else { - const device = await this.herdsman.getDeviceByIeeeAddr(key); - if (device) { - const mapped = await zigbeeHerdsmanConverters.findByDevice(device); - const endpoints = mapped && mapped.endpoint ? mapped.endpoint(device) : null; - let endpoint; - if (endpoints && ep != undefined && endpoints[ep]) { - endpoint = device.getEndpoint(endpoints[ep]); - } else if (endpoints && endpoints['default']) { - endpoint = device.getEndpoint(endpoints['default']); - } else { - const epNum = parseInt(ep); - if (!isNaN(epNum)) { - endpoint = device.getEndpoint(epNum); - } else { - endpoint = device.endpoints[0]; - } - } + try { + if (typeof key === 'string') { + if (key === 'coordinator') { + const coordinator = this.herdsman.getDevicesByType('Coordinator')[0]; return { type: 'device', - device, - mapped, - endpoint, - endpoints: device.endpoints, - name: key, + device: coordinator, + endpoint: coordinator.getEndpoint(1), + name: 'Coordinator', }; + } else { + const device = await this.herdsman.getDeviceByIeeeAddr(key); + if (device) { + const mapped = await zigbeeHerdsmanConverters.findByDevice(device); + const endpoints = mapped && mapped.endpoint ? mapped.endpoint(device) : null; + let endpoint; + if (endpoints && ep != undefined && endpoints[ep]) { + endpoint = device.getEndpoint(endpoints[ep]); + } else if (endpoints && endpoints['default']) { + endpoint = device.getEndpoint(endpoints['default']); + } else { + const epNum = parseInt(ep); + if (!isNaN(epNum)) { + endpoint = device.getEndpoint(epNum); + } else { + endpoint = device.endpoints[0]; + } + } + return { + type: 'device', + device, + mapped, + endpoint, + endpoints: device.endpoints, + name: key, + }; + } + } + } else if (typeof key === 'number') { + let group = await this.herdsman.getGroupByID(key); + if (!group) group = await this.herdsman.createGroup(key); + group.toZigbee = groupConverters; + group.model = 'group'; + return { + type: 'group', + mapped: group, + group, + name: `Group ${key}`, + }; + } else { + let mapped; + try { + mapped = await zigbeeHerdsmanConverters.findByDevice(key); + } catch (err) { + this.error(`zigbeeHerdsmanConverters findByDevice ${key.ieeeAddr}`); } - } - } else if (typeof key === 'number') { - let group = await this.herdsman.getGroupByID(key); - if (!group) group = await this.herdsman.createGroup(key); - group.toZigbee = groupConverters; - group.model = 'group'; - return { - type: 'group', - mapped: group, - group, - name: `Group ${key}`, - }; - } else { - let mapped; - try { - mapped = await zigbeeHerdsmanConverters.findByDevice(key); - } catch (err) { - this.error(`zigbeeHerdsmanConverters findByDevice ${key.ieeeAddr}`); - } - return { - type: 'device', - device: key, - mapped: mapped, - name: key.type === 'Coordinator' ? 'Coordinator' : key.ieeeAddr, - }; + return { + type: 'device', + device: key, + mapped: mapped, + name: key.type === 'Coordinator' ? 'Coordinator' : key.ieeeAddr, + }; + } + } + catch { + return undefined; } + } async incMsgHandler(message) { - this.debug('incoming msg', message); - const device = await this.herdsman.getDeviceByIeeeAddr(message.srcaddr); - if (!device) { - this.debug('Message without device!'); - return; - } - // We can't handle devices without modelId. - if (!device.modelId) { - this.debug('Message without modelId!'); + try { + this.debug('incoming msg', message); + const device = await this.herdsman.getDeviceByIeeeAddr(message.srcaddr); + if (!device) { + this.debug('Message without device!'); + return; + } + // We can't handle devices without modelId. + if (!device.modelId) { + this.debug('Message without modelId!'); + return; + } + this.event('msg', device.ieeeAddr, message, { + modelId: device.modelId + }); + } + catch { return; } - this.event('msg', device.ieeeAddr, message, { - modelId: device.modelId - }); } // Stop controller @@ -814,39 +849,45 @@ class ZigbeeController extends EventEmitter { if (cfg == null) { cfg = {}; } - - if (type === 'foundation') { - cfg.disableDefaultResponse = true; - - if (cmd === 'read' && !Array.isArray(zclData)) { - /* // needs to be iterable (string[] | number []) - zclData[Symbol.iterator] = function* () { - let k; - for (k in this) { - yield k; - } - }; -*/ - } - let result; - if (cmd === 'configReport') { - result = await endpoint.configureReporting(cid, zclData, cfg); + try { + if (type === 'foundation') { + cfg.disableDefaultResponse = true; + /* + if (cmd === 'read' && !Array.isArray(zclData)) { + // needs to be iterable (string[] | number []) + zclData[Symbol.iterator] = function* () { + let k; + for (k in this) { + yield k; + } + }; + } + */ + let result; + if (cmd === 'configReport') { + result = await endpoint.configureReporting(cid, zclData, cfg); + } else { + if (cmd === 'read' && !Array.isArray(zclData)) + result = await endpoint[cmd](cid, Object.keys(zclData), cfg); + else + result = await endpoint[cmd](cid, zclData, cfg); + } + callback && callback(undefined, result); + } else if (type === 'functionalResp') { + cfg.disableDefaultResponse = false; + const result = await endpoint.commandResponse(cid, cmd, zclData, cfg, zclSeqNum); + callback && callback(undefined, result); } else { - if (cmd === 'read' && !Array.isArray(zclData)) - result = await endpoint[cmd](cid, Object.keys(zclData), cfg); - else - result = await endpoint[cmd](cid, zclData, cfg); + cfg.disableDefaultResponse = false; + const result = await endpoint.command(cid, cmd, zclData, cfg); + callback && callback(undefined, result); } - callback && callback(undefined, result); - } else if (type === 'functionalResp') { - cfg.disableDefaultResponse = false; - const result = await endpoint.commandResponse(cid, cmd, zclData, cfg, zclSeqNum); - callback && callback(undefined, result); - } else { - cfg.disableDefaultResponse = false; - const result = await endpoint.command(cid, cmd, zclData, cfg); - callback && callback(undefined, result); } + catch (error) + { + this.log.error(`error sending ${type} ${cmd} to endpoint: ${(error && error.message ? error.message : 'no error message')} ${(error && error.stack ? error.stack : 'no call stack')}`) + } + } async addDevToGroup(devId, groupId, epid) { @@ -957,16 +998,21 @@ class ZigbeeController extends EventEmitter { target = !target ? this.getCoordinator() : target; this.debug(`Binding ${log}`); - ep.bind(cluster, target, error => { - if (error) { - this.sendError(error); - this.error(`Failed to bind ${log} - (${error})`); - } else { - this.debug(`Successfully bound ${log}`); - } + try { + ep.bind(cluster, target, error => { + if (error) { + this.sendError(error); + this.error(`Failed to bind ${log} - (${error})`); + } else { + this.debug(`Successfully bound ${log}`); + } + callback(error); + }); + } + catch (error) { callback(error); - }); + } } unbind(ep, cluster, target, callback) { @@ -974,15 +1020,21 @@ class ZigbeeController extends EventEmitter { target = !target ? this.getCoordinator() : target; this.debug(`Unbinding ${log}`); - ep.unbind(cluster, target, (error) => { - if (error) { - this.error(`Failed to unbind ${log} - (${error})`); - } else { - this.debug(`Successfully unbound ${log}`); - } + try { + ep.unbind(cluster, target, (error) => { + if (error) { + this.error(`Failed to unbind ${log} - (${error})`); + } else { + this.debug(`Successfully unbound ${log}`); + } + callback(error); + }); + } + catch (error) + { callback(error); - }); + } } reset(mode, callback) {