Ruby on Rails应用:如何获取范围内BLE设备并展示在HTML页面
Hey there! Let's figure out how to get BLE device detection working in your Ruby on Rails app. I've got two solid approaches depending on your use case—let's dive in.
Option 1: Use the Web Bluetooth API (Frontend-First)
Modern browsers support the Web Bluetooth API, which lets you scan for BLE devices directly from the user's browser. This is great if you want users to detect devices near their own device, with minimal backend work from Rails.
How to implement it:
Drop this code into one of your Rails views (like app/views/devices/index.html.erb):
<h1>Detected BLE Devices</h1> <button id="scanBtn">Start Scanning</button> <ul id="deviceList"></ul> <script> const scanBtn = document.getElementById('scanBtn'); const deviceList = document.getElementById('deviceList'); scanBtn.addEventListener('click', async () => { try { console.log('Scanning for BLE devices...'); // Request user permission to scan for devices const device = await navigator.bluetooth.requestDevice({ acceptAllDevices: true, // You can filter by service UUIDs here if needed optionalServices: ['00001800-0000-1000-8000-00805f9b34fb'] // Optional: specify services to access }); // Add the detected device to the list const li = document.createElement('li'); li.textContent = `Device: ${device.name || 'Unnamed'}, ID: ${device.id}`; deviceList.appendChild(li); // If you need to connect to the device and read data, you can extend this: // const server = await device.gatt.connect(); // const service = await server.getPrimaryService('your-service-uuid'); // ... } catch (error) { console.error('Scan failed:', error); alert(`Oops, something went wrong: ${error.message}`); } }); </script>
Notes:
- This requires HTTPS (localhost works for development).
- Compatibility: Supported in Chrome, Edge, and Opera. Safari is still in beta testing for Web Bluetooth, and Firefox requires enabling experimental features.
- Users will need to grant permission for the browser to access their Bluetooth adapter.
Option 2: Server-Side Detection (For Server-Level Scanning)
If you need your Rails server to scan for BLE devices (e.g., monitoring devices near the server itself), you'll need to leverage system tools or Ruby gems, since Rails doesn't have built-in BLE support.
Method A: Use BlueZ (Linux Systems)
BlueZ is the official Bluetooth stack for Linux, and it provides command-line tools like bluetoothctl to scan for devices. You can call these tools from your Rails backend and parse the output.
Step 1: Set up the controller action
In app/controllers/devices_controller.rb:
class DevicesController < ApplicationController def scan # Scan for BLE devices for 5 seconds (adjust the sleep time as needed) scan_output = `bluetoothctl scan on & sleep 5; bluetoothctl scan off` # Parse the output to extract device details detected_devices = scan_output.split("\n").select { |line| line.include?('Device') }.map do |line| parts = line.split(' ') { address: parts[1], name: parts[2..-1].join(' ') } end render json: detected_devices end end
Step 2: Add a route
In config/routes.rb:
get '/devices/scan', to: 'devices#scan'
Step 3: Add frontend to trigger the scan
In your view:
<h1>Server-Side BLE Devices</h1> <button id="serverScanBtn">Scan from Server</button> <ul id="serverDeviceList"></ul> <script> const serverScanBtn = document.getElementById('serverScanBtn'); const serverDeviceList = document.getElementById('serverDeviceList'); serverScanBtn.addEventListener('click', async () => { try { const response = await fetch('/devices/scan'); const devices = await response.json(); serverDeviceList.innerHTML = ''; devices.forEach(device => { const li = document.createElement('li'); li.textContent = `Device: ${device.name || 'Unnamed'}, Address: ${device.address}`; serverDeviceList.appendChild(li); }); } catch (error) { console.error('Server scan failed:', error); alert('Could not scan devices from the server'); } }); </script>
Important Notes:
- Your Rails server must have a Bluetooth adapter installed.
- Install BlueZ first:
sudo apt-get install bluez(for Ubuntu/Debian). - The Rails process needs permission to access Bluetooth: add your user to the
bluetoothgroup withsudo usermod -aG bluetooth $USER, then restart the Rails server.
Method B: Use a Ruby Gem
For a more Ruby-native approach, use gems like bluez-ruby which wraps BlueZ functionality.
Step 1: Add the gem to your Gemfile
gem 'bluez-ruby'
Run bundle install to install it.
Step 2: Update the controller action
require 'bluez' class DevicesController < ApplicationController def scan manager = Bluez::Manager.new adapter = manager.default_adapter # Start discovery adapter.start_discovery sleep 5 # Let it scan for 5 seconds # Collect device details detected_devices = adapter.devices.map do |device| { address: device.address, name: device.name, signal_strength: device.rssi } end adapter.stop_discovery render json: detected_devices end end
This approach is cleaner than parsing command-line output, but it still requires BlueZ and a Bluetooth adapter on the server.
Final Recommendations
- Use Web Bluetooth API if you want users to detect devices near their own device (no server Bluetooth hardware needed).
- Use server-side detection if you need the Rails server to monitor BLE devices in its vicinity (requires server hardware and permissions).
内容的提问来源于stack exchange,提问作者Ravi

