1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-07-09 01:05:53 +02:00

feat: Add battery_percentage property to --bluetoothctl output (#564)

* Adds battery_percentage property to bluetoothctl output

* remove ending comma

---------

Co-authored-by: Kelly Brazil <kellyjonbrazil@gmail.com>
This commit is contained in:
Nicolas Mattelaer
2024-04-28 20:27:31 +02:00
committed by GitHub
parent a69e55cb1c
commit 4ef34f7849
3 changed files with 76 additions and 4 deletions

View File

@ -65,7 +65,8 @@ a controller and a device but there might be fields corresponding to one entity.
"rssi": int, "rssi": int,
"txpower": int, "txpower": int,
"uuids": array, "uuids": array,
"modalias": string "modalias": string,
"battery_percentage": int
} }
] ]
@ -96,7 +97,8 @@ Examples:
"Headset HS (00001831-0000-1000-8000-00805f9b34fb)" "Headset HS (00001831-0000-1000-8000-00805f9b34fb)"
], ],
"rssi": -52, "rssi": -52,
"txpower": 4 "txpower": 4,
"battery_percentage": 70
} }
] ]
""" """
@ -161,7 +163,8 @@ try:
"rssi": int, "rssi": int,
"txpower": int, "txpower": int,
"uuids": List[str], "uuids": List[str],
"modalias": str "modalias": str,
"battery_percentage": int
}, },
) )
except ImportError: except ImportError:
@ -280,6 +283,7 @@ _device_line_pattern = (
+ r"|\s*Modalias:\s*(?P<modalias>.+)" + r"|\s*Modalias:\s*(?P<modalias>.+)"
+ r"|\s*RSSI:\s*(?P<rssi>.+)" + r"|\s*RSSI:\s*(?P<rssi>.+)"
+ r"|\s*TxPower:\s*(?P<txpower>.+)" + r"|\s*TxPower:\s*(?P<txpower>.+)"
+ r"|\s*Battery\sPercentage:\s*0[xX][0-9a-fA-F]*\s*\((?P<battery_percentage>[0-9]+)\)"
+ r"|\s*UUID:\s*(?P<uuid>.+))" + r"|\s*UUID:\s*(?P<uuid>.+))"
) )
@ -317,7 +321,8 @@ def _parse_device(next_lines: List[str], quiet: bool) -> Optional[Device]:
"rssi": 0, "rssi": 0,
"txpower": 0, "txpower": 0,
"uuids": [], "uuids": [],
"modalias": '' "modalias": '',
"battery_percentage": 0
} }
if name.endswith("(public)"): if name.endswith("(public)"):
@ -381,6 +386,13 @@ def _parse_device(next_lines: List[str], quiet: bool) -> Optional[Device]:
device["uuids"].append(matches["uuid"]) device["uuids"].append(matches["uuid"])
elif matches["modalias"]: elif matches["modalias"]:
device["modalias"] = matches["modalias"] device["modalias"] = matches["modalias"]
elif matches["battery_percentage"]:
battery_percentage = matches["battery_percentage"]
try:
device["battery_percentage"] = int(battery_percentage)
except ValueError:
if not quiet:
jc.utils.warning_message([f"{next_line} : battery_percentage - {battery_percentage} is not int-able"])
return device return device

View File

@ -0,0 +1,17 @@
Device 67:F6:B4:0E:5C:94 (public)
Name: WH-1000XM3
Alias: WH-1000XM3
Class: 0x11240404 (2360324)
Icon: audio-headset
Paired: yes
Bonded: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Vendor specific (fd096fad-eed7-4504-943b-5fa1c0e761b2)
UUID: Vendor specific (03c57488-f7b6-45a3-8a23-ed4a890075cd)
UUID: Vendor specific (77a369ae-e453-4ff7-bc84-dc8f411eaa6a)
UUID: Vendor specific (8c274bd0-e7bd-4ed0-a391-55465e38005c)
Modalias: usb:v052Cp0DC3d1426
Battery Percentage: 0x46 (70)

View File

@ -177,6 +177,49 @@ class BluetoothctlTests(unittest.TestCase):
"txpower": 4 "txpower": 4
} }
if actual:
for k, v in expected.items():
self.assertEqual(v, actual[0][k], f"Device regex failed on {k}")
def test_bluetoothctl_device_with_battery(self):
"""
Test 'bluetoothctl' with device that has a battery
"""
with open("tests/fixtures/generic/bluetoothctl_device_with_battery.out", "r") as f:
output = f.read()
actual = parse(output, quiet=True)
self.assertIsNotNone(actual)
self.assertIsNotNone(actual[0], actual)
expected = {
"name": "WH-1000XM3",
"is_public": True,
"is_random": False,
"address": "67:F6:B4:0E:5C:94",
"alias": "WH-1000XM3",
"appearance": "",
"class": "0x11240404 (2360324)",
"icon": "audio-headset",
"paired": "yes",
"bonded": "yes",
"trusted": "yes",
"blocked": "no",
"connected": "yes",
"legacy_pairing": "no",
"rssi": 0,
"txpower": 0,
"uuids": [
"Vendor specific (fd096fad-eed7-4504-943b-5fa1c0e761b2)",
"Vendor specific (03c57488-f7b6-45a3-8a23-ed4a890075cd)",
"Vendor specific (77a369ae-e453-4ff7-bc84-dc8f411eaa6a)",
"Vendor specific (8c274bd0-e7bd-4ed0-a391-55465e38005c)"
],
"modalias": "usb:v052Cp0DC3d1426",
"battery_percentage": 70
}
if actual: if actual:
for k, v in expected.items(): for k, v in expected.items():
self.assertEqual(v, actual[0][k], f"Device regex failed on {k}") self.assertEqual(v, actual[0][k], f"Device regex failed on {k}")