Skip to main content

Logitech JavaScript API Documentation

BetterTouchTool >= 5.798 provides a JavaScript API for controlling Logitech HID++ devices (mice, keyboards). All functions support async/await and return Promises. You can use these within the predefined action "Run Real JavaScript". Also have a look at BTT Real JavaScript

Table of Contents


Lifecycle Functions

logitech_start()

Starts the Logitech device manager and begins device discovery.

const result = await logitech_start();
// Returns: { success: true, started: true }
// Or if already running: { success: true, alreadyRunning: true }

logitech_stop()

Stops the Logitech device manager.

const result = await logitech_stop();
// Returns: { success: true }

logitech_is_running()

Checks if the Logitech device manager is currently running.

const result = await logitech_is_running();
// Returns: { isRunning: true } or { isRunning: false }

logitech_scan_devices()

Triggers a scan for known Logitech devices.

const result = await logitech_scan_devices();
// Returns: { success: true }

Device Discovery

logitech_get_devices()

Returns a list of all connected Logitech HID++ devices.

const result = await logitech_get_devices();
// Returns:
// {
// count: 2,
// devices: [
// {
// name: "G502 HERO",
// vendorID: 1133,
// productID: 49291,
// protocolMajor: 4,
// protocolMinor: 2,
// protocolVersion: "4.2",
// isReady: true,
// features: {
// supportsDPI: true,
// supportsLED: true,
// supportsButtons: true,
// supportsProfiles: true,
// supportsScrollWheel: true,
// supportsBattery: false,
// supportsReportRate: true,
// supportsPointerSpeed: true,
// supportsHapticFeedback: false, // MX Master 4 and similar
// supportsBacklight: false // Keyboards only
// }
// },
// ...
// ]
// }

Example: List all connected devices

async function listDevices() {
const result = await logitech_get_devices();

for (const device of result.devices) {
log(`Device: ${device.name}`);
log(` Protocol: HID++ ${device.protocolVersion}`);
log(` DPI Support: ${device.features.supportsDPI}`);
log(` LED Support: ${device.features.supportsLED}`);
}

return `Found ${result.count} device(s)`;
}

DPI Control

logitech_get_dpi(options)

Gets the current DPI setting for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
sensorIndexnumberNoSensor index (default: primary sensor)
const result = await logitech_get_dpi({ deviceName: "G502 HERO" });
// Returns: { dpi: 1600 }
// Or on error: { error: "Error message" }

logitech_set_dpi(options)

Sets the DPI for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
dpinumberYesDPI value to set
sensorIndexnumberNoSensor index (default: primary sensor)
const result = await logitech_set_dpi({ deviceName: "G502 HERO", dpi: 1600 });
// Returns: { success: true, actualDPI: 1600 }
// Note: actualDPI may differ if device only supports specific DPI steps

logitech_get_dpi_capabilities(options)

Gets the DPI capabilities and ranges for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_dpi_capabilities({ deviceName: "G502 HERO" });
// Returns:
// {
// sensors: [
// {
// index: 0,
// currentDPI: 1600,
// minDPI: 100,
// maxDPI: 25600,
// dpiSteps: 50,
// availableDPIs: [] // Empty if continuous range, or list of fixed values
// }
// ]
// }

Example: Increase DPI by 100

async function increaseDPI() {
const deviceName = "G502 HERO";

// Get current DPI
const current = await logitech_get_dpi({ deviceName });
if (current.error) {
return `Error: ${current.error}`;
}

// Increase by 100
const newDPI = current.dpi + 100;
const result = await logitech_set_dpi({ deviceName, dpi: newDPI });

if (result.error) {
return `Error: ${result.error}`;
}

return `DPI changed from ${current.dpi} to ${result.actualDPI}`;
}

Example: Cycle through DPI presets

async function cycleDPI() {
const deviceName = "G502 HERO";
const presets = [800, 1600, 3200, 6400];

const current = await logitech_get_dpi({ deviceName });
if (current.error) return `Error: ${current.error}`;

// Find next preset
let nextIndex = 0;
for (let i = 0; i < presets.length; i++) {
if (current.dpi < presets[i]) {
nextIndex = i;
break;
}
if (i === presets.length - 1) {
nextIndex = 0; // Wrap around
}
}

const result = await logitech_set_dpi({ deviceName, dpi: presets[nextIndex] });
return `DPI set to ${result.actualDPI}`;
}

LED Control

logitech_set_led_color(options)

Sets the LED color for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
rednumberYesRed value (0-255)
greennumberYesGreen value (0-255)
bluenumberYesBlue value (0-255)
zonesarrayNoArray of zone indices to set (default: all zones)
enableHostModebooleanNoEnable host control mode
persistbooleanNoPersist the color setting
// Set all LEDs to red
const result = await logitech_set_led_color({
deviceName: "G502 HERO",
red: 255,
green: 0,
blue: 0
});
// Returns: { success: true }

// Set specific zones to blue
const result2 = await logitech_set_led_color({
deviceName: "G502 HERO",
red: 0,
green: 0,
blue: 255,
zones: [0, 1], // Only zones 0 and 1
persist: true // Save to device memory
});

Example: Color based on battery level

async function setBatteryColor() {
const deviceName = "MX Master 3";

const battery = await logitech_get_battery_status({ deviceName });
if (battery.error) return `Error: ${battery.error}`;

let red = 0, green = 255, blue = 0;

if (battery.level < 20) {
red = 255; green = 0; // Red for low battery
} else if (battery.level < 50) {
red = 255; green = 165; // Orange for medium
}

await logitech_set_led_color({ deviceName, red, green, blue });
return `Battery: ${battery.level}%`;
}

Report Rate

logitech_get_report_rate(options)

Gets the current USB report rate (polling rate) for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_report_rate({ deviceName: "G502 HERO" });
// Returns: { rateHz: 1000 }

logitech_set_report_rate(options)

Sets the USB report rate for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
rateHznumberYesReport rate in Hz (e.g., 125, 250, 500, 1000)
const result = await logitech_set_report_rate({
deviceName: "G502 HERO",
rateHz: 1000
});
// Returns: { success: true }

logitech_get_supported_report_rates(options)

Gets the list of supported report rates for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_supported_report_rates({ deviceName: "G502 HERO" });
// Returns: { rates: [125, 250, 500, 1000] }

Example: Toggle between 500Hz and 1000Hz

async function toggleReportRate() {
const deviceName = "G502 HERO";

const current = await logitech_get_report_rate({ deviceName });
const newRate = current.rateHz === 1000 ? 500 : 1000;

await logitech_set_report_rate({ deviceName, rateHz: newRate });
return `Report rate set to ${newRate}Hz`;
}

Battery Status

logitech_get_battery_status(options)

Gets the battery status for a wireless device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_battery_status({ deviceName: "MX Master 3" });
// Returns:
// {
// level: 85, // Battery percentage (0-100)
// status: "discharging" // "discharging", "charging", "full", or "invalid"
// }

Example: Show battery notification

async function checkBattery() {
const deviceName = "MX Master 3";

const battery = await logitech_get_battery_status({ deviceName });
if (battery.error) return `Error: ${battery.error}`;

if (battery.level < 20) {
// Use BTT to show a notification
await trigger_action({
json: JSON.stringify({
BTTPredefinedActionType: 309, // Show notification
BTTNotificationTitle: "Low Battery Warning",
BTTNotificationText: `${deviceName}: ${battery.level}%`
})
});
}

return `${deviceName}: ${battery.level}% (${battery.status})`;
}

Profile Management

logitech_get_mode(options)

Gets the current operating mode (host or onboard) for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_mode({ deviceName: "G502 HERO" });
// Returns: { mode: "host" } or { mode: "onboard" }

logitech_set_mode(options)

Sets the operating mode for a device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
modestringYes"host" or "onboard"
  • host: BTT controls the device (required for button remapping)
  • onboard: Device uses its onboard profile settings
const result = await logitech_set_mode({
deviceName: "G502 HERO",
mode: "host"
});
// Returns: { success: true }

logitech_get_active_profile(options)

Gets the currently active profile index.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_active_profile({ deviceName: "G502 HERO" });
// Returns: { profileIndex: 0 }

logitech_set_active_profile(options)

Sets the active profile by index.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
profileIndexnumberYesProfile index (typically 0-4)
const result = await logitech_set_active_profile({
deviceName: "G502 HERO",
profileIndex: 1
});
// Returns: { success: true }

Example: Cycle through profiles

async function cycleProfile() {
const deviceName = "G502 HERO";
const maxProfiles = 5;

const current = await logitech_get_active_profile({ deviceName });
if (current.error) return `Error: ${current.error}`;

const nextProfile = (current.profileIndex + 1) % maxProfiles;
await logitech_set_active_profile({ deviceName, profileIndex: nextProfile });

return `Switched to profile ${nextProfile + 1}`;
}

Button Control

logitech_get_buttons(options)

Gets information about all buttons on the device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_buttons({ deviceName: "G502 HERO" });
// Returns:
// {
// buttons: [
// {
// controlId: 80, // 0x0050 = Left Click
// taskId: 80, // Current mapping
// flags: 0,
// position: 0,
// group: 1
// },
// {
// controlId: 81, // 0x0051 = Right Click
// taskId: 81,
// flags: 0,
// position: 1,
// group: 1
// },
// ...
// ]
// }

Common Control IDs:

ID (Hex)ID (Dec)Button
0x005080Left Click
0x005181Right Click
0x005282Middle Click
0x005383Back
0x005686Forward
0x00C3195Thumb Button
0x00C4196DPI Shift
0x00D7215Scroll Left
0x00D8216Scroll Right

logitech_divert_button(options)

Diverts a button to be handled by the host (BTT) instead of the device.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
controlIdnumberYesControl ID of the button
// Divert the thumb button (0x00C3) to BTT
const result = await logitech_divert_button({
deviceName: "G502 HERO",
controlId: 0x00C3
});
// Returns: { success: true }

Example: List all buttons

async function listButtons() {
const deviceName = "G502 HERO";

const result = await logitech_get_buttons({ deviceName });
if (result.error) return `Error: ${result.error}`;

let output = `Buttons on ${deviceName}:\n`;
for (const btn of result.buttons) {
output += ` Control ID: 0x${btn.controlId.toString(16).toUpperCase().padStart(4, '0')}`;
output += ` (${btn.controlId}), Task: ${btn.taskId}\n`;
}

return output;
}

logitech_undivert_button(options)

Restores a button to be handled by the device instead of BTT.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
controlIdnumberYesControl ID of the button
const result = await logitech_undivert_button({
deviceName: "G502 HERO",
controlId: 0x00C3
});
// Returns: { success: true }

Scroll Wheel / SmartShift

logitech_get_ratchet_state(options)

Gets the current scroll wheel ratchet/freespin state.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_ratchet_state({ deviceName: "MX Master 3" });
// Returns: { ratchet: true, state: "ratchet" }
// Or: { ratchet: false, state: "freespin" }

logitech_set_ratchet_state(options)

Sets the scroll wheel to ratchet or freespin mode.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the device. If omitted, applies to ALL mice with scroll wheel support
ratchetbooleanYestrue for ratchet mode, false for freespin
// Set ratchet mode on a specific mouse
const result = await logitech_set_ratchet_state({
deviceName: "MX Master 3",
ratchet: false // Enable freespin
});
// Returns: { success: true }

// Set ratchet mode on ALL connected Logitech mice
const result2 = await logitech_set_ratchet_state({
ratchet: true // Enable ratchet on all mice
});

logitech_toggle_ratchet(options)

Toggles the scroll wheel between ratchet and freespin mode. This is the simplest way to switch modes - it reads the current state and flips it.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the device. If omitted, applies to ALL mice with scroll wheel support
// Toggle ratchet mode on a specific mouse
const result = await logitech_toggle_ratchet({ deviceName: "MX Master 3" });
// Returns: { ratchet: false, state: "freespin" } // or { ratchet: true, state: "ratchet" }

// Toggle ratchet mode on ALL connected Logitech mice
const result2 = await logitech_toggle_ratchet({});

logitech_get_smartshift_mode(options)

Gets the SmartShift mode and auto-disengage threshold.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_smartshift_mode({ deviceName: "MX Master 3" });
// Returns: { mode: "ratchet", autoDisengage: 10 }

logitech_set_smartshift_mode(options)

Sets the SmartShift mode and auto-disengage threshold.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
modestringYes"freespin" or "ratchet"
autoDisengagenumberNoAuto-disengage threshold (0-50)
const result = await logitech_set_smartshift_mode({
deviceName: "MX Master 3",
mode: "ratchet",
autoDisengage: 10
});
// Returns: { success: true }

logitech_get_smartshift_settings(options)

Gets detailed SmartShift settings including torque (for devices that support it).

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_smartshift_settings({ deviceName: "MX Master 3" });
// Returns:
// {
// mode: 2,
// modeString: "ratchet",
// ratchet: true,
// autoDisengage: 10,
// torque: 50 // 0 for standard SmartShift, 1-100 for Enhanced
// }

logitech_set_smartshift(options)

Sets SmartShift settings (works with both standard and enhanced SmartShift).

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
ratchetbooleanYestrue for ratchet, false for freespin
autoDisengagenumberYesAuto-disengage threshold (0-50)
torquenumberNoTorque value 1-100 (only for Enhanced SmartShift)
const result = await logitech_set_smartshift({
deviceName: "MX Master 3",
ratchet: true,
autoDisengage: 15,
torque: 50 // Optional, for Enhanced SmartShift
});
// Returns: { success: true }

logitech_get_smartshift_enhanced_settings(options)

Gets Enhanced SmartShift settings (Feature 0x2111).

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_smartshift_enhanced_settings({ deviceName: "MX Master 3S" });
// Returns:
// {
// mode: 2,
// modeString: "ratchet",
// ratchet: true,
// autoDisengage: 10,
// torque: 50
// }

logitech_set_smartshift_enhanced(options)

Sets Enhanced SmartShift settings (Feature 0x2111).

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
ratchetbooleanYestrue for ratchet, false for freespin
autoDisengagenumberYesAuto-disengage threshold (0-50)
torquenumberYesTorque value (1-100)
const result = await logitech_set_smartshift_enhanced({
deviceName: "MX Master 3S",
ratchet: true,
autoDisengage: 10,
torque: 60
});
// Returns: { success: true }

logitech_get_hires_scrolling(options)

Gets the high-resolution scrolling state.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_hires_scrolling({ deviceName: "MX Master 3" });
// Returns: { enabled: true, inverted: false }

logitech_set_hires_scrolling(options)

Sets high-resolution scrolling options.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
enabledbooleanYes*Enable/disable hi-res scrolling
invertedbooleanNoInvert scroll direction
modenumberNoRaw mode value (overrides enabled if set)

*Either enabled or mode must be provided.

const result = await logitech_set_hires_scrolling({
deviceName: "MX Master 3",
enabled: true,
inverted: false
});
// Returns: { success: true }

logitech_get_thumbwheel_info(options)

Gets thumbwheel configuration (for mice with horizontal scroll wheels like MX Master).

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_thumbwheel_info({ deviceName: "MX Master 3" });
// Returns: { nativeResolution: true, diverted: false }

logitech_set_thumbwheel(options)

Configures the thumbwheel settings.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
invertbooleanNoInvert scroll direction
divertbooleanNoDivert to host for BTT handling
const result = await logitech_set_thumbwheel({
deviceName: "MX Master 3",
invert: true,
divert: false
});
// Returns: { success: true }

Example: Toggle scroll wheel mode

// Simple toggle using the dedicated function
async function toggleScrollMode() {
const result = await logitech_toggle_ratchet({ deviceName: "MX Master 3" });
return `Scroll mode: ${result.state}`;
}

// Or toggle ALL mice at once
async function toggleAllMice() {
const result = await logitech_toggle_ratchet({});
return `Scroll mode: ${result.state}`;
}

Pointer Speed

logitech_get_pointer_speed(options)

Gets the current pointer speed/acceleration setting.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_get_pointer_speed({ deviceName: "G502 HERO" });
// Returns:
// {
// speed: 256, // Raw value (256 = 1.0x)
// multiplier: 1.0, // Calculated multiplier
// percentage: 100 // As percentage
// }

logitech_set_pointer_speed(options)

Sets the pointer speed/acceleration.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
speednumberYesSpeed value (256 = 1.0x, 512 = 2.0x, etc.)
const result = await logitech_set_pointer_speed({
deviceName: "G502 HERO",
speed: 384 // 1.5x speed
});
// Returns: { success: true }

Keyboard Backlight

Control keyboard backlight on supported Logitech keyboards (MX Keys, MX Keys S, Craft, MX Mechanical, etc.).

logitech_get_backlight_state(options)

Gets the current backlight state including mode, level, and timeout durations.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
const result = await logitech_get_backlight_state({ deviceName: "MX Keys S" });
// Returns:
// {
// success: true,
// enabled: true,
// mode: "automatic", // "disabled", "enabled", "automatic", or "manual"
// modeValue: 1, // Raw mode value
// level: 5, // Current brightness (0-maxLevel)
// maxLevel: 10, // Maximum brightness level
// supportsAutomatic: true,
// supportsManual: true,
// durationHandsOut: 55, // Seconds until dim when hands away
// durationHandsIn: 55, // Seconds until dim when hands nearby
// durationPowered: 300 // Seconds until dim on external power
// }

logitech_set_backlight_enabled(options)

Enables or disables the keyboard backlight.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
enabledbooleanYestrue to enable, false to disable
const result = await logitech_set_backlight_enabled({
deviceName: "MX Keys S",
enabled: true
});
// Returns: { success: true }

logitech_set_backlight_mode(options)

Sets the backlight mode.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
modestring/numberYesMode: "disabled", "enabled", "automatic", "manual" (or raw value)

Modes:

  • "disabled" - Backlight off
  • "enabled" - Backlight on (basic)
  • "automatic" - Brightness adjusts based on ambient light and hand proximity
  • "manual" - Fixed brightness level
const result = await logitech_set_backlight_mode({
deviceName: "MX Keys S",
mode: "automatic"
});
// Returns: { success: true }

logitech_set_backlight_level(options)

Sets the backlight brightness level. Automatically switches to manual mode if needed.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
levelnumberYesBrightness level (0 to maxLevel, typically 0-10)
const result = await logitech_set_backlight_level({
deviceName: "MX Keys S",
level: 7
});
// Returns: { success: true }

logitech_set_backlight(options)

Sets the complete backlight configuration in a single call.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
enabledbooleanNoEnable/disable backlight (default: true)
modestring/numberNoBacklight mode (default: "automatic")
levelnumberNoBrightness level (default: 5)
const result = await logitech_set_backlight({
deviceName: "MX Keys S",
enabled: true,
mode: "manual",
level: 8
});
// Returns: { success: true }

logitech_set_backlight_durations(options)

Sets the timeout durations for when the backlight dims/turns off.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the keyboard
handsOutnumberNoSeconds until dim when hands are away (5-600)
handsInnumberNoSeconds until dim when hands are nearby (5-600)
powerednumberNoSeconds until dim when on external power (5-600)
const result = await logitech_set_backlight_durations({
deviceName: "MX Keys S",
handsOut: 30, // Dim after 30 seconds when hands away
handsIn: 120, // Dim after 2 minutes when hands nearby
powered: 600 // Dim after 10 minutes on USB power
});
// Returns: { success: true }

Example: Toggle backlight mode

async function toggleBacklightMode() {
const deviceName = "MX Keys S";

const state = await logitech_get_backlight_state({ deviceName });
if (state.error) return `Error: ${state.error}`;

// Toggle between automatic and manual
const newMode = state.mode === "automatic" ? "manual" : "automatic";

await logitech_set_backlight_mode({ deviceName, mode: newMode });
return `Backlight mode: ${newMode}`;
}

Example: Brightness control with display

async function setBacklightWithNotification(level) {
const deviceName = "MX Keys S";

// Get max level first
const state = await logitech_get_backlight_state({ deviceName });
if (state.error) return `Error: ${state.error}`;

// Clamp level
const clampedLevel = Math.max(0, Math.min(level, state.maxLevel));

await logitech_set_backlight_level({ deviceName, level: clampedLevel });

// Show notification
await trigger_action({
json: JSON.stringify({
BTTPredefinedActionType: 309,
BTTNotificationTitle: "Keyboard Backlight",
BTTNotificationText: `Brightness: ${clampedLevel}/${state.maxLevel}`
})
});

return `Backlight set to ${clampedLevel}`;
}

Example: Dim backlight at night

async function autoBacklightForTime() {
const deviceName = "MX Keys S";
const hour = new Date().getHours();

// Night mode: 10 PM - 6 AM
const isNight = hour >= 22 || hour < 6;

if (isNight) {
// Low brightness, quick timeout
await logitech_set_backlight({
deviceName,
enabled: true,
mode: "manual",
level: 2
});
await logitech_set_backlight_durations({
deviceName,
handsOut: 10,
handsIn: 30,
powered: 60
});
return "Night mode: low brightness";
} else {
// Automatic mode for daytime
await logitech_set_backlight({
deviceName,
enabled: true,
mode: "automatic"
});
return "Day mode: automatic brightness";
}
}

logitech_increase_backlight(options)

Simple helper to increase keyboard backlight by one level.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the keyboard. If omitted, applies to ALL keyboards with backlight support.
// Increase backlight on a specific keyboard
const result = await logitech_increase_backlight({ deviceName: "MX Keys S" });
// Returns: { success: true, level: 6, maxLevel: 10 }

// Increase backlight on ALL connected Logitech keyboards
const result2 = await logitech_increase_backlight({});
// Returns: { success: true, level: 6, maxLevel: 10 }

logitech_decrease_backlight(options)

Simple helper to decrease keyboard backlight by one level.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the keyboard. If omitted, applies to ALL keyboards with backlight support.
// Decrease backlight on a specific keyboard
const result = await logitech_decrease_backlight({ deviceName: "MX Keys S" });
// Returns: { success: true, level: 4, maxLevel: 10 }

// Decrease backlight on ALL connected Logitech keyboards
const result2 = await logitech_decrease_backlight({});
// Returns: { success: true, level: 4, maxLevel: 10 }

DPI Quick Adjustment

Simple helpers for adjusting mouse DPI with logarithmic scaling (feels natural across the entire DPI range).

logitech_increase_dpi(options)

Increases mouse DPI by a percentage-based scale factor.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the mouse. If omitted, applies to ALL mice with DPI support.
scaleFactornumberNoMultiplier for increase (default: 1.2 = 20% increase)
// Increase DPI by 20% (default) on a specific mouse
const result = await logitech_increase_dpi({ deviceName: "MX Master 3" });
// Returns: { success: true, dpi: 1920 } // Was 1600, now 1920

// Increase DPI by 50% on a specific mouse
const result2 = await logitech_increase_dpi({ deviceName: "G502", scaleFactor: 1.5 });
// Returns: { success: true, dpi: 2400 } // Was 1600, now 2400

// Increase DPI on ALL connected Logitech mice
const result3 = await logitech_increase_dpi({});
// Returns: { success: true, dpi: 1920 } // Returns last mouse's new DPI

logitech_decrease_dpi(options)

Decreases mouse DPI by a percentage-based scale factor.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the mouse. If omitted, applies to ALL mice with DPI support.
scaleFactornumberNoDivisor for decrease (default: 1.2 = 20% decrease)
// Decrease DPI by 20% (default) on a specific mouse
const result = await logitech_decrease_dpi({ deviceName: "MX Master 3" });
// Returns: { success: true, dpi: 1333 } // Was 1600, now ~1333

// Decrease DPI by 50% on a specific mouse
const result2 = await logitech_decrease_dpi({ deviceName: "G502", scaleFactor: 1.5 });
// Returns: { success: true, dpi: 1066 } // Was 1600, now ~1066

// Decrease DPI on ALL connected Logitech mice
const result3 = await logitech_decrease_dpi({});
// Returns: { success: true, dpi: 1333 } // Returns last mouse's new DPI

Why logarithmic scaling?

Percentage-based scaling feels more natural than fixed steps:

  • At 800 DPI, a 20% increase adds 160 DPI (noticeable)
  • At 6400 DPI, a 20% increase adds 1280 DPI (also noticeable)

Linear steps (e.g., +200 DPI) would feel huge at low DPI but barely perceptible at high DPI.

Example: DPI adjustment hotkeys

// Bind to keyboard shortcut for quick DPI adjustment on ALL mice
async function dpiUp() {
const result = await logitech_increase_dpi({});
if (result.success) {
return `DPI: ${result.dpi}`;
}
return `Error: ${result.error}`;
}

async function dpiDown() {
const result = await logitech_decrease_dpi({});
if (result.success) {
return `DPI: ${result.dpi}`;
}
return `Error: ${result.error}`;
}

Haptic Feedback

Trigger haptic feedback patterns on supported Logitech mice (MX Master 4, and other devices with haptic motors).

logitech_trigger_haptic(options)

Triggers a haptic feedback pattern on the device's haptic motor.

Parameters:

NameTypeRequiredDescription
deviceNamestringNoName of the device. If omitted, applies to ALL devices with haptic support.
patternnumberNoHaptic pattern ID (0-14, default: 0)

Available Patterns:

IDNameDescription
0Quick ClickShort, crisp tap
1Soft ClickGentle, muted tap
2Strong PulseBold, firm feedback
3Gentle PulseSoft, cushioned feedback
4Light TapBarely noticeable touch
5SuccessPositive confirmation
6WarningError notification
7DoneTask completion
8BuzzSharp digital vibration
9Smooth WaveFlowing oscillation
10BurstExplosive pop
11UrgentIntense alert
12Double TapRhythmic knock
13ChimeMelodic ring
14VibrateContinuous ring
// Trigger default haptic pattern (Quick Click) on a specific mouse
const result = await logitech_trigger_haptic({ deviceName: "MX Master 4" });
// Returns: { success: true, pattern: 0 }

// Trigger "Success" pattern on a specific mouse
const result2 = await logitech_trigger_haptic({
deviceName: "MX Master 4",
pattern: 5
});
// Returns: { success: true, pattern: 5 }

// Trigger haptic on ALL mice with haptic support
const result3 = await logitech_trigger_haptic({ pattern: 7 });
// Returns: { success: true, pattern: 7 }

Example: Haptic feedback for button press confirmation

async function confirmAction() {
// Trigger "Done" pattern to confirm action completed
const result = await logitech_trigger_haptic({
deviceName: "MX Master 4",
pattern: 7 // Done
});

if (result.error) {
return `Error: ${result.error}`;
}

return "Action confirmed with haptic feedback";
}

Example: Different haptic for success vs error

async function performTaskWithFeedback(taskSucceeded) {
if (taskSucceeded) {
// Success pattern
await logitech_trigger_haptic({ pattern: 5 });
return "Task completed!";
} else {
// Warning pattern
await logitech_trigger_haptic({ pattern: 6 });
return "Task failed!";
}
}

Utility Functions

logitech_quick_setup(options)

Configures multiple device settings in a single call. Only provided settings will be changed.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
dpinumberNoDPI value to set
reportRatenumberNoReport rate in Hz
ledColorarrayNoRGB array [red, green, blue]
enableHostModebooleanNoEnable host control mode
remapButtonsToMouseButtonsbooleanNoRemap special buttons to standard mouse buttons
ratchetbooleanNoScroll wheel mode (true=ratchet, false=freespin)
autoDisengagenumberNoSmartShift auto-disengage threshold (0-50)
torquenumberNoSmartShift torque (1-100, Enhanced SmartShift only)
hiResScrollEnabledbooleanNoEnable high-resolution scrolling
invertMainWheelbooleanNoInvert main scroll wheel
invertThumbWheelbooleanNoInvert thumb wheel
const result = await logitech_quick_setup({
deviceName: "G502 HERO",
dpi: 1600,
reportRate: 1000,
ledColor: [0, 128, 255],
enableHostMode: true,
remapButtonsToMouseButtons: true
});
// Returns: { success: true }

Example: Complete mouse setup

async function setupMouse() {
const result = await logitech_quick_setup({
deviceName: "MX Master 3",
dpi: 1600,
enableHostMode: true,
ratchet: false, // Freespin mode
autoDisengage: 10,
hiResScrollEnabled: true,
invertThumbWheel: true
});

return result.success ? "Mouse configured!" : `Error: ${result.error}`;
}

logitech_remap_buttons_to_mouse(options)

Remaps device-specific buttons to standard mouse button events.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_remap_buttons_to_mouse({ deviceName: "G502 HERO" });
// Returns: { success: true }

logitech_reset_to_factory_defaults(options)

Resets the device to factory default settings. The device will reboot.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
const result = await logitech_reset_to_factory_defaults({ deviceName: "G502 HERO" });
// Returns: { success: true, message: "Device reset to factory defaults. Device will reboot." }

logitech_send_raw_request(options)

Sends a raw HID++ request to the device. For advanced users only.

Parameters:

NameTypeRequiredDescription
deviceNamestringYesName of the device
featureIdnumberYesHID++ feature ID (e.g., 0x8100)
functionIdnumberYesFunction ID within the feature
parametersarrayNoArray of parameter bytes
// Example: Read device name (Feature 0x0005, Function 0x00)
const result = await logitech_send_raw_request({
deviceName: "G502 HERO",
featureId: 0x0005,
functionId: 0x00,
parameters: [0]
});
// Returns: { success: true, response: [...] }

Feature Cache Management

BetterTouchTool caches discovered HID++ features for faster device initialization. These functions help manage that cache.

logitech_clear_feature_cache()

Clears the runtime feature cache for all devices. Useful if a device's features have changed or if you're troubleshooting detection issues.

const result = await logitech_clear_feature_cache();
// Returns:
// {
// success: true,
// message: "Feature cache cleared. Reconnect your Logitech devices to re-discover features."
// }

Note: After clearing the cache, you should restart the Logitech manager or reconnect your devices for the changes to take effect.

logitech_get_feature_cache_diagnostics()

Gets diagnostic information about the feature cache, including which devices are cached and their feature counts.

const result = await logitech_get_feature_cache_diagnostics();
// Returns:
// {
// success: true,
// diagnostics: {
// builtInDeviceCount: 0,
// runtimeCacheCount: 2,
// builtInDevices: [],
// cachedDevices: ["046d:b034", "046d:c52b:slot1"]
// }
// }

Example: Troubleshooting device features

async function debugFeatureCache() {
const diagnostics = await logitech_get_feature_cache_diagnostics();

if (!diagnostics.success) {
return `Error: ${diagnostics.error}`;
}

const info = diagnostics.diagnostics;
let output = "Feature Cache Diagnostics:\n";
output += ` Built-in profiles: ${info.builtInDeviceCount}\n`;
output += ` Cached devices: ${info.runtimeCacheCount}\n`;

if (info.cachedDevices.length > 0) {
output += " Cached device IDs:\n";
for (const deviceId of info.cachedDevices) {
output += ` - ${deviceId}\n`;
}
}

return output;
}

Receiver Pairing

logitech_start_pairing(options)

Starts pairing mode on a Logitech receiver.

Parameters:

NameTypeRequiredDescription
timeoutnumberNoPairing timeout in seconds (default: 30)
const result = await logitech_start_pairing({ timeout: 60 });
// Returns: { success: true }
// Or: { error: "No Unifying or Bolt receivers detected" }

logitech_stop_pairing()

Stops pairing mode on all receivers.

const result = await logitech_stop_pairing();
// Returns: { success: true }

Example: Pairing workflow

async function startPairing() {
log("Starting pairing mode for 60 seconds...");
log("Turn on your Logitech device now.");

const result = await logitech_start_pairing({ timeout: 60 });

if (result.error) {
return `Pairing failed: ${result.error}`;
}

return "Pairing mode active. Turn on your device.";
}

Error Handling

All functions return an object. On error, the object will contain an error property:

async function safeGetDPI() {
const deviceName = "G502 HERO";

const result = await logitech_get_dpi({ deviceName });

if (result.error) {
log(`Error: ${result.error}`);
return null;
}

return result.dpi;
}

Common errors:

  • "Missing required parameter: deviceName" - Required parameter not provided
  • "Device not found" - No device with that name is connected
  • "Feature not supported" - Device doesn't support this feature
  • "Device not ready" - Device is still initializing

Complete Example: Mouse Control Panel

async function mouseControlPanel() {
const deviceName = "G502 HERO";

// Get all device info
const devices = await logitech_get_devices();
const device = devices.devices.find(d => d.name === deviceName);

if (!device) {
return `Device "${deviceName}" not found`;
}

let info = `=== ${device.name} ===\n`;
info += `Protocol: HID++ ${device.protocolVersion}\n\n`;

// DPI
if (device.features.supportsDPI) {
const dpi = await logitech_get_dpi({ deviceName });
const caps = await logitech_get_dpi_capabilities({ deviceName });
info += `DPI: ${dpi.dpi}\n`;
if (caps.sensors && caps.sensors[0]) {
info += ` Range: ${caps.sensors[0].minDPI} - ${caps.sensors[0].maxDPI}\n`;
}
}

// Report Rate
if (device.features.supportsReportRate) {
const rate = await logitech_get_report_rate({ deviceName });
info += `Report Rate: ${rate.rateHz}Hz\n`;
}

// Battery
if (device.features.supportsBattery) {
const battery = await logitech_get_battery_status({ deviceName });
info += `Battery: ${battery.level}% (${battery.status})\n`;
}

// Profile
if (device.features.supportsProfiles) {
const mode = await logitech_get_mode({ deviceName });
const profile = await logitech_get_active_profile({ deviceName });
info += `Mode: ${mode.mode}\n`;
info += `Active Profile: ${profile.profileIndex + 1}\n`;
}

return info;
}