functionalities

This commit is contained in:
bendidi 2024-06-27 11:12:33 +02:00
parent 88aced27bf
commit 2e59700bfa
18 changed files with 84 additions and 27 deletions

View File

@ -184,6 +184,21 @@ def release(obj):
PROCESS_BASE.cmd_q().put({'cmd': "release", "args": obj})
return "OK"
@app.route('/pause/<obj>')
def pause_simulation(obj):
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q.put({'cmd': "pause", "arg": obj})
return "Simulation paused"
@app.route('/resume/<obj>')
def resume_simulation(obj):
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q.put({'cmd': "resume", "arg": obj})
return "Simulation resumed"
def just_run():
"""

View File

@ -3,7 +3,11 @@ import json
class State(object):
IGNORE = frozenset(['Coude', 'Noeud', 'P24', 'P0', 'Pulse'])
# these components do not have any states (value/ true or flase...)
Breakpoints = ['Relais']
#possibility to add other breakpoints in the future ;)
def __init__(self, cocosim_server):
self.cocosim_server = cocosim_server
self.conf = self.cocosim_server.conf["ui"]
@ -38,4 +42,5 @@ class State(object):
self._exception = e
def reset_exception(self):
self._exception = None
self._exception = None

View File

@ -14,6 +14,7 @@ class CocosimInstance(object):
conf_fp = open("modele/config.json")
conf = json.load(conf_fp)
self.pause_simulation = False #pause flag
self.conf = conf
self.dt = self.conf['circuit']['DT']
self.cocosim = None
@ -47,15 +48,19 @@ class CocosimInstance(object):
if message == "start":
logging.log(logging.INFO, "Starting")
self.runner = asyncio.create_task(self.run())
elif message == "stop":
logging.log(logging.INFO, "Stopping")
await self.stop()
elif message == "state":
self.state_q.put(self.state.to_json())
elif message == "quit":
logging.log(logging.INFO, "Quitting")
await self.stop()
self.quit = True
elif message == "load":
logging.log(logging.INFO, "Loading file")
try:
@ -63,6 +68,17 @@ class CocosimInstance(object):
self.state_q.put("OK")
except GraphStructException:
self.state_q.put("Error")
elif message == "pause":
but_name = data['args']
logging.log(logging.INFO,"Simulation paused {but_name}")
self.pause_simulation = True
elif message == "resume":
but_name = data['args']
logging.log(logging.INFO,"Simulation resumed {but_name}")
self.pause_simulation = False
elif message == "push":
but_name = data['args']
logging.log(logging.INFO, f"Push button {but_name}")
@ -103,12 +119,17 @@ class CocosimInstance(object):
async def run(self):
try:
while True:
self.state.reset_exception()
self.cycle()
while not self.quit:
if not self.pause_simulation:
self.state.reset_exception()
self.cycle()
else:
print("Simulation paused. Awaiting resume...")
while self.pause_simulation:
await asyncio.sleep(1) #wait until the simulation is resumed
await asyncio.sleep(self.dt)
except:
logging.exception("Exception occured in 'cycle'")
except Exception as e:
logging.exception("Exception occured during simulation run")
async def stop(self):
if self.runner:

View File

@ -1,19 +1,2 @@
INFO:root:Creating instance
INFO:root:Loading file
INFO:root:Setting up
INFO:root:Schema is loaded
INFO:root:State is made up with 5 items.
INFO:root:Graph is initialized.
INFO:root:Cocosim is initialized
INFO:root:Starting
INFO:root:Push button b
INFO:root:Release button b
INFO:root:Stopping
ERROR:root:Exception occured in 'cycle'
Traceback (most recent call last):
File "C:\Users\0203209E\Downloads\gittea\cocosim_python\api_worker\__init__.py", line 109, in run
await asyncio.sleep(self.dt)
File "C:\Program Files\Python312\Lib\asyncio\tasks.py", line 655, in sleep
return await future
^^^^^^^^^^^^
asyncio.exceptions.CancelledError
INFO:root:Cocosim instance destroyed

View File

@ -1,6 +1,5 @@
from modele.exceptions import NonPolariseException, Dir
class Composant(object):
def __init__(self, conf, nom):
"""
@ -38,6 +37,10 @@ class Composant(object):
def etat(self):
raise NotImplementedError
def pause_simulation(self):
pass
class Contact(Composant):
@ -117,6 +120,8 @@ class Relais(Composant):
self._contacts_repos = []
self._contacts_double = []
self.haut = False
self.etat_precedent = False #etat precedent du relais
self.est_point_arret = False #indicateur de point d'arret
def add_travail(self, nom):
self._contacts_travail.append(nom)
@ -150,12 +155,16 @@ class Relais(Composant):
self.graphe[nom].desactive()
def update(self):
etat_precedent = self.haut
super().update()
if self.branche.i() >= self.SEUIL:
self.monte()
else:
self.chute()
if self.est_point_arret and etat_precedent != self.haut:
self.graphe.flag_arret_simulation = True
def etat(self):
return self.haut

View File

@ -13,7 +13,8 @@
"RES_RELAIS": 100.0,
"SEUIL_RELAIS": 0.05,
"SEUIL_TEMPO": 0.05,
"PULSE_PERIODE": 1.0
"PULSE_PERIODE": 1.0,
"TOLERANCE_COURANT": 1e6
},
"ui": {
"DT": 0.13,

View File

@ -138,6 +138,26 @@ class Noeud(Element):
def etat(self):
return self.u() >= self.conf['USEUIL']
def verifier_loi_des_noeuds(self):
"""Dans cette méthode, self._voisins contient les branches connectées au nœud, et polarite indique si le courant est entrant (-1) ou sortant (+1).
La variable courant_total accumule la somme des courants, et self.conf['TOLERANCE_COURANT'] est une petite valeur seuil pour tolérer des imprécisions
numériques (par exemple, 1e-6)."""
courant_total = 0
for voisin, polarite, _ in self._voisins:
if polarite == -1:
courant_total -= voisin.i()
else:
courant_total += voisin.i()
if abs(courant_total) > self.conf['TOLERANCE_COURANT']:
raise Exception(f"La loi des nœuds n'est pas respectée pour le noeud {self.nom}. Total courant: {courant_total}")
class Branche(Element):

View File

@ -38,6 +38,7 @@ class Graphe(object):
self.elements = None
self.composants = None
self.vecteur = None
self.flag_arret_simulation = False
def load_data_from_schema_reader(self, reader):
self.elements = {}
@ -168,4 +169,4 @@ class Graphe(object):
[elt.update() for elt in self.elements.values()]
def coherence(self):
[x.coherence() for x in self.elements.values()]
[x.coherence() for x in self.elements.values()]

View File

@ -0,0 +1 @@
{"blocs":{"p24-1":{"type":"P24","valeur":24,"orientation":0,"x":0,"y":500},"p24-2":{"type":"P24","valeur":24,"orientation":0,"x":0,"y":300},"p0-1":{"type":"P0","valeur":0,"orientation":0,"x":1200,"y":500},"p0-2":{"type":"P0","valeur":0,"x":1200,"y":300},"r1":{"type":"Relais","x":400,"y":500},"r2":{"type":"Relais","x":1000,"y":500},"c3":{"type":"Bouton","x":200,"y":500,"orientation":0},"r2.double":{"type":"ContactDouble","relais":"r2","orientation":0,"x":1000,"y":300},"w1":{"type":"Lampe","x":600,"y":500},"w2":{"type":"Lampe","x":600,"y":300},"n1":{"type":"Noeud","x":800,"y":500},"coude1":{"type":"Coude","x":800,"y":310}},"cables":[["p24-1","d","c3","g"],["c3","d","r1","g"],["r1","d","w1","g"],["w1","d","n1","m"],["n1","m","r2","g"],["r2","d","p0-1","g"],["n1","m","coude1","m"],["coude1","m","r2.double","hg"],["r2.double","d","p0-2","g"],["p24-2","d","w2","g"],["w2","d","r2.double","bg"]]}

View File

@ -0,0 +1 @@
{"blocs":{"p24-1":{"type":"P24","valeur":24,"orientation":0,"x":0,"y":500},"p24-2":{"type":"P24","valeur":24,"orientation":0,"x":0,"y":300},"p0-1":{"type":"P0","valeur":0,"orientation":0,"x":1200,"y":500},"p0-2":{"type":"P0","valeur":0,"x":1200,"y":300},"r1":{"type":"Relais","x":400,"y":500},"r2":{"type":"Relais","x":1000,"y":500},"c3":{"type":"Bouton","x":200,"y":500,"orientation":0},"r2.double":{"type":"ContactDouble","relais":"r2","orientation":0,"x":1000,"y":300},"w1":{"type":"Lampe","x":600,"y":500},"w2":{"type":"Lampe","x":600,"y":200},"n1":{"type":"Noeud","x":800,"y":500},"coude1":{"type":"Coude","x":800,"y":310}},"cables":[["p24-1","d","c3","g"],["c3","d","r1","g"],["r1","d","w1","g"],["w1","d","n1","m"],["n1","m","r2","g"],["r2","d","p0-1","g"],["n1","m","coude1","m"],["coude1","m","r2.double","hg"],["r2.double","d","p0-2","g"],["p24-2","d","w2","g"],["w2","d","r2.double","bg"]]}