Получение процента заряда батареи с клавиатуры и мыши 2,4 ГГц через NodeJs
У меня новая клавиатура и мышь, и я хочу иметь индикатор для обоих устройств на панели задач Windows 1.
Что-то вроде этого:Индикатор батареи на панели задач
Мои устройства:
- Razer Василиск Ultimate
- Клавиатура Nuphy Halo96 (довольно неизвестная компания по производству заказных клавиатур)
Итак, я искал решение и наткнулся на этот пост на Reddit, где кто-то использовал NodeJS (ElecronJS с библиотекой node-usb), чтобы получить процент заряда батареи мыши razer: https://www.reddit.com/r/razer/comments/zwz4rw/razer_battery_taskbar_monitor/
Я новичок в NodeJS и пытался воспроизвести это, но безуспешно. Любая помощь и совет по извлечению такой информации с USB-устройств будут приветствоваться.
Вот мой контент main.js:
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron');
const path = require('path');
const usb = require('usb');
let windows = [];
const webusb = new usb.WebUSB({
allowAllDevices: true
});
const showDevices = async () => {
const devices = await webusb.getDevices();
const text = devices.map(d => `${d.vendorId}\t${d.productId}\t${d.serialNumber || '<no serial>'}`);
text.unshift('VID\tPID\tSerial\n-------------------------------------');
windows.forEach(win => {
if (win) {
win.webContents.send('devices', text.join('\n'));
}
});
// const device = await usb.findByIds(1452, 598); // Keyboard
// const device = await usb.findByIds(5426, 136); // Mouse
let device;
try {
device = await webusb.requestDevice({
filters: [{
vendorId: 5426,
productId: 136
}]
})
} catch (err) {
// No device was selected.
console.log(err);
}
console.log(device);
if (device !== undefined) {
await device.open();
if (device.configuration === null)
await device.selectConfiguration(1);
await device.claimInterface(1);
const request = await device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x09,
value: 0x300,
index: 0x00
})
console.log(request);
}
};
const createWindow = () => {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
// and load the index.html of the app.
win.loadFile('index.html');
// Open the DevTools.
// win.webContents.openDevTools()
windows.push(win);
showDevices();
};
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
webusb.addEventListener('connect', showDevices);
webusb.addEventListener('disconnect', showDevices);
createWindow();
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
webusb.removeEventListener('connect', showDevices);
webusb.removeEventListener('disconnect', showDevices);
app.quit();
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
И мой вывод консоли (сначала попробуйте с мышью razer):
WebUSBDevice {
device: {
busNumber: 1,
deviceAddress: 18,
deviceDescriptor: {
bLength: 18,
bDescriptorType: 1,
bcdUSB: 512,
bDeviceClass: 0,
bDeviceSubClass: 0,
bDeviceProtocol: 0,
bMaxPacketSize0: 64,
idVendor: 5426,
idProduct: 136,
bcdDevice: 512,
iManufacturer: 1,
iProduct: 2,
iSerialNumber: 0,
bNumConfigurations: 1
},
portNumbers: [ 11 ],
interfaces: undefined
},
configurations: [
{
configurationValue: 1,
configurationName: '',
interfaces: [Array]
}
],
usbVersionMajor: 2,
usbVersionMinor: 0,
usbVersionSubminor: 0,
deviceClass: 0,
deviceSubclass: 0,
deviceProtocol: 0,
vendorId: 5426,
productId: 136,
deviceVersionMajor: 2,
deviceVersionMinor: 0,
deviceVersionSubminor: 0,
manufacturerName: 'Razer',
productName: 'Razer Basilisk Ultimate Dongle',
serialNumber: ''
}
(node:65280) UnhandledPromiseRejectionWarning: Error: controlTransferOut error: Error: LIBUSB_ERROR_INVALID_PARAM
at WebUSBDevice.<anonymous> (C:\Users\Fskng\node_modules\usb\dist\webusb\webusb-device.js:376:31)
at step (C:\Users\Fskng\node_modules\usb\dist\webusb\webusb-device.js:33:23)
at Object.throw (C:\Users\Fskng\node_modules\usb\dist\webusb\webusb-device.js:14:53)
at rejected (C:\Users\Fskng\node_modules\usb\dist\webusb\webusb-device.js:6:65)
at process.processTicksAndRejections (node:internal/process/task_queues:96:5)
(Use `electron --trace-warnings ...` to show where the warning was created)
(node:65280) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 6)
[63068:0124/213351.034:ERROR:gpu_init.cc(523)] Passthrough is not supported, GL is disabled, ANGLE is