diff --git a/README.md b/README.md index 00a772c..627d292 100755 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ States: ### **WORK IN PROGRESS** --> ## Changelog -### 3.0.2 (2023-08-13) +### **WORK IN PROGRESS** * (bluefox/Bettman66) Added migration of password on JSON Config ### 2.5.7 (2023-07-07) diff --git a/io-package.json b/io-package.json index 9f83e80..34f5a1b 100755 --- a/io-package.json +++ b/io-package.json @@ -3,19 +3,6 @@ "name": "sonoff", "version": "3.0.2", "news": { - "3.0.2": { - "en": "Added migration of password on JSON Config", - "de": "Migration von Passwort auf JSON Config hinzugefügt", - "ru": "Добавлена миграция пароля на JSON Config", - "pt": "Adicionado migração de senha em JSON Config", - "nl": "Vermelding van wachtwoord op JSON Config", - "fr": "Ajout de la migration de mot de passe sur JSON Config", - "it": "Aggiunta migrazione di password su JSON Config", - "es": "Migración agregada de contraseña en JSON Config", - "pl": "Dostęp do migracji haseł JSON Config", - "uk": "Додано міграції пароля на JSON Config", - "zh-cn": "A. 增加联索行动密码的移徙" - }, "2.5.7": { "en": "Disabled the logging of username and password during connection errors\nadded json config", "de": "Deaktiviert die Protokollierung von Benutzername und Passwort während der Verbindungsfehler\nadd json config", @@ -163,7 +150,7 @@ "port": 1883, "bind": "0.0.0.0", "user": "", - "pass": "", + "password": "", "timeout": 300, "TELE_SENSOR": true, "TELE_STATE": false, diff --git a/lib/server.js b/lib/server.js index 4441213..973b442 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1731,9 +1731,8 @@ function MQTTServer(adapter) { }); }); - server.on('error', err => { - adapter.log.error(`Can not start Server ${err}`); - }); + server.on('error', err => + adapter.log.error(`Can not start Server ${err}`)); config.port = parseInt(config.port, 10) || 1883; diff --git a/test/lib/mqttClient.js b/test/lib/mqttClient.js index f5ab68d..8edd737 100644 --- a/test/lib/mqttClient.js +++ b/test/lib/mqttClient.js @@ -14,13 +14,13 @@ function Client(cbConnected, cbChanged, config) { /*that.client.publish('mqtt/0/test', 'Roger1'); client.publish('test/out/testMessage1', 'Roger1'); client.publish('test/out/testMessage2', 'Roger2'); - client.publish('test/in/testMessage3', 'Roger3'); + client.publish('test/in/testMessage3', 'Roger3'); client.publish('test/in/testMessage4', 'Roger4');*/ - /*client.publish('arduino/kitchen/out/temperature', '10.1'); + /*client.publish('arduino/kitchen/out/temperature', '10.1'); client.publish('arduino/kitchen/out/humidity', '56'); // Current light state - client.publish('arduino/kitchen/in/lightActor', 'false'); + client.publish('arduino/kitchen/in/lightActor', 'false'); client.subscribe('arduino/kitchen/in/#');*/ //client.subscribe('arduino/kitchen/in/updateInterval'); @@ -37,7 +37,7 @@ function Client(cbConnected, cbChanged, config) { } }); this.client.on('close', err => { - if (err) console.error('Connection closed: ' + err); + if (err) console.error(`Connection closed: ${err}`); // message is Buffer if (cbConnected) { cbConnected(false); @@ -47,7 +47,7 @@ function Client(cbConnected, cbChanged, config) { }); this.client.on('error', error => { - console.error('Test MQTT Client error: ' + error); + console.error(`Test MQTT Client error: ${error}`); }); this.publish = (topic, message, qos, retain, cb) => { diff --git a/test/lib/objects.js b/test/lib/objects.js deleted file mode 100644 index fd33e15..0000000 --- a/test/lib/objects.js +++ /dev/null @@ -1,1477 +0,0 @@ -'use strict'; -const path = require('path'); -const rootDir = path.normalize(`${__dirname}/../../`); -let adapterName = path.normalize(rootDir).replace(/\\/g, '/').split('/'); -adapterName = adapterName[adapterName.length - 2]; - -const logger = { - info: function (msg) { - console.log(msg); - }, - debug: function (msg) { - console.log(msg); - }, - warn: function (msg) { - console.warn(msg); - }, - error: function (msg) { - console.error(msg); - } -}; - -function Objects(cb) { - if (!(this instanceof Objects)) return new Objects(cb); - - const _Objects = require(`${rootDir}tmp/node_modules/iobroker.js-controller/lib/objects`); - this.connected = false; - const that = this; - - that.namespace = 'test'; - - this.objects = new _Objects({ - connection: { - type: 'file', - host: '127.0.0.1', - port: 19001, - user: '', - pass: '', - noFileCache: false, - connectTimeout: 2000 - }, - logger: logger, - connected: () => { - this.connected = true; - if (typeof cb === 'function') cb(); - }, - disconnected: () => { - this.connected = false; - }, - change: (id, obj) => { - if (!id) { - logger.error(`${that.namespace} change ID is empty: ${JSON.stringify(obj)}`); - return; - } - - if (id.slice(that.namespace.length) === that.namespace) { - if (typeof options.objectChange === 'function') { - options.objectChange(id.slice(that.namespace.length + 1), obj); - } - - // emit 'objectChange' event instantly - setImmediate(() => that.emit('objectChange', id.slice(that.namespace.length + 1), obj)); - } else { - if (typeof options.objectChange === 'function') { - options.objectChange(id, obj); - } - - // emit 'objectChange' event instantly - setImmediate(() => that.emit('objectChange', id, obj)); - } - }, - connectTimeout: error => { - if (logger) logger.error(`${that.namespace} no connection to objects DB`); - if (typeof cb === 'function') { - cb('Connect timeout'); - } - } - }); - - that._namespaceRegExp = new RegExp(`^${that.namespace}`); // cache the regex object 'adapter.0' - - that._fixId = function _fixId(id) { - let result = ''; - // If id is an object - if (typeof id === 'object') { - // Add namespace + device + channel - result = `${that.namespace}.${id.device ? `${id.device}.` : ''}${id.channel ? `${id.channel}.` : ''}${id.state}`; - } else { - result = id; - if (!that._namespaceRegExp.test(id)) { - result = `${that.namespace}.${id}`; - } - } - return result; - }; - - that.setObject = function setObject(id, obj, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - - if (!id) { - logger.error(`${that.namespace} setObject id missing!!`); - return; - } - - if (!obj) { - logger.error(`${that.namespace} setObject ${id} object missing!`); - return; - } - - if (obj.hasOwnProperty('type')) { - if (!obj.hasOwnProperty('native')) { - logger.warn(`${that.namespace} setObject ${id} (type=${obj.type}) property native missing!`); - obj.native = {}; - } - // Check property 'common' - if (!obj.hasOwnProperty('common')) { - logger.warn(`${that.namespace} setObject ${id} (type=${obj.type}) property common missing!`); - obj.common = {}; - } else if (obj.type === 'state') { - // Try to extend the model for type='state' - // Check property 'role' by 'state' - if (obj.common.hasOwnProperty('role') && defaultObjs[obj.common.role]) { - obj.common = extend(true, defaultObjs[obj.common.role], obj.common); - } else if (!obj.common.hasOwnProperty('role')) { - logger.warn(`${that.namespace} setObject ${id} (type=${obj.type}) property common.role missing!`); - } - if (!obj.common.hasOwnProperty('type')) { - logger.warn(`${that.namespace} setObject ${id} (type=${obj.type}) property common.type missing!`); - } - } - - if (!obj.common.hasOwnProperty('name')) { - obj.common.name = id; - logger.debug(`${that.namespace} setObject ${id} (type=${obj.type}) property common.name missing, using id as name`); - } - - id = that._fixId(id, obj.type); - - if (obj.children || obj.parent) { - logger.warn(`Do not use parent or children for ${id}`); - } - that.objects.setObject(id, obj, options, callback); - - } else { - logger.error(`${that.namespace} setObject ${id} mandatory property type missing!`); - } - }; - - that.extendObject = function extendObject(id, obj, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - id = that._fixId(id, obj.type); - - if (obj.children || obj.parent) { - logger.warn(`Do not use parent or children for ${id}`); - } - // delete arrays if they should be changed - if (obj && ( - (obj.common && obj.common.members) || - (obj.native && obj.native.repositories) || - (obj.native && obj.native.certificates) || - (obj.native && obj.native.devices)) - ) { - // Read whole object - that.objects.getObject(id, options, (err, oldObj) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - if (!oldObj) { - logger.error(`Object ${id} not exist!`); - oldObj = {}; - } - if (obj.native && obj.native.repositories && oldObj.native && oldObj.native.repositories) { - oldObj.native.repositories = []; - } - if (obj.common && obj.common.members && oldObj.common && oldObj.common.members) { - oldObj.common.members = []; - } - if (obj.native && obj.native.certificates && oldObj.native && oldObj.native.certificates) { - oldObj.native.certificates = []; - } - if (obj.native && obj.native.devices && oldObj.native && oldObj.native.devices) { - oldObj.native.devices = []; - } - obj = extend(true, oldObj, obj); - - that.objects.setObject(id, obj, options, callback); - }); - } else { - that.objects.extendObject(id, obj, options, callback); - } - }; - - that.setForeignObject = function setForeignObject(id, obj, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.setObject(id, obj, options, callback); - }; - - that.extendForeignObject = function extendForeignObject(id, obj, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - // delete arrays if they should be changed - if (obj && ((obj.native && (obj.native.repositories || obj.native.certificates || obj.native.devices)) || - (obj.common && obj.common.members))) { - // Read whole object - that.objects.getObject(id, options, (err, oldObj) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - if (!oldObj) { - logger.error(`Object ${id} not exist!`); - oldObj = {}; - } - if (obj.native && obj.native.repositories && oldObj.native && oldObj.native.repositories) { - oldObj.native.repositories = []; - } - if (obj.common && obj.common.members && oldObj.common && oldObj.common.members) { - oldObj.common.members = []; - } - if (obj.native && obj.native.certificates && oldObj.native && oldObj.native.certificates) { - oldObj.native.certificates = []; - } - if (obj.native && obj.native.devices && oldObj.native && oldObj.native.devices) { - oldObj.native.devices = []; - } - obj = extend(true, oldObj, obj); - - that.objects.setObject(id, obj, callback); - }); - } else { - that.objects.extendObject(id, obj, options, callback); - } - }; - - that.getObject = function getObject(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.getObject(that._fixId(id), options, callback); - }; - - // Get the enum tree - that.getEnum = function getEnum(_enum, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (!_enum.match('^enum.')) { - _enum = `enum.${_enum}`; - } - const result = {}; - - that.objects.getObjectView('system', 'enum', {startkey: `${_enum}.`, endkey: `${_enum}.\u9999`}, options, (err, res) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - // Read all - let count = 0; - - for (let t = 0; t < res.rows.length; t++) { - count++; - that.objects.getObject(res.rows[t].id, options, (err, _obj) => { - if (err) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - - if (!err && _obj) result[_obj._id] = _obj; - if (!--count && callback) callback (err, result, _enum); - }); - } - if (!count && callback) callback(err, result); - }); - }; - - // read for given enums the members of them - that.getEnums = function getEnums(_enumList, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - const _enums = {}; - if (_enumList) { - if (typeof _enumList === 'string') _enumList = [_enumList]; - let count = 0; - for (let t = 0; t < _enumList.length; t++) { - count++; - that.getEnum(_enumList[t], options, (list, _enum) => { - _enums[_enum] = list; - if (!--count && callback) callback(_enums); - }); - } - } else { - // Read all enums - that.objects.getObjectView('system', 'enum', {startkey: 'enum.', endkey: 'enum.\u9999'}, options, (err, res) => { - if (err) { - callback(err); - return; - } - const result = {}; - for (let i = 0; i < res.rows.length; i++) { - const parts = res.rows[i].id.split('.', 3); - if (!parts[2]) { - continue; - } - if (!result[`${parts[0]}.${parts[1]}`]) { - result[`${parts[0]}.${parts[1]}`] = {}; - } - result[`${parts[0]}.${parts[1]}`][res.rows[i].id] = res.rows[i].value; - } - - if (callback) callback(err, result); - }); - } - }; - - that.getForeignObjects = function getForeignObjects(pattern, type, enums, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - let params = {}; - if (pattern && pattern !== '*') { - params = { - startkey: pattern.replace('*', ''), - endkey: pattern.replace('*', '\u9999') - }; - } - if (typeof enums === 'function') { - callback = enums; - enums = null; - } - if (typeof type === 'function') { - callback = type; - type = null; - } - that.objects.getObjectView('system', type || 'state', params, options, (err, res) => { - if (err) { - callback(err); - return; - } - - that.getEnums(enums, (_enums) => { - const list = {}; - for (let i = 0; i < res.rows.length; i++) { - list[res.rows[i].id] = res.rows[i].value; - - if (_enums) { - // get device or channel of this state and check it too - const parts = res.rows[i].id.split('.'); - parts.splice(parts.length - 1, 1); - const channel = parts.join('.'); - parts.splice(parts.length - 1, 1); - const device = parts.join('.'); - - list[res.rows[i].id].enums = {}; - for (const es in _enums) { - if (!_enums.hasOwnProperty(es)) continue; - for (const e in _enums[es]) { - if (!_enums[es].hasOwnProperty(e)) continue; - if (!_enums[es][e] || !_enums[es][e].common || !_enums[es][e].common.members) continue; - if (_enums[es][e].common.members.indexOf(res.rows[i].id) !== -1 || - _enums[es][e].common.members.indexOf(channel) !== -1 || - _enums[es][e].common.members.indexOf(device) !== -1) { - list[res.rows[i].id].enums[e] = _enums[es][e].common.name; - } - } - } - } - } - callback(null, list); - }); - }); - - }; - - that.findForeignObject = function findForeignObject(id, type, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.findObject(id, type, options, callback); - }; - - that.getForeignObject = function getForeignObject(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.getObject(id, options, callback); - }; - - that.delObject = function delObject(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - id = that._fixId(id); - that.objects.delObject(id, options, callback); - }; - - that.delForeignObject = function delForeignObject(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.delObject(id, options, callback); - }; - - that.subscribeObjects = function subscribeObjects(pattern, options) { - if (pattern === '*') { - that.objects.subscribe(that.namespace + '.*'); - } else { - pattern = that._fixId(pattern); - that.objects.subscribe(pattern, options); - } - }; - - that.subscribeForeignObjects = function subscribeObjects(pattern, options) { - that.objects.subscribe(pattern, options); - }; - - that.unsubscribeForeignObjects = function unsubscribeForeignObjects(pattern, options) { - if (!pattern) pattern = '*'; - that.objects.unsubscribe(pattern, options); - }; - - that.unsubscribeObjects = function unsubscribeObjects(pattern, options) { - if (pattern === '*') { - that.objects.unsubscribe(`${that.namespace}.*`, options); - } else { - pattern = that._fixId(pattern); - that.objects.unsubscribe(pattern); - } - }; - - that.setObjectNotExists = function setObjectNotExists(id, object, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - id = that._fixId(id); - - if (object.children || object.parent) { - logger.warn('Do not use parent or children for ' + id); - } - - that.objects.getObject(id, options, (err, obj) => { - if (!obj) { - that.objects.setObject(id, object, callback); - } - }); - }; - - that.setForeignObjectNotExists = function setForeignObjectNotExists(id, obj, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.getObject(id, options, (err, obj) => { - if (!obj) { - that.objects.setObject(id, obj, callback); - } - }); - }; - - that._DCS2ID = function (device, channel, stateOrPoint) { - let id = ''; - if (device) id += device; - if (channel) id += ((id) ? '.' : '') + channel; - - if (stateOrPoint !== true && stateOrPoint !== false) { - if (stateOrPoint) id += ((id) ? '.' : '') + stateOrPoint; - } else if (stateOrPoint === true) { - if (id) id += '.'; - } - return id; - }; - - that.createDevice = function createDevice(deviceName, common, _native, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (!deviceName) { - that.log.error('Try to create device with empty name!'); - return; - } - if (typeof _native === 'function') { - callback = _native; - _native = {}; - } - if (typeof common === 'function') { - callback = common; - common = {}; - } - common = common || {}; - common.name = common.name || deviceName; - - deviceName = deviceName.replace(/[.\s]+/g, '_'); - _native = _native || {}; - - that.setObjectNotExists(deviceName, { - 'type': 'device', - 'common': common, - 'native': _native - }, options, callback); - }; - - // name of channel must be in format 'channel' - that.createChannel = function createChannel(parentDevice, channelName, roleOrCommon, _native, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (!channelName) throw 'Try to create channel without name!'; - - if (typeof _native === 'function') { - callback = _native; - _native = {}; - } - - if (typeof roleOrCommon === 'function') { - callback = roleOrCommon; - roleOrCommon = undefined; - } - - let common = {}; - if (typeof roleOrCommon === 'string') { - common = { - role: roleOrCommon - }; - } else if (typeof roleOrCommon === 'object') { - common = roleOrCommon; - } - common.name = common.name || channelName; - - if (parentDevice) parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - channelName = channelName.replace(/[.\s]+/g, '_'); - channelName = that._DCS2ID(parentDevice, channelName); - - _native = _native || {}; - - const obj = { - 'type': 'channel', - 'common': common, - 'native': _native - }; - - that.setObject(channelName, obj, options, callback); - }; - - that.createState = function createState(parentDevice, parentChannel, stateName, roleOrCommon, _native, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (!stateName) throw 'Empty name is not allowed!'; - - if (typeof _native === 'function') { - callback = _native; - _native = {}; - } - - if (typeof roleOrCommon === 'function') { - callback = roleOrCommon; - roleOrCommon = undefined; - } - - let common = {}; - if (typeof roleOrCommon === 'string') { - common = { - role: roleOrCommon - }; - } else if (typeof roleOrCommon === 'object') { - common = roleOrCommon; - } - - common.name = common.name || stateName; - _native = _native || {}; - - common.read = (common.read === undefined) ? true : common.read; - common.write = (common.write === undefined) ? false : common.write; - - if (!common.role) { - logger.error(`Try to create state ${parentDevice ? (parentDevice + '.') : ''}${parentChannel}.${stateName} without role`); - return; - } - - if (parentDevice) parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - if (parentChannel) parentChannel = parentChannel.replace(/[.\s]+/g, '_'); - stateName = stateName.replace(/[.\s]+/g, '_'); - const id = that._fixId({device: parentDevice, channel: parentChannel, state: stateName}); - - that.setObjectNotExists(id, { - type: 'state', - common: common, - native: _native - }, options, callback); - - if (common.def !== undefined) { - that.setState(id, common.def, options); - } else { - that.setState(id, null, false, options); - } - }; - - that.deleteDevice = function deleteDevice(deviceName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - deviceName = deviceName.replace(/[.\s]+/g, '_'); - if (!that._namespaceRegExp.test(deviceName)) { - deviceName = `${that.namespace}.${deviceName}`; - } - - that.objects.getObjectView('system', 'device', {startkey: deviceName, endkey: deviceName}, options, (err, res) => { - if (err || !res || !res.rows) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - let cnt = 0; - if (res.rows.length > 1) that.log.warn(`Found more than one device ${deviceName}`); - - for (let t = 0; t < res.rows.length; t++) { - cnt++; - that.delObject(res.rows[t].id, options, err => { - if (err) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - - if (!--cnt) { - cnt = 0; // just to better understand - that.objects.getObjectView('system', 'channel', {startkey: `${deviceName}.`, endkey: `${deviceName}.\u9999`}, options, (err, res) => { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - return; - } - for (let k = 0; k < res.rows.length; k++) { - cnt++; - that.deleteChannel(deviceName, res.rows[k].id, options, err => { - if (!(--cnt) && callback) { - callback(err); - } else { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - callback = null; - } - } - }); - } - if (!cnt && callback) callback(); - }); - } - }); - } - if (!cnt && callback) callback(); - }); - }; - - that.addChannelToEnum = function addChannelToEnum(enumName, addTo, parentDevice, channelName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (parentDevice) { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (that._namespaceRegExp.test(channelName)) { - channelName = channelName.substring(that.namespace.length + 1); - } - if (parentDevice && channelName.substring(0, parentDevice.length) === parentDevice) { - channelName = channelName.substring(parentDevice.length + 1); - } - channelName = channelName.replace(/[.\s]+/g, '_'); - - const objId = `${that.namespace}.${that._DCS2ID(parentDevice, channelName)}`; - - if (addTo.match(/^enum\./)) { - that.objects.getObject(addTo, options, (err, obj) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - if (!err && obj) { - const pos = obj.common.members.indexOf(objId); - if (pos === -1) { - obj.common.members.push(objId); - that.objects.setObject(obj._id, obj, options, err => { - if (callback) callback(err); - }); - } - } - }); - } else { - if (enumName.match(/^enum\./)) enumName = enumName.substring(5); - - that.objects.getObject(`enum.${enumName}.${addTo}`, options, (err, obj) => { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - return; - } - - if (obj) { - const pos = obj.common.members.indexOf(objId); - if (pos === -1) { - obj.common.members.push(objId); - that.objects.setObject(obj._id, obj, options, callback); - } else { - if (callback) { - callback(); - } - } - } else { - // Create enum - that.objects.setObject(`enum.${enumName}.${addTo}`, { - common: { - name: addTo, - members: [objId] - }, - type: 'enum' - }, options, callback); - } - }); - } - }; - - that.deleteChannelFromEnum = function deleteChannelFromEnum(enumName, parentDevice, channelName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (parentDevice) { - if (parentDevice.substring(0, that.namespace.length) === that.namespace) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (channelName && channelName.substring(0, that.namespace.length) === that.namespace) { - channelName = channelName.substring(that.namespace.length + 1); - } - if (parentDevice && channelName && channelName.substring(0, parentDevice.length) === parentDevice) { - channelName = channelName.substring(parentDevice.length + 1); - } - channelName = channelName || ''; - channelName = channelName.replace(/[.\s]+/g, '_'); - - const objId = `${that.namespace}.${that._DCS2ID(parentDevice, channelName)}`; - - if (enumName) { - enumName = `enum.${enumName}.`; - } else { - enumName = 'enum.'; - } - - that.objects.getObjectView('system', 'enum', {startkey: enumName, endkey: `${enumName}\u9999`}, options, (err, res) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - if (res) { - let count = 0; - for (let i = 0; i < res.rows.length; i++) { - count++; - that.objects.getObject(res.rows[i].id, options, (err, obj) => { - if (err) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - if (!err && obj && obj.common && obj.common.members) { - const pos = obj.common.members.indexOf(objId); - if (pos !== -1) { - obj.common.members.splice(pos, 1); - count++; - that.objects.setObject(obj._id, obj, options, err => { - if (!(--count) && callback) { - callback(err); - } else { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - callback = null; - } - } - }); - } - } - count--; - if (!count && callback) callback(err); - }); - } - } else if (callback) { - callback (err); - } - }); - }; - - that.deleteChannel = function deleteChannel(parentDevice, channelName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (typeof channelName === 'function') { - callback = channelName; - channelName = parentDevice; - parentDevice = ''; - } - if (parentDevice && !channelName) { - channelName = parentDevice; - parentDevice = ''; - } else if (parentDevice && typeof channelName === 'function') { - callback = channelName; - channelName = parentDevice; - parentDevice = ''; - } - if (!parentDevice) parentDevice = ''; - that.deleteChannelFromEnum('', parentDevice, channelName); - const _parentDevice = parentDevice; - const _channelName = channelName; - - if (parentDevice) { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (channelName && that._namespaceRegExp.test(channelName)) { - channelName = channelName.substring(that.namespace.length + 1); - } - if (parentDevice && channelName && channelName.substring(0, parentDevice.length) === parentDevice) { - channelName = channelName.substring(parentDevice.length + 1); - } - channelName = channelName || ''; - channelName = channelName.replace(/[.\s]+/g, '_'); - - channelName = `${that.namespace}.${that._DCS2ID(parentDevice, channelName)}`; - - logger.info(`Delete channel ${channelName}`); - - that.objects.getObjectView('system', 'channel', {startkey: channelName, endkey: channelName}, options, (err, res) => { - if (err || !res || !res.rows) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - let cnt = 0; - if (res.rows.length > 1) { - that.log.warn(`Found more than one channel ${channelName}`); - } - - for (let t = 0; t < res.rows.length; t++) { - cnt++; - that.delObject(res.rows[t].id, options, err => { - if (err) { - if (typeof callback === 'function') callback(err); - callback = null; - return; - } - cnt--; - if (!cnt) { - that.objects.getObjectView('system', 'state', {startkey: `${channelName}.`, endkey: `${channelName}.\u9999`}, options, (err, res) => { - if (err || !res || !res.rows) { - if (typeof callback === 'function') { - callback(err); - } - callback = null; - return; - } - for (let k = 0; k < res.rows.length; k++) { - that.deleteState(_parentDevice, _channelName, res.rows[k].id, options, err => { - if (!(--cnt) && callback) { - callback(err); - } else { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - callback = null; - } - } - }); - } - if (!cnt && callback) { - callback(); - } - }); - } - }); - } - if (!cnt && callback) { - callback(); - } - }); - }; - - that.deleteState = function deleteState(parentDevice, parentChannel, stateName, options, callback) { - if (typeof parentChannel === 'function' && stateName === undefined) { - stateName = parentDevice; - callback = parentChannel; - parentChannel = ''; - parentDevice = ''; - } else - if (parentChannel === undefined && stateName === undefined) { - stateName = parentDevice; - parentDevice = ''; - parentChannel = ''; - } else { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (typeof stateName === 'function') { - callback = stateName; - stateName = parentChannel; - parentChannel = parentDevice; - parentDevice = ''; - } - if (typeof parentChannel === 'function') { - callback = parentChannel; - stateName = parentDevice; - parentChannel = ''; - parentDevice = ''; - } - if (typeof parentChannel === 'function') { - callback = parentChannel; - stateName = parentDevice; - parentChannel = ''; - parentDevice = ''; - } - } - - that.deleteStateFromEnum('', parentDevice, parentChannel, stateName, options); - - if (parentDevice) { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (parentChannel) { - if (that._namespaceRegExp.test(parentChannel)) { - parentChannel = parentChannel.substring(that.namespace.length + 1); - } - if (parentDevice && parentChannel.substring(0, parentDevice.length) === parentDevice) { - parentChannel = parentChannel.substring(parentDevice.length + 1); - } - - parentChannel = parentChannel.replace(/[.\s]+/g, '_'); - } - - if (that._namespaceRegExp.test(stateName)) { - stateName = stateName.substring(that.namespace.length + 1); - } - if (parentDevice && stateName.substring(0, parentDevice.length) === parentDevice) { - stateName = stateName.substring(parentDevice.length + 1); - } - if (parentChannel && stateName.substring(0, parentChannel.length) === parentChannel) { - stateName = stateName.substring(parentChannel.length + 1); - } - stateName = stateName || ''; - stateName = stateName.replace(/[.\s]+/g, '_'); - - const _name = that._DCS2ID(parentDevice, parentChannel, stateName); - that.delState(_name, options, function () { - that.delObject(_name, options, callback); - }); - }; - - that.getDevices = function getDevices(callback, options) { - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.getObjectView('system', 'device', {startkey: `${that.namespace}.`, endkey: `${that.namespace}.\u9999`}, options, (err, obj) => { - if (callback) { - if (obj.rows.length) { - const res = []; - for (let i = 0; i < obj.rows.length; i++) { - res.push(obj.rows[i].value); - } - callback(null, res); - } else { - callback(err, []); - } - } - }); - }; - - that.getChannelsOf = function getChannelsOf(parentDevice, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (typeof parentDevice === 'function') { - callback = parentDevice; - parentDevice = null; - } - if (!parentDevice) parentDevice = ''; - - if (parentDevice && that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - parentDevice = that.namespace + (parentDevice ? ('.' + parentDevice) : ''); - that.objects.getObjectView('system', 'channel', {startkey: `${parentDevice}.`, endkey: `${parentDevice}.\u9999`}, options, (err, obj) => { - if (callback) { - if (obj.rows.length) { - const res = []; - for (let i = 0; i < obj.rows.length; i++) { - res.push(obj.rows[i].value); - } - callback(null, res); - } else { - callback(err, []); - } - } - }); - }; - - that.getChannels = that.getChannelsOf; - - that.getStatesOf = function getStatesOf(parentDevice, parentChannel, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (typeof parentDevice === 'function') { - callback = parentDevice; - parentDevice = null; - parentChannel = null; - } - if (typeof parentChannel === 'function') { - callback = parentChannel; - parentChannel = null; - } - - if (!parentDevice) { - parentDevice = ''; - } else { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (!parentChannel) { - parentChannel = ''; - } else if (that._namespaceRegExp.test(parentChannel)) { - parentChannel = parentChannel.substring(that.namespace.length + 1); - } - - if (parentDevice && parentChannel && parentChannel.substring(0, parentDevice.length) === parentDevice) { - parentChannel = parentChannel.substring(parentDevice.length + 1); - } - - parentChannel = parentChannel.replace(/[.\s]+/g, '_'); - - const id = `${that.namespace}.${that._DCS2ID(parentDevice, parentChannel, true)}`; - - that.objects.getObjectView('system', 'state', {startkey: id, endkey: `${id}\u9999`}, options, (err, obj) => { - if (callback) { - const res = []; - if (obj.rows.length) { - let read = 0; - for (let i = 0; i < obj.rows.length; i++) { - read++; - that.objects.getObject(obj.rows[i].id, (err, subObj) => { - if (subObj) res.push(subObj); - - if (!--read) callback(null, res); - }); - } - } else { - callback(null, res); - } - } - }); - }; - - that.addStateToEnum = function addStateToEnum(enumName, addTo, parentDevice, parentChannel, stateName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (parentDevice) { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (parentChannel) { - if (that._namespaceRegExp.test(parentChannel)) { - parentChannel = parentChannel.substring(that.namespace.length + 1); - } - if (parentDevice && parentChannel.substring(0, parentDevice.length) === parentDevice) { - parentChannel = parentChannel.substring(parentDevice.length + 1); - } - - parentChannel = parentChannel.replace(/[.\s]+/g, '_'); - } - - if (that._namespaceRegExp.test(stateName)) { - stateName = stateName.substring(that.namespace.length + 1); - } - if (parentDevice && stateName.substring(0, parentDevice.length) === parentDevice) { - stateName = stateName.substring(parentDevice.length + 1); - } - if (parentChannel && stateName.substring(0, parentChannel.length) === parentChannel) { - stateName = stateName.substring(parentChannel.length + 1); - } - stateName = stateName.replace(/[.\s]+/g, '_'); - - const objId = that._fixId({device: parentDevice, channel: parentChannel, state: stateName}); - - if (addTo.match(/^enum\./)) { - that.objects.getObject(addTo, options, (err, obj) => { - if (!err && obj) { - const pos = obj.common.members.indexOf(objId); - if (pos === -1) { - obj.common.members.push(objId); - that.objects.setObject(obj._id, obj, options, err => { - if (callback) { - callback(err); - } - }); - } - } - }); - } else { - if (enumName.match(/^enum\./)) enumName = enumName.substring(5); - - that.objects.getObject(`enum.${enumName}.${addTo}`, options, (err, obj) => { - if (!err && obj) { - const pos = obj.common.members.indexOf(objId); - if (pos === -1) { - obj.common.members.push(objId); - that.objects.setObject(obj._id, obj, callback); - } else { - if (callback) callback(); - } - } else { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - return; - } - - // Create enum - that.objects.setObject(`enum.${enumName}.${addTo}`, { - common: { - name: addTo, - members: [objId] - }, - type: 'enum' - }, options, callback); - } - }); - } - }; - - that.deleteStateFromEnum = function deleteStateFromEnum(enumName, parentDevice, parentChannel, stateName, options, callback) { - if (typeof options === 'function') { - callback = options; - options = null; - } - if (parentDevice) { - if (that._namespaceRegExp.test(parentDevice)) { - parentDevice = parentDevice.substring(that.namespace.length + 1); - } - - parentDevice = parentDevice.replace(/[.\s]+/g, '_'); - } - - if (parentChannel) { - if (that._namespaceRegExp.test(parentChannel)) { - parentChannel = parentChannel.substring(that.namespace.length + 1); - } - if (parentDevice && parentChannel.substring(0, parentDevice.length) === parentDevice) { - parentChannel = parentChannel.substring(parentDevice.length + 1); - } - - parentChannel = parentChannel.replace(/[.\s]+/g, '_'); - } - - if (that._namespaceRegExp.test(stateName)) { - stateName = stateName.substring(that.namespace.length + 1); - } - if (parentDevice && stateName.substring(0, parentDevice.length) === parentDevice) { - stateName = stateName.substring(parentDevice.length + 1); - } - if (parentChannel && stateName.substring(0, parentChannel.length) === parentChannel) { - stateName = stateName.substring(parentChannel.length + 1); - } - stateName = stateName.replace(/[.\s]+/g, '_'); - - const objId = that._fixId({device: parentDevice, channel: parentChannel, state: stateName}, 'state'); - - if (enumName) { - enumName = `enum.${enumName}.`; - } else { - enumName = 'enum.'; - } - - that.objects.getObjectView('system', 'enum', {startkey: enumName, endkey: `${enumName}\u9999`}, options, (err, res) => { - if (!err && res) { - let count = 0; - for (let i = 0; i < res.rows.length; i++) { - count++; - that.objects.getObject(res.rows[i].id, options, (err, obj) => { - if (err) { - if (callback) callback(err); - callback = null; - return; - } - - if (!err && obj && obj.common && obj.common.members) { - const pos = obj.common.members.indexOf(objId); - if (pos !== -1) { - obj.common.members.splice(pos, 1); - count++; - that.objects.setObject(obj._id, obj, err => { - if (!--count && callback) { - callback(err); - } - }); - } - } - if (!--count && callback) { - callback(err); - } - }); - } - } else if (callback) { - callback (err); - } - }); - }; - - that.chmodFile = function readDir(adapter, path, options, callback) { - if (adapter === null) adapter = that.name; - - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.chmodFile(adapter, path, options, callback); - }; - - that.readDir = function readDir(adapter, path, options, callback) { - if (adapter === null) { - adapter = that.name; - } - - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.readDir(adapter, path, options, callback); - }; - - that.unlink = function unlink(adapter, name, options, callback) { - if (adapter === null) adapter = that.name; - - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.unlink(adapter, name, options, callback); - }; - - that.rename = function rename(adapter, oldName, newName, options, callback) { - if (adapter === null) { - adapter = that.name; - } - if (typeof options === 'function') { - callback = options; - options = null; - } - that.objects.rename(adapter, oldName, newName, options, callback); - }; - - that.mkdir = function mkdir(adapter, dirname, options, callback) { - if (adapter === null) adapter = that.name; - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.mkdir(adapter, dirname, options, callback); - }; - - that.readFile = function readFile(adapter, filename, options, callback) { - if (adapter === null) { - adapter = that.name; - } - - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.readFile(adapter, filename, options, callback); - }; - - that.writeFile = function writeFile(adapter, filename, data, options, callback) { - if (adapter === null) { - adapter = that.name; - } - - if (typeof options === 'function') { - callback = options; - options = null; - } - - that.objects.writeFile(adapter, filename, data, options, callback); - }; - - that.formatDate = function formatDate(dateObj, isSeconds, _format) { - if (typeof isSeconds !== 'boolean') { - _format = isSeconds; - isSeconds = false; - } - - let format = _format || that.dateFormat || 'DD.MM.YYYY'; - - if (!dateObj) { - return ''; - } - const text = typeof dateObj; - if (text === 'string') { - const pos = dateObj.indexOf('.'); - if (pos !== -1) { - dateObj = dateObj.substring(0, pos); - } - return dateObj; - } - if (text !== 'object') { - dateObj = isSeconds ? new Date(dateObj * 1000) : new Date(dateObj); - } - - let v; - - // Year - if (format.indexOf('YYYY') !== -1 || format.indexOf('JJJJ') !== -1 || format.indexOf('ГГГГ') !== -1) { - v = dateObj.getFullYear(); - format = format.replace('YYYY', v); - format = format.replace('JJJJ', v); - format = format.replace('ГГГГ', v); - } else if (format.indexOf('YY') !== -1 || format.indexOf('JJ') !== -1 || format.indexOf('ГГ') !== -1) { - v = dateObj.getFullYear() % 100; - format = format.replace('YY', v); - format = format.replace('JJ', v); - format = format.replace('ГГ', v); - } - // Month - if (format.indexOf('MM') !== -1 || format.indexOf('ММ') !== -1) { - v = dateObj.getMonth() + 1; - if (v < 10) { - v = '0' + v; - } - format = format.replace('MM', v); - format = format.replace('ММ', v); - } else if (format.indexOf('M') !== -1 || format.indexOf('М') !== -1) { - v = dateObj.getMonth() + 1; - format = format.replace('M', v); - format = format.replace('М', v); - } - - // Day - if (format.indexOf('DD') !== -1 || format.indexOf('TT') !== -1 || format.indexOf('ДД') !== -1) { - v = dateObj.getDate(); - if (v < 10) { - v = '0' + v; - } - format = format.replace('DD', v); - format = format.replace('TT', v); - format = format.replace('ДД', v); - } else if (format.indexOf('D') !== -1 || format.indexOf('TT') !== -1 || format.indexOf('Д') !== -1) { - v = dateObj.getDate(); - format = format.replace('D', v); - format = format.replace('T', v); - format = format.replace('Д', v); - } - - // hours - if (format.indexOf('hh') !== -1 || format.indexOf('SS') !== -1 || format.indexOf('чч') !== -1) { - v = dateObj.getHours(); - if (v < 10) { - v = '0' + v; - } - format = format.replace('hh', v); - format = format.replace('SS', v); - format = format.replace('чч', v); - } else if (format.indexOf('h') !== -1 || format.indexOf('S') !== -1 || format.indexOf('ч') !== -1) { - v = dateObj.getHours(); - format = format.replace('h', v); - format = format.replace('S', v); - format = format.replace('ч', v); - } - - // minutes - if (format.indexOf('mm') !== -1 || format.indexOf('мм') !== -1) { - v = dateObj.getMinutes(); - if (v < 10) { - v = '0' + v; - } - format = format.replace('mm', v); - format = format.replace('мм', v); - } else if (format.indexOf('m') !== -1 || format.indexOf('м') !== -1) { - v = dateObj.getMinutes(); - format = format.replace('m', v); - format = format.replace('v', v); - } - - // seconds - if (format.indexOf('ss') !== -1 || format.indexOf('сс') !== -1) { - v = dateObj.getSeconds(); - if (v < 10) { - v = '0' + v; - } - v = v.toString(); - format = format.replace('ss', v); - format = format.replace('cc', v); - } else if (format.indexOf('s') !== -1 || format.indexOf('с') !== -1) { - v = dateObj.getHours().toString(); - format = format.replace('s', v); - format = format.replace('с', v); - } - return format; - }; - - return this; -} - -module.exports = Objects; \ No newline at end of file diff --git a/test/lib/states.js b/test/lib/states.js deleted file mode 100644 index a915b03..0000000 --- a/test/lib/states.js +++ /dev/null @@ -1,718 +0,0 @@ -'use strict'; -const path = require('path'); -const rootDir = path.normalize(`${__dirname}/../../`); -let adapterName = path.normalize(rootDir).replace(/\\/g, '/').split('/'); -adapterName = adapterName[adapterName.length - 2]; - -const logger = { - info: function (msg) { - console.log(msg); - }, - debug: function (msg) { - console.log(msg); - }, - warn: function (msg) { - console.warn(msg); - }, - error: function (msg) { - console.error(msg); - } -}; - -function States(cb, stateChange) { - const that = this; - const _States = require(`${rootDir}tmp/node_modules/iobroker.js-controller/lib/states`); - let callbackId = 0; - - const options = { - stateChange: (id, state) => stateChange && stateChange(id, state) - }; - - that.namespace = 'test'; - - that.states = new _States({ - connection: { - type : 'file', - host : '127.0.0.1', - port : 19000, - options : { - auth_pass : null, - retry_max_delay : 15000 - } - }, - logger: logger, - change: (id, state) => { - if (!id || typeof id !== 'string') { - console.log(`Something is wrong! ${JSON.stringify(id)}`); - return; - } - - // Clear cache if accidentally got the message about change (Will work for admin and javascript) - if (id.match(/^system\.user\./) || id.match(/^system\.group\./)) { - that.users = []; - } - - // If someone want to have log messages - if (that.logList && id.match(/\.logging$/)) { - that.logRedirect(state ? state.val : false, id.substring(0, id.length - '.logging'.length)); - } else - if (id === `log.system.adapter.${that.namespace}`) { - that.processLog(state); - } else - // If this is messagebox - if (id === `messagebox.system.adapter.${that.namespace}` && state) { - // Read it from fifo list - that.states.delMessage(`system.adapter.${that.namespace}`, state._id); - const obj = state; - if (obj) { - // If callback stored for this request - if (obj.callback && - obj.callback.ack && - obj.callback.id && - that.callbacks && - that.callbacks[`_${obj.callback.id}`]) { - // Call callback function - if (that.callbacks[`_${obj.callback.id}`].cb) { - that.callbacks[`_${obj.callback.id}`].cb(obj.message); - delete that.callbacks[`_${obj.callback.id}`]; - } - // delete too old callbacks IDs, like garbage collector - const now = Date.now(); - for (const _id in that.callbacks) { - if (that.callbacks.hasOwnProperty(_id) && now - that.callbacks[_id].time > 3600000) delete that.callbacks[_id]; - } - - } else { - if (options.message) { - // Else inform about new message the adapter - options.message(obj); - } - that.emit('message', obj); - } - } - } else { - if (id.slice(that.namespace.length) === that.namespace) { - if (typeof options.stateChange === 'function') options.stateChange(id.slice(that.namespace.length + 1), state); - // emit 'stateChange' event instantly - setImmediate(() => that.emit('stateChange', id.slice(that.namespace.length + 1), state)); - - } else { - if (typeof options.stateChange === 'function') options.stateChange(id, state); - if (id.substring(0, 4) === 'log.') { - console.log('LOG'); - } - if (that.emit) { - // emit 'stateChange' event instantly - setImmediate(() => that.emit('stateChange', id, state)); - } - } - } - }, - connectTimeout: (error) => { - if (logger) logger.error(`${that.namespace} no connection to states DB`); - if (cb) cb('Timeout'); - } - }); - - // Send message to other adapter instance or all instances of adapter - that.sendTo = function sendTo(objName, command, message, callback) { - if (typeof message === 'undefined') { - message = command; - command = 'send'; - } - const obj = {command: command, message: message, from: `system.adapter.${that.namespace}`}; - - if (!objName.match(/^system\.adapter\./)) { - objName = `system.adapter.${objName}`; - } - - that.log.info(`sendTo "${command}" to ${objName} from system.adapter.${that.namespace}: ${JSON.stringify(message)}`); - - // If not specific instance - if (!objName.match(/\.[0-9]+$/)) { - // Send to all instances of adapter - that.objects.getObjectView('system', 'instance', {startkey: `${objName}.`, endkey: `${objName}.\u9999`}, (err, _obj) => { - if (_obj) { - for (let i = 0; i < _obj.rows.length; i++) { - that.states.pushMessage(_obj.rows[i].id, obj); - } - } - }); - } else { - if (callback) { - if (typeof callback === 'function') { - // force subscribe even no messagebox enabled - if (!that.common.messagebox && !that.mboxSubscribed) { - that.mboxSubscribed = true; - that.states.subscribeMessage(`system.adapter.${that.namespace}`); - } - - obj.callback = { - message: message, - id: callbackId++, - ack: false, - time: Date.now() - }; - if (callbackId >= 0xFFFFFFFF) { - callbackId = 1; - } - if (!that.callbacks) that.callbacks = {}; - that.callbacks['_' + obj.callback.id] = {cb: callback}; - - // delete too old callbacks IDs - const now = Date.now(); - for (const _id in that.callbacks) { - if (that.callbacks.hasOwnProperty(_id) && now - that.callbacks[_id].time > 3600000) { - delete that.callbacks[_id]; - } - } - } else { - obj.callback = callback; - obj.callback.ack = true; - } - } - - that.states.pushMessage(objName, obj); - } - }; - - // Send message to specific host or to all hosts - that.sendToHost = function sendToHost(objName, command, message, callback) { - if (typeof message === 'undefined') { - message = command; - command = 'send'; - } - const obj = {command: command, message: message, from: `system.adapter.${that.namespace}`}; - - if (objName && objName.substring(0, 'system.host.'.length) !== 'system.host.') { - objName = `system.host.${objName}`; - } - - if (!objName) { - // Send to all hosts - that.objects.getObjectList({startkey: 'system.host.', endkey: `system.host.\u9999`}, null, (err, res) => { - if (!err && res.rows.length) { - for (let i = 0; i < res.rows.length; i++) { - const parts = res.rows[i].id.split('.'); - // ignore system.host.name.alive and so on - if (parts.length === 3) { - that.states.pushMessage(res.rows[i].id, obj); - } - } - } - }); - } else { - if (callback) { - if (typeof callback === 'function') { - // force subscribe even no messagebox enabled - if (!that.common.messagebox && !that.mboxSubscribed) { - that.mboxSubscribed = true; - that.states.subscribeMessage(`system.adapter.${that.namespace}`); - } - - obj.callback = { - message: message, - id: callbackId++, - ack: false, - time: Date.now() - }; - if (callbackId >= 0xFFFFFFFF) { - callbackId = 1; - } - that.callbacks = that.callbacks || {}; - that.callbacks[`_${obj.callback.id}`] = {cb: callback}; - } else { - obj.callback = callback; - obj.callback.ack = true; - } - } - - that.states.pushMessage(objName, obj); - } - }; - - that.setState = function setState(id, state, ack, options, callback) { - if (typeof state === 'object' && typeof ack !== 'boolean') { - callback = options; - options = ack; - ack = undefined; - } - if (typeof options === 'function') { - callback = options; - options = {}; - } - id = that._fixId(id, 'state'); - - if (typeof ack === 'function') { - callback = ack; - ack = undefined; - } - - if (typeof state !== 'object' || state === null || state === undefined) state = {val: state}; - - if (ack !== undefined) { - state.ack = ack; - } - - state.from = `system.adapter.${that.namespace}`; - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'setState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.setState(id, state, callback); - } - }); - } else { - that.states.setState(id, state, callback); - } - }; - - that.setForeignState = function setForeignState(id, state, ack, options, callback) { - if (typeof state === 'object' && typeof ack !== 'boolean') { - callback = options; - options = ack; - ack = undefined; - } - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - if (typeof ack === 'function') { - callback = ack; - ack = undefined; - } - - if (typeof state !== 'object' || state === null || state === undefined) state = {val: state}; - - if (ack !== undefined) { - state.ack = ack; - } - - state.from = 'system.adapter.' + that.namespace; - - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'setState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.setState(id, state, callback); - } - }); - } else { - that.states.setState(id, state, callback); - } - }; - - that.getState = function getState(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - id = that._fixId(id, 'state'); - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'getState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.getState(id, callback); - } - }); - } else { - that.states.getState(id, callback); - } - }; - - that.getStateHistory = function getStateHistory(id, start, end, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - id = that._fixId(id, 'state'); - that.getForeignStateHistory(id, start, end, options, callback); - }; - - that.getForeignStateHistory = function getForeignStateHistory(id, start, end, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - - if (typeof start === 'function') { - callback = start; - start = undefined; - end = undefined; - } else if (typeof end === 'function') { - callback = end; - end = undefined; - } - - start = start || Math.round((new Date()).getTime() / 1000) - 31536000; // - 1 year - end = end || Math.round((new Date()).getTime() / 1000) + 5000; - - const history = []; - const docs = []; - - // get data from states - that.log.debug('get states history ' + id + ' ' + start + ' ' + end); - that.getFifo(id, (err, res) => { - if (!err && res) { - let iProblemCount = 0; - for (let i = 0; i < res.length; i++) { - if (!res[i]) { - iProblemCount++; - continue; - } - if (res[i].ts < start) { - continue; - } else if (res[i].ts > end) { - break; - } - history.push(res[i]); - } - if (iProblemCount) that.log.warn(`got null states ${iProblemCount} times for ${id}`); - - that.log.debug(`got ${res.length} datapoints for ${id}`); - } else { - if (err !== 'Not exists') { - that.log.error(err); - } else { - that.log.debug(`datapoints for ${id} do not yet exist`); - } - } - - // fetch a history document from objectDB - function getObjectsLog(cid, callback) { - that.log.info('getObjectLog ' + cid); - that.getForeignObject(cid, options, (err, res) => { - if (!err && res.common.data) { - for (let i = 0; i < res.common.data.length; i++) { - if (res.common.data[i].ts < start) { - continue; - } else if (res.common.data[i].ts > end) { - break; - } - history.push(res.common.data[i]); - } - } else { - that.log.warn(`${cid} not found`); - } - callback(err); - }); - } - - // queue objects history documents fetching - function queue(ts) { - if (ts < start) { - callback(null, history); - return; - } - const cid = `history.${id}.${ts2day(ts)}`; - if (docs.indexOf(cid) !== -1) { - getObjectsLog(cid, err => queue(ts - 86400)); // - 1 day - } else { - queue(ts - 86400); // - 1 day - } - } - - // get list of available history documents - that.objects.getObjectList({startkey: `history.${id}`, endkey: `history.${id}\u9999`}, options, (err, res) => { - if (!err && res.rows.length) { - for (let i = 0; i < res.rows.length; i++) { - docs.push(res.rows[i].id); - } - queue(end); - } else { - callback(null, history); - } - }); - }); - }; - - // normally only foreign history has interest, so there is no getHistory and getForeignHistory - that.getHistory = function getHistory(id, options, callback) { - options = options || {}; - options.end = options.end || Math.round((new Date()).getTime() / 1000) + 5000; - if (!options.count && !options.start) { - options.start = options.start || Math.round((new Date()).getTime() / 1000) - 604800; // - 1 week - } - - if (!options.instance) { - if (!that.defaultHistory) { - // read default history instance from system.config - return getDefaultHistory(() => that.getHistory(id, options, callback)); - } else { - options.instance = that.defaultHistory; - } - } - - that.sendTo(options.instance || 'history.0', 'getHistory', {id: id, options: options}, res => { - setImmediate(() => callback(res.error, res.result, res.step)); - }); - }; - - // Convert ID adapter.instance.device.channel.state - // Convert ID to {device: D, channel: C, state: S} - that.idToDCS = function idToDCS(id) { - if (!id) return null; - const parts = id.split('.'); - if (`${parts[0]}.${parts[1]}` !== that.namespace) { - that.log.warn("Try to decode id not from this adapter"); - return null; - } - return {device: parts[2], channel: parts[3], state: parts[4]}; - }; - - that.getForeignState = function getForeignState(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'getState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.getState(id, callback); - } - }); - } else { - that.states.getState(id, callback); - } - }; - - that.delForeignState = function delForeignState(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'delState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.delState(id, callback); - } - }); - } else { - that.states.delState(id, callback); - } - - }; - - that.delState = function delState(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - id = that._fixId(id); - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(id, options, 'delState', err => { - if (err) { - if (typeof callback === 'function') callback(err); - } else { - that.states.delState(id, callback); - } - }); - } else { - that.states.delState(id, callback); - } - }; - - that.getStates = function getStates(pattern, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - pattern = that._fixId(pattern, 'state'); - that.getForeignStates(pattern, options, callback); - }; - - that.getForeignStates = function getForeignStates(pattern, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - const list = {}; - if (typeof pattern === 'function') { - callback = pattern; - pattern = '*'; - } - - if (typeof callback !== 'function') { - logger.error(`getForeignStates invalid callback for ${pattern}`); - return; - } - - if (typeof pattern === 'object') { - that.states.getStates(pattern, (err, arr) => { - if (err) { - callback(err); - return; - } - for (let i = 0; i < pattern.length; i++) { - if (typeof arr[i] === 'string') arr[i] = JSON.parse(arr[i]); - list[pattern[i]] = arr[i] || {}; - } - callback(null, list); - }); - return; - } - const keys = []; - let params = {}; - if (pattern && pattern !== '*') { - params = { - startkey: pattern.replace('*', ''), - endkey: pattern.replace('*', '\u9999') - }; - } - that.objects.getObjectView('system', 'state', params, options, (err, res) => { - if (err) { - if (typeof callback === 'function') { - callback(err); - } - return; - } - - for (let i = 0; i < res.rows.length; i++) { - keys.push(res.rows[i].id); - } - - if (options && options.user && options.user !== 'system.user.admin') { - checkStates(keys, options, 'getState', (err, keys) => { - if (err) { - if (typeof callback === 'function') callback(err); - return; - } - that.states.getStates(keys, function (err, arr) { - if (err) { - callback(err); - return; - } - for (let i = 0; i < res.rows.length; i++) { - if (typeof arr[i] === 'string') arr[i] = JSON.parse(arr[i]); - list[keys[i]] = arr[i] || {}; - } - if (typeof callback === 'function') { - callback(null, list); - } - }); - }); - } else { - that.states.getStates(keys, function (err, arr) { - if (err) { - callback(err); - return; - } - for (let i = 0; i < res.rows.length; i++) { - if (typeof arr[i] === 'string') arr[i] = JSON.parse(arr[i]); - list[keys[i]] = arr[i] || {}; - } - if (typeof callback === 'function') callback(null, list); - }); - } - }); - }; - - that.subscribeForeignStates = function subscribeForeignStates(pattern, options) { - if (!pattern) pattern = '*'; - that.states.subscribe(pattern, options); - }; - - that.unsubscribeForeignStates = function unsubscribeForeignStates(pattern, options) { - if (!pattern) pattern = '*'; - that.states.unsubscribe(pattern, options); - }; - - that.subscribeStates = function subscribeStates(pattern, options) { - // Exception. Threat the '*' case automatically - if (!pattern || pattern === '*') { - that.states.subscribe(`${that.namespace}.*`, options); - } else { - pattern = that._fixId(pattern, 'state'); - that.states.subscribe(pattern, options); - } - }; - - that.unsubscribeStates = function unsubscribeStates(pattern, options) { - if (!pattern || pattern === '*') { - that.states.unsubscribe(`${that.namespace}.*`, options); - } else { - pattern = that._fixId(pattern, 'state'); - that.states.unsubscribe(pattern, options); - } - }; - - that.pushFifo = function pushFifo(id, state, callback) { - that.states.pushFifo(id, state, callback); - }; - - that.trimFifo = function trimFifo(id, start, end, callback) { - that.states.trimFifo(id, start, end, callback); - }; - - that.getFifoRange = function getFifoRange(id, start, end, callback) { - that.states.getFifoRange(id, start, end, callback); - }; - - that.getFifo = function getFifo(id, callback) { - that.states.getFifo(id, callback); - }; - - that.lenFifo = function lenFifo(id, callback) { - that.states.lenFifo(id, callback); - }; - - that.subscribeFifo = function subscribeFifo(pattern) { - that.states.subscribeFifo(pattern); - }; - - that.getSession = function getSession(id, callback) { - that.states.getSession(id, callback); - }; - that.setSession = function setSession(id, ttl, data, callback) { - that.states.setSession(id, ttl, data, callback); - }; - that.destroySession = function destroySession(id, callback) { - that.states.destroySession(id, callback); - }; - - that.getMessage = function getMessage(callback) { - that.states.getMessage('system.adapter.' + that.namespace, callback); - }; - - that.lenMessage = function lenMessage(callback) { - that.states.lenMessage(`system.adapter.${that.namespace}`, callback); - }; - - // Write binary block into redis, e.g. image - that.setBinaryState = function setBinaryState(id, binary, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - that.states.setBinaryState(id, binary, callback); - }; - - // Read binary block from redis, e.g. image - that.getBinaryState = function getBinaryState(id, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - that.states.getBinaryState(id, callback); - }; - - logger.debug(`${that.namespace} statesDB connected`); - - if (typeof cb === 'function') { - setImmediate(() => cb(), 0); - } - - return this; -} - -module.exports = States; \ No newline at end of file diff --git a/test/testServer.js b/test/testServer.js index 837e630..9bb4820 100644 --- a/test/testServer.js +++ b/test/testServer.js @@ -52,9 +52,9 @@ const rules = { }, }; -function decrypt(key, value) { +function encryptLegacy(key, value) { let result = ''; - for (let i = 0; i < value.length; ++i) { + for (let i = 0; i < value.length; i++) { result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i)); } return result; @@ -217,7 +217,7 @@ describe('Sonoff server: Test mqtt server', () => { config.common.enabled = true; config.common.loglevel = 'debug'; config.native.user = 'user'; - config.native.pass = decrypt(systemConfig.native.secret, 'pass1'); + config.native.password = encryptLegacy(systemConfig.native.secret, 'pass1'); await setup.setAdapterConfig(config.common, config.native); @@ -245,7 +245,7 @@ describe('Sonoff server: Test mqtt server', () => { for (let r in rules) { (function(id, task) { - it('Sonoff Server: Check receive ' + id, function (done) { // let FUNCTION here + it(`Sonoff Server: Check receive ${id}`, function (done) { // let FUNCTION here checkMqtt2Adapter(id, task, this, done); }); })(r, rules[r]);