Skip to content

Commit 8c8abf0

Browse files
committed
improvement of electric window feature
1 parent 4f77631 commit 8c8abf0

9 files changed

Lines changed: 27 additions & 82 deletions

File tree

‎app/src/main/java/com/mg4/control/hardware/MG4Hardware.kt‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,6 @@ object MG4Hardware {
291291
vehicleConditionCallbacks.remove(callback)
292292
}
293293

294-
/**
295-
* Dernier état d'allumage reçu (CarIgnitionItem), -1 si aucun. Les écouteurs ne sont prévenus
296-
* qu'aux CHANGEMENTS : un abonné arrivé après le RUN du démarrage doit lire l'état ici.
297-
*/
298-
fun lastVehicleIgnitionState(): Int = sLastVcmIgnitionState
299-
300294
/**
301295
* Lit l'état d'allumage courant via CarPropertyManager.
302296
* Retourne -1 si CPM non prêt, 0 si propriété non supportée.

‎app/src/main/java/com/mg4/control/hardware/PowerWindows.kt‎

Lines changed: 18 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ import java.util.concurrent.ConcurrentHashMap
2929
* Pas de verrou de vitesse ([VehicleWriteGate]) : c'est du confort, et les interrupteurs
3030
* physiques restent utilisables en roulant.
3131
*
32-
* Vitres sans capteur : position estimée ([WindowEstimator]) à partir de leur calibration,
33-
* remise à « inconnue » à chaque démarrage de la voiture — sauf si la fermeture automatique en
34-
* quittant la voiture ([WindowAutoClose]) est allée au bout : les vitres partent alors fermées.
32+
* Vitres sans capteur : position estimée ([WindowEstimator]) à partir de leur calibration, supposée
33+
* fermée (0 %) à chaque démarrage de l'app.
3534
*
3635
* Sondes (tag [TAG]) : liste des propriétés déclarées, lectures par zone, chaque commande avec
3736
* son résultat, chaque changement de valeur reçu du véhicule avec le délai depuis la dernière
@@ -103,61 +102,21 @@ object PowerWindows {
103102
private var autoCloseOk = true
104103
private var autoCloseDone: ((Boolean) -> Unit)? = null
105104

106-
/** Marqueur « toutes les vitres fermées par la fermeture automatique, sans commande depuis ». */
107-
private const val KEY_CLOSED_MARKER = "win_closed_marker"
108105

109106
data class Snapshot(
110107
val cpmReady: Boolean,
111108
val subscribed: Boolean,
112109
val values: Map<PowerWindow, Float?>,
113-
/** Vitres calibrées → position estimée (null = inconnue jusqu'à la prochaine course complète). */
110+
/** Vitres calibrées → position estimée (null = inconnue, après une commande de valeur inconnue). */
114111
val estimates: Map<PowerWindow, Float?>,
115112
val lastCommand: String,
116113
)
117114

118-
init {
119-
MG4Hardware.registerVehicleConditionListener { state ->
120-
if (state == MG4Hardware.CarIgnitionItem.RUN) worker.post {
121-
val firstLoad = !estimatorsLoaded
122-
loadEstimators()
123-
// Premier chargement pendant ce RUN : il vient d'appliquer (et consommer) le marqueur.
124-
if (!firstLoad) applyStartupPosition("démarrage", consume = true)
125-
}
126-
}
127-
}
128-
129-
/** Force l'initialisation (écouteur de démarrage) sans attendre l'ouverture de l'onglet. */
115+
/** Charge les calibrations sans attendre l'ouverture de l'onglet. */
130116
fun prepare() {
131117
worker.post { loadEstimators() }
132118
}
133119

134-
/**
135-
* Sur [worker]. Position des vitres estimées au démarrage : fermées si la fermeture automatique
136-
* est active ET que sa dernière séquence est allée au bout sans commande depuis ; sinon
137-
* inconnues (un interrupteur physique a pu servir), une course complète les recalera.
138-
*
139-
* Le marqueur ne vaut que pour UN démarrage : il est consommé au démarrage réel de la voiture
140-
* ([consume]), pas quand le processus se charge voiture éteinte — sans quoi le RUN qui suit
141-
* ne le trouverait plus et remettrait les positions à inconnues.
142-
*/
143-
private fun applyStartupPosition(origin: String, consume: Boolean) {
144-
if (estimators.isEmpty()) return
145-
val context = MG4Hardware.appContext() ?: return
146-
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
147-
val closed = WindowAutoClose.isEnabled(context) && prefs.getBoolean(KEY_CLOSED_MARKER, false)
148-
if (closed && consume) prefs.edit { remove(KEY_CLOSED_MARKER) }
149-
estimators.values.forEach { if (closed) it.setClosed() else it.reset() }
150-
AppLogger.i(TAG, "$origin : positions estimées " +
151-
if (closed) "= fermées (fermeture automatique complète)" else "remises à inconnues")
152-
}
153-
154-
/** Une commande de l'app après la fermeture automatique : on ne peut plus supposer les vitres fermées. */
155-
private fun clearClosedMarker() {
156-
val context = MG4Hardware.appContext() ?: return
157-
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
158-
if (prefs.getBoolean(KEY_CLOSED_MARKER, false)) prefs.edit { remove(KEY_CLOSED_MARKER) }
159-
}
160-
161120
// ── Calibration ─────────────────────────────────────────────────────────
162121

163122
private fun calKey(window: PowerWindow, part: String) = "win_cal_${window.name.lowercase(Locale.ROOT)}_$part"
@@ -180,16 +139,21 @@ object PowerWindows {
180139
worker.post { estimators[window] = WindowEstimator(cal).apply { setClosed() } }
181140
}
182141

183-
/** Sur [worker] : charge une fois les calibrations enregistrées. */
142+
/**
143+
* Sur [worker] : charge une fois les calibrations enregistrées. Chaque vitre calibrée part fermée
144+
* (0 %) : cas le plus courant, sans exiger de course complète au démarrage de l'app.
145+
*/
184146
private fun loadEstimators() {
185147
if (estimatorsLoaded) return
186148
val context = MG4Hardware.appContext() ?: return
187-
PowerWindow.entries.forEach { w -> calibration(context, w)?.let { estimators[w] = WindowEstimator(it) } }
149+
PowerWindow.entries.forEach { w ->
150+
val cal = calibration(context, w) ?: return@forEach
151+
estimators[w] = WindowEstimator(cal).apply { setClosed() }
152+
}
153+
if (estimators.isNotEmpty()) {
154+
AppLogger.i(TAG, "démarrage de l'app : ${estimators.keys.joinToString { it.shortName }} supposées fermées (0 %)")
155+
}
188156
estimatorsLoaded = true
189-
// Processus (re)lancé : même règle qu'au démarrage de la voiture. L'écouteur ne voit que les
190-
// changements d'allumage : voiture déjà en marche = ce chargement EST le démarrage.
191-
applyStartupPosition("chargement",
192-
consume = MG4Hardware.lastVehicleIgnitionState() == MG4Hardware.CarIgnitionItem.RUN)
193157
}
194158

195159
/** Sur [worker] : suit la commande envoyée pour estimer la position ; journalise en fin de mouvement. */
@@ -201,9 +165,8 @@ object PowerWindows {
201165
when {
202166
direction != null -> estimator.start(direction, now)
203167
value == WindowCommand.STOP -> {
204-
val before = estimator.current(now)
205168
estimator.stop(now)
206-
AppLogger.i(TAG, "estimation ${window.shortName} : ${pct(before)} (fin de mouvement)")
169+
AppLogger.i(TAG, "estimation ${window.shortName} : ${pct(estimator.current(now))} (fin de mouvement)")
207170
}
208171
else -> {
209172
estimator.reset()
@@ -223,7 +186,6 @@ object PowerWindows {
223186
*/
224187
fun shortPress(window: PowerWindow, direction: Direction) {
225188
val now = SystemClock.elapsedRealtime()
226-
clearClosedMarker()
227189
worker.post {
228190
if (!window.hasNativeAuto) {
229191
if (!endRepeat(window, "appui court")) startEmulatedCourse(window, direction, "appui court")
@@ -241,7 +203,6 @@ object PowerWindows {
241203

242204
/** Tout ouvrir / tout fermer : toujours la course automatique, jamais le stop. */
243205
fun autoAll(direction: Direction) {
244-
clearClosedMarker()
245206
val origin = "tout ${if (direction == Direction.UP) "fermer" else "ouvrir"}"
246207
worker.post { PowerWindow.entries.forEach { startAuto(it, direction, origin) } }
247208
}
@@ -251,7 +212,6 @@ object PowerWindows {
251212
* pour atteindre la butée même si une ancienne calibration était trop courte.
252213
*/
253214
fun closeForCalibration(window: PowerWindow) {
254-
clearClosedMarker()
255215
lastAutoMs.remove(window)
256216
worker.post { startAuto(window, Direction.UP, "calibration", minEmulatedMs = WindowCommand.EMULATED_COURSE_MS) }
257217
}
@@ -280,7 +240,6 @@ object PowerWindows {
280240

281241
/** Appui long : commande manuelle répétée jusqu'à [stopHold], comme un doigt sur l'interrupteur. */
282242
fun startHold(window: PowerWindow, direction: Direction) {
283-
clearClosedMarker()
284243
lastAutoMs.remove(window)
285244
worker.post {
286245
startRepeat(window, WindowCommand.manual(direction), WindowCommand.HOLD_MAX_MS,
@@ -305,7 +264,6 @@ object PowerWindows {
305264
/** Test brut de l'onglet Diagnostic : n'importe quelle valeur de 0 à 7, pour décoder l'échelle. */
306265
fun sendRaw(window: PowerWindow, value: Int) {
307266
if (!WindowCommand.isValid(value)) return
308-
clearClosedMarker()
309267
lastAutoMs.remove(window)
310268
worker.post {
311269
endRepeat(window, "test brut")
@@ -357,12 +315,10 @@ object PowerWindows {
357315
/**
358316
* Ferme toutes les vitres (déclenchée par [WindowAutoClose]) : course native pour le conducteur,
359317
* course émulée pour les autres. [onDone] (fil principal) reçoit vrai si toutes les courses
360-
* émulées sont allées au bout sans échec ni interruption ; alors seulement le marqueur « vitres
361-
* fermées » est posé pour le prochain démarrage.
318+
* émulées sont allées au bout sans échec ni interruption.
362319
*/
363320
fun closeAllAutomatically(onDone: (Boolean) -> Unit) {
364321
worker.post {
365-
clearClosedMarker()
366322
loadEstimators()
367323
autoClosePending.clear()
368324
autoCloseOk = true
@@ -401,11 +357,7 @@ object PowerWindows {
401357
val ok = autoCloseOk
402358
val done = autoCloseDone ?: return
403359
autoCloseDone = null
404-
MG4Hardware.appContext()?.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)?.edit {
405-
if (ok) putBoolean(KEY_CLOSED_MARKER, true) else remove(KEY_CLOSED_MARKER)
406-
}
407-
AppLogger.i(TAG, "fermeture auto terminée : " +
408-
if (ok) "complète → vitres considérées fermées au prochain démarrage" else "incomplète → positions inconnues au prochain démarrage")
360+
AppLogger.i(TAG, "fermeture auto terminée : ${if (ok) "complète" else "incomplète"}")
409361
main.post { done(ok) }
410362
}
411363

‎app/src/main/java/com/mg4/control/model/WindowEstimator.kt‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ data class WindowCalibration(val downMs: Long, val upMs: Long) {
2626
* Position estimée d'une vitre sans capteur, en % d'ouverture (0 = fermée, 100 = ouverte).
2727
*
2828
* Seules les commandes de l'app sont chronométrées : un interrupteur physique fausse l'estimation
29-
* sans que l'app le voie. D'où deux règles — la position part inconnue (et le redevient à chaque
30-
* démarrage de la voiture), et elle ne devient connue qu'après une course complète, qui amène la
31-
* vitre en butée quel que soit son point de départ. À afficher comme une estimation, jamais à
32-
* utiliser pour une décision de sécurité.
29+
* sans que l'app le voie ; une course complète la recale, la vitre arrivant en butée quel que soit
30+
* son point de départ. Au démarrage de l'app, la vitre est supposée fermée. À afficher comme une
31+
* estimation, jamais à utiliser pour une décision de sécurité.
3332
*/
3433
class WindowEstimator(val calibration: WindowCalibration) {
3534

‎app/src/main/res/values-de/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
<string name="win_all_open">Alle öffnen</string>
513513
<string name="win_auto_title">Automatisches Schließen</string>
514514
<string name="win_auto_label">Fenster beim Verlassen des Autos schließen</string>
515-
<string name="win_auto_desc">Auto in P, sobald nach den Bedingungen unten scharf: Verlässt das Auto den READY-Modus (Fahrertür geöffnet oder Auto ausgeschaltet), schließen alle Fenster nach der gewählten Verzögerung. Eine Rückkehr in READY davor bricht ab. Wird das Schließen abgeschlossen, gelten die Fenster beim nächsten Start als geschlossen.</string>
515+
<string name="win_auto_desc">Auto in P, sobald nach den Bedingungen unten scharf: Verlässt das Auto den READY-Modus (Fahrertür geöffnet oder Auto ausgeschaltet), schließen alle Fenster nach der gewählten Verzögerung. Eine Rückkehr in READY davor bricht ab.</string>
516516
<string name="win_auto_warning">Kein Einklemmschutz an den Fenstern außer dem Fahrerfenster: beim Aussteigen niemand in der Nähe der Fenster.</string>
517517
<string name="win_auto_arming_title">Scharfschalten: nach der Fahrt</string>
518518
<string name="win_auto_speed_label">Erreichte Geschwindigkeit</string>

‎app/src/main/res/values-en/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
<string name="win_all_open">Open all</string>
513513
<string name="win_auto_title">Automatic closing</string>
514514
<string name="win_auto_label">Close the windows when leaving the car</string>
515-
<string name="win_auto_desc">Car in P, once armed by the conditions below: when the car leaves READY (driver door opened or car switched off), all windows close after the chosen delay. Going back to READY before then cancels. If closing completes, the windows are considered closed at the next start.</string>
515+
<string name="win_auto_desc">Car in P, once armed by the conditions below: when the car leaves READY (driver door opened or car switched off), all windows close after the chosen delay. Going back to READY before then cancels.</string>
516516
<string name="win_auto_warning">No anti-pinch protection on windows other than the driver\'s: nobody near the windows when leaving.</string>
517517
<string name="win_auto_arming_title">Arming: after driving</string>
518518
<string name="win_auto_speed_label">Speed reached</string>

‎app/src/main/res/values-es/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
<string name="win_all_open">Abrir todas</string>
513513
<string name="win_auto_title">Cierre automático</string>
514514
<string name="win_auto_label">Cerrar las ventanillas al salir del coche</string>
515-
<string name="win_auto_desc">Coche en P, una vez armado según las condiciones de abajo: cuando el coche sale del modo READY (puerta del conductor abierta o coche apagado), todas las ventanillas se cierran tras el retardo elegido. Volver a READY antes cancela. Si el cierre se completa, las ventanillas se consideran cerradas en el siguiente arranque.</string>
515+
<string name="win_auto_desc">Coche en P, una vez armado según las condiciones de abajo: cuando el coche sale del modo READY (puerta del conductor abierta o coche apagado), todas las ventanillas se cierran tras el retardo elegido. Volver a READY antes cancela.</string>
516516
<string name="win_auto_warning">Sin antipinzamiento en las ventanillas salvo la del conductor: nadie cerca de las ventanillas al salir.</string>
517517
<string name="win_auto_arming_title">Armado: tras circular</string>
518518
<string name="win_auto_speed_label">Velocidad alcanzada</string>

‎app/src/main/res/values-it/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
<string name="win_all_open">Apri tutti</string>
513513
<string name="win_auto_title">Chiusura automatica</string>
514514
<string name="win_auto_label">Chiudi i finestrini scendendo dall\'auto</string>
515-
<string name="win_auto_desc">Auto in P, una volta armata secondo le condizioni sotto: quando l\'auto esce dalla modalità READY (porta del conducente aperta o auto spenta), tutti i finestrini si chiudono dopo il ritardo scelto. Tornare in READY prima annulla. Se la chiusura va a termine, i finestrini sono considerati chiusi all\'avvio successivo.</string>
515+
<string name="win_auto_desc">Auto in P, una volta armata secondo le condizioni sotto: quando l\'auto esce dalla modalità READY (porta del conducente aperta o auto spenta), tutti i finestrini si chiudono dopo il ritardo scelto. Tornare in READY prima annulla.</string>
516516
<string name="win_auto_warning">Nessun antischiacciamento sui finestrini tranne quello del conducente: nessuno vicino ai finestrini quando si scende.</string>
517517
<string name="win_auto_arming_title">Armamento: dopo la guida</string>
518518
<string name="win_auto_speed_label">Velocità raggiunta</string>

‎app/src/main/res/values-pt/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
<string name="win_all_open">Abrir todos</string>
513513
<string name="win_auto_title">Fecho automático</string>
514514
<string name="win_auto_label">Fechar os vidros ao sair do carro</string>
515-
<string name="win_auto_desc">Carro em P, depois de armado pelas condições abaixo: quando o carro sai do modo READY (porta do condutor aberta ou carro desligado), todos os vidros fecham após o atraso escolhido. Voltar a READY antes cancela. Se o fecho for concluído, os vidros são considerados fechados no arranque seguinte.</string>
515+
<string name="win_auto_desc">Carro em P, depois de armado pelas condições abaixo: quando o carro sai do modo READY (porta do condutor aberta ou carro desligado), todos os vidros fecham após o atraso escolhido. Voltar a READY antes cancela.</string>
516516
<string name="win_auto_warning">Sem antientalamento nos vidros exceto o do condutor: ninguém perto dos vidros ao sair.</string>
517517
<string name="win_auto_arming_title">Armar: depois de conduzir</string>
518518
<string name="win_auto_speed_label">Velocidade atingida</string>

‎app/src/main/res/values/strings.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@
514514
<string name="win_all_open">Tout ouvrir</string>
515515
<string name="win_auto_title">Fermeture automatique</string>
516516
<string name="win_auto_label">Fermer les vitres en quittant la voiture</string>
517-
<string name="win_auto_desc">Voiture en P, une fois armée selon les conditions ci-dessous : quand la voiture sort du mode READY (ouverture de la porte conducteur ou extinction), toutes les vitres se ferment après le délai choisi. Un retour en READY avant annule. Si la fermeture va au bout, les vitres sont considérées fermées au démarrage suivant.</string>
517+
<string name="win_auto_desc">Voiture en P, une fois armée selon les conditions ci-dessous : quand la voiture sort du mode READY (ouverture de la porte conducteur ou extinction), toutes les vitres se ferment après le délai choisi. Un retour en READY avant annule.</string>
518518
<string name="win_auto_warning">Sans anti-pincement sur les vitres autres que conducteur : personne près des vitres en partant.</string>
519519
<string name="win_auto_arming_title">Armement : après avoir roulé</string>
520520
<string name="win_auto_speed_label">Vitesse atteinte</string>

0 commit comments

Comments
 (0)