Skip to content

Conversation

@joegoldin
Copy link
Contributor

@joegoldin joegoldin commented May 9, 2025

Compiled on linux (via WSL) and Windows and tested on Windows with a Litra Beam LX and a Litra Glow. All commands worked as expected.

Fixes #133

CLI Testing Output
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle --all-devices        
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): On 💡
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): On 💡
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -s 009F6369D08D      
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): On 💡
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -s 2229FE006UH8      
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle --device-type LitraBeamLX
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): On 💡
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle --device-type LitraGlow
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): On 💡
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): On 💡
  - Brightness: 56 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe brightness --device-type LitraBeamLX --percentage 50
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 215 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe brightness --device-type LitraBeamLX --percentage 20
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 104 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe brightness -s 009F6369D08D --percentage 100
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 400 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe temperature -s 009F6369D08D --value 5000
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 400 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe temperature -s 009F6369D08D --value 4300
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (009F6369D08D): Off 🌑
  - Brightness: 400 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices --json
[{"serial_number":"2229FE006UH8","device_type":"Litra Glow","is_on":false,"brightness_in_lumen":20,"temperature_in_kelvin":5000,"minimum_brightness_in_lumen":20,"maximum_brightness_in_lumen":250,"minimum_temperature_in_kelvin":2700,"maximum_temperature_in_kelvin":6500},{"serial_number":"009F6369D08D","device_type":"Litra Beam LX","is_on":false,"brightness_in_lumen":400,"temperature_in_kelvin":4300,"minimum_brightness_in_lumen":30,"maximum_brightness_in_lumen":400,"minimum_temperature_in_kelvin":2700,"maximum_temperature_in_kelvin":6500}]

Copy link
Owner

@timrogers timrogers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loving the direction on this so far! I have a few suggestions.

@joegoldin
Copy link
Contributor Author

joegoldin commented May 12, 2025

Thanks for the review! 😄

  • Removed deterministic serial number generation and implement device path targeting
  • Added validation to ensure only one filter can be applied at a time
  • Used DeviceType enum instead of String for device_type parameter
  • Changed default behavior to target all devices
  • Updated help text copy
  • Updated README

If these changes look good, I'll fix timrogers/litra-autotoggle#48 and convert it back to a PR once it's updated accordingly.

CLI Testing Output
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices                                                   
- Litra Glow (2229FE006UH8): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -p "\\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices                                                   
- Litra Glow (2229FE006UH8): On 💡
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -p "\\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices                                                   
- Litra Glow (2229FE006UH8): On 💡
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): On 💡
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -t glow                                            
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices       
- Litra Glow (2229FE006UH8): On 💡
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): Off 🌑
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe toggle -t beamlx
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices
- Litra Glow (2229FE006UH8): On 💡
  - Device path: \\?\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 20 lm
    - Minimum: 20 lm
    - Maximum: 250 lm
  - Temperature: 5000 K
    - Minimum: 2700 K
    - Maximum: 6500 K
- Litra Beam LX (UNKNOWN): On 💡
  - Device path: \\?\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
  - Brightness: 67 lm
    - Minimum: 30 lm
    - Maximum: 400 lm
  - Temperature: 4300 K
    - Minimum: 2700 K
    - Maximum: 6500 K
PS C:\Users\Joe\Development\litra-rs> .\target\debug\litra.exe devices --json
[{"serial_number":"2229FE006UH8","device_path":"\\\\?\\HID#VID_046D&PID_C900&Col02#7&2d3520f0&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}","device_type":"Litra Glow","is_on":true,"brightness_in_lumen":20,"temperature_in_kelvin":5000,"minimum_brightness_in_lumen":20,"maximum_brightness_in_lumen":250,"minimum_temperature_in_kelvin":2700,"maximum_temperature_in_kelvin":6500},{"serial_number":"UNKNOWN","device_path":"\\\\?\\HID#VID_046D&PID_C903&Col02#7&2a2a87de&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}","device_type":"Litra Beam LX","is_on":true,"brightness_in_lumen":67,"temperature_in_kelvin":4300,"minimum_brightness_in_lumen":30,"maximum_brightness_in_lumen":400,"minimum_temperature_in_kelvin":2700,"maximum_temperature_in_kelvin":6500}]

@joegoldin joegoldin requested a review from timrogers May 12, 2025 06:23
@joegoldin
Copy link
Contributor Author

Hey @timrogers, just a friendly bump here :)

@timrogers
Copy link
Owner

Thanks for the reminder on this! I've been very busy recently but should get to it in the next couple of days.

Copilot AI review requested due to automatic review settings August 23, 2025 15:27
@timrogers timrogers changed the title feat: --all-devices and --device-type cli flags feat: select devices to target with --device-type and --device-path arguments Aug 23, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for --all-devices and --device-type CLI flags to allow targeting multiple devices or specific device types, expanding the functionality beyond single device targeting by serial number.

Key changes:

  • Added device filtering by type (LitraGlow, LitraBeam, LitraBeamLX) and device path
  • Modified all command handlers to support targeting multiple devices when no specific filter is provided
  • Enhanced MCP server integration with new device targeting options

Reviewed Changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/main.rs Core CLI implementation with new device filtering logic and multi-device command handling
src/lib.rs Added DeviceType parsing, device path methods, and enhanced serial number handling
src/mcp.rs Updated MCP server tools to support new device targeting parameters
Cargo.toml Added schemars dependency for MCP schema generation
README.md Updated documentation to reflect new device targeting options

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +437 to +462
if use_all {
// Get all devices
let devices = get_all_supported_devices(&context, None, None, None)?;
if devices.is_empty() {
return Err(CliError::DeviceNotFound);
}

for device_handle in devices {
// Ignore errors for individual devices when targeting all
let _ = callback(&device_handle);
}
Ok(())
} else {
// Filtering by one of the options
let devices = get_all_supported_devices(&context, serial_number, device_path, device_type)?;
if devices.is_empty() {
return Err(CliError::DeviceNotFound);
}

// Apply to all matched devices
for device_handle in devices {
// Ignore errors for individual devices
let _ = callback(&device_handle);
}
Ok(())
}
Copy link

Copilot AI Aug 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic in both branches of the if-else statement is nearly identical (lines 439-448 and 451-461). This duplicated code should be extracted into a helper function or refactored to eliminate the repetition.

Suggested change
if use_all {
// Get all devices
let devices = get_all_supported_devices(&context, None, None, None)?;
if devices.is_empty() {
return Err(CliError::DeviceNotFound);
}
for device_handle in devices {
// Ignore errors for individual devices when targeting all
let _ = callback(&device_handle);
}
Ok(())
} else {
// Filtering by one of the options
let devices = get_all_supported_devices(&context, serial_number, device_path, device_type)?;
if devices.is_empty() {
return Err(CliError::DeviceNotFound);
}
// Apply to all matched devices
for device_handle in devices {
// Ignore errors for individual devices
let _ = callback(&device_handle);
}
Ok(())
}
let (sn, dp, dt) = if use_all {
(None, None, None)
} else {
(serial_number, device_path, device_type)
};
let devices = get_all_supported_devices(&context, sn, dp, dt)?;
if devices.is_empty() {
return Err(CliError::DeviceNotFound);
}
for device_handle in devices {
// Ignore errors for individual devices
let _ = callback(&device_handle);
}
Ok(())

Copilot uses AI. Check for mistakes.
src/lib.rs Outdated
Comment on lines 110 to 114
let s_lower = s.to_lowercase().replace(" ", "");
match s_lower.as_str() {
"litra_glow" | "glow" => Ok(DeviceType::LitraGlow),
"litra_beam" | "beam" => Ok(DeviceType::LitraBeam),
"litra_beam_lx" | "beam_lx" => Ok(DeviceType::LitraBeamLX),
Copy link

Copilot AI Aug 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string matching patterns use underscores (e.g., 'litra_beam_lx') but the help text and documentation mention 'LitraBeamLX' without underscores. Consider supporting both formats or clarifying the expected input format in documentation.

Suggested change
let s_lower = s.to_lowercase().replace(" ", "");
match s_lower.as_str() {
"litra_glow" | "glow" => Ok(DeviceType::LitraGlow),
"litra_beam" | "beam" => Ok(DeviceType::LitraBeam),
"litra_beam_lx" | "beam_lx" => Ok(DeviceType::LitraBeamLX),
// Normalize: lowercase, remove spaces and underscores
let s_norm = s.to_lowercase().replace([' ', '_'], "");
match s_norm.as_str() {
"litraglow" | "glow" => Ok(DeviceType::LitraGlow),
"litrabeam" | "beam" => Ok(DeviceType::LitraBeam),
"litrabeamlx" | "beamlx" => Ok(DeviceType::LitraBeamLX),

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@timrogers timrogers merged commit b5d1dd6 into timrogers:main Aug 23, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Litra Beams getting no ID

2 participants