diff --git a/gui/.env b/gui/.env index c0cd8613a..7ce15648f 100644 --- a/gui/.env +++ b/gui/.env @@ -1,8 +1,8 @@ -# VITE_FIRMWARE_TOOL_URL=https://fw-tool-api.slimevr.io -# VITE_FIRMWARE_TOOL_S3_URL=https://fw-tool-bucket.slimevr.io -# FIRMWARE_TOOL_SCHEMA_URL=https://fw-tool-api.slimevr.io/api-json +VITE_FIRMWARE_TOOL_URL=https://fw-tool-api.slimevr.io +VITE_FIRMWARE_TOOL_S3_URL=https://fw-tool-bucket.slimevr.io +FIRMWARE_TOOL_SCHEMA_URL=https://fw-tool-api.slimevr.io/api-json -VITE_FIRMWARE_TOOL_URL=http://localhost:3000 -VITE_FIRMWARE_TOOL_S3_URL=http://localhost:9099 -FIRMWARE_TOOL_SCHEMA_URL=http://localhost:3000/api-json +# VITE_FIRMWARE_TOOL_URL=http://localhost:3000 +# VITE_FIRMWARE_TOOL_S3_URL=http://localhost:9000 +# FIRMWARE_TOOL_SCHEMA_URL=http://localhost:3000/api-json diff --git a/gui/package.json b/gui/package.json index 73d083fbf..376770e7f 100644 --- a/gui/package.json +++ b/gui/package.json @@ -25,7 +25,6 @@ "@tauri-apps/plugin-store": "^2.0.0", "@tweenjs/tween.js": "^25.0.0", "@twemoji/svg": "^15.0.0", - "ajv": "^8.17.1", "browser-fs-access": "^0.35.0", "classnames": "^2.5.1", "flatbuffers": "22.10.26", diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index 20f6f6e14..3cf68761a 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -89,7 +89,6 @@ board_type-WEMOSD1MINI = Wemos D1 Mini board_type-TTGO_TBASE = TTGO T-Base board_type-ESP01 = ESP-01 board_type-SLIMEVR = SlimeVR -board_type-SLIMEVR_V1_2 = SlimeVR v1.2 board_type-LOLIN_C3_MINI = Lolin C3 Mini board_type-BEETLE32C3 = Beetle ESP32-C3 board_type-ESP32C3DEVKITM1 = Espressif ESP32-C3 DevKitM-1 @@ -384,8 +383,7 @@ tracker-settings-name_section-label = Tracker name tracker-settings-forget = Forget tracker tracker-settings-forget-description = Removes the tracker from the SlimeVR Server and prevents it from connecting until the server is restarted. The configuration of the tracker won't be lost. tracker-settings-forget-label = Forget tracker -tracker-settings-update-unavailable-v2 = No releases found -tracker-settings-update-incompatible = Cannot update. Incompatible board +tracker-settings-update-unavailable = Cannot be updated (DIY) tracker-settings-update-low-battery = Cannot update. Battery lower than 50% tracker-settings-update-up_to_date = Up to date tracker-settings-update-blocked = Update not available. No other releases available diff --git a/gui/src/components/firmware-tool/FirmwareTool.tsx b/gui/src/components/firmware-tool/FirmwareTool.tsx index d32d1303f..5b95bd08b 100644 --- a/gui/src/components/firmware-tool/FirmwareTool.tsx +++ b/gui/src/components/firmware-tool/FirmwareTool.tsx @@ -3,7 +3,7 @@ import { Typography } from '@/components/commons/Typography'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { FirmwareToolContextC, - provideFirmwareTool, + useFirmwareToolContext, } from '@/hooks/firmware-tool'; import { AddImusStep } from './AddImusStep'; import { SelectBoardStep } from './SelectBoardStep'; @@ -15,87 +15,63 @@ import { SelectFirmwareStep } from './SelectFirmwareStep'; import { BuildStep } from './BuildStep'; import { FlashingMethodStep } from './FlashingMethodStep'; import { FlashingStep } from './FlashingStep'; +import { FlashBtnStep } from './FlashBtnStep'; +import { FirmwareUpdateMethod } from 'solarxr-protocol'; import { useMemo } from 'react'; -import { - useGetHealth, - useGetIsCompatibleVersion, -} from '@/firmware-tool-api/firmwareToolComponents'; -import { SelectSourceSetep } from './steps/SelectSourceStep'; -import { BoardDefaultsStep } from './steps/BoardDefaultsStep'; function FirmwareToolContent() { const { l10n } = useLocalization(); - const context = provideFirmwareTool(); - const { isError, isLoading: isInitialLoading, refetch } = useGetHealth({}); - const compatibilityCheckEnabled = !!__VERSION_TAG__; - const { isLoading: isCompatibilityLoading, data: compatibilityData } = - useGetIsCompatibleVersion( - { pathParams: { version: __VERSION_TAG__ } }, - { enabled: compatibilityCheckEnabled } - ); - - const isLoading = isInitialLoading || isCompatibilityLoading; - const isCompatible = - !compatibilityCheckEnabled || (compatibilityData?.success ?? false); + const context = useFirmwareToolContext(); + const { isError, isGlobalLoading: isLoading, retry, isCompatible } = context; const steps = useMemo(() => { const steps = [ { - id: 'SelectSource', - component: SelectSourceSetep, - title: l10n.getString('firmware_tool-step-select_source'), + id: 'SelectBoard', + component: SelectBoardStep, + title: l10n.getString('firmware_tool-board_step'), }, { - component: BoardDefaultsStep, - title: l10n.getString('firmware_tool-step-board_defaults'), + component: BoardPinsStep, + title: l10n.getString('firmware_tool-board_pins_step'), + }, + { + component: AddImusStep, + title: l10n.getString('firmware_tool-add_imus_step'), + }, + { + id: 'SelectFirmware', + component: SelectFirmwareStep, + title: l10n.getString('firmware_tool-select_firmware_step'), + }, + { + component: FlashingMethodStep, + id: 'FlashingMethod', + title: l10n.getString('firmware_tool-flash_method_step'), + }, + { + component: BuildStep, + title: l10n.getString('firmware_tool-build_step'), + }, + { + component: FlashingStep, + title: l10n.getString('firmware_tool-flashing_step'), }, - // { - // component: BoardPinsStep, - // title: l10n.getString('firmware_tool-board_pins_step'), - // }, - // { - // component: AddImusStep, - // title: l10n.getString('firmware_tool-add_imus_step'), - // }, - // { - // id: 'SelectFirmware', - // component: SelectFirmwareStep, - // title: l10n.getString('firmware_tool-select_firmware_step'), - // }, - // { - // component: FlashingMethodStep, - // id: 'FlashingMethod', - // title: l10n.getString('firmware_tool-flash_method_step'), - // }, - // { - // component: BuildStep, - // title: l10n.getString('firmware_tool-build_step'), - // }, - // { - // component: FlashingStep, - // title: l10n.getString('firmware_tool-flashing_step'), - // }, ]; - // if ( - // context.defaultConfig?.needBootPress && - // context.selectedDevices?.find( - // ({ type }) => type === FirmwareUpdateMethod.SerialFirmwareUpdate - // ) - // ) { - // steps.splice(5, 0, { - // component: FlashBtnStep, - // title: l10n.getString('firmware_tool-flashbtn_step'), - // }); - // } + if ( + context.defaultConfig?.needBootPress && + context.selectedDevices?.find( + ({ type }) => type === FirmwareUpdateMethod.SerialFirmwareUpdate + ) + ) { + steps.splice(5, 0, { + component: FlashBtnStep, + title: l10n.getString('firmware_tool-flashbtn_step'), + }); + } return steps; - }, [ - /* context.defaultConfig?.needBootPress, context.selectedDevices */ l10n, - ]); - - const retry = async () => { - await refetch(); - }; + }, [context.defaultConfig?.needBootPress, context.selectedDevices, l10n]); return ( diff --git a/gui/src/components/firmware-tool/FlashBtnStep.tsx b/gui/src/components/firmware-tool/FlashBtnStep.tsx index 602eaa4f6..3f8bcc98d 100644 --- a/gui/src/components/firmware-tool/FlashBtnStep.tsx +++ b/gui/src/components/firmware-tool/FlashBtnStep.tsx @@ -26,9 +26,7 @@ export function FlashBtnStep({ {l10n.getString('firmware_tool-flashbtn_step-description')} {defaultConfig?.boardConfig.type === - boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR] || - defaultConfig?.boardConfig.type === - boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR_V1_2] ? ( + boardTypeToFirmwareToolBoardType[BoardType.SLIMEVR] ? ( <> {l10n.getString('firmware_tool-flashbtn_step-board_SLIMEVR')} diff --git a/gui/src/components/firmware-tool/steps/BoardDefaultsStep.tsx b/gui/src/components/firmware-tool/steps/BoardDefaultsStep.tsx deleted file mode 100644 index fbd8e4b71..000000000 --- a/gui/src/components/firmware-tool/steps/BoardDefaultsStep.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { useLocalization } from '@fluent/react'; -import { Typography } from '@/components/commons/Typography'; -import { useFirmwareTool } from '@/hooks/firmware-tool'; -import {} from '@/firmware-tool-api/firmwareToolComponents'; -import { SomeJSONSchema } from 'ajv/dist/types/json-schema'; -import { useEffect } from 'react'; - -const refToKey = (ref: string) => ref.substring('#/$defs/'.length); - -type ComponentNode = { label: string } & ( - | { - type: 'checkbox'; - value: boolean; - } - | { - type: 'dropdown'; - items: string[]; - value: string; - } - | { - type: 'text'; - value: string; - } - | { - type: 'group'; - name: string; - childrens: ComponentNode[]; - } - | { - type: 'list'; - childrens: ComponentNode[]; - } -); - -const handleNode = ( - defs: SomeJSONSchema['$defs'], - node: SomeJSONSchema, - data: any, - parentNode: SomeJSONSchema | null = null -): ComponentNode[] => { - const components: ComponentNode[] = []; - if (!node) return []; - - if (node.$ref) { - return handleNode(defs, defs![refToKey(node.$ref)], data, node); - } - if (node.type === 'object') { - if ( - node.oneOf && - Array.isArray(node.oneOf) && - node.discriminator?.propertyName - ) { - const discriminator = node.discriminator.propertyName; - const selected = node.oneOf.find((o) => { - if ( - o.$ref && - defs![refToKey(o.$ref)].properties[discriminator].const === - data[discriminator] - ) { - return true; - } - - if ( - o.type === 'object' && - o.properties[discriminator].const === data[discriminator] - ) { - console.log(data); - return true; - } - return false; - }); - components.push(...handleNode(defs, selected, data, node)); - } else if (node.properties) { - const childs: ComponentNode[] = []; - for (const property of Object.keys(node.properties)) { - childs.push( - ...handleNode(defs, node.properties[property], data[property], node) - ); - } - components.push({ - type: 'group', - name: node.description, - childrens: childs, - label: node.description ?? parentNode?.description ?? 'nothing o', - }); - } else { - throw 'unknown object'; - } - } - if (node.type === 'boolean') { - components.push({ - type: 'checkbox', - label: node.description ?? parentNode?.description ?? 'nothing b', - value: data, - }); - } - if (node.type === 'array') { - if (!Array.isArray(data)) throw 'not an array'; - const childs: ComponentNode[] = []; - data.forEach((d) => { - childs.push(...handleNode(defs, node.items, d, node)); - }); - components.push({ - type: 'list', - childrens: childs, - label: node.description ?? parentNode?.description ?? 'nothing a', - }); - } - if (node.type === 'string') { - if (node.enum) { - components.push({ - type: 'dropdown', - label: node.description ?? parentNode?.description ?? 'nothing e', - items: node.enum, - value: data, - }); - } else { - components.push({ - type: 'text', - label: node.description ?? parentNode?.description ?? 'nothing s', - value: data, - }); - } - } - if (node.type === 'number') { - components.push({ - type: 'text', - label: node.description ?? parentNode?.description ?? 'nothing n', - value: data, - }); - } - return components; -}; - -export function BoardDefaultsStep({ - nextStep, - goTo, -}: { - nextStep: () => void; - prevStep: () => void; - goTo: (id: string) => void; -}) { - const { l10n } = useLocalization(); - const { selectedSource } = useFirmwareTool(); - - useEffect(() => { - if (!selectedSource) return; - const d = selectedSource?.default?.schema as any as SomeJSONSchema; - if (!d.$defs) throw 'no defs'; - const t = refToKey(d.properties.defaults.additionalProperties.$ref); - if (!t) throw 'unable to get defaults ref'; - const boardConfig = d.$defs[t]; - const boardValues = d.$defs[refToKey(boardConfig.properties.values.$ref)]; - const data = selectedSource.default?.defaults.values as any; - console.log( - // selectedSource.default?.defaults.values - JSON.stringify(handleNode(d.$defs, boardValues, data), null, 2) - ); - }, [selectedSource]); - - return ( - <> -
-
- - {l10n.getString('firmware_tool-board_step-description')} - -
-
-
- - ); -} diff --git a/gui/src/components/firmware-tool/steps/SelectSourceStep.tsx b/gui/src/components/firmware-tool/steps/SelectSourceStep.tsx deleted file mode 100644 index 361eb101f..000000000 --- a/gui/src/components/firmware-tool/steps/SelectSourceStep.tsx +++ /dev/null @@ -1,234 +0,0 @@ -import { Localized, useLocalization } from '@fluent/react'; -import { Typography } from '@/components/commons/Typography'; -import { LoaderIcon, SlimeState } from '@/components/commons/icon/LoaderIcon'; -import { useFirmwareTool } from '@/hooks/firmware-tool'; -import classNames from 'classnames'; -import { Button } from '@/components/commons/Button'; -import { - fetchGetFirmwareBoardDefaults, - useGetFirmwareSources, -} from '@/firmware-tool-api/firmwareToolComponents'; -import { useEffect, useMemo, useState } from 'react'; - -function Selector({ - text, - active, - disabled, - official, - onClick, -}: { - text: string; - active: boolean; - official?: boolean; - disabled?: boolean; - onClick: () => void; -}) { - return ( -
{ - if (!disabled) onClick(); - }} - > - {official && ( -
- Official -
- )} - {text} -
- ); -} - -export function SelectSourceSetep({ - nextStep, - goTo, -}: { - nextStep: () => void; - prevStep: () => void; - goTo: (id: string) => void; -}) { - const { l10n } = useLocalization(); - const { setSelectedSource, selectedSource } = useFirmwareTool(); - const [partialBoard, setPartialBoard] = useState<{ - source?: string; - version?: string; - board?: string; - }>(); - const { isFetching, data: sources } = useGetFirmwareSources({}); - - const { possibleBoards, possibleVersions, sourcesGroupped } = useMemo(() => { - return { - sourcesGroupped: sources?.reduce( - (curr, source) => { - if (!curr.find(({ name }) => source.source === name)) - curr.push({ - name: source.source, - official: source.official, - disabled: - !partialBoard?.board || - !source.availableBoards.includes(partialBoard.board), - }); - return curr; - }, - [] as { name: string; official: boolean; disabled: boolean }[] - ), - possibleBoards: sources?.reduce((curr, source) => { - const unknownBoards = source.availableBoards.filter( - (b) => !curr.includes(b) - ); - curr.push(...unknownBoards); - return curr; - }, [] as string[]), - possibleVersions: sources?.reduce( - (curr, source) => { - if (!curr.find(({ name }) => source.version === name)) - curr.push({ - disabled: - !partialBoard?.board || - !source.availableBoards.includes(partialBoard.board) || - source.source !== partialBoard.source, - name: source.version, - }); - - return curr; - }, - [] as { name: string; disabled: boolean }[] - ), - }; - }, [sources, partialBoard]); - - useEffect(() => { - if (partialBoard?.source && partialBoard.board && partialBoard.version) { - const params = { - board: partialBoard.board, - source: partialBoard.source, - version: partialBoard.version, - }; - fetchGetFirmwareBoardDefaults({ - queryParams: params, - }).then((board) => - setSelectedSource({ - source: params, - default: board, - }) - ); - } - }, [partialBoard]); - - const formatSource = (name: string, official: boolean) => { - return !official ? name : name.substring(name.indexOf('/') + 1); - }; - - return ( - <> -
-
- - {l10n.getString('firmware_tool-board_step-description')} - -
-
- {!isFetching && ( - <> -
-
- Board Type -
- {possibleBoards?.map((board) => ( - { - setPartialBoard({ board }); - }} - text={board} - > - ))} -
-
-
- - Firmware Source - -
- {sourcesGroupped?.map(({ name, official, disabled }) => ( - { - setPartialBoard((curr) => ({ - ...curr, - source: name, - })); - }} - text={formatSource(name, official)} - > - ))} -
-
-
- - Firmware Version - -
- {possibleVersions?.map(({ name, disabled }) => ( - { - setPartialBoard((curr) => ({ - ...curr, - version: name, - })); - }} - text={name} - > - ))} -
-
-
-
- - - -
- - )} - - {isFetching && ( -
- - - - -
- )} -
-
- - ); -} diff --git a/gui/src/components/firmware-update/FirmwareUpdate.tsx b/gui/src/components/firmware-update/FirmwareUpdate.tsx index 273156ea4..25578abf3 100644 --- a/gui/src/components/firmware-update/FirmwareUpdate.tsx +++ b/gui/src/components/firmware-update/FirmwareUpdate.tsx @@ -3,7 +3,6 @@ import { Typography } from '@/components/commons/Typography'; import { getTrackerName } from '@/hooks/tracker'; import { ComponentProps, useEffect, useMemo, useRef, useState } from 'react'; import { - BoardType, DeviceDataT, DeviceIdTableT, FirmwareUpdateMethod, @@ -40,8 +39,6 @@ interface FirmwareUpdateForm { selectedDevices: { [key: string]: boolean }; } -type SelectedDeviceWithBoard = SelectedDevice & { board: BoardType }; - interface UpdateStatus { status: FirmwareUpdateStatus; type: FirmwareUpdateMethod; @@ -199,34 +196,21 @@ export function FirmwareUpdate() { }; }, []); - const queueFlashing = (selectedDevices: SelectedDeviceWithBoard[]) => { + const queueFlashing = (selectedDevices: SelectedDevice[]) => { clear(); pendingDevicesRef.current = selectedDevices; + const firmwareFile = currentFirmwareRelease?.firmwareFile; + if (!firmwareFile) throw new Error('invalid state - no firmware file'); + const requests = getFlashingRequests( + selectedDevices, + [{ isFirmware: true, firmwareId: '', url: firmwareFile, offset: 0 }], + { wifi: undefined, alonePage: false, progress: 0 }, // we do not use serial + null // we do not use serial + ); - if (!currentFirmwareRelease) - throw new Error('invalid state - no fw release'); - - const groupedByBoard = selectedDevices.reduce((curr, device) => { - const boards = curr.get(device.board) ?? []; - boards.push(device); - curr.set(device.board, boards); - return curr; - }, new Map()); - for (const [board, devices] of groupedByBoard) { - if (board === BoardType.UNKNOWN) continue; - const firmwareFile = currentFirmwareRelease.firmwareFiles[board]; - if (!firmwareFile) continue; - const requests = getFlashingRequests( - devices, - [{ isFirmware: true, firmwareId: '', url: firmwareFile, offset: 0 }], - { wifi: undefined, alonePage: false, progress: 0 }, // we do not use serial - null // we do not use serial - ); - - requests.forEach((req) => { - sendRPCPacket(RpcMessage.FirmwareUpdateRequest, req); - }); - } + requests.forEach((req) => { + sendRPCPacket(RpcMessage.FirmwareUpdateRequest, req); + }); }; const trackerWithErrors = useMemo( @@ -297,12 +281,11 @@ export function FirmwareUpdate() { { type: FirmwareUpdateMethod.OTAFirmwareUpdate, deviceId: id, - board: device.hardwareInfo?.officialBoardType ?? BoardType.UNKNOWN, deviceNames: deviceNames(device, l10n), }, ]; }, - [] as SelectedDeviceWithBoard[] + [] as SelectedDevice[] ); if (!selectedDevices) throw new Error('invalid state - no selected devices'); diff --git a/gui/src/components/tracker/TrackerSettings.tsx b/gui/src/components/tracker/TrackerSettings.tsx index 0f1e479f8..4f0489cce 100644 --- a/gui/src/components/tracker/TrackerSettings.tsx +++ b/gui/src/components/tracker/TrackerSettings.tsx @@ -170,7 +170,11 @@ export function TrackerSettingsPage() { currentFirmwareRelease && tracker?.device?.hardwareInfo && checkForUpdate(currentFirmwareRelease, tracker?.device); - const updateUnavailable = needUpdate === null; + const updateUnavailable = + tracker?.device?.hardwareInfo?.officialBoardType !== BoardType.SLIMEVR || + !semver.valid( + tracker?.device?.hardwareInfo?.firmwareVersion?.toString() ?? 'none' + ); return (
- {updateUnavailable && ( - - No releases found + + Cannot be updated (DIY) )} {!updateUnavailable && ( <> - {needUpdate === 'unavailable' && ( - - - Cannot be updated, Incompatible board - - - )} {needUpdate === 'blocked' && ( // This happens only if no update is available and or the user is not in the current stagged diff --git a/gui/src/firmware-tool-api/firmwareToolComponents.ts b/gui/src/firmware-tool-api/firmwareToolComponents.ts index caa0ff98e..12c65bab1 100644 --- a/gui/src/firmware-tool-api/firmwareToolComponents.ts +++ b/gui/src/firmware-tool-api/firmwareToolComponents.ts @@ -4,10 +4,7 @@ * @version 0.0.1 */ import * as reactQuery from '@tanstack/react-query'; -import { - useFirmwareToolContext, - FirmwareToolContext, -} from './firmwareToolContext'; +import { useFirmwareToolContext, FirmwareToolContext } from './firmwareToolContext'; import type * as Fetcher from './firmwareToolFetcher'; import { firmwareToolFetch } from './firmwareToolFetcher'; import type * as Schemas from './firmwareToolSchemas'; @@ -30,16 +27,7 @@ export const fetchGetIsCompatibleVersion = ( signal?: AbortSignal ) => firmwareToolFetch< - | { - success: true; - } - | { - success: false; - reason: { - message: string; - versions: string; - }; - }, + Schemas.VerionCheckResponse, GetIsCompatibleVersionError, undefined, {}, @@ -50,51 +38,20 @@ export const fetchGetIsCompatibleVersion = ( /** * Is this api compatible with the server version given */ -export const useGetIsCompatibleVersion = < - TData = - | { - success: true; - } - | { - success: false; - reason: { - message: string; - versions: string; - }; - }, ->( +export const useGetIsCompatibleVersion = ( variables: GetIsCompatibleVersionVariables, options?: Omit< reactQuery.UseQueryOptions< - | { - success: true; - } - | { - success: false; - reason: { - message: string; - versions: string; - }; - }, + Schemas.VerionCheckResponse, GetIsCompatibleVersionError, TData >, 'queryKey' | 'queryFn' | 'initialData' > ) => { - const { fetcherOptions, queryOptions, queryKeyFn } = - useFirmwareToolContext(options); + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); return reactQuery.useQuery< - | { - success: true; - } - | { - success: false; - reason: { - message: string; - versions: string; - }; - }, + Schemas.VerionCheckResponse, GetIsCompatibleVersionError, TData >({ @@ -110,6 +67,504 @@ export const useGetIsCompatibleVersion = < }); }; +export type GetFirmwaresError = Fetcher.ErrorWrapper; + +export type GetFirmwaresResponse = Schemas.FirmwareDTO[]; + +export type GetFirmwaresVariables = FirmwareToolContext['fetcherOptions']; + +/** + * List all the built firmwares + */ +export const fetchGetFirmwares = ( + variables: GetFirmwaresVariables, + signal?: AbortSignal +) => + firmwareToolFetch({ + url: '/firmwares', + method: 'get', + ...variables, + signal, + }); + +/** + * List all the built firmwares + */ +export const useGetFirmwares = ( + variables: GetFirmwaresVariables, + options?: Omit< + reactQuery.UseQueryOptions, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery({ + queryKey: queryKeyFn({ + path: '/firmwares', + operationId: 'getFirmwares', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwares({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type PostFirmwaresBuildError = Fetcher.ErrorWrapper<{ + status: 400; + payload: Schemas.VersionNotFoundExeption; +}>; + +export type PostFirmwaresBuildVariables = { + body: Schemas.CreateBuildFirmwareDTO; +} & FirmwareToolContext['fetcherOptions']; + +/** + * Build a firmware from the requested configuration + */ +export const fetchPostFirmwaresBuild = ( + variables: PostFirmwaresBuildVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + Schemas.BuildResponseDTO, + PostFirmwaresBuildError, + Schemas.CreateBuildFirmwareDTO, + {}, + {}, + {} + >({ url: '/firmwares/build', method: 'post', ...variables, signal }); + +/** + * Build a firmware from the requested configuration + */ +export const usePostFirmwaresBuild = ( + options?: Omit< + reactQuery.UseMutationOptions< + Schemas.BuildResponseDTO, + PostFirmwaresBuildError, + PostFirmwaresBuildVariables + >, + 'mutationFn' + > +) => { + const { fetcherOptions } = useFirmwareToolContext(); + return reactQuery.useMutation< + Schemas.BuildResponseDTO, + PostFirmwaresBuildError, + PostFirmwaresBuildVariables + >({ + mutationFn: (variables: PostFirmwaresBuildVariables) => + fetchPostFirmwaresBuild({ ...fetcherOptions, ...variables }), + ...options, + }); +}; + +export type GetFirmwaresBuildStatusIdPathParams = { + id: string; +}; + +export type GetFirmwaresBuildStatusIdError = Fetcher.ErrorWrapper; + +export type GetFirmwaresBuildStatusIdVariables = { + pathParams: GetFirmwaresBuildStatusIdPathParams; +} & FirmwareToolContext['fetcherOptions']; + +/** + * Get the build status of a firmware + * This is a SSE (Server Sent Event) + * you can use the web browser api to check for the build status and update the ui in real time + */ +export const fetchGetFirmwaresBuildStatusId = ( + variables: GetFirmwaresBuildStatusIdVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + Schemas.ObservableType, + GetFirmwaresBuildStatusIdError, + undefined, + {}, + {}, + GetFirmwaresBuildStatusIdPathParams + >({ + url: '/firmwares/build-status/{id}', + method: 'get', + ...variables, + signal, + }); + +/** + * Get the build status of a firmware + * This is a SSE (Server Sent Event) + * you can use the web browser api to check for the build status and update the ui in real time + */ +export const useGetFirmwaresBuildStatusId = ( + variables: GetFirmwaresBuildStatusIdVariables, + options?: Omit< + reactQuery.UseQueryOptions< + Schemas.ObservableType, + GetFirmwaresBuildStatusIdError, + TData + >, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery< + Schemas.ObservableType, + GetFirmwaresBuildStatusIdError, + TData + >({ + queryKey: queryKeyFn({ + path: '/firmwares/build-status/{id}', + operationId: 'getFirmwaresBuildStatusId', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresBuildStatusId({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresBoardsError = Fetcher.ErrorWrapper; + +export type GetFirmwaresBoardsResponse = string[]; + +export type GetFirmwaresBoardsVariables = FirmwareToolContext['fetcherOptions']; + +/** + * List all the possible board types + */ +export const fetchGetFirmwaresBoards = ( + variables: GetFirmwaresBoardsVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + GetFirmwaresBoardsResponse, + GetFirmwaresBoardsError, + undefined, + {}, + {}, + {} + >({ url: '/firmwares/boards', method: 'get', ...variables, signal }); + +/** + * List all the possible board types + */ +export const useGetFirmwaresBoards = ( + variables: GetFirmwaresBoardsVariables, + options?: Omit< + reactQuery.UseQueryOptions< + GetFirmwaresBoardsResponse, + GetFirmwaresBoardsError, + TData + >, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery< + GetFirmwaresBoardsResponse, + GetFirmwaresBoardsError, + TData + >({ + queryKey: queryKeyFn({ + path: '/firmwares/boards', + operationId: 'getFirmwaresBoards', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresBoards({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresVersionsError = Fetcher.ErrorWrapper; + +export type GetFirmwaresVersionsResponse = Schemas.ReleaseDTO[]; + +export type GetFirmwaresVersionsVariables = FirmwareToolContext['fetcherOptions']; + +/** + * List all the possible versions to build a firmware from + */ +export const fetchGetFirmwaresVersions = ( + variables: GetFirmwaresVersionsVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + GetFirmwaresVersionsResponse, + GetFirmwaresVersionsError, + undefined, + {}, + {}, + {} + >({ url: '/firmwares/versions', method: 'get', ...variables, signal }); + +/** + * List all the possible versions to build a firmware from + */ +export const useGetFirmwaresVersions = ( + variables: GetFirmwaresVersionsVariables, + options?: Omit< + reactQuery.UseQueryOptions< + GetFirmwaresVersionsResponse, + GetFirmwaresVersionsError, + TData + >, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery< + GetFirmwaresVersionsResponse, + GetFirmwaresVersionsError, + TData + >({ + queryKey: queryKeyFn({ + path: '/firmwares/versions', + operationId: 'getFirmwaresVersions', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresVersions({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresImusError = Fetcher.ErrorWrapper; + +export type GetFirmwaresImusResponse = Schemas.Imudto[]; + +export type GetFirmwaresImusVariables = FirmwareToolContext['fetcherOptions']; + +/** + * List all the possible imus to use + */ +export const fetchGetFirmwaresImus = ( + variables: GetFirmwaresImusVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + GetFirmwaresImusResponse, + GetFirmwaresImusError, + undefined, + {}, + {}, + {} + >({ url: '/firmwares/imus', method: 'get', ...variables, signal }); + +/** + * List all the possible imus to use + */ +export const useGetFirmwaresImus = ( + variables: GetFirmwaresImusVariables, + options?: Omit< + reactQuery.UseQueryOptions, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery({ + queryKey: queryKeyFn({ + path: '/firmwares/imus', + operationId: 'getFirmwaresImus', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresImus({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresBatteriesError = Fetcher.ErrorWrapper; + +export type GetFirmwaresBatteriesResponse = string[]; + +export type GetFirmwaresBatteriesVariables = FirmwareToolContext['fetcherOptions']; + +/** + * List all the battery types + */ +export const fetchGetFirmwaresBatteries = ( + variables: GetFirmwaresBatteriesVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + GetFirmwaresBatteriesResponse, + GetFirmwaresBatteriesError, + undefined, + {}, + {}, + {} + >({ url: '/firmwares/batteries', method: 'get', ...variables, signal }); + +/** + * List all the battery types + */ +export const useGetFirmwaresBatteries = ( + variables: GetFirmwaresBatteriesVariables, + options?: Omit< + reactQuery.UseQueryOptions< + GetFirmwaresBatteriesResponse, + GetFirmwaresBatteriesError, + TData + >, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery< + GetFirmwaresBatteriesResponse, + GetFirmwaresBatteriesError, + TData + >({ + queryKey: queryKeyFn({ + path: '/firmwares/batteries', + operationId: 'getFirmwaresBatteries', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresBatteries({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresDefaultConfigBoardPathParams = { + board: + | 'BOARD_SLIMEVR' + | 'BOARD_NODEMCU' + | 'BOARD_WROOM32' + | 'BOARD_WEMOSD1MINI' + | 'BOARD_TTGO_TBASE' + | 'BOARD_ESP01' + | 'BOARD_LOLIN_C3_MINI' + | 'BOARD_BEETLE32C3' + | 'BOARD_ES32C3DEVKITM1'; +}; + +export type GetFirmwaresDefaultConfigBoardError = Fetcher.ErrorWrapper; + +export type GetFirmwaresDefaultConfigBoardVariables = { + pathParams: GetFirmwaresDefaultConfigBoardPathParams; +} & FirmwareToolContext['fetcherOptions']; + +/** + * Gives the default pins / configuration of a given board + */ +export const fetchGetFirmwaresDefaultConfigBoard = ( + variables: GetFirmwaresDefaultConfigBoardVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + Schemas.DefaultBuildConfigDTO, + GetFirmwaresDefaultConfigBoardError, + undefined, + {}, + {}, + GetFirmwaresDefaultConfigBoardPathParams + >({ + url: '/firmwares/default-config/{board}', + method: 'get', + ...variables, + signal, + }); + +/** + * Gives the default pins / configuration of a given board + */ +export const useGetFirmwaresDefaultConfigBoard = < + TData = Schemas.DefaultBuildConfigDTO, +>( + variables: GetFirmwaresDefaultConfigBoardVariables, + options?: Omit< + reactQuery.UseQueryOptions< + Schemas.DefaultBuildConfigDTO, + GetFirmwaresDefaultConfigBoardError, + TData + >, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery< + Schemas.DefaultBuildConfigDTO, + GetFirmwaresDefaultConfigBoardError, + TData + >({ + queryKey: queryKeyFn({ + path: '/firmwares/default-config/{board}', + operationId: 'getFirmwaresDefaultConfigBoard', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresDefaultConfigBoard({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + +export type GetFirmwaresIdPathParams = { + id: string; +}; + +export type GetFirmwaresIdError = Fetcher.ErrorWrapper<{ + status: 404; + payload: Schemas.HttpException; +}>; + +export type GetFirmwaresIdVariables = { + pathParams: GetFirmwaresIdPathParams; +} & FirmwareToolContext['fetcherOptions']; + +/** + * Get the inforamtions about a firmware from its id + * also provide more informations than the simple list, like pins and imus and files + */ +export const fetchGetFirmwaresId = ( + variables: GetFirmwaresIdVariables, + signal?: AbortSignal +) => + firmwareToolFetch< + Schemas.FirmwareDetailDTO, + GetFirmwaresIdError, + undefined, + {}, + {}, + GetFirmwaresIdPathParams + >({ url: '/firmwares/{id}', method: 'get', ...variables, signal }); + +/** + * Get the inforamtions about a firmware from its id + * also provide more informations than the simple list, like pins and imus and files + */ +export const useGetFirmwaresId = ( + variables: GetFirmwaresIdVariables, + options?: Omit< + reactQuery.UseQueryOptions, + 'queryKey' | 'queryFn' | 'initialData' + > +) => { + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); + return reactQuery.useQuery({ + queryKey: queryKeyFn({ + path: '/firmwares/{id}', + operationId: 'getFirmwaresId', + variables, + }), + queryFn: ({ signal }) => + fetchGetFirmwaresId({ ...fetcherOptions, ...variables }, signal), + ...options, + ...queryOptions, + }); +}; + export type GetHealthError = Fetcher.ErrorWrapper; export type GetHealthVariables = FirmwareToolContext['fetcherOptions']; @@ -118,10 +573,7 @@ export type GetHealthVariables = FirmwareToolContext['fetcherOptions']; * Gives the status of the api * this endpoint will always return true */ -export const fetchGetHealth = ( - variables: GetHealthVariables, - signal?: AbortSignal -) => +export const fetchGetHealth = (variables: GetHealthVariables, signal?: AbortSignal) => firmwareToolFetch({ url: '/health', method: 'get', @@ -133,15 +585,14 @@ export const fetchGetHealth = ( * Gives the status of the api * this endpoint will always return true */ -export const useGetHealth = ( +export const useGetHealth = ( variables: GetHealthVariables, options?: Omit< reactQuery.UseQueryOptions, 'queryKey' | 'queryFn' | 'initialData' > ) => { - const { fetcherOptions, queryOptions, queryKeyFn } = - useFirmwareToolContext(options); + const { fetcherOptions, queryOptions, queryKeyFn } = useFirmwareToolContext(options); return reactQuery.useQuery({ queryKey: queryKeyFn({ path: '/health', @@ -155,252 +606,54 @@ export const useGetHealth = ( }); }; -export type GetFirmwareSourcesError = Fetcher.ErrorWrapper; - -export type GetFirmwareSourcesResponse = Schemas.FirmwareSource[]; - -export type GetFirmwareSourcesVariables = FirmwareToolContext['fetcherOptions']; - -/** - * List all the sources you can build a firmware from - */ -export const fetchGetFirmwareSources = ( - variables: GetFirmwareSourcesVariables, - signal?: AbortSignal -) => - firmwareToolFetch< - GetFirmwareSourcesResponse, - GetFirmwareSourcesError, - undefined, - {}, - {}, - {} - >({ url: '/firmware/sources', method: 'get', ...variables, signal }); - -/** - * List all the sources you can build a firmware from - */ -export const useGetFirmwareSources = ( - variables: GetFirmwareSourcesVariables, - options?: Omit< - reactQuery.UseQueryOptions< - GetFirmwareSourcesResponse, - GetFirmwareSourcesError, - TData - >, - 'queryKey' | 'queryFn' | 'initialData' - > -) => { - const { fetcherOptions, queryOptions, queryKeyFn } = - useFirmwareToolContext(options); - return reactQuery.useQuery< - GetFirmwareSourcesResponse, - GetFirmwareSourcesError, - TData - >({ - queryKey: queryKeyFn({ - path: '/firmware/sources', - operationId: 'getFirmwareSources', - variables, - }), - queryFn: ({ signal }) => - fetchGetFirmwareSources({ ...fetcherOptions, ...variables }, signal), - ...options, - ...queryOptions, - }); -}; - -export type GetFirmwareBoardDefaultsQueryParams = { - source: string; - board: string; - version: string; -}; - -export type GetFirmwareBoardDefaultsError = Fetcher.ErrorWrapper; - -export type GetFirmwareBoardDefaultsVariables = { - queryParams: GetFirmwareBoardDefaultsQueryParams; -} & FirmwareToolContext['fetcherOptions']; - -/** - * Fet the defaults of a specific board on a specific firmware - */ -export const fetchGetFirmwareBoardDefaults = ( - variables: GetFirmwareBoardDefaultsVariables, - signal?: AbortSignal -) => - firmwareToolFetch< - Schemas.FirmwareBoardDefaultsNullable, - GetFirmwareBoardDefaultsError, - undefined, - {}, - GetFirmwareBoardDefaultsQueryParams, - {} - >({ url: '/firmware/board-defaults', method: 'get', ...variables, signal }); - -/** - * Fet the defaults of a specific board on a specific firmware - */ -export const useGetFirmwareBoardDefaults = < - TData = Schemas.FirmwareBoardDefaultsNullable, ->( - variables: GetFirmwareBoardDefaultsVariables, - options?: Omit< - reactQuery.UseQueryOptions< - Schemas.FirmwareBoardDefaultsNullable, - GetFirmwareBoardDefaultsError, - TData - >, - 'queryKey' | 'queryFn' | 'initialData' - > -) => { - const { fetcherOptions, queryOptions, queryKeyFn } = - useFirmwareToolContext(options); - return reactQuery.useQuery< - Schemas.FirmwareBoardDefaultsNullable, - GetFirmwareBoardDefaultsError, - TData - >({ - queryKey: queryKeyFn({ - path: '/firmware/board-defaults', - operationId: 'getFirmwareBoardDefaults', - variables, - }), - queryFn: ({ signal }) => - fetchGetFirmwareBoardDefaults( - { ...fetcherOptions, ...variables }, - signal - ), - ...options, - ...queryOptions, - }); -}; - -export type PostFirmwareBuildError = Fetcher.ErrorWrapper; - -export type PostFirmwareBuildVariables = { - body: Schemas.BuildFirmwareBody; -} & FirmwareToolContext['fetcherOptions']; - -export const fetchPostFirmwareBuild = ( - variables: PostFirmwareBuildVariables, - signal?: AbortSignal -) => - firmwareToolFetch< - Schemas.BuildStatusBasic | Schemas.BuildStatusDone, - PostFirmwareBuildError, - Schemas.BuildFirmwareBody, - {}, - {}, - {} - >({ url: '/firmware/build', method: 'post', ...variables, signal }); - -export const usePostFirmwareBuild = ( - options?: Omit< - reactQuery.UseMutationOptions< - Schemas.BuildStatusBasic | Schemas.BuildStatusDone, - PostFirmwareBuildError, - PostFirmwareBuildVariables - >, - 'mutationFn' - > -) => { - const { fetcherOptions } = useFirmwareToolContext(); - return reactQuery.useMutation< - Schemas.BuildStatusBasic | Schemas.BuildStatusDone, - PostFirmwareBuildError, - PostFirmwareBuildVariables - >({ - mutationFn: (variables: PostFirmwareBuildVariables) => - fetchPostFirmwareBuild({ ...fetcherOptions, ...variables }), - ...options, - }); -}; - -export type GetFirmwareIdPathParams = { - id: string; -}; - -export type GetFirmwareIdError = Fetcher.ErrorWrapper; - -export type GetFirmwareIdVariables = { - pathParams: GetFirmwareIdPathParams; -} & FirmwareToolContext['fetcherOptions']; - -/** - * Get the inforamtions about a firmware from its id - * also provide more informations than the simple list, like pins and imus and files - */ -export const fetchGetFirmwareId = ( - variables: GetFirmwareIdVariables, - signal?: AbortSignal -) => - firmwareToolFetch< - Schemas.FirmwareWithFiles, - GetFirmwareIdError, - undefined, - {}, - {}, - GetFirmwareIdPathParams - >({ url: '/firmware/{id}', method: 'get', ...variables, signal }); - -/** - * Get the inforamtions about a firmware from its id - * also provide more informations than the simple list, like pins and imus and files - */ -export const useGetFirmwareId = ( - variables: GetFirmwareIdVariables, - options?: Omit< - reactQuery.UseQueryOptions< - Schemas.FirmwareWithFiles, - GetFirmwareIdError, - TData - >, - 'queryKey' | 'queryFn' | 'initialData' - > -) => { - const { fetcherOptions, queryOptions, queryKeyFn } = - useFirmwareToolContext(options); - return reactQuery.useQuery< - Schemas.FirmwareWithFiles, - GetFirmwareIdError, - TData - >({ - queryKey: queryKeyFn({ - path: '/firmware/{id}', - operationId: 'getFirmwareId', - variables, - }), - queryFn: ({ signal }) => - fetchGetFirmwareId({ ...fetcherOptions, ...variables }, signal), - ...options, - ...queryOptions, - }); -}; - export type QueryOperation = | { path: '/is-compatible/{version}'; operationId: 'getIsCompatibleVersion'; variables: GetIsCompatibleVersionVariables; } + | { + path: '/firmwares'; + operationId: 'getFirmwares'; + variables: GetFirmwaresVariables; + } + | { + path: '/firmwares/build-status/{id}'; + operationId: 'getFirmwaresBuildStatusId'; + variables: GetFirmwaresBuildStatusIdVariables; + } + | { + path: '/firmwares/boards'; + operationId: 'getFirmwaresBoards'; + variables: GetFirmwaresBoardsVariables; + } + | { + path: '/firmwares/versions'; + operationId: 'getFirmwaresVersions'; + variables: GetFirmwaresVersionsVariables; + } + | { + path: '/firmwares/imus'; + operationId: 'getFirmwaresImus'; + variables: GetFirmwaresImusVariables; + } + | { + path: '/firmwares/batteries'; + operationId: 'getFirmwaresBatteries'; + variables: GetFirmwaresBatteriesVariables; + } + | { + path: '/firmwares/default-config/{board}'; + operationId: 'getFirmwaresDefaultConfigBoard'; + variables: GetFirmwaresDefaultConfigBoardVariables; + } + | { + path: '/firmwares/{id}'; + operationId: 'getFirmwaresId'; + variables: GetFirmwaresIdVariables; + } | { path: '/health'; operationId: 'getHealth'; variables: GetHealthVariables; - } - | { - path: '/firmware/sources'; - operationId: 'getFirmwareSources'; - variables: GetFirmwareSourcesVariables; - } - | { - path: '/firmware/board-defaults'; - operationId: 'getFirmwareBoardDefaults'; - variables: GetFirmwareBoardDefaultsVariables; - } - | { - path: '/firmware/{id}'; - operationId: 'getFirmwareId'; - variables: GetFirmwareIdVariables; }; diff --git a/gui/src/firmware-tool-api/firmwareToolSchemas.ts b/gui/src/firmware-tool-api/firmwareToolSchemas.ts index 786d1dfa3..df109c721 100644 --- a/gui/src/firmware-tool-api/firmwareToolSchemas.ts +++ b/gui/src/firmware-tool-api/firmwareToolSchemas.ts @@ -3,96 +3,606 @@ * * @version 0.0.1 */ -export type FirmwareSource = { - version: string; - source: string; - branch?: string; - official: boolean; - prerelease: boolean; - availableBoards: string[]; -}; - -export type FirmwareBoardDefaults = { - schema: void; - defaults: BoardDefaults; -}; - -export type BoardDefaults = { - values: void; - editable: string[]; - flashingRules: { - applicationOffset: number; - needBootPress: boolean; - needManualReboot: boolean; - shouldOnlyUseDefaults: boolean; +export type VerionCheckResponse = { + success: boolean; + reason?: { + message: string; + versions: string; }; }; -export type BoardDefaultsQuery = { - source: string; - board: string; - version: string; -}; - -export type BuildStatusBasic = { +/** + * Root object declaring a built firmware + * this object contains: + * - the status of the build + * - the the repository and commit used as source + */ +export type FirmwareDTO = { + /** + * UUID of the firmware + * + * @format uuid + */ id: string; - status: - | 'QUEUED' + /** + * Id of the firmware version used. + * Usually the commit id of the source + * used to build the firmware + */ + releaseId: string; + /** + * Current status of the build + * this value will change during the build + * process + * + * BUILDING -> DONE \\ the firmwrare is build and ready + * -> FAILED \\ the build failled and will be garbage collected + */ + buildStatus: | 'CREATING_BUILD_FOLDER' - | 'DOWNLOADING_SOURCE' - | 'EXTRACTING_SOURCE' - | 'BUILDING' - | 'SAVING' - | 'ERROR'; -}; - -export type BuildStatusDone = { - id: string; - status: 'DONE'; - files: { - filePath: string; - offset: number; - isFirmware: boolean; - firmwareId: string; - }[]; -}; - -export type BuildFirmwareBody = { - source: string; - board: string; - version: string; - values: void; -}; - -export type FirmwareWithFiles = { - id: string; - release_id: string; - status: - | 'QUEUED' - | 'CREATING_BUILD_FOLDER' - | 'DOWNLOADING_SOURCE' - | 'EXTRACTING_SOURCE' + | 'DOWNLOADING_FIRMWARE' + | 'EXTRACTING_FIRMWARE' + | 'SETTING_UP_DEFINES' | 'BUILDING' | 'SAVING' | 'DONE' | 'ERROR'; /** + * The repository and branch used as source of the firmware + */ + buildVersion: string; + /** + * The date of creation of this firmware build + * * @format date-time */ createdAt: string; - /** - * @format date-time - */ - updatedAt: string; - files: { - filePath: string; - offset: number; - isFirmware: boolean; - firmwareId: string; - }[]; }; -export type FirmwareBoardDefaultsNullable = { - schema: void; - defaults: BoardDefaults; -} | null; +export type BuildResponseDTO = { + /** + * Id of the firmware + * + * @format uuid + */ + id: string; + /** + * Build status of the firmware + */ + status: + | 'CREATING_BUILD_FOLDER' + | 'DOWNLOADING_FIRMWARE' + | 'EXTRACTING_FIRMWARE' + | 'SETTING_UP_DEFINES' + | 'BUILDING' + | 'SAVING' + | 'DONE' + | 'ERROR'; + /** + * List of built firmware files, only set if the build succeeded + */ + firmwareFiles?: FirmwareFileDTO[]; +}; + +export type FirmwareFileDTO = { + /** + * Url to the file + */ + url: string; + /** + * Address of the partition + */ + offset: number; + /** + * Is this file the main firmware + */ + isFirmware: boolean; + /** + * Id of the linked firmware + * + * @format uuid + */ + firmwareId: string; +}; + +export type CreateBuildFirmwareDTO = { + /** + * Repository of the firmware used + */ + version: string; + /** + * Board config, used to declare the pins used by the board + */ + boardConfig: CreateBoardConfigDTO; + /** + * Imu config, list of all the imus used and their pins + * + * @minItems 1 + */ + imusConfig: CreateImuConfigDTO[]; +}; + +export type CreateBoardConfigDTO = { + /** + * Type of the board + */ + type: + | 'BOARD_SLIMEVR' + | 'BOARD_NODEMCU' + | 'BOARD_WROOM32' + | 'BOARD_WEMOSD1MINI' + | 'BOARD_TTGO_TBASE' + | 'BOARD_ESP01' + | 'BOARD_LOLIN_C3_MINI' + | 'BOARD_BEETLE32C3' + | 'BOARD_ES32C3DEVKITM1'; + /** + * Pin address of the indicator LED + */ + ledPin: string; + /** + * Is the indicator LED enabled + */ + enableLed: boolean; + /** + * Is the led inverted + */ + ledInverted: boolean; + /** + * Pin address of the battery indicator + */ + batteryPin: string; + /** + * Type of battery + */ + batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021'; + /** + * Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2] + * + * @minItems 3 + * @maxItems 3 + */ + batteryResistances: number[]; +}; + +export type CreateImuConfigDTO = { + /** + * Type of the imu + */ + type: + | 'IMU_BNO085' + | 'IMU_MPU9250' + | 'IMU_MPU6500' + | 'IMU_BNO080' + | 'IMU_BNO055' + | 'IMU_BNO086' + | 'IMU_MPU6050' + | 'IMU_BMI160' + | 'IMU_ICM20948' + | 'IMU_BMI270'; + /** + * Pin address of the imu int pin + * not all imus use it + */ + intPin: string | null; + /** + * Rotation of the imu in degrees + */ + rotation: number; + /** + * Pin address of the scl pin + */ + sclPin: string; + /** + * Pin address of the sda pin + */ + sdaPin: string; + /** + * Is this imu optionnal + * Allows for extensions to be unplugged + */ + optional: boolean; +}; + +export type VersionNotFoundExeption = { + cause: void; + name: string; + message: string; + stack?: string; +}; + +/** + * A representation of any set of values over any amount of time. This is the most basic building block + * of RxJS. + */ +export type ObservableType = { + /** + * @deprecated true + */ + source?: Observableany; + /** + * @deprecated true + */ + operator?: OperatoranyType; +}; + +/** + * A representation of any set of values over any amount of time. This is the most basic building block + * of RxJS. + */ +export type Observableany = { + /** + * @deprecated true + */ + source?: Observableany; + /** + * @deprecated true + */ + operator?: Operatoranyany; +}; + +/** + * * + */ +export type Operatoranyany = {}; + +/** + * * + */ +export type OperatoranyType = {}; + +export type ReleaseDTO = { + /** + * id of the release, usually the commit id + */ + id: string; + /** + * url of the release + */ + url: string; + /** + * name of the release + */ + name: string; + /** + * url of the source archive + */ + zipball_url: string; + /** + * Is this release a pre release + */ + prerelease: boolean; + /** + * Is this release a draft + */ + draft: boolean; +}; + +export type Imudto = { + /** + * Type of the imu + */ + type: + | 'IMU_BNO085' + | 'IMU_MPU9250' + | 'IMU_MPU6500' + | 'IMU_BNO080' + | 'IMU_BNO055' + | 'IMU_BNO086' + | 'IMU_MPU6050' + | 'IMU_BMI160' + | 'IMU_ICM20948' + | 'IMU_BMI270'; + /** + * Does that imu type require a int pin + */ + hasIntPin: boolean; + /** + * First address of the imu + */ + imuStartAddress: number; + /** + * Increment of the address for each new imus + */ + addressIncrement: number; +}; + +export type DefaultBuildConfigDTO = { + /** + * Default config of the selected board + * contains all the default pins information about the selected board + */ + boardConfig: CreateBoardConfigDTO; + /** + * Inform the flashing utility that the user need to press the boot (or Flash) button + * on the tracker + */ + needBootPress?: boolean; + /** + * Inform the flashing utility that the board will need a reboot after + * being flashed + */ + needManualReboot?: boolean; + /** + * Will use the default values and skip the customisation options + */ + shouldOnlyUseDefaults?: boolean; + /** + * List of the possible imus pins, usually only two items will be sent + * + * @minItems 1 + */ + imuDefaults: IMUDefaultDTO[]; + /** + * Gives the offset of the firmare file in the eeprom. Used for flashing + */ + application_offset: number; +}; + +export type IMUDefaultDTO = { + /** + * Type of the imu + */ + type?: + | 'IMU_BNO085' + | 'IMU_MPU9250' + | 'IMU_MPU6500' + | 'IMU_BNO080' + | 'IMU_BNO055' + | 'IMU_BNO086' + | 'IMU_MPU6050' + | 'IMU_BMI160' + | 'IMU_ICM20948' + | 'IMU_BMI270'; + /** + * Pin address of the imu int pin + * not all imus use it + */ + intPin: string | null; + /** + * Rotation of the imu in degrees + */ + rotation?: number; + /** + * Pin address of the scl pin + */ + sclPin: string; + /** + * Pin address of the sda pin + */ + sdaPin: string; + /** + * Is this imu optionnal + * Allows for extensions to be unplugged + */ + optional: boolean; +}; + +export type BoardConfigDTONullable = { + /** + * Unique id of the board config, used for relations + * + * @format uuid + */ + id: string; + /** + * Type of the board + */ + type: + | 'BOARD_SLIMEVR' + | 'BOARD_NODEMCU' + | 'BOARD_WROOM32' + | 'BOARD_WEMOSD1MINI' + | 'BOARD_TTGO_TBASE' + | 'BOARD_ESP01' + | 'BOARD_LOLIN_C3_MINI' + | 'BOARD_BEETLE32C3' + | 'BOARD_ES32C3DEVKITM1'; + /** + * Pin address of the indicator LED + */ + ledPin: string; + /** + * Is the indicator LED enabled + */ + enableLed: boolean; + /** + * Is the led inverted + */ + ledInverted: boolean; + /** + * Pin address of the battery indicator + */ + batteryPin: string; + /** + * Type of battery + */ + batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021'; + /** + * Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2] + * + * @minItems 3 + * @maxItems 3 + */ + batteryResistances: number[]; + /** + * Id of the linked firmware, used for relations + * + * @format uuid + */ + firmwareId: string; +}; + +export type FirmwareDetailDTO = { + /** + * Pins informations about the board + */ + boardConfig: BoardConfigDTONullable; + /** + * List of the declared imus, and their pin configuration + * + * @minItems 1 + */ + imusConfig: ImuConfigDTO[]; + /** + * List of the built files / partitions with their url and offsets + */ + firmwareFiles: FirmwareFileDTO[]; + /** + * UUID of the firmware + * + * @format uuid + */ + id: string; + /** + * Id of the firmware version used. + * Usually the commit id of the source + * used to build the firmware + */ + releaseId: string; + /** + * Current status of the build + * this value will change during the build + * process + * + * BUILDING -> DONE \\ the firmwrare is build and ready + * -> FAILED \\ the build failled and will be garbage collected + */ + buildStatus: + | 'CREATING_BUILD_FOLDER' + | 'DOWNLOADING_FIRMWARE' + | 'EXTRACTING_FIRMWARE' + | 'SETTING_UP_DEFINES' + | 'BUILDING' + | 'SAVING' + | 'DONE' + | 'ERROR'; + /** + * The repository and branch used as source of the firmware + */ + buildVersion: string; + /** + * The date of creation of this firmware build + * + * @format date-time + */ + createdAt: string; +}; + +export type BoardConfigDTO = { + /** + * Unique id of the board config, used for relations + * + * @format uuid + */ + id: string; + /** + * Type of the board + */ + type: + | 'BOARD_SLIMEVR' + | 'BOARD_NODEMCU' + | 'BOARD_WROOM32' + | 'BOARD_WEMOSD1MINI' + | 'BOARD_TTGO_TBASE' + | 'BOARD_ESP01' + | 'BOARD_LOLIN_C3_MINI' + | 'BOARD_BEETLE32C3' + | 'BOARD_ES32C3DEVKITM1'; + /** + * Pin address of the indicator LED + */ + ledPin: string; + /** + * Is the indicator LED enabled + */ + enableLed: boolean; + /** + * Is the led inverted + */ + ledInverted: boolean; + /** + * Pin address of the battery indicator + */ + batteryPin: string; + /** + * Type of battery + */ + batteryType: 'BAT_EXTERNAL' | 'BAT_INTERNAL' | 'BAT_MCP3021' | 'BAT_INTERNAL_MCP3021'; + /** + * Array of the different battery resistors, [indicator, SHIELD_R1, SHIELD_R2] + * + * @minItems 3 + * @maxItems 3 + */ + batteryResistances: number[]; + /** + * Id of the linked firmware, used for relations + * + * @format uuid + */ + firmwareId: string; +}; + +export type ImuConfigDTO = { + /** + * Unique id of the config + * this probably will never be shown to the user as it is moslty use for relations + * + * @format uuid + */ + id: string; + /** + * Type of the imu + */ + type: + | 'IMU_BNO085' + | 'IMU_MPU9250' + | 'IMU_MPU6500' + | 'IMU_BNO080' + | 'IMU_BNO055' + | 'IMU_BNO086' + | 'IMU_MPU6050' + | 'IMU_BMI160' + | 'IMU_ICM20948' + | 'IMU_BMI270'; + /** + * Rotation of the imu in degrees + */ + rotation: number; + /** + * Pin address of the imu int pin + * not all imus use it + */ + intPin: string | null; + /** + * Pin address of the scl pin + */ + sclPin: string; + /** + * Pin address of the sda pin + */ + sdaPin: string; + /** + * Is this imu optionnal + * Allows for extensions to be unplugged + */ + optional: boolean; + /** + * id of the linked firmware, used for relations + * + * @format uuid + */ + firmwareId: string; +}; + +/** + * Defines the base Nest HTTP exception, which is handled by the default + * Exceptions Handler. + */ +export type HttpException = { + cause: void; + name: string; + message: string; + stack?: string; +}; diff --git a/gui/src/hooks/firmware-tool.ts b/gui/src/hooks/firmware-tool.ts index 25742fada..58f48eda5 100644 --- a/gui/src/hooks/firmware-tool.ts +++ b/gui/src/hooks/firmware-tool.ts @@ -1,5 +1,20 @@ import { createContext, useContext, useState } from 'react'; import { + fetchGetFirmwaresDefaultConfigBoard, + useGetHealth, + useGetIsCompatibleVersion, +} from '@/firmware-tool-api/firmwareToolComponents'; +import { + BuildResponseDTO, + CreateBoardConfigDTO, + CreateBuildFirmwareDTO, + DefaultBuildConfigDTO, + FirmwareFileDTO, +} from '@/firmware-tool-api/firmwareToolSchemas'; +import { BoardPinsForm } from '@/components/firmware-tool/BoardPinsStep'; +import { DeepPartial } from 'react-hook-form'; +import { + BoardType, DeviceIdT, FirmwarePartT, FirmwareUpdateMethod, @@ -10,20 +25,53 @@ import { SerialFirmwareUpdateT, } from 'solarxr-protocol'; import { OnboardingContext } from './onboarding'; -import { - BoardDefaults, - FirmwareBoardDefaultsNullable, - FirmwareSource, - FirmwareWithFiles, -} from '@/firmware-tool-api/firmwareToolSchemas'; -import { GetFirmwareBoardDefaultsQueryParams } from '@/firmware-tool-api/firmwareToolComponents'; +export type PartialBuildFirmware = DeepPartial; +export type FirmwareBuildStatus = BuildResponseDTO; export type SelectedDevice = { type: FirmwareUpdateMethod; deviceId: string | number; deviceNames: string[]; }; +export const boardTypeToFirmwareToolBoardType: Record< + Exclude< + BoardType, + // This boards will not be handled by the firmware tool. + // These are either impossible to compile automatically or deprecated + | BoardType.CUSTOM + | BoardType.SLIMEVR_DEV + | BoardType.SLIMEVR_LEGACY + | BoardType.OWOTRACK + | BoardType.WRANGLER + | BoardType.MOCOPI + | BoardType.HARITORA + | BoardType.DEV_RESERVED + >, + CreateBoardConfigDTO['type'] | null +> = { + [BoardType.UNKNOWN]: null, + [BoardType.NODEMCU]: 'BOARD_NODEMCU', + [BoardType.WROOM32]: 'BOARD_WROOM32', + [BoardType.WEMOSD1MINI]: 'BOARD_WEMOSD1MINI', + [BoardType.TTGO_TBASE]: 'BOARD_TTGO_TBASE', + [BoardType.ESP01]: 'BOARD_ESP01', + [BoardType.SLIMEVR]: 'BOARD_SLIMEVR', + [BoardType.LOLIN_C3_MINI]: 'BOARD_LOLIN_C3_MINI', + [BoardType.BEETLE32C3]: 'BOARD_BEETLE32C3', + [BoardType.ESP32C3DEVKITM1]: 'BOARD_ES32C3DEVKITM1', + [BoardType.WEMOSWROOM02]: null, + [BoardType.XIAO_ESP32C3]: null, + [BoardType.ESP32C6DEVKITC1]: null, + [BoardType.GLOVE_IMU_SLIMEVR_DEV]: null, + [BoardType.GESTURES]: null, +}; + +export const firmwareToolToBoardType: Record = + Object.fromEntries( + Object.entries(boardTypeToFirmwareToolBoardType).map((a) => a.reverse()) + ); + export const firmwareUpdateErrorStatus = [ FirmwareUpdateStatus.ERROR_AUTHENTICATION_FAILED, FirmwareUpdateStatus.ERROR_DEVICE_NOT_FOUND, @@ -61,7 +109,24 @@ export const firmwareUpdateStatusLabel: Record = { [FirmwareUpdateStatus.ERROR_UNKNOWN]: 'firmware_update-status-ERROR_UNKNOWN', }; -export type FirmwareToolContext = ReturnType; +export interface FirmwareToolContext { + selectBoard: (boardType: CreateBoardConfigDTO['type']) => Promise; + selectVersion: (version: CreateBuildFirmwareDTO['version']) => void; + updatePins: (form: BoardPinsForm) => void; + updateImus: (imus: CreateBuildFirmwareDTO['imusConfig']) => void; + setBuildStatus: (buildStatus: FirmwareBuildStatus) => void; + selectDevices: (device: SelectedDevice[] | null) => void; + retry: () => void; + buildStatus: FirmwareBuildStatus; + defaultConfig: DefaultBuildConfigDTO | null; + newConfig: PartialBuildFirmware | null; + selectedDevices: SelectedDevice[] | null; + isStepLoading: boolean; + isGlobalLoading: boolean; + isCompatible: boolean; + isError: boolean; +} + export const FirmwareToolContextC = createContext( undefined as any ); @@ -74,23 +139,97 @@ export function useFirmwareTool() { return context; } -export function provideFirmwareTool() { - const [selectedSource, setSelectedSource] = useState<{ - source: GetFirmwareBoardDefaultsQueryParams; - default: FirmwareBoardDefaultsNullable; - }>(); +export function useFirmwareToolContext(): FirmwareToolContext { + const [defaultConfig, setDefaultConfig] = useState( + null + ); + const [selectedDevices, selectDevices] = useState(null); + const [newConfig, setNewConfig] = useState({}); + const [isLoading, setLoading] = useState(false); + const { isError, isLoading: isInitialLoading, refetch } = useGetHealth({}); + const compatibilityCheckEnabled = !!__VERSION_TAG__; + const { isLoading: isCompatibilityLoading, data: compatibilityData } = + useGetIsCompatibleVersion( + { pathParams: { version: __VERSION_TAG__ } }, + { enabled: compatibilityCheckEnabled } + ); + const [buildStatus, setBuildStatus] = useState({ + status: 'CREATING_BUILD_FOLDER', + id: '', + }); return { - selectedSource, - setSelectedSource, + selectBoard: async (boardType: CreateBoardConfigDTO['type']) => { + setLoading(true); + const boardDefaults = await fetchGetFirmwaresDefaultConfigBoard({ + pathParams: { board: boardType }, + }); + setDefaultConfig(boardDefaults); + if (boardDefaults.shouldOnlyUseDefaults) { + setNewConfig((currConfig) => ({ + ...currConfig, + ...boardDefaults, + imusConfig: boardDefaults.imuDefaults, + })); + } else { + setNewConfig((currConfig) => ({ + ...currConfig, + boardConfig: { ...currConfig.boardConfig, type: boardType }, + imusConfig: [], + })); + } + setLoading(false); + }, + updatePins: (form: BoardPinsForm) => { + setNewConfig((currConfig) => { + return { + ...currConfig, + imusConfig: [...(currConfig?.imusConfig || [])], + boardConfig: { + ...currConfig.boardConfig, + ...form, + batteryResistances: form.batteryResistances.map((r) => Number(r)), + }, + }; + }); + }, + updateImus: (imus: CreateBuildFirmwareDTO['imusConfig']) => { + setNewConfig((currConfig) => { + return { + ...currConfig, + imusConfig: imus.map(({ rotation, ...fields }) => ({ + ...fields, + rotation: Number(rotation), + })), // Make sure that the rotation is handled as number + }; + }); + }, + retry: async () => { + setLoading(true); + await refetch(); + setLoading(false); + }, + selectVersion: (version: CreateBuildFirmwareDTO['version']) => { + setNewConfig((currConfig) => ({ ...currConfig, version })); + }, + setBuildStatus, + selectDevices, + selectedDevices, + buildStatus, + defaultConfig, + newConfig, + isStepLoading: isLoading, + isGlobalLoading: isInitialLoading || isCompatibilityLoading, + isCompatible: !compatibilityCheckEnabled || (compatibilityData?.success ?? false), + isError: isError || (!compatibilityData?.success && compatibilityCheckEnabled), }; } export const getFlashingRequests = ( devices: SelectedDevice[], - firmwareFiles: FirmwareWithFiles['files'], + firmwareFiles: FirmwareFileDTO[], onboardingState: OnboardingContext['state'], - defaultConfig: BoardDefaults | null + defaultConfig: DefaultBuildConfigDTO | null ) => { const firmware = firmwareFiles.find(({ isFirmware }) => isFirmware); if (!firmware) throw new Error('invalid state - no firmware to find'); @@ -105,7 +244,7 @@ export const getFlashingRequests = ( const part = new FirmwarePartT(); part.offset = 0; - part.url = firmware.filePath; + part.url = firmware.url; const method = new OTAFirmwareUpdateT(); method.deviceId = dId; @@ -128,13 +267,12 @@ export const getFlashingRequests = ( method.deviceId = id; method.ssid = onboardingState.wifi.ssid; method.password = onboardingState.wifi.password; - method.needManualReboot = - defaultConfig?.flashingRules.needManualReboot ?? false; + method.needManualReboot = defaultConfig?.needManualReboot ?? false; - method.firmwarePart = firmwareFiles.map(({ offset, filePath }) => { + method.firmwarePart = firmwareFiles.map(({ offset, url }) => { const part = new FirmwarePartT(); part.offset = offset; - part.url = filePath; + part.url = url; return part; }); diff --git a/gui/src/hooks/firmware-update.ts b/gui/src/hooks/firmware-update.ts index 6d20f1f1f..238f5ff3b 100644 --- a/gui/src/hooks/firmware-update.ts +++ b/gui/src/hooks/firmware-update.ts @@ -8,7 +8,7 @@ export interface FirmwareRelease { name: string; version: string; changelog: string; - firmwareFiles: Partial>; + firmwareFile: string; userCanUpdate: boolean; } @@ -89,9 +89,7 @@ export async function fetchCurrentFirmwareRelease(): Promise=8'} @@ -2311,9 +2305,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -2870,9 +2861,6 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -5828,13 +5816,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -6760,8 +6741,6 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.1.0: {} - fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -7316,8 +7295,6 @@ snapshots: json-schema-traverse@0.4.1: {} - json-schema-traverse@1.0.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/udp/FirmwareConstants.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/udp/FirmwareConstants.kt index b51a0cbb4..1b3ebf464 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/udp/FirmwareConstants.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/udp/FirmwareConstants.kt @@ -56,8 +56,6 @@ enum class BoardType(val id: UInt) { ESP32C6DEVKITC1(19u), GLOVE_IMU_SLIMEVR_DEV(20u), GESTURES(21u), - SLIMEVR_V1_2(22u), - ESP32S3_SUPERMINI(23u), DEV_RESERVED(250u), ; @@ -86,8 +84,6 @@ enum class BoardType(val id: UInt) { HARITORA -> "Haritora" ESP32C6DEVKITC1 -> "Espressif ESP32-C6 DevKitC-1" GLOVE_IMU_SLIMEVR_DEV -> "SlimeVR Dev IMU Glove" - SLIMEVR_V1_2 -> "SlimeVR v1.2" - ESP32S3_SUPERMINI -> "ESP32-S3 SuperMini" DEV_RESERVED -> "Prototype" } diff --git a/solarxr-protocol b/solarxr-protocol index eed73567f..df26226d1 160000 --- a/solarxr-protocol +++ b/solarxr-protocol @@ -1 +1 @@ -Subproject commit eed73567f77df0c3b556206803f17ea0748bc761 +Subproject commit df26226d104f75527a669e03879be675777885e3