Skip to content

Commit

Permalink
add Speed slider for RGB modes (#5)
Browse files Browse the repository at this point in the history
* add default speed value + cleanup slice w/ util func

* add speed to hex_color setter

* add slider for speed
  • Loading branch information
aarron-lee authored Nov 27, 2023
1 parent 9260df2 commit 004f6e3
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 44 deletions.
29 changes: 20 additions & 9 deletions py_modules/legion_configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,33 @@ def create_touchpad_command(enable):
buffered_command = byte_command + bytes([0xCD] * (64 - len(byte_command)))
return buffered_command

def create_rgb_control_command(controller, mode, color, brightness, profile):
def create_rgb_control_command(controller, mode, color, brightness, speed, profile=0x01, on=True):
"""
Create a command for RGB LED control.
Create a command to control the RGB LEDs, including setting the profile and turning them on or off.
:param controller: byte - The controller byte (e.g., 0x03, 0x04)
:param mode: byte - The LED mode (e.g., 0x01 for solid)
:param controller: byte - The controller byte (0x03 for left, 0x04 for right)
:param mode: byte - The mode of the LED (e.g., 0x01 for solid, 0x02 for blinking)
:param color: bytes - The RGB color value (e.g., b'\xFF\x00\x00' for red)
:param brightness: byte - The brightness value 0x00 -> 0x64
:param brightness: byte - The brightness value (0x00 to 0x64)
:param speed: byte - The speed setting for dynamic modes (0x00 to 0x64, higher is slower)
:param profile: byte - The profile number
:param on: bool - True to turn on, False to turn off the RGB LEDs
:return: bytes - The command byte array
"""
on_off_byte = 0x01 if on else 0x00
command = [
0x05, 0x0c, # Report ID and Length
0x72, # Command (Nibble 7 + 2)
0x01, controller, mode
] + list(color) + [brightness, profile, 0x01]
0x05, 0x0c if on else 0x06, # Report ID and Length (0x0c for setting profile, 0x06 for on/off)
0x72 if on else 0x70, # Command (Nibble 7 + 2 for profile, 7 + 0 for on/off)
0x01, controller
]

if on:
# Adding profile settings when turning on
command += [mode] + list(color) + [brightness, speed, profile, 0x01]
else:
# Adding the on/off byte when turning off
command += [on_off_byte, 0x01]

return bytes(command) + bytes([0xCD] * (64 - len(command)))

def create_rgb_on_off_command(controller, on):
Expand Down
8 changes: 5 additions & 3 deletions py_modules/rgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def sync_rgb_settings(current_game_id):
rgb_light.get('red'),
rgb_light.get('blue'),
rgb_light.get('green'),
rgb_light.get('brightness')
rgb_light.get('brightness'),
rgb_light.get('speed')
)
else:
rgb_off(current_game_id, controller)
Expand All @@ -40,12 +41,13 @@ def rgb_off(current_game_id, controller: str):
legion_configurator.send_command(rgb_off_command)


def rgb_color(current_game_id, controller: str, mode: str, red, blue, green, brightness):
def rgb_color(current_game_id, controller: str, mode: str, red, blue, green, brightness, speed):
hex_brightness = int(brightness)
hex_speed = int(speed)
color = bytes([red, green, blue])
controller_code = controller_enums.Controller[controller].value
rgb_mode_code = controller_enums.RgbModes[mode].value or controller_enums.RgbModes['SOLID'].value

rgb = legion_configurator.create_rgb_control_command(controller_code, rgb_mode_code, color, hex_brightness, 0x01)
rgb = legion_configurator.create_rgb_control_command(controller_code, rgb_mode_code, color, hex_brightness, hex_speed)
# decky_plugin.logger.info(list(rgb))
legion_configurator.send_command(rgb)
38 changes: 32 additions & 6 deletions src/components/ControllerLightingPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
red: redL,
green: greenL,
blue: blueL,
brightness: brightnessL
brightness: brightnessL,
speed: speedL
},
setIsLeftRgbOn,
setLeftColor,
setLeftLedBrightness
// _setLeftRgbColor
setLeftLedBrightness,
_setLeftRgbColor,
setLeftSpeed
] = useRgb('LEFT');

const [
Expand All @@ -53,12 +55,14 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
red: redR,
green: greenR,
blue: blueR,
brightness: brightnessR
brightness: brightnessR,
speed: speedR
},
setIsRightRgbOn,
setRightColor,
setRightLedBrightness
// _setLeftRgbColor
setRightLedBrightness,
_setRightRgbColor,
setRightSpeed
] = useRgb('RIGHT');

const TPadToggleChange = (value: boolean) => {
Expand Down Expand Up @@ -107,6 +111,17 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
validValues="range"
onChange={(value) => setRightLedBrightness(value)}
></SliderField>
{rightMode !== RgbModes.SOLID && (
<SliderField
label="Speed"
value={speedR}
showValue={true}
min={1}
max={100}
validValues="range"
onChange={(value) => setRightSpeed(value)}
></SliderField>
)}
{rightMode !== RgbModes.DYNAMIC && (
<>
<SliderField
Expand Down Expand Up @@ -183,6 +198,17 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
validValues="range"
onChange={(value) => setLeftLedBrightness(value)}
></SliderField>
{leftMode !== RgbModes.SOLID && (
<SliderField
label="Speed"
value={speedL}
showValue={true}
min={1}
max={100}
validValues="range"
onChange={(value) => setLeftSpeed(value)}
></SliderField>
)}
{leftMode !== RgbModes.DYNAMIC && (
<>
<SliderField
Expand Down
7 changes: 6 additions & 1 deletion src/hooks/rgb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,16 @@ export const useRgb = (controller: ControllerType) => {
return dispatch(rgbSlice.actions.setBrightness({ controller, brightness }));
};

const setSpeed = (speed: number) => {
return dispatch(rgbSlice.actions.setSpeed({ controller, speed }));
};

return [
rgbInfo,
setEnabled,
updateColor,
updateBrightness,
setRgbColor
setRgbColor,
setSpeed
] as any;
};
90 changes: 65 additions & 25 deletions src/redux-modules/rgbSlice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Router } from 'decky-frontend-lib';
const DEFAULT_RGB_LIGHT_VALUES: RgbLight = {
enabled: false,
mode: RgbModes.SOLID,
speed: 50,
red: 255,
green: 255,
blue: 255,
Expand All @@ -25,6 +26,7 @@ enum Colors {
type RgbLight = {
enabled: boolean;
mode: RgbModes;
speed: number;
red: number;
green: number;
blue: number;
Expand Down Expand Up @@ -81,15 +83,27 @@ export const rgbSlice = createSlice({
},
setRgbMode: (
state,
action: PayloadAction<{ controller: string; mode: RgbModes }>
action: PayloadAction<{ controller: ControllerType; mode: RgbModes }>
) => {
const { controller, mode } = action.payload;
if (state.perGameProfilesEnabled) {
const currentGameId = extractCurrentGameId();
state.rgbProfiles[currentGameId][controller]['mode'] = mode;
} else {
state.rgbProfiles['default'][controller]['mode'] = mode;
}
setStateValue({
sliceState: state,
controller,
key: 'mode',
value: mode
});
},
setSpeed: (
state,
action: PayloadAction<{ controller: ControllerType; speed: number }>
) => {
const { controller, speed } = action.payload;
setStateValue({
sliceState: state,
controller,
key: 'speed',
value: speed
});
},
updateRgbProfiles: (state, action: PayloadAction<RgbProfiles>) => {
merge(state.rgbProfiles, action.payload);
Expand All @@ -103,12 +117,12 @@ export const rgbSlice = createSlice({
}>
) => {
const { controller, color, value } = action.payload;
const currentGameId = extractCurrentGameId();
if (state.perGameProfilesEnabled) {
state.rgbProfiles[currentGameId][controller][color] = value;
} else {
state.rgbProfiles['default'][controller][color] = value;
}
setStateValue({
sliceState: state,
controller,
key: color,
value
});
},
setRgbColor: (
state,
Expand Down Expand Up @@ -139,12 +153,13 @@ export const rgbSlice = createSlice({
}>
) => {
const { controller, enabled } = action.payload;
const currentGameId = extractCurrentGameId();
if (state.perGameProfilesEnabled) {
state.rgbProfiles[currentGameId][controller]['enabled'] = enabled;
} else {
state.rgbProfiles['default'][controller]['enabled'] = enabled;
}

setStateValue({
sliceState: state,
controller,
key: 'enabled',
value: enabled
});
},
setBrightness: (
state,
Expand All @@ -154,12 +169,13 @@ export const rgbSlice = createSlice({
}>
) => {
const { controller, brightness } = action.payload;
const currentGameId = extractCurrentGameId();
if (state.perGameProfilesEnabled) {
state.rgbProfiles[currentGameId][controller]['brightness'] = brightness;
} else {
state.rgbProfiles['default'][controller]['brightness'] = brightness;
}

setStateValue({
sliceState: state,
controller,
key: 'brightness',
value: brightness
});
}
},
extraReducers: (builder) => {
Expand Down Expand Up @@ -236,6 +252,7 @@ const mutatingActionTypes = [
rgbSlice.actions.setPerGameProfilesEnabled.type,
rgbSlice.actions.setRgbMode.type,
rgbSlice.actions.setRgbColor.type,
rgbSlice.actions.setSpeed.type,
rgbSlice.actions.setBrightness.type
];

Expand Down Expand Up @@ -288,3 +305,26 @@ export const saveRgbSettingsMiddleware =

return result;
};

// -------------
// Slice Util functions
// -------------

function setStateValue({
sliceState,
controller,
key,
value
}: {
sliceState: RgbState;
controller: ControllerType;
key: string;
value: any;
}) {
if (sliceState.perGameProfilesEnabled) {
const currentGameId = extractCurrentGameId();
sliceState.rgbProfiles[currentGameId][controller][key] = value;
} else {
sliceState.rgbProfiles['default'][controller][key] = value;
}
}

0 comments on commit 004f6e3

Please sign in to comment.