iobroker.absolutehumidity 0.0.1
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/LICENSE +21 -0
- package/README.md +138 -0
- package/admin/TabConfig.json +16 -0
- package/admin/absolutehumidity.svg +27 -0
- package/admin/i18n/de.json +23 -0
- package/admin/i18n/en.json +23 -0
- package/admin/i18n/es.json +23 -0
- package/admin/i18n/fr.json +23 -0
- package/admin/i18n/it.json +23 -0
- package/admin/i18n/nl.json +23 -0
- package/admin/i18n/pl.json +23 -0
- package/admin/i18n/pt.json +23 -0
- package/admin/i18n/ru.json +23 -0
- package/admin/i18n/uk.json +23 -0
- package/admin/i18n/zh-cn.json +23 -0
- package/admin/jsonConfig.json +50 -0
- package/io-package.json +109 -0
- package/lib/adapter-config.d.ts +19 -0
- package/lib/modules/calculation.js +44 -0
- package/lib/modules/constants.js +19 -0
- package/lib/modules/deviceManager.js +312 -0
- package/lib/modules/i18n.js +209 -0
- package/lib/modules/idUtils.js +82 -0
- package/main.js +462 -0
- package/package.json +70 -0
package/main.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
/* eslint-disable jsdoc/require-param-description, jsdoc/require-returns-description, jsdoc/reject-any-type */
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const utils = require('@iobroker/adapter-core');
|
|
7
|
+
const { calculateAbsoluteHumidity, calculateDewPointTemperature } = require('./lib/modules/calculation');
|
|
8
|
+
const {
|
|
9
|
+
DEVICE_ROOT,
|
|
10
|
+
STATE_ABSOLUTE_HUMIDITY,
|
|
11
|
+
STATE_DEW_POINT_TEMPERATURE,
|
|
12
|
+
STATE_RELATIVE_HUMIDITY,
|
|
13
|
+
STATE_TEMPERATURE,
|
|
14
|
+
} = require('./lib/modules/constants');
|
|
15
|
+
const { AbsoluteHumidityDeviceManagement } = require('./lib/modules/deviceManager');
|
|
16
|
+
const { createUniqueDeviceId, createUniqueIdFromBase, legacySanitizeId, sanitizeId } = require('./lib/modules/idUtils');
|
|
17
|
+
const { translate } = require('./lib/modules/i18n');
|
|
18
|
+
|
|
19
|
+
class Absolutehumidity extends utils.Adapter {
|
|
20
|
+
/**
|
|
21
|
+
* @param {Partial<utils.AdapterOptions>} [options] - Adapter options
|
|
22
|
+
*/
|
|
23
|
+
constructor(options) {
|
|
24
|
+
super({
|
|
25
|
+
...options,
|
|
26
|
+
name: 'absolutehumidity',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
this.deviceManagement = null;
|
|
30
|
+
this.subscribedSourceIds = new Set();
|
|
31
|
+
|
|
32
|
+
this.on('ready', this.onReady.bind(this));
|
|
33
|
+
this.on('message', this.onMessage.bind(this));
|
|
34
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
35
|
+
this.on('unload', this.onUnload.bind(this));
|
|
36
|
+
// this.on('objectChange', this.onObjectChange.bind(this));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Is called when databases are connected and adapter received configuration.
|
|
41
|
+
*/
|
|
42
|
+
async onReady() {
|
|
43
|
+
this.deviceManagement = new AbsoluteHumidityDeviceManagement(this);
|
|
44
|
+
await this.ensureInfoStates();
|
|
45
|
+
await this.migrateLegacyDeviceIds();
|
|
46
|
+
await this.rebuildAllDevices();
|
|
47
|
+
await this.refreshSubscriptions();
|
|
48
|
+
await this.updateAllDevices();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @returns {Array<Record<string, any>>}
|
|
53
|
+
*/
|
|
54
|
+
getConfiguredDevices() {
|
|
55
|
+
return Array.isArray(this.config.devices) ? this.config.devices : [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {string} id
|
|
60
|
+
* @returns {Record<string, any> | undefined}
|
|
61
|
+
*/
|
|
62
|
+
getDeviceById(id) {
|
|
63
|
+
return this.getConfiguredDevices().find(device => device.id === id);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Record<string, any>} data
|
|
68
|
+
*/
|
|
69
|
+
async addDevice(data) {
|
|
70
|
+
const devices = this.getConfiguredDevices();
|
|
71
|
+
const device = this.normalizeDeviceFormData(data, createUniqueDeviceId(data.name, devices));
|
|
72
|
+
|
|
73
|
+
await this.saveDevices([...devices, device]);
|
|
74
|
+
await this.ensureDeviceObjects(device);
|
|
75
|
+
await this.refreshSubscriptions();
|
|
76
|
+
await this.updateDeviceValues(device);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {string} id
|
|
81
|
+
* @param {Record<string, any>} data
|
|
82
|
+
*/
|
|
83
|
+
async updateDevice(id, data) {
|
|
84
|
+
const oldDevice = this.getDeviceById(id);
|
|
85
|
+
const devices = this.getConfiguredDevices();
|
|
86
|
+
const device = this.normalizeDeviceFormData(data, id);
|
|
87
|
+
|
|
88
|
+
await this.saveDevices(devices.map(existingDevice => (existingDevice.id === id ? device : existingDevice)));
|
|
89
|
+
|
|
90
|
+
if (oldDevice) {
|
|
91
|
+
await this.deleteObsoleteDeviceStates(oldDevice, device);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
await this.ensureDeviceObjects(device);
|
|
95
|
+
await this.refreshSubscriptions();
|
|
96
|
+
await this.updateDeviceValues(device);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} id
|
|
101
|
+
*/
|
|
102
|
+
async deleteDevice(id) {
|
|
103
|
+
const devices = this.getConfiguredDevices();
|
|
104
|
+
|
|
105
|
+
await this.saveDevices(devices.filter(device => device.id !== id));
|
|
106
|
+
await this.deleteObjectIfExists(this.getDeviceObjectId(id), { recursive: true });
|
|
107
|
+
await this.refreshSubscriptions();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {Record<string, any>} data
|
|
112
|
+
* @param {string} id
|
|
113
|
+
*/
|
|
114
|
+
normalizeDeviceFormData(data, id) {
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
name: String(data.name || id).trim(),
|
|
118
|
+
temperatureStateId: String(data.temperatureStateId || '').trim(),
|
|
119
|
+
relativeHumidityStateId: String(data.relativeHumidityStateId || '').trim(),
|
|
120
|
+
createTemperatureState: data.createTemperatureState !== false,
|
|
121
|
+
createRelativeHumidityState: data.createRelativeHumidityState !== false,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {Record<string, any>[]} devices
|
|
127
|
+
*/
|
|
128
|
+
async saveDevices(devices) {
|
|
129
|
+
const adapterObjectId = `system.adapter.${this.namespace}`;
|
|
130
|
+
const adapterObject = await this.getForeignObjectAsync(adapterObjectId);
|
|
131
|
+
|
|
132
|
+
if (!adapterObject) {
|
|
133
|
+
throw new Error(`Could not find adapter object ${adapterObjectId}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
adapterObject.native = {
|
|
137
|
+
...adapterObject.native,
|
|
138
|
+
devices,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
await this.setForeignObjectAsync(adapterObjectId, adapterObject);
|
|
142
|
+
this.config.devices = devices;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async rebuildAllDevices() {
|
|
146
|
+
for (const device of this.getConfiguredDevices()) {
|
|
147
|
+
await this.ensureDeviceObjects(device);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async migrateLegacyDeviceIds() {
|
|
152
|
+
const devices = this.getConfiguredDevices();
|
|
153
|
+
|
|
154
|
+
if (!devices.length) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const usedLegacyIds = new Set();
|
|
159
|
+
const usedNewIds = new Set();
|
|
160
|
+
const migratedDevices = [];
|
|
161
|
+
const oldIdsToDelete = [];
|
|
162
|
+
|
|
163
|
+
for (const device of devices) {
|
|
164
|
+
const legacyId = createUniqueIdFromBase(legacySanitizeId(device.name || device.id), usedLegacyIds);
|
|
165
|
+
const newId = createUniqueIdFromBase(sanitizeId(device.name || device.id), usedNewIds);
|
|
166
|
+
|
|
167
|
+
usedLegacyIds.add(legacyId);
|
|
168
|
+
usedNewIds.add(newId);
|
|
169
|
+
|
|
170
|
+
if (device.id === legacyId && legacyId !== newId) {
|
|
171
|
+
migratedDevices.push({
|
|
172
|
+
...device,
|
|
173
|
+
id: newId,
|
|
174
|
+
});
|
|
175
|
+
oldIdsToDelete.push(device.id);
|
|
176
|
+
} else {
|
|
177
|
+
migratedDevices.push(device);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (!oldIdsToDelete.length) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await this.saveDevices(migratedDevices);
|
|
186
|
+
|
|
187
|
+
for (const oldId of oldIdsToDelete) {
|
|
188
|
+
await this.deleteObjectIfExists(this.getDeviceObjectId(oldId), { recursive: true });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async ensureInfoStates() {
|
|
193
|
+
await this.setObjectNotExistsAsync('info', {
|
|
194
|
+
type: 'channel',
|
|
195
|
+
common: {
|
|
196
|
+
name: 'Information',
|
|
197
|
+
},
|
|
198
|
+
native: {},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @param {Record<string, any>} device
|
|
204
|
+
*/
|
|
205
|
+
async ensureDeviceObjects(device) {
|
|
206
|
+
const deviceObjectId = this.getDeviceObjectId(device.id);
|
|
207
|
+
|
|
208
|
+
await this.setObjectNotExistsAsync(deviceObjectId, {
|
|
209
|
+
type: 'device',
|
|
210
|
+
common: {
|
|
211
|
+
name: device.name,
|
|
212
|
+
},
|
|
213
|
+
native: {},
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
await this.extendObjectAsync(deviceObjectId, {
|
|
217
|
+
common: {
|
|
218
|
+
name: device.name,
|
|
219
|
+
},
|
|
220
|
+
native: {
|
|
221
|
+
temperatureStateId: device.temperatureStateId,
|
|
222
|
+
relativeHumidityStateId: device.relativeHumidityStateId,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
await this.ensureStateObject(device, STATE_ABSOLUTE_HUMIDITY, {
|
|
227
|
+
name: translate('Absolute humidity'),
|
|
228
|
+
role: 'value.humidity.absolute',
|
|
229
|
+
unit: 'g/m³',
|
|
230
|
+
});
|
|
231
|
+
await this.ensureStateObject(device, STATE_DEW_POINT_TEMPERATURE, {
|
|
232
|
+
name: translate('Dew point temperature'),
|
|
233
|
+
role: 'value.temperature.dewpoint',
|
|
234
|
+
unit: '°C',
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
if (device.createTemperatureState) {
|
|
238
|
+
await this.ensureStateObject(device, STATE_TEMPERATURE, {
|
|
239
|
+
name: translate('Temperature'),
|
|
240
|
+
role: 'value.temperature',
|
|
241
|
+
unit: '°C',
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
await this.deleteObjectIfExists(`${this.getDeviceObjectId(device.id)}.${STATE_TEMPERATURE}`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (device.createRelativeHumidityState) {
|
|
248
|
+
await this.ensureStateObject(device, STATE_RELATIVE_HUMIDITY, {
|
|
249
|
+
name: translate('Relative humidity'),
|
|
250
|
+
role: 'value.humidity',
|
|
251
|
+
unit: '%',
|
|
252
|
+
});
|
|
253
|
+
} else {
|
|
254
|
+
await this.deleteObjectIfExists(`${this.getDeviceObjectId(device.id)}.${STATE_RELATIVE_HUMIDITY}`);
|
|
255
|
+
}
|
|
256
|
+
await this.deleteObjectIfExists(`${this.getDeviceObjectId(device.id)}.sources`, { recursive: true });
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @param {Record<string, any>} device
|
|
261
|
+
* @param {string} stateName
|
|
262
|
+
* @param {{ name: ioBroker.StringOrTranslated; role: string; unit: string }} common
|
|
263
|
+
*/
|
|
264
|
+
async ensureStateObject(device, stateName, common) {
|
|
265
|
+
const stateId = `${this.getDeviceObjectId(device.id)}.${stateName}`;
|
|
266
|
+
|
|
267
|
+
await this.setObjectNotExistsAsync(stateId, {
|
|
268
|
+
type: 'state',
|
|
269
|
+
common: {
|
|
270
|
+
name: common.name,
|
|
271
|
+
type: 'number',
|
|
272
|
+
role: common.role,
|
|
273
|
+
read: true,
|
|
274
|
+
write: false,
|
|
275
|
+
unit: common.unit,
|
|
276
|
+
},
|
|
277
|
+
native: {},
|
|
278
|
+
});
|
|
279
|
+
await this.extendObjectAsync(stateId, {
|
|
280
|
+
common: {
|
|
281
|
+
name: common.name,
|
|
282
|
+
type: 'number',
|
|
283
|
+
role: common.role,
|
|
284
|
+
read: true,
|
|
285
|
+
write: false,
|
|
286
|
+
unit: common.unit,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @param {Record<string, any>} oldDevice
|
|
293
|
+
* @param {Record<string, any>} newDevice
|
|
294
|
+
*/
|
|
295
|
+
async deleteObsoleteDeviceStates(oldDevice, newDevice) {
|
|
296
|
+
if (oldDevice.createTemperatureState && !newDevice.createTemperatureState) {
|
|
297
|
+
await this.deleteObjectIfExists(`${this.getDeviceObjectId(newDevice.id)}.${STATE_TEMPERATURE}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (oldDevice.createRelativeHumidityState && !newDevice.createRelativeHumidityState) {
|
|
301
|
+
await this.deleteObjectIfExists(`${this.getDeviceObjectId(newDevice.id)}.${STATE_RELATIVE_HUMIDITY}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @param {string} id
|
|
307
|
+
* @param {Record<string, unknown>} [options]
|
|
308
|
+
*/
|
|
309
|
+
async deleteObjectIfExists(id, options) {
|
|
310
|
+
const object = await this.getObjectAsync(id);
|
|
311
|
+
|
|
312
|
+
if (object) {
|
|
313
|
+
await this.delObjectAsync(id, options);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async refreshSubscriptions() {
|
|
318
|
+
for (const stateId of this.subscribedSourceIds) {
|
|
319
|
+
this.unsubscribeForeignStates(stateId);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
this.subscribedSourceIds.clear();
|
|
323
|
+
|
|
324
|
+
for (const device of this.getConfiguredDevices()) {
|
|
325
|
+
this.subscribedSourceIds.add(device.temperatureStateId);
|
|
326
|
+
this.subscribedSourceIds.add(device.relativeHumidityStateId);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
for (const stateId of this.subscribedSourceIds) {
|
|
330
|
+
this.subscribeForeignStates(stateId);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async updateAllDevices() {
|
|
335
|
+
for (const device of this.getConfiguredDevices()) {
|
|
336
|
+
await this.updateDeviceValues(device);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// If object subscriptions are needed later, enable the constructor hook and call this.subscribeObjects(...).
|
|
341
|
+
// /**
|
|
342
|
+
// * Is called if a subscribed object changes
|
|
343
|
+
// *
|
|
344
|
+
// * @param {string} id - Object ID
|
|
345
|
+
// * @param {ioBroker.Object | null | undefined} obj - Object
|
|
346
|
+
// */
|
|
347
|
+
// onObjectChange(id, obj) {
|
|
348
|
+
// if (obj) {
|
|
349
|
+
// this.log.debug(`object ${id} changed: ${JSON.stringify(obj)}`);
|
|
350
|
+
// } else {
|
|
351
|
+
// this.log.debug(`object ${id} deleted`);
|
|
352
|
+
// }
|
|
353
|
+
// }
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @param {string} id
|
|
357
|
+
* @param {ioBroker.State | null | undefined} state
|
|
358
|
+
*/
|
|
359
|
+
async onStateChange(id, state) {
|
|
360
|
+
if (!state) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const affectedDevices = this.getConfiguredDevices().filter(
|
|
365
|
+
device => device.temperatureStateId === id || device.relativeHumidityStateId === id,
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
for (const device of affectedDevices) {
|
|
369
|
+
await this.updateDeviceValues(device);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Is called if a message is sent to this adapter instance.
|
|
375
|
+
*
|
|
376
|
+
* @param {ioBroker.Message} obj - Message object
|
|
377
|
+
*/
|
|
378
|
+
onMessage(obj) {
|
|
379
|
+
if (obj.command?.startsWith('dm:')) {
|
|
380
|
+
// Device Manager messages are handled by @iobroker/dm-utils.
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (typeof obj === 'object' && obj.message) {
|
|
385
|
+
this.log.debug(`Unhandled message command: ${obj.command}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* @param {Record<string, any>} device
|
|
391
|
+
*/
|
|
392
|
+
async updateDeviceValues(device) {
|
|
393
|
+
const temperature = await this.readNumberState(device.temperatureStateId);
|
|
394
|
+
const relativeHumidity = await this.readNumberState(device.relativeHumidityStateId);
|
|
395
|
+
const absoluteHumidity = calculateAbsoluteHumidity(temperature, relativeHumidity);
|
|
396
|
+
const dewPointTemperature = calculateDewPointTemperature(temperature, relativeHumidity);
|
|
397
|
+
const deviceObjectId = this.getDeviceObjectId(device.id);
|
|
398
|
+
|
|
399
|
+
if (device.createTemperatureState) {
|
|
400
|
+
await this.setStateChangedAsync(`${deviceObjectId}.${STATE_TEMPERATURE}`, {
|
|
401
|
+
val: temperature,
|
|
402
|
+
ack: true,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (device.createRelativeHumidityState) {
|
|
407
|
+
await this.setStateChangedAsync(`${deviceObjectId}.${STATE_RELATIVE_HUMIDITY}`, {
|
|
408
|
+
val: relativeHumidity,
|
|
409
|
+
ack: true,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
await this.setStateChangedAsync(`${deviceObjectId}.${STATE_ABSOLUTE_HUMIDITY}`, {
|
|
414
|
+
val: absoluteHumidity,
|
|
415
|
+
ack: true,
|
|
416
|
+
});
|
|
417
|
+
await this.setStateChangedAsync(`${deviceObjectId}.${STATE_DEW_POINT_TEMPERATURE}`, {
|
|
418
|
+
val: dewPointTemperature,
|
|
419
|
+
ack: true,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @param {string} stateId
|
|
425
|
+
*/
|
|
426
|
+
async readNumberState(stateId) {
|
|
427
|
+
const state = await this.getForeignStateAsync(stateId);
|
|
428
|
+
const value = Number(state?.val);
|
|
429
|
+
|
|
430
|
+
return Number.isFinite(value) ? value : null;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* @param {string} id
|
|
435
|
+
*/
|
|
436
|
+
getDeviceObjectId(id) {
|
|
437
|
+
return `${DEVICE_ROOT}.${id}`;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Is called when adapter shuts down - callback has to be called under any circumstances!
|
|
442
|
+
*
|
|
443
|
+
* @param {() => void} callback - Callback function
|
|
444
|
+
*/
|
|
445
|
+
onUnload(callback) {
|
|
446
|
+
try {
|
|
447
|
+
callback();
|
|
448
|
+
} catch (error) {
|
|
449
|
+
this.log.error(`Error during unloading: ${error.message}`);
|
|
450
|
+
callback();
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (require.main !== module) {
|
|
456
|
+
/**
|
|
457
|
+
* @param {Partial<utils.AdapterOptions>} [options]
|
|
458
|
+
*/
|
|
459
|
+
module.exports = options => new Absolutehumidity(options);
|
|
460
|
+
} else {
|
|
461
|
+
new Absolutehumidity();
|
|
462
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "iobroker.absolutehumidity",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "build absolute humidity from actual temperature and relative humidity",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "BenAhrdt",
|
|
7
|
+
"email": "github@ben-schmidt.net"
|
|
8
|
+
},
|
|
9
|
+
"contributors": [
|
|
10
|
+
{
|
|
11
|
+
"name": "J-Paul0815"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/BenAhrdt/ioBroker.absolutehumidity",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"absolute Humidity",
|
|
18
|
+
"dewpoint temperature"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git@github.com:BenAhrdt/ioBroker.absolutehumidity.git"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">= 20"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@iobroker/adapter-core": "^3.4.1",
|
|
29
|
+
"@iobroker/dm-utils": "^3.1.1"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@alcalzone/release-script": "^5.2.1",
|
|
33
|
+
"@alcalzone/release-script-plugin-iobroker": "^5.2.0",
|
|
34
|
+
"@alcalzone/release-script-plugin-license": "^5.2.0",
|
|
35
|
+
"@alcalzone/release-script-plugin-manual-review": "^5.2.0",
|
|
36
|
+
"@iobroker/adapter-dev": "^1.5.0",
|
|
37
|
+
"@iobroker/dev-server": "^0.8.0",
|
|
38
|
+
"@iobroker/eslint-config": "^2.3.4",
|
|
39
|
+
"@iobroker/testing": "^5.2.2",
|
|
40
|
+
"@tsconfig/node20": "^20.1.9",
|
|
41
|
+
"@types/iobroker": "npm:@iobroker/types@^7.2.2",
|
|
42
|
+
"@types/node": "^20.19.43",
|
|
43
|
+
"typescript": "~5.9.3"
|
|
44
|
+
},
|
|
45
|
+
"main": "main.js",
|
|
46
|
+
"files": [
|
|
47
|
+
"admin{,/!(src)/**}/!(tsconfig|tsconfig.*|.eslintrc).{json,json5}",
|
|
48
|
+
"admin{,/!(src)/**}/*.{html,css,png,svg,jpg,js}",
|
|
49
|
+
"lib/",
|
|
50
|
+
"www/",
|
|
51
|
+
"io-package.json",
|
|
52
|
+
"LICENSE",
|
|
53
|
+
"main.js"
|
|
54
|
+
],
|
|
55
|
+
"scripts": {
|
|
56
|
+
"test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
|
|
57
|
+
"test:package": "mocha test/package --exit",
|
|
58
|
+
"test:integration": "mocha test/integration --exit",
|
|
59
|
+
"test": "npm run test:js && npm run test:package",
|
|
60
|
+
"check": "tsc --noEmit -p tsconfig.check.json",
|
|
61
|
+
"lint": "eslint -c eslint.config.mjs .",
|
|
62
|
+
"translate": "translate-adapter",
|
|
63
|
+
"release": "release-script",
|
|
64
|
+
"dev-server": "dev-server"
|
|
65
|
+
},
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/BenAhrdt/ioBroker.absolutehumidity/issues"
|
|
68
|
+
},
|
|
69
|
+
"readmeFilename": "README.md"
|
|
70
|
+
}
|