iobroker.panasonic-comfort-cloud 1.2.3 → 1.2.9
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/.github/workflows/test-and-release.yml +59 -0
- package/LICENSE +1 -1
- package/README.md +33 -72
- package/build/lib/tools.js +4 -4
- package/build/main.js +70 -40
- package/io-package.json +28 -2
- package/package.json +2 -2
- package/iob_npm.done +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Test and Release
|
|
2
|
+
|
|
3
|
+
# Run this job on all pushes and pull requests
|
|
4
|
+
# as well as tags with a semantic version
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- "*"
|
|
9
|
+
tags:
|
|
10
|
+
# normal versions
|
|
11
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
12
|
+
# pre-releases
|
|
13
|
+
- "v[0-9]+.[0-9]+.[0-9]+-**"
|
|
14
|
+
pull_request: {}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
# Performs quick checks before the expensive test runs
|
|
18
|
+
check-and-lint:
|
|
19
|
+
if: contains(github.event.head_commit.message, '[skip ci]') == false
|
|
20
|
+
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: ioBroker/testing-action-check@v1
|
|
25
|
+
with:
|
|
26
|
+
node-version: '14.x'
|
|
27
|
+
lint: true
|
|
28
|
+
|
|
29
|
+
adapter-tests:
|
|
30
|
+
if: contains(github.event.head_commit.message, '[skip ci]') == false
|
|
31
|
+
|
|
32
|
+
runs-on: ${{ matrix.os }}
|
|
33
|
+
strategy:
|
|
34
|
+
matrix:
|
|
35
|
+
node-version: [12.x, 14.x, 16.x]
|
|
36
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: ioBroker/testing-action-adapter@v1
|
|
40
|
+
with:
|
|
41
|
+
node-version: ${{ matrix.node-version }}
|
|
42
|
+
os: ${{ matrix.os }}
|
|
43
|
+
|
|
44
|
+
deploy:
|
|
45
|
+
needs: [check-and-lint, adapter-tests]
|
|
46
|
+
|
|
47
|
+
if: |
|
|
48
|
+
contains(github.event.head_commit.message, '[skip ci]') == false &&
|
|
49
|
+
github.event_name == 'push' &&
|
|
50
|
+
startsWith(github.ref, 'refs/tags/v')
|
|
51
|
+
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- uses: ioBroker/testing-action-deploy@v1
|
|
56
|
+
with:
|
|
57
|
+
node-version: '14.x'
|
|
58
|
+
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
59
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 marc <marc@lammers.dev>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -12,85 +12,46 @@
|
|
|
12
12
|
|
|
13
13
|
## panasonic-comfort-cloud adapter for ioBroker
|
|
14
14
|
|
|
15
|
-
Adapter
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
You are almost done, only a few steps left:
|
|
23
|
-
1. Create a new repository on GitHub with the name `ioBroker.panasonic-comfort-cloud`
|
|
24
|
-
1. Initialize the current folder as a new git repository:
|
|
25
|
-
```bash
|
|
26
|
-
git init
|
|
27
|
-
git add .
|
|
28
|
-
git commit -m "Initial commit"
|
|
29
|
-
```
|
|
30
|
-
1. Link your local repository with the one on GitHub:
|
|
31
|
-
```bash
|
|
32
|
-
git remote add origin https://github.com/marc2016/ioBroker.panasonic-comfort-cloud
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
1. Push all files to the GitHub repo:
|
|
36
|
-
```bash
|
|
37
|
-
git push origin master
|
|
38
|
-
```
|
|
39
|
-
1. Head over to [src/main.ts](src/main.ts) and start programming!
|
|
40
|
-
|
|
41
|
-
### Scripts in `package.json`
|
|
42
|
-
Several npm scripts are predefined for your convenience. You can run them using `npm run <scriptname>`
|
|
43
|
-
| Script name | Description |
|
|
44
|
-
|-------------|----------------------------------------------------------|
|
|
45
|
-
| `build` | Re-compile the TypeScript sources. |
|
|
46
|
-
| `watch` | Re-compile the TypeScript sources and watch for changes. |
|
|
47
|
-
| `test:ts` | Executes the tests you defined in `*.test.ts` files. |
|
|
48
|
-
| `test:package` | Ensures your `package.json` and `io-package.json` are valid. |
|
|
49
|
-
| `test:unit` | Tests the adapter startup with unit tests (fast, but might require module mocks to work). |
|
|
50
|
-
| `test:integration`| Tests the adapter startup with an actual instance of ioBroker. |
|
|
51
|
-
| `test` | Performs a minimal test run on package files and your tests. |
|
|
52
|
-
| `coverage` | Generates code coverage using your test files. |
|
|
53
|
-
|
|
54
|
-
### Writing tests
|
|
55
|
-
When done right, testing code is invaluable, because it gives you the
|
|
56
|
-
confidence to change your code while knowing exactly if and when
|
|
57
|
-
something breaks. A good read on the topic of test-driven development
|
|
58
|
-
is https://hackernoon.com/introduction-to-test-driven-development-tdd-61a13bc92d92.
|
|
59
|
-
Although writing tests before the code might seem strange at first, but it has very
|
|
60
|
-
clear upsides.
|
|
61
|
-
|
|
62
|
-
The template provides you with basic tests for the adapter startup and package files.
|
|
63
|
-
It is recommended that you add your own tests into the mix.
|
|
64
|
-
|
|
65
|
-
### Publishing the adapter
|
|
66
|
-
See the documentation of [ioBroker.repositories](https://github.com/ioBroker/ioBroker.repositories#requirements-for-adapter-to-get-added-to-the-latest-repository).
|
|
67
|
-
|
|
68
|
-
### Test the adapter manually on a local ioBroker installation
|
|
69
|
-
In order to install the adapter locally without publishing, the following steps are recommended:
|
|
70
|
-
1. Create a tarball from your dev directory:
|
|
71
|
-
```bash
|
|
72
|
-
npm pack
|
|
73
|
-
```
|
|
74
|
-
1. Upload the resulting file to your ioBroker host
|
|
75
|
-
1. Install it locally (The paths are different on Windows):
|
|
76
|
-
```bash
|
|
77
|
-
cd /opt/iobroker
|
|
78
|
-
npm i /path/to/tarball.tgz
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
For later updates, the above procedure is not necessary. Just do the following:
|
|
82
|
-
1. Overwrite the changed files in the adapter directory (`/opt/iobroker/node_modules/iobroker.panasonic-comfort-cloud`)
|
|
83
|
-
1. Execute `iobroker upload panasonic-comfort-cloud` on the ioBroker host
|
|
15
|
+
Adapter to control devices in the Panasonic Comfort Cloud. It uses REST calls which are extracetd from the official Comfort Cloud app.
|
|
16
|
+
To use the a adpter you need to enter your username and password in the configuration. They are used to authenticate access to the Comfort Cloud. Information of all devices is automatically retrieved and inserted as an object. The adpter polls the device information cyclically (see interval in the settings) and sends commands directly to the cloud.
|
|
17
|
+
|
|
18
|
+
With the method used, only one client can be logged on with the account at a time.
|
|
19
|
+
It is recommended that a second account, for which the devices have been shared, is used.
|
|
20
|
+
|
|
84
21
|
|
|
85
22
|
## Changelog
|
|
86
23
|
|
|
87
|
-
###
|
|
88
|
-
*
|
|
24
|
+
### 1.2.8
|
|
25
|
+
* Fixed bug in Comfort Cloud client.
|
|
26
|
+
|
|
27
|
+
### 1.2.7
|
|
28
|
+
* Comfort Cloud client updated.
|
|
29
|
+
|
|
30
|
+
### 1.2.6
|
|
31
|
+
* Fixed bug that guid is null in device creation.
|
|
32
|
+
|
|
33
|
+
### 1.2.5
|
|
34
|
+
* *Comfort Cloud client updated.
|
|
35
|
+
|
|
36
|
+
### 1.2.4
|
|
37
|
+
* Fixed bug with undefined guid. Log messages added.
|
|
38
|
+
|
|
39
|
+
### 1.2.3
|
|
40
|
+
* Set parameters only for writable states.
|
|
41
|
+
|
|
42
|
+
### 1.2.2
|
|
43
|
+
* *Fixed error handling and added stack info.
|
|
44
|
+
|
|
45
|
+
### 1.2.1
|
|
46
|
+
* Fixed bug in refesh device method.
|
|
47
|
+
|
|
48
|
+
### 1.2.0
|
|
49
|
+
* States insideTemperature, outTemperature and Nanoe added.
|
|
89
50
|
|
|
90
51
|
## License
|
|
91
52
|
MIT License
|
|
92
53
|
|
|
93
|
-
Copyright (c)
|
|
54
|
+
Copyright (c) 2021 marc <marc@lammers.dev>
|
|
94
55
|
|
|
95
56
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
96
57
|
of this software and associated documentation files (the "Software"), to deal
|
package/build/lib/tools.js
CHANGED
|
@@ -19,7 +19,7 @@ function isObject(it) {
|
|
|
19
19
|
// typeof null === 'object'
|
|
20
20
|
// typeof [] === 'object'
|
|
21
21
|
// [] instanceof Object === true
|
|
22
|
-
return Object.prototype.toString.call(it) ===
|
|
22
|
+
return Object.prototype.toString.call(it) === '[object Object]';
|
|
23
23
|
}
|
|
24
24
|
exports.isObject = isObject;
|
|
25
25
|
/**
|
|
@@ -29,7 +29,7 @@ exports.isObject = isObject;
|
|
|
29
29
|
function isArray(it) {
|
|
30
30
|
if (Array.isArray != null)
|
|
31
31
|
return Array.isArray(it);
|
|
32
|
-
return Object.prototype.toString.call(it) ===
|
|
32
|
+
return Object.prototype.toString.call(it) === '[object Array]';
|
|
33
33
|
}
|
|
34
34
|
exports.isArray = isArray;
|
|
35
35
|
/**
|
|
@@ -39,7 +39,7 @@ exports.isArray = isArray;
|
|
|
39
39
|
*/
|
|
40
40
|
function translateText(text, targetLang) {
|
|
41
41
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
if (targetLang ===
|
|
42
|
+
if (targetLang === 'en')
|
|
43
43
|
return text;
|
|
44
44
|
try {
|
|
45
45
|
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`;
|
|
@@ -48,7 +48,7 @@ function translateText(text, targetLang) {
|
|
|
48
48
|
// we got a valid response
|
|
49
49
|
return response.data[0][0][0];
|
|
50
50
|
}
|
|
51
|
-
throw new Error(
|
|
51
|
+
throw new Error('Invalid response for translate request');
|
|
52
52
|
}
|
|
53
53
|
catch (e) {
|
|
54
54
|
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
package/build/main.js
CHANGED
|
@@ -21,12 +21,12 @@ const _ = require("lodash");
|
|
|
21
21
|
const comfortCloudClient = new panasonic_comfort_cloud_client_1.ComfortCloudClient();
|
|
22
22
|
class PanasonicComfortCloud extends utils.Adapter {
|
|
23
23
|
constructor(options = {}) {
|
|
24
|
-
super(Object.assign(Object.assign({}, options), { name:
|
|
25
|
-
this.on(
|
|
26
|
-
this.on(
|
|
27
|
-
this.on(
|
|
24
|
+
super(Object.assign(Object.assign({}, options), { name: 'panasonic-comfort-cloud' }));
|
|
25
|
+
this.on('ready', this.onReady.bind(this));
|
|
26
|
+
this.on('objectChange', this.onObjectChange.bind(this));
|
|
27
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
28
28
|
// this.on('message', this.onMessage.bind(this));
|
|
29
|
-
this.on(
|
|
29
|
+
this.on('unload', this.onUnload.bind(this));
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* Is called when databases are connected and adapter received configuration.
|
|
@@ -36,12 +36,12 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
36
36
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
const refreshInterval = (_a = this.config.refreshInterval) !== null && _a !== void 0 ? _a : 5;
|
|
38
38
|
this.refreshJob = node_schedule_1.scheduleJob(`*/${refreshInterval} * * * *`, this.refreshDevices.bind(this));
|
|
39
|
-
this.subscribeStates(
|
|
39
|
+
this.subscribeStates('*');
|
|
40
40
|
try {
|
|
41
41
|
this.log.debug(`Try to login with username ${this.config.username}.`);
|
|
42
42
|
yield comfortCloudClient.login(this.config.username, this.config.password);
|
|
43
|
-
this.log.info(
|
|
44
|
-
this.log.debug(
|
|
43
|
+
this.log.info('Login successful.');
|
|
44
|
+
this.log.debug('Create devices.');
|
|
45
45
|
const groups = yield comfortCloudClient.getGroups();
|
|
46
46
|
this.createDevices(groups);
|
|
47
47
|
}
|
|
@@ -51,18 +51,30 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
refreshDeviceStates(device) {
|
|
54
|
-
this.log.debug(`Refresh device ${device.name}
|
|
54
|
+
this.log.debug(`Refresh device ${device.name} (${device.guid}).`);
|
|
55
|
+
this.log.debug(`${device.name}: guid => ${device.guid}.`);
|
|
55
56
|
this.setStateChangedAsync(`${device.name}.guid`, device.guid, true);
|
|
57
|
+
this.log.debug(`${device.name}: operate => ${device.operate}.`);
|
|
56
58
|
this.setStateChangedAsync(`${device.name}.operate`, device.operate, true);
|
|
59
|
+
this.log.debug(`${device.name}: temperatureSet => ${device.temperatureSet}.`);
|
|
57
60
|
this.setStateChangedAsync(`${device.name}.temperatureSet`, device.temperatureSet, true);
|
|
61
|
+
this.log.debug(`${device.name}: insideTemperature => ${device.insideTemperature}.`);
|
|
58
62
|
this.setStateChangedAsync(`${device.name}.insideTemperature`, device.insideTemperature, true);
|
|
63
|
+
this.log.debug(`${device.name}: outTemperature => ${device.outTemperature}.`);
|
|
59
64
|
this.setStateChangedAsync(`${device.name}.outTemperature`, device.outTemperature, true);
|
|
65
|
+
this.log.debug(`${device.name}: airSwingLR => ${device.airSwingLR}.`);
|
|
60
66
|
this.setStateChangedAsync(`${device.name}.airSwingLR`, device.airSwingLR, true);
|
|
67
|
+
this.log.debug(`${device.name}: airSwingUD => ${device.airSwingUD}.`);
|
|
61
68
|
this.setStateChangedAsync(`${device.name}.airSwingUD`, device.airSwingUD, true);
|
|
69
|
+
this.log.debug(`${device.name}: fanAutoMode => ${device.fanAutoMode}.`);
|
|
62
70
|
this.setStateChangedAsync(`${device.name}.fanAutoMode`, device.fanAutoMode, true);
|
|
71
|
+
this.log.debug(`${device.name}: ecoMode => ${device.ecoMode}.`);
|
|
63
72
|
this.setStateChangedAsync(`${device.name}.ecoMode`, device.ecoMode, true);
|
|
73
|
+
this.log.debug(`${device.name}: operationMode => ${device.operationMode}.`);
|
|
64
74
|
this.setStateChangedAsync(`${device.name}.operationMode`, device.operationMode, true);
|
|
75
|
+
this.log.debug(`${device.name}: fanSpeed => ${device.fanSpeed}.`);
|
|
65
76
|
this.setStateChangedAsync(`${device.name}.fanSpeed`, device.fanSpeed, true);
|
|
77
|
+
this.log.debug(`${device.name}: actualNanoe => ${device.actualNanoe}.`);
|
|
66
78
|
this.setStateChangedAsync(`${device.name}.actualNanoe`, device.actualNanoe, true);
|
|
67
79
|
this.log.debug(`Refresh device ${device.name} finished.`);
|
|
68
80
|
}
|
|
@@ -86,7 +98,7 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
86
98
|
refreshDevices() {
|
|
87
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
100
|
try {
|
|
89
|
-
this.log.debug(
|
|
101
|
+
this.log.debug('Refresh all devices.');
|
|
90
102
|
const groups = yield comfortCloudClient.getGroups();
|
|
91
103
|
const devices = _.flatMap(groups, g => g.devices);
|
|
92
104
|
const deviceInfos = _.map(devices, d => { return { guid: d.guid, name: d.name }; });
|
|
@@ -94,6 +106,7 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
94
106
|
const device = yield comfortCloudClient.getDevice(deviceInfo.guid);
|
|
95
107
|
if (device != null) {
|
|
96
108
|
device.name = deviceInfo.name;
|
|
109
|
+
device.guid = deviceInfo.guid;
|
|
97
110
|
this.refreshDeviceStates(device);
|
|
98
111
|
}
|
|
99
112
|
})));
|
|
@@ -113,36 +126,46 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
113
126
|
const deviceInfos = _.map(devicesFromService, d => { return { guid: d.guid, name: d.name }; });
|
|
114
127
|
yield Promise.all(deviceInfos.map((deviceInfo) => __awaiter(this, void 0, void 0, function* () {
|
|
115
128
|
this.log.debug(`Device info from group ${deviceInfo.guid}, ${deviceInfo.name}.`);
|
|
116
|
-
|
|
129
|
+
let device = null;
|
|
130
|
+
try {
|
|
131
|
+
device = yield comfortCloudClient.getDevice(deviceInfo.guid);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
this.handleClientError(error);
|
|
135
|
+
}
|
|
117
136
|
if (device != null) {
|
|
118
137
|
if (_.includes(names, deviceInfo.name)) {
|
|
119
138
|
return;
|
|
120
139
|
}
|
|
121
140
|
this.createDevice(deviceInfo.name);
|
|
122
|
-
this.createState(deviceInfo.name,
|
|
123
|
-
this.createState(deviceInfo.name,
|
|
124
|
-
role:
|
|
141
|
+
this.createState(deviceInfo.name, '', 'guid', { role: 'text', write: false, def: deviceInfo.guid, type: 'string' }, undefined);
|
|
142
|
+
this.createState(deviceInfo.name, '', 'operate', {
|
|
143
|
+
role: 'state',
|
|
125
144
|
states: { 0: panasonic_comfort_cloud_client_1.Power[0], 1: panasonic_comfort_cloud_client_1.Power[1] },
|
|
126
145
|
write: true,
|
|
127
146
|
def: device.operate,
|
|
147
|
+
type: 'array',
|
|
128
148
|
}, undefined);
|
|
129
|
-
this.createState(deviceInfo.name,
|
|
130
|
-
role:
|
|
149
|
+
this.createState(deviceInfo.name, '', 'temperatureSet', {
|
|
150
|
+
role: 'level.temperature',
|
|
131
151
|
write: true,
|
|
132
152
|
def: device.temperatureSet,
|
|
153
|
+
type: 'number',
|
|
133
154
|
}, undefined);
|
|
134
|
-
this.createState(deviceInfo.name,
|
|
135
|
-
role:
|
|
155
|
+
this.createState(deviceInfo.name, '', 'insideTemperature', {
|
|
156
|
+
role: 'state',
|
|
136
157
|
write: false,
|
|
137
158
|
def: device.insideTemperature,
|
|
159
|
+
type: 'number',
|
|
138
160
|
}, undefined);
|
|
139
|
-
this.createState(deviceInfo.name,
|
|
140
|
-
role:
|
|
161
|
+
this.createState(deviceInfo.name, '', 'outTemperature', {
|
|
162
|
+
role: 'state',
|
|
141
163
|
write: false,
|
|
142
164
|
def: device.outTemperature,
|
|
165
|
+
type: 'number',
|
|
143
166
|
}, undefined);
|
|
144
|
-
this.createState(deviceInfo.name,
|
|
145
|
-
role:
|
|
167
|
+
this.createState(deviceInfo.name, '', 'airSwingLR', {
|
|
168
|
+
role: 'state',
|
|
146
169
|
states: {
|
|
147
170
|
0: panasonic_comfort_cloud_client_1.AirSwingLR[0],
|
|
148
171
|
1: panasonic_comfort_cloud_client_1.AirSwingLR[1],
|
|
@@ -152,9 +175,10 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
152
175
|
},
|
|
153
176
|
write: true,
|
|
154
177
|
def: device.airSwingLR,
|
|
178
|
+
type: 'array',
|
|
155
179
|
}, undefined);
|
|
156
|
-
this.createState(deviceInfo.name,
|
|
157
|
-
role:
|
|
180
|
+
this.createState(deviceInfo.name, '', 'airSwingUD', {
|
|
181
|
+
role: 'state',
|
|
158
182
|
states: {
|
|
159
183
|
0: panasonic_comfort_cloud_client_1.AirSwingUD[0],
|
|
160
184
|
1: panasonic_comfort_cloud_client_1.AirSwingUD[1],
|
|
@@ -164,9 +188,10 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
164
188
|
},
|
|
165
189
|
write: true,
|
|
166
190
|
def: device.airSwingUD,
|
|
191
|
+
type: 'array',
|
|
167
192
|
}, undefined);
|
|
168
|
-
this.createState(deviceInfo.name,
|
|
169
|
-
role:
|
|
193
|
+
this.createState(deviceInfo.name, '', 'fanAutoMode', {
|
|
194
|
+
role: 'state',
|
|
170
195
|
states: {
|
|
171
196
|
0: panasonic_comfort_cloud_client_1.FanAutoMode[0],
|
|
172
197
|
1: panasonic_comfort_cloud_client_1.FanAutoMode[1],
|
|
@@ -175,15 +200,17 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
175
200
|
},
|
|
176
201
|
write: true,
|
|
177
202
|
def: device.fanAutoMode,
|
|
203
|
+
type: 'array',
|
|
178
204
|
}, undefined);
|
|
179
|
-
this.createState(deviceInfo.name,
|
|
180
|
-
role:
|
|
205
|
+
this.createState(deviceInfo.name, '', 'ecoMode', {
|
|
206
|
+
role: 'state',
|
|
181
207
|
states: { 0: panasonic_comfort_cloud_client_1.EcoMode[0], 1: panasonic_comfort_cloud_client_1.EcoMode[1], 2: panasonic_comfort_cloud_client_1.EcoMode[2] },
|
|
182
208
|
write: true,
|
|
183
209
|
def: device.ecoMode,
|
|
210
|
+
type: 'array',
|
|
184
211
|
}, undefined);
|
|
185
|
-
this.createState(deviceInfo.name,
|
|
186
|
-
role:
|
|
212
|
+
this.createState(deviceInfo.name, '', 'operationMode', {
|
|
213
|
+
role: 'state',
|
|
187
214
|
states: {
|
|
188
215
|
0: panasonic_comfort_cloud_client_1.OperationMode[0],
|
|
189
216
|
1: panasonic_comfort_cloud_client_1.OperationMode[1],
|
|
@@ -193,9 +220,10 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
193
220
|
},
|
|
194
221
|
write: true,
|
|
195
222
|
def: device.operationMode,
|
|
223
|
+
type: 'array',
|
|
196
224
|
}, undefined);
|
|
197
|
-
this.createState(deviceInfo.name,
|
|
198
|
-
role:
|
|
225
|
+
this.createState(deviceInfo.name, '', 'fanSpeed', {
|
|
226
|
+
role: 'state',
|
|
199
227
|
states: {
|
|
200
228
|
0: panasonic_comfort_cloud_client_1.FanSpeed[0],
|
|
201
229
|
1: panasonic_comfort_cloud_client_1.FanSpeed[1],
|
|
@@ -206,9 +234,10 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
206
234
|
},
|
|
207
235
|
write: true,
|
|
208
236
|
def: device.fanSpeed,
|
|
237
|
+
type: 'array',
|
|
209
238
|
}, undefined);
|
|
210
|
-
this.createState(deviceInfo.name,
|
|
211
|
-
role:
|
|
239
|
+
this.createState(deviceInfo.name, '', 'actualNanoe', {
|
|
240
|
+
role: 'state',
|
|
212
241
|
states: {
|
|
213
242
|
0: panasonic_comfort_cloud_client_1.NanoeMode[0],
|
|
214
243
|
1: panasonic_comfort_cloud_client_1.NanoeMode[1],
|
|
@@ -218,11 +247,12 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
218
247
|
},
|
|
219
248
|
write: true,
|
|
220
249
|
def: device.actualNanoe,
|
|
250
|
+
type: 'array',
|
|
221
251
|
}, undefined);
|
|
222
252
|
this.log.info(`Device ${deviceInfo.name} created.`);
|
|
223
253
|
}
|
|
224
254
|
})));
|
|
225
|
-
this.log.debug(
|
|
255
|
+
this.log.debug('Device creation completed.');
|
|
226
256
|
});
|
|
227
257
|
}
|
|
228
258
|
updateDevice(deviceName, stateName, state) {
|
|
@@ -261,7 +291,7 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
261
291
|
onUnload(callback) {
|
|
262
292
|
var _a;
|
|
263
293
|
try {
|
|
264
|
-
this.log.info(
|
|
294
|
+
this.log.info('cleaned everything up...');
|
|
265
295
|
(_a = this.refreshJob) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
266
296
|
callback();
|
|
267
297
|
}
|
|
@@ -287,7 +317,7 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
287
317
|
*/
|
|
288
318
|
onStateChange(id, state) {
|
|
289
319
|
if (state) {
|
|
290
|
-
const elements = id.split(
|
|
320
|
+
const elements = id.split('.');
|
|
291
321
|
const deviceName = elements[elements.length - 2];
|
|
292
322
|
const stateName = elements[elements.length - 1];
|
|
293
323
|
this.updateDevice(deviceName, stateName, state);
|
|
@@ -301,16 +331,16 @@ class PanasonicComfortCloud extends utils.Adapter {
|
|
|
301
331
|
}
|
|
302
332
|
handleClientError(error) {
|
|
303
333
|
return __awaiter(this, void 0, void 0, function* () {
|
|
304
|
-
this.log.debug(
|
|
334
|
+
this.log.debug('Try to handle error.');
|
|
305
335
|
if (error instanceof panasonic_comfort_cloud_client_1.TokenExpiredError) {
|
|
306
336
|
this.log.info(`Token of comfort cloud client expired. Trying to login again. Code=${error.code}. Stack: ${error.stack}`);
|
|
307
337
|
yield comfortCloudClient.login(this.config.username, this.config.password);
|
|
308
|
-
this.log.info(
|
|
338
|
+
this.log.info('Login successful.');
|
|
309
339
|
}
|
|
310
340
|
else if (error instanceof panasonic_comfort_cloud_client_1.ServiceError) {
|
|
311
341
|
this.log.error(`Service error: ${error.message}. Code=${error.code}. Stack: ${error.stack}`);
|
|
312
342
|
}
|
|
313
|
-
else {
|
|
343
|
+
else if (error instanceof Error) {
|
|
314
344
|
this.log.error(`Unknown error: ${error}. Stack: ${error.stack}`);
|
|
315
345
|
}
|
|
316
346
|
});
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "panasonic-comfort-cloud",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.9",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.2.9": {
|
|
7
|
+
"en": "Error handling for get device added.",
|
|
8
|
+
"de": "Fehlerbehandlung beim Abrufen des Geräts hinzugefügt."
|
|
9
|
+
},
|
|
10
|
+
"1.2.8": {
|
|
11
|
+
"en": "Fixed bug in Comfort Cloud client.",
|
|
12
|
+
"de": "Fehler in Comfort Cloud client behoben."
|
|
13
|
+
},
|
|
14
|
+
"1.2.7": {
|
|
15
|
+
"en": "Comfort Cloud client updated.",
|
|
16
|
+
"de": "Comfort Cloud client aktualisiert."
|
|
17
|
+
},
|
|
18
|
+
"1.2.6": {
|
|
19
|
+
"en": "Fixed bug that guid is null in device creation.",
|
|
20
|
+
"de": "Fehler behoben, dass die GUID bei der Geräteerstellung null ist."
|
|
21
|
+
},
|
|
22
|
+
"1.2.5": {
|
|
23
|
+
"en": "Comfort Cloud client updated.",
|
|
24
|
+
"de": "Comfort Cloud client aktualisiert."
|
|
25
|
+
},
|
|
26
|
+
"1.2.4": {
|
|
27
|
+
"en": "Fixed bug with undefined guid. Log messages added.",
|
|
28
|
+
"de": "Problem mit undefinierter guid behoben. Log Ausgaben hinzugefügt."
|
|
29
|
+
},
|
|
6
30
|
"1.2.3": {
|
|
7
31
|
"en": "Set parameters only for writable states.",
|
|
8
32
|
"de": "Parameter werden nur noch für beschreibbare States übertragen."
|
|
@@ -77,6 +101,8 @@
|
|
|
77
101
|
"keywords": ["air condition"],
|
|
78
102
|
"license": "MIT",
|
|
79
103
|
"platform": "Javascript/Node.js",
|
|
104
|
+
"connectionType": "cloud",
|
|
105
|
+
"dataSource": "poll",
|
|
80
106
|
"main": "build/main.js",
|
|
81
107
|
"icon": "panasonic-comfort-cloud.png",
|
|
82
108
|
"enabled": true,
|
|
@@ -89,7 +115,7 @@
|
|
|
89
115
|
"materialize": true,
|
|
90
116
|
"dependencies": [
|
|
91
117
|
{
|
|
92
|
-
"js-controller": ">=1.
|
|
118
|
+
"js-controller": ">=1.5.8"
|
|
93
119
|
}
|
|
94
120
|
]
|
|
95
121
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.panasonic-comfort-cloud",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "Adapter for Panasonic Comfort Cloud",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "marc",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@types/node-schedule": "^1.3.0",
|
|
22
22
|
"lodash": "^4.17.15",
|
|
23
23
|
"node-schedule": "^1.3.2",
|
|
24
|
-
"panasonic-comfort-cloud-client": "^1.1.
|
|
24
|
+
"panasonic-comfort-cloud-client": "^1.1.4",
|
|
25
25
|
"ts-enum-util": "^4.0.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
package/iob_npm.done
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|