From c6a3dcbfba73cdf159fb341f048dcdeba8dda95c Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Wed, 25 Oct 2017 21:57:39 +0200 Subject: [PATCH] extended memLayout() - added manufacturer --- CHANGELOG.md | 6 ++- README.md | 2 +- lib/memory.js | 121 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 94 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc0c51c..90d235e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ### Major (breaking) Changes - Version 3 - works only with [node.js][nodejs-url] **v4.0.0** and above (using now internal ES6 promise function, arrow functions, ...) -- **Promises**. As you can see above, you can now also use it in a promise oriented way. But callbacks are still supported. +- **Promises**. As you can see in the documentation, you can now also use it in a promise oriented way. But callbacks are still supported. +- **Async/Await**. Due to the promises support, systeminformation also works perfectly with the `async/await` pattern (available in [node.js][nodejs-url] **v7.6.0** and above). See example in the docs. - `cpuCurrentspeed`: now returns an object with current minimal, maximal and average CPU frequencies of all cores. - `mem`: now supports also newer versions of `free` (Version 3.3.10 and above); extended information `avaliable` (potentially available memory) - `fsStats`: added information sum bytes read + write (tx) and sum transfer rate/sec (tx_sec) @@ -98,6 +99,7 @@ Other changes | Version | Date | Comment | | -------------- | -------------- | -------- | +| 3.32.0 | 2017-10-23 | extended `memLayout()` - added manufacturer | | 3.31.4 | 2017-10-21 | updated `README.md` | | 3.31.3 | 2017-10-21 | bugfix `graphics()`, fixed typo `README.md` | | 3.31.2 | 2017-10-16 | bugfix `graphics()` vendor and model parsing linux VGA/3D | @@ -187,3 +189,5 @@ Other changes | 0.0.3 | 2014-04-14 | bug-fix (cpu_speed) | | 0.0.2 | 2014-03-14 | Optimization FS-Speed & CPU current speed | | 0.0.1 | 2014-03-13 | initial release | + +[nodejs-url]: https://nodejs.org/en/ diff --git a/README.md b/README.md index a1fa991..156f648 100644 --- a/README.md +++ b/README.md @@ -53,13 +53,13 @@ async function cpu() { ### Latest Activity (last 7 major and minor version releases) +- Version 3.32.0: extended `memLayout()` - added manufacturer - Version 3.31.0: extended windows support `cpuFlags()` (partially) - Version 3.30.0: extended `versions()` (added `yarn`, `gulp`, `grunt`, `tsc`, `git`) - Version 3.29.0: extended windows support `services()` - Version 3.28.0: extended windows support `processes()` - Version 3.27.0: added raw data to `currentLoad()`, fixed `networkInterfaces()` MAC problem node 8.x - Version 3.26.0: improved windows support `getDynamicData()`, updated docs -- Version 3.25.0: improved windows support `networkStats()`, `cpuCache()`, bug fix `getStaticData()` - ... You can find all changes here: [detailed changelog][changelog-url] diff --git a/lib/memory.js b/lib/memory.js index d3f6552..b447def 100644 --- a/lib/memory.js +++ b/lib/memory.js @@ -24,6 +24,20 @@ const _darwin = (_platform === 'Darwin'); const _windows = (_platform === 'Windows_NT'); const NOT_SUPPORTED = 'not supported'; +const OSX_RAM_manufacturers = { + "0x014F": "Transcend Information", + "0x2C00": "Micron Technology Inc.", + "0x802C": "Micron Technology Inc.", + "0x80AD": "Hynix Semiconductor Inc.", + "0x80CE": "Samsung Electronics Inc.", + "0xAD00": "Hynix Semiconductor Inc.", + "0xCE00": "Samsung Electronics Inc.", + "0x02FE": "Elpida", + "0x5105": "Qimonda AG i. In.", + "0x8551": "Qimonda AG i. In.", + "0x859B": "Crucial" +} + // _______________________________________________________________________________________ // | R A M | H D | // |______________________|_________________________| | | @@ -99,23 +113,23 @@ function mem(callback) { let lines = stdout.toString().split('\n'); let mem = lines[1].replace(/ +/g, " ").split(' '); - result.total = parseInt(mem[1]); - result.free = parseInt(mem[3]); + result.total = parseInt(mem[1], 10); + result.free = parseInt(mem[3], 10); if (lines.length === 4) { // free (since free von procps-ng 3.3.10) - result.buffcache = parseInt(mem[5]); - result.available = parseInt(mem[6]); + result.buffcache = parseInt(mem[5], 10); + result.available = parseInt(mem[6], 10); mem = lines[2].replace(/ +/g, " ").split(' '); } else { // free (older versions) - result.buffcache = parseInt(mem[5]) + parseInt(mem[6]); + result.buffcache = parseInt(mem[5], 10) + parseInt(mem[6], 10); result.available = result.free + result.buffcache; mem = lines[3].replace(/ +/g, " ").split(' '); } result.active = result.total - result.free - result.buffcache; - result.swaptotal = parseInt(mem[1]); - result.swapfree = parseInt(mem[3]); - result.swapused = parseInt(mem[2]); + result.swaptotal = parseInt(mem[1], 10); + result.swapfree = parseInt(mem[3], 10); + result.swapused = parseInt(mem[2], 10); } if (callback) { callback(result) } @@ -127,7 +141,7 @@ function mem(callback) { if (!error) { let lines = stdout.toString().split('\n'); - result.active = parseInt(lines[0].split(':')[1]) * 4096; + result.active = parseInt(lines[0].split(':')[1], 10) * 4096; result.buffcache = result.used - result.active; result.available = result.free + result.buffcache; } @@ -159,8 +173,8 @@ function mem(callback) { lines.forEach(function (line) { if (line !== '') { line = line.trim().split(/\s\s+/); - swaptotal = swaptotal + parseInt(line[0]); - swapused = swapused + parseInt(line[1]); + swaptotal = swaptotal + parseInt(line[0], 10); + swapused = swapused + parseInt(line[1], 10); } }); } @@ -180,30 +194,54 @@ exports.mem = mem; function memLayout(callback) { + function getManufacturer(manId) { + if (OSX_RAM_manufacturers.hasOwnProperty(manId)) { + return(OSX_RAM_manufacturers[manId]) + } + return manId; + } + return new Promise((resolve, reject) => { process.nextTick(() => { let result = []; if (_linux) { - exec("dmidecode -t memory | grep -iE 'Size:|Type|Speed|Manufacturer|Form Factor|Locator|Memory Device|Serial Number|Voltage'", function (error, stdout) { + exec("dmidecode -t memory | grep -iE 'Size:|Type|Speed|Manufacturer|Form Factor|Locator|Memory Device|Serial Number|Voltage|Part Number'", function (error, stdout) { if (!error) { let devices = stdout.toString().split('Memory Device'); devices.shift(); devices.forEach(function (device) { let lines = device.split('\n'); - result.push({ - size: parseInt(util.getValue(lines, ' Size'))*1024*1024, - bank: util.getValue(lines, ' Bank Locator'), - type: util.getValue(lines, ' Type:'), - clockSpeed: (util.getValue(lines, ' Configured Clock Speed:') ? parseInt(util.getValue(lines, ' Configured Clock Speed:')) : parseInt(util.getValue(lines, ' Speed:'))), - formFactor: util.getValue(lines, ' Form Factor:'), - partNum: '', - serialNum: util.getValue(lines, ' Serial Number:'), - voltageConfigured: parseFloat(util.getValue(lines, ' Configured Voltage:')), - voltageMin: parseFloat(util.getValue(lines, ' Minimum Voltage:')), - voltageMax: parseFloat(util.getValue(lines, ' Maximum Voltage:')), - }) + if (parseInt(util.getValue(lines, ' Size'), 10) > 0) { + result.push({ + size: parseInt(util.getValue(lines, ' Size'), 10)*1024*1024, + bank: util.getValue(lines, ' Bank Locator'), + type: util.getValue(lines, ' Type:'), + clockSpeed: (util.getValue(lines, ' Configured Clock Speed:') ? parseInt(util.getValue(lines, ' Configured Clock Speed:'), 10) : parseInt(util.getValue(lines, ' Speed:'), 10)), + formFactor: util.getValue(lines, ' Form Factor:'), + manufacturer: util.getValue(lines, ' Manufacturer:'), + partNum: util.getValue(lines, ' Part Number:'), + serialNum: util.getValue(lines, ' Serial Number:'), + voltageConfigured: parseFloat(util.getValue(lines, ' Configured Voltage:') || -1), + voltageMin: parseFloat(util.getValue(lines, ' Minimum Voltage:') || -1), + voltageMax: parseFloat(util.getValue(lines, ' Maximum Voltage:') || -1), + }) + } else { + result.push({ + size: 0, + bank: util.getValue(lines, ' Bank Locator'), + type: 'Empty', + clockSpeed: 0, + formFactor: util.getValue(lines, ' Form Factor:'), + partNum: '', + serialNum: '', + voltageConfigured: -1, + voltageMin: -1, + voltageMax: -1, + }) + + } }); } if (callback) { callback(result) } @@ -218,20 +256,36 @@ function memLayout(callback) { devices.shift(); devices.forEach(function (device) { let lines = device.split('\n'); + const bank = 'BANK ' + lines[0].trim(); const size = parseInt(util.getValue(lines, ' Size')); if (size) { result.push({ size: size * 1024 * 1024 * 1024, - bank: '', + bank: bank, type: util.getValue(lines, ' Type:'), - clockSpeed: parseInt(util.getValue(lines, ' Speed:')), + clockSpeed: parseInt(util.getValue(lines, ' Speed:'), 10), formFactor: '', + manufacturer: getManufacturer(util.getValue(lines, ' Manufacturer:')), partNum: util.getValue(lines, ' Part Number:'), serialNum: util.getValue(lines, ' Serial Number:'), voltageConfigured: -1, voltageMin: -1, voltageMax: -1, }) + } else { + result.push({ + size: 0, + bank: bank, + type: 'Empty', + clockSpeed: 0, + formFactor: '', + manufacturer: '', + partNum: '', + serialNum: '', + voltageConfigured: -1, + voltageMin: -1, + voltageMax: -1, + }) } }); } @@ -250,16 +304,17 @@ function memLayout(callback) { devices.forEach(function (device) { let lines = device.split('\r\n'); result.push({ - size: parseInt(util.getValue(lines, 'Capacity', '=')), + size: parseInt(util.getValue(lines, 'Capacity', '='), 10), bank: util.getValue(lines, 'abel', '='), // BankLabel - type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='))], - clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', '=')), - formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', '='))], + type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='), 10)], + clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', '='), 10), + formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', '='), 10)], + manufacturer: util.getValue(lines, 'Manufacturer', '='), partNum: util.getValue(lines, 'PartNumber', '='), serialNum: util.getValue(lines, 'SerialNumber', '='), - voltageConfigured: parseInt(util.getValue(lines, 'ConfiguredVoltage', '=')) / 1000.0, - voltageMin: parseInt(util.getValue(lines, 'MinVoltage', '=')) / 1000.0, - voltageMax: parseInt(util.getValue(lines, 'MaxVoltage', '=')) / 1000.0, + voltageConfigured: parseInt(util.getValue(lines, 'ConfiguredVoltage', '='), 10) / 1000.0, + voltageMin: parseInt(util.getValue(lines, 'MinVoltage', '='), 10) / 1000.0, + voltageMax: parseInt(util.getValue(lines, 'MaxVoltage', '='), 10) / 1000.0, }) }); }