extended time (timezone), extended windows support (battery, getAll...)

This commit is contained in:
Sebastian Hildebrandt 2017-06-18 09:43:32 +02:00
parent 8c4dc426a2
commit a41ddc6d1f
6 changed files with 117 additions and 142 deletions

View File

@ -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 |

View File

@ -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)

View File

@ -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);
});
}
});
});
};

View File

@ -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 => {

View File

@ -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), {});

View File

@ -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, '') : ''
};
}