bluetooth() adapted parsing to acceptü also new profile (mac OS)

This commit is contained in:
Sebastian Hildebrandt 2022-10-25 07:23:41 +02:00
parent 0136bd5c99
commit fbd0207b7e
10 changed files with 114 additions and 89 deletions

View File

@ -80,6 +80,7 @@ For major (breaking) changes - **version 4, 3 and 2** - see end of page.
| Version | Date | Comment |
| ------- | ---------- | --------------------------------------------------------------------------------------------------- |
| 5.12.10 | 2022-10-25 | `bluetooth()` adapted parsing to acceptü also new profile (mac OS) |
| 5.12.9 | 2022-10-24 | fix typescript typings, code cleanup, docs updated |
| 5.12.8 | 2022-10-23 | `processes()` fix truncated commands (windows) |
| 5.12.7 | 2022-10-15 | `versions()` fix postgres |

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2021 Sebastian Hildebrandt
Copyright (c) 2014-2022 Sebastian Hildebrandt
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@ -1024,7 +1024,7 @@ All other trademarks are the property of their respective owners.
>The [`MIT`][license-url] License (MIT)
>
>Copyright © 2014-2021 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com).
>Copyright © 2014-2022 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com).
>
>Permission is hereby granted, free of charge, to any person obtaining a copy
>of this software and associated documentation files (the "Software"), to deal

View File

@ -30,7 +30,7 @@
<body>
<nav class="nav">
<div class="container">
<a href="."><img class="logo float-left" src="assets/logo.png">
<a href="."><img class="logo float-left" src="assets/logo.png" alt="logo">
<div class="title float-left">systeminformation</div>
</a>
<div class="text float-right github"><a href="https://github.com/sebhildebrandt/systeminformation">View on Github <i class="fab fa-github"></i></a></div>

View File

@ -49,7 +49,7 @@
<div class="col-12 sectionheader">
<div>&nbsp;</div>
<h4>Software:</h4>
<div class="text">&copy; 2021 Sebstian Hildebrandt, <a href="https://github.com/sebhildebrandt/"> <i class="fab fa-github"></i> sebhildebrandt</a>, <a href="https://www.plus-innovations.com"><i class="fal fa-globe"></i> +innovations</a></div>
<div class="text">&copy; 2022 Sebstian Hildebrandt, <a href="https://github.com/sebhildebrandt/"> <i class="fab fa-github"></i> sebhildebrandt</a>, <a href="https://www.plus-innovations.com"><i class="fal fa-globe"></i> +innovations</a></div>
</div>
</div>

View File

@ -57,6 +57,11 @@
</tr>
</thead>
<tbody>
<tr>
<th scope="row">5.12.10</th>
<td>2022-10-25</td>
<td><span class="code">bluetoothDevices()</span> adapted to new profile (mac OS)</td>
</tr>
<tr>
<th scope="row">5.12.9</th>
<td>2022-10-24</td>

View File

@ -170,7 +170,7 @@
<img class="logo" src="assets/logo.png" alt="logo">
<div class="title">systeminformation</div>
<div class="subtitle"><span id="typed"></span>&nbsp;</div>
<div class="version">New Version: <span id="version">5.12.9</span></div>
<div class="version">New Version: <span id="version">5.12.10</span></div>
<button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button>
</div>
<div class="down">
@ -206,7 +206,7 @@
</div>
<div class="row number-section">
<div class="col-xl-4 col-lg-4 col-md-4 col-12">
<div class="numbers">15,315</div>
<div class="numbers">15,217</div>
<div class="title">Lines of code</div>
</div>
<div class="col-xl-4 col-lg-4 col-md-4 col-12">

View File

@ -37,6 +37,25 @@ function parseBluetoothType(str) {
if (str.indexOf('speaker') >= 0) { result = 'Speaker'; }
if (str.indexOf('headset') >= 0) { result = 'Headset'; }
if (str.indexOf('phone') >= 0) { result = 'Phone'; }
if (str.indexOf('macbook') >= 0) { result = 'Computer'; }
if (str.indexOf('imac') >= 0) { result = 'Computer'; }
if (str.indexOf('ipad') >= 0) { result = 'Tablet'; }
if (str.indexOf('watch') >= 0) { result = 'Watch'; }
if (str.indexOf('headphone') >= 0) { result = 'Headset'; }
// to be continued ...
return result;
}
function parseBluetoothManufacturer(str) {
let result = str.split(' ')[0];
str = str.toLowerCase();
if (str.indexOf('apple') >= 0) { result = 'Apple'; }
if (str.indexOf('ipad') >= 0) { result = 'Apple'; }
if (str.indexOf('imac') >= 0) { result = 'Apple'; }
if (str.indexOf('iphone') >= 0) { result = 'Apple'; }
if (str.indexOf('magic mouse') >= 0) { result = 'Apple'; }
if (str.indexOf('macbook') >= 0) { result = 'Apple'; }
// to be continued ...
return result;
@ -59,12 +78,12 @@ function parseLinuxBluetoothInfo(lines, macAddr1, macAddr2) {
function parseDarwinBluetoothDevices(bluetoothObject, macAddr2) {
const result = {};
const typeStr = ((bluetoothObject.device_minorClassOfDevice_string || bluetoothObject.device_majorClassOfDevice_string || '') + (bluetoothObject.device_name || '')).toLowerCase();
const typeStr = ((bluetoothObject.device_minorClassOfDevice_string || bluetoothObject.device_majorClassOfDevice_string || bluetoothObject.device_minorType || '') + (bluetoothObject.device_name || '')).toLowerCase();
result.device = bluetoothObject.device_services || '';
result.name = bluetoothObject.device_name || '';
result.manufacturer = bluetoothObject.device_manufacturer || '';
result.macDevice = (bluetoothObject.device_addr || '').toLowerCase().replace(/-/g, ':');
result.manufacturer = bluetoothObject.device_manufacturer || parseBluetoothManufacturer(bluetoothObject.device_name || '') || '';
result.macDevice = (bluetoothObject.device_addr || bluetoothObject.device_address || '').toLowerCase().replace(/-/g, ':');
result.macHost = macAddr2;
result.batteryPercent = bluetoothObject.device_batteryPercent || null;
result.type = parseBluetoothType(typeStr);
@ -96,16 +115,16 @@ function bluetoothDevices(callback) {
if (_linux) {
// get files in /var/lib/bluetooth/ recursive
const btFiles = util.getFilesInPath('/var/lib/bluetooth/');
for (let i = 0; i < btFiles.length; i++) {
const filename = path.basename(btFiles[i]);
const pathParts = btFiles[i].split('/');
btFiles.forEach((element) => {
const filename = path.basename(element);
const pathParts = element.split('/');
const macAddr1 = pathParts.length >= 6 ? pathParts[pathParts.length - 2] : null;
const macAddr2 = pathParts.length >= 7 ? pathParts[pathParts.length - 3] : null;
if (filename === 'info') {
const infoFile = fs.readFileSync(btFiles[i], { encoding: 'utf8' }).split('\n');
const infoFile = fs.readFileSync(element, { encoding: 'utf8' }).split('\n');
result.push(parseLinuxBluetoothInfo(infoFile, macAddr1, macAddr2));
}
}
});
// determine "connected" with hcitool con
try {
const hdicon = execSync('hcitool con').toString().toLowerCase();
@ -135,9 +154,8 @@ function bluetoothDevices(callback) {
if (outObj.SPBluetoothDataType[0]['local_device_title'] && outObj.SPBluetoothDataType[0].local_device_title.general_address) {
macAddr2 = outObj.SPBluetoothDataType[0].local_device_title.general_address.toLowerCase().replace(/-/g, ':');
}
for (let i = 0; i < outObj.SPBluetoothDataType[0]['device_title'].length; i++) {
const obj = outObj.SPBluetoothDataType[0]['device_title'][i];
outObj.SPBluetoothDataType[0]['device_title'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
@ -145,7 +163,35 @@ function bluetoothDevices(callback) {
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
}
});
}
if (outObj.SPBluetoothDataType && outObj.SPBluetoothDataType.length && outObj.SPBluetoothDataType[0] && outObj.SPBluetoothDataType[0]['device_connected'] && outObj.SPBluetoothDataType[0]['device_connected'].length) {
const macAddr2 = outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':') : null;
outObj.SPBluetoothDataType[0]['device_connected'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
innerObject.device_name = objKey[0];
innerObject.device_isconnected = 'attrib_Yes';
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
});
}
if (outObj.SPBluetoothDataType && outObj.SPBluetoothDataType.length && outObj.SPBluetoothDataType[0] && outObj.SPBluetoothDataType[0]['device_not_connected'] && outObj.SPBluetoothDataType[0]['device_not_connected'].length) {
const macAddr2 = outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':') : null;
outObj.SPBluetoothDataType[0]['device_not_connected'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
innerObject.device_name = objKey[0];
innerObject.device_isconnected = 'attrib_No';
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
});
}
} catch (e) {
util.noop();
@ -161,11 +207,11 @@ function bluetoothDevices(callback) {
util.powerShell('Get-WmiObject Win32_PNPEntity | select PNPClass, Name, Manufacturer | fl').then((stdout, error) => {
if (!error) {
const parts = stdout.toString().split(/\n\s*\n/);
for (let i = 0; i < parts.length; i++) {
if (util.getValue(parts[i].split('\n'), 'PNPClass', ':') === 'Bluetooth') {
result.push(parseWindowsBluetooth(parts[i].split('\n')));
parts.forEach((part) => {
if (util.getValue(part.split('\n'), 'PNPClass', ':') === 'Bluetooth') {
result.push(parseWindowsBluetooth(part.split('\n')));
}
}
});
}
if (callback) {
callback(result);

View File

@ -253,8 +253,8 @@ function services(srv, callback) {
// process
let list_new = {};
let resultProcess = {};
for (let i = 0; i < curr_processes.length; i++) {
resultProcess = calcProcStatLinux(curr_processes[i], all, _services_cpu);
curr_processes.forEach((element) => {
resultProcess = calcProcStatLinux(element, all, _services_cpu);
if (resultProcess.pid) {
let listPos = -1;
@ -279,7 +279,7 @@ function services(srv, callback) {
cstime: resultProcess.cstime
};
}
}
});
// store old values
_services_cpu.all = all;
@ -338,18 +338,18 @@ function services(srv, callback) {
let wincommand = 'Get-WmiObject Win32_Service';
if (srvs[0] !== '*') {
wincommand += ' -Filter "';
for (let i = 0; i < srvs.length; i++) {
wincommand += `Name='${srvs[i]}' or `;
}
srvs.forEach((srv) => {
wincommand += `Name='${srv}' or `;
});
wincommand = `${wincommand.slice(0, -4)}"`;
}
wincommand += ' | select Name,Caption,Started,StartMode,ProcessId | fl';
util.powerShell(wincommand).then((stdout, error) => {
if (!error) {
let serviceSections = stdout.split(/\n\s*\n/);
for (let i = 0; i < serviceSections.length; i++) {
if (serviceSections[i].trim() !== '') {
let lines = serviceSections[i].trim().split('\r\n');
serviceSections.forEach((element) => {
if (element.trim() !== '') {
let lines = element.trim().split('\r\n');
let srvName = util.getValue(lines, 'Name', ':', true).toLowerCase();
let srvCaption = util.getValue(lines, 'Caption', ':', true).toLowerCase();
let started = util.getValue(lines, 'Started', ':', true);
@ -368,7 +368,9 @@ function services(srv, callback) {
dataSrv.push(srvCaption);
}
}
}
});
if (srvString !== '*') {
let srvsMissing = srvs.filter(function (e) {
return dataSrv.indexOf(e) === -1;
@ -740,9 +742,9 @@ function processes(callback) {
if (_linux) {
// calc process_cpu - ps is not accurate in linux!
cmd = 'cat /proc/stat | grep "cpu "';
for (let i = 0; i < result.list.length; i++) {
cmd += (';cat /proc/' + result.list[i].pid + '/stat');
}
result.list.forEach((element) => {
cmd += (';cat /proc/' + element.pid + '/stat');
});
exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
let curr_processes = stdout.toString().split('\n');
@ -752,8 +754,8 @@ function processes(callback) {
// process
let list_new = {};
let resultProcess = {};
for (let i = 0; i < curr_processes.length; i++) {
resultProcess = calcProcStatLinux(curr_processes[i], all, _processes_cpu);
curr_processes.forEach((element) => {
resultProcess = calcProcStatLinux(element, all, _processes_cpu);
if (resultProcess.pid) {
@ -775,7 +777,7 @@ function processes(callback) {
cstime: resultProcess.cstime
};
}
}
});
// store old values
_processes_cpu.all = all;
@ -829,9 +831,9 @@ function processes(callback) {
let list_new = {};
let allcpuu = 0;
let allcpus = 0;
for (let i = 0; i < processSections.length; i++) {
if (processSections[i].trim() !== '') {
let lines = processSections[i].trim().split('\r\n');
processSections.forEach((element) => {
if (element.trim() !== '') {
let lines = element.trim().split('\r\n');
let pid = parseInt(util.getValue(lines, 'ProcessId', ':', true), 10);
let parentPid = parseInt(util.getValue(lines, 'ParentProcessId', ':', true), 10);
let statusValue = util.getValue(lines, 'ExecutionState', ':');
@ -889,11 +891,12 @@ function processes(callback) {
params: ''
});
}
}
});
result.sleeping = result.all - result.running - result.blocked - result.unknown;
result.list = procs;
for (let i = 0; i < procStats.length; i++) {
let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _processes_cpu);
procStats.forEach((element) => {
let resultProcess = calcProcStatWin(element, allcpuu + allcpus, _processes_cpu);
// store pcpu in outer array
let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
@ -910,7 +913,8 @@ function processes(callback) {
utime: resultProcess.utime,
stime: resultProcess.stime
};
}
});
// store old values
_processes_cpu.all = allcpuu + allcpus;
_processes_cpu.all_utime = allcpuu;
@ -972,7 +976,7 @@ function processLoad(proc, callback) {
const s = util.sanitizeShellString(proc);
for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) {
if (s[i] !== undefined) {
processesString = processesString + s[i];
}
}
@ -1008,9 +1012,9 @@ function processLoad(proc, callback) {
let allcpus = 0;
// go through all processes
for (let i = 0; i < processSections.length; i++) {
if (processSections[i].trim() !== '') {
let lines = processSections[i].trim().split('\r\n');
processSections.forEach((element) => {
if (element.trim() !== '') {
let lines = element.trim().split('\r\n');
let pid = parseInt(util.getValue(lines, 'ProcessId', ':', true), 10);
let name = util.getValue(lines, 'Caption', ':', true);
let utime = parseInt(util.getValue(lines, 'UserModeTime', ':', true), 10);
@ -1058,7 +1062,8 @@ function processLoad(proc, callback) {
}
}
}
}
});
// add missing processes
if (processesString !== '*') {
let processesMissing = processes.filter(function (name) {
@ -1077,8 +1082,8 @@ function processLoad(proc, callback) {
}
// calculate proc stats for each proc
for (let i = 0; i < procStats.length; i++) {
let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _process_cpu);
procStats.forEach((element) => {
let resultProcess = calcProcStatWin(element, allcpuu + allcpus, _process_cpu);
let listPos = -1;
for (let j = 0; j < result.length; j++) {
@ -1095,7 +1100,8 @@ function processLoad(proc, callback) {
utime: resultProcess.utime,
stime: resultProcess.stime
};
}
});
// store old values
_process_cpu.all = allcpuu + allcpus;
_process_cpu.all_utime = allcpuu;
@ -1210,9 +1216,8 @@ function processLoad(proc, callback) {
// process
let list_new = {};
let resultProcess = {};
for (let i = 0; i < curr_processes.length; i++) {
resultProcess = calcProcStatLinux(curr_processes[i], all, _process_cpu);
curr_processes.forEach((element) => {
resultProcess = calcProcStatLinux(element, all, _process_cpu);
if (resultProcess.pid) {
@ -1238,7 +1243,7 @@ function processLoad(proc, callback) {
cstime: resultProcess.cstime
};
}
}
});
result.forEach(function (item) {
item.cpu = Math.round(item.cpu * 100) / 100;

View File

@ -14,9 +14,7 @@
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
// const execSync = require('child_process').execSync;
const util = require('./util');
// const fs = require('fs');
let _platform = process.platform;
@ -91,16 +89,6 @@ function parseLinuxUsb(usb) {
return result;
}
// bus
// deviceId
// id
// name(product)
// type(bInterfaceClass)
// removable / hotplug
// vendor
// manufacturer
// maxpower(linux)
function getDarwinUsbType(name) {
let result = '';
if (name.indexOf('camera') >= 0) { result = 'Camera'; }
@ -164,25 +152,6 @@ function parseDarwinUsb(usb, id) {
}
}
// function getWindowsUsbType(service) {
// let result = ''
// if (service.indexOf('usbhub3') >= 0) { result = 'Hub'; }
// else if (service.indexOf('usbstor') >= 0) { result = 'Storage'; }
// else if (service.indexOf('hidusb') >= 0) { result = 'Input'; }
// else if (service.indexOf('usbccgp') >= 0) { result = 'Controller'; }
// else if (service.indexOf('usbxhci') >= 0) { result = 'Controller'; }
// else if (service.indexOf('usbehci') >= 0) { result = 'Controller'; }
// else if (service.indexOf('kbdhid') >= 0) { result = 'Keyboard'; }
// else if (service.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
// else if (service.indexOf('pointing') >= 0) { result = 'Mouse'; }
// else if (service.indexOf('disk') >= 0) { result = 'Storage'; }
// else if (service.indexOf('usbhub') >= 0) { result = 'Hub'; }
// else if (service.indexOf('bthusb') >= 0) { result = ''; }
// else if (service.indexOf('bth') >= 0) { result = ''; }
// else if (service.indexOf('rfcomm') >= 0) { result = ''; }
// return result;
// }
function getWindowsUsbTypeCreation(creationclass, name) {
let result = '';
if (name.indexOf('storage') >= 0) { result = 'Storage'; }
@ -216,7 +185,6 @@ function parseWindowsUsb(lines, id) {
} else {
return null;
}
}
function usb(callback) {