iobroker.vds2465-server
Version:
Empfänger von VdS2465-Meldungen
1,025 lines (991 loc) • 42.2 kB
JavaScript
'use strict';
/*
* Created with @iobroker/create-adapter v2.0.2
*/
// The adapter-core module gives you access to the core ioBroker functions
// you need to create an adapter
const utils = require('@iobroker/adapter-core');
const vds = require('./lib/vds2465server.js');
const vdsmeldungen = require('./lib/vds2465.json');
// Load your modules here, e.g.:
const net = require('net');
let servertcp; // Server instance TCP
let isChangeConnect = false;
const queueConnect = [];
const devicesConnected = [];
class Vds2465Server extends utils.Adapter {
/**
* @param {Partial<utils.AdapterOptions>} [options] Adapteroptionen
*/
constructor(options) {
super({
...options,
name: 'vds2465-server',
});
this.on('ready', this.onReady.bind(this));
this.on('stateChange', this.onStateChange.bind(this));
// this.on('objectChange', this.onObjectChange.bind(this));
this.on('message', this.onMessage.bind(this));
this.on('unload', this.onUnload.bind(this));
//this.sendCommand.bind(this);
}
/**
* Is called when databases are connected and adapter received configuration.
*/
async onReady() {
// Initialize your adapter here
// Reset the connection indicator during startup
this.setState('info.connection', false, true);
// The adapters config (in the instance object everything under the attribute "native") is accessible via
let channel;
try {
for (let i = 0; i < this.config.devices.length; i++) {
// @ts-expect-error identnr
const id = this.config.devices[i].identnr.toString();
await this.grundstrukturAnlegen(id);
}
for (let i = 0; i < this.config.relais.length; i++) {
// @ts-expect-error identnr
const id = this.config.relais[i].identnr.toString();
await this.grundstrukturAnlegen(id);
// @ts-expect-error adr ge und be
channel = await this.linieAnlegen(
id,
this.config.relais[i].adr,
this.config.relais[i].ge,
this.config.relais[i].be,
0,
'Ausgang',
);
this.log.info(`Relais: ${channel} durch Konfiguration angelegt`);
}
} catch (e) {
this.log.error(`${e} in onReady()`);
}
/*
await this.setObjectNotExistsAsync('testVariable', {
type: 'state',
common: {
name: 'testVariable',
type: 'string',
role: 'indicator',
read: true,
write: true,
},
native: {},
});
*/
this.subscribeStates('*.abfrage');
this.subscribeStates('*.ausgangszustand');
this.serverStart();
}
/**
* Is called when adapter shuts down - callback has to be called under any circumstances!
*
* @param {() => void} callback Callbackfunktion
*/
onUnload(callback) {
try {
// Here you must clear all timeouts or intervals that may still be active
// clearTimeout(timeout1);
// clearTimeout(timeout2);
// ...
// clearInterval(interval1);
if (servertcp) {
servertcp.close();
this.setState('info.connection', false, true);
while (devicesConnected.length > 0) {
const obj = devicesConnected.shift();
//this.setConnectState(obj.id, false, null);
obj.ae.disconnect();
}
}
callback();
} catch (e) {
this.log.error(`onUnload error ${e}`);
callback();
}
}
// If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.
// You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.
// /**
// * Is called if a subscribed object changes
// * @param {string} id
// * @param {ioBroker.Object | null | undefined} obj
// */
// onObjectChange(id, obj) {
// if (obj) {
// // The object was changed
// this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);
// } else {
// // The object was deleted
// this.log.info(`object ${id} deleted`);
// }
// }
/**
* Is called if a subscribed state changes
*
* @param {string} id Identnummer
* @param {ioBroker.State | null | undefined} state Status
*/
onStateChange(id, state) {
if (state) {
// The state was changed
if (!state.ack) {
const tmp = id.split('.');
tmp.pop();
const channelid = tmp.join('.');
this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
if (id.indexOf('.abfrage') > 0) {
this.getObject(id, (err, obj) => {
if (err) {
this.log.debug(err.toString());
} else {
//this.log.debug(JSON.stringify(obj));
if (obj && Object.prototype.hasOwnProperty.call(obj.native, 'status')) {
//this.log.debug(obj.native.status);
this.sendCommand(channelid, obj.native.status);
}
}
});
} else if (id.indexOf('.ausgangszustand') > 0) {
this.getObject(id, (err, obj) => {
if (err) {
this.log.debug(err.toString());
} else {
if (obj && Object.prototype.hasOwnProperty.call(obj.native, 'ein') && state.val) {
//this.log.debug(obj.native.ein);
this.sendCommand(channelid, obj.native.ein);
} else if (obj && Object.prototype.hasOwnProperty.call(obj.native, 'aus') && !state.val) {
//this.log.debug(obj.native.aus);
this.sendCommand(channelid, obj.native.aus);
}
}
});
}
}
} else {
// The state was deleted
this.log.debug(`state ${id} deleted`);
}
}
/**
* Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...
* Using this method requires "common.messagebox" property to be set to true in io-package.json
*
* @param {ioBroker.Message} obj Message
*/
onMessage(obj) {
//this.log.debug(JSON.stringify(obj));
if (typeof obj === 'object') {
if (obj.command === 'newKey') {
if (obj.callback) {
const key = vds.getRandomKey();
this.sendTo(obj.from, obj.command, [{ label: key, value: key }], obj.callback);
}
}
}
}
/**
* start socket server for listining
*/
serverStart() {
servertcp = net.createServer(this.onClientConnected.bind(this));
servertcp.listen(this.config.bindPort, this.config.bindIP, () => {
const text = `Server listening on IP-Adress (TCP): ${servertcp.address().address}:${servertcp.address().port}`;
this.log.info(text);
this.setState('info.connection', true, true);
});
servertcp.on('error', e => {
this.log.error(e.message);
});
}
/**
* alarm system connected (TCP/IP)
*
* @param {net.Socket} sock - socket
*/
onClientConnected(sock) {
const remoteAddress = `${sock.remoteAddress}:${sock.remotePort}`;
this.log.debug(`Verbindung von ${remoteAddress}`);
const AE = new vds();
AE.on('log', (msg, level) => {
switch (level) {
case 'debug':
this.log.debug(`AE: ${msg}`);
break;
case 'warn':
this.log.warn(`AE: ${msg}`);
break;
case 'error':
this.log.error(`AE: ${msg}`);
break;
default:
this.log.info(`AE: ${msg}`);
}
});
AE.on('connect', obj => {
this.log.debug(`connect ID: ${obj.id}`);
this.setConnectState(obj, true, AE);
});
AE.on('disconnect', obj => {
this.log.debug(`disconnect ID: ${obj.id}`);
this.setConnectState(obj, false, AE);
});
AE.on('data', obj => {
if (obj && typeof obj === 'object') {
this.log.debug(`Daten von: ${AE.Identnummer}`);
this.zerlegeDaten(AE.Identnummer === '' ? 'unbekannt' : AE.Identnummer, obj);
}
});
AE.setLogLevel(this.log.level);
AE.Polling = this.config.pollIntervall;
if (this.config.devices.length > 0) {
this.config.devices.forEach(obj => {
try {
// @ts-expect-error obj_parameter
AE.addDevice(obj.identnr, obj.stehend, obj.keynr, obj.key);
} catch (e) {
this.log.error(`Setzen Geraetedaten nicht moeglich ${e}`);
}
});
}
AE.connect(sock);
sock.on('data', data => {
//this.log.info('received from ' + remoteAddress + ' following data: ' + JSON.stringify(data));
AE.received(data);
});
sock.on('close', () => {
this.log.debug(`connection from ${remoteAddress} closed`);
AE.disconnect();
});
sock.on('error', err => {
this.log.error(`Connection ${remoteAddress} error: ${err.message}`);
});
}
/**
* Setzt den Verbindungszustand und speichert die Verweise
*
* @param {object} id_obj {'id':Identnummer, 'address': IP:Port}
* @param {boolean} state Zustand
* @param {vds | null} AE Verwalter
*/
async setConnectState(id_obj, state, AE) {
try {
queueConnect.push({ id: id_obj.id, state: state, ae: AE, command: [], address: id_obj.address });
if (isChangeConnect) {
return;
}
isChangeConnect = true;
let obj;
let i;
let isVerbunden;
while (queueConnect.length > 0) {
isVerbunden = false;
obj = queueConnect.shift();
if (obj.state) {
//Aufbau
for (i = 0; i < devicesConnected.length; i++) {
if (devicesConnected[i].id === obj.id) {
isVerbunden = true;
}
}
devicesConnected.push(obj);
if (isVerbunden) {
this.log.warn(`Identnummer ${obj.id} schon verbunden!`);
} else {
await this.grundstrukturAnlegen(obj.id);
}
await this.setStateAsync(`${obj.id}.Info.zustand`, obj.state, true);
} else {
//Abbau
if (devicesConnected.length === 0) {
this.log.debug('Abbau ohne Aufbau??? Warten!');
await this.Sleep(500);
if (devicesConnected.length === 0) {
await this.Sleep(500);
}
this.log.debug(`Jetzt nach Warten: ${devicesConnected.length.toString()}`);
}
for (i = 0; i < devicesConnected.length; i++) {
if (devicesConnected[i].id === obj.id) {
if (devicesConnected[i].address === obj.address) {
//selbe ID und Verbindung
devicesConnected.splice(i, 1);
i--;
} else {
isVerbunden = true; //selbe ID, aber andere Verbindung
}
}
}
if (!isVerbunden) {
await this.setStateAsync(`${obj.id}.Info.zustand`, obj.state, true);
}
}
}
} catch (e) {
this.log.error(`setConnectState: ${e}`);
} finally {
isChangeConnect = false;
}
}
/**
* Setzt die States f�r Abfrage und Fehler nach einem Befehl
*
* @param {string} channel ChannelID oder Identnummer
* @param {string} meldung Fehlermeldung
* @param {number} satz Datensatz (0x03, 0x11 oder 0x20)
*/
async checkCommand(channel, meldung, satz) {
let identnr;
//let isChannelIdentnr = false;
if (channel.indexOf('.') >= 0) {
identnr = channel.split('.')[2];
} else {
identnr = channel;
//isChannelIdentnr = true;
}
for (let i = 0; i < devicesConnected.length; i++) {
if (devicesConnected[i].id === identnr) {
for (let x = 0; x < devicesConnected[i].command.length; x++) {
if (satz === 0x11) {
await this.setStateAsync(`${devicesConnected[i].command[x].channelid}.abfrage`, false, true);
await this.setStateAsync(`${devicesConnected[i].command[x].channelid}.fehler`, meldung, true);
await this.setStateAsync(`${devicesConnected[i].command[x].channelid}.zeit_empfang`, '', true);
}
devicesConnected[i].command.splice(x, 1);
return;
}
}
}
}
/**
* Sendet den Befehl
*
* @param {string} channelid Channel-Id
* @param {string} command Vollstaendiger Satz (0x02 oder 0x10)
*/
async sendCommand(channelid, command) {
const identnr = channelid.split('.')[2];
this.log.debug(`Befehl: ${command} fuer id: ${identnr}`);
for (let i = 0; i < devicesConnected.length; i++) {
if (devicesConnected[i].id === identnr) {
devicesConnected[i].command.push({ channelid: channelid, satz: command });
devicesConnected[i].ae.sendCommand(command);
return;
}
}
await this.setStateAsync(`${channelid}.abfrage`, false, true);
await this.setStateAsync(`${channelid}.fehler`, 'keine Verbindung', true);
await this.setStateAsync(`${channelid}.zeit_empfang`, '', true);
}
/**
* Legt die Grundstruktur an, wenn nicht vorhanden (Device)
*
* @param {string} id Identnummer
*/
async grundstrukturAnlegen(id) {
try {
const objectCheck = await this.getStateAsync(`${id}.Info.merkmale`);
if (objectCheck) {
const Obj = await this.getObjectAsync(id);
if (!Object.prototype.hasOwnProperty.call(Obj.common, 'statusStates')) {
await this.extendObjectAsync(
id,
{
type: 'device',
common: {
statusStates: {
onlineId: `vds2465-server.${this.instance}.${id}.Info.zustand`,
},
},
native: {},
},
{ preserve: { common: ['name'] } },
);
}
return;
}
await this.extendObjectAsync(id, {
type: 'device',
common: {
name: id,
statusStates: {
onlineId: `vds2465-server.${this.instance}.${id}.Info.zustand`,
},
},
native: {},
});
await this.extendObjectAsync(`${id}.Info`, {
type: 'channel',
common: {
name: 'Information',
type: 'string',
},
native: {},
});
await this.extendObjectAsync(`${id}.Info.zustand`, {
type: 'state',
common: {
role: 'indicator.connected',
name: 'Verbindung steht',
type: 'boolean',
read: true,
write: false,
def: false,
},
native: {},
});
await this.extendObjectAsync(`${id}.Info.letzteTestmeldung`, {
type: 'state',
common: {
role: 'info',
name: 'Letzte Testmeldung',
type: 'string',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.Info.hersteller`, {
type: 'state',
common: {
role: 'info',
name: 'Herstellerinfo',
type: 'string',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.Info.merkmale`, {
type: 'state',
common: {
role: 'info',
name: 'Geraetemerkmale',
type: 'string',
read: true,
write: false,
def: '',
},
native: {},
});
this.log.info(`Device: ${id} angelegt`);
} catch (e) {
this.log.error(`grundstrukturAnlegen: ${e}`);
}
}
/**
* Legt die Linien an, wenn nicht vorhanden (Channel und State)
*
* @param {string} id Identnummer
* @param {number} li Adresse
* @param {number} ge Geraet
* @param {number} be Bereich
* @param {number} az Adresszusatz
* @param {string} art Adresserweiterung
* @returns {Promise<string>} ID vom State
*/
async linieAnlegen(id, li, ge, be, az, art) {
const channel_id = `${id}.${art}_${li}-${ge}-${be}-${az}`;
try {
const obj = await this.getObjectAsync(channel_id);
if (!obj) {
const channel = `${art}_${li}-${ge}-${be}-${az}`;
const name = `Li:${li} Ge:${ge} Be:${be} AdrZus:${az}`;
const gebe = ((ge << 4) & 0xf0) | (be & 0x0f);
let Adresserweiterung;
if (art === 'Stoerung') {
switch (li) {
case 1:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: 'Unterspannung',
type: 'string',
},
native: {},
});
break;
case 2:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: 'Akkufehler',
type: 'string',
},
native: {},
});
break;
case 3:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: 'Netzfehler',
type: 'string',
},
native: {},
});
break;
case 17:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: 'Fehler Uebertragungs-Primaerweg',
type: 'string',
},
native: {},
});
break;
case 18:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: 'Fehler Uebertragungs-Ersatzweg',
type: 'string',
},
native: {},
});
break;
default:
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: channel,
type: 'string',
},
native: {},
});
break;
}
} else {
await this.extendObjectAsync(`${id}.${channel}`, {
type: 'channel',
common: {
name: name,
type: 'string',
},
native: {},
});
}
switch (art) {
case 'Eingang':
Adresserweiterung = 1;
await this.extendObjectAsync(`${id}.${channel}.meldungszustand`, {
type: 'state',
common: {
name: 'Meldungszustand',
type: 'boolean',
role: 'indicator.state',
read: true,
write: false,
def: false,
states: {
true: 'Ein',
false: 'Aus',
},
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.meldungsart`, {
type: 'state',
common: {
name: 'Meldungsart',
type: 'number',
role: 'value',
read: true,
write: false,
def: 128,
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.meldungVds`, {
type: 'state',
common: {
name: 'Text',
type: 'string',
role: 'value',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.text`, {
type: 'state',
common: {
name: 'Text zur Meldung',
type: 'string',
role: 'value',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.zeit_meldung`, {
type: 'state',
common: {
name: 'Zeitpunkt der Ausloesung',
type: 'string',
role: 'datetime',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.zeit_empfang`, {
type: 'state',
common: {
name: 'Zeitpunkt des Empfangs',
type: 'string',
role: 'datetime',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.weg`, {
type: 'state',
common: {
name: 'Uebertragungsweg',
type: 'string',
role: 'value',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.fehler`, {
type: 'state',
common: {
name: 'Fehlermeldung',
type: 'string',
role: 'info',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.abfrage`, {
type: 'state',
common: {
name: 'Abfrage des Zustands',
type: 'boolean',
role: 'button',
read: true,
write: true,
def: false,
},
native: {
status: Buffer.from([5, 0x10, gebe, li, az, Adresserweiterung, 0x20]).toString('hex'),
},
});
break;
case 'Ausgang':
Adresserweiterung = 2;
await this.extendObjectAsync(`${id}.${channel}.ausgangszustand`, {
type: 'state',
common: {
name: 'Ausgangszustand',
type: 'boolean',
role: 'indicator.state',
read: true,
write: true,
def: false,
states: {
true: 'Ein',
false: 'Aus',
},
},
native: {
ein: Buffer.from([5, 2, gebe, li, az, Adresserweiterung, 0]).toString('hex'),
aus: Buffer.from([5, 2, gebe, li, az, Adresserweiterung, 128]).toString('hex'),
},
});
await this.extendObjectAsync(`${id}.${channel}.zeit_empfang`, {
type: 'state',
common: {
name: 'Zeitpunkt des Empfangs',
type: 'string',
role: 'datetime',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.fehler`, {
type: 'state',
common: {
name: 'Fehlermeldung',
type: 'string',
role: 'info',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.abfrage`, {
type: 'state',
common: {
name: 'Abfrage des Zustands',
type: 'boolean',
role: 'button',
read: true,
write: true,
def: false,
},
native: {
status: Buffer.from([5, 0x10, gebe, li, az, Adresserweiterung, 0x20]).toString('hex'),
},
});
break;
case 'Stoerung':
Adresserweiterung = 0x10;
await this.extendObjectAsync(`${id}.${channel}.meldungszustand`, {
type: 'state',
common: {
name: 'Meldungszustand',
type: 'boolean',
role: 'indicator.state',
read: true,
write: false,
def: false,
states: {
true: 'Ein',
false: 'Aus',
},
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.meldungsart`, {
type: 'state',
common: {
name: 'Meldungsart',
type: 'number',
role: 'value',
read: true,
write: false,
def: 128,
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.meldungVds`, {
type: 'state',
common: {
name: 'Text',
type: 'string',
role: 'value',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.text`, {
type: 'state',
common: {
name: 'Text',
type: 'string',
role: 'value',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.zeit_meldung`, {
type: 'state',
common: {
name: 'Zeitpunkt der Ausloesung',
type: 'string',
role: 'datetime',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.zeit_empfang`, {
type: 'state',
common: {
name: 'Zeitpunkt des Empfangs',
type: 'string',
role: 'datetime',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.fehler`, {
type: 'state',
common: {
name: 'Fehlermeldung',
type: 'string',
role: 'info',
read: true,
write: false,
def: '',
},
native: {},
});
await this.extendObjectAsync(`${id}.${channel}.abfrage`, {
type: 'state',
common: {
name: 'Abfrage des Zustands',
type: 'boolean',
role: 'button',
read: true,
write: true,
def: false,
},
native: {
status: Buffer.from([5, 0x10, gebe, li, az, Adresserweiterung, 0x20]).toString('hex'),
},
});
break;
}
}
return channel_id;
} catch (e) {
this.log.error(`linieAnlegen: ${e}`);
return channel_id;
}
}
Sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
/**
* Empfangene Daten
*
* @param {string} id Identnummer
* @param {object} obj Daten als JSON
*/
async zerlegeDaten(id, obj) {
let channel = '';
try {
const date = new Date();
const zeit = date.toLocaleString('de-DE');
await this.grundstrukturAnlegen(id);
let Meldungszeit = '';
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_50')) {
const zeit = new Date(obj['Satz_50'].Value);
Meldungszeit = zeit.toLocaleString('de-DE');
}
if (
Object.prototype.hasOwnProperty.call(obj, 'Satz_2') ||
Object.prototype.hasOwnProperty.call(obj, 'Satz_3') ||
Object.prototype.hasOwnProperty.call(obj, 'Satz_4') ||
Object.prototype.hasOwnProperty.call(obj, 'Satz_20')
) {
let satz = 'Satz_2';
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_3')) {
satz = 'Satz_3';
} else if (Object.prototype.hasOwnProperty.call(obj, 'Satz_4')) {
satz = 'Satz_4';
} else if (Object.prototype.hasOwnProperty.call(obj, 'Satz_20')) {
satz = 'Satz_20';
}
channel = await this.linieAnlegen(
id,
obj[satz].Adresse,
obj[satz].Geraet,
obj[satz].Bereich,
obj[satz].Adresszusatz,
obj[satz].Adresserweiterung,
);
let name = vdsmeldungen[obj[satz].Meldungsart];
if (typeof name === 'undefined') {
name = '';
}
if (obj[satz].Adresserweiterung === 'Eingang') {
await this.setStateAsync(`${channel}.abfrage`, false, true);
await this.setStateAsync(`${channel}.fehler`, '', true);
await this.setStateAsync(
`${channel}.meldungszustand`,
obj[satz].Meldungsart < 128 ? true : false,
true,
);
await this.setStateAsync(`${channel}.meldungsart`, obj[satz].Meldungsart, true);
await this.setStateAsync(`${channel}.meldungVds`, name, true);
await this.setStateAsync(
`${channel}.text`,
Object.prototype.hasOwnProperty.call(obj, 'Satz_54') ? obj['Satz_54'].Value : '',
true,
);
await this.setStateAsync(`${channel}.zeit_meldung`, Meldungszeit, true);
await this.setStateAsync(`${channel}.zeit_empfang`, zeit, true);
await this.setStateAsync(
`${channel}.weg`,
Object.prototype.hasOwnProperty.call(obj, 'Satz_61') ? obj['Satz_61'].Value : '',
true,
);
} else if (obj[satz].Adresserweiterung === 'Ausgang') {
await this.setStateAsync(
`${channel}.ausgangszustand`,
obj[satz].Meldungsart < 128 ? true : false,
true,
);
await this.setStateAsync(`${channel}.zeit_empfang`, zeit, true);
await this.setStateAsync(`${channel}.abfrage`, false, true);
await this.setStateAsync(`${channel}.fehler`, '', true);
} else {
await this.setStateAsync(
`${channel}.meldungszustand`,
obj[satz].Meldungsart < 128 ? true : false,
true,
);
await this.setStateAsync(`${channel}.meldungsart`, obj[satz].Meldungsart, true);
await this.setStateAsync(
`${channel}.text`,
Object.prototype.hasOwnProperty.call(obj, 'Satz_54') ? obj['Satz_54'].Value : '',
true,
);
await this.setStateAsync(`${channel}.zeit_meldung`, Meldungszeit, true);
await this.setStateAsync(`${channel}.zeit_empfang`, zeit, true);
await this.setStateAsync(`${channel}.abfrage`, false, true);
await this.setStateAsync(`${channel}.fehler`, '', true);
}
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_3')) {
await this.checkCommand(channel, '', 0x03);
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_11')) {
await this.checkCommand(id, obj['Satz_11'].Value, 0x11);
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_20')) {
await this.checkCommand(channel, '', 0x20);
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_40')) {
await this.setStateAsync(`${id}.Info.letzteTestmeldung`, zeit, true);
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_51')) {
await this.setStateAsync(`${id}.Info.hersteller`, obj['Satz_51'].Value, true);
}
if (Object.prototype.hasOwnProperty.call(obj, 'Satz_59')) {
await this.setStateAsync(`${id}.Info.merkmale`, obj['Satz_59'].Value, true);
}
} catch (e) {
this.log.error(`zerlegeDaten: ${e}`);
}
}
}
if (require.main !== module) {
// Export the constructor in compact mode
/**
* @param {Partial<utils.AdapterOptions>} [options] Adapteroptionen
*/
module.exports = options => new Vds2465Server(options);
} else {
// otherwise start the instance directly
new Vds2465Server();
}