UNPKG

iobroker.tinker

Version:

Tinker Board-Monitor for ioBroker Installations

298 lines (266 loc) 11.6 kB
/** * Tinker Board-Monitor Adapter * * License: MIT */ /* jshint -W097 */ /* jshint strict: false */ /*jslint node: true */ 'use strict'; const utils = require('@iobroker/adapter-core'); // Get common adapter utils const exec = require('child_process').execSync; const adapterName = require('./package.json').name.split('.').pop(); let adapter; let timer; let config; let objects; let tinker = {}; let table = {}; let errorsLogged = {}; function startAdapter(options) { options = options || {}; Object.assign(options, { name: adapterName }); adapter = new utils.Adapter(options); adapter.on('ready', () => { config = adapter.config; if (adapter.config.forceinit) { adapter.getObjectList({ startkey: `${adapter.name}.${adapter.instance}`, endkey: `${adapter.name}.${adapter.instance}\u9999` }, function (err, res) { res = res.rows; for (let i = 0; i < res.length; i++) { const id = res[i].doc.common.name; adapter.log.debug(`Remove ${id}: ${id}`); adapter.delObject(id, function (res, err) { if (res !== undefined && res !== 'Not exists') adapter.log.error(`res from delObject: ${res}`); if (err !== undefined) adapter.log.error(`err from delObject: ${err}`); }); adapter.deleteState(id, function (res, err) { if (res !== undefined && res !== 'Not exists') adapter.log.error(`res from deleteState: ${res}`); if (err !== undefined) adapter.log.error(`err from deleteState: ${err}`); }); } }); } adapter.subscribeStates('*'); adapter.getObjectList({ include_docs: true }, function (err, res) { res = res.rows; objects = {}; for (let i = 0; i < res.length; i++) { objects[res[i].doc._id] = res[i].doc; } adapter.log.debug('received all objects'); main(adapter); }); }); adapter.on('stateChange', (id, state) => { adapter.log.debug(`stateChange for ${id} found state = ${JSON.stringify(state)}`); }); adapter.on('unload', (callback) => { try { adapter.log.info('cleaned everything up...'); clearInterval(timer); callback(); } catch (e) { callback(); } }); return adapter; } function main(adapter) { // TODO: Check which Objects we provide timer = setInterval(parser, adapter.config.interval || 60000); parser(); } function parser() { adapter.log.debug('start parsing'); // Workaround, WebStorm if (config === undefined) { config = adapter.config; } for (let c in config) { if (!config.hasOwnProperty(c)) continue; adapter.log.debug(`PARSING: ${c}`); if (c.indexOf('c_') !== 0 && config[`c_${c}`] === true) { table[c] = new Array(20); const o = config[c]; for (let i in o) { if (!o.hasOwnProperty(i)) continue; adapter.log.debug(` PARSING: ${i}`); const object = o[i]; const command = object.command; let regexp; if (object.multiline !== undefined) { regexp = new RegExp(object.regexp, 'm'); } else { regexp = new RegExp(object.regexp); } const post = object.post; adapter.log.debug(`---> ${command}`); let stdout; try { stdout = exec(command).toString(); adapter.log.debug(`------------- ${stdout}`); } catch (er) { adapter.log.debug(er.stack); if (er.pid) console.log('%s (pid: %d) exited with status %d', er.file, er.pid, er.status); // do not process if exec fails continue; } const match = regexp.exec(stdout); adapter.log.debug(`---> REGEXP: ${regexp}`); if (match !== undefined && match !== null && match.length !== undefined) { adapter.log.debug(`GROUPS: ${match.length}`); } // TODO: if Group Match is bigger then 2 // split groups and header into seperate objects if (match !== undefined && match !== null && match.length > 2) { const lname = i.split(','); for (let m = 1; m < match.length; m++) { const value = match[m]; const name = lname[m - 1]; adapter.log.debug(`MATCHING: ${value}`); adapter.log.debug(`NAME: ${name}, VALULE: ${value}`); tinker[name] = value; table[c][i] = value; } } else { adapter.log.debug(`---> POST: ${post}`); let value; if (match !== undefined && match !== null) { value = match[1]; } else { value = stdout; } tinker[i] = value; table[c][i] = value; } } } } // TODO: Parse twice to get post data and evaluate for (let c in config) { if (!config.hasOwnProperty(c)) continue; adapter.log.debug(`CURRENT = ${c} ${config[`c_${c}`]}`); adapter.log.debug(c.indexOf('c_')); if (c.indexOf('c_') !== 0 && config[`c_${c}`]) { if (objects[c] === undefined) { const stateObj = { common: { name: c, // You can add here some description read: true, write: true, role: 'sensor' }, type: 'device', _id: c }; adapter.extendObject(c, stateObj); } const o = config[c]; for (let i in o) { if (!o.hasOwnProperty(i)) continue; const object = o[i]; const command = object.command; const post = object.post; adapter.log.debug(`---> POST: ${post} for ${i} in ${o}`); let value; const lname = i.split(','); if (lname !== undefined && lname.length > 1) { for (let m = 0; m < lname.length; m++) { const name = lname[m]; value = tinker[name]; // TODO: Check if value is number and format it 2 Digits if (!isNaN(value)) { value = parseFloat(value); const re = new RegExp(/^\d+\.\d+$/); if (re.exec(value)) { value = parseFloat(value.toFixed(2)); } } adapter.log.debug(`MATCHING: ${value}`); adapter.log.debug(`NAME: ${name} VALULE: ${value}`); const objectName = `${adapter.name}.${adapter.instance}.${c}.${name}`; adapter.log.debug(`SETSTATE FOR ${objectName} VALUE = ${value}`); if (objects[objectName] === undefined) { // TODO Create an Objecttree const stateObj = { common: { name: objectName, // You can add here some description read: true, write: true, state: 'state', role: 'value', type: 'number' }, type: 'state', _id: objectName }; adapter.extendObject(objectName, stateObj); } adapter.setState(objectName, { val: value, ack: true }); } } else { value = tinker[i]; if (value !== undefined && value !== '' && value !== null) { if (post.indexOf('$1') !== -1) { adapter.log.debug(`VALUE: ${value} POST: ${post}`); try { value = eval(post.replace('$1', value)); } catch (e) { adapter.log.error(`Cannot evaluate: ${post.replace('$1', value)}`); value = NaN; } } // TODO: Check if value is number and format it 2 Digits if (!isNaN(value)) { value = parseFloat(value); const r = new RegExp(/^\d+\.\d+$/); if (r.exec(value)) { value = parseFloat(value.toFixed(2)); } } const objectName = `${adapter.name}.${adapter.instance}.${c}.${i}`; adapter.log.debug(`SETSTATE FOR ${objectName} VALUE = ${value}`); if (objects[objectName] === undefined) { // TODO Create an Objecttree const stateObj = { common: { name: objectName, // You can add here some description read: true, write: true, state: 'state', role: 'value', type: 'mixed' }, type: 'state', _id: objectName }; adapter.extendObject(objectName, stateObj); } adapter.setState(objectName, { val: value, ack: true }); } else { if (i === 'wifi_send' || i === 'wifi_received') { adapter.log.debug(`No Value found for ${i}`); } else if (!errorsLogged[i]) { adapter.log.error(`No Value found for ${i}`); errorsLogged[i] = true; } } } } } } } // If started as allInOne/compact mode => return function to create instance if (module && module.parent) { module.exports = startAdapter; } else { // or start the instance directly startAdapter(); }