Skip to content

Monitoring Devices

Learn how to monitor your Shure wireless microphone system with django-micboard.

Device Status Overview

Django Micboard provides real-time monitoring of:

  • Battery Levels - Current charge percentage and status
  • RF Signal Strength - Signal quality and interference indicators
  • Audio Levels - Input/output levels and peak indicators
  • Device Status - Online/offline state and connection health
  • Location Tracking - Device location and assignment status

Admin Interface

Access the monitoring interface at /admin/ in your Django application.

Device List View

The main device list shows all discovered devices with key metrics:

  • Device name and model
  • Current battery level (with color coding)
  • RF signal strength
  • Online status
  • Last update time
  • Assigned user/location

Real-time Updates

Device status updates automatically via WebSocket connections:

  • Battery levels refresh every 30 seconds
  • RF signals update continuously
  • Status changes appear immediately
  • Connection health is monitored

Management Commands

Device Polling

Run a one-shot poll directly or enqueue it through native Huey:

Terminal window
# Poll Shure devices now
uv run --no-sync python manage.py poll_devices --manufacturer shure
# Enqueue one poll through native Huey
uv run --no-sync python manage.py poll_devices --manufacturer shure --async

Use your deployment scheduler to enqueue the one-shot command at the required interval.

After a manufacturer poll, Micboard evaluates alerts for active assigned wireless units in primary key order. MICBOARD_POLL_ALERT_MAX_UNITS limits each scan (default: 100, hard maximum: 500). Three additional top-level Django settings bound fanout within that scan: MICBOARD_POLL_ALERT_MAX_ASSIGNMENTS (default: 100, hard maximum: 500), MICBOARD_POLL_ALERT_MAX_RECIPIENTS (default: 250, hard maximum: 1,000), and MICBOARD_POLL_ALERT_MAX_DELIVERIES (default: 250, hard maximum: 1,000). Micboard rotates shared cache cursors through bounded pages so later units, assignments, and recipients are not permanently starved. Inactive assignments, monitoring groups, and users are excluded. Recipient membership and tenant scope are revalidated immediately before alert persistence and again before email delivery, so deactivation or reassignment during a poll fails closed. A cache outage falls back to the first bounded page and never disables alert evaluation.

Polling does not start realtime subscription supervisors. Launch one per manufacturer as a separate foreground process; the integration decides its own transport:

Terminal window
# Shure
uv run --no-sync python manage.py realtime_subscribe --manufacturer shure
# Sennheiser
uv run --no-sync python manage.py realtime_subscribe --manufacturer sennheiser

Hosts that schedule through native Huey should explicitly enqueue the registered start_realtime_subscriptions entrypoint once per manufacturer. Multi-process deployments require a process-shared Django cache for the singleton lease. A stopped or crashed supervisor may take up to 60 seconds to become eligible for restart. See Real-time Updates for limits and settings.

Health Monitoring

Monitor connection health and detect issues:

Terminal window
# Check all connections
uv run --no-sync python manage.py realtime_status
# Check specific manufacturer
uv run --no-sync python manage.py realtime_status --manufacturer shure

Alerts and Notifications

Battery Alerts

Configure alerts for low battery conditions:

  • Set threshold levels (default: 20%)
  • Enable/disable per device or globally
  • Email notifications (planned)
  • Admin interface warnings

RF Signal Alerts

Monitor signal quality:

  • Low signal strength warnings
  • Interference detection
  • Channel conflicts
  • Automatic channel scanning

Device Assignment

User Assignments

Assign devices to specific users:

from micboard.services.core.performer_assignment import PerformerAssignmentService
from micboard.services.core.performer_assignment_dtos import CreatePerformerAssignment
# Assign a wireless unit to a performer
assignment = PerformerAssignmentService.create_assignment(
command=CreatePerformerAssignment(
performer_id=performer.id,
unit_id=wireless_unit.id,
group_id=monitoring_group.id,
alert_on_battery_low=True,
),
user=user,
)

Location Tracking

Read locations through the authenticated monitoring scope. Create, update, and assign locations through the permission-checked Django admin:

from micboard.services.monitoring.monitoring_access import MonitoringService
locations = MonitoringService.get_accessible_locations(request.user)

Troubleshooting

Device Not Updating

Check connection status:

Terminal window
uv run --no-sync python manage.py realtime_status --manufacturer shure

Verify API access:

Terminal window
uv run --no-sync python manage.py diagnostic_api_health_check

Check device logs:

  • Review Django admin logs
  • Check Shure System API logs
  • Verify network connectivity

WebSocket Issues

Test WebSocket connection:

  • Open browser developer tools
  • Check Network tab for WebSocket connections
  • Verify ASGI configuration

Redis connection:

Terminal window
# Test Redis connectivity
uv run --no-sync python manage.py shell -c "from channels.layers import get_channel_layer; print(get_channel_layer())"

Performance Issues

Monitor polling performance:

Terminal window
# Run one poll and inspect its completion summary
uv run --no-sync python manage.py poll_devices --manufacturer shure

Database optimization:

  • Ensure proper indexing on device models
  • Monitor query performance
  • Check connection pooling

Advanced Monitoring

Custom Dashboards

Create custom monitoring views:

  • Filter by location or user
  • Sort by battery level or signal strength
  • Export device reports
  • Historical trend analysis

API Integration

Use the REST API for custom monitoring:

# Get device status
GET /api/v1/devices/
# Get battery levels
GET /api/v1/devices/?battery_level__lt=20
# Real-time updates via WebSocket
ws://your-server/ws

Health Checks

Implement health check endpoints:

from micboard.services.realtime.health_service import RealtimeConnectionHealthService
# Return one bounded, typed status aggregate.
summary = RealtimeConnectionHealthService.summarize()
print(f"Active real-time connections: {summary.connected}")