iobroker.acinfinity 0.7.1 → 0.7.2

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/main.js CHANGED
@@ -1,31 +1,31 @@
1
1
  /**
2
2
  * ioBroker AC Infinity Adapter
3
3
  * Adapter to control AC Infinity devices via ioBroker
4
- *
4
+ *
5
5
  * Based on the Home Assistant integration by dalinicus
6
6
  * https://github.com/dalinicus/homeassistant-acinfinity
7
7
  */
8
8
 
9
- "use strict";
9
+ 'use strict';
10
10
 
11
- const utils = require("@iobroker/adapter-core");
12
- const ACInfinityClient = require("./lib/client");
13
- const StateManager = require("./lib/stateManager");
14
- const { DEFAULT_POLLING_INTERVAL, MINIMUM_POLLING_INTERVAL } = require("./lib/constants");
11
+ const utils = require('@iobroker/adapter-core');
12
+ const ACInfinityClient = require('./lib/client');
13
+ const StateManager = require('./lib/stateManager');
14
+ const { DEFAULT_POLLING_INTERVAL, MINIMUM_POLLING_INTERVAL } = require('./lib/constants');
15
15
 
16
16
  class ACInfinity extends utils.Adapter {
17
17
  /**
18
- * @param {Partial<utils.AdapterOptions>} [options={}]
18
+ * @param {Partial<utils.AdapterOptions>} [options]
19
19
  */
20
20
  constructor(options) {
21
21
  super({
22
22
  ...options,
23
- name: "acinfinity",
23
+ name: 'acinfinity',
24
24
  });
25
25
 
26
- this.on("ready", this.onReady.bind(this));
27
- this.on("stateChange", this.onStateChange.bind(this));
28
- this.on("unload", this.onUnload.bind(this));
26
+ this.on('ready', this.onReady.bind(this));
27
+ this.on('stateChange', this.onStateChange.bind(this));
28
+ this.on('unload', this.onUnload.bind(this));
29
29
 
30
30
  this.client = null;
31
31
  this.stateManager = null;
@@ -38,20 +38,22 @@ class ACInfinity extends utils.Adapter {
38
38
  */
39
39
  async onReady() {
40
40
  // Initialize adapter
41
- this.log.info("Starting AC Infinity adapter");
41
+ this.log.info('Starting AC Infinity adapter');
42
42
 
43
43
  // Display a warning message in the log
44
- this.log.warn("⚠️ WARNING: BETA VERSION ⚠️ - This adapter is in an early development stage. Use at your own risk!");
45
-
44
+ this.log.warn(
45
+ '⚠️ WARNING: BETA VERSION ⚠️ - This adapter is in an early development stage. Use at your own risk!',
46
+ );
47
+
46
48
  // Display a toast notification in the admin UI if possible
47
49
  try {
48
- this.sendTo("system.adapter.admin.0", "toast", {
49
- message: "AC Infinity Adapter: BETA Version - Use at your own risk!",
50
- type: "warning",
51
- duration: 15000
50
+ this.sendTo('system.adapter.admin.0', 'toast', {
51
+ message: 'AC Infinity Adapter: BETA Version - Use at your own risk!',
52
+ type: 'warning',
53
+ duration: 15000,
52
54
  });
53
55
  } catch (e) {
54
- this.log.debug("Could not send toast notification: " + e.message);
56
+ this.log.debug(`Could not send toast notification: ${e.message}`);
55
57
  }
56
58
 
57
59
  // Get adapter configuration
@@ -59,39 +61,39 @@ class ACInfinity extends utils.Adapter {
59
61
  const password = this.config.password;
60
62
  const pollingInterval = Math.max(
61
63
  this.config.pollingInterval || DEFAULT_POLLING_INTERVAL,
62
- MINIMUM_POLLING_INTERVAL
64
+ MINIMUM_POLLING_INTERVAL,
63
65
  );
64
66
 
65
67
  if (!email || !password) {
66
- this.log.error("Missing login credentials. Please configure in adapter settings.");
68
+ this.log.error('Missing login credentials. Please configure in adapter settings.');
67
69
  return;
68
70
  }
69
71
 
70
72
  // Set up connection indicator state
71
- await this.setStateAsync("info.connection", { val: false, ack: true });
73
+ await this.setStateAsync('info.connection', { val: false, ack: true });
72
74
 
73
75
  try {
74
76
  // Initialize API client
75
77
  this.client = new ACInfinityClient(email, password, this.log);
76
78
  this.stateManager = new StateManager(this);
77
-
79
+
78
80
  // Wichtig: Den Client an den StateManager weitergeben
79
81
  this.stateManager.setClient(this.client);
80
82
 
81
83
  // Attempt to login
82
84
  this.log.info(`Logging in with email: ${email}`);
83
85
  await this.client.login();
84
-
86
+
85
87
  // If we got here, login was successful
86
- this.log.info("Login successful");
88
+ this.log.info('Login successful');
87
89
  this.isConnected = true;
88
- await this.setStateAsync("info.connection", { val: true, ack: true });
90
+ await this.setStateAsync('info.connection', { val: true, ack: true });
89
91
 
90
92
  // Store token information
91
- await this.setStateAsync("info.token", { val: this.client.token, ack: true });
93
+ await this.setStateAsync('info.token', { val: this.client.token, ack: true });
92
94
 
93
95
  // Abonniere alle Zustände
94
- this.subscribeStates("*");
96
+ this.subscribeStates('*');
95
97
  this.log.debug("Abonniere alle Zustände mit subscribeStates('*')");
96
98
 
97
99
  // Initialize adapter by fetching devices and setting up states
@@ -104,11 +106,11 @@ class ACInfinity extends utils.Adapter {
104
106
  await this.updateDeviceData();
105
107
  } catch (error) {
106
108
  this.log.error(`Error during polling update: ${error.message}`);
107
- if (error.message.includes("unauthorized") || error.message.includes("auth")) {
108
- this.log.info("Authentication error detected, attempting to re-login");
109
+ if (error.message.includes('unauthorized') || error.message.includes('auth')) {
110
+ this.log.info('Authentication error detected, attempting to re-login');
109
111
  try {
110
112
  await this.client.login();
111
- this.log.info("Re-login successful");
113
+ this.log.info('Re-login successful');
112
114
  } catch (loginError) {
113
115
  this.log.error(`Failed to re-login: ${loginError.message}`);
114
116
  }
@@ -117,7 +119,7 @@ class ACInfinity extends utils.Adapter {
117
119
  }, pollingInterval * 1000);
118
120
  } catch (error) {
119
121
  this.log.error(`Initialization error: ${error.message}`);
120
- await this.setStateAsync("info.connection", { val: false, ack: true });
122
+ await this.setStateAsync('info.connection', { val: false, ack: true });
121
123
  }
122
124
  }
123
125
 
@@ -125,17 +127,17 @@ class ACInfinity extends utils.Adapter {
125
127
  * Initialize adapter by fetching devices and setting up states
126
128
  */
127
129
  async initializeAdapter() {
128
- this.log.info("Initializing adapter and fetching devices");
129
-
130
+ this.log.info('Initializing adapter and fetching devices');
131
+
130
132
  try {
131
133
  // Fetch all devices
132
134
  const devices = await this.client.getDevicesList();
133
-
135
+
134
136
  // Debug log - check structure
135
137
  if (devices && devices.length > 0) {
136
138
  this.log.debug(`First device sample: ${JSON.stringify(devices[0]).substring(0, 1000)}...`);
137
139
  }
138
-
140
+
139
141
  this.log.info(`Found ${devices.length} devices`);
140
142
 
141
143
  // Create device information in state tree
@@ -143,8 +145,8 @@ class ACInfinity extends utils.Adapter {
143
145
 
144
146
  // Perform initial data update
145
147
  await this.updateDeviceData();
146
-
147
- this.log.info("Adapter initialization completed successfully");
148
+
149
+ this.log.info('Adapter initialization completed successfully');
148
150
  } catch (error) {
149
151
  this.log.error(`Failed to initialize adapter: ${error.message}`);
150
152
  throw error;
@@ -156,64 +158,76 @@ class ACInfinity extends utils.Adapter {
156
158
  */
157
159
  async updateDeviceData() {
158
160
  if (!this.isConnected || !this.client) {
159
- this.log.debug("Not connected, skipping update");
161
+ this.log.debug('Not connected, skipping update');
160
162
  return;
161
163
  }
162
164
 
163
- this.log.debug("Updating device data");
165
+ this.log.debug('Updating device data');
164
166
  try {
165
167
  // Get latest device data
166
168
  const devices = await this.client.getDevicesList();
167
-
169
+
168
170
  this.log.debug(`Fetched ${devices.length} devices for update`);
169
-
171
+
170
172
  // Update states for all devices
171
173
  for (const device of devices) {
172
174
  this.log.debug(`Updating device ${device.devId} (${device.devName})`);
173
-
175
+
174
176
  // Debug logging for important values
175
- if (typeof device.temperature !== "undefined") {
176
- this.log.debug(`Device ${device.devId} temperature: ${device.temperature} (raw), ${device.temperature/100} (converted)`);
177
+ if (typeof device.temperature !== 'undefined') {
178
+ this.log.debug(
179
+ `Device ${device.devId} temperature: ${device.temperature} (raw), ${device.temperature / 100} (converted)`,
180
+ );
177
181
  }
178
- if (typeof device.humidity !== "undefined") {
179
- this.log.debug(`Device ${device.devId} humidity: ${device.humidity} (raw), ${device.humidity/100} (converted)`);
182
+ if (typeof device.humidity !== 'undefined') {
183
+ this.log.debug(
184
+ `Device ${device.devId} humidity: ${device.humidity} (raw), ${device.humidity / 100} (converted)`,
185
+ );
180
186
  }
181
- if (typeof device.vpdnums !== "undefined") {
182
- this.log.debug(`Device ${device.devId} vpd: ${device.vpdnums} (raw), ${device.vpdnums/100} (converted)`);
187
+ if (typeof device.vpdnums !== 'undefined') {
188
+ this.log.debug(
189
+ `Device ${device.devId} vpd: ${device.vpdnums} (raw), ${device.vpdnums / 100} (converted)`,
190
+ );
183
191
  }
184
-
192
+
185
193
  await this.stateManager.updateDeviceData(device);
186
-
194
+
187
195
  // Fetch and update port settings for each device
188
196
  if (device.deviceInfo && Array.isArray(device.deviceInfo.ports)) {
189
197
  for (const port of device.deviceInfo.ports) {
190
198
  const portId = port.port;
191
199
  this.log.debug(`Fetching settings for device ${device.devId}, port ${portId}`);
192
-
200
+
193
201
  try {
194
202
  const portSettings = await this.client.getDeviceModeSettings(device.devId, portId);
195
203
  await this.stateManager.updatePortSettings(device.devId, portId, portSettings);
196
204
  } catch (portError) {
197
- this.log.warn(`Error fetching port mode settings for device ${device.devId}, port ${portId}: ${portError.message}`);
205
+ this.log.warn(
206
+ `Error fetching port mode settings for device ${device.devId}, port ${portId}: ${portError.message}`,
207
+ );
198
208
  }
199
-
209
+
200
210
  try {
201
211
  const advancedSettings = await this.client.getDeviceSettings(device.devId, portId);
202
212
  await this.stateManager.updateAdvancedSettings(device.devId, portId, advancedSettings);
203
213
  } catch (advError) {
204
- this.log.warn(`Error fetching advanced settings for device ${device.devId}, port ${portId}: ${advError.message}`);
214
+ this.log.warn(
215
+ `Error fetching advanced settings for device ${device.devId}, port ${portId}: ${advError.message}`,
216
+ );
205
217
  }
206
218
  }
207
219
  } else {
208
220
  this.log.warn(`No ports found for device ${device.devId}`);
209
221
  }
210
-
222
+
211
223
  // Fetch and update advanced settings for controller
212
224
  try {
213
225
  const controllerSettings = await this.client.getDeviceSettings(device.devId, 0);
214
226
  await this.stateManager.updateAdvancedSettings(device.devId, 0, controllerSettings);
215
227
  } catch (ctrlError) {
216
- this.log.warn(`Error fetching controller settings for device ${device.devId}: ${ctrlError.message}`);
228
+ this.log.warn(
229
+ `Error fetching controller settings for device ${device.devId}: ${ctrlError.message}`,
230
+ );
217
231
  }
218
232
  }
219
233
  } catch (error) {
@@ -224,6 +238,7 @@ class ACInfinity extends utils.Adapter {
224
238
 
225
239
  /**
226
240
  * Is called when adapter shuts down - callback has to be called under any circumstances!
241
+ *
227
242
  * @param {() => void} callback
228
243
  */
229
244
  onUnload(callback) {
@@ -233,23 +248,26 @@ class ACInfinity extends utils.Adapter {
233
248
  clearInterval(this.pollingInterval);
234
249
  this.pollingInterval = null;
235
250
  }
236
-
237
- this.log.info("AC Infinity adapter shutting down");
251
+
252
+ this.log.info('AC Infinity adapter shutting down');
238
253
  this.isConnected = false;
239
254
  callback();
240
- } catch (error) {
255
+ } catch {
241
256
  callback();
242
257
  }
243
258
  }
244
259
 
245
260
  /**
246
261
  * Is called if a subscribed state changes
262
+ *
247
263
  * @param {string} id
248
264
  * @param {ioBroker.State | null | undefined} state
249
265
  */
250
266
  async onStateChange(id, state) {
251
267
  // Nur für Debug-Zwecke, kann später entfernt oder als debug-Level geloggt werden
252
- this.log.debug(`State change detected: ${id} = ${state ? state.val : "null"}, ack = ${state ? state.ack : "null"}`);
268
+ this.log.debug(
269
+ `State change detected: ${id} = ${state ? state.val : 'null'}, ack = ${state ? state.ack : 'null'}`,
270
+ );
253
271
 
254
272
  // Standard-Verarbeitung
255
273
  if (!state) {
@@ -267,59 +285,66 @@ class ACInfinity extends utils.Adapter {
267
285
  try {
268
286
  // Überprüfen, ob der Client und StateManager initialisiert wurden
269
287
  if (!this.client || !this.stateManager) {
270
- this.log.error(`Adapter not fully initialized. Client: ${!!this.client}, StateManager: ${!!this.stateManager}`);
271
- throw new Error("Adapter is not fully initialized");
288
+ this.log.error(
289
+ `Adapter not fully initialized. Client: ${!!this.client}, StateManager: ${!!this.stateManager}`,
290
+ );
291
+ throw new Error('Adapter is not fully initialized');
272
292
  }
273
293
 
274
294
  // Überprüfen, ob wir angemeldet sind
275
295
  if (!this.isConnected || !this.client.isLoggedIn()) {
276
- this.log.info(`Not logged in, trying to log in again. isConnected: ${this.isConnected}, isLoggedIn: ${this.client ? this.client.isLoggedIn() : "client is null"}`);
296
+ this.log.info(
297
+ `Not logged in, trying to log in again. isConnected: ${this.isConnected}, isLoggedIn: ${this.client ? this.client.isLoggedIn() : 'client is null'}`,
298
+ );
277
299
  try {
278
300
  await this.client.login();
279
301
  this.log.info(`Re-login successful. Token: ${this.client.token}`);
280
302
  this.isConnected = true;
281
- await this.setStateAsync("info.connection", { val: true, ack: true });
303
+ await this.setStateAsync('info.connection', { val: true, ack: true });
282
304
  } catch (loginError) {
283
305
  this.log.error(`Error during re-login: ${loginError.message}`);
284
306
  this.isConnected = false;
285
- await this.setStateAsync("info.connection", { val: false, ack: true });
286
- throw new Error("Login failed, state change cannot be processed");
307
+ await this.setStateAsync('info.connection', { val: false, ack: true });
308
+ throw new Error('Login failed, state change cannot be processed');
287
309
  }
288
310
  }
289
311
 
290
312
  // Parse ID, um zu prüfen, um welche Art von State es sich handelt
291
- const idParts = id.split(".");
313
+ const idParts = id.split('.');
292
314
  this.log.debug(`ID parts: ${JSON.stringify(idParts)}`);
293
315
 
294
316
  // Lasse den StateManager die Änderung verarbeiten
295
317
  this.log.debug(`Forwarding state change to StateManager: ${id} = ${state.val}`);
296
318
  await this.stateManager.handleStateChange(id, state);
297
319
  this.log.debug(`StateManager processed state change: ${id}`);
298
-
299
320
  } catch (error) {
300
321
  this.log.error(`Error processing state change: ${error.message}`);
301
322
  if (error.stack) {
302
323
  this.log.debug(`Stack trace: ${error.stack}`);
303
324
  }
304
-
325
+
305
326
  // Bei Kommunikationsfehlern Verbindungsstatus aktualisieren
306
- if (error.message.includes("network") || error.message.includes("timeout") ||
307
- error.message.includes("connection") || error.message.includes("connect")) {
327
+ if (
328
+ error.message.includes('network') ||
329
+ error.message.includes('timeout') ||
330
+ error.message.includes('connection') ||
331
+ error.message.includes('connect')
332
+ ) {
308
333
  this.isConnected = false;
309
- await this.setStateAsync("info.connection", { val: false, ack: true });
334
+ await this.setStateAsync('info.connection', { val: false, ack: true });
310
335
  }
311
336
  }
312
337
  }
313
338
  }
314
339
 
315
- // @ts-ignore parent is a valid property on module
340
+ // @ts-expect-error parent is a valid property on module
316
341
  if (module.parent) {
317
342
  // Export the constructor in compact mode
318
343
  /**
319
- * @param {Partial<utils.AdapterOptions>} [options={}]
344
+ * @param {Partial<utils.AdapterOptions>} [options]
320
345
  */
321
- module.exports = (options) => new ACInfinity(options);
346
+ module.exports = options => new ACInfinity(options);
322
347
  } else {
323
348
  // otherwise start the instance directly
324
349
  new ACInfinity();
325
- }
350
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.acinfinity",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Monitor and control AC Infinity devices",
5
5
  "author": {
6
6
  "name": "laurent Standard",
@@ -27,9 +27,9 @@
27
27
  "axios": "^1.5.0"
28
28
  },
29
29
  "devDependencies": {
30
+ "@iobroker/eslint-config": "^2.2.0",
30
31
  "@iobroker/testing": "^5.2.2",
31
32
  "@types/node": "^18.16.18",
32
- "eslint": "^8.44.0",
33
33
  "typescript": "~5.0.4"
34
34
  },
35
35
  "main": "main.js",
@@ -47,11 +47,11 @@
47
47
  "test:integration": "mocha test/integration --exit",
48
48
  "test": "npm run test:js && npm run test:package",
49
49
  "check": "tsc --noEmit -p tsconfig.check.json",
50
- "lint": "eslint .",
50
+ "lint": "eslint -c eslint.config.mjs .",
51
51
  "build": "npm run lint && npm test"
52
52
  },
53
53
  "bugs": {
54
54
  "url": "https://github.com/raspilaurent/ioBroker.acinfinity/issues"
55
55
  },
56
56
  "readmeFilename": "README.md"
57
- }
57
+ }