@@ -6,6 +6,29 @@ use bluer::Device as BTDevice;
66
77use crate :: app:: AppResult ;
88
9+ /// Fallback: read battery percentage from /sys/class/power_supply/ for devices
10+ /// that report battery via kernel drivers (e.g. PS4/PS5 controllers) instead of
11+ /// the Bluetooth Battery Service (BAS) profile exposed through BlueZ's Battery1
12+ /// D-Bus interface.
13+ fn read_battery_from_sysfs ( addr : & Address ) -> Option < u8 > {
14+ let addr_str = addr. to_string ( ) . to_lowercase ( ) ;
15+ let power_supply_dir = std:: path:: Path :: new ( "/sys/class/power_supply" ) ;
16+
17+ if let Ok ( entries) = std:: fs:: read_dir ( power_supply_dir) {
18+ for entry in entries. flatten ( ) {
19+ let name = entry. file_name ( ) ;
20+ let name_str = name. to_string_lossy ( ) ;
21+ if name_str. contains ( & addr_str) {
22+ let capacity_path = entry. path ( ) . join ( "capacity" ) ;
23+ if let Ok ( content) = std:: fs:: read_to_string ( & capacity_path) {
24+ return content. trim ( ) . parse :: < u8 > ( ) . ok ( ) ;
25+ }
26+ }
27+ }
28+ }
29+ None
30+ }
31+
932#[ derive( Debug , Clone ) ]
1033pub struct Controller {
1134 pub adapter : Arc < Adapter > ,
@@ -114,7 +137,8 @@ impl Controller {
114137 let is_trusted = device. is_trusted ( ) . await ?;
115138 let is_connected = device. is_connected ( ) . await ?;
116139 let is_favorite = favorite_devices. contains ( & addr) ;
117- let battery_percentage = device. battery_percentage ( ) . await ?;
140+ let battery_percentage =
141+ device. battery_percentage ( ) . await ?. or_else ( || read_battery_from_sysfs ( & addr) ) ;
118142
119143 let dev = Device {
120144 device,
0 commit comments