iobroker.ebus 3.8.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -201
- package/admin/assets/index-BUE1sWgp.js +1 -0
- package/admin/assets/index-Bd3GtHgn.css +1 -0
- package/admin/assets/index-D1_jHHDi.js +2754 -0
- package/admin/index_m.html +30 -426
- package/admin/manifest.json +15 -0
- package/{lib → build/lib}/TelnetClient.js +38 -29
- package/build/lib/TelnetClient.js.map +1 -0
- package/build/lib/types.js +3 -0
- package/build/lib/types.js.map +1 -0
- package/build/main.js +1350 -0
- package/build/main.js.map +1 -0
- package/io-package.json +76 -36
- package/package.json +15 -7
- package/admin/i18n/de/translations.json +0 -53
- package/admin/i18n/en/translations.json +0 -53
- package/admin/i18n/es/translations.json +0 -53
- package/admin/i18n/fr/translations.json +0 -53
- package/admin/i18n/it/translations.json +0 -53
- package/admin/i18n/nl/translations.json +0 -53
- package/admin/i18n/pl/translations.json +0 -53
- package/admin/i18n/pt/translations.json +0 -53
- package/admin/i18n/ru/translations.json +0 -53
- package/admin/i18n/uk/translations.json +0 -53
- package/admin/i18n/zh-cn/translations.json +0 -53
- package/admin/img/info-big.png +0 -0
- package/admin/jsonConfig.json5 +0 -558
- package/admin/style.css +0 -18
- package/admin/words.js +0 -62
- package/lib/scripts/InstallEbusd.sh +0 -23
- package/lib/scripts/UpdateEbusd.sh +0 -27
- package/lib/support_tools.js +0 -353
- package/main.js +0 -1807
package/build/main.js
ADDED
|
@@ -0,0 +1,1350 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable prefer-template */
|
|
3
|
+
/*
|
|
4
|
+
* Created with @iobroker/create-adapter v2.6.5
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.ebus = void 0;
|
|
44
|
+
// https://www.iobroker.net/#en/documentation/dev/adapterdev.md
|
|
45
|
+
//import os from "os";
|
|
46
|
+
//import fs from "fs";
|
|
47
|
+
//import path from "path";
|
|
48
|
+
//import spawn from "child_process";
|
|
49
|
+
const utils = __importStar(require("@iobroker/adapter-core"));
|
|
50
|
+
const axios_1 = __importDefault(require("axios"));
|
|
51
|
+
const TelnetClient_1 = __importDefault(require("./lib/TelnetClient"));
|
|
52
|
+
class ebus extends utils.Adapter {
|
|
53
|
+
intervalID = null;
|
|
54
|
+
updateTimerID = null;
|
|
55
|
+
requestRunning = false;
|
|
56
|
+
oPolledVars = [];
|
|
57
|
+
oHistoryVars = [];
|
|
58
|
+
oHTTPParamsVars = [];
|
|
59
|
+
ebusdMinVersion = [26, 1];
|
|
60
|
+
ebusdVersion = [0, 0];
|
|
61
|
+
ebusdUpdateVersion = [0, 0];
|
|
62
|
+
constructor(options = {}) {
|
|
63
|
+
super({
|
|
64
|
+
...options,
|
|
65
|
+
name: "ebus",
|
|
66
|
+
});
|
|
67
|
+
this.on("ready", this.onReady.bind(this));
|
|
68
|
+
this.on("stateChange", this.onStateChange.bind(this));
|
|
69
|
+
this.on("objectChange", this.onObjectChange.bind(this));
|
|
70
|
+
this.on("message", this.onMessage.bind(this));
|
|
71
|
+
this.on("unload", this.onUnload.bind(this));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Wird aufgerufen, wenn die Datenbanken verbunden sind und die Adapter-Konfiguration empfangen wurde.
|
|
75
|
+
*/
|
|
76
|
+
async onReady() {
|
|
77
|
+
this.log.debug(JSON.stringify(this.config));
|
|
78
|
+
try {
|
|
79
|
+
await this.main();
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
this.log.error("Exception in onReady [" + e + "]");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Wird aufgerufen, wenn der Adapter heruntergefahren wird - Callback MUSS unter allen Umständen aufgerufen werden!
|
|
87
|
+
*/
|
|
88
|
+
async onUnload(callback) {
|
|
89
|
+
await Promise.resolve(); //dummy await to make function async
|
|
90
|
+
try {
|
|
91
|
+
// Hier müssen alle Timeouts oder Intervalle gelöscht werden, die noch aktiv sein könnten
|
|
92
|
+
if (this.intervalID != null) {
|
|
93
|
+
clearInterval(this.intervalID);
|
|
94
|
+
}
|
|
95
|
+
if (this.updateTimerID != null) {
|
|
96
|
+
clearTimeout(this.updateTimerID);
|
|
97
|
+
}
|
|
98
|
+
this.log.info("cleaned everything up...");
|
|
99
|
+
callback();
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
this.log.error("Exception in onUnload " + e);
|
|
103
|
+
callback();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Wird aufgerufen, wenn ein abonniertes Objekt geändert wird
|
|
108
|
+
*/
|
|
109
|
+
onObjectChange(id, obj) {
|
|
110
|
+
if (obj) {
|
|
111
|
+
this.log.info(`Objekt ${id} geändert: ${JSON.stringify(obj)}`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.log.info(`Objekt ${id} gelöscht`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Wird aufgerufen, wenn ein abonnierter State geändert wird
|
|
119
|
+
*/
|
|
120
|
+
async onStateChange(id, state) {
|
|
121
|
+
if (state != null && state.ack !== true) {
|
|
122
|
+
this.log.debug(`handle state change ${id}`);
|
|
123
|
+
const ids = id.split(".");
|
|
124
|
+
if (ids[2] === "cmd") {
|
|
125
|
+
await this.ebusd_Command();
|
|
126
|
+
this.StartDataRequest();
|
|
127
|
+
//see issue #77: only one request possible
|
|
128
|
+
//await Do();
|
|
129
|
+
}
|
|
130
|
+
else if (ids[2] === "find") {
|
|
131
|
+
//unhandled state change ebus.0.find
|
|
132
|
+
await this.ebusd_find();
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.log.warn(`unhandled state change ${id}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Nachrichtenbehandlung
|
|
141
|
+
*/
|
|
142
|
+
async onMessage(obj) {
|
|
143
|
+
this.log.info("on message " + JSON.stringify(obj));
|
|
144
|
+
await Promise.resolve();
|
|
145
|
+
if (typeof obj === "object" && obj.command) {
|
|
146
|
+
switch (obj.command) {
|
|
147
|
+
case "findParams":
|
|
148
|
+
this.log.debug("message FindParams called");
|
|
149
|
+
await this.FindParams(obj);
|
|
150
|
+
break;
|
|
151
|
+
case "Install":
|
|
152
|
+
this.log.debug("message install called");
|
|
153
|
+
//await this.CallExternalScript("InstallEbusd.sh", obj);
|
|
154
|
+
break;
|
|
155
|
+
case "Update":
|
|
156
|
+
this.log.debug("message update called");
|
|
157
|
+
//await this.CallExternalScript("UpdateEbusd.sh", obj);
|
|
158
|
+
break;
|
|
159
|
+
case "checkInstallableversion":
|
|
160
|
+
await this.CheckVersion("installable", obj);
|
|
161
|
+
break;
|
|
162
|
+
case "checkCurrentVersion":
|
|
163
|
+
await this.CheckVersion("current", obj);
|
|
164
|
+
break;
|
|
165
|
+
case "checkSupportedVersion":
|
|
166
|
+
await this.CheckVersion("supported", obj);
|
|
167
|
+
break;
|
|
168
|
+
default:
|
|
169
|
+
this.log.error(`unknown message ${obj.command}`);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async main() {
|
|
175
|
+
this.log.debug("start with interface ebusd ");
|
|
176
|
+
this.FillPolledVars();
|
|
177
|
+
this.FillHistoryVars();
|
|
178
|
+
this.FillHTTPParamsVars();
|
|
179
|
+
await this.checkVariables();
|
|
180
|
+
await this.subscribeVars();
|
|
181
|
+
let readInterval = 5;
|
|
182
|
+
if (this.config.readInterval > 0) {
|
|
183
|
+
readInterval = this.config.readInterval;
|
|
184
|
+
}
|
|
185
|
+
this.log.debug(`read every ${readInterval} minutes`);
|
|
186
|
+
this.intervalID = setInterval(this.Do.bind(this), readInterval * 60 * 1000);
|
|
187
|
+
//read at thisstart
|
|
188
|
+
await this.Do();
|
|
189
|
+
}
|
|
190
|
+
async DoRequest() {
|
|
191
|
+
this.log.debug("DoRequest ");
|
|
192
|
+
if (!this.requestRunning) {
|
|
193
|
+
this.requestRunning = true;
|
|
194
|
+
await this.ebusd_ReadValues();
|
|
195
|
+
await this.ebusd_ReceiveData();
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this.log.debug("DoRequest: do nothing already running ");
|
|
199
|
+
}
|
|
200
|
+
this.requestRunning = false;
|
|
201
|
+
}
|
|
202
|
+
async Do() {
|
|
203
|
+
this.log.debug("starting ... ");
|
|
204
|
+
await this.ebusd_Command();
|
|
205
|
+
await this.DoRequest();
|
|
206
|
+
}
|
|
207
|
+
StartDataRequest() {
|
|
208
|
+
if (this.updateTimerID != null) {
|
|
209
|
+
//already running
|
|
210
|
+
clearTimeout(this.updateTimerID);
|
|
211
|
+
this.updateTimerID = null;
|
|
212
|
+
}
|
|
213
|
+
//start or restart
|
|
214
|
+
this.updateTimerID = setTimeout(this.DataRequest, 500);
|
|
215
|
+
this.log.debug("StartDataRequest");
|
|
216
|
+
}
|
|
217
|
+
async DataRequest() {
|
|
218
|
+
this.log.debug("get data after command and timeout");
|
|
219
|
+
if (this.updateTimerID != null) {
|
|
220
|
+
clearTimeout(this.updateTimerID);
|
|
221
|
+
this.updateTimerID = null;
|
|
222
|
+
}
|
|
223
|
+
await this.DoRequest();
|
|
224
|
+
}
|
|
225
|
+
FillPolledVars() {
|
|
226
|
+
try {
|
|
227
|
+
if (this.config.PolledDPs !== undefined &&
|
|
228
|
+
this.config.PolledDPs != null &&
|
|
229
|
+
this.config.PolledDPs.length > 0) {
|
|
230
|
+
this.log.debug("use new object list for polled vars");
|
|
231
|
+
//2023-02-10 only active vars
|
|
232
|
+
for (let i = 0; i < this.config.PolledDPs.length; i++) {
|
|
233
|
+
if (this.config.PolledDPs[i].active) {
|
|
234
|
+
this.oPolledVars.push(this.config.PolledDPs[i]);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
this.log.error(`exception in FillPolledVars [${e}]`);
|
|
241
|
+
}
|
|
242
|
+
this.log.debug(`list of polled vars ${JSON.stringify(this.oPolledVars)}`);
|
|
243
|
+
}
|
|
244
|
+
FillHistoryVars() {
|
|
245
|
+
try {
|
|
246
|
+
if (this.config.HistoryDPs !== undefined &&
|
|
247
|
+
this.config.HistoryDPs != null &&
|
|
248
|
+
this.config.HistoryDPs.length > 0) {
|
|
249
|
+
this.log.debug("use new object list for history vars");
|
|
250
|
+
this.oHistoryVars = this.config.HistoryDPs;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
this.log.error(`exception in function FillHistoryVars [${e}]`);
|
|
255
|
+
}
|
|
256
|
+
this.log.debug(`list of history vars ${JSON.stringify(this.oHistoryVars)}`);
|
|
257
|
+
//add a check, that complete dp without ebus.0 is used 2025-08-20
|
|
258
|
+
this.oHistoryVars.forEach((entry, index) => {
|
|
259
|
+
const hasDot = entry.name.includes(".");
|
|
260
|
+
const hasInstance = entry.name.includes("ebus.");
|
|
261
|
+
const hasValue = entry.name.includes("value");
|
|
262
|
+
this.log.debug("checking " + entry.name + " index " + index + " hasDot: " + hasDot + " hasInstance: " + hasInstance + " hasValue: " + hasValue);
|
|
263
|
+
if (!hasDot) {
|
|
264
|
+
this.log.warn("please check history variable: " + entry.name + " -> should contain the complete DP");
|
|
265
|
+
}
|
|
266
|
+
if (!hasValue) {
|
|
267
|
+
this.log.warn("please check history variable " + entry.name + " -> should contain 'value'");
|
|
268
|
+
}
|
|
269
|
+
if (hasInstance) {
|
|
270
|
+
this.log.warn("please check history variable " + entry.name + " -> should not contain instance name and instance number e.g. 'ebus.0' ");
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
//list of history vars [{"name":"ActualEnvironmentPower"},{"name":"YieldTotal"},{"name":"SourceTempInput"},{"name":"SourceTempOutput"},{"name":"HwcTemp"}]
|
|
274
|
+
}
|
|
275
|
+
FillHTTPParamsVars() {
|
|
276
|
+
if (this.config.HTTPparameter !== undefined &&
|
|
277
|
+
this.config.HTTPparameter != null &&
|
|
278
|
+
this.config.HTTPparameter.length > 0) {
|
|
279
|
+
this.oHTTPParamsVars = this.config.HTTPparameter;
|
|
280
|
+
this.log.debug(`use optionally HTTP parameter ${JSON.stringify(this.oHTTPParamsVars)}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//===================================================================================================
|
|
284
|
+
// ebusd interface
|
|
285
|
+
async ebusd_Command() {
|
|
286
|
+
const obj = await this.getStateAsync("cmd");
|
|
287
|
+
if (obj !== undefined && obj != null) {
|
|
288
|
+
const cmds = obj.val?.toString();
|
|
289
|
+
if (cmds != null && cmds !== "") {
|
|
290
|
+
this.log.debug(`got command(s): ${cmds}`);
|
|
291
|
+
this.log.debug(`connect telnet to IP ${this.config.targetIP} port ${this.config.targetTelnetPort}`);
|
|
292
|
+
try {
|
|
293
|
+
//const socket = new net.Socket();
|
|
294
|
+
//const promiseSocket = new PromiseSocket(socket);
|
|
295
|
+
//await promiseSocket.connect(parseInt(this.config.targetTelnetPort), this.config.targetIP);
|
|
296
|
+
//this.log.debug("telnet connected for cmd");
|
|
297
|
+
//promiseSocket.setTimeout(5000);
|
|
298
|
+
const telnet = new TelnetClient_1.default();
|
|
299
|
+
await telnet.connect(this.config.targetIP, this.config.targetTelnetPort);
|
|
300
|
+
const oCmds = cmds.split(",");
|
|
301
|
+
if (oCmds.length > 0) {
|
|
302
|
+
let received = "";
|
|
303
|
+
for (let n = 0; n < oCmds.length; n++) {
|
|
304
|
+
this.log.debug(`send ${oCmds[n]}`);
|
|
305
|
+
//await promiseSocket.write(`${oCmds[n] }\n`);
|
|
306
|
+
await telnet.write(`${oCmds[n]}\n`);
|
|
307
|
+
//const data = await promiseSocket.read();
|
|
308
|
+
const data = await telnet.read();
|
|
309
|
+
if (data.includes("ERR")) {
|
|
310
|
+
this.log.warn(`sent ${oCmds[n]}, received ${data} please check ebusd logs for details!`);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
this.log.debug(`received ${data}`);
|
|
314
|
+
}
|
|
315
|
+
received += data.toString();
|
|
316
|
+
received += ", ";
|
|
317
|
+
}
|
|
318
|
+
//see issue #78: remove CR, LF and last comma
|
|
319
|
+
received = received.replace(/\r?\n|\r/g, "");
|
|
320
|
+
received = received.slice(0, -2);
|
|
321
|
+
//set result to cmdResult
|
|
322
|
+
await this.setState("cmdResult", { ack: true, val: received });
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
this.log.warn(`no commands in list ${cmds} ${JSON.stringify(oCmds)}`);
|
|
326
|
+
}
|
|
327
|
+
await this.setState("cmd", { ack: true, val: "" });
|
|
328
|
+
//promiseSocket.destroy();
|
|
329
|
+
await telnet.disconnect();
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
this.log.error(`exception from tcp socket` + `[${e}]`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
this.log.debug(`object cmd not found ${JSON.stringify(obj)}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async ebusd_find() {
|
|
341
|
+
try {
|
|
342
|
+
//const socket = new net.Socket();
|
|
343
|
+
//const promiseSocket = new PromiseSocket(socket);
|
|
344
|
+
//await promiseSocket.connect(parseInt(this.config.targetTelnetPort), this.config.targetIP);
|
|
345
|
+
//this.log.debug("telnet connected for cmd");
|
|
346
|
+
//promiseSocket.setTimeout(5000);
|
|
347
|
+
const telnet = new TelnetClient_1.default();
|
|
348
|
+
await telnet.connect(this.config.targetIP, this.config.targetTelnetPort);
|
|
349
|
+
//await promiseSocket.write("find -F circuit,name,comment\n");
|
|
350
|
+
await telnet.write("find -F circuit,name,comment\n");
|
|
351
|
+
//const data = await promiseSocket.read();
|
|
352
|
+
const data = await telnet.read();
|
|
353
|
+
if (data.includes("ERR")) {
|
|
354
|
+
this.log.warn(`received error! sent find, received ${data} please check ebusd logs for details!`);
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
this.log.debug(`received ${typeof data} ${data}`);
|
|
358
|
+
}
|
|
359
|
+
let str;
|
|
360
|
+
if (typeof data === "string") {
|
|
361
|
+
str = data;
|
|
362
|
+
}
|
|
363
|
+
else if (data instanceof Uint8Array) {
|
|
364
|
+
str = new TextDecoder().decode(data);
|
|
365
|
+
}
|
|
366
|
+
else if (data instanceof ArrayBuffer) {
|
|
367
|
+
str = new TextDecoder().decode(new Uint8Array(data));
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// fallback: convert to string
|
|
371
|
+
str = String(data);
|
|
372
|
+
}
|
|
373
|
+
//const str = new TextDecoder().decode(data);
|
|
374
|
+
const datas = str.split(/[\r?\n,]+/);
|
|
375
|
+
this.log.info("found entries: " + datas.length);
|
|
376
|
+
for (let i = 0; i < datas.length; i++) {
|
|
377
|
+
//this.log.info(JSON.stringify(datas[i]));
|
|
378
|
+
const names = datas[i].split(",");
|
|
379
|
+
//circuit,name,comment
|
|
380
|
+
await this.UpdateDP(names[0], names[1], names[2]);
|
|
381
|
+
let cmd = `read -f -c ${names[0]} ${names[1]}`;
|
|
382
|
+
this.log.debug(`send cmd ${cmd}`);
|
|
383
|
+
cmd += "\n";
|
|
384
|
+
//await promiseSocket.write(cmd);
|
|
385
|
+
await telnet.write(cmd);
|
|
386
|
+
//const result = await promiseSocket.read();
|
|
387
|
+
const result = await telnet.read();
|
|
388
|
+
this.log.debug(`received ${typeof result} ${result}`);
|
|
389
|
+
}
|
|
390
|
+
//promiseSocket.destroy();
|
|
391
|
+
await telnet.disconnect();
|
|
392
|
+
}
|
|
393
|
+
catch (e) {
|
|
394
|
+
this.log.error(`exception from tcp socket in ebusd_find` + `[${e}]`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
//just call http://192.168.0.123:8889/data
|
|
398
|
+
/*
|
|
399
|
+
http://localhost:8080/data/mc?verbose&since=1483890000&exact
|
|
400
|
+
|
|
401
|
+
since=seconds: limit to messages that have changed since the specified UTC seconds
|
|
402
|
+
poll=prio: set the poll priority of matching message(s) to prio
|
|
403
|
+
exact[=true]: exact search for circuit/message name
|
|
404
|
+
verbose[=true]: include comments and field units
|
|
405
|
+
indexed[=true]: return field indexes instead of names
|
|
406
|
+
numeric[=true]: return numeric values of value list entries
|
|
407
|
+
valuename[=true]: include value and name of value list entries
|
|
408
|
+
full[=true]: include all available attributes
|
|
409
|
+
required[=true]: retrieve the data from the bus if not yet cached
|
|
410
|
+
maxage[=seconds]: retrieve the data from the bus if cached value is older than specified seconds (or not present at all)
|
|
411
|
+
write[=true]: include write messages in addition to read
|
|
412
|
+
raw[=true]: include the raw master/slave symbols as int arrays
|
|
413
|
+
def[=true]: include message/field definition (qq, id, fielddefs)
|
|
414
|
+
define=DEFINITION: (re-)define the message from DEFINITION (in CSV format)
|
|
415
|
+
user=USER: authenticate with USER name
|
|
416
|
+
secret=SECRET: authenticate with user SECRET
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
*/
|
|
420
|
+
async subscribeVars() {
|
|
421
|
+
this.subscribeStates("cmd");
|
|
422
|
+
this.subscribeStates("find");
|
|
423
|
+
await this.setState("cmdResult", { ack: true, val: "" });
|
|
424
|
+
}
|
|
425
|
+
async checkVariables() {
|
|
426
|
+
this.log.debug("init variables ");
|
|
427
|
+
let key;
|
|
428
|
+
let obj;
|
|
429
|
+
key = "cmd";
|
|
430
|
+
obj = {
|
|
431
|
+
type: "state",
|
|
432
|
+
common: {
|
|
433
|
+
name: "ebusd command",
|
|
434
|
+
type: "string",
|
|
435
|
+
role: "text",
|
|
436
|
+
read: true,
|
|
437
|
+
write: true,
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
await this.CreateObject(key, obj);
|
|
441
|
+
key = "cmdResult";
|
|
442
|
+
obj = {
|
|
443
|
+
type: "state",
|
|
444
|
+
common: {
|
|
445
|
+
name: "ebusd command result",
|
|
446
|
+
type: "string",
|
|
447
|
+
role: "text",
|
|
448
|
+
read: true,
|
|
449
|
+
write: false,
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
await this.CreateObject(key, obj);
|
|
453
|
+
key = "find";
|
|
454
|
+
obj = {
|
|
455
|
+
type: "state",
|
|
456
|
+
common: {
|
|
457
|
+
name: "find existing data points",
|
|
458
|
+
type: "boolean",
|
|
459
|
+
role: "button",
|
|
460
|
+
read: false,
|
|
461
|
+
write: true,
|
|
462
|
+
},
|
|
463
|
+
};
|
|
464
|
+
await this.CreateObject(key, obj);
|
|
465
|
+
this.log.debug(`init common variables and ${this.oHistoryVars.length} history DP's`);
|
|
466
|
+
if (this.oHistoryVars.length > 0) {
|
|
467
|
+
if (this.oHistoryVars.length > 4) {
|
|
468
|
+
this.log.warn(`too many history values ${this.oHistoryVars.length} -> maximum is 4`);
|
|
469
|
+
}
|
|
470
|
+
for (let n = 1; n <= this.oHistoryVars.length; n++) {
|
|
471
|
+
if (this.oHistoryVars[n - 1].name.length > 0) {
|
|
472
|
+
const name = `history value ${n} as JSON ${this.oHistoryVars[n - 1].name}`;
|
|
473
|
+
key = `history.value${n}`;
|
|
474
|
+
obj = {
|
|
475
|
+
type: "state",
|
|
476
|
+
common: {
|
|
477
|
+
name: name,
|
|
478
|
+
type: "string",
|
|
479
|
+
role: "value",
|
|
480
|
+
unit: "",
|
|
481
|
+
read: true,
|
|
482
|
+
write: false,
|
|
483
|
+
},
|
|
484
|
+
native: { location: key },
|
|
485
|
+
};
|
|
486
|
+
await this.CreateObject(key, obj);
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
this.log.warn(`ignoring history value ${n} (invalid name)`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
key = "history.date";
|
|
493
|
+
obj = {
|
|
494
|
+
type: "state",
|
|
495
|
+
common: {
|
|
496
|
+
name: "ebus history date / time as JSON",
|
|
497
|
+
type: "string",
|
|
498
|
+
role: "value",
|
|
499
|
+
unit: "",
|
|
500
|
+
read: true,
|
|
501
|
+
write: false,
|
|
502
|
+
},
|
|
503
|
+
native: {
|
|
504
|
+
location: key,
|
|
505
|
+
},
|
|
506
|
+
};
|
|
507
|
+
await this.CreateObject(key, obj);
|
|
508
|
+
}
|
|
509
|
+
key = "history.error";
|
|
510
|
+
obj = {
|
|
511
|
+
type: "state",
|
|
512
|
+
common: {
|
|
513
|
+
name: "ebus error",
|
|
514
|
+
type: "string",
|
|
515
|
+
role: "value",
|
|
516
|
+
unit: "",
|
|
517
|
+
read: true,
|
|
518
|
+
write: false,
|
|
519
|
+
},
|
|
520
|
+
native: { location: key },
|
|
521
|
+
};
|
|
522
|
+
await this.CreateObject(key, obj);
|
|
523
|
+
}
|
|
524
|
+
VersionCheck() {
|
|
525
|
+
if (this.ebusdVersion[0] > 0) {
|
|
526
|
+
if (this.ebusdVersion[0] < this.ebusdMinVersion[0] ||
|
|
527
|
+
(this.ebusdVersion[0] == this.ebusdMinVersion[0] && this.ebusdVersion[1] < this.ebusdMinVersion[1])) {
|
|
528
|
+
this.log.info(`please update ebusd, old version found: ${this.ebusdVersion[0]}.${this.ebusdVersion[1]} supported version is ${this.ebusdMinVersion[0]}.${this.ebusdMinVersion[1]}`);
|
|
529
|
+
}
|
|
530
|
+
if (this.ebusdVersion[0] > this.ebusdMinVersion[0] ||
|
|
531
|
+
(this.ebusdVersion[0] >= this.ebusdMinVersion[0] && this.ebusdVersion[1] > this.ebusdMinVersion[1])) {
|
|
532
|
+
this.log.info(`unsupported ebusd version found (too new): ${this.ebusdVersion[0]}.${this.ebusdVersion[1]} supported version is ${this.ebusdMinVersion[0]}.${this.ebusdMinVersion[1]}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (this.ebusdUpdateVersion[0] > 0 && this.ebusdVersion[0] > 0) {
|
|
536
|
+
if (this.ebusdUpdateVersion[0] > this.ebusdVersion[0] ||
|
|
537
|
+
(this.ebusdUpdateVersion[0] == this.ebusdVersion[0] && this.ebusdUpdateVersion[1] > this.ebusdVersion[1])) {
|
|
538
|
+
this.log.info(`new ebusd version found: ${this.ebusdUpdateVersion[0]}.${this.ebusdUpdateVersion[1]} supported version is ${this.ebusdMinVersion[0]}.${this.ebusdMinVersion[1]}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
//get data via https in json -> this is the main data receiver; telnet just triggers ebusd to read data;
|
|
543
|
+
//https://github.com/john30/ebusd/wiki/3.2.-HTTP-client
|
|
544
|
+
async ebusd_ReceiveData() {
|
|
545
|
+
try {
|
|
546
|
+
let sUrl = `http://${this.config.targetIP}:${this.config.targetHTTPPort}/data`;
|
|
547
|
+
//Erweiterung mit optionalen parametern
|
|
548
|
+
let paramsCnt = 0;
|
|
549
|
+
if (this.oHTTPParamsVars !== undefined && this.oHTTPParamsVars != null && this.oHTTPParamsVars.length > 0) {
|
|
550
|
+
for (let i = 0; i < this.oHTTPParamsVars.length; i++) {
|
|
551
|
+
if (this.oHTTPParamsVars[i].active) {
|
|
552
|
+
if (paramsCnt == 0) {
|
|
553
|
+
sUrl += "?";
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
sUrl += "&";
|
|
557
|
+
}
|
|
558
|
+
sUrl += `${this.oHTTPParamsVars[i].name}=${this.oHTTPParamsVars[i].value}`;
|
|
559
|
+
paramsCnt++;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
this.log.debug(`request data from ${sUrl}`);
|
|
564
|
+
const buffer = await axios_1.default.get(sUrl);
|
|
565
|
+
this.log.debug(`got data ${typeof buffer.data} ${JSON.stringify(buffer.data)}`);
|
|
566
|
+
const flattenObject = (obj, delimiter = ".", prefix = "") => Object.keys(obj).reduce((acc, k) => {
|
|
567
|
+
const pre = prefix.length ? `${prefix}${delimiter}` : "";
|
|
568
|
+
if (typeof obj[k] === "object" && obj[k] !== null && Object.keys(obj[k]).length > 0) {
|
|
569
|
+
Object.assign(acc, flattenObject(obj[k], delimiter, pre + k));
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
acc[pre + k] = obj[k];
|
|
573
|
+
}
|
|
574
|
+
return acc;
|
|
575
|
+
}, {});
|
|
576
|
+
const data = flattenObject(buffer.data, ".");
|
|
577
|
+
//todo: replace any
|
|
578
|
+
const historyvalues = [];
|
|
579
|
+
const historydates = [];
|
|
580
|
+
const oToday = new Date();
|
|
581
|
+
const month = oToday.getMonth() + 1;
|
|
582
|
+
historydates.push({
|
|
583
|
+
date: `${oToday.getDate()}.${month}.${oToday.getFullYear()}`,
|
|
584
|
+
time: `${oToday.getHours()}:${oToday.getMinutes()}:${oToday.getSeconds()}`
|
|
585
|
+
});
|
|
586
|
+
let sError = "none";
|
|
587
|
+
for (let key in data) {
|
|
588
|
+
const subnames = key.split(".");
|
|
589
|
+
//const namelength = subnames.length;
|
|
590
|
+
let value = data[key];
|
|
591
|
+
//this.log.debug("key " + key);
|
|
592
|
+
if (key.includes("[") || key.includes("]")) {
|
|
593
|
+
this.log.debug(`found unsupported chars in ${key}`);
|
|
594
|
+
const start = key.indexOf("[");
|
|
595
|
+
const end = key.lastIndexOf("]");
|
|
596
|
+
if (start > 0 && end > 0) {
|
|
597
|
+
const toReplace = key.slice(start, end + 1);
|
|
598
|
+
key = key.replace(toReplace, "");
|
|
599
|
+
}
|
|
600
|
+
//this.log.warn("new key is " + key);
|
|
601
|
+
}
|
|
602
|
+
//======== version check
|
|
603
|
+
if (key.includes("global.version")) {
|
|
604
|
+
//this.log.info("in version, value " + value);
|
|
605
|
+
const versionInfo = value.split(".");
|
|
606
|
+
if (versionInfo.length > 1) {
|
|
607
|
+
this.log.debug(`installed ebusd version is ${versionInfo[0]}.${versionInfo[1]}`);
|
|
608
|
+
this.ebusdVersion[0] = versionInfo[0];
|
|
609
|
+
this.ebusdVersion[1] = versionInfo[1];
|
|
610
|
+
this.VersionCheck();
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if (key.includes("global.updatecheck")) {
|
|
614
|
+
//revision v21.2 available
|
|
615
|
+
value = value.replace("revision v", "");
|
|
616
|
+
value = value.replace(" available", "");
|
|
617
|
+
const versionInfo = value.split(".");
|
|
618
|
+
if (versionInfo.length > 1) {
|
|
619
|
+
this.log.info(`found ebusd update version ${versionInfo[0]}.${versionInfo[1]}`);
|
|
620
|
+
this.ebusdUpdateVersion[0] = versionInfo[0];
|
|
621
|
+
this.ebusdUpdateVersion[1] = versionInfo[1];
|
|
622
|
+
this.VersionCheck();
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
//============ type check
|
|
626
|
+
let type = this.mapJsTypeToIoBrokerType(value);
|
|
627
|
+
if (this.config.useBoolean4Onoff) {
|
|
628
|
+
if (type == "string" && (value == "on" || value == "off")) {
|
|
629
|
+
this.log.debug(`Key ${key} change to boolean ${value}`);
|
|
630
|
+
//Key mc.messages.Status.fields.1.value could be boolean off
|
|
631
|
+
type = "boolean";
|
|
632
|
+
if (value == "on") {
|
|
633
|
+
value = true;
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
value = false;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
//EVU Sperrzeit
|
|
641
|
+
if (key.includes(".hcmode2.value") || key.includes(".hcmode.value")) {
|
|
642
|
+
if (parseInt(value) === 0) {
|
|
643
|
+
this.log.info(`${key}in hcmode2 with value 0: off`);
|
|
644
|
+
value = "off";
|
|
645
|
+
}
|
|
646
|
+
else if (parseInt(value) === 5) {
|
|
647
|
+
this.log.info(`${key} with value 5: EVU Sperrzeit`);
|
|
648
|
+
value = "EVU Sperrzeit";
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
this.log.debug(`in hcmode2, value ${value}`);
|
|
652
|
+
}
|
|
653
|
+
type = this.mapJsTypeToIoBrokerType(value);
|
|
654
|
+
}
|
|
655
|
+
//lastup umrechnen
|
|
656
|
+
if (key.includes(".lastup")) {
|
|
657
|
+
if (parseInt(value) > 0) {
|
|
658
|
+
//this.log.debug('Key : ' + key + ', Value : ' + newData[key] + " name " + name);
|
|
659
|
+
//umrechnen...
|
|
660
|
+
const oDate = new Date(value * 1000);
|
|
661
|
+
//const nDate = oDate.getDate();
|
|
662
|
+
//const nMonth = oDate.getMonth() + 1;
|
|
663
|
+
//const nYear = oDate.getFullYear();
|
|
664
|
+
//const nHours = oDate.getHours();
|
|
665
|
+
//const nMinutes = oDate.getMinutes();
|
|
666
|
+
//const nSeconds = oDate.getSeconds();
|
|
667
|
+
const sDate = oDate.toLocaleString();
|
|
668
|
+
value = sDate;
|
|
669
|
+
type = this.mapJsTypeToIoBrokerType(value);
|
|
670
|
+
const oToday = new Date();
|
|
671
|
+
let bSkip = false;
|
|
672
|
+
if (subnames[0].includes("scan") ||
|
|
673
|
+
subnames[0].includes("Scan") ||
|
|
674
|
+
subnames[0].includes("ehp") ||
|
|
675
|
+
(subnames.length > 2 && subnames[2].includes("currenterror")) ||
|
|
676
|
+
this.config.DisableTimeUpdateCheck) {
|
|
677
|
+
bSkip = true;
|
|
678
|
+
}
|
|
679
|
+
//this.log.debug("_______________size " + temp);
|
|
680
|
+
if (subnames.length > 2 && subnames[2].includes("Timer")) {
|
|
681
|
+
bSkip = true;
|
|
682
|
+
}
|
|
683
|
+
if (!bSkip && Math.abs(oDate.getTime() - oToday.getTime()) > 1 * 60 * 60 * 1000) {
|
|
684
|
+
const sError1 = `no update since ${sDate} ${key} `;
|
|
685
|
+
if (sError.includes("none")) {
|
|
686
|
+
sError = `ebus: ${sError1}`;
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
sError += sError1;
|
|
690
|
+
}
|
|
691
|
+
this.log.warn(sError1);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
//add and update data
|
|
696
|
+
await this.AddObject(key, type);
|
|
697
|
+
await this.UpdateObject(key, value);
|
|
698
|
+
//push to history
|
|
699
|
+
for (let ii = 0; ii < this.oHistoryVars.length; ii++) {
|
|
700
|
+
//this.log.debug("check " + key + "==" + oHistoryVars[ii].name);
|
|
701
|
+
// check uih.messages.YieldThisYear.fields.energy_1.value==ActualEnvironmentPower
|
|
702
|
+
/*
|
|
703
|
+
ehp.messages.ActualEnvironmentPower.fields.value.value
|
|
704
|
+
ehp.messages.YieldTotal.fields.value.value
|
|
705
|
+
ehp.messages.SourceTempInput.fields.temp.value
|
|
706
|
+
ehp.messages.SourceTempOutput.fields.temp.value
|
|
707
|
+
ehp.messages.HwcTemp.fields.temp.value
|
|
708
|
+
*/
|
|
709
|
+
if (key === this.oHistoryVars[ii].name) {
|
|
710
|
+
const sTemp = '{"' + key + '": "' + value + '"}';
|
|
711
|
+
this.log.debug("push history " + sTemp);
|
|
712
|
+
historyvalues[ii] = [];
|
|
713
|
+
historyvalues[ii].push(JSON.parse(sTemp));
|
|
714
|
+
//this.log.debug(JSON.stringify(historyvalues));
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
await this.setState("history.error", { ack: true, val: sError });
|
|
719
|
+
//this.log.debug(JSON.stringify(historyvalues));
|
|
720
|
+
this.log.debug("all http done");
|
|
721
|
+
if (historyvalues.length > 0 && historydates.length > 0) {
|
|
722
|
+
if (this.config.History4Vis2) {
|
|
723
|
+
await this.UpdateHistory_Vis2(historyvalues, historydates);
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
await this.UpdateHistory(historyvalues, historydates);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
catch (e) {
|
|
731
|
+
this.log.error(`exception in ebusd_ReceiveData [${e}]`);
|
|
732
|
+
await this.setState("history.error", { ack: true, val: "exception in receive" });
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
mapJsTypeToIoBrokerType(value) {
|
|
736
|
+
if (Array.isArray(value)) {
|
|
737
|
+
return "array";
|
|
738
|
+
}
|
|
739
|
+
switch (typeof value) {
|
|
740
|
+
case "string": return "string";
|
|
741
|
+
case "number": return "number";
|
|
742
|
+
case "boolean": return "boolean";
|
|
743
|
+
case "object": return value === null ? "mixed" : "object";
|
|
744
|
+
default: return "mixed";
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
async UpdateHistory_Vis2(values, dates) {
|
|
748
|
+
this.log.debug(`start history 4 VIS-2 ${JSON.stringify(values)} ${JSON.stringify(dates)}`);
|
|
749
|
+
//not used anymore
|
|
750
|
+
await this.setState("history.date", { ack: true, val: "" });
|
|
751
|
+
for (let s = 0; s < values.length; s++) {
|
|
752
|
+
const values1 = values[s];
|
|
753
|
+
//this.log.debug(s + " " + JSON.stringify(values1));
|
|
754
|
+
let val2Write = [];
|
|
755
|
+
const ctr = s + 1;
|
|
756
|
+
const obj = await this.getStateAsync(`history.value${ctr}`);
|
|
757
|
+
if (obj === null || obj === undefined) {
|
|
758
|
+
this.log.warn(`history.value${ctr} not found, creating DP ${JSON.stringify(obj)}`);
|
|
759
|
+
await this.setState(`history.value${ctr}`, { ack: true, val: "[]" });
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
if (obj.val != null && obj.val != "" && typeof obj.val === "string") {
|
|
763
|
+
val2Write = JSON.parse(obj.val);
|
|
764
|
+
this.log.debug(`history.value${ctr} got ${JSON.stringify(val2Write)}`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
for (let ss = 0; ss < values1.length; ss++) {
|
|
768
|
+
const values2 = values1[ss];
|
|
769
|
+
//this.log.debug(ss + " " + JSON.stringify(values2));
|
|
770
|
+
let d = 0;
|
|
771
|
+
for (const n in values2) {
|
|
772
|
+
const val = values2[n];
|
|
773
|
+
const time = dates[d].time;
|
|
774
|
+
const date = dates[d].date;
|
|
775
|
+
d++;
|
|
776
|
+
const times = time.split(":");
|
|
777
|
+
const datesl = date.split(".");
|
|
778
|
+
const day = parseInt(datesl[0]);
|
|
779
|
+
const month = parseInt(datesl[1]) - 1;
|
|
780
|
+
const year = parseInt(datesl[2]);
|
|
781
|
+
const hours = parseInt(times[0]);
|
|
782
|
+
const minutes = parseInt(times[1]);
|
|
783
|
+
const oDate = new Date(year, month, day, hours, minutes, 0, 0);
|
|
784
|
+
this.log.debug(`${n} ${val} ${oDate.toLocaleString()}`);
|
|
785
|
+
val2Write.push([oDate, val]);
|
|
786
|
+
if (val2Write.length > 200) {
|
|
787
|
+
for (let i = val2Write.length; i > 200; i--) {
|
|
788
|
+
//this.log.debug("delete");
|
|
789
|
+
val2Write.shift();
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
await this.setState(`history.value${ctr}`, { ack: true, val: JSON.stringify(val2Write) });
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
async UpdateHistory(values, dates) {
|
|
798
|
+
if (this.oHistoryVars.length > 0) {
|
|
799
|
+
//prüfen ob alle json gleich lang sind
|
|
800
|
+
let NoOfDates = -1;
|
|
801
|
+
const obj = await this.getStateAsync("history.date");
|
|
802
|
+
if (obj !== undefined && obj != null) {
|
|
803
|
+
try {
|
|
804
|
+
let oEbusDates = [];
|
|
805
|
+
//this.log.debug("before " + obj.val);
|
|
806
|
+
if (obj.val != null && obj.val != "" && typeof obj.val === "string") {
|
|
807
|
+
oEbusDates = JSON.parse(obj.val);
|
|
808
|
+
}
|
|
809
|
+
//this.log.debug("after parse " + JSON.stringify(oEbusDates));
|
|
810
|
+
oEbusDates.push(dates);
|
|
811
|
+
//this.log.debug("after push " + JSON.stringify(oEbusDates));
|
|
812
|
+
//limit length of object...
|
|
813
|
+
if (oEbusDates.length > 200) {
|
|
814
|
+
for (let i = oEbusDates.length; i > 200; i--) {
|
|
815
|
+
//this.log.debug("delete");
|
|
816
|
+
oEbusDates.shift();
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
NoOfDates = oEbusDates.length;
|
|
820
|
+
await this.setState("history.date", { ack: true, val: JSON.stringify(oEbusDates) });
|
|
821
|
+
}
|
|
822
|
+
catch (e) {
|
|
823
|
+
this.log.error(`exception in UpdateHistory part1 [${e}]`);
|
|
824
|
+
await this.setState("history.date", { ack: true, val: "[]" });
|
|
825
|
+
NoOfDates = 0;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
else {
|
|
829
|
+
this.log.warn("history.date not found, creating DP ");
|
|
830
|
+
await this.setState("history.date", { ack: true, val: "[]" });
|
|
831
|
+
NoOfDates = 0;
|
|
832
|
+
}
|
|
833
|
+
if (this.oHistoryVars.length > 0) {
|
|
834
|
+
for (let ctr = 1; ctr <= this.oHistoryVars.length; ctr++) {
|
|
835
|
+
if (this.oHistoryVars[ctr - 1].name.length > 0) {
|
|
836
|
+
const ctrOkay = await this.UpdateHistoryValues(values, ctr, NoOfDates);
|
|
837
|
+
if (!ctrOkay) {
|
|
838
|
+
await this.setState("history.date", { ack: true, val: "[]" });
|
|
839
|
+
NoOfDates = 0;
|
|
840
|
+
this.log.warn("reset history date too");
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
this.log.debug(`ignoring history value ${ctr}`);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
this.log.info("all history done");
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
this.log.debug("nothing to do for history");
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
async UpdateHistoryValues(values, ctr, curDateCtr) {
|
|
855
|
+
let bRet = true;
|
|
856
|
+
const obj = await this.getStateAsync(`history.value${ctr}`);
|
|
857
|
+
if (obj !== undefined && obj != null) {
|
|
858
|
+
try {
|
|
859
|
+
let oEbusValues = [];
|
|
860
|
+
if (obj !== null) {
|
|
861
|
+
//this.log.debug("before " + obj.val);
|
|
862
|
+
if (obj.val != null && obj.val != "" && typeof obj.val === "string") {
|
|
863
|
+
oEbusValues = JSON.parse(obj.val);
|
|
864
|
+
}
|
|
865
|
+
//this.log.debug("after parse " + JSON.stringify(oEbusValues));
|
|
866
|
+
//this.log.debug("after parse cnt " + oEbusValues.length);
|
|
867
|
+
}
|
|
868
|
+
//this.log.debug("values " + ctr + ": " + JSON.stringify(values[ctr-1]));
|
|
869
|
+
oEbusValues.push(values[ctr - 1]);
|
|
870
|
+
//this.log.debug("after push " + JSON.stringify(oEbusValues));
|
|
871
|
+
//this.log.debug("after push cnt " + oEbusValues.length);
|
|
872
|
+
//limit length of object...
|
|
873
|
+
if (oEbusValues.length > 200) {
|
|
874
|
+
for (let i = oEbusValues.length; i > 200; i--) {
|
|
875
|
+
//this.log.debug("delete");
|
|
876
|
+
oEbusValues.shift();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
const key = `history.value${ctr}`;
|
|
880
|
+
this.log.debug(`update history ${key}`);
|
|
881
|
+
if (curDateCtr != oEbusValues.length) {
|
|
882
|
+
bRet = false;
|
|
883
|
+
await this.setState(`history.value${ctr}`, { ack: true, val: "[]" });
|
|
884
|
+
this.log.warn(`reset history ${key} because number of values different to date values`);
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
await this.setState(key, { ack: true, val: JSON.stringify(oEbusValues) });
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
catch (e) {
|
|
891
|
+
this.log.error(`exception in UpdateHistory part2 [${e}]`);
|
|
892
|
+
await this.setState(`history.value${ctr}`, { ack: true, val: "[]" });
|
|
893
|
+
if (curDateCtr > 0) {
|
|
894
|
+
bRet = false;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
this.log.warn(`history.value${ctr} not found, creating DP ${JSON.stringify(obj)}`);
|
|
900
|
+
await this.setState(`history.value${ctr}`, { ack: true, val: "[]" });
|
|
901
|
+
if (curDateCtr > 0) {
|
|
902
|
+
bRet = false;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return bRet;
|
|
906
|
+
}
|
|
907
|
+
//this function just triggers ebusd to read data; result will not be parsed; we just take the values from http result
|
|
908
|
+
//here we need a loop over all configured read data in admin-page
|
|
909
|
+
async ebusd_ReadValues() {
|
|
910
|
+
if (this.oPolledVars.length > 0) {
|
|
911
|
+
this.log.debug(`to poll ctr ${this.oPolledVars.length} vals: ${JSON.stringify(this.oPolledVars)}`);
|
|
912
|
+
try {
|
|
913
|
+
//const socket = new net.Socket();
|
|
914
|
+
//const promiseSocket = new PromiseSocket(socket);
|
|
915
|
+
//await promiseSocket.connect(parseInt(this.config.targetTelnetPort), this.config.targetIP);
|
|
916
|
+
//this.log.debug(`telnet connected to poll variables ${ this.config.targetIP } port ${ this.config.targetTelnetPort}`);
|
|
917
|
+
//promiseSocket.setTimeout(5000);
|
|
918
|
+
const telnet = new TelnetClient_1.default();
|
|
919
|
+
await telnet.connect(this.config.targetIP, this.config.targetTelnetPort);
|
|
920
|
+
let retries = 0;
|
|
921
|
+
for (let nCtr = 0; nCtr < this.oPolledVars.length; nCtr++) {
|
|
922
|
+
let circuit = "";
|
|
923
|
+
let params = "";
|
|
924
|
+
if (this.oPolledVars[nCtr].circuit != null && this.oPolledVars[nCtr].circuit.length > 0) {
|
|
925
|
+
circuit = `-c ${this.oPolledVars[nCtr].circuit} `;
|
|
926
|
+
}
|
|
927
|
+
if (this.oPolledVars[nCtr].parameter != null && this.oPolledVars[nCtr].parameter.length > 0) {
|
|
928
|
+
params = ` ${this.oPolledVars[nCtr].parameter}`;
|
|
929
|
+
}
|
|
930
|
+
let cmd = `read -f ${circuit}${this.oPolledVars[nCtr].name}${params}`;
|
|
931
|
+
this.log.debug(`send cmd ${cmd}`);
|
|
932
|
+
cmd += "\n";
|
|
933
|
+
let data = null;
|
|
934
|
+
try {
|
|
935
|
+
//await promiseSocket.write(cmd);
|
|
936
|
+
await telnet.write(cmd);
|
|
937
|
+
//const data = await promiseSocket.read();
|
|
938
|
+
data = await telnet.read();
|
|
939
|
+
}
|
|
940
|
+
catch (e) {
|
|
941
|
+
this.log.warn(`exception from tcp socket write/read in ebusd_ReadValues for cmd ${cmd}` + `[${e}]` + ` -> retry`);
|
|
942
|
+
//todo: retry nur für timeout und arbitration lost? 2025-11-01
|
|
943
|
+
retries++;
|
|
944
|
+
if (retries > this.config.maxretries) {
|
|
945
|
+
this.log.error(`max retries, skip cmd ${cmd}`);
|
|
946
|
+
}
|
|
947
|
+
else {
|
|
948
|
+
nCtr--; //counter wieder zurücksetzen
|
|
949
|
+
this.log.debug("retry to send data ");
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
if (data !== null) {
|
|
953
|
+
this.log.debug(`received ${data} for ${JSON.stringify(this.oPolledVars[nCtr])}`);
|
|
954
|
+
//todo: parse data and set DP's 2025-11-01
|
|
955
|
+
}
|
|
956
|
+
//received ERR: arbitration lost for YieldThisYear
|
|
957
|
+
//if (data !== null && data.includes("ERR")) {
|
|
958
|
+
// this.log.warn(`sent ${ cmd }, received ${ data } for ${ JSON.stringify(oPolledVars[nCtr]) } please check ebusd logs for details!`);
|
|
959
|
+
//
|
|
960
|
+
// /*
|
|
961
|
+
// * sent read -f YieldLastYear, received ERR: arbitration lost for {"circuit":"","name":"YieldLastYear","parameter":""}
|
|
962
|
+
// * */
|
|
963
|
+
// if (data.includes("arbitration lost")) {
|
|
964
|
+
// retries++;
|
|
965
|
+
// if (retries > this.config.maxretries) {
|
|
966
|
+
// this.log.error(`max retries, skip cmd ${ cmd}`);
|
|
967
|
+
// retries = 0;
|
|
968
|
+
// } else {
|
|
969
|
+
// nCtr--;
|
|
970
|
+
// this.log.debug("retry to send data ");
|
|
971
|
+
// }
|
|
972
|
+
// }
|
|
973
|
+
//} else {
|
|
974
|
+
//
|
|
975
|
+
// //muss wieder debug werden 2025-11-01 todo
|
|
976
|
+
// this.log.info(`received ${ data } for ${ JSON.stringify(oPolledVars[nCtr])}`);
|
|
977
|
+
//}
|
|
978
|
+
}
|
|
979
|
+
//promiseSocket.destroy();
|
|
980
|
+
await telnet.disconnect();
|
|
981
|
+
this.log.debug("telnet disonnected");
|
|
982
|
+
}
|
|
983
|
+
catch (e) {
|
|
984
|
+
this.log.error(`exception from tcp socket in ebusd_ReadValues ` + `[${e}]`);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
this.log.debug("nothing to poll; skip telnet");
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
async FindParams(obj) {
|
|
992
|
+
//todo muss wieder debug werden 2025-11-01
|
|
993
|
+
this.log.debug(`FindParams ${JSON.stringify(obj)}`);
|
|
994
|
+
const list = [];
|
|
995
|
+
try {
|
|
996
|
+
//FindParams {"command":"findParams","message":{"circuit":"cc"},"from":"system.this.admin.0","callback":{"message":{"circuit":"cc"},"id":90,"ack":false,"time":1733690088670},"_id":39690903}
|
|
997
|
+
if (obj.message !== null && obj.message.circuit !== null) {
|
|
998
|
+
const circuit = obj.message.circuit;
|
|
999
|
+
//const socket = new net.Socket();
|
|
1000
|
+
//const promiseSocket = new PromiseSocket(socket);
|
|
1001
|
+
//await promiseSocket.connect(parseInt(this.config.targetTelnetPort), this.config.targetIP);
|
|
1002
|
+
//this.log.debug("telnet connected for cmd");
|
|
1003
|
+
//promiseSocket.setTimeout(5000);
|
|
1004
|
+
const telnet = new TelnetClient_1.default();
|
|
1005
|
+
await telnet.connect(this.config.targetIP, this.config.targetTelnetPort);
|
|
1006
|
+
const cmd = `find -c ${circuit} -F circuit,name\n`;
|
|
1007
|
+
//await promiseSocket.write(cmd);
|
|
1008
|
+
this.log.debug(`send cmd ${cmd}`);
|
|
1009
|
+
await telnet.write(cmd);
|
|
1010
|
+
this.log.debug(`sent, wait for data...`);
|
|
1011
|
+
//const data = await promiseSocket.read();
|
|
1012
|
+
const data = await telnet.read();
|
|
1013
|
+
this.log.info(`data received: ` + data);
|
|
1014
|
+
if (data.includes("ERR")) {
|
|
1015
|
+
this.log.warn(`received error! sent find, received ${data} please check ebusd logs for details! ${cmd}`);
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
this.log.info(`received ${typeof data} ${data} ${+cmd}`);
|
|
1019
|
+
}
|
|
1020
|
+
/*
|
|
1021
|
+
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
|
|
1022
|
+
*/
|
|
1023
|
+
//const str = new TextDecoder().decode(data);
|
|
1024
|
+
let str;
|
|
1025
|
+
if (typeof data === "string") {
|
|
1026
|
+
str = data;
|
|
1027
|
+
}
|
|
1028
|
+
else if (data instanceof Uint8Array) {
|
|
1029
|
+
str = new TextDecoder().decode(data);
|
|
1030
|
+
}
|
|
1031
|
+
else if (data instanceof ArrayBuffer) {
|
|
1032
|
+
str = new TextDecoder().decode(new Uint8Array(data));
|
|
1033
|
+
}
|
|
1034
|
+
else {
|
|
1035
|
+
// fallback: convert to string
|
|
1036
|
+
str = String(data);
|
|
1037
|
+
}
|
|
1038
|
+
const datas = str.split(/[\r?\n,]+/);
|
|
1039
|
+
this.log.info("found entries: " + datas.length);
|
|
1040
|
+
for (let i = 0; i < datas.length; i++) {
|
|
1041
|
+
//this.log.info(JSON.stringify(datas[i]));
|
|
1042
|
+
const names = datas[i].split(",");
|
|
1043
|
+
//doppelte und leere herausfiltern
|
|
1044
|
+
let add = true;
|
|
1045
|
+
if (names[0] == "" || names[1] == "") {
|
|
1046
|
+
add = false;
|
|
1047
|
+
}
|
|
1048
|
+
else {
|
|
1049
|
+
for (let n = 0; n < list.length; n++) {
|
|
1050
|
+
if (list[n].circuit == names[0] && list[n].name == names[1]) {
|
|
1051
|
+
add = false;
|
|
1052
|
+
//already in list
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (add) {
|
|
1057
|
+
const entry = {
|
|
1058
|
+
active: false,
|
|
1059
|
+
circuit: names[0],
|
|
1060
|
+
name: names[1],
|
|
1061
|
+
};
|
|
1062
|
+
list.push(entry);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
await telnet.disconnect();
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
this.log.error("no circuit defined where to look for parameter, check values!");
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
catch (e) {
|
|
1072
|
+
this.log.error(`exception in FindParams ` + `[${e}]`);
|
|
1073
|
+
}
|
|
1074
|
+
this.log.info(`parameters ${JSON.stringify(list)}`);
|
|
1075
|
+
this.sendTo(obj.from, obj.command, list, obj.callback);
|
|
1076
|
+
}
|
|
1077
|
+
/*
|
|
1078
|
+
async CallExternalScript(script, msg) {
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
try {
|
|
1083
|
+
if (os.platform() == "linux") {
|
|
1084
|
+
//const cmd = spawn("ls", ["-la"]);
|
|
1085
|
+
|
|
1086
|
+
this.log.info("we are on linux ");
|
|
1087
|
+
|
|
1088
|
+
const folderName = path.join(__dirname, '..', 'iobroker.ebus', 'lib', 'scripts');
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
if (!fs.existsSync(folderName)) {
|
|
1092
|
+
|
|
1093
|
+
this.log.info("folder doesnt exists " + folderName);
|
|
1094
|
+
|
|
1095
|
+
this.sendTo(msg.from, msg.command, { error: 'script folder not found ' + folderName }, msg.callback);
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
this.log.info("folder exists " + folderName);
|
|
1101
|
+
|
|
1102
|
+
const scriptfile = path.join(folderName, script);
|
|
1103
|
+
const stats = await fs.statSync(scriptfile);
|
|
1104
|
+
|
|
1105
|
+
if (!stats.isFile()) {
|
|
1106
|
+
|
|
1107
|
+
this.log.info("file doenst exists " + scriptfile);
|
|
1108
|
+
|
|
1109
|
+
this.sendTo(msg.from, msg.command, { error: 'script not found ' + scriptfile }, msg.callback);
|
|
1110
|
+
|
|
1111
|
+
return;
|
|
1112
|
+
|
|
1113
|
+
} else {
|
|
1114
|
+
|
|
1115
|
+
this.log.info("file exists " + scriptfile);
|
|
1116
|
+
|
|
1117
|
+
const cmd = spawn(scriptfile, [""]);
|
|
1118
|
+
|
|
1119
|
+
cmd.stdout.on("data", data => {
|
|
1120
|
+
this.log.error(`stdout: ${data}`);
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
cmd.stderr.on("data", data => {
|
|
1124
|
+
this.log.error(`stderr: ${data}`);
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
cmd.on('error', (error) => {
|
|
1128
|
+
this.log.error(`error: ${error.message}`);
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
cmd.on("close", code => {
|
|
1132
|
+
this.log.error(`child process exited with code ${code}`);
|
|
1133
|
+
this.sendTo(msg.from, msg.command, {
|
|
1134
|
+
info: 'success '
|
|
1135
|
+
|
|
1136
|
+
}, msg.callback);
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
} else {
|
|
1141
|
+
this.sendTo(msg.from, msg.command, { error: 'possible only on Linux systems, this system is ' + os.platform() }, msg.callback);
|
|
1142
|
+
}
|
|
1143
|
+
} catch (e) {
|
|
1144
|
+
this.log.error("exception in CallExternalScript " + "[" + e + "]");
|
|
1145
|
+
|
|
1146
|
+
this.sendTo(msg.from, msg.command, { error: 'error ' + e }, msg.callback);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
/*
|
|
1151
|
+
try {
|
|
1152
|
+
if (os.platform() == "linux") {
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
let cmd = "\\lib\\scripts\\" + script;
|
|
1156
|
+
|
|
1157
|
+
exec(cmd, (error, stdout, stderr) => {
|
|
1158
|
+
if (error) {
|
|
1159
|
+
this.log.error(`error: ${error.message}`);
|
|
1160
|
+
this.sendTo(msg.from, msg.command, { error: 'error ' + error.message }, msg.callback);
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
if (stderr) {
|
|
1164
|
+
this.log.error(`stderr: ${stderr}`);
|
|
1165
|
+
this.sendTo(msg.from, msg.command, { error: 'error ' + stderr }, msg.callback);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
this.log.info(`stdout: ${stdout}`);
|
|
1169
|
+
this.sendTo(msg.from, msg.command, {
|
|
1170
|
+
info: 'success '
|
|
1171
|
+
|
|
1172
|
+
}, msg.callback);
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
this.sendTo(msg.from, msg.command, { error: 'possible only on Linux systems, this system is ' + os.platform() }, msg.callback);
|
|
1177
|
+
}
|
|
1178
|
+
} catch (e) {
|
|
1179
|
+
this.log.error("exception in CallExternalScript " + "[" + e + "]");
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
*/
|
|
1183
|
+
//}
|
|
1184
|
+
async CheckVersion(version, msg) {
|
|
1185
|
+
if (version == "installable") {
|
|
1186
|
+
let vers = "unknown";
|
|
1187
|
+
if (this.ebusdUpdateVersion[0] > 0 && this.ebusdVersion[0] > 0) {
|
|
1188
|
+
vers = `${this.ebusdUpdateVersion[0]}.${this.ebusdUpdateVersion[1]}`;
|
|
1189
|
+
}
|
|
1190
|
+
else {
|
|
1191
|
+
vers = await this.GetLatestVersionGithub();
|
|
1192
|
+
}
|
|
1193
|
+
this.sendTo(msg.from, msg.command, vers, msg.callback);
|
|
1194
|
+
}
|
|
1195
|
+
else if (version == "current") {
|
|
1196
|
+
this.sendTo(msg.from, msg.command, `${this.ebusdVersion[0]}.${this.ebusdVersion[1]}`, msg.callback);
|
|
1197
|
+
}
|
|
1198
|
+
else if (version == "supported") {
|
|
1199
|
+
this.sendTo(msg.from, msg.command, `${this.ebusdMinVersion[0]}.${this.ebusdMinVersion[1]}`, msg.callback);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
async GetLatestVersionGithub() {
|
|
1203
|
+
let latestVersion = "unknown";
|
|
1204
|
+
try {
|
|
1205
|
+
const url = "https://api.github.com/repos/john30/ebusd/releases/latest";
|
|
1206
|
+
this.log.debug(`call ${url}`);
|
|
1207
|
+
const result = await axios_1.default.get(url, { timeout: 5000 });
|
|
1208
|
+
if (result != null && result.status == 200 && result.data != null) {
|
|
1209
|
+
this.log.info(`installable version on github ${JSON.stringify(result.data.tag_name)} (${JSON.stringify(result.data.name)})`);
|
|
1210
|
+
latestVersion =
|
|
1211
|
+
"on github " + JSON.stringify(result.data.tag_name) + "(" + JSON.stringify(result.data.name) + ")";
|
|
1212
|
+
}
|
|
1213
|
+
else {
|
|
1214
|
+
latestVersion = "unknown / no result";
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
catch (e) {
|
|
1218
|
+
this.log.error(`exception in GetLatestVersionGithub [${e}]`);
|
|
1219
|
+
latestVersion = "unknown / error";
|
|
1220
|
+
}
|
|
1221
|
+
return latestVersion;
|
|
1222
|
+
}
|
|
1223
|
+
//==========================================================
|
|
1224
|
+
// replace by general functions from base.ts
|
|
1225
|
+
async CreateObject(key, obj) {
|
|
1226
|
+
const obj_new = await this.getObjectAsync(key);
|
|
1227
|
+
//adapter.log.warn("got object " + JSON.stringify(obj_new));
|
|
1228
|
+
if (obj_new != null) {
|
|
1229
|
+
if ((obj_new.common.role != obj.common.role ||
|
|
1230
|
+
obj_new.common.type != obj.common.type ||
|
|
1231
|
+
(obj_new.common.unit != obj.common.unit && obj.common.unit != null) ||
|
|
1232
|
+
obj_new.common.read != obj.common.read ||
|
|
1233
|
+
obj_new.common.write != obj.common.write ||
|
|
1234
|
+
obj_new.common.name != obj.common.name) &&
|
|
1235
|
+
obj.type === "state") {
|
|
1236
|
+
this.log.warn(`change object ${JSON.stringify(obj)} ${JSON.stringify(obj_new)}`);
|
|
1237
|
+
await this.extendObject(key, {
|
|
1238
|
+
common: {
|
|
1239
|
+
name: obj.common.name,
|
|
1240
|
+
role: obj.common.role,
|
|
1241
|
+
type: obj.common.type,
|
|
1242
|
+
unit: obj.common.unit,
|
|
1243
|
+
read: obj.common.read,
|
|
1244
|
+
write: obj.common.write,
|
|
1245
|
+
},
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
else {
|
|
1250
|
+
await this.setObjectNotExistsAsync(key, obj);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
//circuit,name,comment
|
|
1254
|
+
async UpdateDP(circuit, name, comment) {
|
|
1255
|
+
const key = `${circuit}.messages.${name}`;
|
|
1256
|
+
this.log.debug(`update check for ${key}`);
|
|
1257
|
+
// ehp.messages.Injection
|
|
1258
|
+
//ebus.0.ehp.messages.Injection
|
|
1259
|
+
const obj = await this.getObjectAsync(key);
|
|
1260
|
+
this.log.debug(`update check got ${JSON.stringify(obj)}`);
|
|
1261
|
+
//update check got null
|
|
1262
|
+
if (obj != null) {
|
|
1263
|
+
if (obj.common.name != comment) {
|
|
1264
|
+
this.log.debug(`update ${key} ${comment}`);
|
|
1265
|
+
await this.extendObject(key, {
|
|
1266
|
+
common: {
|
|
1267
|
+
name: comment,
|
|
1268
|
+
read: true,
|
|
1269
|
+
write: false,
|
|
1270
|
+
},
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
else {
|
|
1275
|
+
await this.setObjectNotExistsAsync(key, {
|
|
1276
|
+
type: "channel",
|
|
1277
|
+
common: {
|
|
1278
|
+
name: comment
|
|
1279
|
+
//read: true,
|
|
1280
|
+
//write: false,
|
|
1281
|
+
},
|
|
1282
|
+
native: {}
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
async AddObject(key, types) {
|
|
1287
|
+
try {
|
|
1288
|
+
const obj = await this.getObjectAsync(key);
|
|
1289
|
+
if (obj != null) {
|
|
1290
|
+
if (obj.common.role != "value" || obj.common.type != types) {
|
|
1291
|
+
this.log.debug(` !!! need to extend for ${key}`);
|
|
1292
|
+
await this.extendObject(key, {
|
|
1293
|
+
common: {
|
|
1294
|
+
type: types,
|
|
1295
|
+
role: "value",
|
|
1296
|
+
},
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
this.log.warn(` !!! does not exist, creating now ${key}`);
|
|
1302
|
+
await this.setObjectNotExistsAsync(key, {
|
|
1303
|
+
type: "state",
|
|
1304
|
+
common: {
|
|
1305
|
+
name: "data",
|
|
1306
|
+
type: types,
|
|
1307
|
+
role: "value",
|
|
1308
|
+
unit: "",
|
|
1309
|
+
read: true,
|
|
1310
|
+
write: false,
|
|
1311
|
+
},
|
|
1312
|
+
native: {
|
|
1313
|
+
location: key,
|
|
1314
|
+
},
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
catch (e) {
|
|
1319
|
+
this.log.error(`exception in AddObject ` + `[${e}]`);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
async UpdateObject(key, value) {
|
|
1323
|
+
try {
|
|
1324
|
+
if (value === undefined) {
|
|
1325
|
+
this.log.warn(`updateObject: not updated ${key} value: ${value} ${typeof value}`);
|
|
1326
|
+
}
|
|
1327
|
+
else if (value == null) {
|
|
1328
|
+
this.log.debug(`updateObject: update to null ${key} value: ${value}`);
|
|
1329
|
+
await this.setState(key, { ack: true, val: null });
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
//this.log.debug("updateObject " + key + " : " + value);
|
|
1333
|
+
await this.setState(key, { ack: true, val: value });
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
catch (e) {
|
|
1337
|
+
this.log.error(`exception in UpdateObject ` + `[${e}]`);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
exports.ebus = ebus;
|
|
1342
|
+
if (require.main !== module) {
|
|
1343
|
+
// Exportiere den Konstruktor im Kompaktmodus
|
|
1344
|
+
module.exports = (options) => new ebus(options);
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
// Starte die Instanz direkt
|
|
1348
|
+
(() => new ebus())();
|
|
1349
|
+
}
|
|
1350
|
+
//# sourceMappingURL=main.js.map
|