UNPKG

iobroker.ems-esp

Version:
493 lines (449 loc) 17.2 kB
/* eslint-disable no-empty */ const Syslog = require('simple-syslog-server'); const fs = require('node:fs'); let server; let telegrams = [], syslog = []; let unloaded = false; let active = false; let active_old = false; let adapter, utils, fn; const init = async function (a, u) { adapter = a; utils = u; const dataDir = utils.getAbsoluteDefaultDataDir(); // /opt/iobroker/iobroker-data await fs.promises.mkdir(`${dataDir}/ems-esp/${adapter.instance}`, { recursive: true }); fn = `${dataDir}/ems-esp/${adapter.instance}/syslog`; adapter = a; await init_syslog(); try { await syslog_server(); } catch (err) { adapter.log.info(err); } }; async function syslog_server() { const options = { type: 'udp4' }; const address = ''; // Any let port = 0; let state = await adapter.getStateAsync('syslog.server.port'); if (state != null) { port = state.val; } if (port == 0) { return; } const listen = { host: address, port: port }; server = Syslog.UDP(options); state = await adapter.getStateAsync('syslog.activated'); if (state != null) { active = state.val; } adapter.setStateAsync('syslog.server.active', { ack: true, val: false }); // Start Syslog Server --------------------------------------------------------------------------------------------------------------------------------- server .on('msg', data => { if (!unloaded) { sys(data); } else { adapter.log.info('syslog server closed due to adapter stop'); server.close(); return; } }) .on('error', err => { adapter.log.error(`syslog error :${err}`); server.close(); return; }) .listen(listen) .then(() => { adapter.log.info(`syslog server now listening on port:${port}`); }) .catch(err => { adapter.log.error(err); }); } // Anaylse syslog data stream ------------------------------------------------------------------------------------------------------------------------------ async function sys(data) { try { let fsrc = '', fdest = '', ftype = '', fpolling = false, fvalue = ''; adapter.getState('syslog.activated', function (err, state) { if (state != null) { active = state.val; } }); const state = await adapter.getStateAsync('syslog.activated'); active = state.val; if (active_old == false && active == true) { telegrams = []; syslog = []; const time = new Date(); const d = { time: time.toLocaleString(), telegram: 'Start' }; telegrams.unshift(d); await adapter.setStateAsync('syslog.telegrams', { ack: true, val: JSON.stringify(telegrams) }); await adapter.setStateAsync('syslog.telegram.dest', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.type', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.type_text', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.type_raw', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.data', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.offset', { ack: true, val: '' }); await adapter.setStateAsync('syslog.telegram.telegram_raw', { ack: true, val: '' }); } if (active_old == true && active == false) { write_file(fn, telegrams); } active_old = active; adapter.setStateAsync('syslog.server.active', { ack: true, val: true }); adapter.setStateAsync('syslog.server.data', { ack: true, val: JSON.stringify(data) }); s_list(syslog, data); let state1 = await adapter.getStateAsync('syslog.filter.src'); if (state1 != null) { fsrc = state1.val; } state1 = await adapter.getStateAsync('syslog.filter.dest'); if (state1 != null) { fdest = state1.val; } state1 = await adapter.getStateAsync('syslog.filter.type'); if (state1 != null) { ftype = state1.val; } state1 = await adapter.getStateAsync('syslog.filter.value'); if (state1 != null) { fvalue = state1.val; } state1 = await adapter.getStateAsync('syslog.filter.polling'); if (state1 != null) { fpolling = state1.val; } let p1 = false, p2 = false, p3 = false, p4 = false, p5 = false, src = '', dest = '', type = '', typet = '', typer = '', offset = '', tdata = '', tg = []; if (data.msg.substr(0, 3) == 'Rx:') { const pos1 = data.msg.indexOf(':'); if (pos1 > -1) { data.msg = data.msg.substring(pos1 + 2); } tg = data.msg.split(' '); src = tg[0]; dest = tg[1]; type = tg[2]; typer = type; offset = tg[3]; tdata = ''; for (let i = 4; i < tg.length - 1; i++) { if (i == 4) { tdata = tg[i]; } else { tdata += ` ${tg[i]}`; } } if (fsrc == src || fsrc == '') { p1 = true; } if (fdest == dest || fdest == '') { p2 = true; } const bits = `00000000${parseInt(dest, 16).toString(2)}`.substr(-8); const bit8 = bits.substring(0, 1); p3 = true; if (bit8 == '1' && fpolling == false) { p3 = false; } if ((type == 'FF' || type == 'F9') && bit8 == '0') { typer = tg[4] + tg[5]; //if (typer.substr(0,1) == "0") typer = typer.substr(1,3); let hexValue = parseInt(typer, 16); hexValue = hexValue + 0x0100; type = hexValue.toString(16).toUpperCase(); tdata = ''; for (let i = 6; i < tg.length - 1; i++) { if (i == 6) { tdata = tg[i]; } else { tdata += ` ${tg[i]}`; } } } if ((type == 'FF' || type == 'F9') && bit8 == '1') { typer = tg[5] + tg[6]; //if (typer.substr(0,1) == "0") typer = typer.substr(1,3); let hexValue = parseInt(typer, 16); hexValue = hexValue + 0x0100; type = hexValue.toString(16).toUpperCase(); tdata = tg[4]; } if (ftype == type || ftype == '' || ftype == typer) { p4 = true; } p5 = false; if (fvalue == '') { p5 = true; } if (fvalue != '' && tdata.indexOf(fvalue) >= 0) { p5 = true; } } const m1 = data.msg.search('->'); const m2 = data.msg.search('<-'); if (m1 > -1 || m2 > -1) { p3 = true; if (m2 > -1 && fpolling == false) { p3 = false; } let d = data.msg; let p11 = d.search(/\(/); let p12 = d.search(/\)/); src = d.substring(p11 + 3, p12); if (fsrc == src || fsrc == '') { p1 = true; } d = d.substring(p12 + 1); p11 = d.search(/\(/); p12 = d.search(/\)/); dest = d.substring(p11 + 3, p12); if (m2 > -1) { if (dest == '08') { dest = '88'; } if (dest == '10') { dest = '90'; } } if (fdest == dest || fdest == '') { p2 = true; } d = d.substring(p12 + 1); p11 = d.search(/\(/); typet = d.substring(2, p11); p12 = d.search(/\)/); type = d.substring(p11 + 3, p12); typer = type; if (typer.length >= 3) { let hexValue = parseInt(typer, 16); hexValue = hexValue - 0x0100; typer = hexValue.toString(16).toUpperCase(); if (typer.length == 3) { typer = `0${typer}`; } } if (ftype == type || ftype == '' || ftype == typer || ftype == typet) { p4 = true; } d = d.substring(p12 + 1); p11 = d.search(/\(/); p12 = d.search(/\)/); offset = '00'; if (p11 > -1 && p12 > -1) { offset = d.substring(p11 + 8, p12); } const offn = parseInt(offset); offset = offn.toString(16); if (p11 == -1) { tdata = d.substring(8); } if (p11 > -1) { tdata = d.substring(8, p11); } p5 = false; if (fvalue == '') { p5 = true; } if (fvalue != '' && tdata.indexOf(fvalue) >= 0) { p5 = true; } } if (p1 && p2 && p3 && p4 && p5 && active && !unloaded) { await adapter.setStateAsync('syslog.telegram.telegram_raw', { ack: true, val: data.msg }); await adapter.setStateAsync('syslog.telegram.src', { ack: true, val: src }); await adapter.setStateAsync('syslog.telegram.dest', { ack: true, val: dest }); await adapter.setStateAsync('syslog.telegram.type', { ack: true, val: type }); await adapter.setStateAsync('syslog.telegram.type_text', { ack: true, val: typet }); await adapter.setStateAsync('syslog.telegram.type_raw', { ack: true, val: typer }); await adapter.setStateAsync('syslog.telegram.offset', { ack: true, val: offset }); await adapter.setStateAsync('syslog.telegram.data', { ack: true, val: tdata }); if (tdata != '<empty>' && tdata != '') { t_list(telegrams, data.msg); } } } catch {} } function write_file(fn, telegrams) { const fnw = `${fn}_${Date.now()}.txt`; let data = ''; for (let i = 0; i < telegrams.length; i++) { data += `${JSON.stringify(telegrams[i])} \n`; } try { fs.writeFileSync(fnw, data, 'utf8'); } catch (err) { adapter.log.info(err); } } function t_list(telegrams, t) { const max = 1000; const time = new Date(); const d = { time: time.toLocaleString(), telegram: t }; telegrams.unshift(d); if (telegrams.length > max) { telegrams.pop(); } adapter.setStateAsync('syslog.telegrams', { ack: true, val: JSON.stringify(telegrams) }); } function s_list(syslog, s) { const max = 1000; syslog.unshift(s); if (syslog.length > max) { syslog.pop(); } adapter.setStateAsync('syslog.server.syslog', { ack: true, val: JSON.stringify(syslog) }); } async function init_syslog() { await adapter.setObjectNotExistsAsync('syslog.filter.src', { type: 'state', common: { type: 'string', name: 'syslog source filter', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.filter.src', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.filter.src', { ack: true, val: '' }); } }); await adapter.setObjectNotExistsAsync('syslog.filter.dest', { type: 'state', common: { type: 'string', name: 'syslog destination filter', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.filter.dest', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.filter.dest', { ack: true, val: '' }); } }); await adapter.setObjectNotExistsAsync('syslog.filter.type', { type: 'state', common: { type: 'string', name: 'syslog type filter', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.filter.type', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.filter.type', { ack: true, val: '' }); } }); await adapter.setObjectNotExistsAsync('syslog.filter.value', { type: 'state', common: { type: 'string', name: 'syslog value filter', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.filter.value', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.filter.value', { ack: true, val: '' }); } }); await adapter.setObjectNotExistsAsync('syslog.filter.polling', { type: 'state', common: { type: 'boolean', name: 'syslog polling filter', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.filter.polling', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.filter.polling', { ack: true, val: false }); } }); await adapter.setObjectNotExistsAsync('syslog.server.active', { type: 'state', common: { type: 'boolean', name: 'syslog server active?', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.server.data', { type: 'state', common: { type: 'object', name: 'syslog data', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.server.port', { type: 'state', common: { type: 'number', name: 'syslog port number', role: 'value', read: true, write: true }, native: {}, }); await adapter.setStateAsync('syslog.server.port', { ack: true, val: adapter.config.syslog_port }); await adapter.setObjectNotExistsAsync('syslog.server.syslog', { type: 'state', common: { type: 'json', name: 'syslog json-list', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.src', { type: 'state', common: { type: 'string', name: 'telegram source', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.dest', { type: 'state', common: { type: 'string', name: 'telegram destination', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.type', { type: 'state', common: { type: 'string', name: 'telegram type-id', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.type_text', { type: 'state', common: { type: 'string', name: 'telegram type-id text', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.offset', { type: 'state', common: { type: 'mixed', name: 'telegram offset', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.data', { type: 'state', common: { type: 'string', name: 'telegram data', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.type_raw', { type: 'state', common: { type: 'string', name: 'telegram type raw (as in telegram)', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.telegram.telegram_raw', { type: 'state', common: { type: 'string', name: 'telegram', role: 'value', read: true, write: true }, native: {}, }); await adapter.setObjectNotExistsAsync('syslog.activated', { type: 'state', common: { type: 'boolean', name: 'syslog telegram analysis active?', role: 'value', read: true, write: true }, native: {}, }); adapter.getState('syslog.activated', function (err, state) { if (state == null) { adapter.setStateAsync('syslog.activated', { ack: true, val: false }); } }); await adapter.setObjectNotExistsAsync('syslog.telegrams', { type: 'state', common: { type: 'json', name: 'telegrams json-list', role: 'value', read: true, write: true }, native: {}, }); } const unload = function (u) { unloaded = u; adapter.log.info('syslog server closed due to adapter stop'); server.close(); }; module.exports = { init, unload };