diff --git a/alexa-remote.js b/alexa-remote.js index 0e8bfc31..4757c8fe 100755 --- a/alexa-remote.js +++ b/alexa-remote.js @@ -10,7 +10,7 @@ const querystring = require('querystring'); const os = require('os'); const extend = require('extend'); const AlexaWsMqtt = require('./alexa-wsmqtt.js'); -const uuidv1 = require('uuid/v1'); +const { v1: uuidv1 } = require('uuid'); const EventEmitter = require('events'); @@ -92,8 +92,12 @@ class AlexaRemote extends EventEmitter { if (this._options.alexaServiceHost) this.baseUrl = this._options.alexaServiceHost; this._options.logger && this._options.logger('Alexa-Remote: Use as Base-URL: ' + this.baseUrl); this._options.alexaServiceHost = this.baseUrl; - if (this._options.refreshCookieInterval !== 0) { - this._options.refreshCookieInterval = this._options.refreshCookieInterval || 7*24*60*60*1000; // Auto Refresh after 7 days + if (this._options.refreshCookieInterval !== undefined && this._options.cookieRefreshInterval === undefined) { + this._options.cookieRefreshInterval = this._options.refreshCookieInterval; + delete this._options.refreshCookieInterval; + } + if (this._options.cookieRefreshInterval !== 0) { + this._options.cookieRefreshInterval = this._options.cookieRefreshInterval || 7*24*60*60*1000; // Auto Refresh after 7 days } const self = this; @@ -264,7 +268,7 @@ class AlexaRemote extends EventEmitter { this.names [name] = device; this.names [name.toLowerCase()] = device; } - device._orig = JSON.parse(JSON.stringify(device)); + //device._orig = JSON.parse(JSON.stringify(device)); device._name = name; device.sendCommand = this.sendCommand.bind(this, device); device.setTunein = this.setTunein.bind(this, device); @@ -330,6 +334,11 @@ class AlexaRemote extends EventEmitter { this.alexaWsMqtt = new AlexaWsMqtt(this._options, this.cookie); if (!this.alexaWsMqtt) return; + this.activityUpdateQueue = []; + this.activityUpdateNotFoundCounter = 0; + this.activityUpdateTimeout = null; + this.activityUpdateRunning = false; + this.alexaWsMqtt.on('disconnect', (retries, msg) => { this.emit('ws-disconnect', retries, msg); }); @@ -594,25 +603,15 @@ class AlexaRemote extends EventEmitter { 'version': 1 } */ - this.getActivities({size: 3, filter: false}, (err, res) => { - if (err || !res) return; - let activity = null; - for (let i = 0; i < res.length; i++) { - if (res[i].data.id.endsWith('#' + payload.key.entryId) && res[i].data.registeredCustomerId === payload.key.registeredUserId) { - activity = res[i]; - break; - } - } - - if (!activity) { - this._options.logger && this._options.logger('Alexa-Remote: Activity for id ' + payload.key.entryId + ' not found'); - return; - } - //this._options.logger && this._options.logger('Alexa-Remote: Activity found for id ' + payload.key.entryId + ': ' + JSON.stringify(activity)); - - activity.destinationUserId = payload.destinationUserId; - this.emit('ws-device-activity', activity); - }); + this.activityUpdateQueue.push(payload); + if (this.activityUpdateTimeout) { + clearTimeout(this.activityUpdateTimeout); + this.activityUpdateTimeout = null; + } + this.activityUpdateTimeout = setTimeout(() => { + this.activityUpdateTimeout = null; + this.getPushedActivities(); + }, 200); return; case 'PUSH_TODO_CHANGE': // does not exist? @@ -648,6 +647,56 @@ class AlexaRemote extends EventEmitter { this.alexaWsMqtt.connect(); } + getPushedActivities() { + if (this.activityUpdateRunning || !this.activityUpdateQueue.length) return; + this.activityUpdateRunning = true; + this.getActivities({size: this.activityUpdateQueue.length + 2, filter: false}, (err, res) => { + this.activityUpdateRunning = false; + if (!err && res) { + + let lastFoundQueueIndex = -1; + this.activityUpdateQueue.forEach((entry, queueIndex) => { + const found = res.findIndex(activity => activity.data.id.endsWith('#' + entry.key.entryId) && activity.data.registeredCustomerId === entry.key.registeredUserId); + + if (found === -1) { + this._options.logger && this._options.logger('Alexa-Remote: Activity for id ' + entry.key.entryId + ' not found'); + } + else { + lastFoundQueueIndex = queueIndex; + const activity = res.splice(found, 1)[0]; + this._options.logger && this._options.logger('Alexa-Remote: Activity found ' + found + ' for Activity ID ' + entry.key.entryId); + activity.destinationUserId = entry.destinationUserId; + this.emit('ws-device-activity', activity); + } + }); + + if (lastFoundQueueIndex === -1) { + this._options.logger && this._options.logger('Alexa-Remote: No activities from stored ' + this.activityUpdateQueue.length + ' entries found in queue (' + this.activityUpdateNotFoundCounter + ')'); + this.activityUpdateNotFoundCounter++; + if (this.activityUpdateNotFoundCounter > 2) { + this._options.logger && this._options.logger('Alexa-Remote: Reset expected activities'); + this.activityUpdateQueue = []; + this.activityUpdateNotFoundCounter = 0; + } + } + else { + this.activityUpdateNotFoundCounter = 0; + this.activityUpdateQueue.splice(0, lastFoundQueueIndex + 1); + this._options.logger && this._options.logger('Alexa-Remote: ' + this.activityUpdateQueue.length + ' entries left in activity queue'); + } + } + + if (this.activityUpdateQueue.length) { + this.activityUpdateTimeout = setTimeout(() => { + this.activityUpdateTimeout = null; + this.getPushedActivities(); + }, 200); + + } + + }); + } + stop() { if (this.cookieRefreshTimeout) { clearTimeout(this.cookieRefreshTimeout); @@ -1501,7 +1550,7 @@ class AlexaRemote extends EventEmitter { seqNode.type = 'Alexa.DeviceControls.Volume'; value = ~~value; if (value < 0 || value > 100) { - return callback(new Error('Volume needs to be between 0 and 100')); + return callback && callback(new Error('Volume needs to be between 0 and 100')); } seqNode.operationPayload.value = value; break; diff --git a/alexa-wsmqtt.js b/alexa-wsmqtt.js index 086d8693..22236525 100755 --- a/alexa-wsmqtt.js +++ b/alexa-wsmqtt.js @@ -124,7 +124,7 @@ class AlexaWsMqtt extends EventEmitter { }); this.websocket.on('unexpected-response', (request, response) => { - this._options.logger && this._options.logger('Alexa-Remote WS-MQTT: Unexpected Response: ' + JSON.stringify(response)); + this._options.logger && this._options.logger('Alexa-Remote WS-MQTT: Unexpected Response: ' + response); }); this.websocket.on('message', (data) => { diff --git a/package-lock.json b/package-lock.json index 308bcaad..4c4d552b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,22 @@ { "name": "alexa-remote2", - "version": "3.0.3", + "version": "3.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/http-proxy": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.3.tgz", + "integrity": "sha512-wIPqXANye5BbORbuh74exbwNzj+UWCwWyeEFJzUQ7Fq3W2NSAy+7x7nX1fgbEypr2/TdKqpeuxLnXWgzN533/Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "13.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", + "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==" + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -14,13 +27,13 @@ } }, "alexa-cookie2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/alexa-cookie2/-/alexa-cookie2-3.0.2.tgz", - "integrity": "sha512-NPNODZBZvcDQQbwSxYhTWfTPPyJy+aNAWX8OUO1E1QbtbuwZlwBBE0C5/HKUnzvgKTq6rc+hFTzWqbQhRla3pQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/alexa-cookie2/-/alexa-cookie2-3.0.3.tgz", + "integrity": "sha512-vj1hWeVMhHnIbVoilrL8tx1Qk/+cjDfoEUYeT7E52F8fYXkPgRgKawpNdhtP8ZQRrBqXbHEquzTZDb/7m1EO1w==", "requires": { "cookie": "^0.4.0", "express": "^4.17.1", - "http-proxy-middleware": "^0.20.0", + "http-proxy-middleware": "^1.0.2", "http-proxy-response-rewrite": "^0.0.1", "https": "^1.0.0", "querystring": "^0.2.0" @@ -218,9 +231,9 @@ } }, "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", + "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", "requires": { "debug": "^3.0.0" }, @@ -273,13 +286,14 @@ } }, "http-proxy-middleware": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.20.0.tgz", - "integrity": "sha512-dNJAk71nEJhPiAczQH9hGvE/MT9kEs+zn2Dh+Hi94PGZe1GluQirC7mw5rdREUtWx6qGS1Gu0bZd4qEAg+REgw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.3.tgz", + "integrity": "sha512-GHvPeBD+A357zS5tHjzj6ISrVOjjCiy0I92bdyTJz0pNmIjFxO0NX/bX+xkGgnclKQE/5hHAB9JEQ7u9Pw4olg==", "requires": { - "http-proxy": "^1.17.0", + "@types/http-proxy": "^1.17.3", + "http-proxy": "^1.18.0", "is-glob": "^4.0.1", - "lodash": "^4.17.14", + "lodash": "^4.17.15", "micromatch": "^4.0.2" } }, @@ -311,9 +325,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is-extglob": { "version": "2.1.1", @@ -373,16 +387,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" }, "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "requires": { - "mime-db": "1.42.0" + "mime-db": "1.43.0" } }, "ms": { @@ -414,9 +428,9 @@ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==" + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" }, "process-nextick-args": { "version": "2.0.1", @@ -424,12 +438,12 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "ipaddr.js": "1.9.1" } }, "qs": { @@ -459,9 +473,9 @@ } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -586,9 +600,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", + "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==" }, "vary": { "version": "1.1.2", @@ -596,9 +610,9 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "ws": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", - "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" } } } diff --git a/package.json b/package.json index 5b240577..d09e86ad 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "alexa-remote2", - "version": "3.0.3", + "version": "3.1.0", "description": "Remote Control for amazon echo devices", "author": { "name": "Apollon77", - "email": "ingo@fischer-ka.de" + "email": "iobroker@fischer-ka.de" }, "contributors": [ { @@ -13,7 +13,7 @@ }, { "name": "Apollon77", - "email": "ingo@fischer-ka.de" + "email": "iobroker@fischer-ka.de" } ], "homepage": "https://github.com/Apollon77/alexa-remote", @@ -25,12 +25,12 @@ "layla.amazon.de" ], "dependencies": { - "alexa-cookie2": "^3.0.2", + "alexa-cookie2": "^3.0.3", "https": "^1.0.0", "querystring": "^0.2.0", - "ws": "^7.2.1", + "ws": "^7.2.3", "extend": "^3.0.2", - "uuid": "^3.3.3" + "uuid": "^7.0.2" }, "devDependencies": {}, "scripts": { diff --git a/readme.md b/readme.md index 827e8056..56173812 100644 --- a/readme.md +++ b/readme.md @@ -27,6 +27,9 @@ Thank you for that work. ## Changelog: +### 3.1.0 (2019-12-30) +* (Apollon77) remove device._orig because really big objects happened and got exceptions on deep copy using JSION.stringify + ### 3.0.3 (2019-12-28) * (Apollon77) update cookie lib