feat: Improve Apple device detection and add Furbo cloud camera support#269
feat: Improve Apple device detection and add Furbo cloud camera support#269ekobres wants to merge 4 commits intoOzark-Connect:mainfrom
Conversation
- Add MAC OUI entries for HomePods (E0:2B:96, F4:34:F0, D4:90:9C) and Apple TVs (A8:51:AB, C8:D0:83, 9C:3E:53) - Add Furbo to cloud camera vendor list for proper IoT VLAN recommendations - Implement Apple vendor override logic to prioritize MAC OUI over generic fingerprints * Apple devices with SmartTV/IoTGeneric fingerprints now use MAC OUI database * Returns 98% confidence to override 95% generic fingerprint detection * Fixes issue where HomePods were detected as "IoT Device" instead of "SmartSpeaker" - Add comprehensive test coverage for new code * Test Furbo camera detection by name and Vendor. * Test Apple TV detection with generic SmartTV fingerprint * Test HomePod detection with generic IoTGeneric fingerprint * Test fallback behavior when MAC OUI has no match * Test interaction between name-based and vendor-based detection Resolves: HomePods now correctly detected as SmartSpeaker and allowed on default VLAN when "Allow Apple streaming devices on main network" setting is enabled.
The explicit name-based check for HomePods with 'siri' or 'homepod' in the name (lines 1274-1292) is now redundant. The generic Apple vendor override logic (lines 1223-1248) already handles all Apple devices with generic fingerprints through MAC OUI detection, including HomePods. This reduces code duplication and maintenance burden while preserving all functionality. All 5,130 tests still pass.
Changed name.Contains("tv") to deviceNameLower.Contains("tv") to match
the pattern used in the rest of the method. This ensures consistent
case-insensitive matching for Apple device name disambiguation.
e9f4403 to
9f5941b
Compare
There was a problem hiding this comment.
Pull request overview
This PR improves device-type classification for Apple streaming devices (Apple TV, HomePod) when UniFi reports generic fingerprints, and expands cloud camera vendor recognition to include Furbo to drive correct VLAN recommendations.
Changes:
- Added Apple TV and HomePod MAC OUI mappings and introduced Apple-specific override logic to prefer MAC OUI over generic SmartTV/IoTGeneric fingerprints.
- Added Furbo to the cloud security vendor list so camera fingerprints are upgraded to CloudCamera for VLAN guidance.
- Expanded unit test coverage for Furbo detection and the Apple generic-fingerprint override/fallback behaviors.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/NetworkOptimizer.Audit.Tests/Services/DeviceTypeDetectionServiceTests.cs | Adds tests for Furbo vendor handling and Apple MAC-OUI override behavior for generic fingerprints, plus fallback cases. |
| src/NetworkOptimizer.Audit/Services/DeviceTypeDetectionService.cs | Implements Apple generic-fingerprint vendor override via MAC OUI and adds Furbo to cloud security vendor detection; refines Apple handling in UniFi OUI detection. |
| src/NetworkOptimizer.Audit/Services/Detectors/MacOuiDetector.cs | Adds Apple TV/HomePod OUI prefixes to curated MAC OUI mappings. |
Comments suppressed due to low confidence (1)
src/NetworkOptimizer.Audit/Services/DeviceTypeDetectionService.cs:184
- The log message for vendor overrides says "vendor defaults to plug unless camera indicated", but this path now also includes Apple MAC-OUI overrides (and potentially other non-plug overrides). This makes logs misleading when diagnosing detections. Consider updating the message to be neutral (e.g., include the override reason from metadata or omit the plug/camera wording).
_logger?.LogDebug("[Detection] '{DisplayName}': Vendor override → {Category} (vendor defaults to plug unless camera indicated)",
displayName, vendorOverrideResult.Category);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return CreateOuiResult(ClientDeviceCategory.StreamingDevice, "Apple TV", OuiHighConfidence); | ||
| if (deviceNameLower.Contains("homepod") || deviceNameLower.Contains("siri")) | ||
| return CreateOuiResult(ClientDeviceCategory.SmartSpeaker, "Apple HomePod", OuiHighConfidence); |
There was a problem hiding this comment.
In the Apple UniFi-OUI handling, CreateOuiResult is called with "Apple TV" / "Apple HomePod" as the vendor argument. That value is also written into Metadata["oui_name"], so the metadata no longer reflects the actual UniFi manufacturer string (e.g., "Apple, Inc."). Consider keeping the original ouiName in the metadata (and/or splitting manufacturer vs product labeling).
| return CreateOuiResult(ClientDeviceCategory.StreamingDevice, "Apple TV", OuiHighConfidence); | |
| if (deviceNameLower.Contains("homepod") || deviceNameLower.Contains("siri")) | |
| return CreateOuiResult(ClientDeviceCategory.SmartSpeaker, "Apple HomePod", OuiHighConfidence); | |
| { | |
| return new DeviceDetectionResult | |
| { | |
| Category = ClientDeviceCategory.StreamingDevice, | |
| Source = DetectionSource.MacOui, | |
| ConfidenceScore = OuiHighConfidence, | |
| VendorName = "Apple TV", | |
| RecommendedNetwork = FingerprintDetector.GetRecommendedNetwork(ClientDeviceCategory.StreamingDevice), | |
| Metadata = new Dictionary<string, object> | |
| { | |
| ["detection_method"] = "unifi_oui_name", | |
| ["oui_name"] = ouiName | |
| } | |
| }; | |
| } | |
| if (deviceNameLower.Contains("homepod") || deviceNameLower.Contains("siri")) | |
| { | |
| return new DeviceDetectionResult | |
| { | |
| Category = ClientDeviceCategory.SmartSpeaker, | |
| Source = DetectionSource.MacOui, | |
| ConfidenceScore = OuiHighConfidence, | |
| VendorName = "Apple HomePod", | |
| RecommendedNetwork = FingerprintDetector.GetRecommendedNetwork(ClientDeviceCategory.SmartSpeaker), | |
| Metadata = new Dictionary<string, object> | |
| { | |
| ["detection_method"] = "unifi_oui_name", | |
| ["oui_name"] = ouiName | |
| } | |
| }; | |
| } |
| { "C8:3A:6B", ("Roku", ClientDeviceCategory.StreamingDevice, 90) }, | ||
|
|
||
| // Apple TV (note: Apple devices can be many things) | ||
| // Apple TV /HomePods (note: Apple devices can be many things) |
There was a problem hiding this comment.
Minor comment formatting: "Apple TV /HomePods" is missing a space after the slash; consider "Apple TV / HomePods" for readability.
| // Apple TV /HomePods (note: Apple devices can be many things) | |
| // Apple TV / HomePods (note: Apple devices can be many things) |
|
Generally MAC OUI is going to be less reliable than the UniFi device fingerprint / icon - the root cause may be that the device fingerprint for Homepods is mapping to something non-specific. I'll look into that before. This should be fine, but I'd rather fix it at the source first, then add this on top. MAC OUI reliability should only be set that high when it's for-sure (like confirmed by Apple engineering) that those MAC ranges are just for those kinds of devices. Otherwise, logically, it's lower confidence than if a user specifies the device icon/fingerprint in UniFi. |
|
They should map to "52": "Smart Audio Device" per the UniFi fingerprint DB which I think I'm probably mapping to IoT Generic. That's an easy fix, I'll check that out and verify that. There's not a ton of functionality that differentiates IoT and Smart Speaker behavior, it's mostly just for labeling. It's been a while and about 800 commits since I implemented the Homepods/Apple TV exception setting, so I need to revisit if this would negatively affect that. I'll get this one into the next next release. Thanks! |
I agree - but the OUIs are definitively Apple - so they should never be confidently fingerprinted as a generic devCat. The only way HomePods were being detected at all before was by name. I found it because I rename my "listening" HomePods to "Siri" - so the Speaker-only HomePods were correctly categorized, but the "Siri" ones were categorized as generic IoT devices, despite a legit Apple OUI. Some of this is probably Ubiquiti's fault - most Apple devices are correctly categorized. Even though these HomePods show up with the correct icon, they are coming across as generic. Okay - just re-read your comment - this is an internal remap... Okay - so whatever you think is best. If you decide to can all of the logic, please hang on to the OUIs. Also, please keep the Furbo categorization as CloudSecurity. Thanks! |
|
Have you traced w/ debug logging? I'm interested to see if your HomePod devices were miscategorized due to Optimizer ignoring the device fingerprint/icon, or if it's just categorizing them as generic IoT (which is the current behavior I'm aware of, which is a minor thing). Before they were getting categorized as something completely wrong, which led to false positive issues being created in Audit. I definitely will be working on this next along with LAG port logic. The Furbo categorization is trivial though, so that'll make it in worst case, but I suspect I can use 95% of this. Much appreciated. |
Furbo dog cameras require internet for remote access and should be categorized as CloudCamera for proper IoT VLAN recommendations. Co-authored-by: ekobres <ekobres@gmail.com> Extracted from #269 - the rest of that PR (Apple device detection improvements) is pending review and testing.
|
I did run some debug tracing to see what was happening. Here's a snippet before my changes: Result: IoT Device (INCORRECT - should be Smart Speaker) |
Furbo dog cameras require internet for remote access and should be categorized as CloudCamera for proper IoT VLAN recommendations. Co-authored-by: ekobres <ekobres@gmail.com> Extracted from #269 - the rest of that PR (Apple device detection improvements) is pending review and testing.
Adds visibility into vendor override decision-making process: - Logs when Apple device with generic fingerprint detected (OUI, dev_cat, MAC) - Shows MAC OUI lookup results with category and vendor name - Logs fallback scenario when MAC OUI has no match This enables accurate documentation of the detection flow for upstream developer review. Previously, logs only showed the final result without intermediate steps, making it difficult to document the vendor override logic accurately. Addresses documentation gap identified during PR Ozark-Connect#269 review.
|
Ah ha That's coming from the UniFi Fingerprint DB. I think it must be this one: I was expecting dev_type_id 52, but 51 is just "Smart Device" in the UniFi fingerprint DB. Your fix is necessary as with similar ones in the codebase to make up for insufficient/incorrect UniFi fingerprinting. Good work. I'd leave in the fallback for the HomePod name check though. |
HomePods now correctly detected as SmartSpeaker and allowed on default VLAN
when "Allow Apple streaming devices on main network" setting is enabled.
Furbo cameras are now properly categorized as CloudSecurity and allowed on Internet-connected VLANs.