Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

battery.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. 'use strict';
  2. // @ts-check;
  3. // ==================================================================================
  4. // battery.js
  5. // ----------------------------------------------------------------------------------
  6. // Description: System Information - library
  7. // for Node.js
  8. // Copyright: (c) 2014 - 2020
  9. // Author: Sebastian Hildebrandt
  10. // ----------------------------------------------------------------------------------
  11. // License: MIT
  12. // ==================================================================================
  13. // 6. Battery
  14. // ----------------------------------------------------------------------------------
  15. const exec = require('child_process').exec;
  16. const fs = require('fs');
  17. const util = require('./util');
  18. let _platform = process.platform;
  19. const _linux = (_platform === 'linux');
  20. const _darwin = (_platform === 'darwin');
  21. const _windows = (_platform === 'win32');
  22. const _freebsd = (_platform === 'freebsd');
  23. const _openbsd = (_platform === 'openbsd');
  24. const _netbsd = (_platform === 'netbsd');
  25. const _sunos = (_platform === 'sunos');
  26. module.exports = function (callback) {
  27. return new Promise((resolve) => {
  28. process.nextTick(() => {
  29. let result = {
  30. hasbattery: false,
  31. cyclecount: 0,
  32. ischarging: false,
  33. designedcapacity: 0,
  34. maxcapacity: 0,
  35. currentcapacity: 0,
  36. voltage: 0,
  37. capacityUnit: '',
  38. percent: 0,
  39. timeremaining: -1,
  40. acconnected: true,
  41. type: '',
  42. model: '',
  43. manufacturer: '',
  44. serial: ''
  45. };
  46. if (_linux) {
  47. let battery_path = '';
  48. if (fs.existsSync('/sys/class/power_supply/BAT1/uevent')) {
  49. battery_path = '/sys/class/power_supply/BAT1/';
  50. } else if (fs.existsSync('/sys/class/power_supply/BAT0/uevent')) {
  51. battery_path = '/sys/class/power_supply/BAT0/';
  52. }
  53. if (battery_path) {
  54. fs.readFile(battery_path + 'uevent', function (error, stdout) {
  55. if (!error) {
  56. let lines = stdout.toString().split('\n');
  57. result.ischarging = (util.getValue(lines, 'POWER_SUPPLY_STATUS', '=').toLowerCase() === 'charging');
  58. result.acconnected = result.ischarging;
  59. result.voltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_NOW', '='), 10) / 1000000.0;
  60. result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
  61. result.cyclecount = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CYCLE_COUNT', '='), 10);
  62. result.maxcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '='), 10) / 1000.0 / (result.voltage || 1));
  63. result.designedcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '='), 10) / 1000.0 / (result.voltage || 1)) | result.maxcapacity;
  64. result.currentcapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10) / 1000.0 / (result.voltage || 1));
  65. if (!result.maxcapacity) {
  66. result.maxcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '='), 10) / 1000.0;
  67. result.designcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', '='), 10) / 1000.0 | result.maxcapacity;
  68. result.currentcapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10) / 1000.0;
  69. }
  70. const percent = util.getValue(lines, 'POWER_SUPPLY_CAPACITY', '=');
  71. const energy = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10);
  72. const power = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_POWER_NOW', '='), 10);
  73. const current = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CURRENT_NOW', '='), 10);
  74. result.percent = parseInt('0' + percent, 10);
  75. if (result.maxcapacity && result.currentcapacity) {
  76. result.hasbattery = true;
  77. if (!percent) {
  78. result.percent = 100.0 * result.currentcapacity / result.maxcapacity;
  79. }
  80. }
  81. if (result.ischarging) {
  82. result.hasbattery = true;
  83. }
  84. if (energy && power) {
  85. result.timeremaining = Math.floor(energy / power * 60);
  86. } else if (current && result.currentcapacity) {
  87. result.timeremaining = Math.floor(result.currentcapacity / current * 60);
  88. }
  89. result.type = util.getValue(lines, 'POWER_SUPPLY_TECHNOLOGY', '=');
  90. result.model = util.getValue(lines, 'POWER_SUPPLY_MODEL_NAME', '=');
  91. result.manufacturer = util.getValue(lines, 'POWER_SUPPLY_MANUFACTURER', '=');
  92. result.serial = util.getValue(lines, 'POWER_SUPPLY_SERIAL_NUMBER', '=');
  93. if (callback) { callback(result); }
  94. resolve(result);
  95. } else {
  96. if (callback) { callback(result); }
  97. resolve(result);
  98. }
  99. });
  100. } else {
  101. if (callback) { callback(result); }
  102. resolve(result);
  103. }
  104. }
  105. if (_freebsd || _openbsd || _netbsd) {
  106. exec('sysctl hw.acpi.battery hw.acpi.acline', function (error, stdout) {
  107. let lines = stdout.toString().split('\n');
  108. const batteries = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.units'), 10);
  109. const percent = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.life'), 10);
  110. result.hasbattery = (batteries > 0);
  111. result.cyclecount = -1;
  112. result.ischarging = util.getValue(lines, 'hw.acpi.acline') !== '1';
  113. result.acconnected = result.ischarging;
  114. result.maxcapacity = -1;
  115. result.currentcapacity = -1;
  116. result.capacityUnit = 'unknown';
  117. result.percent = batteries ? percent : -1;
  118. if (callback) { callback(result); }
  119. resolve(result);
  120. });
  121. }
  122. if (_darwin) {
  123. exec('ioreg -n AppleSmartBattery -r | egrep "CycleCount|IsCharging|DesignCapacity|MaxCapacity|CurrentCapacity|BatterySerialNumber|TimeRemaining|Voltage"; pmset -g batt | grep %', function (error, stdout) {
  124. if (stdout) {
  125. let lines = stdout.toString().replace(/ +/g, '').replace(/"+/g, '').replace(/-/g, '').split('\n');
  126. result.cyclecount = parseInt('0' + util.getValue(lines, 'cyclecount', '='), 10);
  127. result.voltage = parseInt('0' + util.getValue(lines, 'voltage', '='), 10) / 1000.0;
  128. result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
  129. result.maxcapacity = Math.round(parseInt('0' + util.getValue(lines, 'maxcapacity', '='), 10) * (result.voltage || 1));
  130. result.currentcapacity = Math.round(parseInt('0' + util.getValue(lines, 'currentcapacity', '='), 10) * (result.voltage || 1));
  131. result.designedcapacity = Math.round(parseInt('0' + util.getValue(lines, 'DesignCapacity', '='), 10) * (result.voltage || 1));
  132. result.manufacturer = 'Apple';
  133. result.serial = util.getValue(lines, 'BatterySerialNumber', '=');
  134. let percent = -1;
  135. const line = util.getValue(lines, 'internal', 'Battery');
  136. let parts = line.split(';');
  137. if (parts && parts[0]) {
  138. let parts2 = parts[0].split('\t');
  139. if (parts2 && parts2[1]) {
  140. percent = parseFloat(parts2[1].trim().replace(/%/g, ''));
  141. }
  142. }
  143. if (parts && parts[1]) {
  144. result.ischarging = (parts[1].trim() === 'charging');
  145. result.acconnected = (parts[1].trim() !== 'discharging');
  146. } else {
  147. result.ischarging = util.getValue(lines, 'ischarging', '=').toLowerCase() === 'yes';
  148. result.acconnected = result.ischarging;
  149. }
  150. if (result.maxcapacity && result.currentcapacity) {
  151. result.hasbattery = true;
  152. result.type = 'Li-ion';
  153. result.percent = percent !== -1 ? percent : Math.round(100.0 * result.currentcapacity / result.maxcapacity);
  154. if (!result.ischarging) {
  155. result.timeremaining = parseInt('0' + util.getValue(lines, 'TimeRemaining', '='), 10);
  156. }
  157. }
  158. }
  159. if (callback) { callback(result); }
  160. resolve(result);
  161. });
  162. }
  163. if (_sunos) {
  164. if (callback) { callback(result); }
  165. resolve(result);
  166. }
  167. if (_windows) {
  168. try {
  169. util.wmic('Path Win32_Battery Get BatteryStatus, DesignCapacity, EstimatedChargeRemaining, DesignVoltage, FullChargeCapacity /value').then((stdout) => {
  170. if (stdout) {
  171. let lines = stdout.split('\r\n');
  172. let status = util.getValue(lines, 'BatteryStatus', '=').trim();
  173. // 1 = "Discharging"
  174. // 2 = "On A/C"
  175. // 3 = "Fully Charged"
  176. // 4 = "Low"
  177. // 5 = "Critical"
  178. // 6 = "Charging"
  179. // 7 = "Charging High"
  180. // 8 = "Charging Low"
  181. // 9 = "Charging Critical"
  182. // 10 = "Undefined"
  183. // 11 = "Partially Charged"
  184. if (status && status != '10') {
  185. const statusValue = parseInt(status);
  186. result.hasbattery = true;
  187. result.maxcapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0);
  188. result.designcapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0);
  189. result.voltage = parseInt(util.getValue(lines, 'DesignVoltage', '=') || 0) / 1000.0;
  190. result.capacityUnit = 'mWh';
  191. result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', '=') || 0);
  192. result.currentcapacity = parseInt(result.maxcapacity * result.percent / 100);
  193. result.ischarging = (statusValue >= 6 && statusValue <= 9) || statusValue === 11 || (!(statusValue === 3) && !(statusValue === 1) && result.percent < 100);
  194. result.acconnected = result.ischarging || statusValue === 2;
  195. }
  196. }
  197. if (callback) { callback(result); }
  198. resolve(result);
  199. });
  200. } catch (e) {
  201. if (callback) { callback(result); }
  202. resolve(result);
  203. }
  204. }
  205. });
  206. });
  207. };