diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-26 09:03:26 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-26 09:03:26 +0200 |
| commit | 14abc878285d961a90f9e56b85c15a091531f6e5 (patch) | |
| tree | 205067010447c07cf43e89c9bec8a0c4f659f5b8 | |
| parent | f2eec537da3de403b3201a8631e15ba6c491752d (diff) | |
| download | desktop-assistant-14abc878285d961a90f9e56b85c15a091531f6e5.tar.gz desktop-assistant-14abc878285d961a90f9e56b85c15a091531f6e5.zip | |
Add bluetooth and vms example tools
Read-only: bluetoothctl show/devices/info and virsh list, domstate,
dominfo and domifaddr. Connecting devices and handling VMs are phase 2.
The DHCP lease source is empty for bridged guests, so the VM's IP comes
from ARP or the guest agent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | README.md | 4 | ||||
| -rwxr-xr-x | examples/tools/bluetooth.sh | 46 | ||||
| -rw-r--r-- | examples/tools/bluetooth.toml | 2 | ||||
| -rwxr-xr-x | examples/tools/vms.sh | 48 | ||||
| -rw-r--r-- | examples/tools/vms.toml | 7 |
5 files changed, 107 insertions, 0 deletions
@@ -86,6 +86,10 @@ The example tools only read: - `playing`: the current track from `playerctl`, or `mpc` - `finance`: balances, budgets and spending from Firefly III's `firefly` list commands +- `bluetooth`: power, connected devices (battery when reported) and paired + ones, through `bluetoothctl show/devices/info` +- `vms`: libvirt VMs and their state, or one VM's details, through `virsh` + read commands ## License diff --git a/examples/tools/bluetooth.sh b/examples/tools/bluetooth.sh new file mode 100755 index 0000000..a3af0f9 --- /dev/null +++ b/examples/tools/bluetooth.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# desktop-assistant tool: bluetooth status (read-only). +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# bluetooth.sh: whether bluetooth is on, the connected devices with their +# kind (BlueZ icon name) and battery when the device reports one, and the +# paired devices that are not connected. Only show, devices and info run +# here: nothing connects, pairs or scans. + +set -uo pipefail + +power=$(bluetoothctl show | sed -n 's/^\tPowered: //p') +[ -n "$power" ] || { echo "no bluetooth controller" >&2; exit 1; } +[ "$power" = yes ] || { echo "bluetooth is off"; exit 0; } +echo "bluetooth on" + +connected=0 +others=() +while read -r _ mac _; do + info=$(bluetoothctl info "$mac") + alias=$(sed -n 's/^\tAlias: //p' <<<"$info") + if grep -q $'^\tConnected: yes' <<<"$info"; then + kind=$(sed -n 's/^\tIcon: //p' <<<"$info") + battery=$(sed -n 's/^\tBattery Percentage: .*(\([0-9]*\))$/\1/p' <<<"$info") + echo "connected: $alias (${kind:-unknown kind}${battery:+, battery $battery%})" + connected=$((connected + 1)) + else + others+=("$alias") + fi +done < <(bluetoothctl devices Paired) + +[ "$connected" -gt 0 ] || echo "no device connected" +[ "${#others[@]}" -eq 0 ] || { printf 'paired, not connected: '; (IFS=,; echo "${others[*]}" | sed 's/,/, /g'); } diff --git a/examples/tools/bluetooth.toml b/examples/tools/bluetooth.toml new file mode 100644 index 0000000..af1548e --- /dev/null +++ b/examples/tools/bluetooth.toml @@ -0,0 +1,2 @@ +description = "Bluetooth: whether it is on, which devices are connected (with battery when they report it), and which paired devices are not connected. Read-only." +command = ["bluetooth.sh"] diff --git a/examples/tools/vms.sh b/examples/tools/vms.sh new file mode 100755 index 0000000..3595839 --- /dev/null +++ b/examples/tools/vms.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# desktop-assistant tool: virtual machine status through virsh (read-only). +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# vms.sh [NAME]: without NAME, every defined VM with its state; with NAME, +# that VM's state, vCPUs, memory, autostart and IP address when one is +# known. Only list, domstate, dominfo and domifaddr run here: nothing is +# started, stopped or edited. Uses libvirt's default URI (LIBVIRT_DEFAULT_URI +# overrides it). + +set -uo pipefail + +name="${1:-}" +if [ -z "$name" ]; then + vms=$(virsh list --all --name) || exit 1 + [ -n "${vms//[[:space:]]/}" ] || { echo "no virtual machines defined"; exit 0; } + while read -r vm; do + [ -n "$vm" ] && echo "$vm: $(virsh domstate "$vm")" + done <<<"$vms" + exit 0 +fi + +# An unknown name leaves virsh's own error as the last stderr line. +info=$(virsh dominfo "$name") || exit 1 +field() { sed -n "s/^$1: *//p" <<<"$info"; } +echo "$name: $(field State), $(field 'CPU(s)') vCPUs," \ + "$(( $(field 'Max memory' | awk '{print $1}') / 1048576 )) GiB memory," \ + "autostart $(field Autostart)" + +# The DHCP lease is empty for bridged guests; ARP or the guest agent knows. +for source in lease arp agent; do + ip=$(virsh domifaddr "$name" --source "$source" 2>/dev/null \ + | awk 'NR > 2 && $4 != "" && $4 !~ /^127\./ {sub(/\/.*/, "", $4); print $4}' | paste -sd, -) + [ -n "$ip" ] && { echo "IP address: $ip"; break; } +done diff --git a/examples/tools/vms.toml b/examples/tools/vms.toml new file mode 100644 index 0000000..768c7da --- /dev/null +++ b/examples/tools/vms.toml @@ -0,0 +1,7 @@ +description = "Virtual machines (libvirt): which exist and whether they are running, or details of one (vCPUs, memory, autostart, IP address). Read-only." +command = ["vms.sh", "{name}"] +timeout = 15 + +[params.name] +type = "string" +description = "VM name for details. Empty to list every VM with its state." |
