iobroker.drag-indicator 2.2.0 → 2.3.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/README.md +6 -0
- package/admin/jsonConfig.json +15 -3
- package/io-package.json +27 -27
- package/main.js +365 -368
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -21,6 +21,12 @@ e.g. you can use it for power or temperature values.
|
|
|
21
21
|
Placeholder for the next version (at the beginning of the line):
|
|
22
22
|
### **WORK IN PROGRESS**
|
|
23
23
|
-->
|
|
24
|
+
### 2.3.0 (2024-12-04)
|
|
25
|
+
* (BenAhrdt) update eslint
|
|
26
|
+
|
|
27
|
+
### 2.2.1 (2024-11-26)
|
|
28
|
+
* (BenAhrdt) update schema and responsive tags
|
|
29
|
+
|
|
24
30
|
### 2.2.0 (2024-08-13)
|
|
25
31
|
* (BenAhrdt) Update Dependencies: "js-controller": ">=5.0.19"
|
|
26
32
|
Check your System before installing new Version
|
package/admin/jsonConfig.json
CHANGED
|
@@ -5,13 +5,21 @@
|
|
|
5
5
|
"deleteStatesWithDisable": {
|
|
6
6
|
"type": "checkbox",
|
|
7
7
|
"label": "deleteStateWithDisableText",
|
|
8
|
-
"
|
|
8
|
+
"xs": 12,
|
|
9
|
+
"sm": 6,
|
|
10
|
+
"md": 6,
|
|
11
|
+
"lg": 6,
|
|
12
|
+
"xl": 6
|
|
9
13
|
},
|
|
10
14
|
"emptyField":{
|
|
11
15
|
"text": "",
|
|
12
16
|
"type":"staticText",
|
|
13
17
|
"newLine": true,
|
|
14
|
-
"
|
|
18
|
+
"xs": 12,
|
|
19
|
+
"sm": 3,
|
|
20
|
+
"md": 3,
|
|
21
|
+
"lg": 3,
|
|
22
|
+
"xl": 3
|
|
15
23
|
},
|
|
16
24
|
"infoToCustomConfig": {
|
|
17
25
|
"type": "staticText",
|
|
@@ -19,7 +27,11 @@
|
|
|
19
27
|
"style": {
|
|
20
28
|
"color": "red"
|
|
21
29
|
},
|
|
22
|
-
"
|
|
30
|
+
"xs": 12,
|
|
31
|
+
"sm": 6,
|
|
32
|
+
"md": 6,
|
|
33
|
+
"lg": 6,
|
|
34
|
+
"xl": 6
|
|
23
35
|
}
|
|
24
36
|
}
|
|
25
37
|
}
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "drag-indicator",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.3.0": {
|
|
7
|
+
"en": "update eslint",
|
|
8
|
+
"de": "update eslint",
|
|
9
|
+
"ru": "обновление eslint",
|
|
10
|
+
"pt": "atualização eslint",
|
|
11
|
+
"nl": "eslint bijwerken",
|
|
12
|
+
"fr": "mettre à jour eslint",
|
|
13
|
+
"it": "aggiornamento eslint",
|
|
14
|
+
"es": "update eslint",
|
|
15
|
+
"pl": "update eslint",
|
|
16
|
+
"uk": "оновлення eslint",
|
|
17
|
+
"zh-cn": "更新埃斯林特"
|
|
18
|
+
},
|
|
19
|
+
"2.2.1": {
|
|
20
|
+
"en": "update schema and responsive tags",
|
|
21
|
+
"de": "schema und responsive tags aktualisieren",
|
|
22
|
+
"ru": "обновление схемы и адаптивные теги",
|
|
23
|
+
"pt": "atualização schema e tags responsivas",
|
|
24
|
+
"nl": "schema en responsieve tags bijwerken",
|
|
25
|
+
"fr": "mettre à jour le schéma et les balises réactives",
|
|
26
|
+
"it": "schema di aggiornamento e tag reattivi",
|
|
27
|
+
"es": "schema de actualización y etiquetas sensibles",
|
|
28
|
+
"pl": "aktualizacja schematów i identyfikatorów odpowiedzi",
|
|
29
|
+
"uk": "оновлення schema і чуйних тегів",
|
|
30
|
+
"zh-cn": "更新计划和响应标记"
|
|
31
|
+
},
|
|
6
32
|
"2.2.0": {
|
|
7
33
|
"en": "* Update Dependencies: \"js-controller\": \">=5.0.19\"\n Check your System before installing new Version",
|
|
8
34
|
"de": "* Update Dependencies: \"js-controller\": \">=5.0.19\"\nÜberprüfen Sie Ihr System vor der Installation neuer Version",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "tłumaczenie dla uk dodała",
|
|
68
94
|
"uk": "переклад для uk додано",
|
|
69
95
|
"zh-cn": "增 编"
|
|
70
|
-
},
|
|
71
|
-
"2.1.2": {
|
|
72
|
-
"en": "insert check vor node version >= 16",
|
|
73
|
-
"de": "kontrollieren vor knoten version >= anhang",
|
|
74
|
-
"ru": "вставить проверить vor node версия >= 16, 16, 16",
|
|
75
|
-
"pt": "insert check vor node version >= 16",
|
|
76
|
-
"nl": "insert check vor node versie 16",
|
|
77
|
-
"fr": "insert check vor node version phy= 16",
|
|
78
|
-
"it": ">= 16",
|
|
79
|
-
"es": "introducir ver la versión del nodo vor 16",
|
|
80
|
-
"pl": "instrukcja wejściowa w wersji węzłowej >== 16",
|
|
81
|
-
"uk": "вставити перевірку вихрового вузла версії >= 16 мар",
|
|
82
|
-
"zh-cn": "加 检查 16"
|
|
83
|
-
},
|
|
84
|
-
"2.1.1": {
|
|
85
|
-
"en": "correction in jsonconfig schema",
|
|
86
|
-
"de": "korrektur im jsonconfig schema",
|
|
87
|
-
"ru": "коррекция в jsonconfig schema",
|
|
88
|
-
"pt": "correção em jsonconfig schema",
|
|
89
|
-
"nl": "vertaling:",
|
|
90
|
-
"fr": "correction dans le schéma de jsonconfig",
|
|
91
|
-
"it": "correzione nello schema jsonconfig",
|
|
92
|
-
"es": "corrección en jsonconfig schema",
|
|
93
|
-
"pl": "poprawka w schemacie jsonconfig",
|
|
94
|
-
"uk": "корекція в jsonconfig schema",
|
|
95
|
-
"zh-cn": "更正"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
* Created with @iobroker/create-adapter v2.1.1
|
|
@@ -6,400 +6,397 @@
|
|
|
6
6
|
|
|
7
7
|
// The adapter-core module gives you access to the core ioBroker functions
|
|
8
8
|
// you need to create an adapter
|
|
9
|
-
const utils = require(
|
|
10
|
-
const schedule = require(
|
|
11
|
-
const { isDeepStrictEqual } = require(
|
|
9
|
+
const utils = require('@iobroker/adapter-core');
|
|
10
|
+
const schedule = require('node-schedule');
|
|
11
|
+
const { isDeepStrictEqual } = require('util');
|
|
12
12
|
|
|
13
13
|
// Load your modules here, e.g.:
|
|
14
14
|
// const fs = require("fs");
|
|
15
15
|
|
|
16
16
|
class DragIndicator extends utils.Adapter {
|
|
17
|
+
/**
|
|
18
|
+
* @param [options] options of the adapter
|
|
19
|
+
*/
|
|
20
|
+
constructor(options) {
|
|
21
|
+
super({
|
|
22
|
+
...options,
|
|
23
|
+
name: 'drag-indicator',
|
|
24
|
+
});
|
|
25
|
+
this.on('ready', this.onReady.bind(this));
|
|
26
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
27
|
+
this.on('objectChange', this.onObjectChange.bind(this));
|
|
28
|
+
// this.on("message", this.onMessage.bind(this));
|
|
29
|
+
this.on('unload', this.onUnload.bind(this));
|
|
17
30
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
constructor(options) {
|
|
22
|
-
super({
|
|
23
|
-
...options,
|
|
24
|
-
name: "drag-indicator",
|
|
25
|
-
});
|
|
26
|
-
this.on("ready", this.onReady.bind(this));
|
|
27
|
-
this.on("stateChange", this.onStateChange.bind(this));
|
|
28
|
-
this.on("objectChange", this.onObjectChange.bind(this));
|
|
29
|
-
// this.on("message", this.onMessage.bind(this));
|
|
30
|
-
this.on("unload", this.onUnload.bind(this));
|
|
31
|
+
this.subscribecounterId = 'info.subscribedStatesCount';
|
|
32
|
+
this.subscribecounter = 0;
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
this.additionalIds = {
|
|
35
|
+
max: '.max',
|
|
36
|
+
min: '.min',
|
|
37
|
+
reset: '.reset',
|
|
38
|
+
actual: '.actual',
|
|
39
|
+
};
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
reset : ".reset",
|
|
39
|
-
actual : ".actual"
|
|
40
|
-
};
|
|
41
|
+
this.observedValuesId = 'observed_Values.';
|
|
42
|
+
this.cronJobs = {};
|
|
43
|
+
this.jobId = 'jobId';
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
// define arrays for selected states and calculation
|
|
46
|
+
this.activeStates = {};
|
|
47
|
+
this.activeStatesLastAdditionalValues = {};
|
|
48
|
+
}
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Is called when databases are connected and adapter received configuration.
|
|
52
|
+
*/
|
|
53
|
+
async onReady() {
|
|
54
|
+
// Initialize your adapter here
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
*/
|
|
54
|
-
async onReady() {
|
|
55
|
-
// Initialize your adapter here
|
|
56
|
+
//Read all states with custom configuration
|
|
57
|
+
const customStateArray = await this.getObjectViewAsync('system', 'custom', {});
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
// Request if there is an object
|
|
60
|
+
if (customStateArray && customStateArray.rows) {
|
|
61
|
+
for (let index = 0; index < customStateArray.rows.length; index++) {
|
|
62
|
+
if (customStateArray.rows[index].value !== null) {
|
|
63
|
+
// Request if there is an object for this namespace an its enabled
|
|
64
|
+
if (
|
|
65
|
+
customStateArray.rows[index].value[this.namespace] &&
|
|
66
|
+
customStateArray.rows[index].value[this.namespace].enabled === true
|
|
67
|
+
) {
|
|
68
|
+
const id = customStateArray.rows[index].id;
|
|
69
|
+
const obj = await this.getForeignObjectAsync(id);
|
|
70
|
+
if (obj) {
|
|
71
|
+
const common = obj.common;
|
|
72
|
+
const state = await this.getForeignStateAsync(id);
|
|
73
|
+
if (state) {
|
|
74
|
+
await this.addObjectAndCreateState(
|
|
75
|
+
id,
|
|
76
|
+
common,
|
|
77
|
+
customStateArray.rows[index].value[this.namespace],
|
|
78
|
+
state,
|
|
79
|
+
true,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
59
87
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
for(let index = 0 ; index < customStateArray.rows.length ; index++){
|
|
64
|
-
if(customStateArray.rows[index].value !== null){
|
|
65
|
-
// Request if there is an object for this namespace an its enabled
|
|
66
|
-
if (customStateArray.rows[index].value[this.namespace] && customStateArray.rows[index].value[this.namespace].enabled === true) {
|
|
67
|
-
const id = customStateArray.rows[index].id;
|
|
68
|
-
const obj = await this.getForeignObjectAsync(id);
|
|
69
|
-
if(obj){
|
|
70
|
-
const common = obj.common;
|
|
71
|
-
const state = await this.getForeignStateAsync(id);
|
|
72
|
-
if(state){
|
|
73
|
-
await this.addObjectAndCreateState(id,common,customStateArray.rows[index].value[this.namespace],state,true);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
88
|
+
this.subscribeForeignObjects('*');
|
|
89
|
+
this.setState(this.subscribecounterId, this.subscribecounter, true);
|
|
90
|
+
}
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Is called when adapter shuts down - callback has to be called under any circumstances!
|
|
94
|
+
*
|
|
95
|
+
* @param callback function wich is called after shutdown adapter
|
|
96
|
+
*/
|
|
97
|
+
onUnload(callback) {
|
|
98
|
+
try {
|
|
99
|
+
// clear all schedules
|
|
100
|
+
for (const cronJob in this.cronJobs) {
|
|
101
|
+
schedule.cancelJob(this.cronJobs[cronJob][this.jobId]);
|
|
102
|
+
}
|
|
103
|
+
callback();
|
|
104
|
+
} catch (e) {
|
|
105
|
+
this.log.error(e);
|
|
106
|
+
callback();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
84
109
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
110
|
+
async addObjectAndCreateState(id, common, customInfo, state, countUpSubscibecounter) {
|
|
111
|
+
// check if custominfo is available
|
|
112
|
+
if (!customInfo) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (common.type != 'number') {
|
|
116
|
+
this.log.error(`state ${id} is not type number, but ${common.type}`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.activeStates[id] = {};
|
|
120
|
+
this.activeStates[id].customInfo = customInfo;
|
|
121
|
+
// Create adapter internal object
|
|
122
|
+
const tempId = this.createStatestring(id);
|
|
123
|
+
await this.setObjectAsync(tempId, {
|
|
124
|
+
type: 'channel',
|
|
125
|
+
common: {
|
|
126
|
+
name: customInfo.channelName,
|
|
127
|
+
},
|
|
128
|
+
native: {},
|
|
129
|
+
});
|
|
101
130
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
// create adapter internal states
|
|
132
|
+
for (const myId in this.additionalIds) {
|
|
133
|
+
const tempId = this.createStatestring(id) + this.additionalIds[myId];
|
|
134
|
+
if (this.additionalIds[myId] == this.additionalIds.reset) {
|
|
135
|
+
await this.setObjectNotExistsAsync(tempId, {
|
|
136
|
+
type: 'state',
|
|
137
|
+
common: {
|
|
138
|
+
name: myId,
|
|
139
|
+
type: 'boolean',
|
|
140
|
+
role: 'reset',
|
|
141
|
+
read: true,
|
|
142
|
+
write: true,
|
|
143
|
+
def: false,
|
|
144
|
+
},
|
|
145
|
+
native: {},
|
|
146
|
+
});
|
|
147
|
+
this.log.debug(`state ${tempId} added / activated`);
|
|
148
|
+
this.subscribeStates(tempId);
|
|
149
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`] = id;
|
|
150
|
+
this.setState(tempId, false, true);
|
|
151
|
+
} else {
|
|
152
|
+
await this.setObjectNotExistsAsync(tempId, {
|
|
153
|
+
type: 'state',
|
|
154
|
+
common: {
|
|
155
|
+
name: common.name,
|
|
156
|
+
type: common.type,
|
|
157
|
+
role: common.role,
|
|
158
|
+
unit: common.unit,
|
|
159
|
+
read: true,
|
|
160
|
+
write: this.additionalIds[myId] !== this.additionalIds.actual,
|
|
161
|
+
},
|
|
162
|
+
native: {},
|
|
163
|
+
});
|
|
164
|
+
if (this.additionalIds[myId] !== this.additionalIds.actual) {
|
|
165
|
+
this.log.debug(`state ${tempId} added / activated`);
|
|
166
|
+
this.subscribeStates(tempId);
|
|
167
|
+
}
|
|
168
|
+
const lastState = await this.getStateAsync(tempId);
|
|
169
|
+
if (lastState !== undefined && lastState !== null) {
|
|
170
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`] = lastState.val;
|
|
171
|
+
} else {
|
|
172
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`] = state.val;
|
|
173
|
+
this.setState(tempId, state.val, true);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (customInfo.resetCronJob != '') {
|
|
178
|
+
// check that ther is a cronjob configured
|
|
179
|
+
if (!this.cronJobs[customInfo.resetCronJob]) {
|
|
180
|
+
this.cronJobs[customInfo.resetCronJob] = {};
|
|
181
|
+
this.cronJobs[customInfo.resetCronJob][this.jobId] = schedule.scheduleJob(
|
|
182
|
+
customInfo.resetCronJob,
|
|
183
|
+
this.resetWithCronJob.bind(this, customInfo.resetCronJob),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
this.cronJobs[customInfo.resetCronJob][this.createStatestring(id)] = {};
|
|
187
|
+
this.activeStates[id].lastCronJob = customInfo.resetCronJob;
|
|
188
|
+
} else {
|
|
189
|
+
this.activeStates[id].lastCronJob = '';
|
|
190
|
+
}
|
|
124
191
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
name: myId,
|
|
133
|
-
type: "boolean",
|
|
134
|
-
role: "reset",
|
|
135
|
-
read: true,
|
|
136
|
-
write: true,
|
|
137
|
-
def: false
|
|
138
|
-
},
|
|
139
|
-
native: {},
|
|
140
|
-
});
|
|
141
|
-
this.log.debug(`state ${tempId} added / activated`);
|
|
142
|
-
this.subscribeStates(tempId);
|
|
143
|
-
this.activeStatesLastAdditionalValues[this.namespace + "." + tempId] = id;
|
|
144
|
-
this.setState(tempId,false,true);
|
|
145
|
-
}
|
|
146
|
-
else{
|
|
147
|
-
await this.setObjectNotExistsAsync(tempId,{
|
|
148
|
-
type: "state",
|
|
149
|
-
common: {
|
|
150
|
-
name: common.name,
|
|
151
|
-
type: common.type,
|
|
152
|
-
role: common.role,
|
|
153
|
-
unit: common.unit,
|
|
154
|
-
read: true,
|
|
155
|
-
write: this.additionalIds[myId] !== this.additionalIds.actual
|
|
156
|
-
},
|
|
157
|
-
native: {},
|
|
158
|
-
});
|
|
159
|
-
if(this.additionalIds[myId] !== this.additionalIds.actual){
|
|
160
|
-
this.log.debug(`state ${tempId} added / activated`);
|
|
161
|
-
this.subscribeStates(tempId);
|
|
162
|
-
}
|
|
163
|
-
const lastState = await this.getStateAsync(tempId);
|
|
164
|
-
if(lastState !== undefined && lastState !== null){
|
|
165
|
-
this.activeStatesLastAdditionalValues[this.namespace + "." + tempId] = lastState.val;
|
|
166
|
-
}
|
|
167
|
-
else{
|
|
168
|
-
this.activeStatesLastAdditionalValues[this.namespace + "." + tempId] = state.val;
|
|
169
|
-
this.setState(tempId,state.val,true);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if(customInfo.resetCronJob != ""){ // check that ther is a cronjob configured
|
|
174
|
-
if(!this.cronJobs[customInfo.resetCronJob]){
|
|
175
|
-
this.cronJobs[customInfo.resetCronJob] = {};
|
|
176
|
-
this.cronJobs[customInfo.resetCronJob][this.jobId] = schedule.scheduleJob(customInfo.resetCronJob,this.resetWithCronJob.bind(this,customInfo.resetCronJob));
|
|
177
|
-
}
|
|
178
|
-
this.cronJobs[customInfo.resetCronJob][this.createStatestring(id)] = {};
|
|
179
|
-
this.activeStates[id].lastCronJob = customInfo.resetCronJob;
|
|
180
|
-
}
|
|
181
|
-
else
|
|
182
|
-
{
|
|
183
|
-
this.activeStates[id].lastCronJob = "";
|
|
184
|
-
}
|
|
192
|
+
// Subcribe main state
|
|
193
|
+
if (countUpSubscibecounter) {
|
|
194
|
+
this.subscribeForeignStates(id);
|
|
195
|
+
this.subscribecounter += 1;
|
|
196
|
+
this.setState(this.subscribecounterId, this.subscribecounter, true);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
// if the id is scheduled, it will be deleted from active array
|
|
201
|
+
removefromCronJob(cronJob, id) {
|
|
202
|
+
if (this.activeStates[id].lastCronJob != '') {
|
|
203
|
+
delete this.cronJobs[cronJob][this.createStatestring(id)];
|
|
204
|
+
if (Object.keys(this.cronJobs[cronJob]).length <= 1) {
|
|
205
|
+
this.log.debug(`job canceled: ${cronJob}`);
|
|
206
|
+
schedule.cancelJob(this.cronJobs[cronJob][this.jobId]);
|
|
207
|
+
delete this.cronJobs[cronJob];
|
|
208
|
+
}
|
|
209
|
+
this.activeStates[id].lastCronJob = '';
|
|
210
|
+
}
|
|
211
|
+
}
|
|
193
212
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if(this.activeStates[id].lastCronJob != ""){
|
|
198
|
-
delete this.cronJobs[cronJob][this.createStatestring(id)];
|
|
199
|
-
if(Object.keys(this.cronJobs[cronJob]).length <= 1)
|
|
200
|
-
{
|
|
201
|
-
this.log.debug("job canceled: " + cronJob);
|
|
202
|
-
schedule.cancelJob(this.cronJobs[cronJob][this.jobId]);
|
|
203
|
-
delete this.cronJobs[cronJob];
|
|
204
|
-
}
|
|
205
|
-
this.activeStates[id].lastCronJob = "";
|
|
206
|
-
}
|
|
207
|
-
}
|
|
213
|
+
createStatestring(id) {
|
|
214
|
+
return `${this.observedValuesId}${id.replace(/\./g, '_')}`;
|
|
215
|
+
}
|
|
208
216
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
217
|
+
// clear the state from the active array. if selected the state will be deleted
|
|
218
|
+
async clearStateArrayElement(id, deleteState) {
|
|
219
|
+
// Unsubscribe and delete states if exists
|
|
220
|
+
if (this.activeStates[id]) {
|
|
221
|
+
this.removefromCronJob(this.activeStates[id].lastCronJob, id);
|
|
222
|
+
delete this.activeStates[id];
|
|
223
|
+
this.subscribecounter -= 1;
|
|
224
|
+
this.setState(this.subscribecounterId, this.subscribecounter, true);
|
|
225
|
+
if (!this.activeStatesLastAdditionalValues[id]) {
|
|
226
|
+
// Dont unsubscribe in case of is additional value
|
|
227
|
+
this.unsubscribeForeignStates(id);
|
|
228
|
+
this.log.debug(`state ${id} not longer subscribed`);
|
|
229
|
+
} else {
|
|
230
|
+
this.log.debug(`state ${id} not longer subscribed as active state, but still as additional`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (this.config.deleteStatesWithDisable || deleteState) {
|
|
234
|
+
for (const myId in this.additionalIds) {
|
|
235
|
+
const tempId = this.createStatestring(id) + this.additionalIds[myId];
|
|
236
|
+
const myObj = await this.getObjectAsync(tempId);
|
|
237
|
+
if (myObj) {
|
|
238
|
+
this.unsubscribeStatesAsync(tempId);
|
|
239
|
+
this.log.debug(`state ${tempId} removed`);
|
|
240
|
+
this.delObjectAsync(tempId);
|
|
241
|
+
this.log.debug(`state ${this.namespace}.${tempId} deleted`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Delete channel Object
|
|
245
|
+
this.delObjectAsync(this.createStatestring(id));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
212
248
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// Unsubscribe and delete states if exists
|
|
217
|
-
if(this.activeStates[id]){
|
|
218
|
-
this.removefromCronJob(this.activeStates[id].lastCronJob,id);
|
|
219
|
-
delete this.activeStates[id];
|
|
220
|
-
this.subscribecounter -= 1;
|
|
221
|
-
this.setState(this.subscribecounterId,this.subscribecounter,true);
|
|
222
|
-
if(!this.activeStatesLastAdditionalValues[id]){ // Dont unsubscribe in case of is additional value
|
|
223
|
-
this.unsubscribeForeignStates(id);
|
|
224
|
-
this.log.debug(`state ${id} not longer subscribed`);
|
|
225
|
-
}
|
|
226
|
-
else{
|
|
227
|
-
this.log.debug(`state ${id} not longer subscribed as active state, but still as additional`);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if(this.config.deleteStatesWithDisable || deleteState){
|
|
231
|
-
for(const myId in this.additionalIds){
|
|
232
|
-
const tempId = this.createStatestring(id) + this.additionalIds[myId];
|
|
233
|
-
const myObj = await this.getObjectAsync(tempId);
|
|
234
|
-
if(myObj){
|
|
235
|
-
this.unsubscribeStatesAsync(tempId);
|
|
236
|
-
this.log.debug(`state ${tempId} removed`);
|
|
237
|
-
this.delObjectAsync(tempId);
|
|
238
|
-
this.log.debug(`state ${this.namespace}.${tempId} deleted`);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
// Delete channel Object
|
|
242
|
-
this.delObjectAsync(this.createStatestring(id));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
249
|
+
/***************************************************************************************
|
|
250
|
+
* ********************************** Changes ******************************************
|
|
251
|
+
***************************************************************************************/
|
|
245
252
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
async onObjectChange(id, obj) {
|
|
254
|
+
if (obj) {
|
|
255
|
+
try {
|
|
256
|
+
if (!obj.common.custom || !obj.common.custom[this.namespace]) {
|
|
257
|
+
if (this.activeStates[id]) {
|
|
258
|
+
this.clearStateArrayElement(id, false);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
const customInfo = obj.common.custom[this.namespace];
|
|
263
|
+
if (this.activeStates[id]) {
|
|
264
|
+
const state = await this.getForeignStateAsync(id);
|
|
265
|
+
if (state) {
|
|
266
|
+
if (!isDeepStrictEqual(this.activeStates[id].customInfo, customInfo)) {
|
|
267
|
+
this.removefromCronJob(this.activeStates[id].lastCronJob, id);
|
|
268
|
+
await this.addObjectAndCreateState(id, obj.common, customInfo, state, false);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
const state = await this.getForeignStateAsync(id);
|
|
273
|
+
if (state) {
|
|
274
|
+
this.addObjectAndCreateState(id, obj.common, customInfo, state, true);
|
|
275
|
+
} else {
|
|
276
|
+
this.log.error(`could not read state ${id}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
this.log.error(error);
|
|
282
|
+
this.clearStateArrayElement(id, false);
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
// The object was deleted
|
|
286
|
+
// Check if the object is kwnow
|
|
287
|
+
const obj = await this.getObjectAsync(this.createStatestring(id) + this.additionalIds.consumed);
|
|
288
|
+
if (this.activeStates[id] || obj) {
|
|
289
|
+
this.clearStateArrayElement(id, true);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
249
293
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
} else {
|
|
290
|
-
// The object was deleted
|
|
291
|
-
// Check if the object is kwnow
|
|
292
|
-
const obj = await this.getObjectAsync(this.createStatestring(id) + this.additionalIds.consumed);
|
|
293
|
-
if(this.activeStates[id] || obj)
|
|
294
|
-
{
|
|
295
|
-
this.clearStateArrayElement(id,true);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
294
|
+
resetWithCronJob(cronJob) {
|
|
295
|
+
for (const ele in this.cronJobs[cronJob]) {
|
|
296
|
+
if (ele != this.jobId) {
|
|
297
|
+
this.resetValues(
|
|
298
|
+
`${this.namespace}.${ele}${this.additionalIds.reset}`,
|
|
299
|
+
this.namespace.length,
|
|
300
|
+
this.additionalIds.reset.length,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Is called if a subscribed state changes
|
|
307
|
+
*
|
|
308
|
+
* @param id id of the changed state
|
|
309
|
+
* @param state state (val & ack) of the changed state-id
|
|
310
|
+
*/
|
|
311
|
+
async onStateChange(id, state) {
|
|
312
|
+
if (state) {
|
|
313
|
+
// Check if state.val is reachable
|
|
314
|
+
if (state.val !== undefined && state.val !== null) {
|
|
315
|
+
// Check Changes in Foreign states
|
|
316
|
+
if (this.activeStates[id]) {
|
|
317
|
+
let tempId = this.createStatestring(id) + this.additionalIds.max;
|
|
318
|
+
if (state.val > this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`]) {
|
|
319
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`] = state.val;
|
|
320
|
+
this.setStateAsync(tempId, state.val, true);
|
|
321
|
+
} else {
|
|
322
|
+
tempId = this.createStatestring(id) + this.additionalIds.min;
|
|
323
|
+
if (state.val < this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`]) {
|
|
324
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${tempId}`] = state.val;
|
|
325
|
+
this.setStateAsync(tempId, state.val, true);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Set actual value to internal state
|
|
329
|
+
tempId = this.createStatestring(id) + this.additionalIds.actual;
|
|
330
|
+
this.setStateAsync(tempId, state.val, true);
|
|
331
|
+
}
|
|
299
332
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
// Set actual value to internal state
|
|
331
|
-
tempId = this.createStatestring(id) + this.additionalIds.actual;
|
|
332
|
-
this.setStateAsync(tempId,state.val,true);
|
|
333
|
-
}
|
|
333
|
+
// Check Changes in internal States (also if id is active state)
|
|
334
|
+
if (
|
|
335
|
+
this.activeStatesLastAdditionalValues[id] !== undefined &&
|
|
336
|
+
this.activeStatesLastAdditionalValues[id] !== null &&
|
|
337
|
+
!state.ack
|
|
338
|
+
) {
|
|
339
|
+
const extentionLength = this.additionalIds.reset.length;
|
|
340
|
+
const extention = id.substring(id.length - extentionLength);
|
|
341
|
+
const prefixLengt = this.namespace.length;
|
|
342
|
+
const prefix = id.substring(0, prefixLengt);
|
|
343
|
+
if (extention == this.additionalIds.reset && prefix == this.namespace) {
|
|
344
|
+
// check that reset is true
|
|
345
|
+
if (state.val == true) {
|
|
346
|
+
this.resetValues(id, prefixLengt, extentionLength);
|
|
347
|
+
this.setStateAsync(id, true, true);
|
|
348
|
+
} else {
|
|
349
|
+
this.setStateAsync(id, false, true);
|
|
350
|
+
}
|
|
351
|
+
} else {
|
|
352
|
+
this.activeStatesLastAdditionalValues[id] = state.val;
|
|
353
|
+
this.setStateAsync(id, state.val, true);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
// The state was deleted
|
|
359
|
+
this.log.debug(`state ${id} deleted`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
334
362
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
} else {
|
|
359
|
-
// The state was deleted
|
|
360
|
-
this.log.debug(`state ${id} deleted`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
async resetValues(id,prefixLengt,extentionLength){
|
|
365
|
-
const subId = id.substring(prefixLengt + 1,id.length - extentionLength);
|
|
366
|
-
// Get current state
|
|
367
|
-
const curState = await this.getForeignStateAsync(this.activeStatesLastAdditionalValues[id]);
|
|
368
|
-
if(curState){
|
|
369
|
-
this.activeStatesLastAdditionalValues[this.namespace + "." + subId + this.additionalIds.max] = curState.val;
|
|
370
|
-
this.setStateAsync(subId + this.additionalIds.max,curState.val,true);
|
|
371
|
-
this.activeStatesLastAdditionalValues[this.namespace + "." + subId + this.additionalIds.min] = curState.val;
|
|
372
|
-
this.setStateAsync(subId + this.additionalIds.min,curState.val,true);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
// If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.
|
|
376
|
-
// /**
|
|
377
|
-
// * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...
|
|
378
|
-
// * Using this method requires "common.messagebox" property to be set to true in io-package.json
|
|
379
|
-
// * @param {ioBroker.Message} obj
|
|
380
|
-
// */
|
|
381
|
-
// onMessage(obj) {
|
|
382
|
-
// if (typeof obj === "object" && obj.message) {
|
|
383
|
-
// if (obj.command === "send") {
|
|
384
|
-
// // e.g. send email or pushover or whatever
|
|
385
|
-
// this.log.debug("send command");
|
|
386
|
-
|
|
387
|
-
// // Send response in callback if required
|
|
388
|
-
// if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback);
|
|
389
|
-
// }
|
|
390
|
-
// }
|
|
391
|
-
// }
|
|
363
|
+
async resetValues(id, prefixLengt, extentionLength) {
|
|
364
|
+
const subId = id.substring(prefixLengt + 1, id.length - extentionLength);
|
|
365
|
+
// Get current state
|
|
366
|
+
const curState = await this.getForeignStateAsync(this.activeStatesLastAdditionalValues[id]);
|
|
367
|
+
if (curState) {
|
|
368
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${subId}${this.additionalIds.max}`] = curState.val;
|
|
369
|
+
this.setStateAsync(subId + this.additionalIds.max, curState.val, true);
|
|
370
|
+
this.activeStatesLastAdditionalValues[`${this.namespace}.${subId}${this.additionalIds.min}`] = curState.val;
|
|
371
|
+
this.setStateAsync(subId + this.additionalIds.min, curState.val, true);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.
|
|
375
|
+
// /**
|
|
376
|
+
// * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...
|
|
377
|
+
// * Using this method requires "common.messagebox" property to be set to true in io-package.json
|
|
378
|
+
// * @param {ioBroker.Message} obj
|
|
379
|
+
// */
|
|
380
|
+
// onMessage(obj) {
|
|
381
|
+
// if (typeof obj === "object" && obj.message) {
|
|
382
|
+
// if (obj.command === "send") {
|
|
383
|
+
// // e.g. send email or pushover or whatever
|
|
384
|
+
// this.log.debug("send command");
|
|
392
385
|
|
|
386
|
+
// // Send response in callback if required
|
|
387
|
+
// if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback);
|
|
388
|
+
// }
|
|
389
|
+
// }
|
|
390
|
+
// }
|
|
393
391
|
}
|
|
394
392
|
|
|
395
|
-
|
|
396
393
|
if (require.main !== module) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
394
|
+
// Export the constructor in compact mode
|
|
395
|
+
/**
|
|
396
|
+
* @param [options] options of the adapter
|
|
397
|
+
*/
|
|
398
|
+
module.exports = options => new DragIndicator(options);
|
|
402
399
|
} else {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
400
|
+
// otherwise start the instance directly
|
|
401
|
+
new DragIndicator();
|
|
402
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.drag-indicator",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Shows the min and max of a selected value",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "BenAhrdt",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"node": ">= 18"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@iobroker/adapter-core": "^3.
|
|
26
|
+
"@iobroker/adapter-core": "^3.2.2",
|
|
27
27
|
"node-schedule": "^2.1.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
@@ -32,22 +32,22 @@
|
|
|
32
32
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
33
33
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
34
34
|
"@iobroker/adapter-dev": "^1.3.0",
|
|
35
|
-
"@iobroker/
|
|
35
|
+
"@iobroker/eslint-config": "^1.0.0",
|
|
36
|
+
"@iobroker/testing": "^5.0.0",
|
|
36
37
|
"@types/chai": "^4.3.11",
|
|
37
|
-
"@types/chai-as-promised": "^
|
|
38
|
-
"@types/mocha": "^10.0.
|
|
39
|
-
"@types/node": "^22.
|
|
38
|
+
"@types/chai-as-promised": "^8.0.1",
|
|
39
|
+
"@types/mocha": "^10.0.10",
|
|
40
|
+
"@types/node": "^22.10.1",
|
|
40
41
|
"@types/proxyquire": "^1.3.31",
|
|
41
42
|
"@types/sinon": "^17.0.3",
|
|
42
43
|
"@types/sinon-chai": "^3.2.12",
|
|
43
44
|
"chai": "^4.5.0",
|
|
44
|
-
"chai-as-promised": "^8.0.
|
|
45
|
-
"
|
|
46
|
-
"mocha": "^10.7.0",
|
|
45
|
+
"chai-as-promised": "^8.0.1",
|
|
46
|
+
"mocha": "^10.8.2",
|
|
47
47
|
"proxyquire": "^2.1.3",
|
|
48
|
-
"sinon": "^
|
|
48
|
+
"sinon": "^19.0.2",
|
|
49
49
|
"sinon-chai": "^3.7.0",
|
|
50
|
-
"typescript": "~5.
|
|
50
|
+
"typescript": "~5.7.2"
|
|
51
51
|
},
|
|
52
52
|
"main": "main.js",
|
|
53
53
|
"files": [
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"test:integration": "mocha test/integration --exit",
|
|
67
67
|
"test": "npm run test:js && npm run test:package",
|
|
68
68
|
"check": "tsc --noEmit -p tsconfig.check.json",
|
|
69
|
-
"lint": "eslint",
|
|
69
|
+
"lint": "eslint -c eslint.config.mjs .",
|
|
70
70
|
"translate": "translate-adapter",
|
|
71
71
|
"release": "release-script"
|
|
72
72
|
},
|