iobroker.ebus 3.2.4 → 3.2.6
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/.eslintrc.json +34 -34
- package/.releaseconfig.json +3 -0
- package/LICENSE +20 -20
- package/README.md +147 -130
- package/admin/index_m.html +419 -419
- package/admin/style.css +18 -18
- package/admin/words.js +27 -27
- package/io-package.json +218 -192
- package/lib/support_tools.js +370 -370
- package/lib/tools.js +99 -99
- package/main.js +1232 -1232
- package/package.json +13 -11
- package/widgets/ebus/lib/js/flot/jquery.canvaswrapper.js +549 -549
- package/widgets/ebus/lib/js/flot/jquery.colorhelpers.js +199 -199
- package/widgets/ebus/lib/js/flot/jquery.flot.axislabels.js +212 -212
- package/widgets/ebus/lib/js/flot/jquery.flot.browser.js +98 -98
- package/widgets/ebus/lib/js/flot/jquery.flot.categories.js +202 -202
- package/widgets/ebus/lib/js/flot/jquery.flot.composeImages.js +330 -330
- package/widgets/ebus/lib/js/flot/jquery.flot.crosshair.js +202 -202
- package/widgets/ebus/lib/js/flot/jquery.flot.drawSeries.js +662 -662
- package/widgets/ebus/lib/js/flot/jquery.flot.errorbars.js +375 -375
- package/widgets/ebus/lib/js/flot/jquery.flot.fillbetween.js +254 -254
- package/widgets/ebus/lib/js/flot/jquery.flot.flatdata.js +47 -47
- package/widgets/ebus/lib/js/flot/jquery.flot.hover.js +361 -361
- package/widgets/ebus/lib/js/flot/jquery.flot.image.js +249 -249
- package/widgets/ebus/lib/js/flot/jquery.flot.js +2953 -2953
- package/widgets/ebus/lib/js/flot/jquery.flot.legend.js +437 -437
- package/widgets/ebus/lib/js/flot/jquery.flot.logaxis.js +298 -298
- package/widgets/ebus/lib/js/flot/jquery.flot.navigate.js +834 -834
- package/widgets/ebus/lib/js/flot/jquery.flot.pie.js +794 -794
- package/widgets/ebus/lib/js/flot/jquery.flot.resize.js +60 -60
- package/widgets/ebus/lib/js/flot/jquery.flot.saturated.js +43 -43
- package/widgets/ebus/lib/js/flot/jquery.flot.selection.js +527 -527
- package/widgets/ebus/lib/js/flot/jquery.flot.stack.js +220 -220
- package/widgets/ebus/lib/js/flot/jquery.flot.symbol.js +98 -98
- package/widgets/ebus/lib/js/flot/jquery.flot.threshold.js +143 -143
- package/widgets/ebus/lib/js/flot/jquery.flot.time.js +586 -586
- package/widgets/ebus/lib/js/flot/jquery.flot.touch.js +320 -320
- package/widgets/ebus/lib/js/flot/jquery.flot.touchNavigate.js +360 -360
- package/widgets/ebus/lib/js/flot/jquery.flot.uiConstants.js +10 -10
- package/widgets/ebus/lib/js/flot/jquery.js +9473 -9473
- package/widgets/ebus/lib/js/lib/globalize.culture.en-US.js +33 -33
- package/widgets/ebus/lib/js/lib/globalize.js +1601 -1601
- package/widgets/ebus/lib/js/lib/jquery.event.drag.js +145 -145
- package/widgets/ebus/lib/js/lib/jquery.mousewheel.js +86 -86
- package/widgets/ebus.html +2395 -2395
- package/readme.txt +0 -297
package/main.js
CHANGED
|
@@ -1,1233 +1,1233 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* ebus adapter für iobroker
|
|
3
|
-
*
|
|
4
|
-
* Created: 15.09.2016 21:31:28
|
|
5
|
-
* Author: Rene
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/* jshint -W097 */// jshint strict:false
|
|
11
|
-
/*jslint node: true */
|
|
12
|
-
"use strict";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const utils = require("@iobroker/adapter-core");
|
|
18
|
-
const ebusdMinVersion = [23,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let adapter;
|
|
23
|
-
function startAdapter(options) {
|
|
24
|
-
options = options || {};
|
|
25
|
-
Object.assign(options, {
|
|
26
|
-
name: "ebus",
|
|
27
|
-
//#######################################
|
|
28
|
-
//
|
|
29
|
-
ready: function () {
|
|
30
|
-
try {
|
|
31
|
-
//adapter.log.debug('start');
|
|
32
|
-
main();
|
|
33
|
-
}
|
|
34
|
-
catch (e) {
|
|
35
|
-
adapter.log.error("exception catch after ready [" + e + "]");
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
//#######################################
|
|
39
|
-
// is called when adapter shuts down
|
|
40
|
-
unload: function (callback) {
|
|
41
|
-
try {
|
|
42
|
-
|
|
43
|
-
if (intervalID != null) {
|
|
44
|
-
clearInterval(intervalID);
|
|
45
|
-
}
|
|
46
|
-
if (updateTimerID != null) {
|
|
47
|
-
clearTimeout(updateTimerID);
|
|
48
|
-
}
|
|
49
|
-
adapter && adapter.log && adapter.log.info && adapter.log.info("cleaned everything up...");
|
|
50
|
-
//to do stop intervall
|
|
51
|
-
callback();
|
|
52
|
-
} catch (e) {
|
|
53
|
-
callback();
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
stateChange: async (id, state) => {
|
|
58
|
-
await HandleStateChange(id, state);
|
|
59
|
-
},
|
|
60
|
-
//#######################################
|
|
61
|
-
//
|
|
62
|
-
message: async (obj) => {
|
|
63
|
-
if (obj) {
|
|
64
|
-
switch (obj.command) {
|
|
65
|
-
case "findParams":
|
|
66
|
-
// e.g. send email or pushover or whatever
|
|
67
|
-
adapter.log.debug("findParams command");
|
|
68
|
-
// Send response in callback if required
|
|
69
|
-
await FindParams(obj);
|
|
70
|
-
break;
|
|
71
|
-
default:
|
|
72
|
-
adapter.log.error("unknown message " + obj.command);
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
//#######################################
|
|
78
|
-
//
|
|
79
|
-
});
|
|
80
|
-
adapter = new utils.Adapter(options);
|
|
81
|
-
|
|
82
|
-
return adapter;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const axios = require(
|
|
87
|
-
const net = require("net");
|
|
88
|
-
const { PromiseSocket } = require("promise-socket");
|
|
89
|
-
|
|
90
|
-
let intervalID=null;
|
|
91
|
-
let updateTimerID=null;
|
|
92
|
-
|
|
93
|
-
async function main() {
|
|
94
|
-
|
|
95
|
-
adapter.log.debug("start with interface ebusd ");
|
|
96
|
-
|
|
97
|
-
FillPolledVars();
|
|
98
|
-
FillHistoryVars();
|
|
99
|
-
|
|
100
|
-
await checkVariables();
|
|
101
|
-
|
|
102
|
-
await subscribeVars();
|
|
103
|
-
|
|
104
|
-
let readInterval = 5;
|
|
105
|
-
if (parseInt(adapter.config.readInterval) > 0) {
|
|
106
|
-
readInterval = adapter.config.readInterval;
|
|
107
|
-
}
|
|
108
|
-
adapter.log.debug("read every " + readInterval + " minutes");
|
|
109
|
-
intervalID = setInterval(Do, readInterval * 60 * 1000);
|
|
110
|
-
|
|
111
|
-
//read at adapterstart
|
|
112
|
-
await Do();
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
let requestRunning = false;
|
|
117
|
-
|
|
118
|
-
async function DoRequest() {
|
|
119
|
-
|
|
120
|
-
adapter.log.debug("DoRequest ");
|
|
121
|
-
|
|
122
|
-
if (!requestRunning) {
|
|
123
|
-
requestRunning = true;
|
|
124
|
-
await ebusd_ReadValues();
|
|
125
|
-
|
|
126
|
-
await ebusd_ReceiveData();
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
adapter.log.debug("DoRequest: do nothing already running ");
|
|
130
|
-
}
|
|
131
|
-
requestRunning = false;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function Do() {
|
|
135
|
-
|
|
136
|
-
adapter.log.debug("starting ... " );
|
|
137
|
-
|
|
138
|
-
await ebusd_Command();
|
|
139
|
-
|
|
140
|
-
await DoRequest();
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
async function HandleStateChange(id, state) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (state != null && state.ack !== true) {
|
|
149
|
-
|
|
150
|
-
adapter.log.debug("handle state change " + id);
|
|
151
|
-
const ids = id.split(".");
|
|
152
|
-
|
|
153
|
-
if (ids[2] === "cmd") {
|
|
154
|
-
await ebusd_Command();
|
|
155
|
-
StartDataRequest();
|
|
156
|
-
//see issue #77: only one request possible
|
|
157
|
-
//await Do();
|
|
158
|
-
}
|
|
159
|
-
//unhandled state change ebus.0.find
|
|
160
|
-
else if (ids[2] === "find") {
|
|
161
|
-
await ebusd_find();
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
adapter.log.warn("unhandled state change " + id);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
function StartDataRequest() {
|
|
171
|
-
|
|
172
|
-
if (updateTimerID != null) {
|
|
173
|
-
//already running
|
|
174
|
-
clearTimeout(updateTimerID);
|
|
175
|
-
updateTimerID = null;
|
|
176
|
-
}
|
|
177
|
-
//start or restart
|
|
178
|
-
updateTimerID = setTimeout(DataRequest, 500);
|
|
179
|
-
adapter.log.debug("StartDataRequest");
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
async function DataRequest() {
|
|
184
|
-
adapter.log.debug("get data after command and timeout");
|
|
185
|
-
if (updateTimerID != null) {
|
|
186
|
-
clearTimeout(updateTimerID);
|
|
187
|
-
updateTimerID = null;
|
|
188
|
-
}
|
|
189
|
-
await DoRequest();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
function FillPolledVars() {
|
|
195
|
-
|
|
196
|
-
if ( adapter.config.PolledDPs !== undefined && adapter.config.PolledDPs != null && adapter.config.PolledDPs.length > 0) {
|
|
197
|
-
adapter.log.debug("use new object list for polled vars");
|
|
198
|
-
|
|
199
|
-
//2023-02-10 only active vars
|
|
200
|
-
for (let i = 0; i < adapter.config.PolledDPs.length; i++) {
|
|
201
|
-
if (adapter.config.PolledDPs[i].active) {
|
|
202
|
-
oPolledVars.push(adapter.config.PolledDPs[i]);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
//make it compatible to old versions
|
|
209
|
-
adapter.log.debug("check old comma separeted list for polled vars");
|
|
210
|
-
const oPolled = adapter.config.PolledValues.split(",");
|
|
211
|
-
|
|
212
|
-
if (oPolled.length > 0) {
|
|
213
|
-
|
|
214
|
-
for (let i = 0; i < oPolled.length; i++) {
|
|
215
|
-
if (oPolled[i].length > 0) {
|
|
216
|
-
//console.log('add ' + oPolled[i]);
|
|
217
|
-
const value = {
|
|
218
|
-
circuit: "",
|
|
219
|
-
name: oPolled[i],
|
|
220
|
-
parameter: ""
|
|
221
|
-
}
|
|
222
|
-
oPolledVars.push(value);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
adapter.log.info("list of polled vars " + JSON.stringify(oPolledVars));
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
let oHistoryVars = [];
|
|
233
|
-
function FillHistoryVars() {
|
|
234
|
-
|
|
235
|
-
if (adapter.config.HistoryDPs !== undefined && adapter.config.HistoryDPs != null && adapter.config.HistoryDPs.length > 0) {
|
|
236
|
-
adapter.log.debug("use new object list for history vars");
|
|
237
|
-
oHistoryVars = adapter.config.HistoryDPs;
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
//make it compatible to old versions
|
|
241
|
-
adapter.log.debug("check old comma separeted list for history vars");
|
|
242
|
-
const oHistory = adapter.config.HistoryValues.split(",");
|
|
243
|
-
|
|
244
|
-
if (oHistory.length > 0) {
|
|
245
|
-
|
|
246
|
-
for (let i = 0; i < oHistory.length; i++) {
|
|
247
|
-
if (oHistory[i].length > 0) {
|
|
248
|
-
console.log(
|
|
249
|
-
const value = {
|
|
250
|
-
name: oHistory[i],
|
|
251
|
-
}
|
|
252
|
-
oHistoryVars.push(value);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
//===================================================================================================
|
|
266
|
-
// ebusd interface
|
|
267
|
-
|
|
268
|
-
async function ebusd_Command() {
|
|
269
|
-
const obj = await adapter.getStateAsync("cmd");
|
|
270
|
-
|
|
271
|
-
if (obj !== undefined && obj != null) {
|
|
272
|
-
const cmds = obj.val;
|
|
273
|
-
if (cmds !== "") {
|
|
274
|
-
adapter.log.debug("got command(s): " + cmds);
|
|
275
|
-
|
|
276
|
-
adapter.log.debug("connect telnet to IP " + adapter.config.targetIP + " port " + parseInt(adapter.config.targetTelnetPort));
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
const socket = new net.Socket();
|
|
280
|
-
const promiseSocket = new PromiseSocket(socket);
|
|
281
|
-
|
|
282
|
-
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
283
|
-
adapter.log.debug("telnet connected for cmd");
|
|
284
|
-
promiseSocket.setTimeout(5000);
|
|
285
|
-
|
|
286
|
-
const oCmds = cmds.split(",");
|
|
287
|
-
|
|
288
|
-
if (oCmds.length > 0) {
|
|
289
|
-
let received = "";
|
|
290
|
-
for (let n = 0; n < oCmds.length; n++) {
|
|
291
|
-
|
|
292
|
-
adapter.log.debug("send " + oCmds[n]);
|
|
293
|
-
await promiseSocket.write(oCmds[n] + "\n");
|
|
294
|
-
|
|
295
|
-
const data = await promiseSocket.read();
|
|
296
|
-
|
|
297
|
-
if (data.includes("ERR")) {
|
|
298
|
-
adapter.log.warn("sent " + oCmds[n] + ", received " + data + " please check ebusd logs for details!");
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
adapter.log.debug("received " + data);
|
|
302
|
-
}
|
|
303
|
-
received += data.toString();
|
|
304
|
-
received += ", ";
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
//see issue #78: remove CR, LF and last comma
|
|
308
|
-
received = received.replace(/\r?\n|\r/g,"");
|
|
309
|
-
received = received.slice(0, -2);
|
|
310
|
-
|
|
311
|
-
//set result to cmdResult
|
|
312
|
-
await adapter.setStateAsync("cmdResult", { ack: true, val: received });
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
adapter.log.warn("no commands in list " + cmds + " " + JSON.stringify(oCmds));
|
|
316
|
-
}
|
|
317
|
-
await adapter.setStateAsync("cmd", { ack: true, val: "" });
|
|
318
|
-
|
|
319
|
-
promiseSocket.destroy();
|
|
320
|
-
|
|
321
|
-
} catch (e) {
|
|
322
|
-
adapter.log.error("exception from tcp socket" + "[" + e + "]");
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
adapter.log.debug("object cmd not found " + JSON.stringify(obj));
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
async function ebusd_find(){
|
|
332
|
-
try {
|
|
333
|
-
const socket = new net.Socket();
|
|
334
|
-
const promiseSocket = new PromiseSocket(socket);
|
|
335
|
-
|
|
336
|
-
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
337
|
-
adapter.log.debug("telnet connected for cmd");
|
|
338
|
-
promiseSocket.setTimeout(5000);
|
|
339
|
-
|
|
340
|
-
await promiseSocket.write("find -F circuit,name,comment\n");
|
|
341
|
-
|
|
342
|
-
const data = await promiseSocket.read();
|
|
343
|
-
|
|
344
|
-
if (data.includes("ERR")) {
|
|
345
|
-
adapter.log.warn("received error! sent find, received " + data + " please check ebusd logs for details!");
|
|
346
|
-
}
|
|
347
|
-
else {
|
|
348
|
-
adapter.log.debug("received " + typeof data + " " + data);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
for (let i = 0; i < datas.length; i++) {
|
|
355
|
-
|
|
356
|
-
//adapter.log.debug(JSON.stringify(datas[i]));
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
//circuit,name,comment
|
|
361
|
-
await UpdateDP(names[0], names[1], names[2]);
|
|
362
|
-
|
|
363
|
-
let cmd = "read -f -c " + names[0] + " " + names[1] ;
|
|
364
|
-
|
|
365
|
-
adapter.log.debug("send cmd " + cmd);
|
|
366
|
-
|
|
367
|
-
cmd += "\n";
|
|
368
|
-
await promiseSocket.write(cmd);
|
|
369
|
-
|
|
370
|
-
const result = await promiseSocket.read();
|
|
371
|
-
|
|
372
|
-
adapter.log.debug("received " + typeof result + " " + result);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
promiseSocket.destroy();
|
|
377
|
-
|
|
378
|
-
} catch (e) {
|
|
379
|
-
adapter.log.error("exception from tcp socket in ebusd_find" + "[" + e + "]");
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
//just call http://192.168.0.123:8889/data
|
|
387
|
-
|
|
388
|
-
async function subscribeVars() {
|
|
389
|
-
adapter.subscribeStates("cmd");
|
|
390
|
-
|
|
391
|
-
adapter.subscribeStates("find");
|
|
392
|
-
|
|
393
|
-
await adapter.setStateAsync("cmdResult", { ack: true, val: "" });
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
async function CreateObject(key, obj) {
|
|
397
|
-
|
|
398
|
-
const obj_new = await adapter.getObjectAsync(key);
|
|
399
|
-
//adapter.log.warn("got object " + JSON.stringify(obj_new));
|
|
400
|
-
|
|
401
|
-
if (obj_new != null) {
|
|
402
|
-
|
|
403
|
-
if ((obj_new.common.role != obj.common.role
|
|
404
|
-
|| obj_new.common.type != obj.common.type
|
|
405
|
-
|| (obj_new.common.unit != obj.common.unit && obj.common.unit != null)
|
|
406
|
-
|| obj_new.common.read != obj.common.read
|
|
407
|
-
|| obj_new.common.write != obj.common.write
|
|
408
|
-
|| obj_new.common.name != obj.common.name)
|
|
409
|
-
&& obj.type === "state"
|
|
410
|
-
) {
|
|
411
|
-
adapter.log.warn("change object " + JSON.stringify(obj) + " " + JSON.stringify(obj_new));
|
|
412
|
-
await adapter.extendObject(key, {
|
|
413
|
-
common: {
|
|
414
|
-
name: obj.common.name,
|
|
415
|
-
role: obj.common.role,
|
|
416
|
-
type: obj.common.type,
|
|
417
|
-
unit: obj.common.unit,
|
|
418
|
-
read: obj.common.read,
|
|
419
|
-
write: obj.common.write
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
await adapter.setObjectNotExistsAsync(key, obj);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
//circuit,name,comment
|
|
431
|
-
async function UpdateDP(circuit, name, comment) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
adapter.log.debug("update check for " + key);
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
// ehp.messages.Injection
|
|
438
|
-
//ebus.0.ehp.messages.Injection
|
|
439
|
-
|
|
440
|
-
const obj = await adapter.getObjectAsync(key);
|
|
441
|
-
adapter.log.debug("update check got " + JSON.stringify(obj));
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
//update check got null
|
|
445
|
-
|
|
446
|
-
if (obj != null) {
|
|
447
|
-
|
|
448
|
-
if (obj.common.name != comment) {
|
|
449
|
-
adapter.log.debug("update " + key + " " + comment);
|
|
450
|
-
await adapter.extendObject(key, {
|
|
451
|
-
common: {
|
|
452
|
-
name: comment,
|
|
453
|
-
read: true,
|
|
454
|
-
write: false
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
await adapter.setObjectNotExistsAsync(key, {
|
|
461
|
-
type: "channel",
|
|
462
|
-
common: {
|
|
463
|
-
name: comment,
|
|
464
|
-
read: true,
|
|
465
|
-
write: false
|
|
466
|
-
}
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
async function checkVariables() {
|
|
475
|
-
adapter.log.debug("init variables ");
|
|
476
|
-
|
|
477
|
-
let key;
|
|
478
|
-
let obj;
|
|
479
|
-
|
|
480
|
-
key = "cmd";
|
|
481
|
-
obj= {
|
|
482
|
-
type: "state",
|
|
483
|
-
common: {
|
|
484
|
-
name: "ebusd command",
|
|
485
|
-
type: "string",
|
|
486
|
-
role: "text",
|
|
487
|
-
read: true,
|
|
488
|
-
write: true
|
|
489
|
-
}
|
|
490
|
-
};
|
|
491
|
-
await CreateObject(key, obj);
|
|
492
|
-
|
|
493
|
-
key = "cmdResult";
|
|
494
|
-
obj = {
|
|
495
|
-
type: "state",
|
|
496
|
-
common: {
|
|
497
|
-
name: "ebusd command result",
|
|
498
|
-
type: "string",
|
|
499
|
-
role: "text",
|
|
500
|
-
read: true,
|
|
501
|
-
write: false
|
|
502
|
-
}
|
|
503
|
-
};
|
|
504
|
-
await CreateObject(key, obj);
|
|
505
|
-
|
|
506
|
-
key = "find";
|
|
507
|
-
obj = {
|
|
508
|
-
type: "state",
|
|
509
|
-
common: {
|
|
510
|
-
name: "find existing data points",
|
|
511
|
-
type: "boolean",
|
|
512
|
-
role: "button",
|
|
513
|
-
read: false,
|
|
514
|
-
write: true
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
await CreateObject(key, obj);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
adapter.log.debug("init common variables and " + oHistoryVars.length + " history DP's");
|
|
522
|
-
|
|
523
|
-
if (oHistoryVars.length > 0) {
|
|
524
|
-
|
|
525
|
-
if (oHistoryVars.length > 4) {
|
|
526
|
-
adapter.log.warn("too many history values " + oHistoryVars.length + " -> maximum is 4");
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
for (let n = 1; n <= oHistoryVars.length; n++) {
|
|
530
|
-
|
|
531
|
-
if (oHistoryVars[n - 1].name.length > 0) {
|
|
532
|
-
const name = "history value " + n + " as JSON " + oHistoryVars[n - 1].name;
|
|
533
|
-
key = "history.value" + n;
|
|
534
|
-
obj= {
|
|
535
|
-
type: "state",
|
|
536
|
-
common: {
|
|
537
|
-
name: name,
|
|
538
|
-
type: "string",
|
|
539
|
-
role: "value",
|
|
540
|
-
unit: "",
|
|
541
|
-
read: true,
|
|
542
|
-
write: false
|
|
543
|
-
},
|
|
544
|
-
native: { location: key }
|
|
545
|
-
};
|
|
546
|
-
await CreateObject(key, obj);
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
adapter.log.warn("ignoring history value " + n + " (invalid name)");
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
key = "history.date";
|
|
554
|
-
obj= {
|
|
555
|
-
type: "state",
|
|
556
|
-
common: {
|
|
557
|
-
name: "ebus history date / time as JSON",
|
|
558
|
-
type: "string",
|
|
559
|
-
role: "value",
|
|
560
|
-
unit: "",
|
|
561
|
-
read: true,
|
|
562
|
-
write: false
|
|
563
|
-
},
|
|
564
|
-
native: {
|
|
565
|
-
location: key
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
await CreateObject(key, obj);
|
|
569
|
-
}
|
|
570
|
-
key = "history.error";
|
|
571
|
-
obj= {
|
|
572
|
-
type: "state",
|
|
573
|
-
common: {
|
|
574
|
-
name: "ebus error",
|
|
575
|
-
type: "string",
|
|
576
|
-
role: "value",
|
|
577
|
-
unit: "",
|
|
578
|
-
read: true,
|
|
579
|
-
write: false
|
|
580
|
-
},
|
|
581
|
-
native: { location: key }
|
|
582
|
-
};
|
|
583
|
-
await CreateObject(key, obj);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
function VersionCheck() {
|
|
588
|
-
|
|
589
|
-
if (ebusdVersion[0] > 0 ) {
|
|
590
|
-
if (ebusdVersion[0] < ebusdMinVersion[0] || (ebusdVersion[0] == ebusdMinVersion[0] && ebusdVersion[1] < ebusdMinVersion[1])) {
|
|
591
|
-
adapter.log.info("please update ebusd, old version found: " + ebusdVersion[0] + "." + ebusdVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
592
|
-
}
|
|
593
|
-
if (ebusdVersion[0] > ebusdMinVersion[0] || (ebusdVersion[0] >= ebusdMinVersion[0] && ebusdVersion[1] > ebusdMinVersion[1])) {
|
|
594
|
-
adapter.log.info("unsupported ebusd version found (too new): " + ebusdVersion[0] + "." + ebusdVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
if (ebusdUpdateVersion[0] > 0 && ebusdVersion[0] > 0) {
|
|
599
|
-
|
|
600
|
-
if (ebusdUpdateVersion[0] > ebusdVersion[0] || (ebusdUpdateVersion[0] == ebusdVersion[0] && ebusdUpdateVersion[1] > ebusdVersion[1])) {
|
|
601
|
-
adapter.log.info("new ebusd version found: " + ebusdUpdateVersion[0] + "." + ebusdUpdateVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
602
|
-
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
//get data via https in json -> this is the main data receiver; telnet just triggers ebusd to read data;
|
|
609
|
-
//https://github.com/john30/ebusd/wiki/3.2.-HTTP-client
|
|
610
|
-
|
|
611
|
-
async function ebusd_ReceiveData() {
|
|
612
|
-
|
|
613
|
-
const sUrl = "http://" + adapter.config.targetIP + ":" + parseInt(adapter.config.targetHTTPPort) + "/data";
|
|
614
|
-
adapter.log.debug("request data from " + sUrl);
|
|
615
|
-
|
|
616
|
-
try {
|
|
617
|
-
|
|
618
|
-
const buffer = await axios.get(sUrl);
|
|
619
|
-
|
|
620
|
-
adapter.log.debug("got data " + typeof buffer.data + " " + JSON.stringify(buffer.data));
|
|
621
|
-
|
|
622
|
-
const oData = buffer.data;
|
|
623
|
-
|
|
624
|
-
//adapter.log.debug("oData " + oData);
|
|
625
|
-
|
|
626
|
-
const flatten = require("flat");
|
|
627
|
-
|
|
628
|
-
const newData = flatten(oData);
|
|
629
|
-
|
|
630
|
-
const keys = Object.keys(newData);
|
|
631
|
-
|
|
632
|
-
//adapter.log.debug("history: " + options.historyValues);
|
|
633
|
-
|
|
634
|
-
const historyvalues = [];
|
|
635
|
-
const historydates = [];
|
|
636
|
-
|
|
637
|
-
const oToday = new Date();
|
|
638
|
-
const month = oToday.getMonth() + 1;
|
|
639
|
-
|
|
640
|
-
historydates.push({
|
|
641
|
-
"date": oToday.getDate() + "." + month + "." + oToday.getFullYear(),
|
|
642
|
-
"time": oToday.getHours() + ":" + oToday.getMinutes() + ":" + oToday.getSeconds()
|
|
643
|
-
});
|
|
644
|
-
//adapter.log.debug(JSON.stringify(historydates));
|
|
645
|
-
|
|
646
|
-
let name = "unknown";
|
|
647
|
-
let sError = "none";
|
|
648
|
-
for (let i = 0; i < keys.length; i++) {
|
|
649
|
-
let key = keys[i];
|
|
650
|
-
const org_key = key;
|
|
651
|
-
|
|
652
|
-
if (key.includes("[") || key.includes("]")) {
|
|
653
|
-
adapter.log.debug("found unsupported chars in " + key);
|
|
654
|
-
const start = key.indexOf(
|
|
655
|
-
const end = key.lastIndexOf(
|
|
656
|
-
|
|
657
|
-
if (start > 0 && end > 0) {
|
|
658
|
-
const toReplace = key.slice(start, end + 1);
|
|
659
|
-
key = key.replace(toReplace, "");
|
|
660
|
-
}
|
|
661
|
-
//adapter.log.warn("new key is " + key);
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
const subnames = key.split(".");
|
|
665
|
-
const temp = subnames.length;
|
|
666
|
-
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key]);
|
|
667
|
-
|
|
668
|
-
//
|
|
669
|
-
//if (key.match(adapter.FORBIDDEN_CHARS)) { continue; }
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
if (key.includes("global.version")) {
|
|
673
|
-
const value = newData[org_key];
|
|
674
|
-
//adapter.log.info("in version, value " + value);
|
|
675
|
-
const versionInfo = value.split(
|
|
676
|
-
if (versionInfo.length > 1) {
|
|
677
|
-
adapter.log.info("installed ebusd version is " + versionInfo[0] + "." + versionInfo[1]);
|
|
678
|
-
|
|
679
|
-
ebusdVersion[0] = versionInfo[0];
|
|
680
|
-
ebusdVersion[1] = versionInfo[1];
|
|
681
|
-
|
|
682
|
-
VersionCheck();
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
if (key.includes("global.updatecheck")) {
|
|
687
|
-
let value = newData[org_key];
|
|
688
|
-
//adapter.log.info("in version, value " + value);
|
|
689
|
-
|
|
690
|
-
//revision v21.2 available
|
|
691
|
-
value = value.replace("revision v", "");
|
|
692
|
-
value = value.replace(" available", "");
|
|
693
|
-
|
|
694
|
-
const versionInfo = value.split(
|
|
695
|
-
if (versionInfo.length > 1) {
|
|
696
|
-
adapter.log.info("found ebusd update version " + versionInfo[0] + "." + versionInfo[1]);
|
|
697
|
-
|
|
698
|
-
ebusdUpdateVersion[0] = versionInfo[0];
|
|
699
|
-
ebusdUpdateVersion[1] = versionInfo[1];
|
|
700
|
-
|
|
701
|
-
VersionCheck();
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
if (subnames[temp - 1].includes("name")) {
|
|
708
|
-
name = newData[org_key];
|
|
709
|
-
}
|
|
710
|
-
else if (subnames[temp - 1].includes("value")) {
|
|
711
|
-
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
712
|
-
|
|
713
|
-
let value = newData[org_key];
|
|
714
|
-
|
|
715
|
-
if (value == null || value === undefined) {
|
|
716
|
-
adapter.log.debug(
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
if (name === "hcmode2") {
|
|
721
|
-
if (parseInt(value) === 0) {
|
|
722
|
-
adapter.log.info(key + "in hcmode2 with value 0: off");
|
|
723
|
-
value = "off";
|
|
724
|
-
}
|
|
725
|
-
else if (parseInt(value) === 5) {
|
|
726
|
-
adapter.log.info(key + " with value 5: EVU Sperrzeit");
|
|
727
|
-
value = "EVU Sperrzeit";
|
|
728
|
-
}
|
|
729
|
-
else {
|
|
730
|
-
adapter.log.debug("in hcmode2, value " + value);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
let type = typeof value;
|
|
735
|
-
|
|
736
|
-
if (adapter.config.useBoolean4Onoff) {
|
|
737
|
-
if (type == "string" && (value == "on" || value == "off")) {
|
|
738
|
-
adapter.log.debug(
|
|
739
|
-
//Key mc.messages.Status.fields.1.value could be boolean off
|
|
740
|
-
|
|
741
|
-
type = "boolean";
|
|
742
|
-
|
|
743
|
-
if (value == "on") {
|
|
744
|
-
value = true;
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
value = false;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
//value, change type if necessary
|
|
753
|
-
await AddObject(key, type);
|
|
754
|
-
await UpdateObject(key, value);
|
|
755
|
-
|
|
756
|
-
//name parallel to value: used for lists in admin...
|
|
757
|
-
const keyname = key.replace("value", "name");
|
|
758
|
-
await AddObject(keyname, "string");
|
|
759
|
-
|
|
760
|
-
await UpdateObject(keyname, name);
|
|
761
|
-
|
|
762
|
-
//push to history
|
|
763
|
-
//ebus.0.bai.messages.ReturnTemp.fields.temp.value
|
|
764
|
-
//ebus.0.bai.messages.ReturnTemp.fields.tempmirror.value
|
|
765
|
-
if (!subnames[temp - 2].includes("sensor") //ignore sensor states
|
|
766
|
-
&& !subnames[temp - 2].includes("mirror") //ignore mirror-data
|
|
767
|
-
) {
|
|
768
|
-
for (let ii = 0; ii < oHistoryVars.length; ii++) {
|
|
769
|
-
|
|
770
|
-
if (name === oHistoryVars[ii].name) {
|
|
771
|
-
|
|
772
|
-
const sTemp = '{"' + name + '": "' + value + '"}';
|
|
773
|
-
//adapter.log.debug(sTemp);
|
|
774
|
-
historyvalues[ii] = [];
|
|
775
|
-
historyvalues[ii].push(JSON.parse(sTemp));
|
|
776
|
-
//adapter.log.debug(JSON.stringify(historyvalues));
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
else if (subnames[temp - 1].includes("lastup")) {
|
|
782
|
-
|
|
783
|
-
const value = newData[org_key];
|
|
784
|
-
|
|
785
|
-
if (parseInt(value) > 0) {
|
|
786
|
-
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
787
|
-
|
|
788
|
-
//umrechnen...
|
|
789
|
-
const oDate = new Date(value * 1000);
|
|
790
|
-
//const nDate = oDate.getDate();
|
|
791
|
-
//const nMonth = oDate.getMonth() + 1;
|
|
792
|
-
//const nYear = oDate.getFullYear();
|
|
793
|
-
//const nHours = oDate.getHours();
|
|
794
|
-
//const nMinutes = oDate.getMinutes();
|
|
795
|
-
//const nSeconds = oDate.getSeconds();
|
|
796
|
-
|
|
797
|
-
const sDate = oDate.toLocaleString();
|
|
798
|
-
await AddObject(key, "string");
|
|
799
|
-
await UpdateObject(key, sDate);
|
|
800
|
-
|
|
801
|
-
const oToday = new Date();
|
|
802
|
-
|
|
803
|
-
let bSkip = false;
|
|
804
|
-
|
|
805
|
-
if (subnames[0].includes("scan") ||
|
|
806
|
-
subnames[0].includes("ehp") ||
|
|
807
|
-
(subnames.length>2 && subnames[2].includes("currenterror"))
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
bSkip = true;
|
|
811
|
-
}
|
|
812
|
-
if (temp > 2) {
|
|
813
|
-
//adapter.log.debug("_______________size " + temp);
|
|
814
|
-
if (subnames[2].includes("Timer")) {
|
|
815
|
-
bSkip = true;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
if (!bSkip && Math.abs(oDate.getTime() - oToday.getTime()) > 1 * 60 * 60 * 1000) {
|
|
820
|
-
|
|
821
|
-
const sError1 = "no update since " + sDate + " " + key + " ";
|
|
822
|
-
if (sError.includes("none")) {
|
|
823
|
-
sError = "ebus: " + sError1;
|
|
824
|
-
}
|
|
825
|
-
else {
|
|
826
|
-
sError += sError1;
|
|
827
|
-
}
|
|
828
|
-
adapter.log.warn(sError1);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
else if (subnames[0].includes("global")) {
|
|
835
|
-
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
836
|
-
const value = newData[org_key];
|
|
837
|
-
await AddObject(key, typeof value);
|
|
838
|
-
await UpdateObject(key, value);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
await adapter.setStateAsync("history.error", { ack: true, val: sError });
|
|
842
|
-
|
|
843
|
-
//adapter.log.debug(JSON.stringify(historyvalues));
|
|
844
|
-
|
|
845
|
-
adapter.log.info("all http done");
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
await UpdateHistory(historyvalues, historydates);
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
}
|
|
852
|
-
catch (e) {
|
|
853
|
-
adapter.log.error("exception in ebusd_ReceiveData [" + e + "]");
|
|
854
|
-
|
|
855
|
-
await adapter.setStateAsync("history.error", { ack: true, val: "exception in receive" });
|
|
856
|
-
}
|
|
857
|
-
//});
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
async function UpdateHistory(values, dates) {
|
|
863
|
-
|
|
864
|
-
if (oHistoryVars.length > 0) {
|
|
865
|
-
//prüfen ob alle json gleich lang sind
|
|
866
|
-
let NoOfDates = -1;
|
|
867
|
-
|
|
868
|
-
const obj = await adapter.getStateAsync("history.date");
|
|
869
|
-
|
|
870
|
-
if (obj !== undefined && obj != null) {
|
|
871
|
-
try {
|
|
872
|
-
let oEbusDates = [];
|
|
873
|
-
//adapter.log.debug("before " + obj.val);
|
|
874
|
-
oEbusDates = JSON.parse(obj.val);
|
|
875
|
-
//adapter.log.debug("after parse " + JSON.stringify(oEbusDates));
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
oEbusDates.push(dates);
|
|
880
|
-
//adapter.log.debug("after push " + JSON.stringify(oEbusDates));
|
|
881
|
-
//limit length of object...
|
|
882
|
-
if (oEbusDates.length > 200) {
|
|
883
|
-
|
|
884
|
-
for (let i = oEbusDates.length; i > 200; i--) {
|
|
885
|
-
//adapter.log.debug("delete");
|
|
886
|
-
oEbusDates.shift();
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
NoOfDates = oEbusDates.length;
|
|
890
|
-
await adapter.setStateAsync("history.date", { ack: true, val: JSON.stringify(oEbusDates) });
|
|
891
|
-
}
|
|
892
|
-
catch (e) {
|
|
893
|
-
adapter.log.error("exception in UpdateHistory part1 [" + e + "]");
|
|
894
|
-
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
895
|
-
NoOfDates = 0;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
adapter.log.warn("history.date not found, creating DP ");
|
|
900
|
-
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
901
|
-
NoOfDates = 0;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
if (oHistoryVars.length > 0) {
|
|
905
|
-
for (let ctr = 1; ctr <= oHistoryVars.length; ctr++) {
|
|
906
|
-
|
|
907
|
-
if (oHistoryVars[ctr - 1].name.length > 0) {
|
|
908
|
-
const ctrOkay = await UpdateHistoryValues(values, ctr, NoOfDates);
|
|
909
|
-
|
|
910
|
-
if (!ctrOkay) {
|
|
911
|
-
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
912
|
-
NoOfDates = 0;
|
|
913
|
-
adapter.log.warn("reset history date too");
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
else {
|
|
917
|
-
adapter.log.debug("ignoring history value " + ctr);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
adapter.log.info("all history done");
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
else {
|
|
925
|
-
adapter.log.debug("nothing to do for history");
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
async function UpdateHistoryValues(values, ctr, curDateCtr) {
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
let bRet = true;
|
|
935
|
-
|
|
936
|
-
const obj = await adapter.getStateAsync("history.value" + ctr);
|
|
937
|
-
|
|
938
|
-
if (obj !== undefined && obj != null) {
|
|
939
|
-
try {
|
|
940
|
-
let oEbusValues = [];
|
|
941
|
-
if (obj !== null) {
|
|
942
|
-
//adapter.log.debug("before " + obj.val);
|
|
943
|
-
|
|
944
|
-
oEbusValues = JSON.parse(obj.val);
|
|
945
|
-
|
|
946
|
-
//adapter.log.debug("after parse " + JSON.stringify(oEbusValues));
|
|
947
|
-
|
|
948
|
-
//adapter.log.debug("after parse cnt " + oEbusValues.length);
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
//adapter.log.debug("values " + ctr + ": " + JSON.stringify(values[ctr-1]));
|
|
952
|
-
|
|
953
|
-
oEbusValues.push(values[ctr - 1]);
|
|
954
|
-
//adapter.log.debug("after push " + JSON.stringify(oEbusValues));
|
|
955
|
-
//adapter.log.debug("after push cnt " + oEbusValues.length);
|
|
956
|
-
//limit length of object...
|
|
957
|
-
if (oEbusValues.length > 200) {
|
|
958
|
-
|
|
959
|
-
for (let i = oEbusValues.length; i > 200; i--) {
|
|
960
|
-
//adapter.log.debug("delete");
|
|
961
|
-
oEbusValues.shift();
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
const key = "history.value" + ctr;
|
|
966
|
-
adapter.log.debug("update history " + key);
|
|
967
|
-
|
|
968
|
-
if (curDateCtr != oEbusValues.length) {
|
|
969
|
-
bRet = false;
|
|
970
|
-
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
971
|
-
adapter.log.warn("reset history " + key + " because number of values different to date values");
|
|
972
|
-
|
|
973
|
-
}
|
|
974
|
-
else {
|
|
975
|
-
await adapter.setStateAsync(key, { ack: true, val: JSON.stringify(oEbusValues) });
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
}
|
|
980
|
-
catch (e) {
|
|
981
|
-
adapter.log.error("exception in UpdateHistory part2 [" + e + "]");
|
|
982
|
-
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
983
|
-
if (curDateCtr > 0) {
|
|
984
|
-
bRet = false;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
else {
|
|
989
|
-
adapter.log.warn("history.value" + ctr + " not found, creating DP " + JSON.stringify(obj));
|
|
990
|
-
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
991
|
-
if (curDateCtr > 0) {
|
|
992
|
-
bRet = false;
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
return bRet;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
async function AddObject(key, type) {
|
|
1002
|
-
//adapter.log.debug("addObject " + key);
|
|
1003
|
-
|
|
1004
|
-
try {
|
|
1005
|
-
const obj = await adapter.getObjectAsync(key);
|
|
1006
|
-
|
|
1007
|
-
if (obj != null) {
|
|
1008
|
-
//adapter.log.debug(" got Object " + JSON.stringify(obj));
|
|
1009
|
-
if (obj.common.role != "value"
|
|
1010
|
-
|| obj.common.type != type) {
|
|
1011
|
-
adapter.log.debug(" !!! need to extend for " + key);
|
|
1012
|
-
await adapter.extendObject(key, {
|
|
1013
|
-
common: {
|
|
1014
|
-
type: type,
|
|
1015
|
-
role: "value",
|
|
1016
|
-
}
|
|
1017
|
-
});
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
else {
|
|
1021
|
-
adapter.log.warn(" !!! does not exist, creating now " + key );
|
|
1022
|
-
|
|
1023
|
-
await adapter.setObjectNotExistsAsync(key, {
|
|
1024
|
-
type: "state",
|
|
1025
|
-
common: {
|
|
1026
|
-
name: "data",
|
|
1027
|
-
type: type,
|
|
1028
|
-
role: "value",
|
|
1029
|
-
unit: "",
|
|
1030
|
-
read: true,
|
|
1031
|
-
write: false
|
|
1032
|
-
},
|
|
1033
|
-
native: {
|
|
1034
|
-
location: key
|
|
1035
|
-
}
|
|
1036
|
-
});
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
} catch (e) {
|
|
1040
|
-
adapter.log.error("exception in AddObject " + "[" + e + "]");
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
async function UpdateObject(key, value) {
|
|
1045
|
-
try {
|
|
1046
|
-
if (value === undefined) {
|
|
1047
|
-
adapter.log.warn("updateObject: not updated " + key + " value: " + value + " " + typeof value);
|
|
1048
|
-
}
|
|
1049
|
-
else if (value == null ) {
|
|
1050
|
-
adapter.log.debug("updateObject: update to null " + key + " value: " + value);
|
|
1051
|
-
await adapter.setStateAsync(key, { ack: true, val: null });
|
|
1052
|
-
}
|
|
1053
|
-
else {
|
|
1054
|
-
adapter.log.debug("updateObject " + key + " : " + value);
|
|
1055
|
-
await adapter.setStateAsync(key, { ack: true, val: value });
|
|
1056
|
-
}
|
|
1057
|
-
} catch (e) {
|
|
1058
|
-
adapter.log.error("exception in UpdateObject " + "[" + e + "]");
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
//telnet client to write to ebusd
|
|
1064
|
-
//https://github.com/john30/ebusd/wiki/3.1.-TCP-client-commands
|
|
1065
|
-
/*
|
|
1066
|
-
telnet 192.168.3.144 8890
|
|
1067
|
-
|
|
1068
|
-
find -f -c broadcast outsidetemp
|
|
1069
|
-
find -f outsidetemp
|
|
1070
|
-
find -f YieldTotal
|
|
1071
|
-
|
|
1072
|
-
read -f YieldTotal
|
|
1073
|
-
read LegioProtectionEnabled
|
|
1074
|
-
|
|
1075
|
-
read -f YieldTotal,read LegioProtectionEnabled,read -f -c broadcast outsidetemp
|
|
1076
|
-
|
|
1077
|
-
*/
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
//this function just triggers ebusd to read data; result will not be parsed; we just take the values from http result
|
|
1081
|
-
//here we need a loop over all configured read data in admin-page
|
|
1082
|
-
async function ebusd_ReadValues() {
|
|
1083
|
-
|
|
1084
|
-
if (oPolledVars.length > 0) {
|
|
1085
|
-
|
|
1086
|
-
adapter.log.debug("to poll ctr " + oPolledVars.length + " vals: " + JSON.stringify(oPolledVars));
|
|
1087
|
-
|
|
1088
|
-
try {
|
|
1089
|
-
const socket = new net.Socket();
|
|
1090
|
-
const promiseSocket = new PromiseSocket(socket);
|
|
1091
|
-
|
|
1092
|
-
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
1093
|
-
adapter.log.debug("telnet connected to poll variables " + adapter.config.targetIP + " port " + adapter.config.targetTelnetPort);
|
|
1094
|
-
promiseSocket.setTimeout(5000);
|
|
1095
|
-
|
|
1096
|
-
let retries = 0;
|
|
1097
|
-
for (let nCtr = 0; nCtr < oPolledVars.length; nCtr++) {
|
|
1098
|
-
|
|
1099
|
-
let circuit = "";
|
|
1100
|
-
let params = "";
|
|
1101
|
-
if (oPolledVars[nCtr].circuit != null && oPolledVars[nCtr].circuit.length > 0) {
|
|
1102
|
-
circuit = "-c " + oPolledVars[nCtr].circuit + " ";
|
|
1103
|
-
}
|
|
1104
|
-
if (oPolledVars[nCtr].parameter != null && oPolledVars[nCtr].parameter.length > 0) {
|
|
1105
|
-
params = " " + oPolledVars[nCtr].parameter;
|
|
1106
|
-
}
|
|
1107
|
-
let cmd = "read -f " + circuit + oPolledVars[nCtr].name + params;
|
|
1108
|
-
|
|
1109
|
-
adapter.log.debug("send cmd " + cmd);
|
|
1110
|
-
|
|
1111
|
-
cmd += "\n";
|
|
1112
|
-
await promiseSocket.write(cmd);
|
|
1113
|
-
|
|
1114
|
-
const data = await promiseSocket.read();
|
|
1115
|
-
|
|
1116
|
-
//received ERR: arbitration lost for YieldThisYear
|
|
1117
|
-
if (data.includes("ERR")) {
|
|
1118
|
-
adapter.log.warn("sent " + cmd + ", received " + data + " for " + JSON.stringify(oPolledVars[nCtr]) + " please check ebusd logs for details!");
|
|
1119
|
-
|
|
1120
|
-
/*
|
|
1121
|
-
* sent read -f YieldLastYear, received ERR: arbitration lost for {"circuit":"","name":"YieldLastYear","parameter":""}
|
|
1122
|
-
* */
|
|
1123
|
-
if (data.includes("arbitration lost")) {
|
|
1124
|
-
|
|
1125
|
-
retries++;
|
|
1126
|
-
if (retries > adapter.config.maxretries) {
|
|
1127
|
-
adapter.log.error("max retries, skip cmd " + cmd);
|
|
1128
|
-
retries = 0;
|
|
1129
|
-
}
|
|
1130
|
-
else {
|
|
1131
|
-
nCtr--;
|
|
1132
|
-
adapter.log.debug("retry to send data ");
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
else {
|
|
1137
|
-
adapter.log.debug("received " + data + " for " + JSON.stringify(oPolledVars[nCtr]));
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
promiseSocket.destroy();
|
|
1141
|
-
adapter.log.debug("telnet disonnected");
|
|
1142
|
-
|
|
1143
|
-
} catch (e) {
|
|
1144
|
-
adapter.log.error("exception from tcp socket in ebusd_ReadValues " + "[" + e + "]");
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
adapter.log.debug("nothing to poll; skip telnet");
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
async function FindParams(obj) {
|
|
1157
|
-
|
|
1158
|
-
adapter.log.debug("FindParams " + JSON.stringify(obj));
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
try {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
const socket = new net.Socket();
|
|
1166
|
-
const promiseSocket = new PromiseSocket(socket);
|
|
1167
|
-
|
|
1168
|
-
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
1169
|
-
adapter.log.debug("telnet connected for cmd");
|
|
1170
|
-
promiseSocket.setTimeout(5000);
|
|
1171
|
-
|
|
1172
|
-
await promiseSocket.write("find -c " + circuit + " -F circuit,name\n");
|
|
1173
|
-
|
|
1174
|
-
const data = await promiseSocket.read();
|
|
1175
|
-
|
|
1176
|
-
if (data.includes("ERR")) {
|
|
1177
|
-
adapter.log.warn("received error! sent find, received " + data + " please check ebusd logs for details!");
|
|
1178
|
-
}
|
|
1179
|
-
else {
|
|
1180
|
-
adapter.log.debug("received " + typeof data + " " + data);
|
|
1181
|
-
}
|
|
1182
|
-
/*
|
|
1183
|
-
received object ehp,AccelerationTestModeehp,AccelerationTestModeehp,ActualEnvironmentPowerehp,ActualEnvironmentPowerehp,ActualEnvironmentPowerPercentageehp,ActualEnvironmentPowerPercentageehp,ApplianceCodeehp,ApplianceCodeehp,Backupehp,Backupehp,BackupHoursehp,BackupHoursHcehp,BackupHoursHwcehp,BackupHysteresisehp,BackupIntegralehp,BackupModeHcehp,BackupModeHwcehp,BackupPowerCutehp,BackupStartsehp,BackupStartsHcehp,BackupStartsHwcehp,BackupTypeehp,BivalentTempehp,Bleedingehp,Bleedingehp,CirPumpehp,CirPumpehp,Code1ehp,Code1Code2Validehp,Code2ehp,Compehp,Compehp,CompControlStateehp,CompCutPressHighCountehp,CompCutPressLowCountehp,CompCutTempCountehp,CompDemandehp,CompHoursehp,CompHoursHcehp,CompHoursHwcehp,CompHysteresisehp,CompIntegralehp,CompPressHighehp,CompPressHighehp,CompPressLowehp,CompPressLowehp,CompStartsehp,CompStartsHcehp,CompStartsHwcehp,CompStateehp,CondensorTempehp,CondensorTempehp,currenterrorehp,Dateehp,DateTimeehp,DeltaTempT6T7ehp,ElectricWiringDiagramehp,ElectricWiringDiagramehp,EnergyBalancingReleaseehp,errorhistoryehp,FlowTempehp,FlowTempehp,FlowtempCoolingMinehp,FlowTempOffsetehp,Hc1Pumpehp,Hc1Pumpehp,Hc1PumpHoursehp,Hc1PumpPortehp,Hc1PumpStartsehp,Hc2Pumpehp,Hc2PumpHoursehp,HcFlowTempehp,HcFlowTempOffsetehp,HcModeDemandHoursehp,HcModeFulfilledHoursehp,HcParallelStorageFillingEnabledehp,HcPressehp,HcReturnTempehp,HcReturnTempehp,HcReturnTempOffsetehp,HeatPumpStatusehp,HeatPumpStatusehp,HeatpumpTypeehp,HwcHcValveehp,HwcHcValveehp,HwcHcValveStartsehp,HwcLaggingTimeehp,HwcLoadingDelayehp,HwcModeDemandHoursehp,HwcModeFulfilledHoursehp,HwcPumpStartsehp,HwcSwitchehp,HwcTempehp,HwcTempehp,HwcTempOffsetehp,HydraulicSchemeehp,ICLOutehp,ICLOutehp,Injectionehp,Integralehp,Mixer1DutyCycleehp,NumberCompStartsehp,OutsideTempehp,OutsideTempOffsetehp,OverpressureThresholdehp,PhaseOrderehp,PhaseOrderehp,PhaseStatusehp,PhaseStatusehp,PowerCutehp,PowerCutPreloadingehp,PressSwitchehp,PressSwitchehp,RebootCounterehp,ReturnTempMaxehp,SetModeehp,SoftwareCodeehp,Source2PumpHoursehp,Sourceehp,Sourceehp,SourceHoursehp,SourcePortehp,SourcePressehp,SourcePumpPrerunTimeehp,SourceStartsehp,SourceSwitchehp,SourceSwitchehp,SourceTempInputehp,SourceTempInputehp,SourceTempInputOffsetehp,SourceTempOutputehp,SourceTempOutputehp,SourceTempOutputOffsetehp,SourceTempOutputT8Minehp,StateSoftwareCodeehp,StateSoftwareCodeehp,Status01ehp,Status02ehp,Status16ehp,Statusehp,StatusCirPumpehp,StorageTempBottomehp,StorageTempBottomehp,StorageTempBottomOffsetehp,StorageTempTopehp,StorageTempTopehp,StorageTempTopOffsetehp,Subcoolingehp,Superheatehp,T19MaxToCompOffehp,TempInputehp,TempInputehp,TempInputOffsetehp,TempOutputehp,TempOutputehp,TempOutputOffsetehp,Timeehp,TimeBetweenTwoCompStartsMinehp,TimeCompOffMinehp,TimeCompOnMinehp,TimeOfNextPredictedPowerCutehp,TimeOfNextPredictedPowerCutehp,Weekdayehp,YieldTotalehp,YieldTotal
|
|
1184
|
-
*/
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
for (let i = 0; i < datas.length; i++) {
|
|
1189
|
-
|
|
1190
|
-
//adapter.log.debug(JSON.stringify(datas[i]));
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
//doppelte und leere herausfiltern
|
|
1195
|
-
let add = true;
|
|
1196
|
-
|
|
1197
|
-
if (names[0] == "" || names[1] == "") {
|
|
1198
|
-
add = false;
|
|
1199
|
-
}
|
|
1200
|
-
else {
|
|
1201
|
-
|
|
1202
|
-
for (let n = 0; n < list.length; n++) {
|
|
1203
|
-
|
|
1204
|
-
if (list[n].circuit == names[0] && list[n].name == names[1]) {
|
|
1205
|
-
add = false;
|
|
1206
|
-
//already in list
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
if (add) {
|
|
1212
|
-
|
|
1213
|
-
active: false,
|
|
1214
|
-
circuit: names[0],
|
|
1215
|
-
name: names[1]
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
list.push(entry);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
} catch (e) {
|
|
1222
|
-
adapter.log.error("exception in FindParams " + "[" + e + "]");
|
|
1223
|
-
}
|
|
1224
|
-
adapter.sendTo(obj.from, obj.command, list, obj.callback);
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
// If started as allInOne/compact mode => return function to create instance
|
|
1228
|
-
if (module && module.parent) {
|
|
1229
|
-
module.exports = startAdapter;
|
|
1230
|
-
} else {
|
|
1231
|
-
// or start the instance directly
|
|
1232
|
-
startAdapter();
|
|
1
|
+
/*
|
|
2
|
+
* ebus adapter für iobroker
|
|
3
|
+
*
|
|
4
|
+
* Created: 15.09.2016 21:31:28
|
|
5
|
+
* Author: Rene
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* jshint -W097 */// jshint strict:false
|
|
11
|
+
/*jslint node: true */
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const utils = require("@iobroker/adapter-core");
|
|
18
|
+
const ebusdMinVersion = [23, 3];
|
|
19
|
+
const ebusdVersion = [0, 0];
|
|
20
|
+
const ebusdUpdateVersion = [0, 0];
|
|
21
|
+
|
|
22
|
+
let adapter;
|
|
23
|
+
function startAdapter(options) {
|
|
24
|
+
options = options || {};
|
|
25
|
+
Object.assign(options, {
|
|
26
|
+
name: "ebus",
|
|
27
|
+
//#######################################
|
|
28
|
+
//
|
|
29
|
+
ready: function () {
|
|
30
|
+
try {
|
|
31
|
+
//adapter.log.debug('start');
|
|
32
|
+
main();
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
adapter.log.error("exception catch after ready [" + e + "]");
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
//#######################################
|
|
39
|
+
// is called when adapter shuts down
|
|
40
|
+
unload: function (callback) {
|
|
41
|
+
try {
|
|
42
|
+
|
|
43
|
+
if (intervalID != null) {
|
|
44
|
+
clearInterval(intervalID);
|
|
45
|
+
}
|
|
46
|
+
if (updateTimerID != null) {
|
|
47
|
+
clearTimeout(updateTimerID);
|
|
48
|
+
}
|
|
49
|
+
adapter && adapter.log && adapter.log.info && adapter.log.info("cleaned everything up...");
|
|
50
|
+
//to do stop intervall
|
|
51
|
+
callback();
|
|
52
|
+
} catch (e) {
|
|
53
|
+
callback();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
stateChange: async (id, state) => {
|
|
58
|
+
await HandleStateChange(id, state);
|
|
59
|
+
},
|
|
60
|
+
//#######################################
|
|
61
|
+
//
|
|
62
|
+
message: async (obj) => {
|
|
63
|
+
if (obj) {
|
|
64
|
+
switch (obj.command) {
|
|
65
|
+
case "findParams":
|
|
66
|
+
// e.g. send email or pushover or whatever
|
|
67
|
+
adapter.log.debug("findParams command");
|
|
68
|
+
// Send response in callback if required
|
|
69
|
+
await FindParams(obj);
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
adapter.log.error("unknown message " + obj.command);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//#######################################
|
|
78
|
+
//
|
|
79
|
+
});
|
|
80
|
+
adapter = new utils.Adapter(options);
|
|
81
|
+
|
|
82
|
+
return adapter;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
const axios = require("axios");
|
|
87
|
+
const net = require("net");
|
|
88
|
+
const { PromiseSocket } = require("promise-socket");
|
|
89
|
+
|
|
90
|
+
let intervalID=null;
|
|
91
|
+
let updateTimerID=null;
|
|
92
|
+
|
|
93
|
+
async function main() {
|
|
94
|
+
|
|
95
|
+
adapter.log.debug("start with interface ebusd ");
|
|
96
|
+
|
|
97
|
+
FillPolledVars();
|
|
98
|
+
FillHistoryVars();
|
|
99
|
+
|
|
100
|
+
await checkVariables();
|
|
101
|
+
|
|
102
|
+
await subscribeVars();
|
|
103
|
+
|
|
104
|
+
let readInterval = 5;
|
|
105
|
+
if (parseInt(adapter.config.readInterval) > 0) {
|
|
106
|
+
readInterval = adapter.config.readInterval;
|
|
107
|
+
}
|
|
108
|
+
adapter.log.debug("read every " + readInterval + " minutes");
|
|
109
|
+
intervalID = setInterval(Do, readInterval * 60 * 1000);
|
|
110
|
+
|
|
111
|
+
//read at adapterstart
|
|
112
|
+
await Do();
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let requestRunning = false;
|
|
117
|
+
|
|
118
|
+
async function DoRequest() {
|
|
119
|
+
|
|
120
|
+
adapter.log.debug("DoRequest ");
|
|
121
|
+
|
|
122
|
+
if (!requestRunning) {
|
|
123
|
+
requestRunning = true;
|
|
124
|
+
await ebusd_ReadValues();
|
|
125
|
+
|
|
126
|
+
await ebusd_ReceiveData();
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
adapter.log.debug("DoRequest: do nothing already running ");
|
|
130
|
+
}
|
|
131
|
+
requestRunning = false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function Do() {
|
|
135
|
+
|
|
136
|
+
adapter.log.debug("starting ... " );
|
|
137
|
+
|
|
138
|
+
await ebusd_Command();
|
|
139
|
+
|
|
140
|
+
await DoRequest();
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async function HandleStateChange(id, state) {
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
if (state != null && state.ack !== true) {
|
|
149
|
+
|
|
150
|
+
adapter.log.debug("handle state change " + id);
|
|
151
|
+
const ids = id.split(".");
|
|
152
|
+
|
|
153
|
+
if (ids[2] === "cmd") {
|
|
154
|
+
await ebusd_Command();
|
|
155
|
+
StartDataRequest();
|
|
156
|
+
//see issue #77: only one request possible
|
|
157
|
+
//await Do();
|
|
158
|
+
}
|
|
159
|
+
//unhandled state change ebus.0.find
|
|
160
|
+
else if (ids[2] === "find") {
|
|
161
|
+
await ebusd_find();
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
adapter.log.warn("unhandled state change " + id);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
function StartDataRequest() {
|
|
171
|
+
|
|
172
|
+
if (updateTimerID != null) {
|
|
173
|
+
//already running
|
|
174
|
+
clearTimeout(updateTimerID);
|
|
175
|
+
updateTimerID = null;
|
|
176
|
+
}
|
|
177
|
+
//start or restart
|
|
178
|
+
updateTimerID = setTimeout(DataRequest, 500);
|
|
179
|
+
adapter.log.debug("StartDataRequest");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
async function DataRequest() {
|
|
184
|
+
adapter.log.debug("get data after command and timeout");
|
|
185
|
+
if (updateTimerID != null) {
|
|
186
|
+
clearTimeout(updateTimerID);
|
|
187
|
+
updateTimerID = null;
|
|
188
|
+
}
|
|
189
|
+
await DoRequest();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
const oPolledVars = [];
|
|
194
|
+
function FillPolledVars() {
|
|
195
|
+
|
|
196
|
+
if ( adapter.config.PolledDPs !== undefined && adapter.config.PolledDPs != null && adapter.config.PolledDPs.length > 0) {
|
|
197
|
+
adapter.log.debug("use new object list for polled vars");
|
|
198
|
+
|
|
199
|
+
//2023-02-10 only active vars
|
|
200
|
+
for (let i = 0; i < adapter.config.PolledDPs.length; i++) {
|
|
201
|
+
if (adapter.config.PolledDPs[i].active) {
|
|
202
|
+
oPolledVars.push(adapter.config.PolledDPs[i]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
//make it compatible to old versions
|
|
209
|
+
adapter.log.debug("check old comma separeted list for polled vars");
|
|
210
|
+
const oPolled = adapter.config.PolledValues.split(",");
|
|
211
|
+
|
|
212
|
+
if (oPolled.length > 0) {
|
|
213
|
+
|
|
214
|
+
for (let i = 0; i < oPolled.length; i++) {
|
|
215
|
+
if (oPolled[i].length > 0) {
|
|
216
|
+
//console.log('add ' + oPolled[i]);
|
|
217
|
+
const value = {
|
|
218
|
+
circuit: "",
|
|
219
|
+
name: oPolled[i],
|
|
220
|
+
parameter: ""
|
|
221
|
+
};
|
|
222
|
+
oPolledVars.push(value);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
adapter.log.info("list of polled vars " + JSON.stringify(oPolledVars));
|
|
229
|
+
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
let oHistoryVars = [];
|
|
233
|
+
function FillHistoryVars() {
|
|
234
|
+
|
|
235
|
+
if (adapter.config.HistoryDPs !== undefined && adapter.config.HistoryDPs != null && adapter.config.HistoryDPs.length > 0) {
|
|
236
|
+
adapter.log.debug("use new object list for history vars");
|
|
237
|
+
oHistoryVars = adapter.config.HistoryDPs;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
//make it compatible to old versions
|
|
241
|
+
adapter.log.debug("check old comma separeted list for history vars");
|
|
242
|
+
const oHistory = adapter.config.HistoryValues.split(",");
|
|
243
|
+
|
|
244
|
+
if (oHistory.length > 0) {
|
|
245
|
+
|
|
246
|
+
for (let i = 0; i < oHistory.length; i++) {
|
|
247
|
+
if (oHistory[i].length > 0) {
|
|
248
|
+
console.log("add " + oHistory[i]);
|
|
249
|
+
const value = {
|
|
250
|
+
name: oHistory[i],
|
|
251
|
+
};
|
|
252
|
+
oHistoryVars.push(value);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
//===================================================================================================
|
|
266
|
+
// ebusd interface
|
|
267
|
+
|
|
268
|
+
async function ebusd_Command() {
|
|
269
|
+
const obj = await adapter.getStateAsync("cmd");
|
|
270
|
+
|
|
271
|
+
if (obj !== undefined && obj != null) {
|
|
272
|
+
const cmds = obj.val;
|
|
273
|
+
if (cmds !== "") {
|
|
274
|
+
adapter.log.debug("got command(s): " + cmds);
|
|
275
|
+
|
|
276
|
+
adapter.log.debug("connect telnet to IP " + adapter.config.targetIP + " port " + parseInt(adapter.config.targetTelnetPort));
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
const socket = new net.Socket();
|
|
280
|
+
const promiseSocket = new PromiseSocket(socket);
|
|
281
|
+
|
|
282
|
+
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
283
|
+
adapter.log.debug("telnet connected for cmd");
|
|
284
|
+
promiseSocket.setTimeout(5000);
|
|
285
|
+
|
|
286
|
+
const oCmds = cmds.split(",");
|
|
287
|
+
|
|
288
|
+
if (oCmds.length > 0) {
|
|
289
|
+
let received = "";
|
|
290
|
+
for (let n = 0; n < oCmds.length; n++) {
|
|
291
|
+
|
|
292
|
+
adapter.log.debug("send " + oCmds[n]);
|
|
293
|
+
await promiseSocket.write(oCmds[n] + "\n");
|
|
294
|
+
|
|
295
|
+
const data = await promiseSocket.read();
|
|
296
|
+
|
|
297
|
+
if (data.includes("ERR")) {
|
|
298
|
+
adapter.log.warn("sent " + oCmds[n] + ", received " + data + " please check ebusd logs for details!");
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
adapter.log.debug("received " + data);
|
|
302
|
+
}
|
|
303
|
+
received += data.toString();
|
|
304
|
+
received += ", ";
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
//see issue #78: remove CR, LF and last comma
|
|
308
|
+
received = received.replace(/\r?\n|\r/g,"");
|
|
309
|
+
received = received.slice(0, -2);
|
|
310
|
+
|
|
311
|
+
//set result to cmdResult
|
|
312
|
+
await adapter.setStateAsync("cmdResult", { ack: true, val: received });
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
adapter.log.warn("no commands in list " + cmds + " " + JSON.stringify(oCmds));
|
|
316
|
+
}
|
|
317
|
+
await adapter.setStateAsync("cmd", { ack: true, val: "" });
|
|
318
|
+
|
|
319
|
+
promiseSocket.destroy();
|
|
320
|
+
|
|
321
|
+
} catch (e) {
|
|
322
|
+
adapter.log.error("exception from tcp socket" + "[" + e + "]");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
adapter.log.debug("object cmd not found " + JSON.stringify(obj));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async function ebusd_find(){
|
|
332
|
+
try {
|
|
333
|
+
const socket = new net.Socket();
|
|
334
|
+
const promiseSocket = new PromiseSocket(socket);
|
|
335
|
+
|
|
336
|
+
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
337
|
+
adapter.log.debug("telnet connected for cmd");
|
|
338
|
+
promiseSocket.setTimeout(5000);
|
|
339
|
+
|
|
340
|
+
await promiseSocket.write("find -F circuit,name,comment\n");
|
|
341
|
+
|
|
342
|
+
const data = await promiseSocket.read();
|
|
343
|
+
|
|
344
|
+
if (data.includes("ERR")) {
|
|
345
|
+
adapter.log.warn("received error! sent find, received " + data + " please check ebusd logs for details!");
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
adapter.log.debug("received " + typeof data + " " + data);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const str = new TextDecoder().decode(data);
|
|
352
|
+
const datas = str.split(/\r?\n/);
|
|
353
|
+
|
|
354
|
+
for (let i = 0; i < datas.length; i++) {
|
|
355
|
+
|
|
356
|
+
//adapter.log.debug(JSON.stringify(datas[i]));
|
|
357
|
+
|
|
358
|
+
const names = datas[i].split(",");
|
|
359
|
+
|
|
360
|
+
//circuit,name,comment
|
|
361
|
+
await UpdateDP(names[0], names[1], names[2]);
|
|
362
|
+
|
|
363
|
+
let cmd = "read -f -c " + names[0] + " " + names[1] ;
|
|
364
|
+
|
|
365
|
+
adapter.log.debug("send cmd " + cmd);
|
|
366
|
+
|
|
367
|
+
cmd += "\n";
|
|
368
|
+
await promiseSocket.write(cmd);
|
|
369
|
+
|
|
370
|
+
const result = await promiseSocket.read();
|
|
371
|
+
|
|
372
|
+
adapter.log.debug("received " + typeof result + " " + result);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
promiseSocket.destroy();
|
|
377
|
+
|
|
378
|
+
} catch (e) {
|
|
379
|
+
adapter.log.error("exception from tcp socket in ebusd_find" + "[" + e + "]");
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
//just call http://192.168.0.123:8889/data
|
|
387
|
+
|
|
388
|
+
async function subscribeVars() {
|
|
389
|
+
adapter.subscribeStates("cmd");
|
|
390
|
+
|
|
391
|
+
adapter.subscribeStates("find");
|
|
392
|
+
|
|
393
|
+
await adapter.setStateAsync("cmdResult", { ack: true, val: "" });
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async function CreateObject(key, obj) {
|
|
397
|
+
|
|
398
|
+
const obj_new = await adapter.getObjectAsync(key);
|
|
399
|
+
//adapter.log.warn("got object " + JSON.stringify(obj_new));
|
|
400
|
+
|
|
401
|
+
if (obj_new != null) {
|
|
402
|
+
|
|
403
|
+
if ((obj_new.common.role != obj.common.role
|
|
404
|
+
|| obj_new.common.type != obj.common.type
|
|
405
|
+
|| (obj_new.common.unit != obj.common.unit && obj.common.unit != null)
|
|
406
|
+
|| obj_new.common.read != obj.common.read
|
|
407
|
+
|| obj_new.common.write != obj.common.write
|
|
408
|
+
|| obj_new.common.name != obj.common.name)
|
|
409
|
+
&& obj.type === "state"
|
|
410
|
+
) {
|
|
411
|
+
adapter.log.warn("change object " + JSON.stringify(obj) + " " + JSON.stringify(obj_new));
|
|
412
|
+
await adapter.extendObject(key, {
|
|
413
|
+
common: {
|
|
414
|
+
name: obj.common.name,
|
|
415
|
+
role: obj.common.role,
|
|
416
|
+
type: obj.common.type,
|
|
417
|
+
unit: obj.common.unit,
|
|
418
|
+
read: obj.common.read,
|
|
419
|
+
write: obj.common.write
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
await adapter.setObjectNotExistsAsync(key, obj);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
//circuit,name,comment
|
|
431
|
+
async function UpdateDP(circuit, name, comment) {
|
|
432
|
+
|
|
433
|
+
const key = circuit + ".messages." + name;
|
|
434
|
+
adapter.log.debug("update check for " + key);
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
// ehp.messages.Injection
|
|
438
|
+
//ebus.0.ehp.messages.Injection
|
|
439
|
+
|
|
440
|
+
const obj = await adapter.getObjectAsync(key);
|
|
441
|
+
adapter.log.debug("update check got " + JSON.stringify(obj));
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
//update check got null
|
|
445
|
+
|
|
446
|
+
if (obj != null) {
|
|
447
|
+
|
|
448
|
+
if (obj.common.name != comment) {
|
|
449
|
+
adapter.log.debug("update " + key + " " + comment);
|
|
450
|
+
await adapter.extendObject(key, {
|
|
451
|
+
common: {
|
|
452
|
+
name: comment,
|
|
453
|
+
read: true,
|
|
454
|
+
write: false
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
await adapter.setObjectNotExistsAsync(key, {
|
|
461
|
+
type: "channel",
|
|
462
|
+
common: {
|
|
463
|
+
name: comment,
|
|
464
|
+
read: true,
|
|
465
|
+
write: false
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
async function checkVariables() {
|
|
475
|
+
adapter.log.debug("init variables ");
|
|
476
|
+
|
|
477
|
+
let key;
|
|
478
|
+
let obj;
|
|
479
|
+
|
|
480
|
+
key = "cmd";
|
|
481
|
+
obj= {
|
|
482
|
+
type: "state",
|
|
483
|
+
common: {
|
|
484
|
+
name: "ebusd command",
|
|
485
|
+
type: "string",
|
|
486
|
+
role: "text",
|
|
487
|
+
read: true,
|
|
488
|
+
write: true
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
await CreateObject(key, obj);
|
|
492
|
+
|
|
493
|
+
key = "cmdResult";
|
|
494
|
+
obj = {
|
|
495
|
+
type: "state",
|
|
496
|
+
common: {
|
|
497
|
+
name: "ebusd command result",
|
|
498
|
+
type: "string",
|
|
499
|
+
role: "text",
|
|
500
|
+
read: true,
|
|
501
|
+
write: false
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
await CreateObject(key, obj);
|
|
505
|
+
|
|
506
|
+
key = "find";
|
|
507
|
+
obj = {
|
|
508
|
+
type: "state",
|
|
509
|
+
common: {
|
|
510
|
+
name: "find existing data points",
|
|
511
|
+
type: "boolean",
|
|
512
|
+
role: "button",
|
|
513
|
+
read: false,
|
|
514
|
+
write: true
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
await CreateObject(key, obj);
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
adapter.log.debug("init common variables and " + oHistoryVars.length + " history DP's");
|
|
522
|
+
|
|
523
|
+
if (oHistoryVars.length > 0) {
|
|
524
|
+
|
|
525
|
+
if (oHistoryVars.length > 4) {
|
|
526
|
+
adapter.log.warn("too many history values " + oHistoryVars.length + " -> maximum is 4");
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
for (let n = 1; n <= oHistoryVars.length; n++) {
|
|
530
|
+
|
|
531
|
+
if (oHistoryVars[n - 1].name.length > 0) {
|
|
532
|
+
const name = "history value " + n + " as JSON " + oHistoryVars[n - 1].name;
|
|
533
|
+
key = "history.value" + n;
|
|
534
|
+
obj= {
|
|
535
|
+
type: "state",
|
|
536
|
+
common: {
|
|
537
|
+
name: name,
|
|
538
|
+
type: "string",
|
|
539
|
+
role: "value",
|
|
540
|
+
unit: "",
|
|
541
|
+
read: true,
|
|
542
|
+
write: false
|
|
543
|
+
},
|
|
544
|
+
native: { location: key }
|
|
545
|
+
};
|
|
546
|
+
await CreateObject(key, obj);
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
adapter.log.warn("ignoring history value " + n + " (invalid name)");
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
key = "history.date";
|
|
554
|
+
obj= {
|
|
555
|
+
type: "state",
|
|
556
|
+
common: {
|
|
557
|
+
name: "ebus history date / time as JSON",
|
|
558
|
+
type: "string",
|
|
559
|
+
role: "value",
|
|
560
|
+
unit: "",
|
|
561
|
+
read: true,
|
|
562
|
+
write: false
|
|
563
|
+
},
|
|
564
|
+
native: {
|
|
565
|
+
location: key
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
await CreateObject(key, obj);
|
|
569
|
+
}
|
|
570
|
+
key = "history.error";
|
|
571
|
+
obj= {
|
|
572
|
+
type: "state",
|
|
573
|
+
common: {
|
|
574
|
+
name: "ebus error",
|
|
575
|
+
type: "string",
|
|
576
|
+
role: "value",
|
|
577
|
+
unit: "",
|
|
578
|
+
read: true,
|
|
579
|
+
write: false
|
|
580
|
+
},
|
|
581
|
+
native: { location: key }
|
|
582
|
+
};
|
|
583
|
+
await CreateObject(key, obj);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
function VersionCheck() {
|
|
588
|
+
|
|
589
|
+
if (ebusdVersion[0] > 0 ) {
|
|
590
|
+
if (ebusdVersion[0] < ebusdMinVersion[0] || (ebusdVersion[0] == ebusdMinVersion[0] && ebusdVersion[1] < ebusdMinVersion[1])) {
|
|
591
|
+
adapter.log.info("please update ebusd, old version found: " + ebusdVersion[0] + "." + ebusdVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
592
|
+
}
|
|
593
|
+
if (ebusdVersion[0] > ebusdMinVersion[0] || (ebusdVersion[0] >= ebusdMinVersion[0] && ebusdVersion[1] > ebusdMinVersion[1])) {
|
|
594
|
+
adapter.log.info("unsupported ebusd version found (too new): " + ebusdVersion[0] + "." + ebusdVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (ebusdUpdateVersion[0] > 0 && ebusdVersion[0] > 0) {
|
|
599
|
+
|
|
600
|
+
if (ebusdUpdateVersion[0] > ebusdVersion[0] || (ebusdUpdateVersion[0] == ebusdVersion[0] && ebusdUpdateVersion[1] > ebusdVersion[1])) {
|
|
601
|
+
adapter.log.info("new ebusd version found: " + ebusdUpdateVersion[0] + "." + ebusdUpdateVersion[1] + " supported version is " + ebusdMinVersion[0] + "." + ebusdMinVersion[1]);
|
|
602
|
+
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
//get data via https in json -> this is the main data receiver; telnet just triggers ebusd to read data;
|
|
609
|
+
//https://github.com/john30/ebusd/wiki/3.2.-HTTP-client
|
|
610
|
+
|
|
611
|
+
async function ebusd_ReceiveData() {
|
|
612
|
+
|
|
613
|
+
const sUrl = "http://" + adapter.config.targetIP + ":" + parseInt(adapter.config.targetHTTPPort) + "/data";
|
|
614
|
+
adapter.log.debug("request data from " + sUrl);
|
|
615
|
+
|
|
616
|
+
try {
|
|
617
|
+
|
|
618
|
+
const buffer = await axios.get(sUrl);
|
|
619
|
+
|
|
620
|
+
adapter.log.debug("got data " + typeof buffer.data + " " + JSON.stringify(buffer.data));
|
|
621
|
+
|
|
622
|
+
const oData = buffer.data;
|
|
623
|
+
|
|
624
|
+
//adapter.log.debug("oData " + oData);
|
|
625
|
+
|
|
626
|
+
const flatten = require("flat");
|
|
627
|
+
|
|
628
|
+
const newData = flatten(oData);
|
|
629
|
+
|
|
630
|
+
const keys = Object.keys(newData);
|
|
631
|
+
|
|
632
|
+
//adapter.log.debug("history: " + options.historyValues);
|
|
633
|
+
|
|
634
|
+
const historyvalues = [];
|
|
635
|
+
const historydates = [];
|
|
636
|
+
|
|
637
|
+
const oToday = new Date();
|
|
638
|
+
const month = oToday.getMonth() + 1;
|
|
639
|
+
|
|
640
|
+
historydates.push({
|
|
641
|
+
"date": oToday.getDate() + "." + month + "." + oToday.getFullYear(),
|
|
642
|
+
"time": oToday.getHours() + ":" + oToday.getMinutes() + ":" + oToday.getSeconds()
|
|
643
|
+
});
|
|
644
|
+
//adapter.log.debug(JSON.stringify(historydates));
|
|
645
|
+
|
|
646
|
+
let name = "unknown";
|
|
647
|
+
let sError = "none";
|
|
648
|
+
for (let i = 0; i < keys.length; i++) {
|
|
649
|
+
let key = keys[i];
|
|
650
|
+
const org_key = key;
|
|
651
|
+
|
|
652
|
+
if (key.includes("[") || key.includes("]")) {
|
|
653
|
+
adapter.log.debug("found unsupported chars in " + key);
|
|
654
|
+
const start = key.indexOf("[");
|
|
655
|
+
const end = key.lastIndexOf("]");
|
|
656
|
+
|
|
657
|
+
if (start > 0 && end > 0) {
|
|
658
|
+
const toReplace = key.slice(start, end + 1);
|
|
659
|
+
key = key.replace(toReplace, "");
|
|
660
|
+
}
|
|
661
|
+
//adapter.log.warn("new key is " + key);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const subnames = key.split(".");
|
|
665
|
+
const temp = subnames.length;
|
|
666
|
+
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key]);
|
|
667
|
+
|
|
668
|
+
//
|
|
669
|
+
//if (key.match(adapter.FORBIDDEN_CHARS)) { continue; }
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
if (key.includes("global.version")) {
|
|
673
|
+
const value = newData[org_key];
|
|
674
|
+
//adapter.log.info("in version, value " + value);
|
|
675
|
+
const versionInfo = value.split(".");
|
|
676
|
+
if (versionInfo.length > 1) {
|
|
677
|
+
adapter.log.info("installed ebusd version is " + versionInfo[0] + "." + versionInfo[1]);
|
|
678
|
+
|
|
679
|
+
ebusdVersion[0] = versionInfo[0];
|
|
680
|
+
ebusdVersion[1] = versionInfo[1];
|
|
681
|
+
|
|
682
|
+
VersionCheck();
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (key.includes("global.updatecheck")) {
|
|
687
|
+
let value = newData[org_key];
|
|
688
|
+
//adapter.log.info("in version, value " + value);
|
|
689
|
+
|
|
690
|
+
//revision v21.2 available
|
|
691
|
+
value = value.replace("revision v", "");
|
|
692
|
+
value = value.replace(" available", "");
|
|
693
|
+
|
|
694
|
+
const versionInfo = value.split(".");
|
|
695
|
+
if (versionInfo.length > 1) {
|
|
696
|
+
adapter.log.info("found ebusd update version " + versionInfo[0] + "." + versionInfo[1]);
|
|
697
|
+
|
|
698
|
+
ebusdUpdateVersion[0] = versionInfo[0];
|
|
699
|
+
ebusdUpdateVersion[1] = versionInfo[1];
|
|
700
|
+
|
|
701
|
+
VersionCheck();
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
if (subnames[temp - 1].includes("name")) {
|
|
708
|
+
name = newData[org_key];
|
|
709
|
+
}
|
|
710
|
+
else if (subnames[temp - 1].includes("value")) {
|
|
711
|
+
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
712
|
+
|
|
713
|
+
let value = newData[org_key];
|
|
714
|
+
|
|
715
|
+
if (value == null || value === undefined) {
|
|
716
|
+
adapter.log.debug("Key : " + key + ", Value : " + newData[org_key] + " name " + name);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
if (name === "hcmode2") {
|
|
721
|
+
if (parseInt(value) === 0) {
|
|
722
|
+
adapter.log.info(key + "in hcmode2 with value 0: off");
|
|
723
|
+
value = "off";
|
|
724
|
+
}
|
|
725
|
+
else if (parseInt(value) === 5) {
|
|
726
|
+
adapter.log.info(key + " with value 5: EVU Sperrzeit");
|
|
727
|
+
value = "EVU Sperrzeit";
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
adapter.log.debug("in hcmode2, value " + value);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
let type = typeof value;
|
|
735
|
+
|
|
736
|
+
if (adapter.config.useBoolean4Onoff) {
|
|
737
|
+
if (type == "string" && (value == "on" || value == "off")) {
|
|
738
|
+
adapter.log.debug("Key " + key + " change to boolean " + value);
|
|
739
|
+
//Key mc.messages.Status.fields.1.value could be boolean off
|
|
740
|
+
|
|
741
|
+
type = "boolean";
|
|
742
|
+
|
|
743
|
+
if (value == "on") {
|
|
744
|
+
value = true;
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
value = false;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
//value, change type if necessary
|
|
753
|
+
await AddObject(key, type);
|
|
754
|
+
await UpdateObject(key, value);
|
|
755
|
+
|
|
756
|
+
//name parallel to value: used for lists in admin...
|
|
757
|
+
const keyname = key.replace("value", "name");
|
|
758
|
+
await AddObject(keyname, "string");
|
|
759
|
+
|
|
760
|
+
await UpdateObject(keyname, name);
|
|
761
|
+
|
|
762
|
+
//push to history
|
|
763
|
+
//ebus.0.bai.messages.ReturnTemp.fields.temp.value
|
|
764
|
+
//ebus.0.bai.messages.ReturnTemp.fields.tempmirror.value
|
|
765
|
+
if (!subnames[temp - 2].includes("sensor") //ignore sensor states
|
|
766
|
+
&& !subnames[temp - 2].includes("mirror") //ignore mirror-data
|
|
767
|
+
) {
|
|
768
|
+
for (let ii = 0; ii < oHistoryVars.length; ii++) {
|
|
769
|
+
|
|
770
|
+
if (name === oHistoryVars[ii].name) {
|
|
771
|
+
|
|
772
|
+
const sTemp = '{"' + name + '": "' + value + '"}';
|
|
773
|
+
//adapter.log.debug(sTemp);
|
|
774
|
+
historyvalues[ii] = [];
|
|
775
|
+
historyvalues[ii].push(JSON.parse(sTemp));
|
|
776
|
+
//adapter.log.debug(JSON.stringify(historyvalues));
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
else if (subnames[temp - 1].includes("lastup")) {
|
|
782
|
+
|
|
783
|
+
const value = newData[org_key];
|
|
784
|
+
|
|
785
|
+
if (parseInt(value) > 0) {
|
|
786
|
+
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
787
|
+
|
|
788
|
+
//umrechnen...
|
|
789
|
+
const oDate = new Date(value * 1000);
|
|
790
|
+
//const nDate = oDate.getDate();
|
|
791
|
+
//const nMonth = oDate.getMonth() + 1;
|
|
792
|
+
//const nYear = oDate.getFullYear();
|
|
793
|
+
//const nHours = oDate.getHours();
|
|
794
|
+
//const nMinutes = oDate.getMinutes();
|
|
795
|
+
//const nSeconds = oDate.getSeconds();
|
|
796
|
+
|
|
797
|
+
const sDate = oDate.toLocaleString();
|
|
798
|
+
await AddObject(key, "string");
|
|
799
|
+
await UpdateObject(key, sDate);
|
|
800
|
+
|
|
801
|
+
const oToday = new Date();
|
|
802
|
+
|
|
803
|
+
let bSkip = false;
|
|
804
|
+
|
|
805
|
+
if (subnames[0].includes("scan") ||
|
|
806
|
+
subnames[0].includes("ehp") ||
|
|
807
|
+
(subnames.length>2 && subnames[2].includes("currenterror"))
|
|
808
|
+
|
|
809
|
+
) {
|
|
810
|
+
bSkip = true;
|
|
811
|
+
}
|
|
812
|
+
if (temp > 2) {
|
|
813
|
+
//adapter.log.debug("_______________size " + temp);
|
|
814
|
+
if (subnames[2].includes("Timer")) {
|
|
815
|
+
bSkip = true;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
if (!bSkip && Math.abs(oDate.getTime() - oToday.getTime()) > 1 * 60 * 60 * 1000) {
|
|
820
|
+
|
|
821
|
+
const sError1 = "no update since " + sDate + " " + key + " ";
|
|
822
|
+
if (sError.includes("none")) {
|
|
823
|
+
sError = "ebus: " + sError1;
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
sError += sError1;
|
|
827
|
+
}
|
|
828
|
+
adapter.log.warn(sError1);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
else if (subnames[0].includes("global")) {
|
|
835
|
+
//adapter.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
836
|
+
const value = newData[org_key];
|
|
837
|
+
await AddObject(key, typeof value);
|
|
838
|
+
await UpdateObject(key, value);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
await adapter.setStateAsync("history.error", { ack: true, val: sError });
|
|
842
|
+
|
|
843
|
+
//adapter.log.debug(JSON.stringify(historyvalues));
|
|
844
|
+
|
|
845
|
+
adapter.log.info("all http done");
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
await UpdateHistory(historyvalues, historydates);
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
}
|
|
852
|
+
catch (e) {
|
|
853
|
+
adapter.log.error("exception in ebusd_ReceiveData [" + e + "]");
|
|
854
|
+
|
|
855
|
+
await adapter.setStateAsync("history.error", { ack: true, val: "exception in receive" });
|
|
856
|
+
}
|
|
857
|
+
//});
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
async function UpdateHistory(values, dates) {
|
|
863
|
+
|
|
864
|
+
if (oHistoryVars.length > 0) {
|
|
865
|
+
//prüfen ob alle json gleich lang sind
|
|
866
|
+
let NoOfDates = -1;
|
|
867
|
+
|
|
868
|
+
const obj = await adapter.getStateAsync("history.date");
|
|
869
|
+
|
|
870
|
+
if (obj !== undefined && obj != null) {
|
|
871
|
+
try {
|
|
872
|
+
let oEbusDates = [];
|
|
873
|
+
//adapter.log.debug("before " + obj.val);
|
|
874
|
+
oEbusDates = JSON.parse(obj.val);
|
|
875
|
+
//adapter.log.debug("after parse " + JSON.stringify(oEbusDates));
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
oEbusDates.push(dates);
|
|
880
|
+
//adapter.log.debug("after push " + JSON.stringify(oEbusDates));
|
|
881
|
+
//limit length of object...
|
|
882
|
+
if (oEbusDates.length > 200) {
|
|
883
|
+
|
|
884
|
+
for (let i = oEbusDates.length; i > 200; i--) {
|
|
885
|
+
//adapter.log.debug("delete");
|
|
886
|
+
oEbusDates.shift();
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
NoOfDates = oEbusDates.length;
|
|
890
|
+
await adapter.setStateAsync("history.date", { ack: true, val: JSON.stringify(oEbusDates) });
|
|
891
|
+
}
|
|
892
|
+
catch (e) {
|
|
893
|
+
adapter.log.error("exception in UpdateHistory part1 [" + e + "]");
|
|
894
|
+
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
895
|
+
NoOfDates = 0;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
adapter.log.warn("history.date not found, creating DP ");
|
|
900
|
+
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
901
|
+
NoOfDates = 0;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (oHistoryVars.length > 0) {
|
|
905
|
+
for (let ctr = 1; ctr <= oHistoryVars.length; ctr++) {
|
|
906
|
+
|
|
907
|
+
if (oHistoryVars[ctr - 1].name.length > 0) {
|
|
908
|
+
const ctrOkay = await UpdateHistoryValues(values, ctr, NoOfDates);
|
|
909
|
+
|
|
910
|
+
if (!ctrOkay) {
|
|
911
|
+
await adapter.setStateAsync("history.date", { ack: true, val: "[]" });
|
|
912
|
+
NoOfDates = 0;
|
|
913
|
+
adapter.log.warn("reset history date too");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
else {
|
|
917
|
+
adapter.log.debug("ignoring history value " + ctr);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
adapter.log.info("all history done");
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
adapter.log.debug("nothing to do for history");
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
async function UpdateHistoryValues(values, ctr, curDateCtr) {
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
let bRet = true;
|
|
935
|
+
|
|
936
|
+
const obj = await adapter.getStateAsync("history.value" + ctr);
|
|
937
|
+
|
|
938
|
+
if (obj !== undefined && obj != null) {
|
|
939
|
+
try {
|
|
940
|
+
let oEbusValues = [];
|
|
941
|
+
if (obj !== null) {
|
|
942
|
+
//adapter.log.debug("before " + obj.val);
|
|
943
|
+
|
|
944
|
+
oEbusValues = JSON.parse(obj.val);
|
|
945
|
+
|
|
946
|
+
//adapter.log.debug("after parse " + JSON.stringify(oEbusValues));
|
|
947
|
+
|
|
948
|
+
//adapter.log.debug("after parse cnt " + oEbusValues.length);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
//adapter.log.debug("values " + ctr + ": " + JSON.stringify(values[ctr-1]));
|
|
952
|
+
|
|
953
|
+
oEbusValues.push(values[ctr - 1]);
|
|
954
|
+
//adapter.log.debug("after push " + JSON.stringify(oEbusValues));
|
|
955
|
+
//adapter.log.debug("after push cnt " + oEbusValues.length);
|
|
956
|
+
//limit length of object...
|
|
957
|
+
if (oEbusValues.length > 200) {
|
|
958
|
+
|
|
959
|
+
for (let i = oEbusValues.length; i > 200; i--) {
|
|
960
|
+
//adapter.log.debug("delete");
|
|
961
|
+
oEbusValues.shift();
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
const key = "history.value" + ctr;
|
|
966
|
+
adapter.log.debug("update history " + key);
|
|
967
|
+
|
|
968
|
+
if (curDateCtr != oEbusValues.length) {
|
|
969
|
+
bRet = false;
|
|
970
|
+
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
971
|
+
adapter.log.warn("reset history " + key + " because number of values different to date values");
|
|
972
|
+
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
await adapter.setStateAsync(key, { ack: true, val: JSON.stringify(oEbusValues) });
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
}
|
|
980
|
+
catch (e) {
|
|
981
|
+
adapter.log.error("exception in UpdateHistory part2 [" + e + "]");
|
|
982
|
+
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
983
|
+
if (curDateCtr > 0) {
|
|
984
|
+
bRet = false;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
adapter.log.warn("history.value" + ctr + " not found, creating DP " + JSON.stringify(obj));
|
|
990
|
+
await adapter.setStateAsync("history.value" + ctr, { ack: true, val: "[]" });
|
|
991
|
+
if (curDateCtr > 0) {
|
|
992
|
+
bRet = false;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
return bRet;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
async function AddObject(key, type) {
|
|
1002
|
+
//adapter.log.debug("addObject " + key);
|
|
1003
|
+
|
|
1004
|
+
try {
|
|
1005
|
+
const obj = await adapter.getObjectAsync(key);
|
|
1006
|
+
|
|
1007
|
+
if (obj != null) {
|
|
1008
|
+
//adapter.log.debug(" got Object " + JSON.stringify(obj));
|
|
1009
|
+
if (obj.common.role != "value"
|
|
1010
|
+
|| obj.common.type != type) {
|
|
1011
|
+
adapter.log.debug(" !!! need to extend for " + key);
|
|
1012
|
+
await adapter.extendObject(key, {
|
|
1013
|
+
common: {
|
|
1014
|
+
type: type,
|
|
1015
|
+
role: "value",
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
adapter.log.warn(" !!! does not exist, creating now " + key );
|
|
1022
|
+
|
|
1023
|
+
await adapter.setObjectNotExistsAsync(key, {
|
|
1024
|
+
type: "state",
|
|
1025
|
+
common: {
|
|
1026
|
+
name: "data",
|
|
1027
|
+
type: type,
|
|
1028
|
+
role: "value",
|
|
1029
|
+
unit: "",
|
|
1030
|
+
read: true,
|
|
1031
|
+
write: false
|
|
1032
|
+
},
|
|
1033
|
+
native: {
|
|
1034
|
+
location: key
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
} catch (e) {
|
|
1040
|
+
adapter.log.error("exception in AddObject " + "[" + e + "]");
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
async function UpdateObject(key, value) {
|
|
1045
|
+
try {
|
|
1046
|
+
if (value === undefined) {
|
|
1047
|
+
adapter.log.warn("updateObject: not updated " + key + " value: " + value + " " + typeof value);
|
|
1048
|
+
}
|
|
1049
|
+
else if (value == null ) {
|
|
1050
|
+
adapter.log.debug("updateObject: update to null " + key + " value: " + value);
|
|
1051
|
+
await adapter.setStateAsync(key, { ack: true, val: null });
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
adapter.log.debug("updateObject " + key + " : " + value);
|
|
1055
|
+
await adapter.setStateAsync(key, { ack: true, val: value });
|
|
1056
|
+
}
|
|
1057
|
+
} catch (e) {
|
|
1058
|
+
adapter.log.error("exception in UpdateObject " + "[" + e + "]");
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
//telnet client to write to ebusd
|
|
1064
|
+
//https://github.com/john30/ebusd/wiki/3.1.-TCP-client-commands
|
|
1065
|
+
/*
|
|
1066
|
+
telnet 192.168.3.144 8890
|
|
1067
|
+
|
|
1068
|
+
find -f -c broadcast outsidetemp
|
|
1069
|
+
find -f outsidetemp
|
|
1070
|
+
find -f YieldTotal
|
|
1071
|
+
|
|
1072
|
+
read -f YieldTotal
|
|
1073
|
+
read LegioProtectionEnabled
|
|
1074
|
+
|
|
1075
|
+
read -f YieldTotal,read LegioProtectionEnabled,read -f -c broadcast outsidetemp
|
|
1076
|
+
|
|
1077
|
+
*/
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
//this function just triggers ebusd to read data; result will not be parsed; we just take the values from http result
|
|
1081
|
+
//here we need a loop over all configured read data in admin-page
|
|
1082
|
+
async function ebusd_ReadValues() {
|
|
1083
|
+
|
|
1084
|
+
if (oPolledVars.length > 0) {
|
|
1085
|
+
|
|
1086
|
+
adapter.log.debug("to poll ctr " + oPolledVars.length + " vals: " + JSON.stringify(oPolledVars));
|
|
1087
|
+
|
|
1088
|
+
try {
|
|
1089
|
+
const socket = new net.Socket();
|
|
1090
|
+
const promiseSocket = new PromiseSocket(socket);
|
|
1091
|
+
|
|
1092
|
+
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
1093
|
+
adapter.log.debug("telnet connected to poll variables " + adapter.config.targetIP + " port " + adapter.config.targetTelnetPort);
|
|
1094
|
+
promiseSocket.setTimeout(5000);
|
|
1095
|
+
|
|
1096
|
+
let retries = 0;
|
|
1097
|
+
for (let nCtr = 0; nCtr < oPolledVars.length; nCtr++) {
|
|
1098
|
+
|
|
1099
|
+
let circuit = "";
|
|
1100
|
+
let params = "";
|
|
1101
|
+
if (oPolledVars[nCtr].circuit != null && oPolledVars[nCtr].circuit.length > 0) {
|
|
1102
|
+
circuit = "-c " + oPolledVars[nCtr].circuit + " ";
|
|
1103
|
+
}
|
|
1104
|
+
if (oPolledVars[nCtr].parameter != null && oPolledVars[nCtr].parameter.length > 0) {
|
|
1105
|
+
params = " " + oPolledVars[nCtr].parameter;
|
|
1106
|
+
}
|
|
1107
|
+
let cmd = "read -f " + circuit + oPolledVars[nCtr].name + params;
|
|
1108
|
+
|
|
1109
|
+
adapter.log.debug("send cmd " + cmd);
|
|
1110
|
+
|
|
1111
|
+
cmd += "\n";
|
|
1112
|
+
await promiseSocket.write(cmd);
|
|
1113
|
+
|
|
1114
|
+
const data = await promiseSocket.read();
|
|
1115
|
+
|
|
1116
|
+
//received ERR: arbitration lost for YieldThisYear
|
|
1117
|
+
if (data.includes("ERR")) {
|
|
1118
|
+
adapter.log.warn("sent " + cmd + ", received " + data + " for " + JSON.stringify(oPolledVars[nCtr]) + " please check ebusd logs for details!");
|
|
1119
|
+
|
|
1120
|
+
/*
|
|
1121
|
+
* sent read -f YieldLastYear, received ERR: arbitration lost for {"circuit":"","name":"YieldLastYear","parameter":""}
|
|
1122
|
+
* */
|
|
1123
|
+
if (data.includes("arbitration lost")) {
|
|
1124
|
+
|
|
1125
|
+
retries++;
|
|
1126
|
+
if (retries > adapter.config.maxretries) {
|
|
1127
|
+
adapter.log.error("max retries, skip cmd " + cmd);
|
|
1128
|
+
retries = 0;
|
|
1129
|
+
}
|
|
1130
|
+
else {
|
|
1131
|
+
nCtr--;
|
|
1132
|
+
adapter.log.debug("retry to send data ");
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
adapter.log.debug("received " + data + " for " + JSON.stringify(oPolledVars[nCtr]));
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
promiseSocket.destroy();
|
|
1141
|
+
adapter.log.debug("telnet disonnected");
|
|
1142
|
+
|
|
1143
|
+
} catch (e) {
|
|
1144
|
+
adapter.log.error("exception from tcp socket in ebusd_ReadValues " + "[" + e + "]");
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
}
|
|
1149
|
+
else {
|
|
1150
|
+
adapter.log.debug("nothing to poll; skip telnet");
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
async function FindParams(obj) {
|
|
1157
|
+
|
|
1158
|
+
adapter.log.debug("FindParams " + JSON.stringify(obj));
|
|
1159
|
+
|
|
1160
|
+
const list = [];
|
|
1161
|
+
|
|
1162
|
+
try {
|
|
1163
|
+
const circuit = obj.message;
|
|
1164
|
+
|
|
1165
|
+
const socket = new net.Socket();
|
|
1166
|
+
const promiseSocket = new PromiseSocket(socket);
|
|
1167
|
+
|
|
1168
|
+
await promiseSocket.connect(parseInt(adapter.config.targetTelnetPort), adapter.config.targetIP);
|
|
1169
|
+
adapter.log.debug("telnet connected for cmd");
|
|
1170
|
+
promiseSocket.setTimeout(5000);
|
|
1171
|
+
|
|
1172
|
+
await promiseSocket.write("find -c " + circuit + " -F circuit,name\n");
|
|
1173
|
+
|
|
1174
|
+
const data = await promiseSocket.read();
|
|
1175
|
+
|
|
1176
|
+
if (data.includes("ERR")) {
|
|
1177
|
+
adapter.log.warn("received error! sent find, received " + data + " please check ebusd logs for details!");
|
|
1178
|
+
}
|
|
1179
|
+
else {
|
|
1180
|
+
adapter.log.debug("received " + typeof data + " " + data);
|
|
1181
|
+
}
|
|
1182
|
+
/*
|
|
1183
|
+
received object ehp,AccelerationTestModeehp,AccelerationTestModeehp,ActualEnvironmentPowerehp,ActualEnvironmentPowerehp,ActualEnvironmentPowerPercentageehp,ActualEnvironmentPowerPercentageehp,ApplianceCodeehp,ApplianceCodeehp,Backupehp,Backupehp,BackupHoursehp,BackupHoursHcehp,BackupHoursHwcehp,BackupHysteresisehp,BackupIntegralehp,BackupModeHcehp,BackupModeHwcehp,BackupPowerCutehp,BackupStartsehp,BackupStartsHcehp,BackupStartsHwcehp,BackupTypeehp,BivalentTempehp,Bleedingehp,Bleedingehp,CirPumpehp,CirPumpehp,Code1ehp,Code1Code2Validehp,Code2ehp,Compehp,Compehp,CompControlStateehp,CompCutPressHighCountehp,CompCutPressLowCountehp,CompCutTempCountehp,CompDemandehp,CompHoursehp,CompHoursHcehp,CompHoursHwcehp,CompHysteresisehp,CompIntegralehp,CompPressHighehp,CompPressHighehp,CompPressLowehp,CompPressLowehp,CompStartsehp,CompStartsHcehp,CompStartsHwcehp,CompStateehp,CondensorTempehp,CondensorTempehp,currenterrorehp,Dateehp,DateTimeehp,DeltaTempT6T7ehp,ElectricWiringDiagramehp,ElectricWiringDiagramehp,EnergyBalancingReleaseehp,errorhistoryehp,FlowTempehp,FlowTempehp,FlowtempCoolingMinehp,FlowTempOffsetehp,Hc1Pumpehp,Hc1Pumpehp,Hc1PumpHoursehp,Hc1PumpPortehp,Hc1PumpStartsehp,Hc2Pumpehp,Hc2PumpHoursehp,HcFlowTempehp,HcFlowTempOffsetehp,HcModeDemandHoursehp,HcModeFulfilledHoursehp,HcParallelStorageFillingEnabledehp,HcPressehp,HcReturnTempehp,HcReturnTempehp,HcReturnTempOffsetehp,HeatPumpStatusehp,HeatPumpStatusehp,HeatpumpTypeehp,HwcHcValveehp,HwcHcValveehp,HwcHcValveStartsehp,HwcLaggingTimeehp,HwcLoadingDelayehp,HwcModeDemandHoursehp,HwcModeFulfilledHoursehp,HwcPumpStartsehp,HwcSwitchehp,HwcTempehp,HwcTempehp,HwcTempOffsetehp,HydraulicSchemeehp,ICLOutehp,ICLOutehp,Injectionehp,Integralehp,Mixer1DutyCycleehp,NumberCompStartsehp,OutsideTempehp,OutsideTempOffsetehp,OverpressureThresholdehp,PhaseOrderehp,PhaseOrderehp,PhaseStatusehp,PhaseStatusehp,PowerCutehp,PowerCutPreloadingehp,PressSwitchehp,PressSwitchehp,RebootCounterehp,ReturnTempMaxehp,SetModeehp,SoftwareCodeehp,Source2PumpHoursehp,Sourceehp,Sourceehp,SourceHoursehp,SourcePortehp,SourcePressehp,SourcePumpPrerunTimeehp,SourceStartsehp,SourceSwitchehp,SourceSwitchehp,SourceTempInputehp,SourceTempInputehp,SourceTempInputOffsetehp,SourceTempOutputehp,SourceTempOutputehp,SourceTempOutputOffsetehp,SourceTempOutputT8Minehp,StateSoftwareCodeehp,StateSoftwareCodeehp,Status01ehp,Status02ehp,Status16ehp,Statusehp,StatusCirPumpehp,StorageTempBottomehp,StorageTempBottomehp,StorageTempBottomOffsetehp,StorageTempTopehp,StorageTempTopehp,StorageTempTopOffsetehp,Subcoolingehp,Superheatehp,T19MaxToCompOffehp,TempInputehp,TempInputehp,TempInputOffsetehp,TempOutputehp,TempOutputehp,TempOutputOffsetehp,Timeehp,TimeBetweenTwoCompStartsMinehp,TimeCompOffMinehp,TimeCompOnMinehp,TimeOfNextPredictedPowerCutehp,TimeOfNextPredictedPowerCutehp,Weekdayehp,YieldTotalehp,YieldTotal
|
|
1184
|
+
*/
|
|
1185
|
+
const str = new TextDecoder().decode(data);
|
|
1186
|
+
const datas = str.split(/\r?\n/);
|
|
1187
|
+
|
|
1188
|
+
for (let i = 0; i < datas.length; i++) {
|
|
1189
|
+
|
|
1190
|
+
//adapter.log.debug(JSON.stringify(datas[i]));
|
|
1191
|
+
|
|
1192
|
+
const names = datas[i].split(",");
|
|
1193
|
+
|
|
1194
|
+
//doppelte und leere herausfiltern
|
|
1195
|
+
let add = true;
|
|
1196
|
+
|
|
1197
|
+
if (names[0] == "" || names[1] == "") {
|
|
1198
|
+
add = false;
|
|
1199
|
+
}
|
|
1200
|
+
else {
|
|
1201
|
+
|
|
1202
|
+
for (let n = 0; n < list.length; n++) {
|
|
1203
|
+
|
|
1204
|
+
if (list[n].circuit == names[0] && list[n].name == names[1]) {
|
|
1205
|
+
add = false;
|
|
1206
|
+
//already in list
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
if (add) {
|
|
1212
|
+
const entry = {
|
|
1213
|
+
active: false,
|
|
1214
|
+
circuit: names[0],
|
|
1215
|
+
name: names[1]
|
|
1216
|
+
};
|
|
1217
|
+
|
|
1218
|
+
list.push(entry);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
} catch (e) {
|
|
1222
|
+
adapter.log.error("exception in FindParams " + "[" + e + "]");
|
|
1223
|
+
}
|
|
1224
|
+
adapter.sendTo(obj.from, obj.command, list, obj.callback);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// If started as allInOne/compact mode => return function to create instance
|
|
1228
|
+
if (module && module.parent) {
|
|
1229
|
+
module.exports = startAdapter;
|
|
1230
|
+
} else {
|
|
1231
|
+
// or start the instance directly
|
|
1232
|
+
startAdapter();
|
|
1233
1233
|
}
|