automation_machineRéférence complète de l'API utilisée pour définir des séquences AutomationView en Python.
from automation_machine import (
Machine,
Sequence,
SequenceType,
Step,
StepType,
Transition,
Action,
ActionQualifier,
ActionInstruction,
ActionOperand,
Variable,
)
| Symbole | Type | Rôle |
|---|---|---|
Machine |
classe | Registre singleton pour les instances et le matériel |
Sequence |
classe | Classe de base pour chaque séquence SFC |
SequenceType |
énumération | NORMAL, MACRO, ENCLOSING |
Step |
classe | Une étape dans une séquence |
StepType |
énumération | INITIAL, NORMAL, MACRO, ENCLOSING |
Transition |
classe | Un lien booléen entre étapes |
Action |
classe | Une paire qualificatif + instruction attachée à une étape |
ActionQualifier |
énumération | Quand l'action s'exécute (N, S, R, ...) |
ActionInstruction |
énumération | Ce que l'action fait (TON, MOVE, CTU, ...) |
ActionOperand |
classe | Opérande pour les instructions multi-entrées |
Variable |
classe | Un tag dans la table des variables du projet |
MachineLe singleton au niveau projet. AutomationView crée une Machine par projet et y enregistre toutes les instances de séquences.
from automation_machine import Machine
machine = Machine()
machine.name = "PackagingLine"
machine.version = "1.0.0"
machine.description = "Ligne de conditionnement carton"
machine.author = "Équipe Ingénierie"
| Champ | Type | Notes |
|---|---|---|
name |
str |
Nom de la machine |
version |
str |
Chaîne de version libre |
description |
str |
Résumé court |
author |
str |
Propriétaire ou équipe |
clients |
list[str] |
Identifiants des clients connectés |
metadata |
dict[str, Any] |
Métadonnées projet arbitraires |
| Méthode | Rôle |
|---|---|
setup() |
Hook de cycle de vie - déclarer instances et matériel ici |
add_instance(class_name, instance_name, **params) |
Instancier une séquence par nom de classe avec paramètres |
add_station(label, *, protocol=None) |
Enregistrer une station matérielle |
Machine.get_instance(name) |
Rechercher une instance de séquence enregistrée par nom |
Machine.get_all_instances() |
Retourner le dict complet des instances enregistrées |
Machine.reset() |
Supprimer toutes les instances enregistrées - utilisé par les tests |
class Line(Machine):
def setup(self):
self.name = "Ligne 1"
self.add_instance("CylinderCycle", "front_cylinder")
self.add_instance("CylinderCycle", "rear_cylinder")
SequenceLa classe de base pour chaque SFC. Sous-classez-la et redéfinissez setup().
Sequence est rarement instanciée à la main - AutomationView crée les instances via Machine.add_instance ou via l'éditeur visuel. La signature du constructeur est :
Sequence(
name: Optional[str] = None,
sequence_type: SequenceType = SequenceType.NORMAL,
parent_sequence_id: Optional[str] = None,
parent_sequence: Optional["Sequence"] = None,
instance_name: Optional[str] = None,
**kwargs,
)
setup() du cycle de vieRedéfinissez setup() pour déclarer vos étapes, transitions et actions :
from automation_machine import Sequence, StepType
class Heater(Sequence):
def setup(self):
self.s0 = self.add_step(StepType.INITIAL, name="Off")
self.s1 = self.add_step(name="Heating")
self.add_transition(self.s0, self.s1, "cmd_on")
self.s1.add_action("heater_relay")
| Méthode | Retourne | Rôle |
|---|---|---|
add_step(step_type=NORMAL, name=None, comment=None) |
Step |
Créer une étape |
add_transition(source, target, condition="", comment=None) |
Transition |
Câbler une transition |
add_macro_step(name, sub_class_name, entry_step=None, exit_step=None) |
Step |
Intégrer une séquence macro |
add_enclosing_step(name, sub_class_name) |
Step |
Intégrer une séquence encapsulée (parallèle) |
get_sub_sequence(name) |
Sequence ou None |
Rechercher une séquence enfant par nom |
to_dict() |
dict |
Sérialiser la séquence |
validate() |
list[str] |
Retourner les erreurs de validation (vide si valide) |
| Champ | Type | Notes |
|---|---|---|
id |
str |
Identifiant unique auto-généré |
name |
str |
Nom d'affichage |
instance_name |
str ou None |
Défini lors de l'instanciation via Machine |
sequence_type |
SequenceType |
NORMAL, MACRO ou ENCLOSING |
steps |
list[Step] |
Toutes les étapes déclarées dans setup() |
transitions |
list[Transition] |
Toutes les transitions déclarées dans setup() |
sub_sequences |
list[Sequence] |
Enfants macro et d'encapsulation |
params |
dict[str, Any] |
Paramètres passés via add_instance |
SequenceTypeclass SequenceType(Enum):
NORMAL = "normal" # Séquence standard de niveau supérieur
MACRO = "macro" # Sous-séquence réutilisable invoquée par étape macro
ENCLOSING = "enclosing" # Enfant parallèle d'une étape d'encapsulation
StepUn noeud du SFC. Retourné par Sequence.add_step().
add_action()step.add_action(
name: str,
description: str = "",
qualifier: ActionQualifier = ActionQualifier.N,
instruction: ActionInstruction | str | None = None,
duration: float | None = None,
operands: list[ActionOperand] | None = None,
condition: str | None = None,
code: str | None = None,
preset_value: int | None = None,
comment: str | None = None,
parameters: dict[str, Any] | None = None,
) -> Action
s1.add_action("motor_run", description="Moteur convoyeur")
s2.add_action(
"delay_timer",
instruction=ActionInstruction.TON,
duration=2500,
)
| Champ | Type | Notes |
|---|---|---|
step_type |
StepType |
INITIAL, NORMAL, MACRO, ENCLOSING |
name |
str |
Nom d'affichage |
id |
str |
Identifiant auto-généré |
actions |
list[Action] |
Actions attachées à cette étape |
sub_sequence |
Sequence ou None |
Séquence enfant pour les étapes macro/encapsulation |
entry_step_name |
str ou None |
Entrée dans une sous-séquence macro |
exit_step_name |
str ou None |
Sortie d'une sous-séquence macro |
StepTypeclass StepType(Enum):
INITIAL = "initial" # Étape de départ (exactement une par séquence)
NORMAL = "normal" # Étape standard
MACRO = "macro" # Étape qui invoque une sous-séquence macro
ENCLOSING = "enclosing" # Étape qui enveloppe une sous-séquence parallèle
s_start = self.add_step(StepType.INITIAL, name="Start")
s_run = self.add_step(name="Run") # NORMAL par défaut
s_pack = self.add_macro_step(name="Pack", sub_class_name="PackingMacro")
s_super = self.add_enclosing_step(name="Supervise", sub_class_name="SafetyMonitor")
TransitionUn lien directionnel et booléen entre étapes. Retourné par Sequence.add_transition().
| Champ | Type | Notes |
|---|---|---|
source_steps |
list[Step] |
Une étape normalement, plusieurs pour une convergence |
target_steps |
list[Step] |
Une étape normalement, plusieurs pour une divergence |
condition |
str |
Expression booléenne évaluée à chaque scan |
id |
str |
Identifiant auto-généré |
comment |
str ou None |
Note inline optionnelle |
# Transition simple
self.add_transition(s0, s1, condition="start_button")
# Convergence : s_a ET s_b doivent être terminées avant de continuer
self.add_transition([s_a, s_b], s_done, condition="TRUE")
# Divergence : de s_choose vers s_left ou s_right selon le drapeau
self.add_transition(s_choose, s_left, condition="direction = 0")
self.add_transition(s_choose, s_right, condition="direction = 1")
ActionL'unité de comportement attachée à une étape. Retournée par Step.add_action() - rarement construite directement.
| Champ | Type | Notes |
|---|---|---|
name |
str |
Variable ou instance de bloc fonctionnel |
description |
str |
Label lisible |
qualifier |
ActionQualifier |
Quand l'action s'exécute |
instruction |
ActionInstruction ou str ou None |
Ce que l'action fait |
duration |
float ou None |
Millisecondes (pour les temporisateurs et qualificatifs temporisés) |
operands |
list[ActionOperand] |
Entrées pour les instructions multi-opérandes |
condition |
str ou None |
Expression de gating optionnelle |
preset_value |
int ou None |
Présélection pour les compteurs |
code |
str ou None |
Code ST inline pour les actions personnalisées |
ActionQualifierContrôle quand une action s'exécute pendant que son étape est active. Par défaut N.
| Valeur | Nom | Comportement |
|---|---|---|
N |
Non mémorisé | Actif pendant toute la durée de l'étape (défaut) |
S |
Set (mémorisé) | Verrouillé à ON quand l'étape s'active - reste ON jusqu'au reset |
R |
Reset | Verrouillé à OFF quand l'étape s'active - efface un S précédent |
P |
Impulsion | Impulsion d'un cycle de scan à l'activation de l'étape |
L |
Limité dans le temps | Actif pendant la durée, puis s'arrête (même si l'étape est active) |
D |
Différé | S'active après la durée si l'étape est toujours active |
SD |
Mémorisé et différé | S après la durée |
DS |
Différé et mémorisé | S différé, effacé à la désactivation si la durée n'est pas atteinte |
SL |
Mémorisé et limité | S pendant la durée, puis auto-reset |
Les qualificatifs
L,D,SD,DSetSLrequièrent tous un argumentduration(millisecondes).
from automation_machine import ActionQualifier
s1.add_action("alarm_lamp", qualifier=ActionQualifier.S) # verrouiller ON
s2.add_action("alarm_lamp", qualifier=ActionQualifier.R) # verrouiller OFF
s3.add_action("warning_pulse", qualifier=ActionQualifier.P) # un scan
s4.add_action("indicator", qualifier=ActionQualifier.L, duration=3000) # 3 s seulement
Voir la référence des qualificatifs pour la sémantique complète et les diagrammes temporels.
ActionInstructionContrôle ce que fait l'action. Sans instruction, une action pilote simplement la variable name selon le qualificatif.
| Valeur | Nom | Utilisation |
|---|---|---|
MOVE |
Move | Copier une valeur dans la variable de l'action |
s1.add_action(
"target_speed",
instruction=ActionInstruction.MOVE,
operands=[ActionOperand("1500", is_literal=True)],
)
| Valeur | Nom | Utilisation |
|---|---|---|
SR |
Bascule à dominance Set | La sortie reste à 1 quand les deux entrées sont à TRUE |
RS |
Bascule à dominance Reset | La sortie reste à 0 quand les deux entrées sont à TRUE |
| Valeur | Nom | Sortie |
|---|---|---|
R_TRIG |
Front montant | Impulsion d'un scan sur FALSE -> TRUE |
F_TRIG |
Front descendant | Impulsion d'un scan sur TRUE -> FALSE |
s1.add_action(
"start_edge",
instruction=ActionInstruction.R_TRIG,
operands=[ActionOperand("start_button")],
)
| Valeur | Nom | Opération |
|---|---|---|
ADD |
Addition | result := a + b |
SUB |
Soustraction | result := a - b |
MUL |
Multiplication | result := a * b |
DIV |
Division | result := a / b |
s1.add_action(
"total_count",
instruction=ActionInstruction.ADD,
operands=[
ActionOperand("part_count"),
ActionOperand("1", is_literal=True),
],
)
| Valeur | Nom | Résultat booléen |
|---|---|---|
EQ |
Égal | a = b |
NE |
Différent | a <> b |
GT |
Supérieur | a > b |
GE |
Supérieur ou égal | a >= b |
LT |
Inférieur | a < b |
LE |
Inférieur ou égal | a <= b |
s1.add_action(
"above_setpoint",
instruction=ActionInstruction.GT,
operands=[
ActionOperand("temperature"),
ActionOperand("setpoint"),
],
)
Toutes les durées sont en millisecondes. Les sorties sont exposées via .Q (booléen) et .ET (temps écoulé) sur la variable du temporisateur.
| Valeur | Nom | Comportement |
|---|---|---|
TON |
Retard à la montée | .Q passe à TRUE après duration d'entrée continue |
TOF |
Retard à la descente | .Q reste TRUE pendant duration après que l'entrée passe à FALSE |
TP |
Temporisateur impulsion | .Q est TRUE pendant exactement duration sur front montant |
RTO |
Retard à la montée rétentif | Comme TON mais accumule sur les cycles désactivés/activés |
s1.add_action(
"warmup_timer",
instruction=ActionInstruction.TON,
duration=5000,
)
# Référencer le résultat dans une transition :
self.add_transition(s1, s2, condition="warmup_timer.Q")
.CV (valeur courante) et .Q (présélection atteinte) sont exposés sur la variable du compteur.
| Valeur | Nom | Comportement |
|---|---|---|
CTU |
Compteur ascendant | Incrémente .CV à chaque front montant de l'entrée |
CTD |
Compteur descendant | Décrémente .CV depuis la présélection à chaque front montant |
CTUR |
Comptage ascendant avec reset | CTU avec une entrée de reset |
CTDR |
Comptage descendant avec reset | CTD avec une entrée de reset |
s1.add_action(
"cycle_counter",
instruction=ActionInstruction.CTU,
preset_value=100,
operands=[ActionOperand("cycle_trigger")],
)
self.add_transition(s1, s2, condition="cycle_counter.Q")
Voir la référence des instructions pour la documentation approfondie de chaque instruction avec diagrammes temporels.
ActionOperandUne entrée typée pour les instructions qui nécessitent plus que le name implicite. Utilisée par ADD, SUB, MUL, DIV, MOVE, les instructions de comparaison, les détecteurs de fronts et les compteurs.
from automation_machine import ActionOperand
ActionOperand("temperature") # référence variable
ActionOperand("1500", is_literal=True) # valeur littérale
| Paramètre | Type | Notes |
|---|---|---|
value |
str |
Nom de variable ou texte littéral |
is_literal |
bool |
True pour une valeur littérale, False pour une référence de variable (défaut False) |
VariableUn tag dans la table des variables du projet. Les variables sont généralement déclarées dans l'éditeur visuel ou le fichier .machine, mais peuvent aussi être construites par programme.
| Champ | Type | Notes |
|---|---|---|
name |
str |
Nom de variable (unique dans la portée) |
data_type |
str |
BOOL, INT, DINT, REAL, STRING, ... |
initial_value |
bool ou int ou float ou str ou None |
Valeur par défaut au démarrage |
current_value |
comme initial_value |
Valeur en direct pendant l'émulation |
description |
str |
Documentation |
address |
str ou None |
Adresse E/S physique |
| Méthode | Rôle |
|---|---|
set_value(value) |
Mettre à jour la valeur courante |
get_value() |
Lire la valeur courante |
reset() |
Réinitialiser à initial_value |
to_dict() |
Sérialiser |
from automation_machine import Variable
cycle_count = Variable()
cycle_count.name = "cycle_count"
cycle_count.data_type = "DINT"
cycle_count.initial_value = 0
cycle_count.description = "Cycles de production terminés"
Le type de donnée est inféré automatiquement lors de la première utilisation de la variable dans une étape ou transition. Vous n'avez besoin de construire des instances
Variabledirectement que pour des scénarios de scripting avancés.
Le module expose quelques fonctions d'aide :
| Fonction | Rôle |
|---|---|
is_timed_qualifier(q) |
True si le qualificatif requiert une duration (L, D, SD, DS, SL) |
is_stored_qualifier(q) |
True si le qualificatif mémorise l'état (S, SD, DS, SL) |
requires_operands(i) |
True si l'instruction requiert des operands |
instruction_to_str(i) |
Normaliser une instruction vers son nom textuel |
Les ensembles figés TIMED_QUALIFIERS, STORED_QUALIFIERS, OPERAND_INSTRUCTIONS et BOOLEAN_INSTRUCTIONS sont également exportés pour le code qui s'appuie sur des recherches.
Une séquence courte mais complète qui utilise l'essentiel de l'API :
from automation_machine import (
Sequence, StepType, ActionQualifier, ActionInstruction, ActionOperand,
)
class FillStation(Sequence):
"""Remplir un réservoir jusqu'au niveau cible, puis vidanger sur commande."""
def setup(self):
s_idle = self.add_step(StepType.INITIAL, name="Idle")
s_fill = self.add_step(name="Filling")
s_full = self.add_step(name="Full")
s_drain = self.add_step(name="Draining")
# Ouvrir la vanne d'entrée pendant le remplissage
s_fill.add_action("inlet_valve")
# Comparer le niveau à la consigne - pilote la variable booléenne `level_ok`
s_fill.add_action(
"level_ok",
instruction=ActionInstruction.GE,
operands=[ActionOperand("tank_level"), ActionOperand("setpoint")],
)
# Verrouiller un drapeau "défaut" si le remplissage dure plus de 30 s
s_fill.add_action(
"fill_fault",
qualifier=ActionQualifier.D,
duration=30000,
)
# Idle : effacer le défaut
s_idle.add_action("fill_fault", qualifier=ActionQualifier.R)
# Vanne de vidange ouverte pendant la vidange
s_drain.add_action("drain_valve")
# Câblage
self.add_transition(s_idle, s_fill, "cmd_fill AND NOT fill_fault")
self.add_transition(s_fill, s_full, "level_ok")
self.add_transition(s_full, s_drain, "cmd_drain")
self.add_transition(s_drain, s_idle, "tank_level <= 5")