Skip to content

feat: Improve Apple device detection and add Furbo cloud camera support#269

Open
ekobres wants to merge 4 commits intoOzark-Connect:mainfrom
ekobres:feature/device-detection-improvements
Open

feat: Improve Apple device detection and add Furbo cloud camera support#269
ekobres wants to merge 4 commits intoOzark-Connect:mainfrom
ekobres:feature/device-detection-improvements

Conversation

@ekobres
Copy link
Contributor

@ekobres ekobres commented Feb 14, 2026

  • 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

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.

Copilot AI review requested due to automatic review settings February 14, 2026 19:46
- 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.
@ekobres ekobres force-pushed the feature/device-detection-improvements branch from e9f4403 to 9f5941b Compare February 14, 2026 19:48
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +451 to +453
return CreateOuiResult(ClientDeviceCategory.StreamingDevice, "Apple TV", OuiHighConfidence);
if (deviceNameLower.Contains("homepod") || deviceNameLower.Contains("siri"))
return CreateOuiResult(ClientDeviceCategory.SmartSpeaker, "Apple HomePod", OuiHighConfidence);
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
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
}
};
}

Copilot uses AI. Check for mistakes.
{ "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)
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comment formatting: "Apple TV /HomePods" is missing a space after the slash; consider "Apple TV / HomePods" for readability.

Suggested change
// Apple TV /HomePods (note: Apple devices can be many things)
// Apple TV / HomePods (note: Apple devices can be many things)

Copilot uses AI. Check for mistakes.
@tvancott42
Copy link
Collaborator

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.

@tvancott42
Copy link
Collaborator

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!

@ekobres
Copy link
Contributor Author

ekobres commented Feb 14, 2026

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.

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!

@tvancott42
Copy link
Collaborator

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.

tvancott42 added a commit that referenced this pull request Feb 14, 2026
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.
@ekobres
Copy link
Contributor Author

ekobres commented Feb 14, 2026

I did run some debug tracing to see what was happening. Here's a snippet before my changes:

Device: "Bar Siri"
MAC: f4:34:f0:50:09:cf (Apple HomePod OUI prefix)

Detection Flow:
--------------
[15:10:14 DBG] [Detection] Starting detection for 'Bar Siri' (MAC: f4:34:f0:50:09:cf)
[15:10:14 DBG] [Detection] Fingerprint: IoTGeneric (dev_cat=51, dev_vendor=320)
[15:10:14 DBG] [Detection] UniFi OUI: No match for manufacturer 'Apple, Inc.'
[15:10:14 DBG] [Detection] MAC OUI: No match for prefix f4:34:f0  ← PROBLEM: HomePod OUI not in database
[15:10:14 DBG] [Detection] Name pattern: SmartSpeaker from 'HomePod' (isPort=False)  ← Name pattern matches but...
[15:10:14 DBG] [Detection] 'Bar Siri' (f4:34:f0:50:09:cf): UniFiFingerprint → IoTGeneric (95%)  ← ...fingerprint wins
[15:10:14 DBG] Wireless client: Bar Siri (f4:34:f0:50:09:cf) on Home - detected as IoT Device, Radio=na, Channel=149

Result: IoT Device (INCORRECT - should be Smart Speaker)

tvancott42 added a commit that referenced this pull request Feb 14, 2026
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.
@tvancott42
Copy link
Collaborator

Ah ha [15:10:14 DBG] [Detection] Fingerprint: IoTGeneric (dev_cat=51, dev_vendor=320)

That's coming from the UniFi Fingerprint DB. I think it must be this one:

        "4456": {
            "dev_type_id": "51",
            "family_id": "18",
            "fb_id": "0",
            "name": "Apple HomePod Mini",
            "os_class_id": "1",
            "os_name_id": "1",
            "tm_id": "0",
            "vendor_id": "320"
        }

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants