Something X Documentation

Something X is a Linux-native companion app for Nothing and CMF Bluetooth audio devices. It provides ANC, EQ, battery monitoring, volume control, and CLI access — all via the reverse-engineered RFCOMM 0x55 protocol, without requiring the Android app.

Tip

Omarchy / Hyprland users: Something X is built and optimised for the Omarchy desktop. Pure black, JetBrains Mono, Nothing Red — it matches your setup out of the box.

Requirements #

System

RequirementVersionNotes
bluetoothd / BlueZ≥ 5.6Must be running; handles D-Bus and RFCOMM
GTK4≥ 4.6UI toolkit
libadwaita≥ 1.2Navigation, dark theme integration
Python≥ 3.11Match syntax used throughout
pactlanyOptional — volume control via PulseAudio / PipeWire

Python packages

PackagePurpose
python-gobjectGTK4, libadwaita, GLib, Gio bindings
python-dbusBlueZ D-Bus interface (device discovery, connect/disconnect)
python-cairoSplash screen and earbud visual rendering

Installation #

Arch Linux / Omarchy

# system dependencies
sudo pacman -S python-gobject python-dbus python-cairo gtk4 libadwaita

# install via pip
pip install something-x

# or install from AUR
paru -S something-x

Ubuntu 24.04+

sudo apt install python3-gi python3-dbus python3-cairo gir1.2-gtk-4.0 gir1.2-adw-1
pip install something-x

Fedora 39+

sudo dnf install python3-gobject python3-dbus python3-cairo gtk4 libadwaita
pip install something-x

NixOS

# run directly from the flake
nix run github:SoaOaoS/something-x

# add as an input in your system flake — see flake.nix in the repository

From Source

git clone https://github.com/SoaOaoS/something-x
cd something-x
# install system deps for your distro first, then:
./somethingx

First Launch #

  1. Run something-x (pip) or ./somethingx (source). The animated splash screen plays for ~2.3 s.
  2. The Home page lists all paired Bluetooth devices. Nothing / CMF devices are highlighted with a NOTHING badge.
  3. If your device isn't visible, press SCAN FOR DEVICES to run a 30-second BlueZ discovery.
  4. Tap a device card to open the Device page. The app connects over RFCOMM automatically.
  5. ANC, EQ, and volume controls are now live. Settings are saved immediately and restored on the next reconnect.
Note

Bluetooth must be paired first. Use your desktop's Bluetooth manager or bluetoothctl to pair before launching Something X.


Home Page #

The Home page shows all Bluetooth devices known to BlueZ, grouped by connection status. Nothing and CMF devices that support the 0x55 RFCOMM protocol receive a red NOTHING badge and expose quick connect / disconnect actions inline.

The Bluetooth settings button in the top-right opens your system's Bluetooth settings panel. The refresh button re-queries BlueZ for device state without running a full scan.

Device Page #

Tapping a device card opens the Device page. The app opens an RFCOMM socket to the device on channel 10 and begins exchanging protocol frames.

ANC Control

Three modes are available: Off, Noise Cancellation, and Transparency. Selecting a mode sends the corresponding RFCOMM command immediately. The chosen mode is saved to the device profile and restored automatically on the next connection.

ModeCommand byte
Off0x00
Noise Cancellation0x02
Transparency0x03

EQ Presets

Four presets are shipped: Balanced, More Bass, More Treble, and Voice. Each maps to a fixed payload sent over RFCOMM. Custom per-band EQ is planned for v2.x.

Volume

The volume slider calls pactl set-sink-volume on the active A2DP PipeWire/PulseAudio sink. This controls system volume for the device, not an in-earphone DSP level.

Battery

Battery levels for Left, Right, and Case are polled from the device over RFCOMM and displayed as animated radial rings. A notify-send desktop notification fires when any bud drops below 20 %. The system tray icon shows a battery tooltip on hover.

Background Mode #

Closing the window does not quit the app — it hides it. The Gio single-instance mechanism keeps the process alive so BlueZ reconnects are handled automatically and the tray icon remains active.

Running something-x again while the app is in the background shows the window without a second splash screen. To fully quit, use the tray icon menu or send SIGTERM to the process.

System Tray #

Something X registers a StatusNotifierItem (SNI) tray icon that is compatible with Waybar, KDE Plasma, GNOME (with AppIndicator extension), and any other SNI-aware panel.

The tooltip shows the battery percentage of the active device. Left-clicking the icon shows or hides the main window.


CLI Reference #

All CLI flags connect to the running app instance (or start a headless one) over the Gio D-Bus single-instance channel, so the GUI and CLI always share state.

--battery

something-x --battery

Prints L / R / Case battery percentages and exits. Returns non-zero if no device is connected.

--anc

something-x --anc off | on | transparency

Sets the ANC mode. on maps to Noise Cancellation. The setting is persisted to the device profile.

--eq

something-x --eq balanced | bass | treble | voice

Switches the EQ preset. Saved to the device profile.

--device

something-x --device AA:BB:CC:DD:EE:FF --battery

Targets a specific device by Bluetooth address. Useful when multiple Nothing / CMF devices are connected simultaneously.

Combining flags

# set ANC and EQ in one call
something-x --anc on --eq bass

Device Profiles #

ANC mode and EQ preset are saved per Bluetooth address to:

~/.config/something-x/profiles.json

The file is plain JSON and safe to edit manually. Each key is a Bluetooth MAC address:

{
  "AA:BB:CC:DD:EE:FF": {
    "anc":  "noise_cancellation",
    "eq":   "balanced"
  }
}

Profiles are applied automatically when the device connects over RFCOMM, with no user interaction required.

Desktop Entry #

A .desktop file is bundled in nothing_app/data/. Install it so Something X appears in Walker, Rofi, GNOME Shell, or any XDG-compliant launcher:

cp nothing_app/data/com.something.x.omarchy.desktop \
   ~/.local/share/applications/
update-desktop-database ~/.local/share/applications/
Note

If installed via pip, the .desktop file is placed automatically by the installer.


Architecture #

nothing_app/
├── application.py — Adw.Application: CSS, dark theme, splash, background mode, CLI flags
├── splash.py — Animated splash screen (Cairo, typewriter, ripple rings, ~2.3 s)
├── window.py — AdwNavigationView: home ↔ device routing, HeaderBar
├── bluetooth.py — BlueZ D-Bus manager: discovery, connect/disconnect signals, battery polling
├── protocol.py — Nothing Ear RFCOMM 0x55 protocol: frame encode/decode, CRC16-ARC
├── profiles.py — Per-device ANC/EQ persistence via ~/.config/something-x/profiles.json
├── data/
│ └── style.css — Nothing X dark theme (glass morphism, red accents, JetBrains Mono)
└── pages/
├── home.py — Device list + scan button + quick connect/disconnect
└── device.py — ANC / EQ / volume / info + Cairo earbud visual

RFCOMM Protocol #

The Nothing Ear protocol was reverse-engineered from the official Android APK. All communication happens over an RFCOMM socket on channel 10.

Frame Format

FieldSizeValue / Notes
SOF1 byte0x55
ctrl2 bytes LE0x0160 for all outgoing frames
cmd2 bytes LECommand identifier (see table below)
len2 bytes LEPayload length in bytes
FSN1 byteFrame sequence number (increments per frame)
payloadlen bytesCommand-specific data
CRC162 bytes LECRC16-ARC over all preceding bytes
Warning

CRC is mandatory. The device silently drops SET commands if any frame in the session was sent without a valid CRC16-ARC checksum.

Command IDs

CommandIDDirection
Battery request0x0006Host → Device
Battery response0x0106Device → Host
ANC set0x0802Host → Device
ANC get0x0801Host → Device
EQ set0x0a04Host → Device
In-ear detection set0x0603Host → Device
Device info0x0001Host → Device

Contributing #

Contributions are welcome, especially protocol work for unverified devices. The best place to start is GitHub Issues.

Development setup

git clone https://github.com/SoaOaoS/something-x
cd something-x
# install system deps for your distro, then run directly:
./somethingx

Debug Mode #

Set SOMETHING_X_DEBUG=1 to dump every raw RFCOMM frame to stdout:

SOMETHING_X_DEBUG=1 ./somethingx

If your device doesn't work as expected, capture the debug output and open an issue — include the raw frames so the command IDs can be identified.

Versioning #

This project uses Conventional Commits. Pushing to main triggers automatic versioning and a PyPI release via CI.

Commit prefixVersion bump
feat!: / BREAKING CHANGEMajor x.0.0
feat:Minor 1.x.0
fix: / perf: / refactor:Patch 1.0.x
docs: / chore: / style: / ci:No release

Troubleshooting #

Device not appearing

Make sure the device is paired (not just discoverable) via your system Bluetooth manager or bluetoothctl. Then press the refresh button or SCAN FOR DEVICES in the app.

RFCOMM connection fails

Confirm bluetoothd is running (systemctl status bluetooth) and that the device is connected at the Bluetooth level before Something X tries to open the RFCOMM socket. Run with SOMETHING_X_DEBUG=1 to see the exact error.

Volume slider has no effect

Ensure pactl is installed (pacman -S libpulse / apt install pulseaudio-utils). The slider controls the A2DP PipeWire/PulseAudio sink — the device must be connected as an audio sink, not just paired.

Tray icon not showing

Your panel must support the StatusNotifierItem protocol. For GNOME Shell, install the AppIndicator and KStatusNotifierItem Support extension. For Waybar, ensure tray is in your modules.

App won't start — missing module

You're likely missing a system dependency. GTK bindings cannot be installed via pip — they must come from your distro's package manager. Re-run the install command for your distro from the Installation section.

Changelog #

See the GitHub Releases page for the full changelog. Releases are generated automatically from Conventional Commits on every push to main.