@@ -4928,22 +4928,38 @@ object MG4Hardware {
49284928 /* *
49294929 * État clim sur A9, via CarHvacClient.
49304930 *
4931- * ⚠️ Deux inconnues à mesurer sur véhicule (l'API n'expose pas de bornes) :
4932- * • la plage de température et le niveau de ventilation max — valeurs par défaut prudentes ;
4933- * • l'encodage de `getAirCirculationStatus()` : on suppose la même convention que l'old-SDK
4934- * (0=intérieur, 1=extérieur, 2=auto), à confirmer par la sonde Diagnostic.
4931+ * ⚠️ Les bornes sont ÉCRITES EN DUR, contrairement à l'ancien SDK qui les demande au
4932+ * véhicule : `ICarHvacService` n'expose aucun `getMinTemp` / `getMaxTemp` / niveau de
4933+ * ventilation maximal — vérifié dans le service décompilé. Il n'y a donc rien à lire.
4934+ *
4935+ * Les valeurs ci-dessous ne sont plus des estimations prudentes : elles ont été MESURÉES sur
4936+ * SWI132 (rapports de diagnostic du 2026-08-25, réglages poussés aux extrêmes) puis
4937+ * recoupées avec les constantes du launcher d'origine — variante EH32 :
4938+ * `AUTO_TEMP_MIN_LEVEL=0x12` (18), `AUTO_TEMP_MAX_LEVEL=0x20` (32),
4939+ * `AUTO_FANS_MIN_LEVEL=1`, `AUTO_FANS_MAX_LEVEL=0xb` (11).
4940+ *
4941+ * L'écart entre 18–32 (le launcher) et 17–33 (la mesure) n'est pas une contradiction : 18–32
4942+ * est la plage NUMÉRIQUE, tandis que 17 et 33 sont les positions LO et HI qui l'encadrent.
4943+ * On garde donc 17–33, ce que le véhicule accepte réellement.
4944+ *
4945+ * ⚠️ Le launcher connaît une seconde variante (ventilation 1–8, température 16–28). Si un
4946+ * jour un A9 refuse ces bornes, c'est la première piste — et il faudra alors trouver comment
4947+ * le véhicule déclare sa variante, le SDK ne le disant pas.
4948+ *
4949+ * Reste supposé : l'encodage de `getAirCirculationStatus()` — même convention que l'old-SDK
4950+ * (0=intérieur, 1=extérieur, 2=auto), à confirmer par la sonde Diagnostic.
49354951 */
49364952 private fun getClimateStateA9 (): ClimateState ? {
49374953 if (hvacA9() == null ) return null
49384954 val temp = (a9Get(" getDriverTemperature" ) as ? Float )?.takeIf { ! it.isNaN() && it > 0f }?.toInt()
49394955 return ClimateState (
49404956 powerOn = a9Get(" getHvacPowerStatus" ) as ? Boolean ,
49414957 tempC = temp,
4942- tempMin = 16 ,
4943- tempMax = 32 ,
4958+ tempMin = 17 , // LO, mesuré
4959+ tempMax = 33 , // HI, mesuré
49444960 fanLevel = (a9Get(" getFanSpeed" ) as ? Int )?.takeIf { it >= 0 },
4945- fanMin = 1 ,
4946- fanMax = 10 ,
4961+ fanMin = 1 , // 0 = éteint, ce qui relève de l'interrupteur, pas du cran
4962+ fanMax = 11 , // mesuré, et identique à AUTO_FANS_MAX_LEVEL du launcher
49474963 acOn = a9Get(" getACStatus" ) as ? Boolean ,
49484964 autoOn = a9Get(" getAutoStatus" ) as ? Boolean ,
49494965 loopMode = (a9Get(" getAirCirculationStatus" ) as ? Int )?.takeIf { it >= 0 },
0 commit comments