From a41ddc6d1f80dc48457d231343650411260fcea8 Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Sun, 18 Jun 2017 09:43:32 +0200 Subject: [PATCH] extended time (timezone), extended windows support (battery, getAll...) --- CHANGELOG.md | 1 + README.md | 24 ++++--- lib/battery.js | 34 +++++++-- lib/index.js | 186 +++++++++++++++++-------------------------------- lib/network.js | 8 ++- lib/osinfo.js | 6 +- 6 files changed, 117 insertions(+), 142 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 231fdef..fc34cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,7 @@ Other changes | Version | Date | Comment | | -------------- | -------------- | -------- | +| 3.21.0 | 2017-06-18 | extended time (timezone), extended windows support (battery, getAll...) | | 3.20.1 | 2017-06-17 | updated docs | | 3.20.0 | 2017-06-16 | extend windows support (cpu, cpuCache, cpuCurrentspeed, mem, networkInterfaces, docker) | | 3.19.0 | 2017-06-12 | OSX temperature now an optional dependency | diff --git a/README.md b/README.md index 893ffc4..c8f989f 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,8 @@ si.cpu() ### Latest Activity -- Version 3.20.0: added additional windows support (cpu, cpuCache, cpuCurrentspeed, mem, networkInterfaces, docker) +- Version 3.21.0: extended `time` (timezone), extended windows support (`battery`, `getAll...`) +- Version 3.20.0: added additional windows support (`cpu`, `cpuCache`, `cpuCurrentspeed`, `mem`, `networkInterfaces`, `docker`) - Version 3.19.0: OSX temperature now an optional dependency (see comments below in reference!) - Version 3.18.0: extended `cpu` info (vendor, family, model, stepping, revision, cache, speedmin, speedmax) - Version 3.17.0: windows support for some very first functions (work in progress) @@ -94,6 +95,8 @@ I also created a nice little command line tool called [mmon][mmon-github-url] ( | si.time() | {...} | X | X | X | (no callback/promise) | | | current | X | X | X | local time | | | uptime | X | X | X | uptime | +| | timezone | X | X | X | e.g. GMT+0200 | +| | timezoneName | X | X | X | e.g. CEST | #### 2. System (HW) @@ -151,12 +154,13 @@ I also created a nice little command line tool called [mmon][mmon-github-url] ( | | swaptotal | X | X | X | | | | swapused | X | X | X | | | | swapfree | X | X | X | | -| si.battery(cb) | {...} | X | X | | battery information | -| | hasbattery | X | X | | indicates presence of battery | -| | ischarging | X | X | | indicates if battery is charging | -| | maxcapacity | X | X | | max capacity of battery | -| | currentcapacity | X | X | | current capacity of battery | -| | percent | X | X | | charging level in percent | +| si.battery(cb) | {...} | X | X | X | battery information | +| | hasbattery | X | X | X | indicates presence of battery | +| | cyclecount | X | X | | numbers of recharges | +| | ischarging | X | X | X | indicates if battery is charging | +| | maxcapacity | X | X | X | max capacity of battery | +| | currentcapacity | X | X | X | current capacity of battery | +| | percent | X | X | X | charging level in percent | | si.graphics(cb) | {...} | X | X | | arrays of graphics controllers and displays | | | controllers[0].model | X | X | X | graphics controller model | | | controllers[0].vendor | X | X | X | e.g. ATI | @@ -364,9 +368,9 @@ I also created a nice little command line tool called [mmon][mmon-github-url] ( | Function | Result object | Linux | OSX | Win | Comments | | --------------- | ----- | ----- | ---- | ------- | -------- | -| si.getStaticData(cb) | {...} | X | X | | all static data at once | -| si.getDynamicData(srv,iface,cb) | {...} | X | X | | all dynamic data at once | -| si.getAllData(srv,iface,cb) | {...} | X | X | | all data at once | +| si.getStaticData(cb) | {...} | X | X | X | all static data at once | +| si.getDynamicData(srv,iface,cb) | {...} | X | X | X | all dynamic data at once | +| si.getAllData(srv,iface,cb) | {...} | X | X | X | all data at once | ### cb: Asynchronous Function Calls (callback) diff --git a/lib/battery.js b/lib/battery.js index be546e9..ab328d8 100644 --- a/lib/battery.js +++ b/lib/battery.js @@ -24,16 +24,24 @@ const _darwin = (_platform === 'Darwin'); const _windows = (_platform === 'Windows_NT'); const NOT_SUPPORTED = 'not supported'; +function getValue(lines, property, separator) { + separator = separator || ':'; + property = property.toLowerCase(); + for (let i = 0; i < lines.length; i++) { + if (lines[i].toLowerCase().startsWith(property)) { + const parts = lines[i].split(separator); + if (parts.length > 1) { + return parts[1].trim(); + } + } + } + return ''; +} + module.exports = function (callback) { return new Promise((resolve, reject) => { process.nextTick(() => { - if (_windows) { - let error = new Error(NOT_SUPPORTED); - if (callback) { callback(NOT_SUPPORTED) } - reject(error); - } - let result = { hasbattery: false, cyclecount: 0, @@ -107,6 +115,20 @@ module.exports = function (callback) { resolve(result); }); } + if (_windows) { + exec("WMIC Path Win32_Battery Get BatteryStatus, DesignCapacity, EstimatedChargeRemaining /value", function (error, stdout) { + if (!error) { + let lines = stdout.split('\r\n'); + let status = parseInt(getValue(lines, 'BatteryStatus', '=') || '2'); + result.ischarging = (status >= 6 && status <= 9); + result.maxcapacity = parseInt(getValue(lines, 'DesignCapacity', '=') || 0); + result.percent = parseInt(getValue(lines, 'EstimatedChargeRemaining', '=') || 0); + result.currentcapacity = parseInt(result.maxcapacity * result.percent / 100); + } + if (callback) { callback(result) } + resolve(result); + }); + } }); }); }; diff --git a/lib/index.js b/lib/index.js index 6f6ea39..fc9509e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -68,78 +68,16 @@ // // This library is still work in progress. Version 3 comes with further improvements. First it // requires now node.js version 4.0 and above. Another big change is, that all functions now -// return promises. You can use them like before with callbacks OR with promises (see documentation -// below. I am sure, there is for sure room for improvement. I was only able to test it on several -// Debian, Raspbian, Ubuntu distributions as well as OS X (Mavericks, Yosemite, El Captain). -// Since version 2 nearly all functionality is available on OS X/Darwin platforms. -// But be careful, this library will definitely NOT work on Windows platforms! +// return promises. You can use them like before with callbacks OR with promises +// (see example in this documentation). I am sure, there is for sure room for improvement. +// I was only able to test it on several Debian, Raspbian, Ubuntu distributions as well as +// OS X (Mavericks, Yosemite, El Captain) and some Windows machines. +// Since version 2 nearly all functionality is available for OS X/Darwin platforms. +// In Version 3 I started to add (limited!) windows support. // // Comments, suggestions & reports are very welcome! // // ================================================================================== -// -// Version history -// -------------------------------- -// -// version date comment -// 3.20.0 2017-06-16 extend windows support (cpu, cpuCache, cpuCurrentspeed, mem, networkInterfaces, docker) -// 3.19.0 2017-06-12 OSX temperature now an optional dependency -// 3.18.0 2017-05-27 extended `cpu` info (vendor, family, model, stepping, revision, cache, speedmin/max) -// 3.17.3 2017-04-29 minor fix (blockDevices data array, Windows) -// 3.17.2 2017-04-24 minor fix (removed console.log) -// 3.17.1 2017-04-23 fixed bugs fsSize(win), si.processes (command), si.osinfo(win) -// 3.17.0 2017-02-19 windows support for some first functions -// 3.16.0 2017-01-19 blockDevices: added removable attribute + fix -// 3.15.1 2017-01-17 minor cpuTemperature fix (OSX) -// 3.15.0 2017-01-15 added cpuTemperature also for OSX -// 3.14.0 2017-01-14 added currentLoad per cpu/core, cpu cache (L1, L2, L3) and cpu flags -// 3.13.0 2016-11-23 added shell (determines standard shell) -// 3.12.0 2016-11-17 refactoring and extended currentLoad (better OSX coverage and added irq load) -// 3.11.2 2016-11-16 blockDevices: improved for older lsblk versions -// 3.11.1 2016-11-16 fixed small bug in blockDevices -// 3.11.0 2016-11-15 blockDevices for OSX and extended blockDevices -// 3.10.2 2016-11-14 bug fix fsSize on OSX -// 3.10.1 2016-11-14 optimization fsStats, disksIO, networkStats -// 3.10.0 2016-11-12 added blockDevices, fixed fsSize, added file system type -// 3.9.0 2016-11-11 added MAC address to networkInterfaces, fixed currentLoad -// 3.8.1 2016-11-04 updated docs -// 3.8.0 2016-11-04 added dockerContainerProcesses -// 3.7.1 2016-11-03 code refactoring -// 3.7.0 2016-11-02 extended docker stats, and no longer relying on curl (version conflicts) -// 3.6.0 2016-09-16 added versions (kernel, ssl, node, npm, pm2, ...) -// 3.5.1 2016-09-14 bugfix graphics info -// 3.5.0 2016-09-14 added graphics info (controller, display) -// 3.4.4 2016-09-02 tiny fixes system.model, getDefaultNetworkInterface -// 3.4.3 2016-09-02 tiny bug fix fsStats, disksIO OSX -// 3.4.2 2016-09-01 improved default network interface -// 3.4.1 2016-08-30 updated docs -// 3.4.0 2016-08-30 rewritten current process cpu usage (linux) -// 3.3.0 2016-08-24 added process list -// 3.2.1 2016-08-20 updated docs, improvement system -// 3.2.0 2016-08-19 added battery info -// 3.1.1 2016-08-18 improved system and os detection (vm, ...), bug fix disksIO -// 3.1.0 2016-08-18 added docker stats -// 3.0.1 2016-08-17 Bug-Fix disksIO, users, updated docs -// 3.0.0 2016-08-03 new major version 3.0 -// 2.0.5 2016-02-22 some more tiny correction ... -// 2.0.4 2016-02-22 tiny correction - removed double quotes CPU brand, ... -// 2.0.3 2016-02-22 optimized cpuCurrentspeed -// 2.0.2 2016-02-22 added CoreOS identification -// 2.0.1 2016-01-07 minor patch -// 2.0.0 2016-01-07 new major version 2.0 -// 1.0.7 2015-11-27 fixed: si.network_speed() -// 1.0.6 2015-09-17 fixed: si.users() -// 1.0.5 2015-09-14 updated dependencies -// 1.0.4 2015-07-18 updated docs -// 1.0.3 2015-07-18 bugfix cpu cores -// 1.0.2 2015-07-18 bugfix cpu_currentspeed, cpu_temperature -// 1.0.1 2015-07-18 documentation update -// 1.0.0 2015-07-18 bug-fixes, version bump, published as npm component -// 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 -// -// ================================================================================== // ---------------------------------------------------------------------------------- // Dependencies @@ -187,11 +125,6 @@ function getStaticData(callback) { return new Promise((resolve, reject) => { process.nextTick(() => { - if (_windows) { - let error = new Error(NOT_SUPPORTED); - if (callback) { callback(NOT_SUPPORTED) } - reject(error); - } let data = {}; @@ -242,22 +175,19 @@ function getDynamicData(srv, iface, callback) { return new Promise((resolve, reject) => { process.nextTick(() => { - if (_windows) { - let error = new Error(NOT_SUPPORTED); - if (callback) { callback(NOT_SUPPORTED) } - reject(error); - } iface = iface || network.getDefaultNetworkInterface(); srv = srv || ''; // use closure to track ƒ completion let functionProcessed = (function () { - let totalFunctions = 14; + let totalFunctions = (_windows ? 5 : 14); return function () { if (--totalFunctions === 0) { - if (callback) { callback(data) } + if (callback) { + callback(data) + } resolve(data); } }; @@ -290,35 +220,45 @@ function getDynamicData(srv, iface, callback) { functionProcessed(); }); - users.users().then(res => { - data.users = res; - functionProcessed(); - }); + if (!_windows) { + users.users().then(res => { + data.users = res; + functionProcessed(); + }); + } - processes.processes().then(res => { - data.processes = res; - functionProcessed(); - }); + if (!_windows) { + processes.processes().then(res => { + data.processes = res; + functionProcessed(); + }); + } - cpu.currentLoad().then(res => { - data.currentLoad = res; - functionProcessed(); - }); + if (!_windows) { + cpu.currentLoad().then(res => { + data.currentLoad = res; + functionProcessed(); + }); + } cpu.cpuTemperature().then(res => { data.temp = res; functionProcessed(); }); - network.networkStats(iface).then(res => { - data.networkStats = res; - functionProcessed(); - }); + if (!_windows) { + network.networkStats(iface).then(res => { + data.networkStats = res; + functionProcessed(); + }); + } - network.networkConnections().then(res => { - data.networkConnections = res; - functionProcessed(); - }); + if (!_windows) { + network.networkConnections().then(res => { + data.networkConnections = res; + functionProcessed(); + }); + } mem().then(res => { data.mem = res; @@ -330,30 +270,38 @@ function getDynamicData(srv, iface, callback) { functionProcessed(); }); - processes.services(srv).then(res => { - data.services = res; - functionProcessed(); - }); + if (!_windows) { + processes.services(srv).then(res => { + data.services = res; + functionProcessed(); + }); + } filesystem.fsSize().then(res => { data.fsSize = res; functionProcessed(); }); - filesystem.fsStats().then(res => { - data.fsStats = res; - functionProcessed(); - }); + if (!_windows) { + filesystem.fsStats().then(res => { + data.fsStats = res; + functionProcessed(); + }); + } - filesystem.disksIO().then(res => { - data.disksIO = res; - functionProcessed(); - }); + if (!_windows) { + filesystem.disksIO().then(res => { + data.disksIO = res; + functionProcessed(); + }); + } - internet.inetLatency().then(res => { - data.inetLatency = res; - functionProcessed(); - }); + if (!_windows) { + internet.inetLatency().then(res => { + data.inetLatency = res; + functionProcessed(); + }); + } }); }); } @@ -369,12 +317,6 @@ function getAllData(srv, iface, callback) { return new Promise((resolve, reject) => { process.nextTick(() => { - if (_windows) { - let error = new Error(NOT_SUPPORTED); - if (callback) { callback(NOT_SUPPORTED) } - reject(error); - } - let data = {}; getStaticData().then(res => { diff --git a/lib/network.js b/lib/network.js index 4108326..2f68d1f 100644 --- a/lib/network.js +++ b/lib/network.js @@ -32,9 +32,11 @@ function getDefaultNetworkInterface() { if (!_default_iface) { let ifacename = ''; - let cmd = (_linux ? "route 2>/dev/null | grep default | awk '{print $8}'" : "route get 0.0.0.0 2>/dev/null | grep interface: | awk '{print $2}'"); - let result = execSync(cmd); - ifacename = result.toString().split('\n')[0]; + if (_linux || _darwin) { + let cmd = (_linux ? "route 2>/dev/null | grep default | awk '{print $8}'" : "route get 0.0.0.0 2>/dev/null | grep interface: | awk '{print $2}'"); + let result = execSync(cmd); + ifacename = result.toString().split('\n')[0]; + } if (!ifacename) { // fallback - "first" external interface const sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {}); diff --git a/lib/osinfo.js b/lib/osinfo.js index 855ecc1..a32dccf 100644 --- a/lib/osinfo.js +++ b/lib/osinfo.js @@ -28,9 +28,13 @@ const NOT_SUPPORTED = 'not supported'; // Get current time and OS uptime function time() { + let t = new Date().toString().split(' '); + return { current: Date.now(), - uptime: os.uptime() + uptime: os.uptime(), + timezone: (t.length >= 7) ? t[5] : '', + timezoneName: (t.length >= 7) ? t.slice(6).join(' ').replace(/\(/g, '').replace(/\)/g, '') : '' }; }