Last active
May 2, 2020 14:24
-
-
Save aetheryx/5e4b79e0edbdc1db3d53f765f2aad0cb to your computer and use it in GitHub Desktop.
arctis-7-tasmota; a small application to map the ChatMix slider on the SteelSeries Arctis 7 to a smart bulb running Tasmota (https://youtu.be/X5MLXNftdC4)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const HID = require('node-hid'); | |
const mqtt = require('mqtt'); | |
const config = { | |
/** | |
* The amount of times (per second) your headset gets polled. | |
* Higher = smoother, but more battery-hungry. | |
* In my experience setting this higher than 100 will cause your headset, Windows, or both to shit themselves. | |
*/ | |
pollingRate: 10, | |
/** | |
* Change this to your Tasmota MQTT broker IP. | |
*/ | |
brokerIP: '192.168.178.20' | |
}; | |
const constants = { | |
VENDOR_ID: 0x1038, | |
PRODUCT_ID: 0x12AD, | |
USAGE_ID: 0x202, | |
POLL_PAYLOAD: [ 0x06, 0x24 ], | |
DIMMER_COMMAND: 'cmnd/bulb/Dimmer' | |
}; | |
console.log( | |
'='.repeat(80) + '\n\n' + | |
' '.repeat(32) + 'arctis-7-tasmota' + '\n\n' + | |
'A small application to map the ChatMix slider on the SteelSeries Arctis 7\n' + | |
'to a smart bulb running Tasmota (https://github.com/arendst/Sonoff-Tasmota).\n' + | |
'Use at your own risk; albeit unlikely, I\'m not liable for any bricked devices.\n' + | |
'You can see a short preview here: https://youtu.be/X5MLXNftdC4\n\n' + | |
'='.repeat(80) + '\n\n' | |
); | |
const deviceData = HID.devices() | |
.find(device => ( | |
device.vendorId === constants.VENDOR_ID && | |
device.productId === constants.PRODUCT_ID && | |
(process.platform !== 'win32' ^ (device.usage === constants.USAGE_ID)) | |
)); | |
if (!deviceData) { | |
console.error('Unable to detect an Arctis 7 plugged in. Exiting...'); | |
process.exit(1); | |
} | |
const device = new HID.HID(deviceData.path); | |
const client = mqtt.connect(`tcp://${config.brokerIP}`); | |
client.on('connect', () => { | |
console.log('Established connection with MQTT broker'); | |
}); | |
let oldValue = -1; | |
device.on('data', (payload) => { | |
if (oldValue === -1) { | |
console.log('Successfully polling position at', config.pollingRate, 'Hz'); | |
} | |
const getValue = (offset) => (payload.readInt8(offset) / -64) * 100; | |
const [ game, chat ] = [ 2, 3 ].map(getValue); | |
const newValue = Math.abs(game || chat); | |
if (newValue !== oldValue) { | |
client.publish( | |
constants.DIMMER_COMMAND, | |
(oldValue = newValue).toString() | |
); | |
} | |
}); | |
setInterval(() => { | |
try { | |
device.write(constants.POLL_PAYLOAD); | |
} catch (err) { | |
if (err.message === 'Cannot write to HID device') { | |
console.error( | |
'Failed at writing payload to device.', | |
'Try:\n', | |
' - Ensuring your polling rate isn\'t too high\n', | |
' - Ensuring you\'re running under sudo if you\'re not on Windows\n', | |
' - Ensuring your device is detected properly by SSE\n', | |
' - Turning your headset off, plugging the wireless transmitter out and back in, then turning your headset back on', | |
' - Reinstalling the device drivers entirely (including the 50 trillion entries under Windows\' Device Manager)', | |
); | |
} else { | |
console.error(err); | |
} | |
process.exit(1); | |
} | |
}, 1000 / config.pollingRate); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment