diff --git a/Sources/KitchenSyncApp/Discovery/DeviceMatch.swift b/Sources/KitchenSyncApp/Discovery/DeviceMatch.swift index bd973f4..d96e551 100644 --- a/Sources/KitchenSyncApp/Discovery/DeviceMatch.swift +++ b/Sources/KitchenSyncApp/Discovery/DeviceMatch.swift @@ -34,7 +34,9 @@ enum DeviceMatch { /// P4, `kstouch-dfd0` on the Touch, `x32link-7a1c` on the headless (ESP-035). Missing /// `kstouch` is what made a real device invisible once already. private static func matchesKnownHostname(_ name: String) -> Bool { - knownHostPrefixes.contains { name.hasPrefix($0) } + let lower = name.lowercased() // a Bonjour instance name's case is not meaningful — + // the P4 advertises "KitchenSync", the Touch "kstouch-…" + return knownHostPrefixes.contains { lower.hasPrefix($0) } } /// `x32link` joined this list in ESP-035 — but adding it here was the SMALL half. That diff --git a/Tests/KitchenSyncAppTests/DeviceMatchTests.swift b/Tests/KitchenSyncAppTests/DeviceMatchTests.swift index e7bf692..f8c9122 100644 --- a/Tests/KitchenSyncAppTests/DeviceMatchTests.swift +++ b/Tests/KitchenSyncAppTests/DeviceMatchTests.swift @@ -16,6 +16,16 @@ final class DeviceMatchTests: XCTestCase { "a real Touch on the bench was invisible to the app because of this") } + /// **A real P4 found this.** The ESP32-P4 advertises its Bonjour INSTANCE NAME as + /// "KitchenSync" (capital K, a friendly name), not the lowercase hostname the Touch + /// and X32Link use. hasPrefix is case-sensitive, so `"KitchenSync".hasPrefix( + /// "kitchensync")` is false and the P4 was invisible. A Bonjour name's case is not + /// meaningful; the match must be case-insensitive. + func test_the_p4_is_matched_despite_a_capitalised_instance_name() { + XCTAssertTrue(DeviceMatch.isKitchenSync(serviceName: "KitchenSync", txt: nil)) + XCTAssertTrue(DeviceMatch.isKitchenSync(serviceName: "KSTouch-DFD0", txt: nil)) + } + /// Units already in the field have no TXT record and won't until they're reflashed. Breaking /// them would be a worse bug than the one being fixed. func test_the_existing_devices_still_match_on_hostname() {