Skip to content

Commit 2a56e4d

Browse files
committed
fix: Omit program slot ID when not specified.
We don't have a UI for it, so we should assume no slot is chosen rather than default to the first slot. This allows the user to select the slot on the hub without a front end UI. This is compatible with the existing protocol.
1 parent 0aeb53d commit 2a56e4d

File tree

6 files changed

+25
-14
lines changed

6 files changed

+25
-14
lines changed

lib/pybricks-blocks

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 6288d327b5c897f83296633a04b442b85b3aeb6d

src/ble-pybricks-service/actions.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2021-2024 The Pybricks Authors
2+
// Copyright (c) 2021-2025 The Pybricks Authors
33
//
44
// Actions for Bluetooth Low Energy Pybricks service
55

@@ -85,11 +85,13 @@ export const sendLegacyStartReplCommand = createAction((id: number) => ({
8585
*
8686
* @since Pybricks Profile v1.4.0
8787
*/
88-
export const sendStartUserProgramCommand = createAction((id: number, slot: number) => ({
89-
type: 'blePybricksServiceCommand.action.sendStartUserProgram',
90-
id,
91-
slot,
92-
}));
88+
export const sendStartUserProgramCommand = createAction(
89+
(id: number, slot: number | null) => ({
90+
type: 'blePybricksServiceCommand.action.sendStartUserProgram',
91+
id,
92+
slot,
93+
}),
94+
);
9395

9496
/**
9597
* Action that requests to write user program metadata.

src/ble-pybricks-service/protocol.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2020-2024 The Pybricks Authors
2+
// Copyright (c) 2020-2025 The Pybricks Authors
33
//
44
// Definitions related to the Pybricks Bluetooth low energy GATT service.
55

@@ -114,12 +114,20 @@ export function createStopUserProgramCommand(): Uint8Array {
114114
* Parameters:
115115
* - slot: Program identifier (one byte). Slots 0--127 are reserved for
116116
* downloaded user programs. Slots 128--255 are for builtin user programs.
117+
* If null, the hub will start the program slot selected on the hub.
117118
*
118119
* @since Pybricks Profile v1.4.0
119120
*/
120121
export function createStartUserProgramCommand(
121-
slot: number | BuiltinProgramId,
122+
slot: number | BuiltinProgramId | null,
122123
): Uint8Array {
124+
// Omit optional slot id to start currently active slot.
125+
if (slot === null) {
126+
const msg = new Uint8Array(1);
127+
msg[0] = CommandType.StartUserProgram;
128+
return msg;
129+
}
130+
123131
const msg = new Uint8Array(2);
124132
msg[0] = CommandType.StartUserProgram;
125133
msg[1] = slot;

src/hub/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2020-2024 The Pybricks Authors
2+
// Copyright (c) 2020-2025 The Pybricks Authors
33

44
import { createAction } from '../actions';
55
import { FileFormat } from '../ble-pybricks-service/protocol';
@@ -26,7 +26,7 @@ export const downloadAndRun = createAction(
2626
fileFormat: FileFormat | null,
2727
useLegacyDownload: boolean,
2828
useLegacyStartUserProgram: boolean,
29-
slot: number,
29+
slot: number | null,
3030
) => ({
3131
type: 'hub.action.downloadAndRun',
3232
fileFormat,

src/hub/sagas.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2020-2024 The Pybricks Authors
2+
// Copyright (c) 2020-2025 The Pybricks Authors
33

44
import { AsyncSaga } from '../../test';
55
import { alertsShowAlert } from '../alerts/actions';
@@ -38,7 +38,7 @@ describe('downloadAndRun', () => {
3838

3939
saga.updateState({ editor: { isReady: true } });
4040

41-
saga.put(downloadAndRun(FileFormat.Mpy5, true, true, 0));
41+
saga.put(downloadAndRun(FileFormat.Mpy5, true, true, null));
4242

4343
// first, it gets the value from the current editor
4444
const editorValueAction = await saga.take();

src/toolbar/buttons/run/RunButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2020-2024 The Pybricks Authors
2+
// Copyright (c) 2020-2025 The Pybricks Authors
33

44
import React from 'react';
55
import { useDispatch } from 'react-redux';
@@ -48,7 +48,7 @@ const RunButton: React.FunctionComponent<RunButtonProps> = ({ id }) => {
4848
preferredFileFormat,
4949
useLegacyDownload,
5050
useLegacyStartUserProgram,
51-
0, // No slot UI yet
51+
null, // No slot UI yet, downloading to active hub slot
5252
),
5353
)
5454
}

0 commit comments

Comments
 (0)