diff --git a/src/components/board.ts b/src/components/board.ts index db49f00e1..9cf7ed298 100644 --- a/src/components/board.ts +++ b/src/components/board.ts @@ -1,2 +1,2 @@ -export type { Board } from './board/board'; +export { type Board, type Duration, PowerMode } from './board/board'; export { BoardClient } from './board/client'; diff --git a/src/components/board/board.ts b/src/components/board/board.ts index b6c5421db..04d4b0cd1 100644 --- a/src/components/board/board.ts +++ b/src/components/board/board.ts @@ -1,3 +1,5 @@ +import { type Duration as PBDuration } from 'google-protobuf/google/protobuf/duration_pb'; +import pb from '../../gen/component/board/v1/board_pb'; import type { Resource, StructType } from '../../types'; interface Status { @@ -5,6 +7,12 @@ interface Status { digitalInterrupts: Record; } +type ValueOf = T[keyof T]; +export const { PowerMode } = pb; +export type PowerMode = ValueOf; + +export type Duration = PBDuration.AsObject; + /** * Represents a physical general purpose compute board that contains various * components such as analog readers, and digital interrupts. @@ -74,4 +82,17 @@ export interface Board extends Resource { digitalInterruptName: string, extra?: StructType ): Promise; + /** + * Set power mode of the board. + * + * @param name - The name of the board. + * @param powerMode - The requested power mode. + * @param duration - The requested duration to stay in power mode. + */ + setPowerMode( + name: string, + powerMode: PowerMode, + duration: Duration, + extra?: StructType + ): Promise; } diff --git a/src/components/board/client.ts b/src/components/board/client.ts index bcc0e0576..eee4a1a28 100644 --- a/src/components/board/client.ts +++ b/src/components/board/client.ts @@ -1,12 +1,13 @@ import { Struct } from 'google-protobuf/google/protobuf/struct_pb'; +import { Duration as PBDuration } from 'google-protobuf/google/protobuf/duration_pb'; import { BoardServiceClient } from '../../gen/component/board/v1/board_pb_service'; import type { RobotClient } from '../../robot'; import type { Options, StructType } from '../../types'; import pb from '../../gen/component/board/v1/board_pb'; import { promisify, doCommandFromClient } from '../../utils'; -import type { Board } from './board'; +import type { Board, Duration, PowerMode } from './board'; /** * A gRPC-web client for the Board component. @@ -202,6 +203,32 @@ export class BoardClient implements Board { return response.getValue(); } + async setPowerMode( + name: string, + powerMode: PowerMode, + duration?: Duration, + extra = {} + ) { + const { boardService } = this; + const request = new pb.SetPowerModeRequest(); + request.setName(name); + request.setPowerMode(powerMode); + if (duration) { + const pbDuration = new PBDuration(); + pbDuration.setNanos(duration.nanos); + pbDuration.setSeconds(duration.seconds); + request.setDuration(pbDuration); + } + request.setExtra(Struct.fromJavaScript(extra)); + + this.options.requestLogger?.(request); + + await promisify( + boardService.setPowerMode.bind(boardService), + request + ); + } + async doCommand(command: StructType): Promise { const { boardService } = this; return doCommandFromClient(boardService, this.name, command, this.options); diff --git a/src/main.ts b/src/main.ts index 22e782213..25f71f3b9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -78,7 +78,12 @@ export { type Base, type BaseProperties, BaseClient } from './components/base'; * @group Raw Protobufs */ export { default as boardApi } from './gen/component/board/v1/board_pb'; -export { type Board, BoardClient } from './components/board'; +export { + type Board, + BoardClient, + type Duration, + PowerMode, +} from './components/board'; /** * Raw Protobuf interfaces for a Camera component. diff --git a/src/robot/dial.ts b/src/robot/dial.ts index 5653da3cf..03fa58126 100644 --- a/src/robot/dial.ts +++ b/src/robot/dial.ts @@ -157,7 +157,13 @@ export const createRobotClient = async ( ): Promise => { let client; if (conf.authEntity) { - conf.authEntity = new URL(conf.authEntity).host; + try { + conf.authEntity = new URL(conf.authEntity).host; + } catch (error) { + if (!(error instanceof TypeError)) { + throw error; + } + } } if (conf.reconnectMaxAttempts && !isPosInt(conf.reconnectMaxAttempts)) {