functionalities
This commit is contained in:
parent
88aced27bf
commit
2e59700bfa
Binary file not shown.
Binary file not shown.
@ -184,6 +184,21 @@ def release(obj):
|
|||||||
PROCESS_BASE.cmd_q().put({'cmd': "release", "args": obj})
|
PROCESS_BASE.cmd_q().put({'cmd': "release", "args": obj})
|
||||||
return "OK"
|
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():
|
def just_run():
|
||||||
"""
|
"""
|
||||||
|
@ -3,6 +3,10 @@ import json
|
|||||||
|
|
||||||
class State(object):
|
class State(object):
|
||||||
IGNORE = frozenset(['Coude', 'Noeud', 'P24', 'P0', 'Pulse'])
|
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):
|
def __init__(self, cocosim_server):
|
||||||
self.cocosim_server = cocosim_server
|
self.cocosim_server = cocosim_server
|
||||||
@ -39,3 +43,4 @@ class State(object):
|
|||||||
|
|
||||||
def reset_exception(self):
|
def reset_exception(self):
|
||||||
self._exception = None
|
self._exception = None
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ class CocosimInstance(object):
|
|||||||
conf_fp = open("modele/config.json")
|
conf_fp = open("modele/config.json")
|
||||||
conf = json.load(conf_fp)
|
conf = json.load(conf_fp)
|
||||||
|
|
||||||
|
self.pause_simulation = False #pause flag
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.dt = self.conf['circuit']['DT']
|
self.dt = self.conf['circuit']['DT']
|
||||||
self.cocosim = None
|
self.cocosim = None
|
||||||
@ -47,15 +48,19 @@ class CocosimInstance(object):
|
|||||||
if message == "start":
|
if message == "start":
|
||||||
logging.log(logging.INFO, "Starting")
|
logging.log(logging.INFO, "Starting")
|
||||||
self.runner = asyncio.create_task(self.run())
|
self.runner = asyncio.create_task(self.run())
|
||||||
|
|
||||||
elif message == "stop":
|
elif message == "stop":
|
||||||
logging.log(logging.INFO, "Stopping")
|
logging.log(logging.INFO, "Stopping")
|
||||||
await self.stop()
|
await self.stop()
|
||||||
|
|
||||||
elif message == "state":
|
elif message == "state":
|
||||||
self.state_q.put(self.state.to_json())
|
self.state_q.put(self.state.to_json())
|
||||||
|
|
||||||
elif message == "quit":
|
elif message == "quit":
|
||||||
logging.log(logging.INFO, "Quitting")
|
logging.log(logging.INFO, "Quitting")
|
||||||
await self.stop()
|
await self.stop()
|
||||||
self.quit = True
|
self.quit = True
|
||||||
|
|
||||||
elif message == "load":
|
elif message == "load":
|
||||||
logging.log(logging.INFO, "Loading file")
|
logging.log(logging.INFO, "Loading file")
|
||||||
try:
|
try:
|
||||||
@ -63,6 +68,17 @@ class CocosimInstance(object):
|
|||||||
self.state_q.put("OK")
|
self.state_q.put("OK")
|
||||||
except GraphStructException:
|
except GraphStructException:
|
||||||
self.state_q.put("Error")
|
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":
|
elif message == "push":
|
||||||
but_name = data['args']
|
but_name = data['args']
|
||||||
logging.log(logging.INFO, f"Push button {but_name}")
|
logging.log(logging.INFO, f"Push button {but_name}")
|
||||||
@ -103,12 +119,17 @@ class CocosimInstance(object):
|
|||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
try:
|
try:
|
||||||
while True:
|
while not self.quit:
|
||||||
|
if not self.pause_simulation:
|
||||||
self.state.reset_exception()
|
self.state.reset_exception()
|
||||||
self.cycle()
|
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)
|
await asyncio.sleep(self.dt)
|
||||||
except:
|
except Exception as e:
|
||||||
logging.exception("Exception occured in 'cycle'")
|
logging.exception("Exception occured during simulation run")
|
||||||
|
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
if self.runner:
|
if self.runner:
|
||||||
|
Binary file not shown.
19
cocosim.log
19
cocosim.log
@ -1,19 +1,2 @@
|
|||||||
INFO:root:Creating instance
|
INFO:root:Creating instance
|
||||||
INFO:root:Loading file
|
INFO:root:Cocosim instance destroyed
|
||||||
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
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,5 @@
|
|||||||
from modele.exceptions import NonPolariseException, Dir
|
from modele.exceptions import NonPolariseException, Dir
|
||||||
|
|
||||||
|
|
||||||
class Composant(object):
|
class Composant(object):
|
||||||
def __init__(self, conf, nom):
|
def __init__(self, conf, nom):
|
||||||
"""
|
"""
|
||||||
@ -39,6 +38,10 @@ class Composant(object):
|
|||||||
def etat(self):
|
def etat(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def pause_simulation(self):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Contact(Composant):
|
class Contact(Composant):
|
||||||
def __init__(self, conf, nom, contact_type):
|
def __init__(self, conf, nom, contact_type):
|
||||||
@ -117,6 +120,8 @@ class Relais(Composant):
|
|||||||
self._contacts_repos = []
|
self._contacts_repos = []
|
||||||
self._contacts_double = []
|
self._contacts_double = []
|
||||||
self.haut = False
|
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):
|
def add_travail(self, nom):
|
||||||
self._contacts_travail.append(nom)
|
self._contacts_travail.append(nom)
|
||||||
@ -150,12 +155,16 @@ class Relais(Composant):
|
|||||||
self.graphe[nom].desactive()
|
self.graphe[nom].desactive()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
etat_precedent = self.haut
|
||||||
super().update()
|
super().update()
|
||||||
if self.branche.i() >= self.SEUIL:
|
if self.branche.i() >= self.SEUIL:
|
||||||
self.monte()
|
self.monte()
|
||||||
else:
|
else:
|
||||||
self.chute()
|
self.chute()
|
||||||
|
|
||||||
|
if self.est_point_arret and etat_precedent != self.haut:
|
||||||
|
self.graphe.flag_arret_simulation = True
|
||||||
|
|
||||||
def etat(self):
|
def etat(self):
|
||||||
return self.haut
|
return self.haut
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"RES_RELAIS": 100.0,
|
"RES_RELAIS": 100.0,
|
||||||
"SEUIL_RELAIS": 0.05,
|
"SEUIL_RELAIS": 0.05,
|
||||||
"SEUIL_TEMPO": 0.05,
|
"SEUIL_TEMPO": 0.05,
|
||||||
"PULSE_PERIODE": 1.0
|
"PULSE_PERIODE": 1.0,
|
||||||
|
"TOLERANCE_COURANT": 1e6
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"DT": 0.13,
|
"DT": 0.13,
|
||||||
|
@ -140,6 +140,26 @@ class Noeud(Element):
|
|||||||
return self.u() >= self.conf['USEUIL']
|
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):
|
class Branche(Element):
|
||||||
"""
|
"""
|
||||||
Branche du graphe.
|
Branche du graphe.
|
||||||
|
@ -38,6 +38,7 @@ class Graphe(object):
|
|||||||
self.elements = None
|
self.elements = None
|
||||||
self.composants = None
|
self.composants = None
|
||||||
self.vecteur = None
|
self.vecteur = None
|
||||||
|
self.flag_arret_simulation = False
|
||||||
|
|
||||||
def load_data_from_schema_reader(self, reader):
|
def load_data_from_schema_reader(self, reader):
|
||||||
self.elements = {}
|
self.elements = {}
|
||||||
|
1
schemas_v1/output-file.ccs
Normal file
1
schemas_v1/output-file.ccs
Normal 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"]]}
|
1
schemas_v1/output-file11.ccs
Normal file
1
schemas_v1/output-file11.ccs
Normal 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"]]}
|
Loading…
x
Reference in New Issue
Block a user