An open API service indexing awesome lists of open source software.

https://github.com/ydah/blueruvia

Web Bluetooth API-style BLE interface for Ruby.
https://github.com/ydah/blueruvia

api ble interface ruby web-bluetooth web-bluetooth-api

Last synced: 12 days ago
JSON representation

Web Bluetooth API-style BLE interface for Ruby.

Awesome Lists containing this project

README

          

# BlueRuvia

[![CI](https://github.com/ydah/blueruvia/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/blueruvia/actions/workflows/ci.yml)
[![Gem Version](https://badge.fury.io/rb/blueruvia.svg)](https://badge.fury.io/rb/blueruvia)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Web Bluetooth API-style BLE interface for Ruby.

BlueRuvia provides a Web Bluetooth API-inspired interface for interacting with Bluetooth Low Energy (BLE) devices from Ruby. It supports GATT operations including device scanning, connection management, service discovery, and characteristic read/write/notify via platform-native adapters.

## Installation

Install the gem and add the platform adapter dependency your runtime needs:

```bash
bundle add blueruvia
bundle add ruby-dbus --require dbus # Linux / BlueZ
bundle add ffi # macOS / CoreBluetooth
```

If bundler is not being used to manage dependencies, install the gem by executing:

```bash
gem install blueruvia
gem install ruby-dbus # Linux / BlueZ
gem install ffi # macOS / CoreBluetooth
```

Platform-specific runtime dependencies:

- Linux: `ruby-dbus` (loaded with `require 'dbus'`)
- macOS: `ffi`, Xcode Command Line Tools / Swift toolchain

### System Requirements

- **Ruby** >= 3.2
- **Linux**: BlueZ 5.50+ and D-Bus (`sudo apt-get install libdbus-1-dev`)
- **macOS**: CoreBluetooth.framework and Xcode Command Line Tools

## Quick Start

```ruby
require 'blueruvia'

# Scan for a heart rate monitor
device = BlueRuvia::Bluetooth.request_device(
filters: [{ services: ['heart_rate'] }]
)

puts "Found: #{device.name} (#{device.address})"

# Connect to the GATT server
device.gatt.connect

# Get the Heart Rate service
service = device.gatt.get_primary_service('heart_rate')

# Read the Heart Rate Measurement characteristic
char = service.get_characteristic('heart_rate_measurement')

# Subscribe to notifications
char.on(:value_changed) do |value|
heart_rate = value.unpack1('xC')
puts "Heart Rate: #{heart_rate} bpm"
end

char.start_notifications
sleep(30)

# Clean up
char.stop_notifications
device.gatt.disconnect
```

## Usage

### Device Scanning

```ruby
# Filter by service UUID
device = BlueRuvia::Bluetooth.request_device(
filters: [{ services: ['heart_rate'] }]
)

# Filter by device name prefix
device = BlueRuvia::Bluetooth.request_device(
filters: [{ name_prefix: 'Arduino' }],
optional_services: ['battery_service']
)

# Accept all devices
device = BlueRuvia::Bluetooth.request_device(
accept_all_devices: true,
optional_services: ['generic_access']
)

# Filter by manufacturer data prefix
device = BlueRuvia::Bluetooth.request_device(
filters: [
{
manufacturer_data: [
{ company_identifier: 76, data_prefix: [0x01, 0x02] }
]
}
]
)
```

### GATT Server Connection

```ruby
device.gatt.connect
puts "Connected: #{device.connected?}"

# Discover services
services = device.gatt.get_primary_services
services.each { |s| puts "Service: #{s.uuid}" }

device.gatt.disconnect
```

### Reading and Writing Characteristics

```ruby
# Read a value
value = char.read_value
battery_level = value.unpack1('C')
puts "Battery: #{battery_level}%"

# Write with response
char.write_value([0x01, 0x02, 0x03].pack('C*'))

# Write without response
char.write_value_without_response([0xFF].pack('C'))
```

### Notifications

```ruby
char.on(:value_changed) do |value|
puts "New value: #{value.unpack1('C')}"
end

char.start_notifications

# ... later
char.stop_notifications
```

### Configuration

```ruby
BlueRuvia.configure do |config|
config.adapter = :bluez # :auto, :bluez, :core_bluetooth
config.scan_timeout = 15 # Scan timeout in seconds
config.connection_timeout = 10 # Connection timeout in seconds
config.device_selector = :first # :first, :strongest, or a custom lambda
config.log_level = :info # :debug, :info, :warn, :error
config.logger = Logger.new($stdout)
end
```

## Supported Platforms

| Platform | Adapter | Status |
|----------|---------|--------|
| Linux | BlueZ (D-Bus) | ✅ Supported |
| macOS | CoreBluetooth | ✅ Supported |

On macOS, `device.address` is `CBPeripheral.identifier.uuidString` because CoreBluetooth does not expose BLE MAC addresses.

## Development

After checking out the repo, install dependencies and run the standard checks:

```bash
bundle install
bundle exec rake
bundle exec rspec
bundle exec rubocop
```

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ydah/blueruvia.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).