A comprehensive Home Assistant integration for Rdio-Scanner that provides real-time police/fire/EMS radio monitoring with audio playback directly from the Rdio-Scanner database.
This integration connects Home Assistant to your Rdio-Scanner SQLite database, providing access to:
- Live scanner audio stored as BLOBs in the database
- Call metadata and talkgroup information
- Real-time monitoring of new calls
- Historical call playback
- System and talkgroup statistics
graph LR
A[Trunk Recorder] -->|WAV + JSON| B[Rdio-Scanner]
B -->|Imports to SQLite| C[rdio-scanner.db]
C -->|This Integration| D[Home Assistant]
D --> E[Dashboard/Automations]
- Trunk Recorder records radio calls as WAV files with JSON metadata
- Rdio-Scanner imports these files into its SQLite database
- This integration reads the database to provide calls in Home Assistant
- You can listen to calls, create automations, and build dashboards
- Direct Database Access - Connects directly to rdio-scanner.db SQLite database
- Audio Playback - Stream recorded calls from database BLOBs
- Real-time Updates - Monitor new calls as they're imported
- Remote Access - Full functionality via Home Assistant remote access
- Call Metadata - Access talkgroup names, frequencies, units, and more
- Statistics - Track calls per system, talkgroup activity, and call volumes
- Media Player - Built-in media player entity for audio control
- Automation Ready - Trigger automations based on specific talkgroups or systems
- Home Assistant 2024.1.0 or newer
- Rdio-Scanner installation with SQLite database
- Access to the rdio-scanner.db file location
- Trunk Recorder feeding audio to Rdio-Scanner
- Open HACS in Home Assistant
- Click on "Integrations"
- Click the three dots menu and select "Custom repositories"
- Add this repository URL:
https://github.com/tsquared96/ha-rdio-scanner
- Select "Integration" as the category
- Click "Add"
- Search for "Rdio-Scanner" and install
- Restart Home Assistant
- Download the latest release from the releases page
- Extract the
rdio_scanner
folder to yourcustom_components
directory:custom_components/ βββ rdio_scanner/ βββ __init__.py βββ manifest.json βββ config_flow.py βββ ...
- Restart Home Assistant
- Go to Settings β Devices & Services
- Click Add Integration
- Search for Rdio-Scanner
- Enter configuration:
- Name: Friendly name for the integration (e.g., "Scanner")
- Data Directory Path: Path to Rdio-Scanner data directory (e.g.,
/opt/rdio-scanner/data
)
The integration will look for rdio-scanner.db
in the specified directory.
After setup, you should see several new entities:
sensor.rdio_scanner_active_calls
- Number of recent callssensor.rdio_scanner_total_calls
- Total calls in recent historysensor.rdio_scanner_systems
- Number of radio systemssensor.rdio_scanner_talkgroups
- Number of talkgroupsmedia_player.rdio_scanner_player
- Audio playback control
The integration reads from the Rdio-Scanner SQLite database with this structure:
id
- Unique call identifieraudio
- Audio data as BLOB (MP3 format)audioName
- Original filenameaudioType
- MIME type (usually audio/mpeg)dateTime
- Timestamp in millisecondssystem
- System numbertalkgroup
- Talkgroup IDtalkgroupData
- JSON with talkgroup details (label, tag, group)frequency
- Frequency in Hzfrequencies
- JSON array of all frequencies usedsources
- JSON array of unit IDspatches
- JSON array of patched talkgroupslen
- Call length in seconds
- Active Calls - Calls from the last 30 seconds
- Total Calls - Recent call history count
- Systems - Number of unique systems
- Talkgroups - Number of unique talkgroups
Each sensor includes attributes with additional details like latest call information.
- Rdio-Scanner Player - Control audio playback
- Play/pause/stop controls
- Shows current talkgroup and system
- Integrates with Home Assistant media controls
type: vertical-stack
cards:
- type: entities
title: Scanner Status
entities:
- sensor.rdio_scanner_active_calls
- sensor.rdio_scanner_total_calls
- sensor.rdio_scanner_systems
- sensor.rdio_scanner_talkgroups
- type: media-control
entity: media_player.rdio_scanner_player
type: markdown
title: Recent Calls
content: |
{% for call in state_attr('sensor.rdio_scanner_total_calls', 'calls')[:10] %}
**{{ call.talkgroup_name }}** - {{ call.timestamp }}
Length: {{ call.call_length }}s - System {{ call.system }}
{% endfor %}
automation:
- alias: "Scanner Emergency Alert"
trigger:
- platform: state
entity_id: sensor.rdio_scanner_active_calls
condition:
- condition: template
value_template: >
{{ 'Fire Dispatch' in state_attr('sensor.rdio_scanner_total_calls', 'latest_talkgroup') }}
action:
- service: notify.mobile_app
data:
title: "Emergency Call"
message: "Fire Dispatch active"
automation:
- alias: "Auto-play Scanner Calls"
trigger:
- platform: state
entity_id: sensor.rdio_scanner_active_calls
condition:
- condition: numeric_state
entity_id: sensor.rdio_scanner_active_calls
above: 0
action:
- service: media_player.play_media
target:
entity_id: media_player.rdio_scanner_player
data:
media_content_type: music
media_content_id: "{{ state_attr('sensor.rdio_scanner_total_calls', 'latest_call_id') }}"
The integration polls the database every 10 seconds by default. This can be adjusted in the coordinator if needed.
The integration caches up to 50 recent audio files in memory (under 10MB each) for faster playback.
Audio playback works through Home Assistant's authentication system, so it's accessible remotely through:
- Nabu Casa Cloud
- VPN connection
- Reverse proxy setup
- Verify the path to rdio-scanner.db is correct
- Check file permissions (Home Assistant must have read access)
- Ensure Rdio-Scanner is running and importing calls
- Check that audio BLOBs are being stored in the database
- Verify the media_player entity is created
- Check Home Assistant logs for errors
- Verify Trunk Recorder is feeding calls to Rdio-Scanner
- Check Rdio-Scanner logs for import issues
- Ensure database isn't locked by another process
- Consider limiting the number of calls retrieved
- Check database size (consider archiving old calls)
- Ensure SQLite database is on fast storage (SSD recommended)
custom_components/rdio_scanner/
βββ __init__.py # Integration setup and coordinator
βββ manifest.json # Integration metadata
βββ config_flow.py # Configuration UI
βββ const.py # Constants
βββ rdio_db.py # Database interface
βββ sensor.py # Sensor entities
βββ media_player.py # Media player entity
βββ audio_handler.py # Audio serving endpoint
βββ translations/
βββ en.json # UI translations
The integration uses aiosqlite
for async database access:
# Example: Getting audio from database
async def get_call_audio(call_id):
query = "SELECT audio, audioType FROM rdio_scanner_calls WHERE id = ?"
cursor = await conn.execute(query, (call_id,))
row = await cursor.fetchone()
return row['audio'] # Returns BLOB data
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Rdio-Scanner by chuot
- Trunk-Recorder by robotastic
- Home Assistant community for testing and feedback
- Custom Lovelace card with waveform display
- WebSocket support for instant updates
- Call transcription display (if available)
- Advanced filtering by talkgroup/system
- Call export functionality
- Statistics dashboard
- Integration with police/fire department APIs
- Support for multiple Rdio-Scanner instances
This integration is not affiliated with or endorsed by the Rdio-Scanner or Trunk-Recorder projects. Use at your own risk. Ensure you comply with all local laws and regulations regarding radio monitoring and recording in your jurisdiction.
Made with β€οΈ for the Home Assistant and Scanner Communities