Konubinix' opinionated web of thoughts

Calculer Les Tâches À Faire Sur Une Voiture

Fleeting

comment ça marche

Cette note est une “bibliothèque” : elle définit un bloc de calcul python réutilisable, plus deux tableaux d’exemple (releves et seuils) qui servent surtout à documenter le format attendu. Le vrai usage se fait dans les notes par-voiture, qui appellent ce bloc avec leurs propres données. Voir exemple de suivi d’entretien d’une voiture pour un cas d’usage complet.

l’idée générale

Pour entretenir une voiture, il faut suivre tout un tas d’actions périodiques : pression des pneus, vidange, révision, remplacement de filtres, contrôle de liquide de frein, etc. Chacune a sa propre périodicité, exprimée soit en kilomètres, soit en durée, soit (le plus souvent) au premier des deux atteint.

Plutôt que de tenir un calendrier manuel par action, je tiens un journal de relevés. À chaque relevé, je note la date, le kilométrage, et la liste des actions effectuées (ou simplement vérifiées) ce jour-là. À partir de ce journal et des seuils, le bloc python recalcule pour chaque action si elle est en retard (“A FAIRE”) ou encore valide (“ok”).

les deux tableaux d’entrée

releves
le journal. Une ligne par observation, du plus récent au plus ancien. Les colonnes essentielles sont la date, le kilométrage, et la colonne actions qui liste, séparées par des virgules, les actions constatées ce jour-là. Les autres colonnes (stamp, Diff Km, Nb jours, Km/J) sont calculées automatiquement par les #+TBLFM associées et servent à se faire une idée de l’usage.
seuils
la table des règles. Une ligne par action, avec un seuil en kilomètres (seuilkm) et/ou un seuil en durée (seuiltmp, exprimé sous la forme 1y, 6m, 4m, 2y, etc.). L’un, l’autre ou les deux peuvent être vides : si seuilkm est vide, on ne tient compte que du temps ; si seuiltmp est vide, on ne tient compte que des kilomètres.

le bloc calcul

Le bloc nommé calcul prend ces deux tableaux en paramètre et produit, pour chaque action de seuils, une ligne avec :

  • le statut (A FAIRE si périmé, ok sinon),
  • le nombre de kilomètres restant avant le prochain seuil km (None si pas applicable),
  • le nombre de jours restant avant le prochain seuil temps (négatif si déjà dépassé),
  • le commentaire de la dernière colonne de seuils.

Le résultat est trié par statut, donc les “A FAIRE” remontent en haut.

comment réutiliser ça pour une voiture

Dans une note dédiée à une voiture, on définit ses propres tableaux nommés releves et seuils, puis on appelle le bloc partagé via #+CALL :

#+CALL: calculer_les_taches_a_faire_sur_une_voiture.org:calcul(seuils=seuils, releves=releves)

Org-babel résout seuils et releves dans le contexte local de la note (les tableaux locaux), et exécute le bloc calcul défini ici. Le tableau de résultats est inséré sous une ligne #+RESULTS:.

Concrètement, mettre à jour l’état d’entretien d’une voiture revient à :

  1. ajouter une ligne en haut du tableau releves avec la date du jour, le kilométrage, et les actions faites/vérifiées ;
  2. recalculer les formules du tableau (C-u C-c C-c sur la ligne #+TBLFM) pour mettre à jour stamp, Diff Km, etc. ;
  3. évaluer le #+CALL pour régénérer le tableau de résultats ;
  4. lire ce qui est en “A FAIRE” et planifier les prochaines interventions.

le rôle des seuils par voiture

Les seuils ne sont pas universels : ils dépendent du modèle, du carnet d’entretien constructeur, et des choix qu’on assume. Par exemple :

  • une thermique aura typiquement une longue liste : vidange, filtres à huile/air, bougies, courroie d’accessoires, etc. ;
  • une électrique aura une liste très réduite : pas de vidange ni de bougies, et certains contrôles fluides peuvent être espacés (par exemple 4y au lieu de 1y d’origine, si on l’assume après vérification).

Autrement dit, le tableau seuils est l’endroit où l’on encode la politique d’entretien qu’on a décidé de suivre pour cette voiture-ci, en partant du carnet constructeur puis en adaptant.

ce qu’on gagne

  • une seule source pour la logique de calcul : si je change la façon dont les seuils sont interprétés, ça profite à toutes les voitures ;
  • un journal qui sert aussi d’historique d’entretien (date, kilométrage, consommation par jour, actions effectuées) ;
  • une vision rapide de ce qui est en retard, sans rien à mémoriser ni à planifier soi-même.

tableaux de référence

Les tableaux ci-dessous servent surtout d’exemple et de gabarit pour copier dans une nouvelle note de voiture. Le bloc calcul juste après est celui qu’on appelle depuis les autres notes.

Date stamp Km Diff Km Nb jours Km/J Km restant Tps restant Km/J restant actions
[2018-06-12 Tue 20:00] 1528826400.0 0 0/0 PressionPneus, UsurePneus, Feux, NiveauBattery, ControlerHuileDA, RevisionUniqueEurope, RemplacementFiltreHabitacle, RemplacementFiltreHuile, VidangeHuile, ControlerLiquideFrein, ControlerLiquideRefroidissement, RemplacementFiltreAir, RemplacementLiquideFrein, RemplacementLiquideRefroidissement, RemplacementCourroieAccessoireEtGalet, CtrlOeilNuPlaquettesFrein, RemplacementLiquideRefroidissement, RemplacementBougiesAllumage, CtrlDepoussierageGarnitureFreinTambour, ControlerHuile, CtrlLigneEchappement, VerifNivHuileBoiteVitesses, VerifOuRemplacementAmortisseurs, VerifAirbag, ChangerEssuieGlaces

action seuilkm seuiltmp
PressionPneus 1m Ou avant tout déplacement important
UsurePneus 4m
Feux 6m arrière, position, croisement, route, plaque arrière, clignotants avant, clignotants arrière, clignotants coté, arrière haut
NiveauBattery 6m
ControlerHuileDA 15000 1y
RevisionUniqueEurope 20000 1y
RemplacementFiltreHabitacle 20000 1y
RemplacementFiltreHuile 20000 1y
VidangeHuile 20000 1y ou à chaque intervention importante sur le moteur, avec remplacement du filtre à huile
ControlerLiquideFrein 45000 1y
ControlerLiquideRefroidissement 1y
RemplacementFiltreAir 60000 4y
RemplacementLiquideFrein 120000 4y
RemplacementLiquideRefroidissement 120000 5y
RemplacementCourroieAccessoireEtGalet 120000 6y
CtrlOeilNuPlaquettesFrein 10000 1y
RemplacementLiquideRefroidissement 6y préconisé tous les 6 ans (liquide bleu/vert) ou 10 ans (rouge/orange)
RemplacementBougiesAllumage 60000
CtrlDepoussierageGarnitureFreinTambour 80000
ControlerHuile 1000 ou avant chaque parcours important
CtrlLigneEchappement 30000 2y
VerifNivHuileBoiteVitesses 30000 2y
VerifOuRemplacementAmortisseurs 100000
VerifAirbag 100000
ChangerEssuieGlaces 3y

import pandas as pd
from dateutil.relativedelta import relativedelta
import re
from datetime import datetime

DURATION_THRESHOLD_REGEX = re.compile(r'^((?P<years>\d+)y)?((?P<months>\d+)m)?$')

def parse_duration_threshold(duration_threshold_str):
    """Convert a duration threshold like '1y' or '6m' into a relativedelta."""
    match = DURATION_THRESHOLD_REGEX.match(duration_threshold_str)
    if not match:
        return None
    return relativedelta(**{
        unit: int(quantity)
        for unit, quantity in match.groupdict().items()
        if quantity
    })

def sort_key_by_status(result_row):
    """Sort 'A FAIRE' before 'ok' (alphabetical order on the status column)."""
    return result_row[1]

log_df = pd.DataFrame(releves[1:], columns=releves[0])
log_df["date"] = pd.to_datetime(log_df.stamp, unit="s")
current_km = log_df["Km"].iloc[0]

occurrences_df = (
    log_df.assign(action=log_df["actions"].str.split(", "))
          .explode("action")
          .rename(columns={"Km": "km"})
          [["km", "date", "action"]]
)
latest_per_action = occurrences_df.drop_duplicates("action").set_index("action")

now = datetime.now()
results = []
for action, km_threshold, duration_threshold, comment in seuils[1:]:
    latest = latest_per_action.loc[action]
    remaining_km = (
        km_threshold - (current_km - latest["km"])
        if km_threshold else None
    )
    duration = parse_duration_threshold(duration_threshold)
    next_due_date = latest["date"] + duration if duration else None
    km_overdue = remaining_km is not None and remaining_km < 0
    time_overdue = next_due_date is not None and next_due_date < now
    status = "A FAIRE" if (km_overdue or time_overdue) else "ok"
    results.append([
        action,
        status,
        f"{remaining_km} km",
        f"{(next_due_date - now).days} days" if next_due_date else None,
        comment,
    ])
return sorted(results, key=sort_key_by_status)
PressionPneus A FAIRE None km -2857 days Ou avant tout déplacement important
UsurePneus A FAIRE None km -2765 days
Feux A FAIRE None km -2704 days arrière, position, croisement, route, plaque arrière, clignotants avant, clignotants arrière, clignotants coté, arrière haut
NiveauBattery A FAIRE None km -2704 days
ControlerHuileDA A FAIRE 15000 km -2522 days
RevisionUniqueEurope A FAIRE 20000 km -2522 days
RemplacementFiltreHabitacle A FAIRE 20000 km -2522 days
RemplacementFiltreHuile A FAIRE 20000 km -2522 days
VidangeHuile A FAIRE 20000 km -2522 days ou à chaque intervention importante sur le moteur, avec remplacement du filtre à huile
ControlerLiquideFrein A FAIRE 45000 km -2522 days
ControlerLiquideRefroidissement A FAIRE None km -2522 days
RemplacementFiltreAir A FAIRE 60000 km -1426 days
RemplacementLiquideFrein A FAIRE 120000 km -1426 days
RemplacementLiquideRefroidissement A FAIRE None km -695 days préconisé tous les 6 ans (liquide bleu/vert) ou 10 ans (rouge/orange)
RemplacementCourroieAccessoireEtGalet A FAIRE 120000 km -695 days
CtrlOeilNuPlaquettesFrein A FAIRE 10000 km -2522 days
CtrlLigneEchappement A FAIRE 30000 km -2156 days
VerifNivHuileBoiteVitesses A FAIRE 30000 km -2156 days
ChangerEssuieGlaces A FAIRE None km -1791 days
RemplacementBougiesAllumage ok 60000 km None
CtrlDepoussierageGarnitureFreinTambour ok 80000 km None
ControlerHuile ok 1000 km None ou avant chaque parcours important
VerifOuRemplacementAmortisseurs ok 100000 km None
VerifAirbag ok 100000 km None

Notes pointant ici