Calculer Les Tâches À Faire Sur Une Voiture
Fleetingcomment ç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
actionsqui 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#+TBLFMassocié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 forme1y,6m,4m,2y, etc.). L’un, l’autre ou les deux peuvent être vides : siseuilkmest vide, on ne tient compte que du temps ; siseuiltmpest 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 FAIREsi périmé,oksinon), - le nombre de kilomètres restant avant le prochain seuil km (
Nonesi 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 à :
- ajouter une ligne en haut du tableau
relevesavec la date du jour, le kilométrage, et les actions faites/vérifiées ; - recalculer les formules du tableau (
C-u C-c C-csur la ligne#+TBLFM) pour mettre à jourstamp,Diff Km, etc. ; - évaluer le
#+CALLpour régénérer le tableau de résultats ; - 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
4yau lieu de1yd’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 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 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 |