Aller au contenu principal

Les formules Python

La formule Python vous permet d'écrire des traitements personnalisés qui dépassent les capacités des formules natives (arithmétique, conditionnelle, consommation, temps de fonctionnement). C'est le type de formule à utiliser pour : filtres horaires complexes (HP/HC/Pointe), alarmes comparatives (J-7, S-1), moyennes dynamiques tolérantes aux capteurs absents, ou toute logique conditionnelle avancée.

Avant d'écrire du Python

Vérifiez qu'un type natif ne suffit pas : une simple addition ou un ratio se font mieux en formule Arithmétique, un delta de compteur en formule Consommation. Les types natifs sont plus performants et plus robustes que du Python custom. Voir les types de formules.

Assistant IA pour vous aider à rédiger vos formules (Beta)

Un prompt d'assistant IA est mis à votre disposition pour vous aider à créer vos formules Python (règles d'or, patterns prod, génération de code prêt à l'emploi). Voir la section Assistant IA — Aide à la rédaction de formules en fin de page.

L'interface d'édition

L'éditeur de formule Python s'organise autour de trois onglets : Paramètres, Éditeur & Test et Analytique.

Onglet Paramètres

Cet onglet liste les variables et constantes que votre code Python pourra utiliser. Chaque ligne définit un input (variable source ou constante) avec sa source, son mode de récupération, son agrégation et son unité.

Le bloc de gauche permet aussi de choisir le pas de temps de sortie (Temporel ou Synchronisé) — voir Le pas de temps de sortie pour le détail des deux modes.

Onglet Éditeur & Test

C'est ici que vous écrivez votre code Python. L'éditeur de code occupe la partie gauche, le panneau Résultats du Test la partie droite.

Éditeur de code Python avec bouton Exécuter
Éditeur de code Python avec bouton Exécuter
Cliquer pour ouvrir

Le bouton Exécuter en haut à droite lance le code sur la plateforme et affiche le résultat dans le panneau de droite. Vous pouvez choisir le timestamp de déclenchement avec le sélecteur de date à côté du bouton, ce qui permet de tester la formule sur des données historiques.

Sous la zone de code, trois boutons (Importer un fichier, Exporter le fichier, Effacer) permettent de gérer directement le fichier .py.

Onglet Analytique

Une fois la formule fonctionnelle, l'onglet Analytique affiche un graphique comparant le résultat de votre formule aux variables d'entrée sur la période choisie, ainsi que les KPI agrégés en haut (dernière valeur, moyenne, minimum, maximum).

Onglet Analytique - visualisation du résultat
Onglet Analytique - visualisation du résultat
Cliquer pour ouvrir

Cette vue permet de valider visuellement le comportement de la formule avant de la mettre en production.


Modèle d'exécution

Une formule Python reçoit ses données via un objet input et doit retourner une valeur scalaire unique (nombre, booléen, chaîne ou None) à chaque déclenchement. Les DataFrames reçus sont en lecture seule.

Accès aux variables d'entrée — chaque variable est un DataFrame pandas avec deux colonnes timestamp (datetime64) et value (float64). On y accède par attribut ou comme dans un dictionnaire :

# Accès par attribut (le plus courant)
input.temperature

# Accès style dictionnaire
input['temperature']

# Dernière valeur d'une variable
input.temperature['value'].iloc[-1]

# Itération sur l'historique
for i in range(len(input.temperature)):
ts = input.temperature['timestamp'].iloc[i]
v = input.temperature['value'].iloc[i]

Explorer l'objet input — il se manipule comme un dictionnaire :

MéthodeDescription
input.keys()Noms de toutes les variables d'entrée
input.values()Tous les DataFrames
input.items()Paires (nom, DataFrame)
len(input)Nombre de variables d'entrée
'temperature' in inputTeste l'existence d'une variable
attention

Itérer directement sur input parcourt les noms des variables, pas les DataFrames :

for name in input:      # name = nom de la variable
df = input[name] # récupérer le DataFrame correspondant

Accès aux constantes — une constante est un scalaire directement utilisable :

surface = input.surface   # PAS input.surface['value'].iloc[-1]

Variable globale timestamp — pd.Timestamp en UTC, représente le moment où la formule est déclenchée :

_hour = timestamp.hour
_month = timestamp.month
_wd = timestamp.dayofweek + 1 # 1 = Lundi ... 7 = Dimanche

Retour — la valeur finale est renvoyée par return. Elle doit être scalaire :

return 42.5      # numérique
return 100 # entier
return "high" # chaîne
return True # booléen / alarme (0 ou 1)
return None # aucun résultat

Sont interdits en retour : DataFrame, Series, liste, dict. Pour signaler une absence de donnée, renvoyez 0, une valeur sentinelle (-1) ou None.

Librairies disponibles

Les librairies suivantes sont pré-importées (pas de import à écrire) :

LibrairieAliasUsage
pandaspdDataFrames, Series, Timestamp, Timedelta
numpynpFonctions mathématiques (sqrt, exp, log, sin, cos…)
timetimeModule standard Python

Tout autre import est interdit (datetime, pytz, math, re…). Pour la gestion des fuseaux horaires DST, voir l'exemple "Filtre horaire HP/HC" ci-dessous.

Exemples de formules

Exemple 1 — Retransmettre une valeur (pass-through)

Le plus basique : recopier la dernière valeur d'une source.

if len(input.source) == 0:
return 0

return input.source['value'].iloc[-1]

Exemple 2 — Ratio avec protection division par zéro

Calculer le ratio entre deux variables en évitant une division par zéro.

if len(input.numerateur) == 0 or len(input.denominateur) == 0:
return 0

num = input.numerateur['value'].iloc[-1]
den = input.denominateur['value'].iloc[-1]

if den == 0:
return 0

return num / den * 100 # pourcentage

Exemple 3 — Filtre horaire HP/HC (DST-aware Europe/Paris)

Ne retransmettre la valeur que pendant les Heures Creuses (22h-6h en semaine et samedi, dimanche entier). La conversion DST UTC → heure locale est faite manuellement.

if len(input.source) == 0:
return 0
val = input.source['value'].iloc[-1]

# Calcul du décalage DST pour Europe/Paris
_year = timestamp.year
_last_mar = pd.Timestamp(f'{_year}-03-31')
_dst_start_day = 31 - (_last_mar.dayofweek + 1) % 7
_dst_start_utc = pd.Timestamp(f'{_year}-03-{_dst_start_day:02d} 01:00:00')

_last_oct = pd.Timestamp(f'{_year}-10-31')
_dst_end_day = 31 - (_last_oct.dayofweek + 1) % 7
_dst_end_utc = pd.Timestamp(f'{_year}-10-{_dst_end_day:02d} 01:00:00')

_offset = 2 if _dst_start_utc <= timestamp < _dst_end_utc else 1
_ts_local = timestamp + pd.Timedelta(hours=_offset)
_hour = _ts_local.hour
_wd = _ts_local.dayofweek + 1 # 1=Lun ... 7=Dim

is_hc = (_wd <= 6 and (_hour >= 22 or _hour < 6)) or (_wd == 7)

if is_hc:
return val
return 0

Exemple 4 — Somme dynamique multi-inputs

Sommer plusieurs variables en gérant les capteurs absents ou en panne. Utile pour une consommation totale calculée à partir de sous-compteurs dont certains peuvent ne pas exister sur tous les sites.

inputs_a_sommer = ['meter1', 'meter2', 'meter3', 'meter4']

total = 0.0
for name in inputs_a_sommer:
if name in input and len(input[name]) > 0:
v = input[name]['value'].iloc[-1]
if not pd.isna(v):
total += float(v)

return total

Limitations et contraintes

Le service d'exécution impose des limites strictes :

ContrainteValeur
Temps d'exécution0,5 seconde maximum (par défaut)
Imports externesAucun (pd, np, time uniquement)
Accès aux donnéesDataFrames en lecture seule
Valeur de retourScalaire uniquement (pas de DataFrame, Series, liste…)

Gardez vos scripts simples et rapides : au-delà de 0,5 s, l'exécution est interrompue.

Référence technique

Règles d'or pour éviter les erreurs en production

Le moteur d'exécution Python utilise une émulation custom de pandas/numpy. Certaines fonctionnalités du Python standard ne fonctionnent pas. Voici les règles principales à respecter :

Retour de formule

  • Toujours retourner une valeur scalaire : return 42, return 0, return True
  • Jamais de DataFrame, liste, dict ou Series en retour
  • Pour signaler "pas de donnée", retourner 0 ou une valeur sentinel (-1)

Imports

  • Aucun import : pd, np, time sont déjà disponibles
  • datetime, pytz, math, re : indisponibles → utiliser les équivalents pandas/numpy

Accès aux données

  • Toujours vérifier qu'un input n'est pas vide : if len(input.X) == 0: return 0
  • Les constantes sont des scalaires : input.surface directement, sans ['value'].iloc[-1]
  • Ne jamais utiliser dir(input) (crash) → utiliser input.keys()
  • Ne jamais utiliser .values sur une Series → utiliser list(series)

Manipulation des timestamps

  • .dt.year, .dt.month, .dt.day, .dt.dayofweek : OK
  • .dt.hour, .dt.minute, .dt.floor(), .dt.normalize() : ne fonctionnent pas → utiliser .apply(lambda ts: ts.hour) ou str(ts)[:13]
  • Ne jamais soustraire un pd.Timedelta à la variable globale timestamp (TypeError) → soustraire entre timestamps existants

Numpy

  • OK : np.array, np.sqrt, np.exp, np.log, np.abs, np.isnan, np.nan, np.pi
  • Plantent : np.where, np.ones, np.zeros, np.minimum, np.maximum, np.mean, np.sum → utiliser un ternaire Python, min(), max(), ou les méthodes Series (.mean(), .sum())

Assistant IA — Aide à la rédaction de formules (Beta)

Fonctionnalité en Beta

Cet assistant est en cours de test. Les règles et patterns proposés sont issus de cas de production réels, mais peuvent évoluer après les mises à jour de la plateforme. Toujours valider la formule générée avec une simulation sur la plateforme avant de la mettre en production.

Pour vous aider à rédiger vos formules Python, nous mettons à disposition un prompt d'assistant IA compatible avec Claude, ChatGPT, Gemini ou tout autre LLM. Ce prompt transforme l'assistant en expert de la création de formules Python sur la plateforme Datamonk / GraalPython.

Ce que l'assistant vous apporte

  • Règles d'or et pièges propres à l'émulation GraalPython (pandas/numpy limités, accesseur .dt partiel, manipulation des timestamps, etc.)
  • Catalogue de patterns prêts à l'emploi : pass-through, ratio, filtre HP/HC DST-aware, alarme J-7, somme dynamique multi-inputs, métronome, etc.
  • Génération de code : décrivez votre besoin métier, l'assistant pose 1-2 questions de clarification puis fournit le code Python + la configuration des inputs et du pas de temps de sortie
  • Debugging : il peut diagnostiquer une formule qui ne fonctionne pas en production

Mode d'emploi

  1. Téléchargez le prompt : assistant-formule-python.md
  2. Ouvrez une nouvelle conversation avec votre assistant IA préféré (Claude, ChatGPT, Gemini, etc.)
  3. Collez l'intégralité du contenu du fichier comme premier message (ou comme system prompt si l'outil le permet)
  4. Décrivez votre besoin : « Je veux une formule qui calcule la consommation HP entre 6h et 22h hors weekend pour un compteur électrique. »
  5. L'assistant vous fournira la formule Python prête à coller dans l'éditeur, avec la configuration des inputs et du pas de temps de sortie correspondants
Quel assistant IA choisir ?

Nos tests internes montrent une performance améliorée avec Claude (Anthropic), notamment sur le respect des règles GraalPython et la qualité du code généré. Les autres assistants (ChatGPT, Gemini, etc.) fonctionnent également et donnent de bons résultats, mais peuvent demander un peu plus d'allers-retours pour affiner la formule.

astuce

Plus vous donnez de contexte (nom des variables disponibles, fréquence souhaitée, format de sortie attendu), plus la formule générée sera prête à l'emploi.

Vous ne trouvez pas la réponse à votre question ?

Contactez nous via notre outil de support