def ajouterElement(self, element): if isinstance(element, Etape): identifiant = 'E' + str(element.numero) elif isinstance(element, Transition): identifiant = 'T' + str(element.numero) elif isinstance(element, Liaison): identifiant = 'L' + str(element.numero) else: raise GrafcetError( "Un élément de type inconnu est passé à :\ Diagramme.ajouterElement()") if identifiant not in self._elements.keys(): self._elements[identifiant] = element else: raise GrafcetError( "Tentative d'ajout d'un élément muni d'un identifiant déjà\ utilisé")
def dureeMs(debut, fin): """ Renvoie le temps écoulé en ms entre debut et fin """ if (isinstance(debut, datetime) and isinstance(fin, datetime)): duree = fin - debut return duree.microseconds // 1000 else: raise GrafcetError( "La fonction Horloge.dureeMs() a été appelée avec des paramètres\ incorrects")
def deXml(self, element_xml, elements_diagramme): """ Construit l'élément à partir d'un élément xml et des éléments du diagramme étapes et transitions. """ # 1. Identification des étapes et des transitions : etapes = [] transitions = [] for element in elements_diagramme: if isinstance(element, Etape): etapes.append(element) if isinstance(element, Transition): transitions.append(element) # 2. Création de la Liaison self.X = int(element_xml.get('X')) self.Y = int(element_xml.get('Y')) if element_xml.get('numero') is not None: self._numero = int(element_xml.get('numero')) self._amont = True if element_xml.get('amont') == 'True' else False # Liaison aux étapes, code un peu plus complexe... numeros_etapes = str(element_xml.get('etapes')).split(sep=',') for numero in numeros_etapes: if numero is not '': try: self._etapes.append( next(etape for etape in etapes if etape.numero == int(numero))) except StopIteration as error: raise GrafcetError( "Erreur d'intégrité XML : une liaison ({}) essaie de\ s'attacher à une étape ({}) qui n'existe pas !".format( self.numero, numero)) # Liaison à la transition : try: self._transition = next( transition for transition in transitions if transition.numero == int(element_xml.get('transition'))) if self._transition is not None and self.X == 0 and self.Y == 0: self.X = self._transition.X self.Y = self._transition.Y except StopIteration as error: raise GrafcetError( "Erreur d'intégrité XML : une liaison ({}) essaie de\ s'attacher à une transition ({}) qui n'existe pas !". format(self.numero, int(element_xml.get('transition'))))
def calculerEvolution(self): """ Conforme au chapitre 4.5 de la norme """ situation_initiale = deepcopy(self.situation) situation_intermediaire = deepcopy(self.situation) while True: # 1. Détermination des liaisons amonts franchissables liaisons_amont_franchissables = list( liaison for liaison in self.liaisons if liaison.franchissable) # 2. Détermination des transitions "validées" transitions_validees = list( liaison.transition for liaison in liaisons_amont_franchissables) # 3. Détermination des transitions franchies transitions_franchies = list( transition for transition in transitions_validees if transition.receptivite) # 4. Détermination des étapes à désactiver groupes_etapes_desactivees = list( liaison.etapes for liaison in liaisons_amont_franchissables if liaison.transition in transitions_franchies) # 5. Détermination des étapes à activer groupes_etapes_activees = list( liaison.etapes for liaison in self.liaisons if liaison.amont is False and liaison.transition in transitions_franchies) for etapes in groupes_etapes_desactivees: for etape in etapes: etape.desactiver() for etapes in groupes_etapes_activees: for etape in etapes: etape.activer() print("liaisons_amont_franchissables") for liaison in liaisons_amont_franchissables: print(liaison) print("transitions_validees") for transition in transitions_validees: print(transition) print("transitions_franchies") for transition in transitions_franchies: print(transition) print("groupes_etapes_desactivees") for etapes in groupes_etapes_desactivees: for etape in etapes: print(etape) print("groupes_etapes_activees") for etapes in groupes_etapes_activees: for etape in etapes: print(etape) print(self.situation) if situation_intermediaire == self.situation: # pas d'évolution break # on sort de la méthode calculerEvolution situation_intermediaire = deepcopy(self.situation) if situation_intermediaire == situation_initiale: raise GrafcetError("Évolution infinie du Grafcet !")
def chargerXML(self, fichier): """ Vide le dictionnaire elements et le remplit avec les données du fichier XML """ logI("Chargement du fichier " + str(fichier) + "...") self._elements.clear() try: arbre = parse(source=fichier) except FileNotFoundError as e: raise GrafcetError("Fichier : " + str(fichier) + " introuvable !") except ParseError as e: raise GrafcetError( "Erreur lors du chargement du fichier XML : " + fichier + "\nMessage du module XML : " + ErrorString(e.code)) # TODO : vérifier intégrité du fichier xml etapes = arbre.find('Etapes') transitions = arbre.find('Transitions') liaisons = arbre.find('Liaisons') for etape_xml in etapes.findall('Etape'): etape = Etape() etape.deXml(etape_xml) logD(etape) self._elements['E' + str(etape.numero)] = etape for transition_xml in transitions.findall('Transition'): transition = Transition() transition.deXml(transition_xml) logD(transition) self._elements['T' + str(transition.numero)] = transition for liaison_xml in liaisons.findall('Liaison'): liaison = Liaison() liaison.deXml(liaison_xml, self._elements.values()) logD(liaison) self._elements['L' + str(liaison.numero)] = liaison logI(str(len(self._elements)) + " éléments trouvés !")
def dessinerElement(self): """ Calcul des coordonnées bas-gauche du carré inscrit dans le widget puis dessin de l'élément pour chaque élément. """ for element in self.elements: if isinstance(element, Etape): self.canvas.add(dessins.dessinerEtape(self, element)) elif isinstance(element, Transition): self.canvas.add(dessins.dessinerTransition(self, element)) elif isinstance(element, Liaison): self.canvas.add(dessins.dessinerLiaison(self, element)) else: raise GrafcetError( "Un élément inconnu a été passé à la méthode : \ case.Case.dessinerElement()" + str(element))
def sauvegarderXML(self, fichier): """ Le fichier est écrasé """ try: arbre = parse(source='../XML/diagramme_vide.xml') etapes = arbre.find('Etapes') transitions = arbre.find('Transitions') liaisons = arbre.find('Liaisons') for element in self._elements.values(): if isinstance(element, Etape): etapes.append(element.xml) elif isinstance(element, Transition): transitions.append(element.xml) elif isinstance(element, Liaison): liaisons.append(element.xml) arbre.write( fichier, encoding='unicode', short_empty_elements=False) except ParseError as e: raise GrafcetError('Erreur du Parser XML/nMessage : ' + e.message)
class Element: """ La classe Element est une interface qui permet de définir les coordonnées (X, Y) des éléments composant le diagramme Grafcet. L'index permet de définir l'élément le plus haut en cas de superposition. """ def __init__(self, X=0, Y=0, index=0): self.X = X self.Y = Y self.index = index def case(self, cases): """ Retourne la case correspondante """ for case in cases: if case.X == self.X and case.Y == self.Y: return case return GrafcetError( "Impossible de trouver la case", self.X, self.Y, "correspondante !")