iobroker.sonoff 2.5.0 → 2.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/tools.js CHANGED
@@ -1,99 +1,99 @@
1
- const axios = require('axios').default;
2
-
3
- /**
4
- * Tests whether the given variable is a real object and not an Array
5
- * @param {any} it The variable to test
6
- * @returns {it is Record<string, any>}
7
- */
8
- function isObject(it) {
9
- // This is necessary because:
10
- // typeof null === 'object'
11
- // typeof [] === 'object'
12
- // [] instanceof Object === true
13
- return Object.prototype.toString.call(it) === '[object Object]';
14
- }
15
-
16
- /**
17
- * Tests whether the given variable is really an Array
18
- * @param {any} it The variable to test
19
- * @returns {it is any[]}
20
- */
21
- function isArray(it) {
22
- if (typeof Array.isArray === 'function') return Array.isArray(it);
23
- return Object.prototype.toString.call(it) === '[object Array]';
24
- }
25
-
26
- /**
27
- * Translates text to the target language. Automatically chooses the right translation API.
28
- * @param {string} text The text to translate
29
- * @param {string} targetLang The target languate
30
- * @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
31
- * @returns {Promise<string>}
32
- */
33
- async function translateText(text, targetLang, yandexApiKey) {
34
- if (targetLang === 'en') {
35
- return text;
36
- } else if (!text) {
37
- return '';
38
- }
39
- if (yandexApiKey) {
40
- return translateYandex(text, targetLang, yandexApiKey);
41
- } else {
42
- return translateGoogle(text, targetLang);
43
- }
44
- }
45
-
46
- /**
47
- * Translates text with Yandex API
48
- * @param {string} text The text to translate
49
- * @param {string} targetLang The target languate
50
- * @param {string} apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers
51
- * @returns {Promise<string>}
52
- */
53
- async function translateYandex(text, targetLang, apiKey) {
54
- if (targetLang === 'zh-cn') {
55
- targetLang = 'zh';
56
- }
57
- try {
58
- const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
59
- const response = await axios({url, timeout: 15000});
60
- if (response.data && response.data.text && isArray(response.data.text)) {
61
- return response.data.text[0];
62
- }
63
- throw new Error('Invalid response for translate request');
64
- } catch (e) {
65
- throw new Error(`Could not translate to "${targetLang}": ${e}`);
66
- }
67
- }
68
-
69
- /**
70
- * Translates text with Google API
71
- * @param {string} text The text to translate
72
- * @param {string} targetLang The target languate
73
- * @returns {Promise<string>}
74
- */
75
- async function translateGoogle(text, targetLang) {
76
- try {
77
- const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
78
- const response = await axios({url, timeout: 15000});
79
- if (isArray(response.data)) {
80
- // we got a valid response
81
- return response.data[0][0][0];
82
- }
83
- throw new Error('Invalid response for translate request');
84
- } catch (e) {
85
- if (e.response && e.response.status === 429) {
86
- throw new Error(
87
- `Could not translate to "${targetLang}": Rate-limited by Google Translate`
88
- );
89
- } else {
90
- throw new Error(`Could not translate to "${targetLang}": ${e}`);
91
- }
92
- }
93
- }
94
-
95
- module.exports = {
96
- isArray,
97
- isObject,
98
- translateText
99
- };
1
+ const axios = require('axios').default;
2
+
3
+ /**
4
+ * Tests whether the given variable is a real object and not an Array
5
+ * @param {any} it The variable to test
6
+ * @returns {it is Record<string, any>}
7
+ */
8
+ function isObject(it) {
9
+ // This is necessary because:
10
+ // typeof null === 'object'
11
+ // typeof [] === 'object'
12
+ // [] instanceof Object === true
13
+ return Object.prototype.toString.call(it) === '[object Object]';
14
+ }
15
+
16
+ /**
17
+ * Tests whether the given variable is really an Array
18
+ * @param {any} it The variable to test
19
+ * @returns {it is any[]}
20
+ */
21
+ function isArray(it) {
22
+ if (typeof Array.isArray === 'function') return Array.isArray(it);
23
+ return Object.prototype.toString.call(it) === '[object Array]';
24
+ }
25
+
26
+ /**
27
+ * Translates text to the target language. Automatically chooses the right translation API.
28
+ * @param {string} text The text to translate
29
+ * @param {string} targetLang The target languate
30
+ * @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
31
+ * @returns {Promise<string>}
32
+ */
33
+ async function translateText(text, targetLang, yandexApiKey) {
34
+ if (targetLang === 'en') {
35
+ return text;
36
+ } else if (!text) {
37
+ return '';
38
+ }
39
+ if (yandexApiKey) {
40
+ return translateYandex(text, targetLang, yandexApiKey);
41
+ } else {
42
+ return translateGoogle(text, targetLang);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Translates text with Yandex API
48
+ * @param {string} text The text to translate
49
+ * @param {string} targetLang The target languate
50
+ * @param {string} apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers
51
+ * @returns {Promise<string>}
52
+ */
53
+ async function translateYandex(text, targetLang, apiKey) {
54
+ if (targetLang === 'zh-cn') {
55
+ targetLang = 'zh';
56
+ }
57
+ try {
58
+ const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
59
+ const response = await axios({url, timeout: 15000});
60
+ if (response.data && response.data.text && isArray(response.data.text)) {
61
+ return response.data.text[0];
62
+ }
63
+ throw new Error('Invalid response for translate request');
64
+ } catch (e) {
65
+ throw new Error(`Could not translate to "${targetLang}": ${e}`);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Translates text with Google API
71
+ * @param {string} text The text to translate
72
+ * @param {string} targetLang The target languate
73
+ * @returns {Promise<string>}
74
+ */
75
+ async function translateGoogle(text, targetLang) {
76
+ try {
77
+ const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
78
+ const response = await axios({url, timeout: 15000});
79
+ if (isArray(response.data)) {
80
+ // we got a valid response
81
+ return response.data[0][0][0];
82
+ }
83
+ throw new Error('Invalid response for translate request');
84
+ } catch (e) {
85
+ if (e.response && e.response.status === 429) {
86
+ throw new Error(
87
+ `Could not translate to "${targetLang}": Rate-limited by Google Translate`
88
+ );
89
+ } else {
90
+ throw new Error(`Could not translate to "${targetLang}": ${e}`);
91
+ }
92
+ }
93
+ }
94
+
95
+ module.exports = {
96
+ isArray,
97
+ isObject,
98
+ translateText
99
+ };
package/main.js CHANGED
@@ -1,93 +1,93 @@
1
- /* jshint -W097 */
2
- /* jshint strict:true */
3
- /* jslint node: true */
4
- /* jslint esversion: 6 */
5
-
6
- /**
7
- *
8
- * ioBroker sonoff Adapter
9
- *
10
- * (c) 2017-2021 bluefox
11
- *
12
- * MIT License
13
- *
14
- */
15
- 'use strict';
16
-
17
- const utils = require('@iobroker/adapter-core'); // Get common adapter utils
18
- const adapterName = require('./package.json').name.split('.').pop();
19
- const Server = require('./lib/server');
20
- let server = null;
21
- let adapter;
22
-
23
- function decrypt(key, value) {
24
- let result = '';
25
- for (let i = 0; i < value.length; ++i) {
26
- result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
27
- }
28
- return result;
29
- }
30
-
31
- function startAdapter(options) {
32
- options = options || {};
33
- Object.assign(options, {name: adapterName});
34
-
35
- adapter = new utils.Adapter(options);
36
-
37
- adapter.on('ready', () => {
38
- // it must be like this
39
-
40
- adapter.getForeignObject('system.config', (err, obj) => {
41
- if (obj && obj.native && obj.native.secret) {
42
- //noinspection JSUnresolvedVariable
43
- adapter.config.pass = decrypt(obj.native.secret, adapter.config.pass);
44
- } else {
45
- //noinspection JSUnresolvedVariable
46
- adapter.config.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.pass);
47
- }
48
- main();
49
- });
50
- });
51
-
52
- adapter.on('unload', cb => {
53
- if (server) {
54
- server.destroy(cb);
55
- server = null;
56
- } else if (typeof cb === 'function') {
57
- cb();
58
- }
59
- });
60
-
61
- // is called if a subscribed state changes
62
- adapter.on('stateChange', (id, state) => {
63
- adapter.log.debug(`stateChange ${id}: ${JSON.stringify(state)}`);
64
- // you can use the ack flag to detect if state is desired or acknowledged
65
- state && !state.ack && server && server.onStateChange(id, state);
66
- });
67
- return adapter;
68
- }
69
-
70
- function main() {
71
- adapter.config.TELE_SENSOR = adapter.config.TELE_SENSOR === true || adapter.config.TELE_SENSOR === 'true';
72
- adapter.config.TELE_STATE = adapter.config.TELE_STATE === true || adapter.config.TELE_STATE === 'true';
73
- adapter.config.STAT_RESULT = adapter.config.STAT_RESULT === true || adapter.config.STAT_RESULT === 'true';
74
- adapter.config.OBJ_TREE = adapter.config.OBJ_TREE === true || adapter.config.OBJ_TREE === 'true';
75
-
76
- // subscribe for all own variables
77
- adapter.subscribeStates('*');
78
-
79
- // read all states and set alive to false
80
- adapter.getStatesOf('', '', (err, states) =>
81
- states && states.length && states.forEach(state =>
82
- state._id.match(/\.alive$/) && adapter.setForeignState(state._id, false, true)));
83
-
84
- server = new Server(adapter);
85
- }
86
-
87
- // If started as allInOne/compact mode => return function to create instance
88
- if (module && module.parent) {
89
- module.exports = startAdapter;
90
- } else {
91
- // or start the instance directly
92
- startAdapter();
93
- }
1
+ /* jshint -W097 */
2
+ /* jshint strict:true */
3
+ /* jslint node: true */
4
+ /* jslint esversion: 6 */
5
+
6
+ /**
7
+ *
8
+ * ioBroker sonoff Adapter
9
+ *
10
+ * (c) 2017-2023 bluefox
11
+ *
12
+ * MIT License
13
+ *
14
+ */
15
+ 'use strict';
16
+
17
+ const utils = require('@iobroker/adapter-core'); // Get common adapter utils
18
+ const adapterName = require('./package.json').name.split('.').pop();
19
+ const Server = require('./lib/server');
20
+ let server = null;
21
+ let adapter;
22
+
23
+ function decrypt(key, value) {
24
+ let result = '';
25
+ for (let i = 0; i < value.length; ++i) {
26
+ result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
27
+ }
28
+ return result;
29
+ }
30
+
31
+ function startAdapter(options) {
32
+ options = options || {};
33
+ Object.assign(options, {name: adapterName});
34
+
35
+ adapter = new utils.Adapter(options);
36
+
37
+ adapter.on('ready', () => {
38
+ // it must be like this
39
+
40
+ adapter.getForeignObject('system.config', (err, obj) => {
41
+ if (obj && obj.native && obj.native.secret) {
42
+ //noinspection JSUnresolvedVariable
43
+ adapter.config.pass = decrypt(obj.native.secret, adapter.config.pass);
44
+ } else {
45
+ //noinspection JSUnresolvedVariable
46
+ adapter.config.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.pass);
47
+ }
48
+ main();
49
+ });
50
+ });
51
+
52
+ adapter.on('unload', cb => {
53
+ if (server) {
54
+ server.destroy(cb);
55
+ server = null;
56
+ } else if (typeof cb === 'function') {
57
+ cb();
58
+ }
59
+ });
60
+
61
+ // is called if a subscribed state changes
62
+ adapter.on('stateChange', (id, state) => {
63
+ adapter.log.debug(`stateChange ${id}: ${JSON.stringify(state)}`);
64
+ // you can use the ack flag to detect if state is desired or acknowledged
65
+ state && !state.ack && server && server.onStateChange(id, state);
66
+ });
67
+ return adapter;
68
+ }
69
+
70
+ function main() {
71
+ adapter.config.TELE_SENSOR = adapter.config.TELE_SENSOR === true || adapter.config.TELE_SENSOR === 'true';
72
+ adapter.config.TELE_STATE = adapter.config.TELE_STATE === true || adapter.config.TELE_STATE === 'true';
73
+ adapter.config.STAT_RESULT = adapter.config.STAT_RESULT === true || adapter.config.STAT_RESULT === 'true';
74
+ adapter.config.OBJ_TREE = adapter.config.OBJ_TREE === true || adapter.config.OBJ_TREE === 'true';
75
+
76
+ // subscribe for all own variables
77
+ adapter.subscribeStates('*');
78
+
79
+ // read all states and set alive to false
80
+ adapter.getStatesOf('', '', (err, states) =>
81
+ states && states.length && states.forEach(state =>
82
+ state._id.match(/\.alive$/) && adapter.setForeignState(state._id, false, true)));
83
+
84
+ server = new Server(adapter);
85
+ }
86
+
87
+ // If started as allInOne/compact mode => return function to create instance
88
+ if (module && module.parent) {
89
+ module.exports = startAdapter;
90
+ } else {
91
+ // or start the instance directly
92
+ startAdapter();
93
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iobroker.sonoff",
3
3
  "description": "The adapter allows to send and receive MQTT messages from ioBroker and to be a broker.",
4
- "version": "2.5.0",
4
+ "version": "2.5.3",
5
5
  "author": "bluefox <dogafox@gmail.com>",
6
6
  "homepage": "https://github.com/ioBroker/ioBroker.sonoff",
7
7
  "repository": {
@@ -17,25 +17,36 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "mqtt-connection": "^4.1.0",
20
- "@iobroker/adapter-core": "^2.6.0"
20
+ "@iobroker/adapter-core": "^2.6.8"
21
21
  },
22
22
  "devDependencies": {
23
- "@alcalzone/release-script": "^3.5.6",
24
- "@alcalzone/release-script-plugin-iobroker": "^3.5.7",
25
- "@alcalzone/release-script-plugin-license": "^3.5.3",
26
- "axios": "^0.26.1",
23
+ "@alcalzone/release-script": "^3.5.9",
24
+ "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
25
+ "@alcalzone/release-script-plugin-license": "^3.5.9",
26
+ "@iobroker/legacy-testing": "^0.1.1",
27
+ "axios": "^1.3.4",
27
28
  "mqtt": "^4.3.7",
28
29
  "gulp": "^4.0.2",
29
- "mocha": "^9.2.2",
30
- "chai": "^4.3.6"
30
+ "mocha": "^10.2.0",
31
+ "chai": "^4.3.7"
31
32
  },
32
33
  "bugs": {
33
34
  "url": "https://github.com/ioBroker/ioBroker.sonoff/issues"
34
35
  },
35
36
  "main": "main.js",
37
+ "files": [
38
+ "main.js",
39
+ "admin/",
40
+ "lib/",
41
+ "io-package.json",
42
+ "LICENSE"
43
+ ],
36
44
  "scripts": {
37
45
  "test": "node node_modules/mocha/bin/mocha --exit",
38
- "release": "release-script"
46
+ "release": "release-script",
47
+ "release-patch": "release-script patch --yes",
48
+ "release-minor": "release-script minor --yes",
49
+ "release-major": "release-script major --yes"
39
50
  },
40
51
  "engines": {
41
52
  "node": ">=4.0.0"
@@ -1,37 +0,0 @@
1
- ---
2
- name: Bug report
3
- about: Something is not working as it should
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
- ---
8
-
9
- **Check if the Bug maybe is with Amazon**
10
- The adapter is using the same API as the Alexa mobile App. This means:
11
- * If you can not do this what you want with the App then the Adapter also can not do it!
12
- * Also if the App can do it please test if the same effect then the bug also happens with the App (e.g. a speak command do not work on a certain device ... can you do a speak via Alexa App? If not - Amazon problem!)
13
-
14
- **Describe the bug**
15
- A clear and concise description of what the bug is. Especially describe what you verified using the Alexa App (see above).
16
-
17
- **To Reproduce**
18
- Steps to reproduce the behavior:
19
- 1. Go to '...'
20
- 2. Click on '...'
21
- 3. Scroll down to '....'
22
- 4. See error
23
-
24
- **Expected behavior**
25
- A clear and concise description of what you expected to happen.
26
-
27
- **Screenshots & Logfiles**
28
- If applicable, add screenshots and logfiles to help explain your problem.
29
-
30
- **Versions:**
31
- - Adapter version: <adapter-version>
32
- - JS-Controller version: <js-controller-version> <!-- determine this with `iobroker -v` on the console -->
33
- - Node version: <node-version> <!-- determine this with `node -v` on the console -->
34
- - Operating system: <os-name>
35
-
36
- **Additional context**
37
- Add any other context about the problem here.
@@ -1,24 +0,0 @@
1
- ---
2
- name: Feature request
3
- about: Suggest an idea for this project
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
- **Consider the Reality**
10
- The adapter is using the same API as the Alexa mobile App. This means:
11
-
12
- If you can not do this what you want with the App then the Adapter also can not do it! Also a feature rewuest most likely will not be possible.
13
-
14
- **Is your feature request related to a problem? Please describe.**
15
- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
16
-
17
- **Describe the solution you'd like**
18
- A clear and concise description of what you want to happen.
19
-
20
- **Describe alternatives you've considered**
21
- A clear and concise description of any alternative solutions or features you've considered.
22
-
23
- **Additional context**
24
- Add any other context or screenshots about the feature request here.
@@ -1,17 +0,0 @@
1
- # Configure here which dependency updates should be merged automatically.
2
- # The recommended configuration is the following:
3
- - match:
4
- # Only merge patches for production dependencies
5
- dependency_type: production
6
- update_type: "semver:patch"
7
- - match:
8
- # Except for security fixes, here we allow minor patches
9
- dependency_type: production
10
- update_type: "security:minor"
11
- - match:
12
- # and development dependencies can have a minor update, too
13
- dependency_type: development
14
- update_type: "semver:minor"
15
-
16
- # The syntax is based on the legacy dependabot v1 automerged_updates syntax, see:
17
- # https://dependabot.com/docs/config-file/#automerged_updates
@@ -1,16 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: github-actions
4
- directory: "/"
5
- schedule:
6
- interval: monthly
7
- time: "04:00"
8
- timezone: Europe/Berlin
9
- - package-ecosystem: npm
10
- directory: "/"
11
- schedule:
12
- interval: monthly
13
- time: "04:00"
14
- timezone: Europe/Berlin
15
- open-pull-requests-limit: 20
16
- versioning-strategy: increase
package/.github/stale.yml DELETED
@@ -1,78 +0,0 @@
1
- # Configuration for probot-stale - https://github.com/probot/stale
2
-
3
- # Number of days of inactivity before an Issue or Pull Request becomes stale
4
- daysUntilStale: 90
5
-
6
- # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
7
- # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
8
- daysUntilClose: 7
9
-
10
- # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
11
- onlyLabels: []
12
-
13
- # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
14
- exemptLabels:
15
- - enhancement
16
- - security
17
-
18
- # Set to true to ignore issues in a project (defaults to false)
19
- exemptProjects: true
20
-
21
- # Set to true to ignore issues in a milestone (defaults to false)
22
- exemptMilestones: true
23
-
24
- # Set to true to ignore issues with an assignee (defaults to false)
25
- exemptAssignees: false
26
-
27
- # Label to use when marking as stale
28
- staleLabel: wontfix
29
-
30
- # Comment to post when marking as stale. Set to `false` to disable
31
- markComment: >
32
- This issue has been automatically marked as stale because it has not had
33
- recent activity. It will be closed if no further activity occurs within the next 7 days.
34
- Please check if the issue is still relevant in the most current version of the adapter
35
- and tell us. Also check that all relevant details, logs and reproduction steps
36
- are included and update them if needed.
37
- Thank you for your contributions.
38
-
39
- Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivitäten gab.
40
- Es wird geschlossen, wenn nicht innerhalb der nächsten 7 Tage weitere Aktivitäten stattfinden.
41
- Bitte überprüft, ob das Problem auch in der aktuellsten Version des Adapters noch relevant ist,
42
- und teilt uns dies mit. Überprüft auch, ob alle relevanten Details, Logs und Reproduktionsschritte
43
- enthalten sind bzw. aktualisiert diese.
44
- Vielen Dank für Eure Unterstützung.
45
-
46
- # Comment to post when removing the stale label.
47
- # unmarkComment: >
48
- # Your comment here.
49
-
50
- # Comment to post when closing a stale Issue or Pull Request.
51
- closeComment: >
52
- This issue has been automatically closed because of inactivity. Please open a new
53
- issue if still relevant and make sure to include all relevant details, logs and
54
- reproduction steps.
55
- Thank you for your contributions.
56
-
57
- Dieses Problem wurde aufgrund von Inaktivität automatisch geschlossen. Bitte öffnet ein
58
- neues Issue, falls dies noch relevant ist und stellt sicher das alle relevanten Details,
59
- Logs und Reproduktionsschritte enthalten sind.
60
- Vielen Dank für Eure Unterstützung.
61
-
62
- # Limit the number of actions per hour, from 1-30. Default is 30
63
- limitPerRun: 30
64
-
65
- # Limit to only `issues` or `pulls`
66
- only: issues
67
-
68
- # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
69
- # pulls:
70
- # daysUntilStale: 30
71
- # markComment: >
72
- # This pull request has been automatically marked as stale because it has not had
73
- # recent activity. It will be closed if no further activity occurs. Thank you
74
- # for your contributions.
75
-
76
- # issues:
77
- # exemptLabels:
78
- # - confirmed
@@ -1,22 +0,0 @@
1
- # Automatically merge Dependabot PRs when version comparison is within the range
2
- # that is configured in .github/auto-merge.yml
3
-
4
- name: Auto-Merge Dependabot PRs
5
-
6
- on:
7
- pull_request_target:
8
-
9
- jobs:
10
- auto-merge:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout code
14
- uses: actions/checkout@v2
15
-
16
- - name: Check if PR should be auto-merged
17
- uses: ahmadnassri/action-dependabot-auto-merge@v2
18
- with:
19
- # This must be a personal access token with push access
20
- github-token: ${{ secrets.AUTO_MERGE_TOKEN }}
21
- # By default, squash and merge, so Github chooses nice commit messages
22
- command: squash and merge