Skip to content

Commit 613b4a1

Browse files
committed
Add new shortcut : Custom Regen Cycle
1 parent 5d44f08 commit 613b4a1

3 files changed

Lines changed: 79 additions & 30 deletions

File tree

‎app/src/main/java/com/mg4/control/service/MG4ControlService.kt‎

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class MG4ControlService : Service() {
6060
ShortcutAction.DROWSINESS_SEN_CYCLE, ShortcutAction.HVAC_TOGGLE,
6161
ShortcutAction.HVAC_TEMP_UP, ShortcutAction.HVAC_TEMP_DOWN,
6262
ShortcutAction.HVAC_FAN_UP, ShortcutAction.HVAC_FAN_DOWN,
63+
ShortcutAction.ADAS_CYCLE,
6364
ShortcutAction.REGEN_CYCLE, ShortcutAction.SEAT_HEAT_LEFT_CYCLE,
6465
ShortcutAction.SEAT_HEAT_RIGHT_CYCLE, ShortcutAction.STEERING_HEAT_TOGGLE,
6566
ShortcutAction.DEFROST_FRONT_TOGGLE, ShortcutAction.DEFROST_REAR_TOGGLE,
@@ -506,6 +507,48 @@ class MG4ControlService : Service() {
506507
* ⚠️ Bloquant (lectures binder, et ~1 s pour l'ESC qui confirme son état avant d'agir) :
507508
* à n'appeler que depuis un contexte IO.
508509
*/
510+
/**
511+
* Index ADAS courant — 0=Off, 1=Lim. manuel, 2=Lim. auto, 3=ACC, 4=ICA/TJA — ou `null` si le
512+
* véhicule ne répond pas. Mêmes indices et même conversion que l'écran ADAS, sans quoi le
513+
* raccourci et l'écran ne parleraient pas de la même chose.
514+
*/
515+
private fun adasIndexCourant(): Int? {
516+
if (!FirmwareInfo.isVsmBased()) {
517+
// SWI133 : l'index EST la valeur de la propriété VPM.
518+
val v = MG4Hardware.getMixedIntelligentDrive()
519+
return if (v < 0) null else v
520+
}
521+
val accTja = MG4Hardware.getAccTjaMode()
522+
if (accTja < 0) return null
523+
// Le limiteur prime dans l'affichage : il est exclusif du mode ACC/TJA côté véhicule.
524+
val sas = MG4Hardware.getSpeedLimiterMode()
525+
return when {
526+
sas == MG4Hardware.SasMode.MANUEL -> 1
527+
sas == MG4Hardware.SasMode.INTELLIGENT -> 2
528+
accTja == Swi68Mode.ACC -> 3
529+
accTja == Swi68Mode.TJA -> 4
530+
else -> 0
531+
}
532+
}
533+
534+
/**
535+
* Écrit un index ADAS. Sur VSM, mode ACC/TJA et limiteur sont deux réglages EXCLUSIFS : il
536+
* faut poser les deux à chaque fois, sinon l'ancien resterait actif à côté du nouveau.
537+
*/
538+
private fun ecrireModeAdas(index: Int) {
539+
if (!FirmwareInfo.isVsmBased()) {
540+
MG4Hardware.setMixedIntelligentDrive(index)
541+
return
542+
}
543+
when (index) {
544+
1 -> { MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.MANUEL); MG4Hardware.setAccTjaMode(Swi68Mode.OFF) }
545+
2 -> { MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.INTELLIGENT); MG4Hardware.setAccTjaMode(Swi68Mode.OFF) }
546+
3 -> { MG4Hardware.setAccTjaMode(Swi68Mode.ACC); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
547+
4 -> { MG4Hardware.setAccTjaMode(Swi68Mode.TJA); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
548+
else -> { MG4Hardware.setAccTjaMode(Swi68Mode.OFF); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
549+
}
550+
}
551+
509552
private fun executeVehicleAction(action: ShortcutAction) {
510553
when (action) {
511554
ShortcutAction.ESC_TOGGLE -> {
@@ -589,6 +632,34 @@ class MG4ControlService : Service() {
589632
MG4Hardware.setRegenLevel(suivant)
590633
}
591634

635+
ShortcutAction.ADAS_CYCLE -> {
636+
val prefs = getSharedPreferences(PREFS_SHORTCUTS, MODE_PRIVATE)
637+
// Mêmes valeurs par défaut que l'écran de configuration (Off / ACC). Elles y
638+
// étaient inversées : l'écran montrait A=Off et B=ACC, le service faisait
639+
// l'inverse tant que l'utilisateur n'avait touché aucun bouton.
640+
val modeA = prefs.getInt("shortcut_adas_mode_a", 0)
641+
val modeB = prefs.getInt("shortcut_adas_mode_b", 3)
642+
if (modeA == modeB) {
643+
AppLogger.w(TAG, "SHORTCUT ADAS — les deux modes sont identiques ($modeA), " +
644+
"rien à alterner")
645+
return
646+
}
647+
// Lecture RÉELLE du mode courant, comme pour la clim ou les sièges chauffants.
648+
// L'état mémorisé qui servait jusqu'ici repartait de zéro à chaque démarrage du
649+
// service et ignorait l'écran d'origine : deux appuis de suite pouvaient
650+
// réécrire le même mode, ce qui se voit comme un raccourci sans effet.
651+
val actuel = adasIndexCourant()
652+
if (actuel == null) {
653+
AppLogger.w(TAG, "SHORTCUT ADAS — mode illisible, aucune action")
654+
return
655+
}
656+
// Sur n'importe quel mode qui n'est ni A ni B (l'utilisateur est passé par
657+
// l'écran d'origine), on entre par A plutôt que de ne rien faire.
658+
val cible = if (actuel == modeA) modeB else modeA
659+
AppLogger.i(TAG, "SHORTCUT ADAS : index $actuel → $cible (A=$modeA, B=$modeB)")
660+
ecrireModeAdas(cible)
661+
}
662+
592663
ShortcutAction.SEAT_HEAT_LEFT_CYCLE, ShortcutAction.SEAT_HEAT_RIGHT_CYCLE -> {
593664
val gauche = action == ShortcutAction.SEAT_HEAT_LEFT_CYCLE
594665
// Lectures NULLABLES obligatoires : getSeatHeatLeft() rend 0 aussi bien pour
@@ -789,26 +860,6 @@ class MG4ControlService : Service() {
789860
ShortcutAction.SOUND_WARNING -> MG4Hardware.setSoundWarning(newState)
790861
ShortcutAction.OVERSPEED_ALARM -> MG4Hardware.setOverspeedAlarm(newState)
791862
ShortcutAction.SPEED_LIMIT_TONE -> MG4Hardware.setSpeedLimitTone(newState)
792-
ShortcutAction.ADAS_CYCLE -> {
793-
// Tous les firmwares connus stockent des indices 0-4 (Off/Lim.Manuel/Lim.Auto/ACC/ICA|TJA)
794-
val modeA = prefs.getInt("shortcut_adas_mode_a", 3)
795-
val modeB = prefs.getInt("shortcut_adas_mode_b", 0)
796-
val mode = if (newState) modeA else modeB
797-
if (FirmwareInfo.isVsmBased()) {
798-
// VSM (SWI68/69/131/132/165) : index → mode ACC/TJA (setAccTjaMode)
799-
// + limiteur de vitesse (setSpeedLimiterMode), réglages exclusifs.
800-
when (mode) {
801-
1 -> { MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.MANUEL); MG4Hardware.setAccTjaMode(Swi68Mode.OFF) }
802-
2 -> { MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.INTELLIGENT); MG4Hardware.setAccTjaMode(Swi68Mode.OFF) }
803-
3 -> { MG4Hardware.setAccTjaMode(Swi68Mode.ACC); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
804-
4 -> { MG4Hardware.setAccTjaMode(Swi68Mode.TJA); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
805-
else -> { MG4Hardware.setAccTjaMode(Swi68Mode.OFF); MG4Hardware.setSpeedLimiterMode(MG4Hardware.SasMode.OFF) }
806-
}
807-
} else {
808-
// SWI133 : VPM direct (l'index est aussi la valeur mixedIntelligentDrive)
809-
MG4Hardware.setMixedIntelligentDrive(mode)
810-
}
811-
}
812863
ShortcutAction.ENERGY_SAVING_TOGGLE -> MG4Hardware.setEnergySavingMode(newState)
813864
ShortcutAction.TSR_TOGGLE -> MG4Hardware.setTsrMode(newState)
814865
ShortcutAction.OPEN_APP -> {

‎app/src/main/java/com/mg4/control/ui/ShortcutsFragment.kt‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,7 @@ class ShortcutsFragment : Fragment() {
750750
view.findViewById<MaterialButton>(R.id.btn_sc_sub_regen) to view.findViewById<ViewGroup>(R.id.page_sc_regen),
751751
view.findViewById<MaterialButton>(R.id.btn_sc_sub_list) to view.findViewById<ViewGroup>(R.id.page_sc_list)
752752
)
753-
val pageClassique = tabs[0].second
754-
val pageCycle = tabs[4].second
755-
val btnSubList = tabs[5].first
753+
val pageCycle = tabs[4].second
756754

757755
// Chaque page de réglage est adossée à une fonction : elle n'existe que si un bouton la
758756
// déclenche. C'est la règle qui manquait aux deux premières, dont les réglages ne
@@ -805,12 +803,10 @@ class ShortcutsFragment : Fragment() {
805803
btn.setTextColor(if (on) railOn else textOff)
806804
btn.strokeColor = ColorStateList.valueOf(if (on) railOn else border)
807805
}
808-
// La liste appartient au contexte avancé : sur la page des emplacements
809-
// classiques elle encombrerait le rail sans rien vouloir dire. Les pages de réglage,
810-
// elles, ne sont soumises à aucun contexte — on y arrive depuis l'un ou l'autre
811-
// onglet, et les masquer rendrait le réglage introuvable pour qui ne va jamais dans
812-
// l'avancé.
813-
if (pageClassique.visibility == View.VISIBLE) btnSubList.visibility = View.GONE
806+
// Aucune entrée n'est masquée par le CONTEXTE : la liste reste atteignable depuis
807+
// n'importe quel onglet, et les pages de réglage ne dépendent que de l'attribution
808+
// de leur fonction. La règle de contexte qui cachait la liste hors de l'onglet
809+
// avancé obligeait à un détour pour la consulter.
814810
}
815811

816812
tabs.forEach { (btn, page) ->

‎app/src/main/res/layout/fragment_shortcuts.xml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,11 @@
142142
app:strokeColor="@color/dash_border"
143143
app:cornerRadius="8dp" />
144144

145+
<!-- Pas de retrait, contrairement aux trois réglages : la liste n'est pas
146+
conditionnelle, c'est une destination permanente au même rang que les deux
147+
premiers onglets. -->
145148
<com.google.android.material.button.MaterialButton
146149
android:id="@+id/btn_sc_sub_list"
147-
android:layout_marginStart="16dp"
148150
android:layout_width="match_parent"
149151
android:layout_height="64dp"
150152
android:layout_marginBottom="8dp"

0 commit comments

Comments
 (0)