Packages
rockbox_ex
0.1.0
Idiomatic Elixir SDK for Rockbox — pipe-friendly, builder-friendly, with real-time event subscriptions and a plugin system.
Current section
Files
Jump to
Current section
Files
lib/rockbox/bluetooth.ex
defmodule Rockbox.Bluetooth do
@moduledoc """
Bluetooth device management (Linux only — backed by BlueZ).
Calls return `{:error, %Rockbox.GraphQLError{}}` on non-Linux hosts with the
message `"Bluetooth is only supported on Linux"`.
"""
alias Rockbox.{BluetoothDevice, Client, Transport, Util}
@fragment ~S"""
fragment BluetoothDeviceFields on BluetoothDevice {
address name paired trusted connected rssi
}
"""
@spec devices(Client.t()) :: {:ok, [BluetoothDevice.t()]} | {:error, Exception.t()}
def devices(client) do
query =
@fragment <> "query BluetoothDevices { bluetoothDevices { ...BluetoothDeviceFields } }"
with {:ok, %{"bluetoothDevices" => list}} <- Transport.execute(client, query) do
{:ok, Util.to_struct_list(BluetoothDevice, list)}
end
end
@spec devices!(Client.t()) :: [BluetoothDevice.t()]
def devices!(client), do: bang(devices(client))
@doc "Scan for nearby devices. `timeout_secs` defaults to the firmware default."
@spec scan(Client.t(), pos_integer() | nil) ::
{:ok, [BluetoothDevice.t()]} | {:error, Exception.t()}
def scan(client, timeout_secs \\ nil) do
query =
@fragment <>
"mutation BluetoothScan($timeoutSecs: Int) { bluetoothScan(timeoutSecs: $timeoutSecs) { ...BluetoothDeviceFields } }"
with {:ok, %{"bluetoothScan" => list}} <-
Transport.execute(client, query, %{timeout_secs: timeout_secs}) do
{:ok, Util.to_struct_list(BluetoothDevice, list)}
end
end
@spec connect(Client.t(), String.t()) :: :ok | {:error, Exception.t()}
def connect(client, address),
do:
void(
Transport.execute(
client,
"mutation BluetoothConnect($address: String!) { bluetoothConnect(address: $address) }",
%{address: address}
)
)
@spec disconnect(Client.t(), String.t()) :: :ok | {:error, Exception.t()}
def disconnect(client, address),
do:
void(
Transport.execute(
client,
"mutation BluetoothDisconnect($address: String!) { bluetoothDisconnect(address: $address) }",
%{address: address}
)
)
defp void({:ok, _}), do: :ok
defp void(err), do: err
defp bang({:ok, value}), do: value
defp bang({:error, exception}), do: raise(exception)
end