systeminformation
Version:
Advanced, lightweight system and OS information library
1,653 lines (1,587 loc) • 71.2 kB
JavaScript
'use strict';
// @ts-check
// ==================================================================================
// cpu.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2026
// 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');
const _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,
steal: 0,
guest: 0,
load: 0,
tick: 0,
ms: 0,
currentLoad: 0,
currentLoadUser: 0,
currentLoadSystem: 0,
currentLoadNice: 0,
currentLoadIdle: 0,
currentLoadIrq: 0,
currentLoadSteal: 0,
currentLoadGuest: 0,
rawCurrentLoad: 0,
rawCurrentLoadUser: 0,
rawCurrentLoadSystem: 0,
rawCurrentLoadNice: 0,
rawCurrentLoadIdle: 0,
rawCurrentLoadIrq: 0,
rawCurrentLoadSteal: 0,
rawCurrentLoadGuest: 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)
'7773X': '2.2',
7763: '2.45',
7713: '2.0',
'7713P': '2.0',
7663: '2.0',
7643: '2.3',
'7573X': '2.8',
'75F3': '2.95',
7543: '2.8',
'7543P': '2.8',
7513: '2.6',
'7473X': '2.8',
7453: '2.75',
'74F3': '3.2',
7443: '2.85',
'7443P': '2.85',
7413: '2.65',
'7373X': '3.05',
'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',
'5945WX': '4.1',
'5955WX': '4.0',
'5965WX': '3.8',
'5975WX': '3.6',
'5995WX': '2.7',
'7960X': '4.2',
'7970X': '4.0',
'7980X': '3.2',
'7965WX': '4.2',
'7975WX': '4.0',
'7985WX': '3.2',
'7995WX': '2.5',
// ZEN4
9754: '2.25',
'9754S': '2.25',
9734: '2.2',
'9684X': '2.55',
'9384X': '3.1',
'9184X': '3.55',
'9654P': '2.4',
9654: '2.4',
9634: '2.25',
'9554P': '3.1',
9554: '3.1',
9534: '2.45',
'9474F': '3.6',
'9454P': '2.75',
9454: '2.75',
'9374F': '3.85',
'9354P': '3.25',
9354: '3.25',
9334: '2.7',
'9274F': '4.05',
9254: '2.9',
9224: '2.5',
'9174F': '4.1',
9124: '3.0',
// Epyc 4th gen
'4124P': '3.8',
'4244P': '3.8',
'4344P': '3.8',
'4364P': '4.5',
'4464P': '3.7',
'4484PX': '4.4',
'4564P': '4.5',
'4584PX': '4.2',
'8024P': '2.4',
'8024PN': '2.05',
'8124P': '2.45',
'8124PN': '2.0',
'8224P': '2.55',
'8224PN': '2.0',
'8324P': '2.65',
'8324PN': '2.05',
'8434P': '2.5',
'8434PN': '2.0',
'8534P': '2.3',
'8534PN': '2.0',
// Epyc 5th gen
9115: '2.6',
9135: '3.65',
'9175F': '4.2',
9255: '3.25',
'9275F': '4.1',
9335: '3.0',
'9355P': '3.55',
9355: '3.55',
'9375F': '3.8',
9365: '3.4',
'9455P': '3.15',
9455: '3.15',
'9475F': '3.65',
9535: '2.4',
'9555P': '3.2',
9555: '3.2',
'9575F': '3.3',
9565: '3.15',
'9655P': '2.5',
9655: '2.5',
9755: '2.7',
'4245P': '3.9',
'4345P': '3.8',
'4465P': '3.4',
'4545P': '3.0',
'4565P': '4.3',
'4585PX': '4.3',
'5900XT': '3.3',
5900: '3.0',
5945: '3.0',
'5800X3D': '3.4',
'5800XT': '3.8',
5800: '3.4',
'5700X3D': '3.0',
'5700X': '3.4',
5845: '3.4',
'5600X3D': '3.3',
'5600XT': '3.7',
'5600T': '3.5',
5600: '3.5',
'5600F': '3.0',
5645: '3.7',
'5500X3D': '3.0',
'5980HX': '3.3',
'5980HS': '3.0',
'5900HX': '3.3',
'5900HS': '3.0',
'5800H': '3.2',
'5800HS': '2.8',
'5800U': '1.9',
'5600H': '3.3',
'5600HS': '3.0',
'5600U': '2.3',
'5560U': '2.3',
'5400U': '2.7',
'5825U': '2.0',
'5625U': '2.3',
'5425U': '2.7',
'5125C': '3.0',
'7730U': '2.0',
'7530U': '2.0',
'7430U': '2.3',
'7330U': '2.3',
7203: '2.8',
7303: '2.4',
'7663P': '2.0',
'6980HX': '3.3',
'6980HS': '3.3',
'6900HX': '3.3',
'6900HS': '3.3',
'6800H': '3.2',
'6800HS': '3.2',
'6800U': '2.7',
'6600H': '3.3',
'6600HS': '3.3',
'6600U': '2.9',
'7735HS': '3.2',
'7735H': '3.2',
'7736U': '2.7',
'7735U': '2.7',
'7435HS': '3.1',
'7435H': '3.1',
'7535HS': '3.3',
'7535H': '3.3',
'7535U': '2.9',
'7235HS': '3.2',
'7235H': '3.2',
'7335U': '3.0',
270: '4.0',
260: '3.8',
250: '3.3',
240: '4.3',
230: '3.5',
220: '3.0',
210: '2.8',
'8945HS': '4.0',
'8845HS': '3.8',
'8840HS': '3.3',
'8840U': '3.3',
'8645HS': '4.3',
'8640HS': '3.5',
'8640U': '3.5',
'8540U': '3.0',
'8440U': '2.8',
'9950X3D': '4.3',
'9950X': '4.3',
'9900X3D': '4.4',
'9900X': '4.4',
'9800X3D': '4.7',
'9700X': '3.8',
'9700F': '3.8',
'9600X': '3.9',
9600: '3.8',
'9500F': '3.8',
'9995WX': '2.5',
'9985WX': '3.2',
'9975WX': '4.0',
'9965WX': '4.2',
'9955WX': '4.5',
'9945WX': '4.7',
'9980X': '3.2',
'9970X': '4.0',
'9960X': '4.2',
'PRO HX375': '2.0',
HX375: '2.0',
'PRO HX370': '2.0',
HX370: '2.0',
365: '2.0',
'PRO 360': '2.0',
350: '2.0',
'PRO 350': '2.0',
340: '2.0',
'PRO 340': '2.0',
330: '2.0',
395: '3.0',
'PRO 395': '3.0',
390: '3.2',
'PRO 390': '3.2',
385: '3.6',
'PRO 385': '3.6',
'PRO 380': '3.6',
'9955HX3D': '2.3',
'9955HX': '2.5',
'9850HX': '3.0',
9015: '3.6',
9965: '2.25',
9845: '2.1',
9825: '2.2',
9745: '2.4',
9645: '2.3'
};
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',
64: 'LGA1700',
65: 'BGA1744',
66: 'BGA1781',
67: 'BGA1211',
68: 'BGA2422',
69: 'LGA1211',
70: 'LGA2422',
71: 'LGA5773',
72: 'BGA5773',
73: 'AM5',
74: 'SP5',
75: 'SP6',
76: 'BGA883',
77: 'BGA1190',
78: 'BGA4129',
79: 'LGA4710',
80: 'LGA7529',
81: 'BGA1964',
82: 'BGA1792',
83: 'BGA2049',
84: 'BGA2551',
85: 'LGA1851',
86: 'BGA2114',
87: 'BGA2833'
};
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(' ');
names.forEach((element) => {
if (str.indexOf(element) >= 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';
}
if (str.indexOf('sifive') >= 0) {
result = 'SiFive';
}
if (str.indexOf('thead') >= 0) {
result = 'T-Head';
}
if (str.indexOf('andestech') >= 0) {
result = 'Andes Technology';
}
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', (error, stdout) => {
const 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') {
result.socket = 'SOC';
try {
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.efficiencyCores = efficiencyCores;
result.performanceCores = performanceCores;
} catch {
util.noop();
}
}
if (countProcessors) {
result.processors = parseInt(countProcessors, 10) || 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', (error, stdout) => {
if (!error) {
lines = stdout.toString().split('\n');
}
modelline = util.getValue(lines, 'model name') || modelline;
modelline = util.getValue(lines, 'bios model name') || modelline;
modelline = util.cleanString(modelline);
const modellineParts = modelline.split('@');
result.brand = modellineParts[0].trim();
if (result.brand.indexOf('Unknown') >= 0) {
result.brand = result.brand.split('Unknown')[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';
const threadsPerCoreInt = parseInt(threadsPerCore, 10); // threads per code (normally only for performance cores)
const 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' && util.isRaspberry()) {
const rPIRevision = util.decodePiCpuinfo();
result.family = result.manufacturer;
result.manufacturer = rPIRevision.manufacturer;
result.brand = rPIRevision.processor;
result.revision = rPIRevision.revisionCode;
result.socket = 'SOC';
}
// Test RISC-V
if (util.getValue(lines, 'architecture') === 'riscv64') {
const linesRiscV = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
const uarch = util.getValue(linesRiscV, 'uarch') || '';
if (uarch.indexOf(',') > -1) {
const split = uarch.split(',');
result.manufacturer = cpuManufacturer(split[0]);
result.brand = split[1];
}
}
// socket type
let lines2 = [];
exec('export LC_ALL=C; dmidecode –t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', (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', (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-CimInstance Win32_processor | select Name, Revision, L2CacheSize, L3CacheSize, Manufacturer, MaxClockSpeed, Description, UpgradeMethod, Caption, NumberOfLogicalProcessors, NumberOfCores | fl'
)
);
workload.push(util.powerShell('Get-CimInstance 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.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;
}
result.cache = parseWinCache(data[0], data[1]);
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() {
const cpus = os.cpus();
let minFreq = 999999999;
let maxFreq = 0;
let avgFreq = 0;
const cores = [];
const speeds = [];
if (cpus && cpus.length && Object.prototype.hasOwnProperty.call(cpus[0], 'speed')) {
for (let i in cpus) {
speeds.push(cpus[i].speed > 100 ? (cpus[i].speed + 1) / 1000 : cpus[i].speed / 10);
}
} else if (_linux) {
try {
const speedStrings = execSync('cat /proc/cpuinfo | grep "cpu MHz" | cut -d " " -f 3', util.execOptsLinux)
.toString()
.split('\n')
.filter((line) => line.length > 0);
for (let i in speedStrings) {
speeds.push(Math.floor(parseInt(speedStrings[i], 10) / 10) / 100);
}
} catch {
util.noop();
}
}
if (speeds && speeds.length) {
try {
for (const i in speeds) {
avgFreq = avgFreq + speeds[i];
if (speeds[i] > maxFreq) {
maxFreq = speeds[i];
}
if (speeds[i] < minFreq) {
minFreq = speeds[i];
}
cores.push(parseFloat(speeds[i].toFixed(2)));
}
avgFreq = avgFreq / speeds.length;
return {
min: parseFloat(minFreq.toFixed(2)),
max: parseFloat(maxFreq.toFixed(2)),
avg: parseFloat(avgFreq.toFixed(2)),
cores: cores
};
} catch (e) {
return {
min: 0,
max: 0,
avg: 0,
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, util.execOptsLinux).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, (error, stdout) => {
stdout = stdout.toString();
const tdiePos = stdout.toLowerCase().indexOf('tdie');
if (tdiePos !== -1) {
stdout = stdout.substring(tdiePos);
}
const lines = stdout.split('\n');
let tctl = 0;
lines.forEach((line) => {
const parts = line.split('___');
const label = parts[0];
const value = parts.length > 1 && parts[1] ? parts[1] : '0';
if (value && label && label.toLowerCase() === 'tctl') {
tctl = result.main = Math.round(parseInt(value, 10) / 100) / 10;
}
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 && (label.toLowerCase().indexOf('package') >= 0 || label.toLowerCase().indexOf('physical') >= 0 || label.toLowerCase() === 'tccd1')) {
result.main = Math.round(parseInt(value, 10) / 100) / 10;
}
});
if (tctl && result.main === null) {
result.main = tctl;
}
if (result.cores.length > 0) {
if (result.main === null) {
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', (error, stdout) => {
if (!error) {
const lines = stdout.toString().split('\n');
let tdieTemp = null;
let newSectionStarts = true;
let section = '';
lines.forEach((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';
}
if (line.trim().toLowerCase().startsWith('k10temp')) {
section = 'coreAMD';
}
newSectionStarts = false;
}
const regex = /[+-]([^°]*)/g;
const temps = line.match(regex);
const 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) {
result.chipset = parseFloat(temps);
}
}
// cpu temp
if (firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1 || (section === 'coreAMD' && firstPart.indexOf('TDIE') !== -1) || firstPart.indexOf('TEMP') !== -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);
const 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) {
result.max = result.main;
}
if (result.main !== null || result.max !== null) {
if (callback) {
callback(result);
}
resolve(result);
return;
}
}
fs.stat('/sys/class/thermal/thermal_zone0/temp', (err) => {
if (err === null) {
fs.readFile('/sys/class/thermal/thermal_zone0/temp', (error, stdout) => {
if (!error) {
const 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', (error, stdout) => {
if (!error) {
const 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 {
if (callback) {
callback(result);
}
resolve(result);
}
}
if (_freebsd || _openbsd || _netbsd) {
exec('sysctl dev.cpu | grep temp', (error, stdout) => {
if (!error) {
const lines = stdout.toString().split('\n');
let sum = 0;
lines.forEach((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) {
try {
const osxTemp = require('osx-temperature-sensor');
result = osxTemp.cpuTemperature();
if (result.main) {
// round to 2 digits
result.main = Math.round(result.main * 100) / 100;
}
if (result.max) {
result.max = Math.round(result.max * 100) / 100;
}
if (result && result.cores && result.cores.length) {
for (let i = 0; i < result.cores.length; i++) {
result.cores[i] = Math.round(result.cores[i] * 100) / 100;
}
}
} catch {
util.noop();
}
try {
const macosTemp = require('macos-temperature-sensor');
const res = macosTemp.temperature();
if (res.cpu) {
// round to 2 digits
result.main = Math.round(res.cpu * 100) / 100;
result.max = result.main;
}
if (res.soc) {
// round to 2 digits
result.chipset = Math.round(res.soc * 100) / 100;
}
if (res && res.cpuDieTemps.length) {
for (const temp of res.cpuDieTemps) {
result.cores.push(Math.round(temp * 100) / 100);
}
}
} catch {
util.noop();
}
if (callback) {
callback(result);
}
resolve(result);
}
if (_sunos) {
if (callback) {
callback(result);
}
resolve(result);
}
if (_windows) {
try {
util.powerShell('Get-CimInstance MSAcpi_ThermalZoneTemperature -Namespace "root/wmi" | Select CurrentTemperature').then((stdout, error) => {
if (!error) {
let sum = 0;
const lines = stdout
.split('\r\n')
.filter((line) => line.trim() !== '')
.filter((line, idx) => idx > 0);
lines.forEach((line) => {
const 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 {
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, (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',