Generic devices help - Microsoft Presenter+

Hoping to seek a little bit of guidance from the wise, I have a Microsoft Presenter+ that connects via Bluetooth. The Slide forward / back, and also mouse pointer buttons work just fine out of the box.

I'm trying to map the other two buttons on the device to keyboard shortcuts, because why not (the buttons are to join teams call & mute.....but obviously with the amazing BTT can be anything).

I've had a look at the instructions, however my issue is that the Analyser shows me that the buttons change the values across two indexes (1 & 2) in the same report (#4)....just not sure how to code this up as the example is only for a single value in one index (hope I've explained this ok).

Here is a picture that should clear up my confused outline above.

image

Where:
04 3f 01 = Mute button pressed
04 3f 00 = Mute button not pressed
04 3e 01 = Teams button pressed
04 3e 00 = Teams button not pressed

Thanks for any help or guidance.

you just need to adapt the IF condition to contain all of the bytes:

e.g.

// Enter your input analyzer script here. 
// Do not change the function signatures
function analyzeDeviceInput(targetDevice, reportID, reportDataHex) {
      
	let reportBuffer = buffer.Buffer.from(reportDataHex, 'hex');
    // the values you see above are in hex format. To read such a byte
    // use readUInt8(index).
    if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3f && reportBuffer.readUInt8(0) === 0x01) {
        log('mute button pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'muteButtonPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3f && reportBuffer.readUInt8(0) === 0x00) {
        log('mute button NOT pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'muteButtonNotPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3e && reportBuffer.readUInt8(0) === 0x01) {
        log('teams button pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'teamsButtonPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3e && reportBuffer.readUInt8(0) === 0x00) {
        log('teams button not pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'teamsButtonNotPressed');
    }    

    // If you want to get the next report even though,
    // the data has not changed, call this function:
    // bttGetNextEvenWithoutChange(targetDevice, reportID)
}

(however from your example you wouldn't need the 0x04, as it's always the same)

@Andreas_Hegenberg now that is an amazing and super helpful response, my thanks to you!

Just had to amend slightly to read the index 0x02 value :slight_smile:

I'm now using the Microsoft Presenter+, that is advertised with MacOS support, the way it should work.

Better Touch Tool to the rescue again!

1 Like

Nice! Maybe post your final script so others can also use it :slight_smile:

1 Like

Hello @stevemac, could you share how you got it to work? Thanks!

happy to try to help, here is what I think is needed that worked for me on MacOS with the Microsoft Presenter+

I've since (sadly) returned to a Windows laptop for work, not by choice that is for sure. However I still have a MacBook for personal use and would be happy to help sharing further details.

Here are the Generic Device Config details

Here is the Device Handling Java Script entry that is required under "Analyser" / "Parse Device Input / Output".

// Enter your input analyzer script here. 
// Do not change the function signatures
function analyzeDeviceInput(targetDevice, reportID, reportDataHex) {
    
    let reportBuffer = buffer.Buffer.from(reportDataHex, 'hex');
    // the values you see above are in hex format. To read such a byte
    // use readUInt8(index).  

	if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3f && reportBuffer.readUInt8(2) === 0x01) {
        log('mute button pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'muteButtonPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3f && reportBuffer.readUInt8(2) === 0x00) {
        log('mute button NOT pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'muteButtonNotPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3e && reportBuffer.readUInt8(2) === 0x01) {
        log('teams button pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'teamsButtonPressed');
    } else  if(reportBuffer.readUInt8(0) === 0x04 && reportBuffer.readUInt8(1) === 0x3e && reportBuffer.readUInt8(2) === 0x00) {
        log('teams button not pressed!!');
        bttTriggerDeviceTrigger(targetDevice, 'teamsButtonNotPressed');
    }    

    // If you want to get the next report even though,
    // the data has not changed, call this function:
    // bttGetNextEvenWithoutChange(targetDevice, reportID)
}

// Advanced, optional. Use if you want to trigger commands that send data to
// the device, from a BTT predefined action.
// See https://docs.folivora.ai/1500_generic_devices.html
async function executeBTTCommand(targetDevice, commandName, commandInput) {
    log("execute command: " + commandName)
    switch(commandName) {
        case "exampleCommand": {
            // send any hex string to the device
            let deviceResponse = await bttSendDataToDevice({
              BTTActionSendDataTargetDevice: targetDevice,
              BTTActionSendDataData: 'FEEDC0DE',
              BTTActionSendDataReportType: 1,
              BTTActionSendDataResponseType: -1,
              BTTActionSendDataResponsePrefix: ''
            }); 
            break;
        }
    }
    return 'done executing ' + commandName
}

Provided Triggers that I configured:

muteButtonPressed
muteButtonNotPressed
teamsButtonPressed
teamsButtonNotPressed

And the actual configured actions:

Thanks a lot @stevemac ! That worked great :slight_smile: Do you know any way to disable the original functions of the Microsoft Presenter+ on Mac? I've used Karabiner but then there is also no event on BTT. Thanks a lot!