iobroker.airzone 2.0.2 → 3.0.0
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/ISSUE_TEMPLATE/bug_report.md +32 -32
- package/CHANGELOG.md +7 -0
- package/LocalApi/AirzoneLocalApi.js +94 -25
- package/LocalApi/Constants.js +53 -9
- package/LocalApi/IAQSensor.js +123 -0
- package/LocalApi/System.js +37 -38
- package/LocalApi/Zone.js +164 -18
- package/README.md +20 -0
- package/Utils/asyncRequest.js +118 -75
- package/eslint.config.js +30 -0
- package/io-package.json +53 -6
- package/main.js +62 -41
- package/main.test.js +13 -13
- package/package.json +41 -42
- package/test-integration.js +144 -0
- package/test-standalone.js +114 -0
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report
|
|
3
|
-
about: Something is not working as it should
|
|
4
|
-
title: ''
|
|
5
|
-
labels: ''
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
**Describe the bug**
|
|
10
|
-
A clear and concise description of what the bug is.
|
|
11
|
-
|
|
12
|
-
**To Reproduce**
|
|
13
|
-
Steps to reproduce the behavior:
|
|
14
|
-
1. Go to '...'
|
|
15
|
-
2. Click on '...'
|
|
16
|
-
3. Scroll down to '....'
|
|
17
|
-
4. See error
|
|
18
|
-
|
|
19
|
-
**Expected behavior**
|
|
20
|
-
A clear and concise description of what you expected to happen.
|
|
21
|
-
|
|
22
|
-
**Screenshots & Logfiles**
|
|
23
|
-
If applicable, add screenshots and logfiles to help explain your problem.
|
|
24
|
-
|
|
25
|
-
**Versions:**
|
|
26
|
-
- Adapter version: <adapter-version>
|
|
27
|
-
- JS-Controller version: <js-controller-version> <!-- determine this with `iobroker -v` on the console -->
|
|
28
|
-
- Node version: <node-version> <!-- determine this with `node -v` on the console -->
|
|
29
|
-
- Operating system: <os-name>
|
|
30
|
-
|
|
31
|
-
**Additional context**
|
|
32
|
-
Add any other context about the problem here.
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something is not working as it should
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**Describe the bug**
|
|
10
|
+
A clear and concise description of what the bug is.
|
|
11
|
+
|
|
12
|
+
**To Reproduce**
|
|
13
|
+
Steps to reproduce the behavior:
|
|
14
|
+
1. Go to '...'
|
|
15
|
+
2. Click on '...'
|
|
16
|
+
3. Scroll down to '....'
|
|
17
|
+
4. See error
|
|
18
|
+
|
|
19
|
+
**Expected behavior**
|
|
20
|
+
A clear and concise description of what you expected to happen.
|
|
21
|
+
|
|
22
|
+
**Screenshots & Logfiles**
|
|
23
|
+
If applicable, add screenshots and logfiles to help explain your problem.
|
|
24
|
+
|
|
25
|
+
**Versions:**
|
|
26
|
+
- Adapter version: <adapter-version>
|
|
27
|
+
- JS-Controller version: <js-controller-version> <!-- determine this with `iobroker -v` on the console -->
|
|
28
|
+
- Node version: <node-version> <!-- determine this with `node -v` on the console -->
|
|
29
|
+
- Operating system: <os-name>
|
|
30
|
+
|
|
31
|
+
**Additional context**
|
|
32
|
+
Add any other context about the problem here.
|
package/CHANGELOG.md
ADDED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const AsyncRequest = require('../Utils/asyncRequest');
|
|
4
|
-
const System = require('./System')
|
|
4
|
+
const System = require('./System');
|
|
5
|
+
const Constants = require('./Constants');
|
|
5
6
|
|
|
6
7
|
// Allow to connect to Airzone local API
|
|
7
8
|
|
|
@@ -11,16 +12,26 @@ class AirzoneLocalApi {
|
|
|
11
12
|
constructor(a, local_ip)
|
|
12
13
|
{
|
|
13
14
|
adapter = a;
|
|
14
|
-
log = a.log;
|
|
15
|
+
log = a.log;
|
|
15
16
|
this.local_ip = local_ip;
|
|
17
|
+
this.baseUrl = `http://${local_ip}:3000`;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
async init(system_id) {
|
|
19
|
-
|
|
20
21
|
this.system = new System(adapter, this, system_id);
|
|
21
22
|
await this.system.init();
|
|
23
|
+
|
|
24
|
+
// Try to get version info
|
|
25
|
+
try {
|
|
26
|
+
const version = await this.getVersion();
|
|
27
|
+
if (version) {
|
|
28
|
+
this.logInfo(`Airzone API Version: ${JSON.stringify(version)}`);
|
|
29
|
+
}
|
|
30
|
+
} catch (_e) {
|
|
31
|
+
this.logInfo('Version endpoint not available');
|
|
32
|
+
}
|
|
22
33
|
}
|
|
23
|
-
|
|
34
|
+
|
|
24
35
|
async update() {
|
|
25
36
|
if(this.system == undefined)
|
|
26
37
|
return;
|
|
@@ -36,47 +47,105 @@ class AirzoneLocalApi {
|
|
|
36
47
|
log.error(msg);
|
|
37
48
|
}
|
|
38
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Get the API version information
|
|
52
|
+
* @returns {Promise<object|undefined>} Version info or undefined on error
|
|
53
|
+
*/
|
|
54
|
+
async getVersion() {
|
|
55
|
+
const url = this.baseUrl + Constants.API_ENDPOINTS.VERSION;
|
|
56
|
+
const response = await AsyncRequest.jsonGetRequest(url);
|
|
57
|
+
|
|
58
|
+
if (response['errors']) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const body = response['body'];
|
|
63
|
+
return body ? JSON.parse(body) : undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get webserver information (if available)
|
|
68
|
+
* @returns {Promise<object|undefined>} Webserver info or undefined on error
|
|
69
|
+
*/
|
|
70
|
+
async getWebserverInfo() {
|
|
71
|
+
const url = this.baseUrl + Constants.API_ENDPOINTS.WEBSERVER;
|
|
72
|
+
const data = {};
|
|
73
|
+
const response = await AsyncRequest.jsonPostRequest(url, data);
|
|
74
|
+
|
|
75
|
+
if (response['errors']) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const body = response['body'];
|
|
80
|
+
return body ? JSON.parse(body) : undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
39
83
|
async getZoneState() {
|
|
40
84
|
if(this.system == undefined)
|
|
41
85
|
return undefined;
|
|
42
|
-
|
|
43
|
-
var url = "http://"+this.local_ip+":3000/api/v1/hvac";
|
|
44
|
-
var systemId = this.system.id;
|
|
45
|
-
var data = '{\"systemID\":'+systemId+', \"ZoneID\":0}';
|
|
46
|
-
var response = await AsyncRequest.jsonPostRequest(url, data);
|
|
47
86
|
|
|
48
|
-
|
|
87
|
+
const url = this.baseUrl + Constants.API_ENDPOINTS.HVAC;
|
|
88
|
+
const systemId = this.system.id;
|
|
89
|
+
const data = { systemID: systemId, ZoneID: 0 };
|
|
90
|
+
const response = await AsyncRequest.jsonPostRequest(url, data);
|
|
91
|
+
|
|
92
|
+
const errors = response['errors'];
|
|
49
93
|
if(errors)
|
|
50
94
|
{
|
|
51
|
-
this.logError(
|
|
95
|
+
this.logError('Failed to get zone state: (statusCode: '+response['statusCode']+') - '+response['errors']);
|
|
52
96
|
return undefined;
|
|
53
97
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
const body = response['body'];
|
|
99
|
+
const zones = JSON.parse(body)['data'];
|
|
100
|
+
|
|
57
101
|
return zones;
|
|
58
102
|
}
|
|
59
103
|
|
|
60
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Get IAQ sensor data (if available)
|
|
106
|
+
* @returns {Promise<Array|undefined>} IAQ data array or undefined on error
|
|
107
|
+
*/
|
|
108
|
+
async getIAQData() {
|
|
109
|
+
if(this.system == undefined)
|
|
110
|
+
return undefined;
|
|
111
|
+
|
|
112
|
+
const url = this.baseUrl + Constants.API_ENDPOINTS.IAQ;
|
|
113
|
+
const systemId = this.system.id;
|
|
114
|
+
const data = { systemID: systemId };
|
|
115
|
+
const response = await AsyncRequest.jsonPostRequest(url, data);
|
|
116
|
+
|
|
117
|
+
const errors = response['errors'];
|
|
118
|
+
if (errors) {
|
|
119
|
+
// IAQ endpoint may not be available on all devices
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const body = response['body'];
|
|
124
|
+
const iaqData = body ? JSON.parse(body)['data'] : undefined;
|
|
125
|
+
|
|
126
|
+
return iaqData;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async sendUpdate(zoneid, key, value)
|
|
61
130
|
{
|
|
62
131
|
if(this.system == undefined)
|
|
63
132
|
return false;
|
|
64
133
|
|
|
65
134
|
try
|
|
66
135
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
136
|
+
const url = this.baseUrl + Constants.API_ENDPOINTS.HVAC;
|
|
137
|
+
const systemId = this.system.id;
|
|
138
|
+
const data = { systemID: systemId, zoneID: zoneid, [key]: value };
|
|
139
|
+
const response = await AsyncRequest.jsonPutRequest(url, data);
|
|
140
|
+
const errors = response['errors'];
|
|
72
141
|
if(errors)
|
|
73
142
|
{
|
|
74
|
-
this.logError("Failed to update '"+key+"' with value '"+value+"': (statusCode: "+response[
|
|
75
|
-
return
|
|
143
|
+
this.logError("Failed to update '"+key+"' with value '"+value+"': (statusCode: "+response['statusCode']+') - '+response['errors']);
|
|
144
|
+
return false;
|
|
76
145
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return responseData.hasOwnProperty(key);
|
|
146
|
+
const body = response['body'];
|
|
147
|
+
const responseData = JSON.parse(body)['data'];
|
|
148
|
+
return responseData && responseData.hasOwnProperty(key);
|
|
80
149
|
}
|
|
81
150
|
catch (e) {
|
|
82
151
|
this.logError('error during sendUpdate '+e+'\r\n'+e.stack);
|
package/LocalApi/Constants.js
CHANGED
|
@@ -1,14 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
module.exports = Object.freeze({
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
// Operating modes - Mode 7 (Auto) added for newer firmware
|
|
5
|
+
MODES_CONVERTER: {
|
|
6
|
+
'1': { 'name': 'Stop' },
|
|
7
|
+
'2': { 'name': 'Cooling' },
|
|
8
|
+
'3': { 'name': 'Heating' },
|
|
9
|
+
'4': { 'name': 'Fan' },
|
|
10
|
+
'5': { 'name': 'Dry' },
|
|
11
|
+
'7': { 'name': 'Auto' }
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
// Temperature units
|
|
15
|
+
UNIT_CONVERTER: {
|
|
16
|
+
'0': { 'name': 'Celsius', 'unit': '°C' },
|
|
17
|
+
'1': { 'name': 'Fahrenheit', 'unit': '°F' }
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// Fan speed levels (0 = Auto, 1-7 = Manual speeds)
|
|
21
|
+
FAN_SPEED_CONVERTER: {
|
|
22
|
+
'0': { 'name': 'Auto' },
|
|
23
|
+
'1': { 'name': 'Speed 1 (Lowest)' },
|
|
24
|
+
'2': { 'name': 'Speed 2' },
|
|
25
|
+
'3': { 'name': 'Speed 3' },
|
|
26
|
+
'4': { 'name': 'Speed 4' },
|
|
27
|
+
'5': { 'name': 'Speed 5' },
|
|
28
|
+
'6': { 'name': 'Speed 6' },
|
|
29
|
+
'7': { 'name': 'Speed 7 (Highest)' }
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// Indoor Air Quality score mapping
|
|
33
|
+
IAQ_SCORE_CONVERTER: {
|
|
34
|
+
'1': { 'name': 'Good', 'color': 'green' },
|
|
35
|
+
'2': { 'name': 'Medium', 'color': 'yellow' },
|
|
36
|
+
'3': { 'name': 'Bad', 'color': 'orange' },
|
|
37
|
+
'4': { 'name': 'Very Bad', 'color': 'red' }
|
|
8
38
|
},
|
|
9
39
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
40
|
+
// API Endpoints
|
|
41
|
+
API_ENDPOINTS: {
|
|
42
|
+
HVAC: '/api/v1/hvac',
|
|
43
|
+
SYSTEMS: '/api/v1/systems',
|
|
44
|
+
ZONES: '/api/v1/zones',
|
|
45
|
+
WEBSERVER: '/api/v1/webserver',
|
|
46
|
+
VERSION: '/api/v1/version',
|
|
47
|
+
IAQ: '/api/v1/iaq'
|
|
13
48
|
},
|
|
49
|
+
|
|
50
|
+
// Error codes from the API
|
|
51
|
+
ERROR_CODES: {
|
|
52
|
+
'-1': 'System error',
|
|
53
|
+
'1': 'Invalid parameter',
|
|
54
|
+
'2': 'Invalid value',
|
|
55
|
+
'3': 'Out of range',
|
|
56
|
+
'4': 'Permission denied'
|
|
57
|
+
}
|
|
14
58
|
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Constants = require('./Constants');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Indoor Air Quality (IAQ) Sensor class
|
|
7
|
+
* Handles air quality sensor data from the Airzone system
|
|
8
|
+
*/
|
|
9
|
+
class IAQSensor {
|
|
10
|
+
constructor(adapter, localApi) {
|
|
11
|
+
this.adapter = adapter;
|
|
12
|
+
this.localApi = localApi;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the IAQ sensor with data from the airzone local api
|
|
17
|
+
* @param {string} path - Base path for the sensor objects
|
|
18
|
+
* @param {object} iaqData - IAQ sensor data from the API
|
|
19
|
+
*/
|
|
20
|
+
async init(path, iaqData) {
|
|
21
|
+
this.systemId = parseInt(iaqData['system_id'] || iaqData['systemID'] || 1);
|
|
22
|
+
this.zoneId = parseInt(iaqData['zone_id'] || iaqData['zoneID'] || 0);
|
|
23
|
+
|
|
24
|
+
this.path = path + '.IAQ_Zone' + this.zoneId;
|
|
25
|
+
await this.adapter.setObjectNotExistsAsync(this.path, {
|
|
26
|
+
type: 'device',
|
|
27
|
+
common: {
|
|
28
|
+
name: 'IAQ_Sensor_Zone_' + this.zoneId,
|
|
29
|
+
type: 'object',
|
|
30
|
+
read: true,
|
|
31
|
+
write: false,
|
|
32
|
+
},
|
|
33
|
+
native: {},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// IAQ Index (overall air quality score 1-4)
|
|
37
|
+
await this.adapter.createProperty(this.path, 'iaq_index', 'number', true, false, 'value');
|
|
38
|
+
await this.adapter.createProperty(this.path, 'iaq_score_name', 'string', true, false, 'text');
|
|
39
|
+
|
|
40
|
+
// CO2 level
|
|
41
|
+
await this.adapter.createUnitProperty(this.path, 'co2', 'number', 0, 5000, 'ppm', true, false, 'value.co2');
|
|
42
|
+
|
|
43
|
+
// Temperature from IAQ sensor
|
|
44
|
+
await this.adapter.createUnitProperty(this.path, 'temperature', 'number', -50, 100, '°C', true, false, 'value.temperature');
|
|
45
|
+
|
|
46
|
+
// Humidity from IAQ sensor
|
|
47
|
+
await this.adapter.createUnitProperty(this.path, 'humidity', 'number', 0, 100, '%', true, false, 'value.humidity');
|
|
48
|
+
|
|
49
|
+
// PM2.5 (Particulate Matter)
|
|
50
|
+
await this.adapter.createUnitProperty(this.path, 'pm2_5', 'number', 0, 1000, 'µg/m³', true, false, 'value');
|
|
51
|
+
|
|
52
|
+
// PM10 (Particulate Matter)
|
|
53
|
+
await this.adapter.createUnitProperty(this.path, 'pm10', 'number', 0, 1000, 'µg/m³', true, false, 'value');
|
|
54
|
+
|
|
55
|
+
// TVOC (Total Volatile Organic Compounds)
|
|
56
|
+
await this.adapter.createUnitProperty(this.path, 'tvoc', 'number', 0, 10000, 'ppb', true, false, 'value');
|
|
57
|
+
|
|
58
|
+
// Atmospheric pressure
|
|
59
|
+
await this.adapter.createUnitProperty(this.path, 'pressure', 'number', 800, 1200, 'hPa', true, false, 'value.pressure');
|
|
60
|
+
|
|
61
|
+
// Ventilation mode
|
|
62
|
+
await this.adapter.createProperty(this.path, 'ventilation_mode', 'number', true, false, 'value');
|
|
63
|
+
|
|
64
|
+
await this.updateData(iaqData);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Update the IAQ sensor data
|
|
69
|
+
* @param {object} iaqData - IAQ sensor data from the API
|
|
70
|
+
*/
|
|
71
|
+
async updateData(iaqData) {
|
|
72
|
+
// IAQ Index
|
|
73
|
+
if (iaqData.hasOwnProperty('iaq_index')) {
|
|
74
|
+
const iaqIndex = iaqData['iaq_index'];
|
|
75
|
+
await this.adapter.updatePropertyValue(this.path, 'iaq_index', iaqIndex);
|
|
76
|
+
|
|
77
|
+
const scoreName = Constants.IAQ_SCORE_CONVERTER[iaqIndex.toString()]?.name || 'Unknown';
|
|
78
|
+
await this.adapter.updatePropertyValue(this.path, 'iaq_score_name', scoreName);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// CO2
|
|
82
|
+
if (iaqData.hasOwnProperty('co2_value')) {
|
|
83
|
+
await this.adapter.updatePropertyValue(this.path, 'co2', iaqData['co2_value']);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Temperature
|
|
87
|
+
if (iaqData.hasOwnProperty('iaq_temp_value')) {
|
|
88
|
+
await this.adapter.updatePropertyValue(this.path, 'temperature', iaqData['iaq_temp_value']);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Humidity
|
|
92
|
+
if (iaqData.hasOwnProperty('iaq_humidity_value')) {
|
|
93
|
+
await this.adapter.updatePropertyValue(this.path, 'humidity', iaqData['iaq_humidity_value']);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// PM2.5
|
|
97
|
+
if (iaqData.hasOwnProperty('pm2_5_value')) {
|
|
98
|
+
await this.adapter.updatePropertyValue(this.path, 'pm2_5', iaqData['pm2_5_value']);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// PM10
|
|
102
|
+
if (iaqData.hasOwnProperty('pm10_value')) {
|
|
103
|
+
await this.adapter.updatePropertyValue(this.path, 'pm10', iaqData['pm10_value']);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// TVOC
|
|
107
|
+
if (iaqData.hasOwnProperty('tvoc_value')) {
|
|
108
|
+
await this.adapter.updatePropertyValue(this.path, 'tvoc', iaqData['tvoc_value']);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Pressure
|
|
112
|
+
if (iaqData.hasOwnProperty('pressure_value')) {
|
|
113
|
+
await this.adapter.updatePropertyValue(this.path, 'pressure', iaqData['pressure_value']);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Ventilation mode
|
|
117
|
+
if (iaqData.hasOwnProperty('iaq_mode_vent')) {
|
|
118
|
+
await this.adapter.updatePropertyValue(this.path, 'ventilation_mode', iaqData['iaq_mode_vent']);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = IAQSensor;
|
package/LocalApi/System.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
const Zone = require('./Zone')
|
|
2
|
-
const AsyncRequest = require('../Utils/asyncRequest');
|
|
1
|
+
const Zone = require('./Zone');
|
|
3
2
|
const Constants = require('./Constants');
|
|
4
3
|
|
|
5
4
|
class System {
|
|
6
5
|
constructor(adapter, localApi, id)
|
|
7
6
|
{
|
|
8
7
|
this.adapter = adapter;
|
|
9
|
-
this.localApi = localApi;
|
|
8
|
+
this.localApi = localApi;
|
|
10
9
|
this.id = id;
|
|
11
10
|
}
|
|
12
11
|
|
|
@@ -14,7 +13,7 @@ class System {
|
|
|
14
13
|
* Initialize the system with the data from the airzone local api
|
|
15
14
|
*/
|
|
16
15
|
async init() {
|
|
17
|
-
this.path =
|
|
16
|
+
this.path = 'System'+this.id;
|
|
18
17
|
await this.adapter.setObjectNotExistsAsync(this.path, {
|
|
19
18
|
type: 'device',
|
|
20
19
|
common: {
|
|
@@ -26,12 +25,12 @@ class System {
|
|
|
26
25
|
native: {},
|
|
27
26
|
});
|
|
28
27
|
|
|
29
|
-
await this.adapter.createProperty(this.path, 'mode_raw', '
|
|
28
|
+
await this.adapter.createProperty(this.path, 'mode_raw', 'number', true, true, 'state');
|
|
30
29
|
await this.adapter.createProperty(this.path, 'mode', 'string', true, false, 'text');
|
|
31
30
|
|
|
32
31
|
this.adapter.subscribeState(this.path+'.mode_raw', this, this.reactToModeRawChange);
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
|
|
33
|
+
const masterZone = await this.load_zones(this.path);
|
|
35
34
|
if(masterZone == undefined)
|
|
36
35
|
return false;
|
|
37
36
|
|
|
@@ -44,24 +43,24 @@ class System {
|
|
|
44
43
|
* Synchronized the system data from airzone into the iobroker data points
|
|
45
44
|
*/
|
|
46
45
|
async updateData(masterZoneData)
|
|
47
|
-
{
|
|
46
|
+
{
|
|
48
47
|
if(masterZoneData == undefined)
|
|
49
48
|
{
|
|
50
|
-
this.localApi.logError(
|
|
49
|
+
this.localApi.logError('Missing master Zone');
|
|
51
50
|
return;
|
|
52
|
-
}
|
|
51
|
+
}
|
|
53
52
|
|
|
54
|
-
this.mode_raw = masterZoneData[
|
|
53
|
+
this.mode_raw = masterZoneData['mode'];
|
|
55
54
|
await this.adapter.updatePropertyValue(this.path, 'mode_raw', this.mode_raw);
|
|
56
|
-
this.mode = Constants.MODES_CONVERTER[this.mode_raw][
|
|
55
|
+
this.mode = Constants.MODES_CONVERTER[this.mode_raw]['name'];
|
|
57
56
|
await this.adapter.updatePropertyValue(this.path, 'mode', this.mode);
|
|
58
57
|
}
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
/**
|
|
61
60
|
* Synchronized the system data from airzone into the iobroker data points and call update for all sub zones
|
|
62
61
|
*/
|
|
63
|
-
async update() {
|
|
64
|
-
|
|
62
|
+
async update() {
|
|
63
|
+
const masterZoneData = await this.update_zones();
|
|
65
64
|
|
|
66
65
|
await this.updateData(masterZoneData);
|
|
67
66
|
}
|
|
@@ -71,25 +70,25 @@ class System {
|
|
|
71
70
|
*/
|
|
72
71
|
async load_zones(path) {
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
const zones_relations = await this.localApi.getZoneState();
|
|
75
74
|
if(zones_relations == undefined)
|
|
76
75
|
return undefined;
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
let masterZoneData = undefined;
|
|
79
78
|
this.zones = [];
|
|
80
79
|
for (let index = 0; index < zones_relations.length; index++) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await zone.init(path, zoneData)
|
|
84
|
-
this.zones[index] = zone;
|
|
85
|
-
|
|
86
|
-
if(zoneData.hasOwnProperty(
|
|
80
|
+
const zoneData = zones_relations[index];
|
|
81
|
+
const zone = new Zone(this.adapter, this.localApi);
|
|
82
|
+
await zone.init(path, zoneData);
|
|
83
|
+
this.zones[index] = zone;
|
|
84
|
+
|
|
85
|
+
if(zoneData.hasOwnProperty('mode'))
|
|
87
86
|
{
|
|
88
87
|
masterZoneData = zoneData;
|
|
89
88
|
this.masterZoneId = this.zones[index].id;
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
|
-
|
|
91
|
+
|
|
93
92
|
return masterZoneData;
|
|
94
93
|
}
|
|
95
94
|
|
|
@@ -97,21 +96,21 @@ class System {
|
|
|
97
96
|
* Update zones with the current zone data from airzone local api
|
|
98
97
|
*/
|
|
99
98
|
async update_zones() {
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
|
|
100
|
+
const zones_relations = await this.localApi.getZoneState();
|
|
102
101
|
if(zones_relations == undefined)
|
|
103
102
|
return undefined;
|
|
104
103
|
|
|
105
104
|
if(this.zones == undefined)
|
|
106
105
|
return undefined;
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
let masterZoneData = undefined;
|
|
109
108
|
|
|
110
109
|
for (let index = 0; index < zones_relations.length; index++) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if(zoneData.hasOwnProperty(
|
|
110
|
+
const zoneData = zones_relations[index];
|
|
111
|
+
const zId = zoneData['zoneID'];
|
|
112
|
+
|
|
113
|
+
if(zoneData.hasOwnProperty('mode'))
|
|
115
114
|
masterZoneData = zoneData;
|
|
116
115
|
|
|
117
116
|
for(let i = 0;i<this.zones.length;i++) {
|
|
@@ -119,24 +118,24 @@ class System {
|
|
|
119
118
|
await this.zones[i].updateData(zoneData);
|
|
120
119
|
break;
|
|
121
120
|
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
124
123
|
|
|
125
124
|
return masterZoneData;
|
|
126
125
|
}
|
|
127
|
-
|
|
126
|
+
|
|
128
127
|
/**
|
|
129
128
|
* Is called when the state of mode was changed
|
|
130
129
|
*/
|
|
131
130
|
async reactToModeRawChange(self, id, state) {
|
|
132
|
-
|
|
131
|
+
|
|
133
132
|
if(state.val == 0)
|
|
134
133
|
{
|
|
135
134
|
self.zones.forEach(zone => {
|
|
136
135
|
zone.turn_off();
|
|
137
136
|
});
|
|
138
137
|
}
|
|
139
|
-
|
|
138
|
+
|
|
140
139
|
self.sendEvent('mode', state.val);
|
|
141
140
|
}
|
|
142
141
|
|
|
@@ -144,7 +143,7 @@ class System {
|
|
|
144
143
|
* Send event to the airzone local api
|
|
145
144
|
*/
|
|
146
145
|
async sendEvent(option, value) {
|
|
147
|
-
await this.localApi.sendUpdate(this.masterZoneId, option, value)
|
|
148
|
-
}
|
|
146
|
+
await this.localApi.sendUpdate(this.masterZoneId, option, value);
|
|
147
|
+
}
|
|
149
148
|
}
|
|
150
149
|
module.exports = System;
|