172 lines
6.7 KiB
Python
172 lines
6.7 KiB
Python
import modele.composants as mc
|
|
import modele.elements as me
|
|
from modele.exceptions import Dir
|
|
from modele.donnees import GraphStructException
|
|
|
|
|
|
class Vecteur(object):
|
|
"""
|
|
Associe les éléments du graphe à leur rang dans le vecteur correspondant aux rangs dans la matrice.
|
|
"""
|
|
def __init__(self, elements):
|
|
self._liste = [eq_elt for element in elements.values() for eq_elt in element.eq_elts()]
|
|
|
|
self._index = {} # Associe à un élément son index dans la matrice
|
|
for index, element in enumerate(self._liste):
|
|
self._index[element] = index
|
|
|
|
def __len__(self):
|
|
return len(self._liste)
|
|
|
|
def index(self, element):
|
|
return self._index[element]
|
|
|
|
def __iter__(self):
|
|
return self._liste.__iter__()
|
|
|
|
|
|
class Graphe(object):
|
|
ID_BR = -1
|
|
|
|
@classmethod
|
|
def branch_id(cls):
|
|
cls.ID_BR += 1
|
|
return f"b{cls.ID_BR}"
|
|
|
|
def __init__(self, conf):
|
|
self.conf = conf
|
|
self.elements = None
|
|
self.composants = None
|
|
self.vecteur = None
|
|
|
|
def load_data_from_schema_reader(self, reader):
|
|
self.elements = {}
|
|
self.composants = {}
|
|
|
|
# Construction des éléments et composants
|
|
for nom, valeur in reader.composants.items():
|
|
if valeur.type == 'Bouton' or valeur.type == 'ContactTravail' or valeur.type == 'ContactRepos' \
|
|
or valeur.type == 'Levier':
|
|
self.composants[nom] = mc.Contact(self.conf, nom, valeur.type)
|
|
elif valeur.type == 'Relais':
|
|
if valeur.donnees.get('basculeur') == 'gauche':
|
|
self.composants[nom] = mc.DemiRelaisBasculeur(self.conf, nom, self, Dir.GAUCHE)
|
|
elif valeur.donnees.get('basculeur') == 'droite':
|
|
self.composants[nom] = mc.DemiRelaisBasculeur(self.conf, nom, self, Dir.DROITE)
|
|
else:
|
|
self.composants[nom] = mc.Relais(self.conf, nom, self)
|
|
elif valeur.type == 'Tempo':
|
|
self.composants[nom] = mc.Tempo(self.conf, nom, valeur.donnees['tempo_blocage'],
|
|
valeur.donnees['tempo_liberation'])
|
|
elif valeur.type == 'Resistance':
|
|
if 'valeur' not in valeur.donnees:
|
|
v = None
|
|
else:
|
|
v = valeur.donnees['valeur']
|
|
self.composants[nom] = mc.Resistance(self.conf, nom, v)
|
|
del v
|
|
elif valeur.type == 'Lampe':
|
|
self.composants[nom] = mc.Lampe(self.conf, nom)
|
|
elif valeur.type == 'Diode':
|
|
d = mc.Diode(self.conf, nom)
|
|
self.composants[nom] = d
|
|
self.composants["!" + nom] = d
|
|
del d
|
|
|
|
for nom, valeur in reader.noeuds.items():
|
|
if valeur.type == "Noeud":
|
|
self.elements[nom] = me.Noeud(self.conf, nom)
|
|
elif valeur.type == "P24":
|
|
self.elements[nom] = me.Potentiel(self.conf, nom, 24.)
|
|
elif valeur.type == "P0":
|
|
self.elements[nom] = me.Potentiel(self.conf, nom, 0.)
|
|
elif valeur.type == "Pulse":
|
|
if "periode" not in valeur.donnees:
|
|
p = None
|
|
else:
|
|
p = valeur.donnees["periode"]
|
|
self.elements[nom] = me.PotPulse(self.conf, nom, 24., p)
|
|
elif valeur.type == "ContactBasculeur":
|
|
self.elements[nom] = me.ContactBasculeur(self.conf, nom, self)
|
|
elif valeur.type == "ContactDouble":
|
|
self.elements[nom] = me.ContactDouble(self.conf, nom, self, orientation=valeur.donnees['orientation'])
|
|
|
|
for nom, valeur in reader.condensateurs.items():
|
|
cnd = me.Condensateur(self.conf, nom, valeur.donnees['capacite'], valeur.donnees['coef_mul_tension'])
|
|
|
|
v_amont_schm, v_amont_dir = valeur.get_amont()
|
|
v_aval_schm, v_aval_dir = valeur.get_aval()
|
|
|
|
v_amont = self.elements[v_amont_schm.nom]
|
|
v_aval = self.elements[v_aval_schm.nom]
|
|
|
|
cnd.add_voisins(v_amont, v_aval)
|
|
v_amont.add_voisins([(cnd, -1, v_amont_dir)])
|
|
v_aval.add_voisins([(cnd, +1, v_aval_dir)])
|
|
self.elements[nom] = cnd
|
|
del cnd
|
|
|
|
# Ajout des liens entre relais et contacts
|
|
try:
|
|
for nom, valeur in reader.composants.items():
|
|
if valeur.type == "ContactTravail":
|
|
self.composants[valeur.donnees["relais"]].add_travail(nom)
|
|
elif valeur.type == "ContactRepos":
|
|
self.composants[valeur.donnees["relais"]].add_repos(nom)
|
|
|
|
for nom, valeur in reader.noeuds.items():
|
|
if valeur.type == "ContactBasculeur":
|
|
self.composants[valeur.donnees["relais"] + ".gauche"].add_contact(nom)
|
|
self.composants[valeur.donnees["relais"] + ".droite"].add_contact(nom)
|
|
elif valeur.type == "ContactDouble":
|
|
self.composants[valeur.donnees["relais"]].add_double(nom)
|
|
except KeyError:
|
|
raise GraphStructException("Mauvais identificateur de relais dans un contact")
|
|
|
|
# Construction des branches
|
|
for branche in reader.branches:
|
|
nom = self.branch_id()
|
|
br = me.Branche(self.conf, nom, [self.composants[x.nom] for x in branche.composants])
|
|
[self.composants[x.nom].reverse() for x in branche.composants if x.nom[0] == '!'] # Diode
|
|
for c in br.composants:
|
|
c.branche = br
|
|
|
|
v_amont_schm, v_amont_dir = branche.get_amont()
|
|
v_aval_schm, v_aval_dir = branche.get_aval()
|
|
|
|
v_amont = self.elements[v_amont_schm.nom].get_potentiel(v_amont_dir)
|
|
v_aval = self.elements[v_aval_schm.nom].get_potentiel(v_aval_dir)
|
|
|
|
br.add_voisins(v_amont, v_aval)
|
|
v_amont.add_voisins([(br, -1, v_amont_dir)])
|
|
v_aval.add_voisins([(br, +1, v_aval_dir)])
|
|
self.elements[nom] = br
|
|
del br
|
|
|
|
self.vecteur = Vecteur(self.elements)
|
|
|
|
def __getitem__(self, item):
|
|
"""
|
|
Retourne un composant
|
|
"""
|
|
if item in self.composants:
|
|
res = self.composants[item]
|
|
else:
|
|
res = self.elements[item]
|
|
return res
|
|
|
|
def __contains__(self, item):
|
|
return item in self.composants or item in self.elements
|
|
|
|
def init_cycle(self):
|
|
[elt.init_cycle() for elt in self.elements.values()]
|
|
|
|
def passe_calcul(self, solutions):
|
|
[elt.passe_calcul(solutions, self.vecteur.index(elt)) for elt in self.elements.values()]
|
|
|
|
def update(self):
|
|
[elt.update() for elt in self.elements.values()]
|
|
|
|
def coherence(self):
|
|
[x.coherence() for x in self.elements.values()]
|