From 422b6ac3e69af147016db3c94aaa5103ca35f9b2 Mon Sep 17 00:00:00 2001 From: Sylvain Bettinelli Date: Tue, 1 Sep 2026 08:30:48 +0000 Subject: [PATCH] =?UTF-8?q?=C2=AB=20Fermer=20l'app=20Polar=20Flow=20=C2=BB?= =?UTF-8?q?=20=C3=A9tait=20un=20conseil=20faux,=20et=20mesur=C3=A9=20tel?= =?UTF-8?q?=20d=C3=A8s=20le=2031/08?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sylvain enchaîne un troisième envoi et reçoit « le canal est probablement occupé » — notre propre message, déclenché par watchNotFound avec des montres muettes : le service PsFTP est là, il ne répond pas. La chronologie de ses trois envois explique tout. Le premier réussit, montre fraîchement réinitialisée donc pas encore liée à Flow. Le deuxième renvoie 104 DIRECTORY_EXISTS, ce qui prouve que le canal était ENCORE libre. Le troisième échoue : Flow a repris la main entre-temps. Le canal n'est donc pas ouvert ou fermé en général — il y a une fenêtre, qui se referme dès que Flow se reconnecte. Le message conseillait de fermer complètement l'app Polar Flow. C'était faux, et la mesure du 31/08 le disait déjà : la montre affichait « connexion impossible » pendant que les réglages iOS la disaient toujours connectée à Flow. iOS maintient le lien d'un accessoire appairé, app fermée ou non. Le message nomme maintenant le geste qui libère réellement le canal — redémarrer la montre — précise que fermer l'app n'y change rien, et rappelle que le câble est le chemin fiable. Corrigé au passage le message des appareils sans PsFTP, qui présentait encore la question comme « l'inconnue restante » alors qu'elle a été tranchée le 31/08 : la montre expose bien PsFTP quand elle est connectée. Un test interdit désormais de la rouvrir dans l'UI. 88 tests Linux verts, dont deux nouveaux qui verrouillent l'absence du conseil inutile et la présence du geste utile. Co-Authored-By: Claude Opus 5 (1M context) --- docs/polar-ble-runbook-mac.md | 30 +++++++++++++++++ ios/App/App/PolarPftpStep.swift | 32 +++++++++++++++---- .../CoachModelTests/PolarPftpStepTests.swift | 22 +++++++++++-- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/docs/polar-ble-runbook-mac.md b/docs/polar-ble-runbook-mac.md index 9a76fe1..af4705d 100644 --- a/docs/polar-ble-runbook-mac.md +++ b/docs/polar-ble-runbook-mac.md @@ -383,3 +383,33 @@ documentée et devra être mesurée. **câble**. [ancs]: https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html + +### La séquence du 01/09, et ce qu'elle apprend sur la fenêtre + +Trois envois consécutifs, trois résultats différents — c'est la chronologie qui +explique tout : + +| # | résultat | lecture | +|---|---|---| +| 1 | **réussi** | montre fraîchement réinitialisée, **pas encore liée à Flow** : canal libre | +| 2 | **errorcode 104** `DIRECTORY_EXISTS` | canal **toujours** libre, la session s'ouvre — seul le `mkdir` bute sur un dossier déjà créé au 1ᵉʳ envoi | +| 3 | **« canal probablement occupé »** | Flow a repris la main entre-temps | + +⇒ Le canal n'est pas ouvert ou fermé « en général » : il y a une **fenêtre**, +qui commence quand la montre n'est liée à personne et se referme dès que Flow +se reconnecte. C'est cohérent avec le 31/08 et avec l'USB, où il faut fermer +Flow. + +⚠️ **Le message d'erreur du plugin conseillait « fermer complètement l'app Polar +Flow ». C'est faux, et ça l'était déjà le 31/08** : la montre affichait +« connexion impossible » pendant que les réglages iOS la disaient **toujours +connectée** à Flow. iOS maintient le lien d'un accessoire appairé, app fermée ou +non. Message corrigé le 01/09 — il nomme désormais le geste qui libère +réellement le canal (redémarrer la montre) et rappelle que le câble est le +chemin fiable. + +**Hypothèse ouverte, non vérifiée** : redémarrer la montre puis écrire *dans la +foulée*, avant que Flow ne se reconnecte, pourrait suffire. Ça expliquerait les +envois 1 et 2. Ce n'est pas une méthode tant que ça n'a pas été reproduit +plusieurs fois — et ⛔ chaque essai a un coût matériel avéré (l'USB désactivé le +31/08). **Écrire la séance par câble AVANT tout essai.** diff --git a/ios/App/App/PolarPftpStep.swift b/ios/App/App/PolarPftpStep.swift index 717ef1a..be70d57 100644 --- a/ios/App/App/PolarPftpStep.swift +++ b/ios/App/App/PolarPftpStep.swift @@ -210,17 +210,37 @@ public enum PolarPftpError: Error, CustomStringConvertible, Equatable { + "la montre allumée et à portée." case .watchNotFound(let seconds, let vues, _, let muettes) where muettes > 0: - // Le service est là mais ne répond pas : signature d'un canal déjà pris. + // Le service est là mais ne répond pas : canal déjà pris. + // + // ⚠️ Ce message conseillait « fermer l'app Polar Flow ». C'était + // faux, et mesuré comme tel le 31/08/2026 : la montre affichait + // « connexion impossible » pendant que les réglages iOS la + // disaient TOUJOURS connectée à Flow. iOS maintient le lien d'un + // accessoire appairé, app fermée ou non — fermer l'app ne rend pas + // le canal. + // + // Ce qui l'a rendu, le 01/09 : une montre fraîchement + // réinitialisée, donc pas encore liée à Flow. Redémarrer la montre + // libère aussi son canal, mais Flow le reprend. return "\(vues) appareil(s) vu(s), \(muettes) portant PsFTP mais sans " - + "réponse en \(Int(seconds)) s. Le canal est probablement déjà " - + "occupé : fermer complètement l'app Polar Flow (elle synchronise " - + "en arrière-plan), puis réessayer." + + "réponse en \(Int(seconds)) s. Le canal PsFTP de la Vantage " + + "n'accepte qu'une session, et Polar Flow la détient tant que " + + "la montre lui est appairée — fermer l'app n'y change rien, " + + "iOS maintient le lien. Redémarrer la montre (appui long sur " + + "OK) libère le canal ; il faut écrire dans la foulée, avant " + + "que Flow ne le reprenne. Chemin fiable : le câble." case .watchNotFound(let seconds, let vues, _, _): // Des appareils, mais aucun ne porte le service. + // ⚠️ Ce message parlait d'« inconnue restante ». Elle a été levée le + // 31/08/2026 : la montre EST atteignable et expose bien PsFTP + // (« 12 appareils vus, 1 portant PsFTP ») — quand elle est + // connectée. N'en voir aucun est donc autre chose : montre éteinte, + // hors de portée, ou pas encore connectée à l'iPhone. return "\(vues) appareil(s) Bluetooth vu(s) en \(Int(seconds)) s, aucun " - + "n'expose PsFTP. La Vantage n'annonce peut-être pas ce service " - + "tant qu'elle est appairée à Flow — c'est l'inconnue restante." + + "n'expose PsFTP. La Vantage expose bien ce service quand elle " + + "est connectée (vérifié le 31/08) : la chercher plutôt du côté " + + "de la montre — allumée, à portée, et reliée à l'iPhone." } } } diff --git a/tests-linux/Tests/CoachModelTests/PolarPftpStepTests.swift b/tests-linux/Tests/CoachModelTests/PolarPftpStepTests.swift index 8ed4ce8..924e5af 100644 --- a/tests-linux/Tests/CoachModelTests/PolarPftpStepTests.swift +++ b/tests-linux/Tests/CoachModelTests/PolarPftpStepTests.swift @@ -138,13 +138,31 @@ final class PolarPftpErrorTests: XCTestCase { func testUneMontreMuettePointeVersFlow() { let e = PolarPftpError.watchNotFound(30, vues: 3, sansPsFtp: 2, muettes: 1) XCTAssertTrue(e.description.contains("Polar Flow")) - XCTAssertTrue(e.description.contains("occupé")) } - func testDesAppareilsSansPsFtpNommentLInconnueRestante() { + /// ⚠️ Le message conseillait « fermer complètement l'app Polar Flow ». + /// Mesuré faux le 31/08/2026 : la montre affichait « connexion impossible » + /// pendant que les réglages iOS la disaient toujours connectée à Flow. iOS + /// maintient le lien d'un accessoire appairé, app fermée ou non. + func testLeMessageNeConseillePlusDeFermerLApp() { + let e = PolarPftpError.watchNotFound(30, vues: 3, sansPsFtp: 2, muettes: 1) + XCTAssertTrue(e.description.contains("fermer l'app n'y change rien"), + "le geste inutile doit être explicitement écarté") + XCTAssertTrue(e.description.contains("Redémarrer la montre"), + "le geste qui libère réellement le canal doit être donné") + XCTAssertTrue(e.description.contains("câble"), + "le chemin fiable doit être rappelé") + } + + /// L'« inconnue restante » a été levée le 31/08 : la montre expose bien + /// PsFTP quand elle est connectée. Le message ne doit plus la présenter + /// comme une question ouverte. + func testDesAppareilsSansPsFtpNePresententPlusUneInconnue() { let e = PolarPftpError.watchNotFound(30, vues: 4, sansPsFtp: 4, muettes: 0) XCTAssertTrue(e.description.contains("n'expose PsFTP")) XCTAssertTrue(e.description.contains("4 appareil")) + XCTAssertFalse(e.description.contains("inconnue"), + "la question a été tranchée, ne pas la rouvrir dans l'UI") } func testLesTroisMessagesSontDistincts() {