@@ -256,19 +256,39 @@ public async Task<InputReading> RunInputAsync(uint featureIndex, DeviceInputComm
256256 /// <summary>
257257 /// Reads the battery level of the device.
258258 /// </summary>
259+ /// <param name="timeout">Optional timeout for the operation.</param>
259260 /// <param name="token">Cancellation token.</param>
260261 /// <returns>Battery level as a value between 0.0 and 1.0.</returns>
261- public async Task < double > BatteryAsync ( CancellationToken token = default )
262+ /// <exception cref="ButtplugDeviceException">Thrown if the device does not support battery reading.</exception>
263+ /// <exception cref="ButtplugMessageException">Thrown if the battery reading response is invalid.</exception>
264+ /// <exception cref="OperationCanceledException">Thrown if the operation times out or is cancelled.</exception>
265+ public async Task < double > BatteryAsync ( TimeSpan ? timeout = null , CancellationToken token = default )
262266 {
263- var reading = await RunInputAsync ( DeviceInput . Battery . Read ( ) , token ) . ConfigureAwait ( false ) ;
264- var batteryValue = reading ? . GetValue ( InputType . Battery ) ;
265- if ( ! batteryValue . HasValue )
267+ CancellationTokenSource linkedCts = null ;
268+ try
266269 {
267- throw new ButtplugMessageException ( "Battery reading did not contain battery value." ) ;
268- }
270+ var effectiveToken = token ;
271+ if ( timeout . HasValue )
272+ {
273+ linkedCts = CancellationTokenSource . CreateLinkedTokenSource ( token ) ;
274+ linkedCts . CancelAfter ( timeout . Value ) ;
275+ effectiveToken = linkedCts . Token ;
276+ }
269277
270- // Battery is typically returned as 0-100, convert to 0.0-1.0
271- return batteryValue . Value / 100.0 ;
278+ var reading = await RunInputAsync ( DeviceInput . Battery . Read ( ) , effectiveToken ) . ConfigureAwait ( false ) ;
279+ var batteryValue = reading ? . GetValue ( InputType . Battery ) ;
280+ if ( ! batteryValue . HasValue )
281+ {
282+ throw new ButtplugMessageException ( $ "Battery reading from device '{ Name } ' did not contain a battery value.") ;
283+ }
284+
285+ // Battery is typically returned as 0-100, convert to 0.0-1.0
286+ return batteryValue . Value / 100.0 ;
287+ }
288+ finally
289+ {
290+ linkedCts ? . Dispose ( ) ;
291+ }
272292 }
273293
274294 /// <summary>
0 commit comments