diff --git a/lib/battery.js b/lib/battery.js index 0102bb9..c01eb00 100644 --- a/lib/battery.js +++ b/lib/battery.js @@ -27,6 +27,40 @@ const _openbsd = (_platform === 'openbsd'); const _netbsd = (_platform === 'netbsd'); const _sunos = (_platform === 'sunos'); +function parseWinBatteryPart(lines, designCapacity, fullChargeCapacity) { + const result = {}; + let status = util.getValue(lines, 'BatteryStatus', '=').trim(); + // 1 = "Discharging" + // 2 = "On A/C" + // 3 = "Fully Charged" + // 4 = "Low" + // 5 = "Critical" + // 6 = "Charging" + // 7 = "Charging High" + // 8 = "Charging Low" + // 9 = "Charging Critical" + // 10 = "Undefined" + // 11 = "Partially Charged" + if (lines.join('').toLowerCase().indexOf('BatteryStatus') >= 0) { + const statusValue = status ? parseInt(status) : 0; + result.status = statusValue; + result.hasBattery = true; + result.maxCapacity = fullChargeCapacity || parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0); + result.designCapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || designCapacity); + result.voltage = parseInt(util.getValue(lines, 'DesignVoltage', '=') || 0) / 1000.0; + result.capacityUnit = 'mWh'; + result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', '=') || 0); + result.currentCapacity = parseInt(result.maxcapacity * result.percent / 100); + result.isCharging = (statusValue >= 6 && statusValue <= 9) || statusValue === 11 || (!(statusValue === 3) && !(statusValue === 1) && result.percent < 100); + result.acConnected = result.ischarging || statusValue === 2; + result.model = util.getValue(lines, 'DeviceID', '='); + } else { + result.status = -1; + } + + return result; +} + module.exports = function (callback) { return new Promise((resolve) => { @@ -175,32 +209,65 @@ module.exports = function (callback) { } if (_windows) { try { - util.wmic('Path Win32_Battery Get BatteryStatus, DesignCapacity, EstimatedChargeRemaining, DesignVoltage, FullChargeCapacity /value').then((stdout) => { - if (stdout) { - let lines = stdout.split('\r\n'); - let status = util.getValue(lines, 'BatteryStatus', '=').trim(); - // 1 = "Discharging" - // 2 = "On A/C" - // 3 = "Fully Charged" - // 4 = "Low" - // 5 = "Critical" - // 6 = "Charging" - // 7 = "Charging High" - // 8 = "Charging Low" - // 9 = "Charging Critical" - // 10 = "Undefined" - // 11 = "Partially Charged" - if (status && status != '10') { - const statusValue = parseInt(status); - result.hasBattery = true; - result.maxCapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0); - result.designCapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0); - result.voltage = parseInt(util.getValue(lines, 'DesignVoltage', '=') || 0) / 1000.0; - result.capacityUnit = 'mWh'; - result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', '=') || 0); - result.currentCapacity = parseInt(result.maxcapacity * result.percent / 100); - result.isCharging = (statusValue >= 6 && statusValue <= 9) || statusValue === 11 || (!(statusValue === 3) && !(statusValue === 1) && result.percent < 100); - result.acConnected = result.ischarging || statusValue === 2; + const workload = []; + workload.push(util.wmic('Path Win32_Battery Get /value')); + workload.push(util.powerShell('(Get-WmiObject -Class BatteryStaticData -Namespace ROOT/WMI).DesignedCapacity')); + workload.push(util.powerShell('(Get-WmiObject -Class BatteryFullChargedCapacity -Namespace ROOT/WMI).FullChargedCapacity')); + util.promiseAll( + workload + ).then(data => { + if (data) { + let parts = data.results[0].split(/\n\s*\n/); + let designCapacities = data.results[1].split('\r\n'); + let fullChargeCapacities = data.results[2].split('\r\n'); + if (parts && parts.length) { + let first = false; + let additionalBatteries = []; + for (let i = 0; i < parts.length; i++) { + let lines = parts[i].split('\r\n'); + const designCapacity = designCapacities && designCapacities.length >= (i + 1) && designCapacities[i] ? util.toInt(designCapacities[i]) : 0; + const fullChargeCapacity = fullChargeCapacities && fullChargeCapacities.length >= (i + 1) && fullChargeCapacities[i] ? util.toInt(fullChargeCapacities[i]) : 0; + const parsed = parseWinBatteryPart(lines, designCapacity, fullChargeCapacity); + if (!first && parsed.status > 0 && parsed.status !== 10) { + result.hasBattery = parsed.hasBattery; + result.maxCapacity = parsed.maxCapacity; + result.designCapacity = parsed.designCapacity; + result.voltage = parsed.voltage; + result.capacityUnit = parsed.capacityUnit; + result.percent = parsed.percent; + result.currentCapacity = parsed.currentCapacity; + result.isCharging = parsed.isCharging; + result.acConnected = parsed.acConnected; + result.model = parsed.model; + first = true; + } else if (parsed.status !== -1) { + additionalBatteries.push( + { + hasBattery: parsed.hasBattery, + maxCapacity: parsed.maxCapacity, + designCapacity: parsed.designCapacity, + voltage: parsed.voltage, + capacityUnit: parsed.capacityUnit, + percent: parsed.percent, + currentCapacity: parsed.currentCapacity, + isCharging: parsed.isCharging, + timeRemaining: null, + acConnected: parsed.acConnected, + model: parsed.model, + type: '', + manufacturer: '', + serial: '' + } + ); + } + } + if (!first && additionalBatteries.length) { + result = additionalBatteries[0]; + additionalBatteries.shift(); + } + if (additionalBatteries.length) { + result.additionalBatteries = additionalBatteries; + } } } if (callback) { callback(result); }