summaryrefslogtreecommitdiff
path: root/MistyCore/node_modules/systeminformation/lib/cpu.js
diff options
context:
space:
mode:
Diffstat (limited to 'MistyCore/node_modules/systeminformation/lib/cpu.js')
-rw-r--r--MistyCore/node_modules/systeminformation/lib/cpu.js1702
1 files changed, 1702 insertions, 0 deletions
diff --git a/MistyCore/node_modules/systeminformation/lib/cpu.js b/MistyCore/node_modules/systeminformation/lib/cpu.js
new file mode 100644
index 0000000..eea5dbf
--- /dev/null
+++ b/MistyCore/node_modules/systeminformation/lib/cpu.js
@@ -0,0 +1,1702 @@
+'use strict';
+// @ts-check
+// ==================================================================================
+// cpu.js
+// ----------------------------------------------------------------------------------
+// Description: System Information - library
+// for Node.js
+// Copyright: (c) 2014 - 2022
+// Author: Sebastian Hildebrandt
+// ----------------------------------------------------------------------------------
+// License: MIT
+// ==================================================================================
+// 4. CPU
+// ----------------------------------------------------------------------------------
+
+const os = require('os');
+const exec = require('child_process').exec;
+const execSync = require('child_process').execSync;
+const fs = require('fs');
+const util = require('./util');
+
+let _platform = process.platform;
+
+const _linux = (_platform === 'linux' || _platform === 'android');
+const _darwin = (_platform === 'darwin');
+const _windows = (_platform === 'win32');
+const _freebsd = (_platform === 'freebsd');
+const _openbsd = (_platform === 'openbsd');
+const _netbsd = (_platform === 'netbsd');
+const _sunos = (_platform === 'sunos');
+
+let _cpu_speed = 0;
+let _current_cpu = {
+ user: 0,
+ nice: 0,
+ system: 0,
+ idle: 0,
+ irq: 0,
+ load: 0,
+ tick: 0,
+ ms: 0,
+ currentLoad: 0,
+ currentLoadUser: 0,
+ currentLoadSystem: 0,
+ currentLoadNice: 0,
+ currentLoadIdle: 0,
+ currentLoadIrq: 0,
+ rawCurrentLoad: 0,
+ rawCurrentLoadUser: 0,
+ rawCurrentLoadSystem: 0,
+ rawCurrentLoadNice: 0,
+ rawCurrentLoadIdle: 0,
+ rawCurrentLoadIrq: 0
+};
+let _cpus = [];
+let _corecount = 0;
+
+const AMDBaseFrequencies = {
+ '8346': '1.8',
+ '8347': '1.9',
+ '8350': '2.0',
+ '8354': '2.2',
+ '8356|SE': '2.4',
+ '8356': '2.3',
+ '8360': '2.5',
+ '2372': '2.1',
+ '2373': '2.1',
+ '2374': '2.2',
+ '2376': '2.3',
+ '2377': '2.3',
+ '2378': '2.4',
+ '2379': '2.4',
+ '2380': '2.5',
+ '2381': '2.5',
+ '2382': '2.6',
+ '2384': '2.7',
+ '2386': '2.8',
+ '2387': '2.8',
+ '2389': '2.9',
+ '2393': '3.1',
+ '8374': '2.2',
+ '8376': '2.3',
+ '8378': '2.4',
+ '8379': '2.4',
+ '8380': '2.5',
+ '8381': '2.5',
+ '8382': '2.6',
+ '8384': '2.7',
+ '8386': '2.8',
+ '8387': '2.8',
+ '8389': '2.9',
+ '8393': '3.1',
+ '2419EE': '1.8',
+ '2423HE': '2.0',
+ '2425HE': '2.1',
+ '2427': '2.2',
+ '2431': '2.4',
+ '2435': '2.6',
+ '2439SE': '2.8',
+ '8425HE': '2.1',
+ '8431': '2.4',
+ '8435': '2.6',
+ '8439SE': '2.8',
+ '4122': '2.2',
+ '4130': '2.6',
+ '4162EE': '1.7',
+ '4164EE': '1.8',
+ '4170HE': '2.1',
+ '4174HE': '2.3',
+ '4176HE': '2.4',
+ '4180': '2.6',
+ '4184': '2.8',
+ '6124HE': '1.8',
+ '6128HE': '2.0',
+ '6132HE': '2.2',
+ '6128': '2.0',
+ '6134': '2.3',
+ '6136': '2.4',
+ '6140': '2.6',
+ '6164HE': '1.7',
+ '6166HE': '1.8',
+ '6168': '1.9',
+ '6172': '2.1',
+ '6174': '2.2',
+ '6176': '2.3',
+ '6176SE': '2.3',
+ '6180SE': '2.5',
+ '3250': '2.5',
+ '3260': '2.7',
+ '3280': '2.4',
+ '4226': '2.7',
+ '4228': '2.8',
+ '4230': '2.9',
+ '4234': '3.1',
+ '4238': '3.3',
+ '4240': '3.4',
+ '4256': '1.6',
+ '4274': '2.5',
+ '4276': '2.6',
+ '4280': '2.8',
+ '4284': '3.0',
+ '6204': '3.3',
+ '6212': '2.6',
+ '6220': '3.0',
+ '6234': '2.4',
+ '6238': '2.6',
+ '6262HE': '1.6',
+ '6272': '2.1',
+ '6274': '2.2',
+ '6276': '2.3',
+ '6278': '2.4',
+ '6282SE': '2.6',
+ '6284SE': '2.7',
+ '6308': '3.5',
+ '6320': '2.8',
+ '6328': '3.2',
+ '6338P': '2.3',
+ '6344': '2.6',
+ '6348': '2.8',
+ '6366': '1.8',
+ '6370P': '2.0',
+ '6376': '2.3',
+ '6378': '2.4',
+ '6380': '2.5',
+ '6386': '2.8',
+ 'FX|4100': '3.6',
+ 'FX|4120': '3.9',
+ 'FX|4130': '3.8',
+ 'FX|4150': '3.8',
+ 'FX|4170': '4.2',
+ 'FX|6100': '3.3',
+ 'FX|6120': '3.6',
+ 'FX|6130': '3.6',
+ 'FX|6200': '3.8',
+ 'FX|8100': '2.8',
+ 'FX|8120': '3.1',
+ 'FX|8140': '3.2',
+ 'FX|8150': '3.6',
+ 'FX|8170': '3.9',
+ 'FX|4300': '3.8',
+ 'FX|4320': '4.0',
+ 'FX|4350': '4.2',
+ 'FX|6300': '3.5',
+ 'FX|6350': '3.9',
+ 'FX|8300': '3.3',
+ 'FX|8310': '3.4',
+ 'FX|8320': '3.5',
+ 'FX|8350': '4.0',
+ 'FX|8370': '4.0',
+ 'FX|9370': '4.4',
+ 'FX|9590': '4.7',
+ 'FX|8320E': '3.2',
+ 'FX|8370E': '3.3',
+
+ // ZEN Desktop CPUs
+ '1200': '3.1',
+ 'Pro 1200': '3.1',
+ '1300X': '3.5',
+ 'Pro 1300': '3.5',
+ '1400': '3.2',
+ '1500X': '3.5',
+ 'Pro 1500': '3.5',
+ '1600': '3.2',
+ '1600X': '3.6',
+ 'Pro 1600': '3.2',
+ '1700': '3.0',
+ 'Pro 1700': '3.0',
+ '1700X': '3.4',
+ 'Pro 1700X': '3.4',
+ '1800X': '3.6',
+ '1900X': '3.8',
+ '1920': '3.2',
+ '1920X': '3.5',
+ '1950X': '3.4',
+
+ // ZEN Desktop APUs
+ '200GE': '3.2',
+ 'Pro 200GE': '3.2',
+ '220GE': '3.4',
+ '240GE': '3.5',
+ '3000G': '3.5',
+ '300GE': '3.4',
+ '3050GE': '3.4',
+ '2200G': '3.5',
+ 'Pro 2200G': '3.5',
+ '2200GE': '3.2',
+ 'Pro 2200GE': '3.2',
+ '2400G': '3.6',
+ 'Pro 2400G': '3.6',
+ '2400GE': '3.2',
+ 'Pro 2400GE': '3.2',
+
+ // ZEN Mobile APUs
+ 'Pro 200U': '2.3',
+ '300U': '2.4',
+ '2200U': '2.5',
+ '3200U': '2.6',
+ '2300U': '2.0',
+ 'Pro 2300U': '2.0',
+ '2500U': '2.0',
+ 'Pro 2500U': '2.2',
+ '2600H': '3.2',
+ '2700U': '2.0',
+ 'Pro 2700U': '2.2',
+ '2800H': '3.3',
+
+ // ZEN Server Processors
+ '7351': '2.4',
+ '7351P': '2.4',
+ '7401': '2.0',
+ '7401P': '2.0',
+ '7551P': '2.0',
+ '7551': '2.0',
+ '7251': '2.1',
+ '7261': '2.5',
+ '7281': '2.1',
+ '7301': '2.2',
+ '7371': '3.1',
+ '7451': '2.3',
+ '7501': '2.0',
+ '7571': '2.2',
+ '7601': '2.2',
+
+ // ZEN Embedded Processors
+ 'V1500B': '2.2',
+ 'V1780B': '3.35',
+ 'V1202B': '2.3',
+ 'V1404I': '2.0',
+ 'V1605B': '2.0',
+ 'V1756B': '3.25',
+ 'V1807B': '3.35',
+
+ '3101': '2.1',
+ '3151': '2.7',
+ '3201': '1.5',
+ '3251': '2.5',
+ '3255': '2.5',
+ '3301': '2.0',
+ '3351': '1.9',
+ '3401': '1.85',
+ '3451': '2.15',
+
+ // ZEN+ Desktop
+ '1200|AF': '3.1',
+ '2300X': '3.5',
+ '2500X': '3.6',
+ '2600': '3.4',
+ '2600E': '3.1',
+ '1600|AF': '3.2',
+ '2600X': '3.6',
+ '2700': '3.2',
+ '2700E': '2.8',
+ 'Pro 2700': '3.2',
+ '2700X': '3.7',
+ 'Pro 2700X': '3.6',
+ '2920X': '3.5',
+ '2950X': '3.5',
+ '2970WX': '3.0',
+ '2990WX': '3.0',
+
+ // ZEN+ Desktop APU
+ 'Pro 300GE': '3.4',
+ 'Pro 3125GE': '3.4',
+ '3150G': '3.5',
+ 'Pro 3150G': '3.5',
+ '3150GE': '3.3',
+ 'Pro 3150GE': '3.3',
+ '3200G': '3.6',
+ 'Pro 3200G': '3.6',
+ '3200GE': '3.3',
+ 'Pro 3200GE': '3.3',
+ '3350G': '3.6',
+ 'Pro 3350G': '3.6',
+ '3350GE': '3.3',
+ 'Pro 3350GE': '3.3',
+ '3400G': '3.7',
+ 'Pro 3400G': '3.7',
+ '3400GE': '3.3',
+ 'Pro 3400GE': '3.3',
+
+ // ZEN+ Mobile
+ '3300U': '2.1',
+ 'PRO 3300U': '2.1',
+ '3450U': '2.1',
+ '3500U': '2.1',
+ 'PRO 3500U': '2.1',
+ '3500C': '2.1',
+ '3550H': '2.1',
+ '3580U': '2.1',
+ '3700U': '2.3',
+ 'PRO 3700U': '2.3',
+ '3700C': '2.3',
+ '3750H': '2.3',
+ '3780U': '2.3',
+
+ // ZEN2 Desktop CPUS
+ '3100': '3.6',
+ '3300X': '3.8',
+ '3500': '3.6',
+ '3500X': '3.6',
+ '3600': '3.6',
+ 'Pro 3600': '3.6',
+ '3600X': '3.8',
+ '3600XT': '3.8',
+ 'Pro 3700': '3.6',
+ '3700X': '3.6',
+ '3800X': '3.9',
+ '3800XT': '3.9',
+ '3900': '3.1',
+ 'Pro 3900': '3.1',
+ '3900X': '3.8',
+ '3900XT': '3.8',
+ '3950X': '3.5',
+ '3960X': '3.8',
+ '3970X': '3.7',
+ '3990X': '2.9',
+ '3945WX': '4.0',
+ '3955WX': '3.9',
+ '3975WX': '3.5',
+ '3995WX': '2.7',
+
+ // ZEN2 Desktop APUs
+ '4300GE': '3.5',
+ 'Pro 4300GE': '3.5',
+ '4300G': '3.8',
+ 'Pro 4300G': '3.8',
+ '4600GE': '3.3',
+ 'Pro 4650GE': '3.3',
+ '4600G': '3.7',
+ 'Pro 4650G': '3.7',
+ '4700GE': '3.1',
+ 'Pro 4750GE': '3.1',
+ '4700G': '3.6',
+ 'Pro 4750G': '3.6',
+ '4300U': '2.7',
+ '4450U': '2.5',
+ 'Pro 4450U': '2.5',
+ '4500U': '2.3',
+ '4600U': '2.1',
+ 'PRO 4650U': '2.1',
+ '4680U': '2.1',
+ '4600HS': '3.0',
+ '4600H': '3.0',
+ '4700U': '2.0',
+ 'PRO 4750U': '1.7',
+ '4800U': '1.8',
+ '4800HS': '2.9',
+ '4800H': '2.9',
+ '4900HS': '3.0',
+ '4900H': '3.3',
+ '5300U': '2.6',
+ '5500U': '2.1',
+ '5700U': '1.8',
+
+ // ZEN2 - EPYC
+ '7232P': '3.1',
+ '7302P': '3.0',
+ '7402P': '2.8',
+ '7502P': '2.5',
+ '7702P': '2.0',
+ '7252': '3.1',
+ '7262': '3.2',
+ '7272': '2.9',
+ '7282': '2.8',
+ '7302': '3.0',
+ '7352': '2.3',
+ '7402': '2.8',
+ '7452': '2.35',
+ '7502': '2.5',
+ '7532': '2.4',
+ '7542': '2.9',
+ '7552': '2.2',
+ '7642': '2.3',
+ '7662': '2.0',
+ '7702': '2.0',
+ '7742': '2.25',
+ '7H12': '2.6',
+ '7F32': '3.7',
+ '7F52': '3.5',
+ '7F72': '3.2',
+
+ // Epyc (Milan)
+
+ '7763': '2.45',
+ '7713': '2.0',
+ '7713P': '2.0',
+ '7663': '2.0',
+ '7643': '2.3',
+ '75F3': '2.95',
+ '7543': '2.8',
+ '7543P': '2.8',
+ '7513': '2.6',
+ '7453': '2.75',
+ '74F3': '3.2',
+ '7443': '2.85',
+ '7443P': '2.85',
+ '7413': '2.65',
+ '73F3': '3.5',
+ '7343': '3.2',
+ '7313': '3.0',
+ '7313P': '3.0',
+ '72F3': '3.7',
+
+ // ZEN3
+ '5600X': '3.7',
+ '5800X': '3.8',
+ '5900X': '3.7',
+ '5950X': '3.4'
+};
+
+
+const socketTypes = {
+ 1: 'Other',
+ 2: 'Unknown',
+ 3: 'Daughter Board',
+ 4: 'ZIF Socket',
+ 5: 'Replacement/Piggy Back',
+ 6: 'None',
+ 7: 'LIF Socket',
+ 8: 'Slot 1',
+ 9: 'Slot 2',
+ 10: '370 Pin Socket',
+ 11: 'Slot A',
+ 12: 'Slot M',
+ 13: '423',
+ 14: 'A (Socket 462)',
+ 15: '478',
+ 16: '754',
+ 17: '940',
+ 18: '939',
+ 19: 'mPGA604',
+ 20: 'LGA771',
+ 21: 'LGA775',
+ 22: 'S1',
+ 23: 'AM2',
+ 24: 'F (1207)',
+ 25: 'LGA1366',
+ 26: 'G34',
+ 27: 'AM3',
+ 28: 'C32',
+ 29: 'LGA1156',
+ 30: 'LGA1567',
+ 31: 'PGA988A',
+ 32: 'BGA1288',
+ 33: 'rPGA988B',
+ 34: 'BGA1023',
+ 35: 'BGA1224',
+ 36: 'LGA1155',
+ 37: 'LGA1356',
+ 38: 'LGA2011',
+ 39: 'FS1',
+ 40: 'FS2',
+ 41: 'FM1',
+ 42: 'FM2',
+ 43: 'LGA2011-3',
+ 44: 'LGA1356-3',
+ 45: 'LGA1150',
+ 46: 'BGA1168',
+ 47: 'BGA1234',
+ 48: 'BGA1364',
+ 49: 'AM4',
+ 50: 'LGA1151',
+ 51: 'BGA1356',
+ 52: 'BGA1440',
+ 53: 'BGA1515',
+ 54: 'LGA3647-1',
+ 55: 'SP3',
+ 56: 'SP3r2',
+ 57: 'LGA2066',
+ 58: 'BGA1392',
+ 59: 'BGA1510',
+ 60: 'BGA1528',
+ 61: 'LGA4189',
+ 62: 'LGA1200',
+ 63: 'LGA4677',
+};
+
+const socketTypesByName = {
+ 'LGA1150': 'i7-5775C i3-4340 i3-4170 G3250 i3-4160T i3-4160 E3-1231 G3258 G3240 i7-4790S i7-4790K i7-4790 i5-4690K i5-4690 i5-4590T i5-4590S i5-4590 i5-4460 i3-4360 i3-4150 G1820 G3420 G3220 i7-4771 i5-4440 i3-4330 i3-4130T i3-4130 E3-1230 i7-4770S i7-4770K i7-4770 i5-4670K i5-4670 i5-4570T i5-4570S i5-4570 i5-4430',
+ 'LGA1151': 'i9-9900KS E-2288G E-2224 G5420 i9-9900T i9-9900 i7-9700T i7-9700F i7-9700E i7-9700 i5-9600 i5-9500T i5-9500F i5-9500 i5-9400T i3-9350K i3-9300 i3-9100T i3-9100F i3-9100 G4930 i9-9900KF i7-9700KF i5-9600KF i5-9400F i5-9400 i3-9350KF i9-9900K i7-9700K i5-9600K G5500 G5400 i7-8700T i7-8086K i5-8600 i5-8500T i5-8500 i5-8400T i3-8300 i3-8100T G4900 i7-8700K i7-8700 i5-8600K i5-8400 i3-8350K i3-8100 E3-1270 G4600 G4560 i7-7700T i7-7700K i7-7700 i5-7600K i5-7600 i5-7500T i5-7500 i5-7400 i3-7350K i3-7300 i3-7100T i3-7100 G3930 G3900 G4400 i7-6700T i7-6700K i7-6700 i5-6600K i5-6600 i5-6500T i5-6500 i5-6400T i5-6400 i3-6300 i3-6100T i3-6100 E3-1270 E3-1270 T4500 T4400',
+ '1155': 'G440 G460 G465 G470 G530T G540T G550T G1610T G1620T G530 G540 G1610 G550 G1620 G555 G1630 i3-2100T i3-2120T i3-3220T i3-3240T i3-3250T i3-2100 i3-2105 i3-2102 i3-3210 i3-3220 i3-2125 i3-2120 i3-3225 i3-2130 i3-3245 i3-3240 i3-3250 i5-3570T i5-2500T i5-2400S i5-2405S i5-2390T i5-3330S i5-2500S i5-3335S i5-2300 i5-3450S i5-3340S i5-3470S i5-3475S i5-3470T i5-2310 i5-3550S i5-2320 i5-3330 i5-3350P i5-3450 i5-2400 i5-3340 i5-3570S i5-2380P i5-2450P i5-3470 i5-2500K i5-3550 i5-2500 i5-3570 i5-3570K i5-2550K i7-3770T i7-2600S i7-3770S i7-2600K i7-2600 i7-3770 i7-3770K i7-2700K G620T G630T G640T G2020T G645T G2100T G2030T G622 G860T G620 G632 G2120T G630 G640 G2010 G840 G2020 G850 G645 G2030 G860 G2120 G870 G2130 G2140 E3-1220L E3-1220L E3-1260L E3-1265L E3-1220 E3-1225 E3-1220 E3-1235 E3-1225 E3-1230 E3-1230 E3-1240 E3-1245 E3-1270 E3-1275 E3-1240 E3-1245 E3-1270 E3-1280 E3-1275 E3-1290 E3-1280 E3-1290'
+};
+
+function getSocketTypesByName(str) {
+ let result = '';
+ for (const key in socketTypesByName) {
+ const names = socketTypesByName[key].split(' ');
+ for (let i = 0; i < names.length; i++) {
+ if (str.indexOf(names[i]) >= 0) {
+ result = key;
+ }
+ }
+ }
+ return result;
+}
+
+function cpuManufacturer(str) {
+ let result = str;
+ str = str.toLowerCase();
+
+ if (str.indexOf('intel') >= 0) { result = 'Intel'; }
+ if (str.indexOf('amd') >= 0) { result = 'AMD'; }
+ if (str.indexOf('qemu') >= 0) { result = 'QEMU'; }
+ if (str.indexOf('hygon') >= 0) { result = 'Hygon'; }
+ if (str.indexOf('centaur') >= 0) { result = 'WinChip/Via'; }
+ if (str.indexOf('vmware') >= 0) { result = 'VMware'; }
+ if (str.indexOf('Xen') >= 0) { result = 'Xen Hypervisor'; }
+ if (str.indexOf('tcg') >= 0) { result = 'QEMU'; }
+ if (str.indexOf('apple') >= 0) { result = 'Apple'; }
+
+ return result;
+}
+
+function cpuBrandManufacturer(res) {
+ res.brand = res.brand.replace(/\(R\)+/g, '®').replace(/\s+/g, ' ').trim();
+ res.brand = res.brand.replace(/\(TM\)+/g, '™').replace(/\s+/g, ' ').trim();
+ res.brand = res.brand.replace(/\(C\)+/g, '©').replace(/\s+/g, ' ').trim();
+ res.brand = res.brand.replace(/CPU+/g, '').replace(/\s+/g, ' ').trim();
+ res.manufacturer = cpuManufacturer(res.brand);
+
+ let parts = res.brand.split(' ');
+ parts.shift();
+ res.brand = parts.join(' ');
+ return res;
+}
+
+function getAMDSpeed(brand) {
+ let result = '0';
+ for (let key in AMDBaseFrequencies) {
+ if ({}.hasOwnProperty.call(AMDBaseFrequencies, key)) {
+ let parts = key.split('|');
+ let found = 0;
+ parts.forEach(item => {
+ if (brand.indexOf(item) > -1) {
+ found++;
+ }
+ });
+ if (found === parts.length) {
+ result = AMDBaseFrequencies[key];
+ }
+ }
+ }
+ return parseFloat(result);
+}
+
+// --------------------------
+// CPU - brand, speed
+
+function getCpu() {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ const UNKNOWN = 'unknown';
+ let result = {
+ manufacturer: UNKNOWN,
+ brand: UNKNOWN,
+ vendor: '',
+ family: '',
+ model: '',
+ stepping: '',
+ revision: '',
+ voltage: '',
+ speed: 0,
+ speedMin: 0,
+ speedMax: 0,
+ governor: '',
+ cores: util.cores(),
+ physicalCores: util.cores(),
+ performanceCores: util.cores(),
+ efficiencyCores: 0,
+ processors: 1,
+ socket: '',
+ flags: '',
+ virtualization: false,
+ cache: {}
+ };
+ cpuFlags().then(flags => {
+ result.flags = flags;
+ result.virtualization = flags.indexOf('vmx') > -1 || flags.indexOf('svm') > -1;
+ if (_darwin) {
+ exec('sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min hw.packages hw.physicalcpu_max hw.ncpu hw.tbfrequency hw.cpufamily hw.cpusubfamily', function (error, stdout) {
+ let lines = stdout.toString().split('\n');
+ const modelline = util.getValue(lines, 'machdep.cpu.brand_string');
+ const modellineParts = modelline.split('@');
+ result.brand = modellineParts[0].trim();
+ const speed = modellineParts[1] ? modellineParts[1].trim() : '0';
+ result.speed = parseFloat(speed.replace(/GHz+/g, ''));
+ let tbFrequency = util.getValue(lines, 'hw.tbfrequency') / 1000000000.0;
+ tbFrequency = tbFrequency < 0.1 ? tbFrequency * 100 : tbFrequency;
+ result.speed = result.speed === 0 ? tbFrequency : result.speed;
+
+ _cpu_speed = result.speed;
+ result = cpuBrandManufacturer(result);
+ result.speedMin = util.getValue(lines, 'hw.cpufrequency_min') ? (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0) : result.speed;
+ result.speedMax = util.getValue(lines, 'hw.cpufrequency_max') ? (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0) : result.speed;
+ result.vendor = util.getValue(lines, 'machdep.cpu.vendor') || 'Apple';
+ result.family = util.getValue(lines, 'machdep.cpu.family') || util.getValue(lines, 'hw.cpufamily');
+ result.model = util.getValue(lines, 'machdep.cpu.model');
+ result.stepping = util.getValue(lines, 'machdep.cpu.stepping') || util.getValue(lines, 'hw.cpusubfamily');
+ result.virtualization = true;
+ const countProcessors = util.getValue(lines, 'hw.packages');
+ const countCores = util.getValue(lines, 'hw.physicalcpu_max');
+ const countThreads = util.getValue(lines, 'hw.ncpu');
+ if (os.arch() === 'arm64') {
+ const clusters = execSync('ioreg -c IOPlatformDevice -d 3 -r | grep cluster-type').toString().split('\n');
+ const efficiencyCores = clusters.filter(line => line.indexOf('"E"') >= 0).length;
+ const performanceCores = clusters.filter(line => line.indexOf('"P"') >= 0).length;
+ result.socket = 'SOC';
+ result.efficiencyCores = efficiencyCores;
+ result.performanceCores = performanceCores;
+ }
+ if (countProcessors) {
+ result.processors = parseInt(countProcessors) || 1;
+ }
+ if (countCores && countThreads) {
+ result.cores = parseInt(countThreads) || util.cores();
+ result.physicalCores = parseInt(countCores) || util.cores();
+ }
+ cpuCache().then((res) => {
+ result.cache = res;
+ resolve(result);
+ });
+ });
+ }
+ if (_linux) {
+ let modelline = '';
+ let lines = [];
+ if (os.cpus()[0] && os.cpus()[0].model) { modelline = os.cpus()[0].model; }
+ exec('export LC_ALL=C; lscpu; echo -n "Governor: "; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null; echo; unset LC_ALL', function (error, stdout) {
+ if (!error) {
+ lines = stdout.toString().split('\n');
+ }
+ modelline = util.getValue(lines, 'model name') || modelline;
+ const modellineParts = modelline.split('@');
+ result.brand = modellineParts[0].trim();
+ result.speed = modellineParts[1] ? parseFloat(modellineParts[1].trim()) : 0;
+ if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
+ result.speed = getAMDSpeed(result.brand);
+ }
+ if (result.speed === 0) {
+ const current = getCpuCurrentSpeedSync();
+ if (current.avg !== 0) { result.speed = current.avg; }
+ }
+ _cpu_speed = result.speed;
+ result.speedMin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100;
+ result.speedMax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100;
+
+ result = cpuBrandManufacturer(result);
+ result.vendor = cpuManufacturer(util.getValue(lines, 'vendor id'));
+
+ result.family = util.getValue(lines, 'cpu family');
+ result.model = util.getValue(lines, 'model:');
+ result.stepping = util.getValue(lines, 'stepping');
+ result.revision = util.getValue(lines, 'cpu revision');
+ result.cache.l1d = util.getValue(lines, 'l1d cache');
+ if (result.cache.l1d) { result.cache.l1d = parseInt(result.cache.l1d) * (result.cache.l1d.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l1d.indexOf('K') !== -1 ? 1024 : 1)); }
+ result.cache.l1i = util.getValue(lines, 'l1i cache');
+ if (result.cache.l1i) { result.cache.l1i = parseInt(result.cache.l1i) * (result.cache.l1i.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l1i.indexOf('K') !== -1 ? 1024 : 1)); }
+ result.cache.l2 = util.getValue(lines, 'l2 cache');
+ if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1)); }
+ result.cache.l3 = util.getValue(lines, 'l3 cache');
+ if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1)); }
+
+ const threadsPerCore = util.getValue(lines, 'thread(s) per core') || '1';
+ const processors = util.getValue(lines, 'socket(s)') || '1';
+ let threadsPerCoreInt = parseInt(threadsPerCore, 10); // threads per code (normally only for performance cores)
+ let processorsInt = parseInt(processors, 10) || 1; // number of sockets / processor units in machine (normally 1)
+ const coresPerSocket = parseInt(util.getValue(lines, 'core(s) per socket'), 10); // number of cores (e.g. 16 on i12900)
+ result.physicalCores = coresPerSocket ? coresPerSocket * processorsInt : result.cores / threadsPerCoreInt;
+ result.performanceCores = threadsPerCoreInt > 1 ? result.cores - result.physicalCores : result.cores;
+ result.efficiencyCores = threadsPerCoreInt > 1 ? result.cores - (threadsPerCoreInt * result.performanceCores) : 0;
+ result.processors = processorsInt;
+ result.governor = util.getValue(lines, 'governor') || '';
+
+ // Test Raspberry
+ if (result.vendor === 'ARM') {
+ const linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
+ const rPIRevision = util.decodePiCpuinfo(linesRpi);
+ if (rPIRevision.model.toLowerCase().indexOf('raspberry') >= 0) {
+ result.family = result.manufacturer;
+ result.manufacturer = rPIRevision.manufacturer;
+ result.brand = rPIRevision.processor;
+ result.revision = rPIRevision.revisionCode;
+ result.socket = 'SOC';
+ }
+ }
+
+ // socket type
+ let lines2 = [];
+ exec('export LC_ALL=C; dmidecode –t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', function (error2, stdout2) {
+ lines2 = stdout2.toString().split('\n');
+ if (lines2 && lines2.length) {
+ result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim() || result.socket;
+ }
+ resolve(result);
+ });
+ });
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+ let modelline = '';
+ let lines = [];
+ if (os.cpus()[0] && os.cpus()[0].model) { modelline = os.cpus()[0].model; }
+ exec('export LC_ALL=C; dmidecode -t 4; dmidecode -t 7 unset LC_ALL', function (error, stdout) {
+ let cache = [];
+ if (!error) {
+ const data = stdout.toString().split('# dmidecode');
+ const processor = data.length > 1 ? data[1] : '';
+ cache = data.length > 2 ? data[2].split('Cache Information') : [];
+
+ lines = processor.split('\n');
+ }
+ result.brand = modelline.split('@')[0].trim();
+ result.speed = modelline.split('@')[1] ? parseFloat(modelline.split('@')[1].trim()) : 0;
+ if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
+ result.speed = getAMDSpeed(result.brand);
+ }
+ if (result.speed === 0) {
+ const current = getCpuCurrentSpeedSync();
+ if (current.avg !== 0) { result.speed = current.avg; }
+ }
+ _cpu_speed = result.speed;
+ result.speedMin = result.speed;
+ result.speedMax = Math.round(parseFloat(util.getValue(lines, 'max speed').replace(/Mhz/g, '')) / 10.0) / 100;
+
+ result = cpuBrandManufacturer(result);
+ result.vendor = cpuManufacturer(util.getValue(lines, 'manufacturer'));
+ let sig = util.getValue(lines, 'signature');
+ sig = sig.split(',');
+ for (let i = 0; i < sig.length; i++) {
+ sig[i] = sig[i].trim();
+ }
+ result.family = util.getValue(sig, 'Family', ' ', true);
+ result.model = util.getValue(sig, 'Model', ' ', true);
+ result.stepping = util.getValue(sig, 'Stepping', ' ', true);
+ result.revision = '';
+ const voltage = parseFloat(util.getValue(lines, 'voltage'));
+ result.voltage = isNaN(voltage) ? '' : voltage.toFixed(2);
+ for (let i = 0; i < cache.length; i++) {
+ lines = cache[i].split('\n');
+ let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-');
+ cacheType = cacheType.length ? cacheType[0] : '';
+ const sizeParts = util.getValue(lines, 'Installed Size').split(' ');
+ let size = parseInt(sizeParts[0], 10);
+ const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb';
+ size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1)));
+ if (cacheType) {
+ if (cacheType === 'l1') {
+ result.cache[cacheType + 'd'] = size / 2;
+ result.cache[cacheType + 'i'] = size / 2;
+ } else {
+ result.cache[cacheType] = size;
+ }
+ }
+ }
+ // socket type
+ result.socket = util.getValue(lines, 'Upgrade').replace('Socket', '').trim();
+ // # threads / # cores
+ const threadCount = util.getValue(lines, 'thread count').trim();
+ const coreCount = util.getValue(lines, 'core count').trim();
+ if (coreCount && threadCount) {
+ result.cores = parseInt(threadCount, 10);
+ result.physicalCores = parseInt(coreCount, 10);
+ }
+ resolve(result);
+ });
+ }
+ if (_sunos) {
+ resolve(result);
+ }
+ if (_windows) {
+ try {
+ const workload = [];
+ workload.push(util.powerShell('Get-WmiObject Win32_processor | select Name, Revision, L2CacheSize, L3CacheSize, Manufacturer, MaxClockSpeed, Description, UpgradeMethod, Caption, NumberOfLogicalProcessors, NumberOfCores | fl'));
+ workload.push(util.powerShell('Get-WmiObject Win32_CacheMemory | select CacheType,InstalledSize,Level | fl'));
+ workload.push(util.powerShell('(Get-CimInstance Win32_ComputerSystem).HypervisorPresent'));
+
+ Promise.all(
+ workload
+ ).then((data) => {
+ let lines = data[0].split('\r\n');
+ let name = util.getValue(lines, 'name', ':') || '';
+ if (name.indexOf('@') >= 0) {
+ result.brand = name.split('@')[0].trim();
+ result.speed = name.split('@')[1] ? parseFloat(name.split('@')[1].trim()) : 0;
+ _cpu_speed = result.speed;
+ } else {
+ result.brand = name.trim();
+ result.speed = 0;
+ }
+ result = cpuBrandManufacturer(result);
+ result.revision = util.getValue(lines, 'revision', ':');
+ result.cache.l1d = 0;
+ result.cache.l1i = 0;
+ result.cache.l2 = util.getValue(lines, 'l2cachesize', ':');
+ result.cache.l3 = util.getValue(lines, 'l3cachesize', ':');
+ if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2, 10) * 1024; }
+ if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3, 10) * 1024; }
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
+ result.speedMax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', ':').replace(/,/g, '.')) / 10.0) / 100;
+ if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
+ result.speed = getAMDSpeed(result.brand);
+ }
+ if (result.speed === 0) {
+ result.speed = result.speedMax;
+ }
+ result.speedMin = result.speed;
+
+ let description = util.getValue(lines, 'description', ':').split(' ');
+ for (let i = 0; i < description.length; i++) {
+ if (description[i].toLowerCase().startsWith('family') && (i + 1) < description.length && description[i + 1]) {
+ result.family = description[i + 1];
+ }
+ if (description[i].toLowerCase().startsWith('model') && (i + 1) < description.length && description[i + 1]) {
+ result.model = description[i + 1];
+ }
+ if (description[i].toLowerCase().startsWith('stepping') && (i + 1) < description.length && description[i + 1]) {
+ result.stepping = description[i + 1];
+ }
+ }
+ // socket type
+ const socketId = util.getValue(lines, 'UpgradeMethod', ':');
+ if (socketTypes[socketId]) {
+ result.socket = socketTypes[socketId];
+ }
+ const socketByName = getSocketTypesByName(name);
+ if (socketByName) {
+ result.socket = socketByName;
+ }
+ // # threads / # cores
+ const countProcessors = util.countLines(lines, 'Caption');
+ const countThreads = util.getValue(lines, 'NumberOfLogicalProcessors', ':');
+ const countCores = util.getValue(lines, 'NumberOfCores', ':');
+ if (countProcessors) {
+ result.processors = parseInt(countProcessors) || 1;
+ }
+ if (countCores && countThreads) {
+ result.cores = parseInt(countThreads) || util.cores();
+ result.physicalCores = parseInt(countCores) || util.cores();
+ }
+ if (countProcessors > 1) {
+ result.cores = result.cores * countProcessors;
+ result.physicalCores = result.physicalCores * countProcessors;
+ }
+ const parts = data[1].split(/\n\s*\n/);
+ parts.forEach(function (part) {
+ lines = part.split('\r\n');
+ const cacheType = util.getValue(lines, 'CacheType');
+ const level = util.getValue(lines, 'Level');
+ const installedSize = util.getValue(lines, 'InstalledSize');
+ // L1 Instructions
+ if (level === '3' && cacheType === '3') {
+ result.cache.l1i = parseInt(installedSize, 10);
+ }
+ // L1 Data
+ if (level === '3' && cacheType === '4') {
+ result.cache.l1d = parseInt(installedSize, 10);
+ }
+ // L1 all
+ if (level === '3' && cacheType === '5' && !result.cache.l1i && !result.cache.l1d) {
+ result.cache.l1i = parseInt(installedSize, 10) / 2;
+ result.cache.l1d = parseInt(installedSize, 10) / 2;
+ }
+ });
+ const hyperv = data[2] ? data[2].toString().toLowerCase() : '';
+ result.virtualization = hyperv.indexOf('true') !== -1;
+
+ resolve(result);
+ });
+ } catch (e) {
+ resolve(result);
+ }
+ }
+ });
+ });
+ });
+}
+
+// --------------------------
+// CPU - Processor Data
+
+function cpu(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ getCpu().then(result => {
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ });
+ });
+}
+
+exports.cpu = cpu;
+
+// --------------------------
+// CPU - current speed - in GHz
+
+function getCpuCurrentSpeedSync() {
+
+ let cpus = os.cpus();
+ let minFreq = 999999999;
+ let maxFreq = 0;
+ let avgFreq = 0;
+ let cores = [];
+
+ if (cpus && cpus.length) {
+ for (let i in cpus) {
+ if ({}.hasOwnProperty.call(cpus, i)) {
+ let freq = cpus[i].speed > 100 ? (cpus[i].speed + 1) / 1000 : cpus[i].speed / 10;
+ avgFreq = avgFreq + freq;
+ if (freq > maxFreq) { maxFreq = freq; }
+ if (freq < minFreq) { minFreq = freq; }
+ cores.push(parseFloat(freq.toFixed(2)));
+ }
+ }
+ avgFreq = avgFreq / cpus.length;
+ return {
+ min: parseFloat(minFreq.toFixed(2)),
+ max: parseFloat(maxFreq.toFixed(2)),
+ avg: parseFloat((avgFreq).toFixed(2)),
+ cores: cores
+ };
+ } else {
+ return {
+ min: 0,
+ max: 0,
+ avg: 0,
+ cores: cores
+ };
+ }
+}
+
+function cpuCurrentSpeed(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ let result = getCpuCurrentSpeedSync();
+ if (result.avg === 0 && _cpu_speed !== 0) {
+ const currCpuSpeed = parseFloat(_cpu_speed);
+ result = {
+ min: currCpuSpeed,
+ max: currCpuSpeed,
+ avg: currCpuSpeed,
+ cores: []
+ };
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ });
+}
+
+exports.cpuCurrentSpeed = cpuCurrentSpeed;
+
+// --------------------------
+// CPU - temperature
+// if sensors are installed
+
+function cpuTemperature(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ let result = {
+ main: null,
+ cores: [],
+ max: null,
+ socket: [],
+ chipset: null
+ };
+ if (_linux) {
+ // CPU Chipset, Socket
+ try {
+ const cmd = 'cat /sys/class/thermal/thermal_zone*/type 2>/dev/null; echo "-----"; cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null;';
+ const parts = execSync(cmd).toString().split('-----\n');
+ if (parts.length === 2) {
+ const lines = parts[0].split('\n');
+ const lines2 = parts[1].split('\n');
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i].trim();
+ if (line.startsWith('acpi') && lines2[i]) {
+ result.socket.push(Math.round(parseInt(lines2[i], 10) / 100) / 10);
+ }
+ if (line.startsWith('pch') && lines2[i]) {
+ result.chipset = Math.round(parseInt(lines2[i], 10) / 100) / 10;
+ }
+ }
+ }
+ } catch (e) {
+ util.noop();
+ }
+
+ const cmd = 'for mon in /sys/class/hwmon/hwmon*; do for label in "$mon"/temp*_label; do if [ -f $label ]; then value=${label%_*}_input; echo $(cat "$label")___$(cat "$value"); fi; done; done;';
+ try {
+ exec(cmd, function (error, stdout) {
+ stdout = stdout.toString();
+ const tdiePos = stdout.toLowerCase().indexOf('tdie');
+ if (tdiePos !== -1) {
+ stdout = stdout.substring(tdiePos);
+ }
+ let lines = stdout.split('\n');
+ lines.forEach(line => {
+ const parts = line.split('___');
+ const label = parts[0];
+ const value = parts.length > 1 && parts[1] ? parts[1] : '0';
+ if (value && (label === undefined || (label && label.toLowerCase().startsWith('core')))) {
+ result.cores.push(Math.round(parseInt(value, 10) / 100) / 10);
+ } else if (value && label && result.main === null) {
+ result.main = Math.round(parseInt(value, 10) / 100) / 10;
+ }
+ });
+
+ if (result.cores.length > 0) {
+ result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length);
+ let maxtmp = Math.max.apply(Math, result.cores);
+ result.max = (maxtmp > result.main) ? maxtmp : result.main;
+ }
+ if (result.main !== null) {
+ if (result.max === null) {
+ result.max = result.main;
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ return;
+ }
+ exec('sensors', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ let tdieTemp = null;
+ let newSectionStarts = true;
+ let section = '';
+ lines.forEach(function (line) {
+ // determine section
+ if (line.trim() === '') {
+ newSectionStarts = true;
+ } else if (newSectionStarts) {
+ if (line.trim().toLowerCase().startsWith('acpi')) { section = 'acpi'; }
+ if (line.trim().toLowerCase().startsWith('pch')) { section = 'pch'; }
+ if (line.trim().toLowerCase().startsWith('core')) { section = 'core'; }
+ newSectionStarts = false;
+ }
+ let regex = /[+-]([^°]*)/g;
+ let temps = line.match(regex);
+ let firstPart = line.split(':')[0].toUpperCase();
+ if (section === 'acpi') {
+ // socket temp
+ if (firstPart.indexOf('TEMP') !== -1) {
+ result.socket.push(parseFloat(temps));
+ }
+ } else if (section === 'pch') {
+ // chipset temp
+ if (firstPart.indexOf('TEMP') !== -1) {
+ result.chipset = parseFloat(temps);
+ }
+ }
+ // cpu temp
+ if (firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1) {
+ result.main = parseFloat(temps);
+ }
+ if (firstPart.indexOf('CORE ') !== -1) {
+ result.cores.push(parseFloat(temps));
+ }
+ if (firstPart.indexOf('TDIE') !== -1 && tdieTemp === null) {
+ tdieTemp = parseFloat(temps);
+ }
+ });
+ if (result.cores.length > 0) {
+ result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length);
+ let maxtmp = Math.max.apply(Math, result.cores);
+ result.max = (maxtmp > result.main) ? maxtmp : result.main;
+ } else {
+ if (result.main === null && tdieTemp !== null) {
+ result.main = tdieTemp;
+ result.max = tdieTemp;
+ }
+ }
+ if (result.main !== null || result.max !== null) {
+ if (callback) { callback(result); }
+ resolve(result);
+ return;
+ }
+ }
+ fs.stat('/sys/class/thermal/thermal_zone0/temp', function (err) {
+ if (err === null) {
+ fs.readFile('/sys/class/thermal/thermal_zone0/temp', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ if (lines.length > 0) {
+ result.main = parseFloat(lines[0]) / 1000.0;
+ result.max = result.main;
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ } else {
+ exec('/opt/vc/bin/vcgencmd measure_temp', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ if (lines.length > 0 && lines[0].indexOf('=')) {
+ result.main = parseFloat(lines[0].split('=')[1]);
+ result.max = result.main;
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ });
+ });
+ });
+ } catch (er) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+ exec('sysctl dev.cpu | grep temp', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ let sum = 0;
+ lines.forEach(function (line) {
+ const parts = line.split(':');
+ if (parts.length > 1) {
+ const temp = parseFloat(parts[1].replace(',', '.'));
+ if (temp > result.max) { result.max = temp; }
+ sum = sum + temp;
+ result.cores.push(temp);
+ }
+ });
+ if (result.cores.length) {
+ result.main = Math.round(sum / result.cores.length * 100) / 100;
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_darwin) {
+ let osxTemp = null;
+ try {
+ osxTemp = require('osx-temperature-sensor');
+ } catch (er) {
+ osxTemp = null;
+ }
+ if (osxTemp) {
+ result = osxTemp.cpuTemperature();
+ // round to 2 digits
+ if (result.main) {
+ result.main = Math.round(result.main * 100) / 100;
+ }
+ if (result.max) {
+ result.max = Math.round(result.max * 100) / 100;
+ }
+ if (result.cores && result.cores.length) {
+ for (let i = 0; i < result.cores.length; i++) {
+ result.cores[i] = Math.round(result.cores[i] * 100) / 100;
+ }
+ }
+ }
+
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ if (_sunos) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ if (_windows) {
+ try {
+ util.powerShell('Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi" | Select CurrentTemperature').then((stdout, error) => {
+ if (!error) {
+ let sum = 0;
+ let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
+ lines.forEach(function (line) {
+ let value = (parseInt(line, 10) - 2732) / 10;
+ if (!isNaN(value)) {
+ sum = sum + value;
+ if (value > result.max) { result.max = value; }
+ result.cores.push(value);
+ }
+ });
+ if (result.cores.length) {
+ result.main = sum / result.cores.length;
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ });
+ });
+}
+
+exports.cpuTemperature = cpuTemperature;
+
+// --------------------------
+// CPU Flags
+
+function cpuFlags(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ let result = '';
+ if (_windows) {
+ try {
+ exec('reg query "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" /v FeatureSet', util.execOptsWin, function (error, stdout) {
+ if (!error) {
+ let flag_hex = stdout.split('0x').pop().trim();
+ let flag_bin_unpadded = parseInt(flag_hex, 16).toString(2);
+ let flag_bin = '0'.repeat(32 - flag_bin_unpadded.length) + flag_bin_unpadded;
+ // empty flags are the reserved fields in the CPUID feature bit list
+ // as found on wikipedia:
+ // https://en.wikipedia.org/wiki/CPUID
+ let all_flags = [
+ 'fpu', 'vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce', 'cx8', 'apic',
+ '', 'sep', 'mtrr', 'pge', 'mca', 'cmov', 'pat', 'pse-36', 'psn', 'clfsh',
+ '', 'ds', 'acpi', 'mmx', 'fxsr', 'sse', 'sse2', 'ss', 'htt', 'tm', 'ia64', 'pbe'
+ ];
+ for (let f = 0; f < all_flags.length; f++) {
+ if (flag_bin[f] === '1' && all_flags[f] !== '') {
+ result += ' ' + all_flags[f];
+ }
+ }
+ result = result.trim().toLowerCase();
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ if (_linux) {
+ try {
+
+ exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ lines.forEach(function (line) {
+ if (line.split(':')[0].toUpperCase().indexOf('FLAGS') !== -1) {
+ result = line.split(':')[1].trim().toLowerCase();
+ }
+ });
+ }
+ if (!result) {
+ fs.readFile('/proc/cpuinfo', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ result = util.getValue(lines, 'features', ':', true).toLowerCase();
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ } else {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+ exec('export LC_ALL=C; dmidecode -t 4 2>/dev/null; unset LC_ALL', function (error, stdout) {
+ let flags = [];
+ if (!error) {
+ let parts = stdout.toString().split('\tFlags:');
+ const lines = parts.length > 1 ? parts[1].split('\tVersion:')[0].split('\n') : [];
+ lines.forEach(function (line) {
+ let flag = (line.indexOf('(') ? line.split('(')[0].toLowerCase() : '').trim().replace(/\t/g, '');
+ if (flag) {
+ flags.push(flag);
+ }
+ });
+ }
+ result = flags.join(' ').trim().toLowerCase();
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_darwin) {
+ exec('sysctl machdep.cpu.features', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ if (lines.length > 0 && lines[0].indexOf('machdep.cpu.features:') !== -1) {
+ result = lines[0].split(':')[1].trim().toLowerCase();
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_sunos) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ });
+ });
+}
+
+exports.cpuFlags = cpuFlags;
+
+// --------------------------
+// CPU Cache
+
+function cpuCache(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+
+ let result = {
+ l1d: null,
+ l1i: null,
+ l2: null,
+ l3: null,
+ };
+ if (_linux) {
+ try {
+ exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ lines.forEach(function (line) {
+ let parts = line.split(':');
+ if (parts[0].toUpperCase().indexOf('L1D CACHE') !== -1) {
+ result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1));
+ }
+ if (parts[0].toUpperCase().indexOf('L1I CACHE') !== -1) {
+ result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1));
+ }
+ if (parts[0].toUpperCase().indexOf('L2 CACHE') !== -1) {
+ result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1));
+ }
+ if (parts[0].toUpperCase().indexOf('L3 CACHE') !== -1) {
+ result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1));
+ }
+ });
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+ exec('export LC_ALL=C; dmidecode -t 7 2>/dev/null; unset LC_ALL', function (error, stdout) {
+ let cache = [];
+ if (!error) {
+ const data = stdout.toString();
+ cache = data.split('Cache Information');
+ cache.shift();
+ }
+ for (let i = 0; i < cache.length; i++) {
+ const lines = cache[i].split('\n');
+ let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-');
+ cacheType = cacheType.length ? cacheType[0] : '';
+ const sizeParts = util.getValue(lines, 'Installed Size').split(' ');
+ let size = parseInt(sizeParts[0], 10);
+ const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb';
+ size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1)));
+ if (cacheType) {
+ if (cacheType === 'l1') {
+ result.cache[cacheType + 'd'] = size / 2;
+ result.cache[cacheType + 'i'] = size / 2;
+ } else {
+ result.cache[cacheType] = size;
+ }
+ }
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_darwin) {
+ exec('sysctl hw.l1icachesize hw.l1dcachesize hw.l2cachesize hw.l3cachesize', function (error, stdout) {
+ if (!error) {
+ let lines = stdout.toString().split('\n');
+ lines.forEach(function (line) {
+ let parts = line.split(':');
+ if (parts[0].toLowerCase().indexOf('hw.l1icachesize') !== -1) {
+ result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
+ }
+ if (parts[0].toLowerCase().indexOf('hw.l1dcachesize') !== -1) {
+ result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
+ }
+ if (parts[0].toLowerCase().indexOf('hw.l2cachesize') !== -1) {
+ result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
+ }
+ if (parts[0].toLowerCase().indexOf('hw.l3cachesize') !== -1) {
+ result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
+ }
+ });
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_sunos) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ if (_windows) {
+ try {
+ util.powerShell('Get-WmiObject Win32_processor | select L2CacheSize, L3CacheSize | fl').then((stdout, error) => {
+ if (!error) {
+ let lines = stdout.split('\r\n');
+ result.l1d = 0;
+ result.l1i = 0;
+ result.l2 = util.getValue(lines, 'l2cachesize', ':');
+ result.l3 = util.getValue(lines, 'l3cachesize', ':');
+ if (result.l2) { result.l2 = parseInt(result.l2, 10) * 1024; }
+ if (result.l3) { result.l3 = parseInt(result.l3, 10) * 1024; }
+ }
+ util.powerShell('Get-WmiObject Win32_CacheMemory | select CacheType,InstalledSize,Level | fl').then((stdout, error) => {
+ if (!error) {
+ const parts = stdout.split(/\n\s*\n/);
+ parts.forEach(function (part) {
+ const lines = part.split('\r\n');
+ const cacheType = util.getValue(lines, 'CacheType');
+ const level = util.getValue(lines, 'Level');
+ const installedSize = util.getValue(lines, 'InstalledSize');
+ // L1 Instructions
+ if (level === '3' && cacheType === '3') {
+ result.l1i = parseInt(installedSize, 10);
+ }
+ // L1 Data
+ if (level === '3' && cacheType === '4') {
+ result.l1d = parseInt(installedSize, 10);
+ }
+ // L1 all
+ if (level === '3' && cacheType === '5' && !result.l1i && !result.l1d) {
+ result.l1i = parseInt(installedSize, 10) / 2;
+ result.l1d = parseInt(installedSize, 10) / 2;
+ }
+ });
+ }
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ });
+ });
+}
+
+exports.cpuCache = cpuCache;
+
+// --------------------------
+// CPU - current load - in %
+
+function getLoad() {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ let loads = os.loadavg().map(function (x) { return x / util.cores(); });
+ let avgLoad = parseFloat((Math.max.apply(Math, loads)).toFixed(2));
+ let result = {};
+
+ let now = Date.now() - _current_cpu.ms;
+ if (now >= 200) {
+ _current_cpu.ms = Date.now();
+ const cpus = os.cpus();
+ let totalUser = 0;
+ let totalSystem = 0;
+ let totalNice = 0;
+ let totalIrq = 0;
+ let totalIdle = 0;
+ let cores = [];
+ _corecount = (cpus && cpus.length) ? cpus.length : 0;
+
+ for (let i = 0; i < _corecount; i++) {
+ const cpu = cpus[i].times;
+ totalUser += cpu.user;
+ totalSystem += cpu.sys;
+ totalNice += cpu.nice;
+ totalIdle += cpu.idle;
+ totalIrq += cpu.irq;
+ let tmpTick = (_cpus && _cpus[i] && _cpus[i].totalTick ? _cpus[i].totalTick : 0);
+ let tmpLoad = (_cpus && _cpus[i] && _cpus[i].totalLoad ? _cpus[i].totalLoad : 0);
+ let tmpUser = (_cpus && _cpus[i] && _cpus[i].user ? _cpus[i].user : 0);
+ let tmpSystem = (_cpus && _cpus[i] && _cpus[i].sys ? _cpus[i].sys : 0);
+ let tmpNice = (_cpus && _cpus[i] && _cpus[i].nice ? _cpus[i].nice : 0);
+ let tmpIdle = (_cpus && _cpus[i] && _cpus[i].idle ? _cpus[i].idle : 0);
+ let tmpIrq = (_cpus && _cpus[i] && _cpus[i].irq ? _cpus[i].irq : 0);
+ _cpus[i] = cpu;
+ _cpus[i].totalTick = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq + _cpus[i].idle;
+ _cpus[i].totalLoad = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq;
+ _cpus[i].currentTick = _cpus[i].totalTick - tmpTick;
+ _cpus[i].load = (_cpus[i].totalLoad - tmpLoad);
+ _cpus[i].loadUser = (_cpus[i].user - tmpUser);
+ _cpus[i].loadSystem = (_cpus[i].sys - tmpSystem);
+ _cpus[i].loadNice = (_cpus[i].nice - tmpNice);
+ _cpus[i].loadIdle = (_cpus[i].idle - tmpIdle);
+ _cpus[i].loadIrq = (_cpus[i].irq - tmpIrq);
+ cores[i] = {};
+ cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100;
+ cores[i].loadUser = _cpus[i].loadUser / _cpus[i].currentTick * 100;
+ cores[i].loadSystem = _cpus[i].loadSystem / _cpus[i].currentTick * 100;
+ cores[i].loadNice = _cpus[i].loadNice / _cpus[i].currentTick * 100;
+ cores[i].loadIdle = _cpus[i].loadIdle / _cpus[i].currentTick * 100;
+ cores[i].loadIrq = _cpus[i].loadIrq / _cpus[i].currentTick * 100;
+ cores[i].rawLoad = _cpus[i].load;
+ cores[i].rawLoadUser = _cpus[i].loadUser;
+ cores[i].rawLoadSystem = _cpus[i].loadSystem;
+ cores[i].rawLoadNice = _cpus[i].loadNice;
+ cores[i].rawLoadIdle = _cpus[i].loadIdle;
+ cores[i].rawLoadIrq = _cpus[i].loadIrq;
+ }
+ let totalTick = totalUser + totalSystem + totalNice + totalIrq + totalIdle;
+ let totalLoad = totalUser + totalSystem + totalNice + totalIrq;
+ let currentTick = totalTick - _current_cpu.tick;
+ result = {
+ avgLoad: avgLoad,
+ currentLoad: (totalLoad - _current_cpu.load) / currentTick * 100,
+ currentLoadUser: (totalUser - _current_cpu.user) / currentTick * 100,
+ currentLoadSystem: (totalSystem - _current_cpu.system) / currentTick * 100,
+ currentLoadNice: (totalNice - _current_cpu.nice) / currentTick * 100,
+ currentLoadIdle: (totalIdle - _current_cpu.idle) / currentTick * 100,
+ currentLoadIrq: (totalIrq - _current_cpu.irq) / currentTick * 100,
+ rawCurrentLoad: (totalLoad - _current_cpu.load),
+ rawCurrentLoadUser: (totalUser - _current_cpu.user),
+ rawCurrentLoadSystem: (totalSystem - _current_cpu.system),
+ rawCurrentLoadNice: (totalNice - _current_cpu.nice),
+ rawCurrentLoadIdle: (totalIdle - _current_cpu.idle),
+ rawCurrentLoadIrq: (totalIrq - _current_cpu.irq),
+ cpus: cores
+ };
+ _current_cpu = {
+ user: totalUser,
+ nice: totalNice,
+ system: totalSystem,
+ idle: totalIdle,
+ irq: totalIrq,
+ tick: totalTick,
+ load: totalLoad,
+ ms: _current_cpu.ms,
+ currentLoad: result.currentLoad,
+ currentLoadUser: result.currentLoadUser,
+ currentLoadSystem: result.currentLoadSystem,
+ currentLoadNice: result.currentLoadNice,
+ currentLoadIdle: result.currentLoadIdle,
+ currentLoadIrq: result.currentLoadIrq,
+ rawCurrentLoad: result.rawCurrentLoad,
+ rawCurrentLoadUser: result.rawCurrentLoadUser,
+ rawCurrentLoadSystem: result.rawCurrentLoadSystem,
+ rawCurrentLoadNice: result.rawCurrentLoadNice,
+ rawCurrentLoadIdle: result.rawCurrentLoadIdle,
+ rawCurrentLoadIrq: result.rawCurrentLoadIrq,
+ };
+ } else {
+ let cores = [];
+ for (let i = 0; i < _corecount; i++) {
+ cores[i] = {};
+ cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100;
+ cores[i].loadUser = _cpus[i].loadUser / _cpus[i].currentTick * 100;
+ cores[i].loadSystem = _cpus[i].loadSystem / _cpus[i].currentTick * 100;
+ cores[i].loadNice = _cpus[i].loadNice / _cpus[i].currentTick * 100;
+ cores[i].loadIdle = _cpus[i].loadIdle / _cpus[i].currentTick * 100;
+ cores[i].loadIrq = _cpus[i].loadIrq / _cpus[i].currentTick * 100;
+ cores[i].rawLoad = _cpus[i].load;
+ cores[i].rawLoadUser = _cpus[i].loadUser;
+ cores[i].rawLoadSystem = _cpus[i].loadSystem;
+ cores[i].rawLoadNice = _cpus[i].loadNice;
+ cores[i].rawLoadIdle = _cpus[i].loadIdle;
+ cores[i].rawLoadIrq = _cpus[i].loadIrq;
+ }
+ result = {
+ avgLoad: avgLoad,
+ currentLoad: _current_cpu.currentLoad,
+ currentLoadUser: _current_cpu.currentLoadUser,
+ currentLoadSystem: _current_cpu.currentLoadSystem,
+ currentLoadNice: _current_cpu.currentLoadNice,
+ currentLoadIdle: _current_cpu.currentLoadIdle,
+ currentLoadIrq: _current_cpu.currentLoadIrq,
+ rawCurrentLoad: _current_cpu.rawCurrentLoad,
+ rawCurrentLoadUser: _current_cpu.rawCurrentLoadUser,
+ rawCurrentLoadSystem: _current_cpu.rawCurrentLoadSystem,
+ rawCurrentLoadNice: _current_cpu.rawCurrentLoadNice,
+ rawCurrentLoadIdle: _current_cpu.rawCurrentLoadIdle,
+ rawCurrentLoadIrq: _current_cpu.rawCurrentLoadIrq,
+ cpus: cores
+ };
+ }
+ resolve(result);
+ });
+ });
+}
+
+function currentLoad(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ getLoad().then(result => {
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ });
+ });
+}
+
+exports.currentLoad = currentLoad;
+
+// --------------------------
+// PS - full load
+// since bootup
+
+function getFullLoad() {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+
+ const cpus = os.cpus();
+ let totalUser = 0;
+ let totalSystem = 0;
+ let totalNice = 0;
+ let totalIrq = 0;
+ let totalIdle = 0;
+
+ let result = 0;
+
+ if (cpus && cpus.length) {
+ for (let i = 0, len = cpus.length; i < len; i++) {
+ const cpu = cpus[i].times;
+ totalUser += cpu.user;
+ totalSystem += cpu.sys;
+ totalNice += cpu.nice;
+ totalIrq += cpu.irq;
+ totalIdle += cpu.idle;
+ }
+ let totalTicks = totalIdle + totalIrq + totalNice + totalSystem + totalUser;
+ result = (totalTicks - totalIdle) / totalTicks * 100.0;
+
+ }
+ resolve(result);
+ });
+ });
+}
+
+function fullLoad(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ getFullLoad().then(result => {
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ });
+ });
+}
+
+exports.fullLoad = fullLoad;