Skip to content

[Repo Assist] feat(device): add BatteryStatusRequested event to DeviceCapability#248

Closed
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/improve-device-battery-2026-04-30-ef74c3c5d1bda8b0
Closed

[Repo Assist] feat(device): add BatteryStatusRequested event to DeviceCapability#248
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/improve-device-battery-2026-04-30-ef74c3c5d1bda8b0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This is an automated PR from Repo Assist.

Implements the BatteryStatusRequested event API described in issue #240 and tracked in Repo Assist's future-work list. This opens the door for real battery data in device.status responses without adding WinRT dependencies to the cross-platform OpenClaw.Shared project.

Background

device.status has always returned a battery stub:

{"level": null, "state": "unknown", "lowPowerModeEnabled": false}

Issue #240 identified that battery info requires Windows.Devices.Power.Battery (WinRT), which is only available in OpenClaw.Tray.WinUI (TFM net10.0-windows10.0.19041.0). The Shared project targets net10.0 (cross-platform) and cannot use WinRT directly.

Solution

Same event-delegation pattern used by CameraCapability and ScreenCapability:

OpenClaw.Shared (net10.0)
└── DeviceCapability.BatteryStatusRequested   ← Func<Task<DeviceBatteryStatus?>> event

OpenClaw.Tray.WinUI (net10.0-windows10.0.19041.0)
└── NodeService.cs  ← subscribes with WinRT-backed lambda (TODO, next PR)

Changes

src/OpenClaw.Shared/Capabilities/DeviceCapability.cs

  • BatteryStatusRequested: Func<Task<DeviceBatteryStatus?>>? event
  • DeviceBatteryStatus class: Present, ChargePercent?, IsCharging, EstimatedMinutesRemaining?
  • HandleStatusHandleStatusAsync: awaits the provider if wired; falls back gracefully if provider is null or throws
  • Battery response now includes a present field (false when no provider is wired)
  • ExecuteAsync updated to await HandleStatusAsync

src/OpenClaw.Tray.WinUI/Services/NodeService.cs

  • TODO comment at _deviceCapability registration pointing to where the WinRT BatteryStatusProvider should be wired. Actual WinRT implementation is the follow-up step.

tests/OpenClaw.Shared.Tests/CapabilityTests.cs

Four new tests in DeviceCapabilityTests:

Test Covers
DeviceStatus_BatteryProvider_Charging_ReturnsChargingState Provider returns 72 % charging → state=charging, level≈0.72
DeviceStatus_BatteryProvider_Unplugged_ReturnsUnpluggedState Provider returns 45 % discharging → state=unplugged
DeviceStatus_BatteryProvider_NotPresent_ReturnsUnknown Provider signals no battery → state=unknown, present=false
DeviceStatus_BatteryProvider_Throws_FallsBackToUnknown Provider throws → device.status still succeeds, falls back to stub

Test Status

Suite Result
OpenClaw.Shared.Tests ✅ 1045 passed (+4 new), 5 pre-existing McpHttpServer failures, 20 skipped
OpenClaw.Tray.Tests ✅ 245 passed, 0 failed
./build.ps1 ⚠️ Not runnable on Linux CI; Shared build succeeded.

Next Step

Wire _deviceCapability.BatteryStatusRequested in NodeService.cs to a WinRT implementation using Windows.Devices.Power.Battery.AggregateBattery.GetReport(). This is a Windows-only build step that requires the WinUI project — best done in a follow-up PR on a Windows machine.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

DeviceCapability.HandleStatus() always returned battery as null/unknown.
Issue #240 identified that real battery data requires WinRT APIs
(Windows.Devices.Power.Battery) that are unavailable in the cross-platform
Shared project (net10.0 TFM).

Follows the same event-delegation pattern used by CameraCapability and
ScreenCapability: the capability exposes a Func<Task<DeviceBatteryStatus?>>
event; the Tray.WinUI project subscribes a WinRT-backed provider.

Changes:
- DeviceCapability: add BatteryStatusRequested event + DeviceBatteryStatus class
- HandleStatus -> HandleStatusAsync: awaits provider if wired; falls back
  gracefully to unknown if provider throws or is null
- battery response now includes a 'present' field (false when no provider)
- NodeService.cs: TODO comment marking where WinRT provider should be wired
- CapabilityTests: 4 new tests covering charging, unplugged, not-present,
  and provider-throws-graceful-fallback scenarios

Test Status:
- Shared.Tests: 1045 passed (+4), 5 pre-existing McpHttpServer failures, 20 skipped
- Tray.Tests: 245 passed, 0 failed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanselman
Copy link
Copy Markdown
Contributor

Closing per repo-assist triage: this is superseded by #249 and is not useful enough on its own without the provider-backed battery implementation.

@shanselman shanselman closed this May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant