UNPKG

@ali-pay/node-red-contrib-s7

Version:

A Node-RED node to interact with Siemens S7 PLCs

85 lines (67 loc) 2.49 kB
//@ts-check /* Copyright: (c) 2016-2020, ST-One Ltda., Guilherme Francescon Cittolin <guilherme@st-one.io> GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) */ const path = require('path'); const util = require('util'); const os = require('os'); const exec = util.promisify(require('child_process').exec); const pnToolsPath = 'pn-tools'; const pnDevRoleMask = 0x02; class Tools { constructor() { this.pnToolsAvailable = null; this.ifaceCache = new Map(); } async isPnToolsAvailable() { if (this.pnToolsAvailable === null) { try { await exec(`${pnToolsPath} version`); this.pnToolsAvailable = true; } catch (e) { this.pnToolsAvailable = false; } } return this.pnToolsAvailable; } getIfaces() { let ifaces = os.networkInterfaces(); return Object.keys(ifaces).filter(v => ifaces[v][0] && !ifaces[v][0].internal) } async listDevicesPN() { if (!await this.isPnToolsAvailable()) return []; let proms = []; for (const iface of this.getIfaces()) { proms.push(exec(`${pnToolsPath} discovery -o -i "${iface}"`).then(res => {return {iface, res};})); } let devs = []; let results = await Promise.all(proms); for (const elm of results) { let iface = elm.iface; let out = elm.res.stdout.trim().split('\n'); if (out.length < 2) continue; let keys = out.shift().split('\t'); for (const row of out) { let dev = {}; let elms = row.split('\t'); for (const i in elms) { dev[keys[i]] = elms[i]; } this.ifaceCache.set(dev['MAC Address'], iface); devs.push(dev); } } // filters out devices that don't have the "IO-Controller" (0x02) bit set return devs.filter(val => (parseInt(val['Device Role']) & pnDevRoleMask)); } async flashLedPN(mac_addr, iface) { if (!await this.isPnToolsAvailable()) return; iface = iface || this.ifaceCache.get(mac_addr); if (!iface) { throw new Error(`Could not determine interface for [${mac_addr}]`); } await exec(`${pnToolsPath} flashled -i "${iface}" -t "${mac_addr}"`); } } module.exports = new Tools();