Regulatory Coverage Monitoring
Overview
Django Micboard includes automatic monitoring and alerting for RF channels operating without regulatory frequency data coverage. This helps ensure compliance and data completeness.
Architecture Understanding
Three-layer RF coordination architecture with regulatory compliance at each level:
WirelessChassis (Base Station) ↓ has band plan (frequency RANGE - what it CAN operate on) ↓ regulatory check: band plan coverageRFChannel (RF Slot/Channel) ↓ has frequency assignment (specific FREQUENCY - what it IS doing) ↓ regulatory check: frequency coverage (PRIMARY COORDINATION)WirelessUnit (Field Device) ↓ reports what it receives ↓ delegates to RFChannelRegulatory Compliance Layers:
-
WirelessChassis Band Plan (Foundational)
- Example: Shure ULXD4Q band G50 operates 470-534 MHz
- Checks: Is the entire band plan range allowed in this regulatory domain?
- Impact: Determines what frequencies the chassis CAN be coordinated to
-
RFChannel Frequency (Primary Coordination)
- Example: Channel 1 assigned to 520.125 MHz
- Checks: Is this specific frequency allowed in this regulatory domain?
- Impact: The actual coordinated frequency being used
-
WirelessUnit (Secondary/Reporting)
- Example: Handheld mic reports 520.125 MHz
- Checks: Delegates to assigned RFChannel
- Impact: Field device reflects coordinated frequency
Features
1. WirelessChassis Band Plan Checks (Foundational)
The hardware domain modules provide band-plan regulatory checking without model delegation methods:
Functions for WirelessChassis
rf_channel_service.get_regulatory_domain_for_location(chassis.location)
- Returns the applicable
RegulatoryDomainfrom the location - Checks location.regulatory_domain first, then country code lookup
chassis_regulatory_service.get_band_plan_status(chassis)
- Returns True if chassis has band plan configured (min/max MHz)
chassis_regulatory_service.has_band_plan_regulatory_coverage(chassis)
- Returns
Trueif the entire band plan range is covered by regulatory data - Returns
Falseif no band plan, no regulatory domain, or insufficient coverage
chassis_regulatory_service.get_needs_band_plan_regulatory_update(chassis)
- Flags online chassis with band plans that lack regulatory coverage
- Used to trigger admin alerts
chassis_regulatory_service.get_band_plan_regulatory_status(chassis)
- Returns comprehensive status dictionary including:
has_band_plan: boolhas_coverage: boolregulatory_domain: str (domain code like ‘FCC’, ‘ETSI’)band_plan_range: str (human-readable range with name)needs_update: boolmessage: str (human-readable status)
Band Plan Fields:
band_plan_min_mhz: Float - Minimum frequency (MHz)band_plan_max_mhz: Float - Maximum frequency (MHz)band_plan_name: String - Band identifier (e.g., “G50 470-534MHz”, “UHF Band IV”)
2. RFChannel Regulatory Checks (Primary Coordination)
The RFChannel model includes frequency-specific regulatory checking:
1. RFChannel Regulatory Services (Primary)
The RF-channel service module owns comprehensive regulatory checks:
Functions in micboard.services.hardware.rf_channel_service
get_regulatory_domain()
- Returns the applicable
RegulatoryDomainbased on chassis location - Checks chassis.location.regulatory_domain first, then country code lookup
has_regulatory_coverage()
- Returns
Trueif the channel’s frequency is covered by regulatory data - Returns
Falseif no coverage exists
get_needs_regulatory_update(channel)
- Flags active channels operating without regulatory coverage
- Used to trigger admin alerts
get_regulatory_status()
- Returns comprehensive status dictionary including:
has_coverage: boolregulatory_domain: str (domain code like ‘FCC’, ‘ETSI’)operating_frequency_mhz: float (the coordinated frequency)needs_update: boolmessage: str (human-readable status)
2. WirelessUnit Regulatory Services (Secondary)
The wireless-unit service resolves and checks the unit’s assigned RF channel:
get_assigned_rf_channel(unit)
- Returns the RFChannel this unit is assigned to
- Returns None if no channel assigned
get_regulatory_status(unit)
- Delegates to the RF-channel service
- Returns “no channel assigned” status if not linked to any channel
- Includes
source: "rf_channel"orsource: "no_channel"in response
4. Django Admin Integration
The Django admin interface displays regulatory status at all three levels:
Wireless Chassis Admin (/admin/micboard/wirelesschassis/) - FOUNDATIONAL
- New “Band Plan” column shows configured frequency range
- New “Band Plan Regulatory Status” column shows:
- ✅ OK - Green when band plan is covered
- ⚠️ Missing coverage - Red when band plan lacks regulatory data
- ℹ️ No band plan - Gray when not configured
RF Channels Admin (/admin/micboard/rfchannel/) - PRIMARY COORDINATION
- “Regulatory Status” column shows:
- ✅ OK (frequency MHz) - Green for covered
- ⚠️ Missing coverage - Red for channels needing updates
- ℹ️ No frequency - Gray for channels without frequency assignment
Wireless Units Admin (/admin/micboard/wirelessunit/) - SECONDARY (delegates)
- Regulatory status delegates to assigned RFChannel
- Shows “Via RFChannel N: [status]” when channel assigned
- Shows “No RF channel assigned” when not linked
5. Audit Management Command
A management command audits all three levels:
uv run --no-sync python manage.py audit_regulatory_coverageOptions:
--verbose- Show detailed information for each device--show-ok- Display devices with OK coverage (default: only shows issues)
Output Example:
================================================================================REGULATORY COVERAGE AUDIT================================================================================
Architecture: Chassis (band plan) → RFChannel (frequency) → WirelessUnitRF coordination happens at RFChannel level (frequency assignment).Band plan compliance checked at Chassis level (operating range).
🏢 WIRELESS CHASSIS (Foundational - Band Plan Coverage)-------------------------------------------------------------------------------- ⚠️ [CHASSIS] Shure ULXD4Q (receiver) - Main Rack 1 - ⚠️ Band plan G50 (470.0-534.0 MHz) not covered by FCC regulatory data - admin needs to update ✅ [CHASSIS] Sennheiser EM 6000 (receiver) - Side Stage - ✅ Band plan regulatory coverage OK (ETSI)
Total online chassis: 12 ✅ OK: 10 ℹ️ No band plan: 1 ⚠️ Needs update: 1
📻 RF CHANNELS (Primary - Where Coordination Happens)-------------------------------------------------------------------------------- ⚠️ ULXD4D-1 - RF Ch 1 (Receive) - ⚠️ Frequency 795.0 MHz not covered by FCC regulatory data - admin needs to update
Total active channels: 48 ✅ OK: 47 ℹ️ No frequency: 0 ⚠️ Needs update: 1
📡 WIRELESS UNITS (Secondary - Delegates to RF Channels)-------------------------------------------------------------------------------- ℹ️ Bodypack 5 (Microphone Transmitter) - Slot 5 - ℹ️ No RF channel assigned - regulatory check not applicable
Total active units: 45 ✅ OK (via RF channel): 43 ℹ️ No RF channel: 2 ⚠️ Needs update: 0
================================================================================SUMMARY================================================================================⚠️ 2 issue(s) need regulatory data updates: - 1 chassis band plan(s) - 1 RF channel(s)
ACTION REQUIRED: 1. Review chassis band plans and RF channels flagged above 2. Run: uv run --no-sync python manage.py import_efis_regulations --force 3. Or manually add frequency bands in Django admin for missing regions 4. Update chassis band plan fields if devices have band infoWorkflow
RF Coordination Architecture
Understanding the three-layer data flow:
1. WirelessChassis discovered → Band plan info stored (what it CAN do)2. RFChannel created → Static channel assignment on chassis3. Frequency coordinated → RFChannel.frequency set (what it IS doing - COORDINATION HAPPENS HERE)4. WirelessUnit linked → Field device assigned to RFChannel5. Regulatory checks: a. Band plan check → Validates chassis band_plan_min/max_mhz against regulatory bands b. Frequency check → Validates RFChannel.frequency against regulatory bands (primary) c. Unit check → Delegates to assigned RFChannelWhen Band Plans & Frequencies Are Assigned
- Chassis discovered with band plan information (e.g., G50 470-534MHz)
- Band plan stored in
band_plan_min_mhz,band_plan_max_mhz,band_plan_namefields- Auto-population available: Use Django admin dropdown to select standard band plans (see Band Plan Auto-Population Guide)
- Frequencies auto-fill from registry for Shure, Sennheiser, Lectrosonics, Wisycom, Audio-Technica, Sony
- Bulk updates supported for multiple chassis
- Band plan validated - Check if operating range is allowed in regulatory domain
- RF channels created when chassis discovered
- Frequency coordination happens - Admin or automation assigns specific frequencies to RFChannels
- Frequency validated - Check if specific frequency is allowed in regulatory domain
- Admin sees alerts in Django admin for both band plan and frequency coverage issues
Resolving Missing Coverage
Option 1: Import EFIS Data (European frequencies)
uv run --no-sync python manage.py import_efis_regulations --forceThis imports the latest European regulatory data from CEPT EFIS API.
Option 2: Manual Entry (Non-European or custom)
- Navigate to Django Admin → RF Coordination → Regulatory Domains
- Add or update the relevant domain (e.g., ‘FCC’, ‘ACMA’)
- Add frequency bands under that domain
- Re-run audit:
uv run --no-sync python manage.py audit_regulatory_coverage
Option 3: Update Chassis Location If the chassis location has wrong or missing regulatory domain:
- Django Admin → Locations → Building
- Find the building/location where chassis is deployed
- Set the correct
regulatory_domainorcountryfield - Re-run audit
Option 4: Add/Update Chassis Band Plan If chassis is missing band plan information:
- Django Admin → Wireless Chassis
- Find the chassis device
- Set
band_plan_min_mhz,band_plan_max_mhz, andband_plan_name- Example for Shure ULXD G50: min=470, max=534, name=“G50 470-534MHz”
- Example for Sennheiser Aw+: min=470, max=558, name=“Aw+ 470-558MHz”
- Re-run audit to verify coverage
Monitoring in Production
Scheduled Audit: Add to your cron/scheduled tasks:
# Daily audit at 6am0 6 * * * cd /path/to/project && uv run --no-sync python manage.py audit_regulatory_coverage --verbose >> /var/log/micboard/regulatory_audit.log 2>&1Integration with Monitoring Tools: The audit command exits with:
- Exit code 0: All devices OK
- Console output parseable for log monitoring
Data Model
RegulatoryDomain
code: Domain identifier (e.g., ‘FCC’, ‘ETSI’, ‘ACMA’)country_code: ISO 3166-1 alpha-2 (e.g., ‘US’, ‘DE’, ‘AU’)min_frequency_mhz/max_frequency_mhz: General frequency bounds
FrequencyBand
regulatory_domain: FK to RegulatoryDomainstart_frequency_mhz/end_frequency_mhz: Specific band rangeband_type: ‘allowed’, ‘restricted’, ‘forbidden’, ‘guard’name: Band description (e.g., ‘UHF TV Band IV’)
Device Frequency Fields
RFChannel.frequency: FloatField - WHERE RF COORDINATION HAPPENS (primary)WirelessUnit.frequency: CharField - Reported value from device (secondary, echoes RFChannel)
API Integration
The regulatory status is available programmatically:
from micboard.models.hardware.wireless_unit import WirelessUnitfrom micboard.models.rf_coordination.rf_channel import RFChannelfrom micboard.services.hardware.rf_channel_service import ( get_needs_regulatory_update, get_regulatory_status as get_rf_channel_regulatory_status,)from micboard.services.hardware.wireless_unit_service import ( get_regulatory_status as get_wireless_unit_regulatory_status,)
# Check an RF channel (primary - where coordination happens)channel = RFChannel.objects.get(pk=1)status = get_rf_channel_regulatory_status(channel)print(status)# {# 'has_coverage': False,# 'regulatory_domain': 'FCC',# 'operating_frequency_mhz': 520.5,# 'needs_update': True,# 'message': '⚠️ Frequency 520.5 MHz not covered by FCC regulatory data - admin needs to update'# }
# Flag for alertingif get_needs_regulatory_update(channel): send_alert_to_admin(channel)
# Check a wireless unit (delegates to RF channel)unit = WirelessUnit.objects.get(pk=1)status = get_wireless_unit_regulatory_status(unit)print(status)# {# 'has_coverage': False,# 'regulatory_domain': 'FCC',# 'operating_frequency_mhz': 520.5,# 'needs_update': True,# 'source': 'rf_channel',# 'message': 'Via RFChannel 1: ⚠️ Frequency 520.5 MHz not covered...'# }Best Practices
- Run EFIS import regularly (weekly) to keep European data current
- Audit after RF coordination changes to catch missing coverage early
- Monitor audit logs for trends in missing coverage
- Document custom frequency bands for non-European regions
- Set location regulatory domains proactively during chassis deployment
- Focus on RFChannel compliance - that’s where coordination happens
Future Enhancements
Potential additions:
- Automated alerting via email/Slack when devices need updates
- Dashboard widget showing regulatory coverage percentage
- Bulk import for FCC/ACMA/other regional data
- Frequency coordination recommendations based on regulatory bands
- Integration with RF scan file imports for venue-specific constraints
Related Documentation
- Resolving Missing Coverage - European frequency data import
- RF Coordination Overview - Frequency management concepts
- Location Setup - Configuring buildings and regulatory domains
