@depup/systeminformation 5.31.4-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/lib/audio.js +276 -0
- package/lib/battery.js +330 -0
- package/lib/bluetooth.js +311 -0
- package/lib/bluetoothVendors.js +1138 -0
- package/lib/cli.js +100 -0
- package/lib/cpu.js +2237 -0
- package/lib/docker.js +803 -0
- package/lib/dockerSocket.js +322 -0
- package/lib/filesystem.js +1745 -0
- package/lib/graphics.js +1235 -0
- package/lib/index.d.ts +1053 -0
- package/lib/index.js +518 -0
- package/lib/internet.js +259 -0
- package/lib/memory.js +613 -0
- package/lib/network.js +2022 -0
- package/lib/osinfo.js +1303 -0
- package/lib/printer.js +209 -0
- package/lib/processes.js +1425 -0
- package/lib/system.js +856 -0
- package/lib/usb.js +313 -0
- package/lib/users.js +412 -0
- package/lib/util.js +2760 -0
- package/lib/virtualbox.js +110 -0
- package/lib/wifi.js +843 -0
- package/package.json +115 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014-2026 Sebastian Hildebrandt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @depup/systeminformation
|
|
2
|
+
|
|
3
|
+
> Dependency-bumped version of [systeminformation](https://www.npmjs.com/package/systeminformation)
|
|
4
|
+
|
|
5
|
+
Generated by [DepUp](https://github.com/depup/npm) -- all production
|
|
6
|
+
dependencies bumped to latest versions.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @depup/systeminformation
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Field | Value |
|
|
15
|
+
|-------|-------|
|
|
16
|
+
| Original | [systeminformation](https://www.npmjs.com/package/systeminformation) @ 5.31.4 |
|
|
17
|
+
| Processed | 2026-03-17 |
|
|
18
|
+
| Smoke test | passed |
|
|
19
|
+
| Deps updated | 0 |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
Source: https://github.com/depup/npm | Original: https://www.npmjs.com/package/systeminformation
|
|
24
|
+
|
|
25
|
+
License inherited from the original package.
|
package/changes.json
ADDED
package/lib/audio.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// @ts-check
|
|
3
|
+
// ==================================================================================
|
|
4
|
+
// audio.js
|
|
5
|
+
// ----------------------------------------------------------------------------------
|
|
6
|
+
// Description: System Information - library
|
|
7
|
+
// for Node.js
|
|
8
|
+
// Copyright: (c) 2014 - 2026
|
|
9
|
+
// Author: Sebastian Hildebrandt
|
|
10
|
+
// ----------------------------------------------------------------------------------
|
|
11
|
+
// License: MIT
|
|
12
|
+
// ==================================================================================
|
|
13
|
+
// 16. audio
|
|
14
|
+
// ----------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
const exec = require('child_process').exec;
|
|
17
|
+
const execSync = require('child_process').execSync;
|
|
18
|
+
const util = require('./util');
|
|
19
|
+
|
|
20
|
+
const _platform = process.platform;
|
|
21
|
+
|
|
22
|
+
const _linux = _platform === 'linux' || _platform === 'android';
|
|
23
|
+
const _darwin = _platform === 'darwin';
|
|
24
|
+
const _windows = _platform === 'win32';
|
|
25
|
+
const _freebsd = _platform === 'freebsd';
|
|
26
|
+
const _openbsd = _platform === 'openbsd';
|
|
27
|
+
const _netbsd = _platform === 'netbsd';
|
|
28
|
+
const _sunos = _platform === 'sunos';
|
|
29
|
+
|
|
30
|
+
function parseAudioType(str, input, output) {
|
|
31
|
+
str = str.toLowerCase();
|
|
32
|
+
let result = '';
|
|
33
|
+
|
|
34
|
+
if (str.indexOf('input') >= 0) {
|
|
35
|
+
result = 'Microphone';
|
|
36
|
+
}
|
|
37
|
+
if (str.indexOf('display audio') >= 0) {
|
|
38
|
+
result = 'Speaker';
|
|
39
|
+
}
|
|
40
|
+
if (str.indexOf('speak') >= 0) {
|
|
41
|
+
result = 'Speaker';
|
|
42
|
+
}
|
|
43
|
+
if (str.indexOf('laut') >= 0) {
|
|
44
|
+
result = 'Speaker';
|
|
45
|
+
}
|
|
46
|
+
if (str.indexOf('loud') >= 0) {
|
|
47
|
+
result = 'Speaker';
|
|
48
|
+
}
|
|
49
|
+
if (str.indexOf('head') >= 0) {
|
|
50
|
+
result = 'Headset';
|
|
51
|
+
}
|
|
52
|
+
if (str.indexOf('mic') >= 0) {
|
|
53
|
+
result = 'Microphone';
|
|
54
|
+
}
|
|
55
|
+
if (str.indexOf('mikr') >= 0) {
|
|
56
|
+
result = 'Microphone';
|
|
57
|
+
}
|
|
58
|
+
if (str.indexOf('phone') >= 0) {
|
|
59
|
+
result = 'Phone';
|
|
60
|
+
}
|
|
61
|
+
if (str.indexOf('controll') >= 0) {
|
|
62
|
+
result = 'Controller';
|
|
63
|
+
}
|
|
64
|
+
if (str.indexOf('line o') >= 0) {
|
|
65
|
+
result = 'Line Out';
|
|
66
|
+
}
|
|
67
|
+
if (str.indexOf('digital o') >= 0) {
|
|
68
|
+
result = 'Digital Out';
|
|
69
|
+
}
|
|
70
|
+
if (str.indexOf('smart sound technology') >= 0) {
|
|
71
|
+
result = 'Digital Signal Processor';
|
|
72
|
+
}
|
|
73
|
+
if (str.indexOf('high definition audio') >= 0) {
|
|
74
|
+
result = 'Sound Driver';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!result && output) {
|
|
78
|
+
result = 'Speaker';
|
|
79
|
+
} else if (!result && input) {
|
|
80
|
+
result = 'Microphone';
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getLinuxAudioPci() {
|
|
86
|
+
const cmd = 'lspci -v 2>/dev/null';
|
|
87
|
+
const result = [];
|
|
88
|
+
try {
|
|
89
|
+
const parts = execSync(cmd, util.execOptsLinux).toString().split('\n\n');
|
|
90
|
+
parts.forEach((element) => {
|
|
91
|
+
const lines = element.split('\n');
|
|
92
|
+
if (lines && lines.length && lines[0].toLowerCase().indexOf('audio') >= 0) {
|
|
93
|
+
const audio = {};
|
|
94
|
+
audio.slotId = lines[0].split(' ')[0];
|
|
95
|
+
audio.driver = util.getValue(lines, 'Kernel driver in use', ':', true) || util.getValue(lines, 'Kernel modules', ':', true);
|
|
96
|
+
result.push(audio);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return result;
|
|
100
|
+
} catch {
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parseWinAudioStatus(n) {
|
|
106
|
+
let status = n;
|
|
107
|
+
if (n === 1) {
|
|
108
|
+
status = 'other';
|
|
109
|
+
} else if (n === 2) {
|
|
110
|
+
status = 'unknown';
|
|
111
|
+
} else if (n === 3) {
|
|
112
|
+
status = 'enabled';
|
|
113
|
+
} else if (n === 4) {
|
|
114
|
+
status = 'disabled';
|
|
115
|
+
} else if (n === 5) {
|
|
116
|
+
status = 'not applicable';
|
|
117
|
+
}
|
|
118
|
+
return status;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function parseLinuxAudioPciMM(lines, audioPCI) {
|
|
122
|
+
const result = {};
|
|
123
|
+
const slotId = util.getValue(lines, 'Slot');
|
|
124
|
+
|
|
125
|
+
const pciMatch = audioPCI.filter((item) => item.slotId === slotId);
|
|
126
|
+
|
|
127
|
+
result.id = slotId;
|
|
128
|
+
result.name = util.getValue(lines, 'SDevice');
|
|
129
|
+
result.manufacturer = util.getValue(lines, 'SVendor');
|
|
130
|
+
result.revision = util.getValue(lines, 'Rev');
|
|
131
|
+
result.driver = pciMatch && pciMatch.length === 1 && pciMatch[0].driver ? pciMatch[0].driver : '';
|
|
132
|
+
result.default = null;
|
|
133
|
+
result.channel = 'PCIe';
|
|
134
|
+
result.type = parseAudioType(result.name, null, null);
|
|
135
|
+
result.in = null;
|
|
136
|
+
result.out = null;
|
|
137
|
+
result.status = 'online';
|
|
138
|
+
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function parseDarwinChannel(str) {
|
|
143
|
+
let result = '';
|
|
144
|
+
|
|
145
|
+
if (str.indexOf('builtin') >= 0) {
|
|
146
|
+
result = 'Built-In';
|
|
147
|
+
}
|
|
148
|
+
if (str.indexOf('extern') >= 0) {
|
|
149
|
+
result = 'Audio-Jack';
|
|
150
|
+
}
|
|
151
|
+
if (str.indexOf('hdmi') >= 0) {
|
|
152
|
+
result = 'HDMI';
|
|
153
|
+
}
|
|
154
|
+
if (str.indexOf('displayport') >= 0) {
|
|
155
|
+
result = 'Display-Port';
|
|
156
|
+
}
|
|
157
|
+
if (str.indexOf('usb') >= 0) {
|
|
158
|
+
result = 'USB';
|
|
159
|
+
}
|
|
160
|
+
if (str.indexOf('pci') >= 0) {
|
|
161
|
+
result = 'PCIe';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function parseDarwinAudio(audioObject, id) {
|
|
168
|
+
const result = {};
|
|
169
|
+
const channelStr = ((audioObject.coreaudio_device_transport || '') + ' ' + (audioObject._name || '')).toLowerCase();
|
|
170
|
+
|
|
171
|
+
result.id = id;
|
|
172
|
+
result.name = audioObject._name;
|
|
173
|
+
result.manufacturer = audioObject.coreaudio_device_manufacturer;
|
|
174
|
+
result.revision = null;
|
|
175
|
+
result.driver = null;
|
|
176
|
+
result.default = !!(audioObject.coreaudio_default_audio_input_device || '') || !!(audioObject.coreaudio_default_audio_output_device || '');
|
|
177
|
+
result.channel = parseDarwinChannel(channelStr);
|
|
178
|
+
result.type = parseAudioType(result.name, !!(audioObject.coreaudio_device_input || ''), !!(audioObject.coreaudio_device_output || ''));
|
|
179
|
+
result.in = !!(audioObject.coreaudio_device_input || '');
|
|
180
|
+
result.out = !!(audioObject.coreaudio_device_output || '');
|
|
181
|
+
result.status = 'online';
|
|
182
|
+
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function parseWindowsAudio(lines) {
|
|
187
|
+
const result = {};
|
|
188
|
+
const status = parseWinAudioStatus(util.getValue(lines, 'StatusInfo', ':'));
|
|
189
|
+
|
|
190
|
+
result.id = util.getValue(lines, 'DeviceID', ':'); // PNPDeviceID??
|
|
191
|
+
result.name = util.getValue(lines, 'name', ':');
|
|
192
|
+
result.manufacturer = util.getValue(lines, 'manufacturer', ':');
|
|
193
|
+
result.revision = null;
|
|
194
|
+
result.driver = null;
|
|
195
|
+
result.default = null;
|
|
196
|
+
result.channel = null;
|
|
197
|
+
result.type = parseAudioType(result.name, null, null);
|
|
198
|
+
result.in = null;
|
|
199
|
+
result.out = null;
|
|
200
|
+
result.status = status;
|
|
201
|
+
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function audio(callback) {
|
|
206
|
+
return new Promise((resolve) => {
|
|
207
|
+
process.nextTick(() => {
|
|
208
|
+
const result = [];
|
|
209
|
+
if (_linux || _freebsd || _openbsd || _netbsd) {
|
|
210
|
+
const cmd = 'lspci -vmm 2>/dev/null';
|
|
211
|
+
exec(cmd, (error, stdout) => {
|
|
212
|
+
// PCI
|
|
213
|
+
if (!error) {
|
|
214
|
+
const audioPCI = getLinuxAudioPci();
|
|
215
|
+
const parts = stdout.toString().split('\n\n');
|
|
216
|
+
parts.forEach((element) => {
|
|
217
|
+
const lines = element.split('\n');
|
|
218
|
+
if (util.getValue(lines, 'class', ':', true).toLowerCase().indexOf('audio') >= 0) {
|
|
219
|
+
const audio = parseLinuxAudioPciMM(lines, audioPCI);
|
|
220
|
+
result.push(audio);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (callback) {
|
|
225
|
+
callback(result);
|
|
226
|
+
}
|
|
227
|
+
resolve(result);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (_darwin) {
|
|
231
|
+
const cmd = 'system_profiler SPAudioDataType -json';
|
|
232
|
+
exec(cmd, (error, stdout) => {
|
|
233
|
+
if (!error) {
|
|
234
|
+
try {
|
|
235
|
+
const outObj = JSON.parse(stdout.toString());
|
|
236
|
+
if (outObj.SPAudioDataType && outObj.SPAudioDataType.length && outObj.SPAudioDataType[0] && outObj.SPAudioDataType[0]['_items'] && outObj.SPAudioDataType[0]['_items'].length) {
|
|
237
|
+
for (let i = 0; i < outObj.SPAudioDataType[0]['_items'].length; i++) {
|
|
238
|
+
const audio = parseDarwinAudio(outObj.SPAudioDataType[0]['_items'][i], i);
|
|
239
|
+
result.push(audio);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} catch {
|
|
243
|
+
util.noop();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (callback) {
|
|
247
|
+
callback(result);
|
|
248
|
+
}
|
|
249
|
+
resolve(result);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (_windows) {
|
|
253
|
+
util.powerShell('Get-CimInstance Win32_SoundDevice | select DeviceID,StatusInfo,Name,Manufacturer | fl').then((stdout, error) => {
|
|
254
|
+
if (!error) {
|
|
255
|
+
const parts = stdout.toString().split(/\n\s*\n/);
|
|
256
|
+
parts.forEach((element) => {
|
|
257
|
+
const lines = element.split('\n');
|
|
258
|
+
if (util.getValue(lines, 'name', ':')) {
|
|
259
|
+
result.push(parseWindowsAudio(lines));
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (callback) {
|
|
264
|
+
callback(result);
|
|
265
|
+
}
|
|
266
|
+
resolve(result);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (_sunos) {
|
|
270
|
+
resolve(null);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
exports.audio = audio;
|
package/lib/battery.js
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// @ts-check;
|
|
3
|
+
// ==================================================================================
|
|
4
|
+
// battery.js
|
|
5
|
+
// ----------------------------------------------------------------------------------
|
|
6
|
+
// Description: System Information - library
|
|
7
|
+
// for Node.js
|
|
8
|
+
// Copyright: (c) 2014 - 2026
|
|
9
|
+
// Author: Sebastian Hildebrandt
|
|
10
|
+
// ----------------------------------------------------------------------------------
|
|
11
|
+
// License: MIT
|
|
12
|
+
// ==================================================================================
|
|
13
|
+
// 6. Battery
|
|
14
|
+
// ----------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
const exec = require('child_process').exec;
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const util = require('./util');
|
|
19
|
+
|
|
20
|
+
const _platform = process.platform;
|
|
21
|
+
|
|
22
|
+
const _linux = _platform === 'linux' || _platform === 'android';
|
|
23
|
+
const _darwin = _platform === 'darwin';
|
|
24
|
+
const _windows = _platform === 'win32';
|
|
25
|
+
const _freebsd = _platform === 'freebsd';
|
|
26
|
+
const _openbsd = _platform === 'openbsd';
|
|
27
|
+
const _netbsd = _platform === 'netbsd';
|
|
28
|
+
const _sunos = _platform === 'sunos';
|
|
29
|
+
|
|
30
|
+
function parseWinBatteryPart(lines, designedCapacity, fullChargeCapacity) {
|
|
31
|
+
const result = {};
|
|
32
|
+
let status = parseInt(util.getValue(lines, 'BatteryStatus', ':').trim(), 10) || 0;
|
|
33
|
+
// let status = util.getValue(lines, 'BatteryStatus', ':').trim();
|
|
34
|
+
// 1 = "Discharging"
|
|
35
|
+
// 2 = "On A/C"
|
|
36
|
+
// 3 = "Fully Charged"
|
|
37
|
+
// 4 = "Low"
|
|
38
|
+
// 5 = "Critical"
|
|
39
|
+
// 6 = "Charging"
|
|
40
|
+
// 7 = "Charging High"
|
|
41
|
+
// 8 = "Charging Low"
|
|
42
|
+
// 9 = "Charging Critical"
|
|
43
|
+
// 10 = "Undefined"
|
|
44
|
+
// 11 = "Partially Charged"
|
|
45
|
+
if (status >= 0) {
|
|
46
|
+
const statusValue = status;
|
|
47
|
+
result.status = statusValue;
|
|
48
|
+
result.hasBattery = true;
|
|
49
|
+
result.maxCapacity = fullChargeCapacity || parseInt(util.getValue(lines, 'DesignCapacity', ':') || 0);
|
|
50
|
+
result.designedCapacity = parseInt(util.getValue(lines, 'DesignCapacity', ':') || designedCapacity);
|
|
51
|
+
result.voltage = (parseInt(util.getValue(lines, 'DesignVoltage', ':'), 10) || 0) / 1000;
|
|
52
|
+
result.capacityUnit = 'mWh';
|
|
53
|
+
result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', ':'), 10) || 0;
|
|
54
|
+
result.currentCapacity = parseInt((result.maxCapacity * result.percent) / 100);
|
|
55
|
+
result.isCharging = (statusValue >= 6 && statusValue <= 9) || statusValue === 11 || (statusValue !== 3 && statusValue !== 1 && result.percent < 100);
|
|
56
|
+
result.acConnected = result.isCharging || statusValue === 2;
|
|
57
|
+
result.model = util.getValue(lines, 'DeviceID', ':');
|
|
58
|
+
} else {
|
|
59
|
+
result.status = -1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = (callback) =>
|
|
66
|
+
new Promise((resolve) => {
|
|
67
|
+
process.nextTick(() => {
|
|
68
|
+
let result = {
|
|
69
|
+
hasBattery: false,
|
|
70
|
+
cycleCount: 0,
|
|
71
|
+
isCharging: false,
|
|
72
|
+
designedCapacity: 0,
|
|
73
|
+
maxCapacity: 0,
|
|
74
|
+
currentCapacity: 0,
|
|
75
|
+
voltage: 0,
|
|
76
|
+
capacityUnit: '',
|
|
77
|
+
percent: 0,
|
|
78
|
+
timeRemaining: null,
|
|
79
|
+
acConnected: true,
|
|
80
|
+
type: '',
|
|
81
|
+
model: '',
|
|
82
|
+
manufacturer: '',
|
|
83
|
+
serial: ''
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if (_linux) {
|
|
87
|
+
let battery_path = '';
|
|
88
|
+
if (fs.existsSync('/sys/class/power_supply/BAT1/uevent')) {
|
|
89
|
+
battery_path = '/sys/class/power_supply/BAT1/';
|
|
90
|
+
} else if (fs.existsSync('/sys/class/power_supply/BAT0/uevent')) {
|
|
91
|
+
battery_path = '/sys/class/power_supply/BAT0/';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let acConnected = false;
|
|
95
|
+
let acPath = '';
|
|
96
|
+
if (fs.existsSync('/sys/class/power_supply/AC/online')) {
|
|
97
|
+
acPath = '/sys/class/power_supply/AC/online';
|
|
98
|
+
} else if (fs.existsSync('/sys/class/power_supply/AC0/online')) {
|
|
99
|
+
acPath = '/sys/class/power_supply/AC0/online';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (acPath) {
|
|
103
|
+
const file = fs.readFileSync(acPath);
|
|
104
|
+
acConnected = file.toString().trim() === '1';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (battery_path) {
|
|
108
|
+
fs.readFile(battery_path + 'uevent', (error, stdout) => {
|
|
109
|
+
if (!error) {
|
|
110
|
+
let lines = stdout.toString().split('\n');
|
|
111
|
+
|
|
112
|
+
result.isCharging = util.getValue(lines, 'POWER_SUPPLY_STATUS', '=').toLowerCase() === 'charging';
|
|
113
|
+
result.acConnected = acConnected || result.isCharging;
|
|
114
|
+
result.voltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_NOW', '='), 10) / 1000000.0;
|
|
115
|
+
result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
|
|
116
|
+
result.cycleCount = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CYCLE_COUNT', '='), 10);
|
|
117
|
+
result.maxCapacity = Math.round((parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '=', true, true), 10) / 1000.0) * (result.voltage || 1));
|
|
118
|
+
const desingedMinVoltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_MIN_DESIGN', '='), 10) / 1000000.0;
|
|
119
|
+
result.designedCapacity = Math.round(
|
|
120
|
+
(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '=', true, true), 10) / 1000.0) * (desingedMinVoltage || result.voltage || 1)
|
|
121
|
+
);
|
|
122
|
+
result.currentCapacity = Math.round((parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10) / 1000.0) * (result.voltage || 1));
|
|
123
|
+
if (!result.maxCapacity) {
|
|
124
|
+
result.maxCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '=', true, true), 10) / 1000.0;
|
|
125
|
+
result.designedCapacity = (parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', '=', true, true), 10) / 1000.0) | result.maxCapacity;
|
|
126
|
+
result.currentCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10) / 1000.0;
|
|
127
|
+
}
|
|
128
|
+
const percent = util.getValue(lines, 'POWER_SUPPLY_CAPACITY', '=');
|
|
129
|
+
const energy = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10);
|
|
130
|
+
const power = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_POWER_NOW', '='), 10);
|
|
131
|
+
const current = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CURRENT_NOW', '='), 10);
|
|
132
|
+
const charge = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10);
|
|
133
|
+
|
|
134
|
+
result.percent = parseInt('0' + percent, 10);
|
|
135
|
+
if (result.maxCapacity && result.currentCapacity) {
|
|
136
|
+
result.hasBattery = true;
|
|
137
|
+
if (!percent) {
|
|
138
|
+
result.percent = (100.0 * result.currentCapacity) / result.maxCapacity;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (result.isCharging) {
|
|
142
|
+
result.hasBattery = true;
|
|
143
|
+
}
|
|
144
|
+
if (energy && power) {
|
|
145
|
+
result.timeRemaining = Math.floor((energy / power) * 60);
|
|
146
|
+
} else if (current && charge) {
|
|
147
|
+
result.timeRemaining = Math.floor((charge / current) * 60);
|
|
148
|
+
} else if (current && result.currentCapacity) {
|
|
149
|
+
result.timeRemaining = Math.floor((result.currentCapacity / current) * 60);
|
|
150
|
+
}
|
|
151
|
+
result.type = util.getValue(lines, 'POWER_SUPPLY_TECHNOLOGY', '=');
|
|
152
|
+
result.model = util.getValue(lines, 'POWER_SUPPLY_MODEL_NAME', '=');
|
|
153
|
+
result.manufacturer = util.getValue(lines, 'POWER_SUPPLY_MANUFACTURER', '=');
|
|
154
|
+
result.serial = util.getValue(lines, 'POWER_SUPPLY_SERIAL_NUMBER', '=');
|
|
155
|
+
if (callback) {
|
|
156
|
+
callback(result);
|
|
157
|
+
}
|
|
158
|
+
resolve(result);
|
|
159
|
+
} else {
|
|
160
|
+
if (callback) {
|
|
161
|
+
callback(result);
|
|
162
|
+
}
|
|
163
|
+
resolve(result);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
if (callback) {
|
|
168
|
+
callback(result);
|
|
169
|
+
}
|
|
170
|
+
resolve(result);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (_freebsd || _openbsd || _netbsd) {
|
|
174
|
+
exec('sysctl -i hw.acpi.battery hw.acpi.acline', (error, stdout) => {
|
|
175
|
+
let lines = stdout.toString().split('\n');
|
|
176
|
+
const batteries = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.units'), 10);
|
|
177
|
+
const percent = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.life'), 10);
|
|
178
|
+
result.hasBattery = batteries > 0;
|
|
179
|
+
result.cycleCount = null;
|
|
180
|
+
result.isCharging = util.getValue(lines, 'hw.acpi.acline') !== '1';
|
|
181
|
+
result.acConnected = result.isCharging;
|
|
182
|
+
result.maxCapacity = null;
|
|
183
|
+
result.currentCapacity = null;
|
|
184
|
+
result.capacityUnit = 'unknown';
|
|
185
|
+
result.percent = batteries ? percent : null;
|
|
186
|
+
if (callback) {
|
|
187
|
+
callback(result);
|
|
188
|
+
}
|
|
189
|
+
resolve(result);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (_darwin) {
|
|
194
|
+
exec(
|
|
195
|
+
'ioreg -n AppleSmartBattery -r | egrep "CycleCount|IsCharging|DesignCapacity|MaxCapacity|CurrentCapacity|DeviceName|BatterySerialNumber|Serial|TimeRemaining|Voltage"; pmset -g batt | grep %',
|
|
196
|
+
(error, stdout) => {
|
|
197
|
+
if (stdout) {
|
|
198
|
+
let lines = stdout.toString().replace(/ +/g, '').replace(/"+/g, '').replace(/-/g, '').split('\n');
|
|
199
|
+
result.cycleCount = parseInt('0' + util.getValue(lines, 'cyclecount', '='), 10);
|
|
200
|
+
result.voltage = parseInt('0' + util.getValue(lines, 'voltage', '='), 10) / 1000.0;
|
|
201
|
+
result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
|
|
202
|
+
result.maxCapacity = Math.round(parseInt('0' + util.getValue(lines, 'applerawmaxcapacity', '='), 10) * (result.voltage || 1));
|
|
203
|
+
result.currentCapacity = Math.round(parseInt('0' + util.getValue(lines, 'applerawcurrentcapacity', '='), 10) * (result.voltage || 1));
|
|
204
|
+
result.designedCapacity = Math.round(parseInt('0' + util.getValue(lines, 'DesignCapacity', '='), 10) * (result.voltage || 1));
|
|
205
|
+
result.manufacturer = 'Apple';
|
|
206
|
+
result.serial = util.getValue(lines, 'BatterySerialNumber', '=') || util.getValue(lines, 'Serial', '=');
|
|
207
|
+
result.model = util.getValue(lines, 'DeviceName', '=');
|
|
208
|
+
let percent = null;
|
|
209
|
+
const line = util.getValue(lines, 'internal', 'Battery');
|
|
210
|
+
let parts = line.split(';');
|
|
211
|
+
if (parts && parts[0]) {
|
|
212
|
+
let parts2 = parts[0].split('\t');
|
|
213
|
+
if (parts2 && parts2[1]) {
|
|
214
|
+
percent = parseFloat(parts2[1].trim().replace(/%/g, ''));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (parts && parts[1]) {
|
|
218
|
+
result.isCharging = parts[1].trim() === 'charging';
|
|
219
|
+
result.acConnected = parts[1].trim() !== 'discharging';
|
|
220
|
+
} else {
|
|
221
|
+
result.isCharging = util.getValue(lines, 'ischarging', '=').toLowerCase() === 'yes';
|
|
222
|
+
result.acConnected = result.isCharging;
|
|
223
|
+
}
|
|
224
|
+
if (result.maxCapacity && result.currentCapacity) {
|
|
225
|
+
result.hasBattery = true;
|
|
226
|
+
result.type = 'Li-ion';
|
|
227
|
+
result.percent = percent !== null ? percent : Math.round((100.0 * result.currentCapacity) / result.maxCapacity);
|
|
228
|
+
if (!result.isCharging) {
|
|
229
|
+
result.timeRemaining = parseInt('0' + util.getValue(lines, 'TimeRemaining', '='), 10);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (callback) {
|
|
234
|
+
callback(result);
|
|
235
|
+
}
|
|
236
|
+
resolve(result);
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
if (_sunos) {
|
|
241
|
+
if (callback) {
|
|
242
|
+
callback(result);
|
|
243
|
+
}
|
|
244
|
+
resolve(result);
|
|
245
|
+
}
|
|
246
|
+
if (_windows) {
|
|
247
|
+
try {
|
|
248
|
+
const workload = [];
|
|
249
|
+
workload.push(util.powerShell('Get-CimInstance Win32_Battery | select BatteryStatus, DesignCapacity, DesignVoltage, EstimatedChargeRemaining, DeviceID | fl'));
|
|
250
|
+
workload.push(util.powerShell('(Get-WmiObject -Class BatteryStaticData -Namespace ROOT/WMI).DesignedCapacity'));
|
|
251
|
+
workload.push(util.powerShell('(Get-CimInstance -Class BatteryFullChargedCapacity -Namespace ROOT/WMI).FullChargedCapacity'));
|
|
252
|
+
util.promiseAll(workload).then((data) => {
|
|
253
|
+
if (data) {
|
|
254
|
+
const parts = data.results[0].split(/\n\s*\n/);
|
|
255
|
+
const batteries = [];
|
|
256
|
+
const hasValue = (value) => /\S/.test(value);
|
|
257
|
+
for (let i = 0; i < parts.length; i++) {
|
|
258
|
+
// if (hasValue(parts[i]) && (!batteries.length || !hasValue(parts[i - 1]))) {
|
|
259
|
+
// batteries.push([]);
|
|
260
|
+
// }
|
|
261
|
+
if (hasValue(parts[i])) {
|
|
262
|
+
// batteries[batteries.length - 1].push(parts[i]);
|
|
263
|
+
batteries.push(parts[i]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const designCapacities = data.results[1].split('\r\n').filter((e) => e);
|
|
267
|
+
const fullChargeCapacities = data.results[2].split('\r\n').filter((e) => e);
|
|
268
|
+
if (batteries.length) {
|
|
269
|
+
let first = false;
|
|
270
|
+
const additionalBatteries = [];
|
|
271
|
+
for (let i = 0; i < batteries.length; i++) {
|
|
272
|
+
// let lines = batteries[i][0].split('\r\n');
|
|
273
|
+
const lines = batteries[i].split('\r\n');
|
|
274
|
+
const designedCapacity = designCapacities && designCapacities.length >= i + 1 && designCapacities[i] ? util.toInt(designCapacities[i]) : 0;
|
|
275
|
+
const fullChargeCapacity = fullChargeCapacities && fullChargeCapacities.length >= i + 1 && fullChargeCapacities[i] ? util.toInt(fullChargeCapacities[i]) : 0;
|
|
276
|
+
const parsed = parseWinBatteryPart(lines, designedCapacity, fullChargeCapacity);
|
|
277
|
+
if (!first && parsed.status > 0 && parsed.status !== 10) {
|
|
278
|
+
result.hasBattery = parsed.hasBattery;
|
|
279
|
+
result.maxCapacity = parsed.maxCapacity;
|
|
280
|
+
result.designedCapacity = parsed.designedCapacity;
|
|
281
|
+
result.voltage = parsed.voltage;
|
|
282
|
+
result.capacityUnit = parsed.capacityUnit;
|
|
283
|
+
result.percent = parsed.percent;
|
|
284
|
+
result.currentCapacity = parsed.currentCapacity;
|
|
285
|
+
result.isCharging = parsed.isCharging;
|
|
286
|
+
result.acConnected = parsed.acConnected;
|
|
287
|
+
result.model = parsed.model;
|
|
288
|
+
first = true;
|
|
289
|
+
} else if (parsed.status !== -1) {
|
|
290
|
+
additionalBatteries.push({
|
|
291
|
+
hasBattery: parsed.hasBattery,
|
|
292
|
+
maxCapacity: parsed.maxCapacity,
|
|
293
|
+
designedCapacity: parsed.designedCapacity,
|
|
294
|
+
voltage: parsed.voltage,
|
|
295
|
+
capacityUnit: parsed.capacityUnit,
|
|
296
|
+
percent: parsed.percent,
|
|
297
|
+
currentCapacity: parsed.currentCapacity,
|
|
298
|
+
isCharging: parsed.isCharging,
|
|
299
|
+
timeRemaining: null,
|
|
300
|
+
acConnected: parsed.acConnected,
|
|
301
|
+
model: parsed.model,
|
|
302
|
+
type: '',
|
|
303
|
+
manufacturer: '',
|
|
304
|
+
serial: ''
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (!first && additionalBatteries.length) {
|
|
309
|
+
result = additionalBatteries[0];
|
|
310
|
+
additionalBatteries.shift();
|
|
311
|
+
}
|
|
312
|
+
if (additionalBatteries.length) {
|
|
313
|
+
result.additionalBatteries = additionalBatteries;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (callback) {
|
|
318
|
+
callback(result);
|
|
319
|
+
}
|
|
320
|
+
resolve(result);
|
|
321
|
+
});
|
|
322
|
+
} catch {
|
|
323
|
+
if (callback) {
|
|
324
|
+
callback(result);
|
|
325
|
+
}
|
|
326
|
+
resolve(result);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
});
|