123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- 'use strict';
- // @ts-check;
- // ==================================================================================
- // battery.js
- // ----------------------------------------------------------------------------------
- // Description: System Information - library
- // for Node.js
- // Copyright: (c) 2014 - 2020
- // Author: Sebastian Hildebrandt
- // ----------------------------------------------------------------------------------
- // License: MIT
- // ==================================================================================
- // 6. Battery
- // ----------------------------------------------------------------------------------
-
- const exec = require('child_process').exec;
- const fs = require('fs');
- const util = require('./util');
-
- let _platform = process.platform;
-
- const _linux = (_platform === 'linux');
- const _darwin = (_platform === 'darwin');
- const _windows = (_platform === 'win32');
- const _freebsd = (_platform === 'freebsd');
- const _openbsd = (_platform === 'openbsd');
- const _netbsd = (_platform === 'netbsd');
- const _sunos = (_platform === 'sunos');
-
- module.exports = function (callback) {
-
- return new Promise((resolve) => {
- process.nextTick(() => {
- let result = {
- hasbattery: false,
- cyclecount: 0,
- ischarging: false,
- designedcapacity: 0,
- maxcapacity: 0,
- currentcapacity: 0,
- voltage: 0,
- capacityUnit: '',
- percent: 0,
- timeremaining: -1,
- acconnected: true,
- type: '',
- model: '',
- manufacturer: '',
- serial: ''
- };
-
- if (_linux) {
- let battery_path = '';
- if (fs.existsSync('/sys/class/power_supply/BAT1/uevent')) {
- battery_path = '/sys/class/power_supply/BAT1/';
- } else if (fs.existsSync('/sys/class/power_supply/BAT0/uevent')) {
- battery_path = '/sys/class/power_supply/BAT0/';
- }
- if (battery_path) {
- fs.readFile(battery_path + 'uevent', function (error, stdout) {
- if (!error) {
- let lines = stdout.toString().split('\n');
-
- result.ischarging = (util.getValue(lines, 'POWER_SUPPLY_STATUS', '=').toLowerCase() === 'charging');
- result.acconnected = result.ischarging;
- result.voltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_NOW', '='), 10) / 1000000.0;
- result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
- result.cyclecount = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CYCLE_COUNT', '='), 10);
- result.maxcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '='), 10) / 1000.0 / (result.voltage || 1));
- result.designedcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '='), 10) / 1000.0 / (result.voltage || 1)) | result.maxcapacity;
- result.currentcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10) / 1000.0 / (result.voltage || 1));
- if (!result.maxcapacity) {
- result.maxcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '='), 10) / 1000.0;
- result.designcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', '='), 10) / 1000.0 | result.maxcapacity;
- result.currentcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10) / 1000.0;
- }
- const percent = util.getValue(lines, 'POWER_SUPPLY_CAPACITY', '=');
- const energy = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10);
- const power = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_POWER_NOW', '='), 10);
- const current = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CURRENT_NOW', '='), 10);
-
- result.percent = parseInt('0' + percent, 10);
- if (result.maxcapacity && result.currentcapacity) {
- result.hasbattery = true;
- if (!percent) {
- result.percent = 100.0 * result.currentcapacity / result.maxcapacity;
- }
- }
- if (result.ischarging) {
- result.hasbattery = true;
- }
- if (energy && power) {
- result.timeremaining = Math.floor(energy / power * 60);
- } else if (current && result.currentcapacity) {
- result.timeremaining = Math.floor(result.currentcapacity / current * 60);
- }
- result.type = util.getValue(lines, 'POWER_SUPPLY_TECHNOLOGY', '=');
- result.model = util.getValue(lines, 'POWER_SUPPLY_MODEL_NAME', '=');
- result.manufacturer = util.getValue(lines, 'POWER_SUPPLY_MANUFACTURER', '=');
- result.serial = util.getValue(lines, 'POWER_SUPPLY_SERIAL_NUMBER', '=');
- if (callback) { callback(result); }
- resolve(result);
- } else {
- if (callback) { callback(result); }
- resolve(result);
- }
- });
- } else {
- if (callback) { callback(result); }
- resolve(result);
- }
- }
- if (_freebsd || _openbsd || _netbsd) {
- exec('sysctl hw.acpi.battery hw.acpi.acline', function (error, stdout) {
- let lines = stdout.toString().split('\n');
- const batteries = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.units'), 10);
- const percent = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.life'), 10);
- result.hasbattery = (batteries > 0);
- result.cyclecount = -1;
- result.ischarging = util.getValue(lines, 'hw.acpi.acline') !== '1';
- result.acconnected = result.ischarging;
- result.maxcapacity = -1;
- result.currentcapacity = -1;
- result.capacityUnit = 'unknown';
- result.percent = batteries ? percent : -1;
- if (callback) { callback(result); }
- resolve(result);
- });
- }
-
- if (_darwin) {
- exec('ioreg -n AppleSmartBattery -r | egrep "CycleCount|IsCharging|DesignCapacity|MaxCapacity|CurrentCapacity|BatterySerialNumber|TimeRemaining|Voltage"; pmset -g batt | grep %', function (error, stdout) {
- if (stdout) {
- let lines = stdout.toString().replace(/ +/g, '').replace(/"+/g, '').replace(/-/g, '').split('\n');
- result.cyclecount = parseInt('0' + util.getValue(lines, 'cyclecount', '='), 10);
- result.voltage = parseInt('0' + util.getValue(lines, 'voltage', '='), 10) / 1000.0;
- result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
- result.maxcapacity = Math.round(parseInt('0' + util.getValue(lines, 'maxcapacity', '='), 10) * (result.voltage || 1));
- result.currentcapacity = Math.round(parseInt('0' + util.getValue(lines, 'currentcapacity', '='), 10) * (result.voltage || 1));
- result.designedcapacity = Math.round(parseInt('0' + util.getValue(lines, 'DesignCapacity', '='), 10) * (result.voltage || 1));
- result.manufacturer = 'Apple';
- result.serial = util.getValue(lines, 'BatterySerialNumber', '=');
- let percent = -1;
- const line = util.getValue(lines, 'internal', 'Battery');
- let parts = line.split(';');
- if (parts && parts[0]) {
- let parts2 = parts[0].split('\t');
- if (parts2 && parts2[1]) {
- percent = parseFloat(parts2[1].trim().replace(/%/g, ''));
- }
- }
- if (parts && parts[1]) {
- result.ischarging = (parts[1].trim() === 'charging');
- result.acconnected = (parts[1].trim() !== 'discharging');
- } else {
- result.ischarging = util.getValue(lines, 'ischarging', '=').toLowerCase() === 'yes';
- result.acconnected = result.ischarging;
- }
- if (result.maxcapacity && result.currentcapacity) {
- result.hasbattery = true;
- result.type = 'Li-ion';
- result.percent = percent !== -1 ? percent : Math.round(100.0 * result.currentcapacity / result.maxcapacity);
- if (!result.ischarging) {
- result.timeremaining = parseInt('0' + util.getValue(lines, 'TimeRemaining', '='), 10);
- }
- }
- }
- if (callback) { callback(result); }
- resolve(result);
- });
- }
- if (_sunos) {
- if (callback) { callback(result); }
- resolve(result);
- }
- 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;
- }
- }
- if (callback) { callback(result); }
- resolve(result);
- });
- } catch (e) {
- if (callback) { callback(result); }
- resolve(result);
- }
- }
- });
- });
- };
|