import de fichiers

This commit is contained in:
bendidi 2024-02-28 11:40:09 +01:00
parent 25610fd4fa
commit 88aced27bf
112 changed files with 3678 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

218
api_server/app.py Normal file
View File

@ -0,0 +1,218 @@
"""
Lancer avec python -m flask --debug --app server\\__init__.py run
"""
import logging
import sys
import time
from flask import Flask, request, session
import multiprocessing as mp
from api_worker.__init__ import run_instance
import uuid
from flask_cors import CORS
app = Flask("COCOSIM")
CORS(app, supports_credentials=True)
app.secret_key = bytes.fromhex('192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf')
class ProcessBase(object):
SESSION_MAX_AGE = 60 * 5
def __init__(self):
self._cmd_q = {}
self._state_q = {}
self._process = {}
self._last = {}
def known(self):
return 'id' in session and session['id'] in self._cmd_q
def update(self):
self._last[session['id']] = time.time()
def cmd_q(self):
self.update()
return self._cmd_q[session['id']]
def state_q(self):
self.update()
return self._state_q[session['id']]
def init_q(self):
self.update()
self._state_q[session['id']] = mp.Queue()
self._cmd_q[session['id']] = mp.Queue()
def init_process(self, p):
self.update()
self.cleanup()
self._process[session['id']] = p
def process(self):
return self._process[session['id']]
def purge(self, k=None):
if k is None:
k = session['id']
del self._cmd_q[k]
del self._state_q[k]
del self._process[k]
del self._last[k]
def quit(self):
self.purge()
self.cleanup()
def cleanup(self):
ctime = time.time()
to_purge = []
for k, v in self._last.items():
if ctime - v > self.SESSION_MAX_AGE:
to_purge.append(k)
for k in to_purge:
logging.info(f"Purging {k}")
self.purge(k)
def __str__(self):
return str(list(self._process.keys()))
def __len__(self):
return len(self._process.keys())
PROCESS_BASE = ProcessBase()
@app.route('/')
def hello():
PROCESS_BASE.cleanup()
return f"Hello sailor !\nProcess base : {str(PROCESS_BASE)}"
@app.route('/init')
def init():
session['id'] = uuid.uuid4().int
PROCESS_BASE.init_q()
PROCESS_BASE.init_process(mp.Process(target=run_instance, args=(session['id'], PROCESS_BASE.cmd_q(), PROCESS_BASE.state_q())))
PROCESS_BASE.process().start()
return "OK"
@app.route('/start')
def start():
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "start"})
return "OK"
@app.route('/stop')
def stop():
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "stop"})
return "OK"
@app.route('/state')
def state():
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "state"})
data = PROCESS_BASE.state_q().get()
return data
@app.route('/quit')
def quit():
if not PROCESS_BASE.known():
PROCESS_BASE.cleanup()
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "quit"})
PROCESS_BASE.process().join()
PROCESS_BASE.quit()
del session['id']
logging.info("Purge effectuée")
return "OK"
@app.route('/load', methods=['POST'])
def load():
if not PROCESS_BASE.known():
return "Unknown", 401
try:
data = request.json
PROCESS_BASE.cmd_q().put({'cmd': "load", "args": data})
except Exception:
logging.exception("ERROR")
return "Error", 418
if PROCESS_BASE.state_q().get() == "OK":
return "OK"
else:
return "Error in graph", 418
@app.route('/push/<obj>')
def push(obj):
"""
Push button
"""
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "push", "args": obj})
return "OK"
@app.route('/release/<obj>')
def release(obj):
"""
Release button
"""
if not PROCESS_BASE.known():
return "Unknown", 401
PROCESS_BASE.cmd_q().put({'cmd': "release", "args": obj})
return "OK"
def just_run():
"""
Pour lancer avec gunicorn
"""
mp.set_start_method('spawn')
app.run() # Ne pas mettre debug en mode multiprocess
def main(argv):
host = '127.0.0.1'
ssl_context = None
for arg in argv[1:]:
if arg == '-remote':
host = '0.0.0.0'
elif arg == '-secure-cookie':
app.config.update(SESSION_COOKIE_SAMESITE="None", SESSION_COOKIE_SECURE="True")
elif arg == '-ssl':
ssl_context = 'adhoc'
elif arg == '-h':
print("""
Options :
-remote : bind on 0.0.0.0 instead of 127.0.0.1
-secure-cookie : send secure cookie (for browser UI to be happy)
-ssl : enable https with adhoc certificate
""")
sys.exit(0)
else:
print(f"Unknown argument : {arg}")
sys.exit(-1)
mp.set_start_method('spawn')
app.run(debug=False, host=host, port=5555, ssl_context=ssl_context) # Ne pas mettre debug en mode multiprocess

41
api_server/state.py Normal file
View File

@ -0,0 +1,41 @@
import json
class State(object):
IGNORE = frozenset(['Coude', 'Noeud', 'P24', 'P0', 'Pulse'])
def __init__(self, cocosim_server):
self.cocosim_server = cocosim_server
self.conf = self.cocosim_server.conf["ui"]
self.composants = {}
self._exception = None
def load_conf(self, schema_d):
# Chargement des blocs
for nom, valeur in schema_d['blocs'].items():
if valeur['type'] not in self.IGNORE:
self.composants[nom] = None
def to_json(self):
if self._exception:
return json.dumps({'exn': self._exception})
else:
return json.dumps(self.composants)
def __iter__(self):
return self.conf.__iter__
def items(self):
return self.composants.items()
def keys(self):
return self.composants.keys()
def update(self, nom, valeur):
self.composants[nom] = valeur
def exception(self, e):
self._exception = e
def reset_exception(self):
self._exception = None

19
api_server/test_client.py Normal file
View File

@ -0,0 +1,19 @@
import asyncio
async def tcp_client():
reader, writer = await asyncio.open_connection(
'127.0.0.1', 8888)
while not writer.is_closing():
message = input("> ")
print(f'Send: {message!r}')
writer.write(message.encode())
await writer.drain()
if message == "state":
data = await reader.read(1000)
else:
data = await reader.read(100)
print(f'Received: {data.decode()!r}')
asyncio.run(tcp_client())

135
api_worker/__init__.py Normal file
View File

@ -0,0 +1,135 @@
import json
import asyncio
from modele.donnees import SchemaReader, GraphStructException
from modele.graphe import Graphe
from modele.cocosim import Cocosim
from api_server.state import State
import logging
import modele.exceptions
class CocosimInstance(object):
def __init__(self, cmd_q, state_q):
self.runner = None
try:
conf_fp = open("modele/config.json")
conf = json.load(conf_fp)
self.conf = conf
self.dt = self.conf['circuit']['DT']
self.cocosim = None
self.state = None
self.cmd_q = cmd_q
self.state_q = state_q
self.quit = False
except (OSError, json.JSONDecodeError) as e:
logging.exception("Reading conf. file")
raise modele.G
def setup(self, schema_d):
logging.info("Setting up")
reader = SchemaReader(schema_d)
reader.process()
logging.info("Schema is loaded")
self.state = State(self)
self.state.load_conf(schema_d)
logging.info(f"State is made up with {len(self.state.composants)} items.")
graphe = Graphe(self.conf['circuit'])
graphe.load_data_from_schema_reader(reader)
logging.info("Graph is initialized.")
self.cocosim = Cocosim(self.conf, graphe, {}, {})
logging.info("Cocosim is initialized")
async def handler(self):
loop = asyncio.get_running_loop()
data = await loop.run_in_executor(None, self.cmd_q.get)
message = data['cmd']
try:
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:
self.setup(data['args'] if type(data['args']) == dict else json.loads(data['args'])) # Compatibilité avec certaines IHM
self.state_q.put("OK")
except GraphStructException:
self.state_q.put("Error")
elif message == "push":
but_name = data['args']
logging.log(logging.INFO, f"Push button {but_name}")
if self.cocosim.graphe[but_name] == "Bouton":
self.cocosim.graphe[but_name].ferme()
else:
self.cocosim.graphe[but_name].bascule()
elif message == "release":
but_name = data['args']
logging.log(logging.INFO, f"Release button {but_name}")
if self.cocosim.graphe[but_name].type == "Bouton":
self.cocosim.graphe[but_name].ouvre()
# Dans le cas contraire on ne traite pas le release
else:
logging.log(logging.ERROR, "Commande inconnue")
except Exception:
logging.exception("Exception occured in handler")
def cycle(self):
try:
self.cocosim.cycle()
for nom in self.state.keys():
if nom not in self.cocosim.graphe and nom[-7:] == ".double": # TODO : a supprimer apràs refactoring contact double
nom_translate = nom[:-7] + ".travail"
value = self.cocosim.graphe[nom_translate].etat() if nom_translate in self.cocosim.graphe else None
self.state.update(nom, value)
else:
value = self.cocosim.graphe[nom].etat() if nom in self.cocosim.graphe else None
self.state.update(nom, value)
except modele.base.SurintensiteException as e:
self.state.exception("Surintensité")
raise e
except modele.base.SurtensionException as e:
self.state.exception("Surtension")
raise e
async def run(self):
try:
while True:
self.state.reset_exception()
self.cycle()
await asyncio.sleep(self.dt)
except:
logging.exception("Exception occured in 'cycle'")
async def stop(self):
if self.runner:
self.runner.cancel()
try:
await self.runner
except asyncio.CancelledError:
logging.info("Runner is stopped.")
self.runner = None
async def handle_requests(self):
while not self.quit:
await self.handler()
logging.info("Stop handling request")
def __del__(self):
logging.info("Cocosim instance destroyed")
def run_instance(uid, cmd_q, state_q):
logging.basicConfig(filename=f"cocosim.log", filemode="w", level=logging.INFO)
logging.info("Creating instance")
i = CocosimInstance(cmd_q, state_q)
asyncio.run(i.handle_requests())

Binary file not shown.

View File

View File

View File

19
cocosim.log Normal file
View File

@ -0,0 +1,19 @@
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

BIN
images_v1/CoCoSIM_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="256"
height="256"
viewBox="0 0 256 256"
fill="none"
version="1.1"
id="svg71"
sodipodi:docname="CoCoSIM_icon.svg"
inkscape:export-filename="CoCoSIM_icon.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview73"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="3.3189655"
inkscape:cx="-31.184416"
inkscape:cy="125.49091"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="2391"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="svg71" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1">
<rect
style="fill:#000000;stroke-width:4.75706"
id="rect286"
width="256.48053"
height="256.55585"
x="-0.60259742"
y="-0.67792207" />
</g>
<g
clip-path="url(#clip0_22_80)"
id="g64"
transform="matrix(10.390846,0,0,10.390846,24,3.997707)">
<path
d="M 2.49756,19.4869 C 2.61625,19.6506 2.581,19.8814 2.41915,20.0014 2.2573,20.1215 2.02926,20.0859 1.91057,19.9221 1.29913,19.0808 0.815726,18.1383 0.487704,17.1252 0.171191,16.1463 -7.32422e-4,15.1012 -7.32422e-4,14.0182 -7.32422e-4,12.4309 0.366854,10.9279 1.02002,9.59315 1.69836,8.20814 2.68459,7.00509 3.88878,6.07641 4.04847,5.95341 4.2765,5.98398 4.39807,6.14555 4.51964,6.30712 4.48943,6.53784 4.32974,6.66084 3.21403,7.52183 2.29974,8.63609 1.67175,9.91848 1.0675,11.1521 0.727966,12.5444 0.727966,14.0175 c 0,1.0065 0.158256,1.9745 0.451034,2.8791 0.30356,0.9382 0.75171,1.8108 1.31784,2.5896 M 18.7649,11.9061 c -0.0454,-0.198 0.0762,-0.3959 0.2719,-0.4425 0.1956,-0.0459 0.3913,0.0771 0.4373,0.2751 0.0849,0.369 0.1504,0.746 0.1936,1.1296 0.0431,0.3799 0.0654,0.7634 0.0654,1.1484 0,2.7562 -1.1042,5.2518 -2.8896,7.059 -1.7854,1.8064 -4.2521,2.9236 -6.97695,2.9236 -0.91573,0 -1.80556,-0.1274 -2.65151,-0.3661 C 6.34391,23.3879 5.52025,23.0233 4.76278,22.5597 4.59158,22.4549 4.53691,22.2285 4.64049,22.0553 4.74408,21.8821 4.9678,21.826 5.139,21.9316 c 0.69993,0.4287 1.46243,0.7656 2.27026,0.9934 0.77905,0.2191 1.60342,0.337 2.45801,0.337 2.52343,0 4.80813,-1.0349 6.46113,-2.7074 1.6538,-1.6732 2.676,-3.984 2.676,-6.5371 0,-0.3632 -0.0201,-0.7191 -0.0597,-1.0648 -0.0403,-0.3552 -0.1007,-0.7038 -0.1791,-1.0459 z"
fill="#ea4c89"
id="path56" />
<path
d="m 11.0398,4.12735 c -0.2331,-0.23581 -0.556,-0.38137 -0.9136,-0.38137 -0.35748,0 -0.67975,0.14629 -0.91353,0.38283 H 9.21123 c -0.23307,0.2358 -0.37694,0.56259 -0.37694,0.9243 0,0.36172 0.13739,0.67395 0.36111,0.9083 l 0.01727,0.01601 c 0.23378,0.23654 0.55677,0.38283 0.91353,0.38283 0.3568,0 0.6813,-0.14556 0.9136,-0.38137 l 0.0014,-0.00146 c 0.2331,-0.2358 0.377,-0.56259 0.377,-0.92431 0,-0.36171 -0.1439,-0.68922 -0.377,-0.9243 z M 10.1262,3.00799 c 0.5568,0 1.0611,0.22853 1.4279,0.59898 l 0.0022,0.00219 c 0.3654,0.37117 0.5913,0.88136 0.5913,1.44323 0,0.56186 -0.2259,1.0735 -0.592,1.44468 L 11.5534,6.49926 C 11.1866,6.86898 10.6823,7.09751 10.127,7.09751 9.57162,7.09751 9.06376,6.86825 8.69761,6.49853 L 8.67747,6.47597 C 8.32355,6.10697 8.10559,5.60479 8.10559,5.05239 8.10559,4.49998 8.33218,3.97815 8.69833,3.60697 9.06304,3.23579 9.56874,3.00726 10.127,3.00726 Z"
fill="#2ed73c"
id="path58" />
<path
d="m 7.59772,10.9221 c 0.09135,-0.1812 0.31075,-0.2533 0.48987,-0.1616 0.17912,0.0925 0.25033,0.3145 0.1597,0.4957 L 2.58027,22.5124 C 2.48891,22.6936 2.26951,22.7656 2.0904,22.6739 1.91128,22.5815 1.84006,22.3595 1.9307,22.1783 Z"
fill="#2d7aff"
id="path60" />
<path
d="m 2.57814,21.9964 h 2.05805 c 3.7406,-1.9251 5.01169,-4.38 4.95702,-6.543 C 9.55005,13.7402 8.68251,12.203 7.56033,11.262 6.48203,10.3581 5.17858,10.016 4.19523,10.6412 L 4.11466,10.695 c -0.01295,0.011 -0.02661,0.0204 -0.041,0.0299 -0.87904,0.6463 -1.50559,2.1113 -1.50559,4.695 H 2.56663 l 0.01079,6.5772 z M 17.2427,14.647 c -7e-4,1.0801 -0.2359,2.0451 -0.2373,2.0524 l -0.0029,0.0124 c -1.4409,5.7707 -5.3527,6.0196 -5.3635,6.0204 l -0.0287,0.0014 H 2.21631 c -0.20142,0 -0.36471,-0.1652 -0.36471,-0.3683 L 1.85304,22.3326 1.84153,15.4199 H 1.84009 c 0,-2.735 0.69201,-4.3755 1.68039,-5.1914 V 8.36753 c 0,-2.23872 0.78481,-4.29549 2.14294,-5.80931 C 6.9791,1.09169 8.83214,0.13609 11.029,0.0167308 14.1388,-0.152119 16.3831,0.991986 17.8527,2.71469 c 0.9402,1.10262 1.5589,2.44032 1.8804,3.81951 0.3209,1.37482 0.3475,2.79621 0.1058,4.0706 -0.3439,1.81 -1.2316,3.3326 -2.5962,4.0422 z M 13.5381,4.88209 c 0,-0.00728 0.0453,-2.36463 2.3825,-2.92504 C 14.6797,1.12081 13.072,0.641185 11.0664,0.750355 9.07312,0.858798 7.39417,1.72488 6.20221,3.05312 4.96493,4.43231 4.2499,6.31295 4.2499,8.3668 V 9.78966 C 5.44689,9.3013 6.86113,9.71688 8.02575,10.6936 c 1.26677,1.0619 2.24585,2.8013 2.29475,4.7416 0.0546,2.1703 -1.04668,4.5837 -4.2003,6.5604 h 5.48 c 0.2647,-0.0247 3.4399,-0.4257 4.6973,-5.4672 0.0302,-0.1259 1.1711,-4.9811 -2.2616,-3.8821 -0.0417,0.0167 -0.087,0.0255 -0.1338,0.0255 -0.2014,0 -0.3647,-0.1653 -0.3647,-0.369 V 4.89228 h 0.0014 z m 3.1745,-2.29986 c -2.3163,0.14556 -2.4415,2.15211 -2.448,2.30932 h 0.0015 v 6.92865 c 2.0516,-0.4832 2.7479,0.6893 2.9256,2.0051 0.9955,-0.6586 1.6552,-1.8981 1.9329,-3.3595 0.223,-1.17541 0.1978,-2.48983 -0.1,-3.76493 C 18.7282,5.43012 18.1621,4.20232 17.3032,3.19577 17.1197,2.98107 16.9234,2.7751 16.7126,2.58223 Z"
fill="#2d7aff"
id="path62" />
</g>
<defs
id="defs69">
<clipPath
id="clip0_22_80">
<rect
width="20"
height="24"
fill="#ffffff"
id="rect66"
x="0"
y="0" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

BIN
images_v1/bouton_ferme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M4.199,50.153 L73.998,45.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M60.429,46.554 L55.564,54.459 L61.854,53.716 L55.92,61.131 L62.505,60.135 L55.974,68.734 C55.974,68.734 62.767,67.244 62.767,67.244" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
images_v1/bouton_ouvert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M5.417,50.404 L73.417,30.404" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M59.29,36.05 L56.43,45.325 L62.325,42.358 L58.32,51.552 L64.443,48.238 L60.137,58.773 C60.137,58.773 66.345,54.913 66.345,54.913" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
images_v1/condensateur.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,50.5 L36.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M44.5,50.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M36.5,30.5 L36.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M44.5,30.5 L44.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M70.5,20.5 L38.12,96.229" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M5,38 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M55,38 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M70.5,24.5 C70.5,22.291 72.739,20.5 75.5,20.5 C78.261,20.5 80.5,22.291 80.5,24.5 C80.5,26.709 78.261,28.5 75.5,28.5 C72.739,28.5 70.5,26.709 70.5,24.5 z" fill="#000000"/>
<path d="M70.5,24.5 C70.5,22.291 72.739,20.5 75.5,20.5 C78.261,20.5 80.5,22.291 80.5,24.5 C80.5,26.709 78.261,28.5 75.5,28.5 C72.739,28.5 70.5,26.709 70.5,24.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M32.5,96.5 C32.5,94.291 34.739,92.5 37.5,92.5 C40.261,92.5 42.5,94.291 42.5,96.5 C42.5,98.709 40.261,100.5 37.5,100.5 C34.739,100.5 32.5,98.709 32.5,96.5 z" fill="#000000"/>
<path d="M32.5,96.5 C32.5,94.291 34.739,92.5 37.5,92.5 C40.261,92.5 42.5,94.291 42.5,96.5 C42.5,98.709 40.261,100.5 37.5,100.5 C34.739,100.5 32.5,98.709 32.5,96.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M0.5,24.5 C0.5,22.291 2.739,20.5 5.5,20.5 C8.261,20.5 10.5,22.291 10.5,24.5 C10.5,26.709 8.261,28.5 5.5,28.5 C2.739,28.5 0.5,26.709 0.5,24.5 z" fill="#000000"/>
<path d="M0.5,24.5 C0.5,22.291 2.739,20.5 5.5,20.5 C8.261,20.5 10.5,22.291 10.5,24.5 C10.5,26.709 8.261,28.5 5.5,28.5 C2.739,28.5 0.5,26.709 0.5,24.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M10.5,20.5 L38.12,96.229" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M5,38 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M55,38 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M70.5,24.5 C70.5,22.291 72.739,20.5 75.5,20.5 C78.261,20.5 80.5,22.291 80.5,24.5 C80.5,26.709 78.261,28.5 75.5,28.5 C72.739,28.5 70.5,26.709 70.5,24.5 z" fill="#000000"/>
<path d="M70.5,24.5 C70.5,22.291 72.739,20.5 75.5,20.5 C78.261,20.5 80.5,22.291 80.5,24.5 C80.5,26.709 78.261,28.5 75.5,28.5 C72.739,28.5 70.5,26.709 70.5,24.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M32.5,96.5 C32.5,94.291 34.739,92.5 37.5,92.5 C40.261,92.5 42.5,94.291 42.5,96.5 C42.5,98.709 40.261,100.5 37.5,100.5 C34.739,100.5 32.5,98.709 32.5,96.5 z" fill="#000000"/>
<path d="M32.5,96.5 C32.5,94.291 34.739,92.5 37.5,92.5 C40.261,92.5 42.5,94.291 42.5,96.5 C42.5,98.709 40.261,100.5 37.5,100.5 C34.739,100.5 32.5,98.709 32.5,96.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M0.5,24.5 C0.5,22.291 2.739,20.5 5.5,20.5 C8.261,20.5 10.5,22.291 10.5,24.5 C10.5,26.709 8.261,28.5 5.5,28.5 C2.739,28.5 0.5,26.709 0.5,24.5 z" fill="#000000"/>
<path d="M0.5,24.5 C0.5,22.291 2.739,20.5 5.5,20.5 C8.261,20.5 10.5,22.291 10.5,24.5 C10.5,26.709 8.261,28.5 5.5,28.5 C2.739,28.5 0.5,26.709 0.5,24.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,60.5 L76.5,49" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,40.5 C2.291,40.5 0.5,38.261 0.5,35.5 C0.5,32.739 2.291,30.5 4.5,30.5 C6.709,30.5 8.5,32.739 8.5,35.5 C8.5,38.261 6.709,40.5 4.5,40.5 z" fill="#000000"/>
<path d="M4.5,40.5 C2.291,40.5 0.5,38.261 0.5,35.5 C0.5,32.739 2.291,30.5 4.5,30.5 C6.709,30.5 8.5,32.739 8.5,35.5 C8.5,38.261 6.709,40.5 4.5,40.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M4.5,70.5 C2.291,70.5 0.5,68.261 0.5,65.5 C0.5,62.739 2.291,60.5 4.5,60.5 C6.709,60.5 8.5,62.739 8.5,65.5 C8.5,68.261 6.709,70.5 4.5,70.5 z" fill="#000000"/>
<path d="M4.5,70.5 C2.291,70.5 0.5,68.261 0.5,65.5 C0.5,62.739 2.291,60.5 4.5,60.5 C6.709,60.5 8.5,62.739 8.5,65.5 C8.5,68.261 6.709,70.5 4.5,70.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,40.5 L76.5,49" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,40.5 C2.291,40.5 0.5,38.261 0.5,35.5 C0.5,32.739 2.291,30.5 4.5,30.5 C6.709,30.5 8.5,32.739 8.5,35.5 C8.5,38.261 6.709,40.5 4.5,40.5 z" fill="#000000"/>
<path d="M4.5,40.5 C2.291,40.5 0.5,38.261 0.5,35.5 C0.5,32.739 2.291,30.5 4.5,30.5 C6.709,30.5 8.5,32.739 8.5,35.5 C8.5,38.261 6.709,40.5 4.5,40.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M4.5,70.5 C2.291,70.5 0.5,68.261 0.5,65.5 C0.5,62.739 2.291,60.5 4.5,60.5 C6.709,60.5 8.5,62.739 8.5,65.5 C8.5,68.261 6.709,70.5 4.5,70.5 z" fill="#000000"/>
<path d="M4.5,70.5 C2.291,70.5 0.5,68.261 0.5,65.5 C0.5,62.739 2.291,60.5 4.5,60.5 C6.709,60.5 8.5,62.739 8.5,65.5 C8.5,68.261 6.709,70.5 4.5,70.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
images_v1/diode_dg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

22
images_v1/diode_dg.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M76.5,50.5 L4.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M68.5,0.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M68.5,50.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 z" fill="#000000"/>
<path d="M76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 z" fill="#000000"/>
<path d="M4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M24.5,76.5 L24.5,25.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<g>
<path d="M56.5,75.5 L24.5,50.5 L56.5,25.5 L56.5,75.5 z" fill="#000000"/>
<path d="M56.5,75.5 L24.5,50.5 L56.5,25.5 L56.5,75.5 z" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linejoin="bevel"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images_v1/diode_gd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

22
images_v1/diode_gd.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,50.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M56.5,25.5 L56.5,75.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<g>
<path d="M24.5,25.5 L56.5,50.5 L24.5,75.5 z" fill="#000000"/>
<path d="M24.5,25.5 L56.5,50.5 L24.5,75.5 z" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linejoin="bevel"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images_v1/lampe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

22
images_v1/lampe.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M5.5,55.5 C2.739,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.739,45.5 5.5,45.5 C8.261,45.5 10.5,47.739 10.5,50.5 C10.5,53.261 8.261,55.5 5.5,55.5 z" fill="#000000"/>
<path d="M5.5,55.5 C2.739,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.739,45.5 5.5,45.5 C8.261,45.5 10.5,47.739 10.5,50.5 C10.5,53.261 8.261,55.5 5.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M75.5,55.5 C72.739,55.5 70.5,53.261 70.5,50.5 C70.5,47.739 72.739,45.5 75.5,45.5 C78.261,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.261,55.5 75.5,55.5 z" fill="#000000"/>
<path d="M75.5,55.5 C72.739,55.5 70.5,53.261 70.5,50.5 C70.5,47.739 72.739,45.5 75.5,45.5 C78.261,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.261,55.5 75.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M40.5,80.5 C23.931,80.5 10.5,67.069 10.5,50.5 C10.5,33.931 23.931,20.5 40.5,20.5 C57.069,20.5 70.5,33.931 70.5,50.5 C70.5,67.069 57.069,80.5 40.5,80.5 z" fill="#FFFFFF"/>
<path d="M40.5,80.5 C23.931,80.5 10.5,67.069 10.5,50.5 C10.5,33.931 23.931,20.5 40.5,20.5 C57.069,20.5 70.5,33.931 70.5,50.5 C70.5,67.069 57.069,80.5 40.5,80.5 z" fill-opacity="0" stroke="#000000" stroke-width="2.7"/>
</g>
<path d="M20.5,70.5 L60.5,30.5" fill-opacity="0" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
<path d="M20.5,30.5 L60.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
images_v1/levier_ferme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

100
images_v1/levier_ferme.svg Normal file
View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0"
y="0"
width="80"
height="100"
viewBox="0, 0, 80, 100"
id="svg10"
sodipodi:docname="levier_ouvert.svg"
inkscape:version="1.3-beta (cedbd6c, 2023-05-28)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="8.2929269"
inkscape:cx="33.884297"
inkscape:cy="51.972001"
inkscape:window-width="1710"
inkscape:window-height="1069"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="0"
inkscape:current-layer="svg10" />
<path
d="M 12.5,101.5 Z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path1" />
<path
d="M 12.5,51.5 Z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path2" />
<g
id="g4">
<path
d="m 5.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill="#000000"
id="path3" />
<path
d="m 5.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path4" />
</g>
<g
id="g6"
transform="translate(-0.72350814)">
<path
d="m 75.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill="#000000"
id="path5" />
<path
d="m 75.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path6" />
</g>
<g
id="g8">
<path
d="m 40.5,80.5 c -16.569,0 -30,-13.431 -30,-30 0,-16.569 13.431,-30 30,-30 16.569,0 30,13.431 30,30 0,16.569 -13.431,30 -30,30 z"
fill="#ffffff"
id="path7" />
<path
d="m 40.5,80.5 c -16.569,0 -30,-13.431 -30,-30 0,-16.569 13.431,-30 30,-30 16.569,0 30,13.431 30,30 0,16.569 -13.431,30 -30,30 z"
fill-opacity="0"
stroke="#000000"
stroke-width="2.7"
id="path8" />
</g>
<path
style="fill:#121212;stroke:#000000;stroke-width:4.41824"
id="path11"
sodipodi:type="arc"
sodipodi:cx="40.160213"
sodipodi:cy="49.300335"
sodipodi:rx="29.252346"
sodipodi:ry="27.2386"
sodipodi:start="3.1415927"
sodipodi:end="0"
sodipodi:arc-type="slice"
d="m 10.907867,49.300335 a 29.252346,27.2386 0 0 1 29.252346,-27.2386 29.252346,27.2386 0 0 1 29.252347,27.2386 H 40.160213 Z" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
images_v1/levier_ouvert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

106
images_v1/levier_ouvert.svg Normal file
View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0"
y="0"
width="80"
height="100"
viewBox="0, 0, 80, 100"
id="svg10"
sodipodi:docname="levier_ferme.svg"
inkscape:version="1.3-beta (cedbd6c, 2023-05-28)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="8.2929269"
inkscape:cx="33.884297"
inkscape:cy="51.972001"
inkscape:window-width="1710"
inkscape:window-height="1069"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="0"
inkscape:current-layer="svg10" />
<path
d="M 12.5,101.5 Z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path1" />
<path
d="M 12.5,51.5 Z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path2" />
<g
id="g4">
<path
d="m 5.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill="#000000"
id="path3" />
<path
d="m 5.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path4" />
</g>
<g
id="g6">
<path
d="m 75.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill="#000000"
id="path5" />
<path
d="m 75.5,55.5 c -2.761,0 -5,-2.239 -5,-5 0,-2.761 2.239,-5 5,-5 2.761,0 5,2.239 5,5 0,2.761 -2.239,5 -5,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path6" />
</g>
<g
id="g8">
<path
d="m 40.5,80.5 c -16.569,0 -30,-13.431 -30,-30 0,-16.569 13.431,-30 30,-30 16.569,0 30,13.431 30,30 0,16.569 -13.431,30 -30,30 z"
fill="#ffffff"
id="path7" />
<path
d="m 40.5,80.5 c -16.569,0 -30,-13.431 -30,-30 0,-16.569 13.431,-30 30,-30 16.569,0 30,13.431 30,30 0,16.569 -13.431,30 -30,30 z"
fill-opacity="0"
stroke="#000000"
stroke-width="2.7"
id="path8" />
</g>
<path
d="m 20.5,70.5 40,-40"
fill-opacity="0"
stroke="#000000"
stroke-width="2"
stroke-linecap="round"
id="path9" />
<path
style="fill:#121212;stroke:#000000;stroke-width:4.41824"
id="path11"
sodipodi:type="arc"
sodipodi:cx="40.160213"
sodipodi:cy="49.300335"
sodipodi:rx="29.252346"
sodipodi:ry="27.2386"
sodipodi:start="2.3561945"
sodipodi:end="5.4925512"
sodipodi:arc-type="slice"
d="M 19.475681,68.560933 A 29.252346,27.2386 0 0 1 19.421601,30.090226 29.252346,27.2386 0 0 1 60.73616,29.939153 L 40.160213,49.300335 Z" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

BIN
images_v1/mirror_moins.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

BIN
images_v1/mirror_plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
images_v1/mirror_pulse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<text transform="matrix(1, 0, 0, 1, 44.212, 50)">
<tspan x="-20.012" y="5.5" font-family="Helvetica" font-size="16" fill="#000000">Pulsé</tspan>
</text>
<text transform="matrix(1, 0, 0, 1, 47.2, 33.5)">
<tspan x="-24.427" y="6.5" font-family="Helvetica" font-size="28.8" fill="#000000">+24</tspan>
</text>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

BIN
images_v1/moins.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

15
images_v1/moins.svg Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<text transform="matrix(1, 0, 0, 1, 22.837, 29)">
<tspan x="-8.991" y="12" font-family="Helvetica" font-size="54" fill="#000000">-</tspan>
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
images_v1/noeud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

12
images_v1/noeud.svg Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M40.5,55.5 C38.291,55.5 36.5,53.261 36.5,50.5 C36.5,47.739 38.291,45.5 40.5,45.5 C42.709,45.5 44.5,47.739 44.5,50.5 C44.5,53.261 42.709,55.5 40.5,55.5 z" fill="#000000"/>
<path d="M40.5,55.5 C38.291,55.5 36.5,53.261 36.5,50.5 C36.5,47.739 38.291,45.5 40.5,45.5 C42.709,45.5 44.5,47.739 44.5,50.5 C44.5,53.261 42.709,55.5 40.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 921 B

BIN
images_v1/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

15
images_v1/plus.svg Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<text transform="matrix(1, 0, 0, 1, 47.2, 33.5)">
<tspan x="-24.427" y="6.5" font-family="Helvetica" font-size="28.8" fill="#000000">+24</tspan>
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images_v1/pulse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

18
images_v1/pulse.svg Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<text transform="matrix(1, 0, 0, 1, 47.2, 33.5)">
<tspan x="-24.427" y="6.5" font-family="Helvetica" font-size="28.8" fill="#000000">+24</tspan>
</text>
<text transform="matrix(1, 0, 0, 1, 44.212, 50)">
<tspan x="-20.012" y="5.5" font-family="Helvetica" font-size="16" fill="#000000">Pulsé</tspan>
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images_v1/relais.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

22
images_v1/relais.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<g>
<path d="M8.5,10.5 L72.5,10.5 L72.5,90.5 L8.5,90.5 z" fill="#FFFFFF"/>
<path d="M8.5,10.5 L72.5,10.5 L72.5,90.5 L8.5,90.5 z" fill-opacity="0" stroke="#000000" stroke-width="4.05"/>
</g>
<path d="M8.5,30.5 L40.5,60.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M40.5,60.5 L72.5,30.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="160" height="100" viewBox="0, 0, 160, 100">
<g id="Layer_1">
<g>
<path d="M5,30.385 C2.239,30.385 0,28.189 0,25.481 C0,22.773 2.239,20.577 5,20.577 C7.761,20.577 10,22.773 10,25.481 C10,28.189 7.761,30.385 5,30.385 z" fill="#000000"/>
<path d="M5,30.385 C2.239,30.385 0,28.189 0,25.481 C0,22.773 2.239,20.577 5,20.577 C7.761,20.577 10,22.773 10,25.481 C10,28.189 7.761,30.385 5,30.385 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<g>
<g>
<path d="M9.678,8.5 L72.586,8.5 L72.586,88.5 L9.678,88.5 z" fill="#FFFFFF"/>
<path d="M9.678,8.5 L72.586,8.5 L72.586,88.5 L9.678,88.5 z" fill-opacity="0" stroke="#000000" stroke-width="4.05"/>
</g>
<path d="M9.678,28.5 L41.132,58.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M41.132,58.5 L72.586,28.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
</g>
<path d="M0,100 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M0,50 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<g>
<path d="M87.103,8.5 L150.011,8.5 L150.011,88.5 L87.103,88.5 z" fill="#FFFFFF"/>
<path d="M87.103,8.5 L150.011,8.5 L150.011,88.5 L87.103,88.5 z" fill-opacity="0" stroke="#000000" stroke-width="4.05"/>
</g>
<path d="M87.103,28.5 L118.557,58.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M118.557,58.5 L150.011,28.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
</g>
<g>
<path d="M70.378,8.5 L88.429,8.5 L88.429,88.5 L70.378,88.5 L70.378,8.5 z" fill="#000000"/>
<path d="M70.378,8.5 L88.429,8.5 L88.429,88.5 L70.378,88.5 L70.378,8.5 z" fill-opacity="0" stroke="#000000" stroke-width="1"/>
</g>
</g>
<g>
<path d="M5,69.916 C2.239,69.916 -0,67.677 -0,64.916 C-0,62.155 2.239,59.916 5,59.916 C7.761,59.916 10,62.155 10,64.916 C10,67.677 7.761,69.916 5,69.916 z" fill="#000000"/>
<path d="M5,69.916 C2.239,69.916 -0,67.677 -0,64.916 C-0,62.155 2.239,59.916 5,59.916 C7.761,59.916 10,62.155 10,64.916 C10,67.677 7.761,69.916 5,69.916 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M155.005,30.385 C152.247,30.385 150.011,28.146 150.011,25.385 C150.011,22.624 152.247,20.385 155.005,20.385 C157.764,20.385 160,22.624 160,25.385 C160,28.146 157.764,30.385 155.005,30.385 z" fill="#000000"/>
<path d="M155.005,30.385 C152.247,30.385 150.011,28.146 150.011,25.385 C150.011,22.624 152.247,20.385 155.005,20.385 C157.764,20.385 160,22.624 160,25.385 C160,28.146 157.764,30.385 155.005,30.385 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M155.005,69.916 C152.247,69.916 150.011,67.677 150.011,64.916 C150.011,62.155 152.247,59.916 155.005,59.916 C157.764,59.916 160,62.155 160,64.916 C160,67.677 157.764,69.916 155.005,69.916 z" fill="#000000"/>
<path d="M155.005,69.916 C152.247,69.916 150.011,67.677 150.011,64.916 C150.011,62.155 152.247,59.916 155.005,59.916 C157.764,59.916 160,62.155 160,64.916 C160,67.677 157.764,69.916 155.005,69.916 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
images_v1/relais_cote.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

107
images_v1/relais_cote.svg Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0"
y="0"
width="80"
height="100"
viewBox="0, 0, 80, 100"
id="svg29"
sodipodi:docname="relais_cote.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs33" />
<sodipodi:namedview
id="namedview31"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="8.14"
inkscape:cx="37.100737"
inkscape:cy="50.061425"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="svg29" />
<g
id="Layer_1">
<g
id="g6">
<path
d="M8.5,10.5 L72.5,10.5 L72.5,90.5 L8.5,90.5 z"
fill="#FFFFFF"
id="path2" />
<path
d="M8.5,10.5 L72.5,10.5 L72.5,90.5 L8.5,90.5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="4.05"
id="path4" />
</g>
<path
d="M8.5,30.5 L40.5,60.5"
fill-opacity="0"
stroke="#000000"
stroke-width="2.7"
stroke-linecap="round"
id="path8" />
<path
d="M40.5,60.5 L72.5,30.5"
fill-opacity="0"
stroke="#000000"
stroke-width="2.7"
stroke-linecap="round"
id="path10" />
<path
d="M12.5,101.5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path12" />
<path
d="M12.5,51.5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path14" />
</g>
<g
id="g26"
transform="translate(-71.954546,-22.40172)">
<path
d="m 76.5,55.5 c -2.209,0 -4,-2.239 -4,-5 0,-2.761 1.791,-5 4,-5 2.209,0 4,2.239 4,5 0,2.761 -1.791,5 -4,5 z"
fill="#000000"
id="path22" />
<path
d="m 76.5,55.5 c -2.209,0 -4,-2.239 -4,-5 0,-2.761 1.791,-5 4,-5 2.209,0 4,2.239 4,5 0,2.761 -1.791,5 -4,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path24" />
</g>
<g
id="g20"
transform="translate(0.07985261,18.114251)">
<path
d="m 4.5,55.5 c -2.209,0 -4,-2.239 -4,-5 0,-2.761 1.791,-5 4,-5 2.209,0 4,2.239 4,5 0,2.761 -1.791,5 -4,5 z"
fill="#000000"
id="path16" />
<path
d="m 4.5,55.5 c -2.209,0 -4,-2.239 -4,-5 0,-2.761 1.791,-5 4,-5 2.209,0 4,2.239 4,5 0,2.761 -1.791,5 -4,5 z"
fill-opacity="0"
stroke="#000000"
stroke-width="0.9"
id="path18" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
images_v1/repos_ferme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

23
images_v1/repos_ferme.svg Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,65.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M16.5,75.5 C14.291,75.5 12.5,73.261 12.5,70.5 C12.5,67.739 14.291,65.5 16.5,65.5 C18.709,65.5 20.5,67.739 20.5,70.5 C20.5,73.261 18.709,75.5 16.5,75.5 z" fill="#000000"/>
<path d="M16.5,75.5 C14.291,75.5 12.5,73.261 12.5,70.5 C12.5,67.739 14.291,65.5 16.5,65.5 C18.709,65.5 20.5,67.739 20.5,70.5 C20.5,73.261 18.709,75.5 16.5,75.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M4.5,50.5 L4.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M4.5,70.5 L16.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
images_v1/repos_ouvert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M16.5,50.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M16.5,75.5 C14.291,75.5 12.5,73.261 12.5,70.5 C12.5,67.739 14.291,65.5 16.5,65.5 C18.709,65.5 20.5,67.739 20.5,70.5 C20.5,73.261 18.709,75.5 16.5,75.5 z" fill="#000000"/>
<path d="M16.5,75.5 C14.291,75.5 12.5,73.261 12.5,70.5 C12.5,67.739 14.291,65.5 16.5,65.5 C18.709,65.5 20.5,67.739 20.5,70.5 C20.5,73.261 18.709,75.5 16.5,75.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M4.5,50.5 L4.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M4.5,70.5 L16.5,70.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
images_v1/resistance.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

19
images_v1/resistance.svg Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,50.5 L20.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M60.5,50.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="2.7" stroke-linecap="round"/>
<path d="M20.5,50.5 C20.5,50.5 20.5,35.5 20.5,35.5 L28.5,35.5 C28.5,35.5 28.5,65.5 28.5,65.5 C28.5,65.5 36.5,65.5 36.5,65.5 L36.5,35.5 L44.5,35.5 L44.5,65.5 L52.5,65.5 L52.5,35.5 L60.5,35.5 L60.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="2.7"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
images_v1/tempo_ferme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

25
images_v1/tempo_ferme.svg Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M4.199,50.153 L73.998,45.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M40.5,36.9 C35.033,36.9 30.601,31.489 30.601,24.815 C30.601,18.14 35.033,12.729 40.5,12.729 C45.967,12.729 50.399,18.14 50.399,24.815 C50.399,31.489 45.967,36.9 40.5,36.9 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M38.5,12.729 L38.5,7.729 L42.5,7.729 L42.5,12.729" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M45.682,14.113 L46.788,12.224 L48.304,13.611 L47.198,15.5" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M40.5,26.539 C40.044,26.539 39.674,26.075 39.674,25.503 C39.674,24.93 40.044,24.466 40.5,24.466 C40.956,24.466 41.326,24.93 41.326,25.503 C41.326,26.075 40.956,26.539 40.5,26.539 z" fill="#000000"/>
<path d="M40.5,26.539 C40.044,26.539 39.674,26.075 39.674,25.503 C39.674,24.93 40.044,24.466 40.5,24.466 C40.956,24.466 41.326,24.93 41.326,25.503 C41.326,26.075 40.956,26.539 40.5,26.539 z" fill-opacity="0" stroke="#000000" stroke-width="0.9" stroke-linejoin="bevel"/>
</g>
<path d="M40.521,16.651 L40.474,25.251" fill-opacity="0" stroke="#000000" stroke-width="0.9" stroke-linejoin="bevel"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
images_v1/tempo_ouvert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<path d="M4.199,50.153 L74.515,31.649" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M40.5,36.9 C35.033,36.9 30.601,31.489 30.601,24.815 C30.601,18.14 35.033,12.729 40.5,12.729 C45.967,12.729 50.399,18.14 50.399,24.815 C50.399,31.489 45.967,36.9 40.5,36.9 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M38.5,12.729 L38.5,7.729 L42.5,7.729 L42.5,12.729" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M45.682,14.113 L46.788,12.224 L48.304,13.611 L47.198,15.5" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M40.5,26.539 C40.044,26.539 39.674,26.075 39.674,25.503 C39.674,24.93 40.044,24.466 40.5,24.466 C40.956,24.466 41.326,24.93 41.326,25.503 C41.326,26.075 40.956,26.539 40.5,26.539 z" fill="#000000"/>
<path d="M40.5,26.539 C40.044,26.539 39.674,26.075 39.674,25.503 C39.674,24.93 40.044,24.466 40.5,24.466 C40.956,24.466 41.326,24.93 41.326,25.503 C41.326,26.075 40.956,26.539 40.5,26.539 z" fill-opacity="0" stroke="#000000" stroke-width="0.9" stroke-linejoin="bevel"/>
</g>
<path d="M40.521,16.651 L40.474,25.251" fill-opacity="0" stroke="#000000" stroke-width="0.9" stroke-linejoin="bevel"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
images_v1/travail_ferme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M8.5,75.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="80" height="100" viewBox="0, 0, 80, 100">
<g id="Layer_1">
<path d="M4.5,55.5 L76.5,50.5" fill-opacity="0" stroke="#000000" stroke-width="4.5" stroke-linecap="round"/>
<path d="M12.5,101.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<path d="M12.5,51.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
<g>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill="#000000"/>
<path d="M4.5,55.5 C2.291,55.5 0.5,53.261 0.5,50.5 C0.5,47.739 2.291,45.5 4.5,45.5 C6.709,45.5 8.5,47.739 8.5,50.5 C8.5,53.261 6.709,55.5 4.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
<g>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill="#000000"/>
<path d="M76.5,55.5 C74.291,55.5 72.5,53.261 72.5,50.5 C72.5,47.739 74.291,45.5 76.5,45.5 C78.709,45.5 80.5,47.739 80.5,50.5 C80.5,53.261 78.709,55.5 76.5,55.5 z" fill-opacity="0" stroke="#000000" stroke-width="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

52
modele/cocosim.py Normal file
View File

@ -0,0 +1,52 @@
from modele.matrice import Matrice
class Cocosim(object):
def __init__(self, conf, graphe, scenario, observateur):
self.conf = conf
self.graphe = graphe
self.scenario = scenario
if 'max' in self.scenario:
self.max_cycles = self.scenario['max']
else:
self.max_cycles = None
self.n_cycle = 0
self.matrice = Matrice(self.graphe)
self.observatoire = {}
self.observateur = observateur
for k,_,_ in self.observateur:
self.observatoire[k] = []
def cycle(self):
"""
Un cycle se fait en deux passes plus la mise à jour des composants.
"""
if self.n_cycle in self.scenario:
[f(self.graphe[x]) for x, f in self.scenario[self.n_cycle]]
self.graphe.init_cycle()
# Passe 1
self.matrice.init_mat()
xvect = self.matrice.solve()
self.graphe.passe_calcul(xvect)
# Passe 2 (pour les diodes)
self.matrice.init_mat()
xvect = self.matrice.solve()
self.graphe.passe_calcul(xvect)
# Mise à jour des états
self.graphe.update()
self.graphe.coherence()
for k, obj, fun in self.observateur:
self.observatoire[k].append(fun(self.graphe[obj]))
self.n_cycle += 1
def run(self):
for cycle in range(self.max_cycles):
self.cycle()

264
modele/composants.py Normal file
View File

@ -0,0 +1,264 @@
from modele.exceptions import NonPolariseException, Dir
class Composant(object):
def __init__(self, conf, nom):
"""
Un composant doit a minima savoir donner une résistance
"""
self.branche = None # Pour récupérer l'intensité dans la branche
self.nom = nom
self.conf = conf
self.r = None
def init_cycle(self):
"""
Initialisation du composant avant la 1ere passe de calcul.
Pour la plupart des composants (ceux qui se calculent en une seule passe) on ne fait
rien. N'est utile que pour les composants se calculant en plusieurs passes (diodes...).
"""
pass
def passe_calcul(self):
"""
Initialisation du composant apres la 1ere passe de calcul.
Pour la plupart des composants (ceux qui se calculent en une seule passe) on ne fait
rien. N'est utile que pour les composants se calculant en plusieurs passes (diodes...). """
pass
def update(self):
# Par défaut ne fait rien
pass
def reverse(self):
"""
Permet de retourner les composants polarisés (s'ils sont préfixés par "!")
"""
raise NonPolariseException
def etat(self):
raise NotImplementedError
class Contact(Composant):
def __init__(self, conf, nom, contact_type):
super().__init__(conf, nom)
self.ouvert = None
self.ouvre()
self.type = contact_type
def ouvre(self):
self.ouvert = True
self.r = self.conf['RMAX']
def ferme(self):
self.ouvert = False
self.r = self.conf['RMIN']
def etat(self):
return not self.ouvert
def bascule(self):
if self.ouvert:
self.ferme()
else:
self.ouvre()
class Resistance(Composant):
def __init__(self, conf, nom, valeur):
super().__init__(conf, nom)
self.RDEFAULT = self.conf["RES_DEFAULT"]
if valeur is None:
self.r = self.RDEFAULT
else:
self.r = valeur
def set_r(self, valeur):
self.r = valeur
def etat(self):
return None
class Lampe(Resistance):
def __init__(self, conf, nom):
self.RLAMPE = conf["RES_LAMPE"]
self.SEUIL = conf["SEUIL_LAMPE"]
super().__init__(conf, nom, self.RLAMPE)
self.haut = False
self.chute()
def monte(self):
self.haut = True
def chute(self):
self.haut = False
def update(self):
super().update()
if abs(self.branche.i()) >= self.SEUIL:
self.monte()
else:
self.chute()
def etat(self):
return self.haut
class Relais(Composant):
def __init__(self, conf, nom, graphe):
super().__init__(conf, nom)
self.graphe = graphe
self.r = self.conf["RES_RELAIS"]
self.SEUIL = self.conf["SEUIL_RELAIS"]
prefix = nom.split('.')
self._contacts_travail = []
self._contacts_repos = []
self._contacts_double = []
self.haut = False
def add_travail(self, nom):
self._contacts_travail.append(nom)
def add_repos(self, nom):
self._contacts_repos.append(nom)
def add_double(self, nom):
self._contacts_double.append(nom)
def monte(self):
self.haut = True
for nom in self._contacts_repos:
self.graphe[nom].ouvre()
for nom in self._contacts_travail:
self.graphe[nom].ferme()
for nom in self._contacts_double:
self.graphe[nom].active()
def chute(self):
self.haut = False
for nom in self._contacts_repos:
self.graphe[nom].ferme()
for nom in self._contacts_travail:
self.graphe[nom].ouvre()
for nom in self._contacts_double:
self.graphe[nom].desactive()
def update(self):
super().update()
if self.branche.i() >= self.SEUIL:
self.monte()
else:
self.chute()
def etat(self):
return self.haut
class DemiRelaisBasculeur(Composant):
def __init__(self, conf, nom, graphe, cote):
super().__init__(conf, nom)
self.SEUIL = self.conf["SEUIL_RELAIS"]
self.r = self.conf["RES_RELAIS"]
self._contacts_basc = []
self.haut = False
self.cote = cote
self.graphe = graphe
def add_contact(self, nom):
self._contacts_basc.append(nom)
def monte(self):
self.haut = True
if self.cote == Dir.GAUCHE:
for nom in self._contacts_basc:
self.graphe.elements[nom].bascule_gauche()
elif self.cote == Dir.DROITE:
for nom in self._contacts_basc:
self.graphe.elements[nom].bascule_droite()
else:
assert False
def chute(self):
self.haut = False
def update(self):
super().update()
if self.branche.i() >= self.SEUIL:
self.monte()
else:
self.chute()
def etat(self):
return self.haut
class Tempo(Composant):
"""
Tempo type "bilame piloté par le temps"
"""
def __init__(self, conf, nom, tempo_blocage, tempo_liberation):
super().__init__(conf, nom)
self.SEUIL = self.conf["SEUIL_TEMPO"]
self.h_trans = 0 # heure de la transition
self.h = 0 # heure courante
self.i_prec = 0.0 # intensité précédente
self.tempo_blocage = tempo_blocage / self.conf["DT"] # durée de la tempo de blocage
self.tempo_liberation = tempo_liberation / self.conf["DT"] # durée de la tempo de blocage
self.blocage = False
self.r = self.conf['RMIN']
def update(self):
if self.blocage:
if self.h - self.h_trans >= self.tempo_liberation:
self.h_trans = self.h
self.blocage = False
self.r = self.conf["RMIN"]
else:
if self.branche.i() >= self.SEUIL:
if self.i_prec < self.SEUIL:
self.h_trans = self.h # On mémorise l'heure de la transition
if self.h - self.h_trans >= self.tempo_blocage - 1:
self.r = self.conf["RMAX"]
self.blocage = True
self.h_trans = self.h # On mémorise l'heure à laquelle on bloque
else:
pass # On est au-delà du seuil mais la tempo n'est pas échue
self.i_prec = self.branche.i()
self.h += 1
@property
def ouvert(self):
return self.blocage
def etat(self):
return not self.blocage
class Diode(Composant):
def __init__(self, conf, nom):
super().__init__(conf, nom)
self.r = self.conf["RMAX"]
self.reversed = False # La diode est dans le sens opposé à la branche
def init_cycle(self):
self.r = self.conf["RMAX"]
def passe_calcul(self):
if (not self.reversed and (self.branche.amont.u() > self.branche.aval.u())) \
or (self.reversed and (self.branche.amont.u() < self.branche.aval.u())):
self.r = self.conf["RMIN"]
else:
self.r = self.conf["RMAX"]
def reverse(self):
self.reversed = True
def etat(self):
return None

28
modele/config.json Normal file
View File

@ -0,0 +1,28 @@
{
"circuit": {
"DT": 0.05,
"RMIN": 1E-32,
"RMAX": 1E32,
"UMAX": 24.5,
"USEUIL": 5,
"ISEUIL": 0.05,
"IMAX": 5.0,
"RES_DEFAULT": 100,
"RES_LAMPE": 100.0,
"SEUIL_LAMPE": 0.05,
"RES_RELAIS": 100.0,
"SEUIL_RELAIS": 0.05,
"SEUIL_TEMPO": 0.05,
"PULSE_PERIODE": 1.0
},
"ui": {
"DT": 0.13,
"BLOCK_H": 50,
"BLOCK_W": 40,
"RELAISBASC_WIDTH": 1.6,
"LINE_W": 1,
"WINDOW_W": 1100,
"WINDOW_H": 600
}
}

356
modele/donnees.py Normal file
View File

@ -0,0 +1,356 @@
import logging
class GraphStructException(Exception):
pass
class Noeud(object):
def __init__(self, donnees):
self.nom = donnees['nom']
self.donnees = donnees
self.type = donnees['type']
self.assoc_connecteurs = {}
def __str__(self):
return f"<Noeud : {self.nom}, {self.type}>"
def set_branche(self, direction, branche):
# Associe la branche correspondant à un connecteur
if direction in self.assoc_connecteurs:
self.assoc_connecteurs[direction].append(branche)
else:
self.assoc_connecteurs[direction] = [branche]
def get_branches(self, direction):
return self.assoc_connecteurs[direction]
def get_branche(self, direction):
c = self.get_branches(direction)
if len(c) == 1:
return c[0]
else:
raise GraphStructException("Invalid number of connectors")
def remove_branche(self, branche, direction):
self.assoc_connecteurs[direction].remove(branche)
class Arete(object):
def __init__(self, amont, amont_dir, aval, aval_dir):
self.amont = amont
self.amont_dir = amont_dir
self.aval = aval
self.aval_dir = aval_dir
def deconnecte(self):
self.amont.remove_branche(self, self.amont_dir)
self.aval.remove_branche(self, self.aval_dir)
self.amont = None
self.aval = None
self.amont_dir = None
self.aval_dir = None
def reconnecte_noeud(self, nsrc, ndir_src, ndest, ndir_dest):
"""
Déconnecte le noeud source, et le remplace par le noeud dest
"""
if nsrc == self.amont and self.amont_dir == ndir_src:
self.amont.remove_branche(self, self.amont_dir)
self.amont = ndest
self.amont_dir = ndir_dest
ndest.set_branche(ndir_dest,self)
elif nsrc == self.aval and self.aval_dir == ndir_src:
self.aval.remove_branche(self, self.aval_dir)
self.aval = ndest
self.aval_dir = ndir_dest
ndest.set_branche(ndir_dest,self)
else:
raise GraphStructException
def get_neighbour(self, noeud, direction):
if self.amont == noeud and self.amont_dir == direction:
return self.aval, self.aval_dir
elif self.aval == noeud and self.aval_dir == direction:
return self.amont, self.amont_dir
else:
raise GraphStructException("No such neighbour")
def get_amont(self):
return self.amont, self.amont_dir
def get_aval (self):
return self.aval, self.aval_dir
class Branche(Arete):
def __init__(self, amont, amont_dir, aval, aval_dir, composants=None):
super().__init__(amont, amont_dir, aval, aval_dir)
self.composants = [] if composants is None else composants
class Condensateur(object):
"""
Un condensateur correspond en fait à l'objet connecteur câblé à deux noeuds amonts et aval
C'est donc "à la fois un noeud et deux branches"
"""
def __init__(self, donnees):
self.nom = donnees['nom']
self.donnees = donnees
self.type = donnees['type']
self.amont = None
self.aval = None
self.amont_dir = None # le connecteur du noeud amont auquel on est raccordé
self.aval_dir = None # le connecteur du noeud aval auquel on est raccordé
def get_amont(self):
return self.amont, self.amont_dir
def get_aval (self):
return self.aval, self.aval_dir
class SchemaReader(object):
"""
A la lecture du graphe, tous les objets sont des noeuds et ils sont raccordés par des branches.
La simplification permet de supprimer les coudes.
La réduction des branches permet de transformer une série de branches et de composants en une seule branche
contentant les composants.
"""
REDUCTIBLE = ["ContactRepos", "Relais", "Tempo", "ContactTravail", "Bouton", "Resistance",
"Diode", "Lampe", "RelaisCote", "Levier"]
RIEN_A_FAIRE = ["P24", "P0", "Pulse", "Noeud", "Condensateur", "ContactBasculeur", "ContactDouble"]
ID_NOM = -1
def __init__(self, d):
self.noeuds = {}
self.condensateurs = {}
self.branches = []
self.composants = None
self.lire_donnees(d)
@classmethod
def nouveau_nom(cls, prefix=""):
"""
Crée un nouveau nom
"""
cls.ID_NOM += 1
return f"@{prefix}{cls.ID_NOM}"
def connecte(self, n1, d1, n2, d2, composants=None):
"""
Crée une branche et connecte deux noeuds avec
"""
a = Branche(n1, d1, n2, d2, composants=composants)
self.branches.append(a)
n1.set_branche(d1, a)
n2.set_branche(d2, a)
def connecte_condensateur_amont(self, cond, n1, d1):
cond.amont = n1
cond.amont_dir = d1
def connecte_condensateur_aval(self, cond, n1, d1):
cond.aval = n1
cond.aval_dir = d1
def remove_branche(self, branche):
self.branches.remove(branche)
branche.deconnecte()
return branche.composants
def remove_noeud(self, noeud):
del self.noeuds[noeud]
def lire_donnees(self, d):
"""
Lit le dictionnaire contenant le schéma
"""
# On commence par lire les noeuds
try:
for nom, donnees in d['blocs'].items():
donnees['nom'] = nom
self.noeuds[nom] = Noeud(donnees)
# On lit (et lie) ensuite les câbles
for amont, dir_amont, aval, dir_aval in d['cables']:
self.connecte(self.noeuds[amont], dir_amont, self.noeuds[aval], dir_aval)
except KeyError:
raise GraphStructException
def traiter_composites(self):
"""
Traite les noeuds composites (contacts doubles, relais basculeurs, etc.) et les transforme en objets simples.
"""
noeuds_a_supprimer = []
noeuds_a_ajouter = []
for nom, noeud in self.noeuds.items():
# Parcoure les noeuds en cherchant les noeuds composites
if noeud.type == "RelaisCote":
# On transforme en relais simple
noeud.type = "Relais"
if 'orientation' not in noeud.donnees or noeud.donnees['orientation'] == 0:
b_hg = noeud.get_branche("hg")
b_bg = noeud.get_branche("bg")
b_hg.reconnecte_noeud(noeud, "hg", noeud, "g")
b_bg.reconnecte_noeud(noeud, "bg", noeud, "d")
elif noeud.donnees['orientation'] == 180:
b_hd = noeud.get_branche("hd")
b_bd = noeud.get_branche("bd")
b_hd.reconnecte_noeud(noeud, "hd", noeud, "g")
b_bd.reconnecte_noeud(noeud, "bd", noeud, "d")
else:
assert False, "Rien à faire là"
elif noeud.type == "RelaisBasculeur":
noeuds_a_supprimer.append(nom)
rel_g = Noeud({'nom': noeud.nom + ".gauche", 'type': 'Relais',
'orientation': noeud.donnees['orientation'], 'basculeur': 'gauche'})
rel_d = Noeud({'nom': noeud.nom + ".droite", 'type': 'Relais',
'orientation': noeud.donnees['orientation'], 'basculeur': 'droite'})
noeuds_a_ajouter.append((noeud.nom + ".gauche", rel_g))
noeuds_a_ajouter.append((noeud.nom + ".droite", rel_d))
# On récupère les branches
br_hg = noeud.get_branche("hg")
br_bg = noeud.get_branche("bg")
br_hd = noeud.get_branche("hd")
br_bd = noeud.get_branche("bd")
# Puis les voisins
vois_hg, vois_hg_dir = br_hg.get_neighbour(noeud, "hg")
vois_bg, vois_bg_dir = br_bg.get_neighbour(noeud, "bg")
vois_hd, vois_hd_dir = br_hd.get_neighbour(noeud, "hd")
vois_bd, vois_bd_dir = br_bd.get_neighbour(noeud, "bd")
# On supprime les branches
cmp_hg = self.remove_branche(br_hg)
cmp_bg = self.remove_branche(br_bg)
cmp_hd = self.remove_branche(br_hd)
cmp_bd = self.remove_branche(br_bd)
# On lie les nouveaux noeuds
self.connecte(rel_g, "g", vois_hg, vois_hg_dir, cmp_hg)
self.connecte(rel_g, "d", vois_bg, vois_bg_dir, cmp_bg)
self.connecte(rel_d, "g", vois_hd, vois_hd_dir, cmp_hd)
self.connecte(rel_d, "d", vois_bd, vois_bd_dir, cmp_bd)
[self.remove_noeud(n) for n in noeuds_a_supprimer]
[self.noeuds.__setitem__(nom, valeur) for nom, valeur in noeuds_a_ajouter]
def simplifier(self):
"""
Simplifie le graphe :
- supprime les coudes
"""
# Supprime les coudes
coudes = []
for n in self.noeuds.values():
if n.type == 'Coude':
try:
a1, a2 = n.get_branches("m")
except ValueError:
raise GraphStructException("Un coude doit avoir deux voisins")
# On récupère les voisins
v1, d1 = a1.get_neighbour(n, "m")
v2, d2 = a2.get_neighbour(n, "m")
comp1 = self.remove_branche(a1)
comp2 = self.remove_branche(a2)
self.connecte(v1, d1, v2, d2, comp1 + comp2)
coudes.append(n)
[self.remove_noeud(n.nom) for n in coudes]
def traiter_condensateurs(self):
cond_list = []
for nom, noeud in self.noeuds.items():
if noeud.type == "Condensateur":
branche_g = noeud.get_branche("g")
branche_d = noeud.get_branche("d")
n1 = self.nouveau_nom()
nn_amont = Noeud({'nom': n1, 'type': 'Noeud'})
cond_list.append(nn_amont)
n2 = self.nouveau_nom()
nn_aval = Noeud({'nom': n2, 'type': 'Noeud'})
cond_list.append(nn_aval)
cond = Condensateur(noeud.donnees)
self.condensateurs[nom] = cond
cond.amont = nn_amont
cond.aval = nn_aval
# On raccorde le nouveau noeud amont au voisin amont initial
voisin_g, dir_g = branche_g.get_neighbour(noeud, "g")
composants_g = self.remove_branche(branche_g)
self.connecte(voisin_g, dir_g, nn_amont, "m", composants_g)
# Le noeud nouveau noeud amont au condensateur
self.connecte_condensateur_amont(cond, nn_amont, "m")
# Le nouveau noeud aval au condensateur
self.connecte_condensateur_aval(cond, nn_aval, "m")
# On raccorde le nouveau noeud aval à la branche aval initiale
voisin_d, dir_d = branche_d.get_neighbour(noeud, "d")
composants_d = self.remove_branche(branche_d)
self.connecte(voisin_d, dir_d, nn_aval, "m", composants_d)
for c in cond_list:
self.noeuds[c.nom] = c
def reduire_branches(self):
noeuds_a_supprimer = []
for nom, noeud in self.noeuds.items():
if noeud.type in self.REDUCTIBLE:
# Le composant est stockable dans la branche (composant simple en série)
b_gauche = noeud.get_branche("g")
b_droite = noeud.get_branche("d")
voisin_g, voisin_g_dir = b_gauche.get_neighbour(noeud, "g")
voisin_d, voisin_d_dir = b_droite.get_neighbour(noeud, "d")
comp_br_gauche = self.remove_branche(b_gauche)
comp_br_droite = self.remove_branche(b_droite)
self.connecte(voisin_g, voisin_g_dir, voisin_d, voisin_d_dir, comp_br_gauche + [noeud] + comp_br_droite)
noeuds_a_supprimer.append(nom)
if noeud.type == "Diode" and noeud.donnees['orientation'] == 180:
noeud.nom = "!" + noeud.nom
elif noeud.type == "Coude":
assert False, "Les coudes auraient dûs être éliminés !"
elif noeud.type in self.RIEN_A_FAIRE:
pass
else:
raise GraphStructException("Type inconnu : " + noeud.type)
for n in noeuds_a_supprimer:
del self.noeuds[n]
def make_liste_composants(self):
self.composants = {}
for b in self.branches:
for c in b.composants:
self.composants[c.nom] = c
def process(self):
"""
Méthode principale de traitement du graphe
"""
try:
self.simplifier()
self.traiter_composites()
self.traiter_condensateurs()
self.reduire_branches()
self.make_liste_composants()
except KeyError:
logging.exception("Erreur de chaînage dans le graphe")
raise GraphStructException

514
modele/elements.py Normal file
View File

@ -0,0 +1,514 @@
from modele.exceptions import (WrongElecPropertyException, SurtensionException,
SurintensiteException, Dir)
class Element(object):
"""
Classe mère.
Le graphe lui-même est composé de Potentiels fixes (Potentiel), de Noeuds, et de Branches.
Les branches contiennent une liste de composants en série.
Les éléments doivent implémenter quatre méthodes pour le calcul des valeurs :
init_cycle est appelée avant chaque cycle, avant l'initialisation de la matrice
report_pass_1 est appelée après la première passe pour report des valeurs de la matrice (et avant la construction
de la matrice de la deuxième passe)
report_pass2 est appelée après la 2e passe pour reporter les valeurs finales calculées
update est appelée après le report de la 2e passe, pour pouvoir faire la mise à jour des états des éléments
"""
P_CST, P_NOEUD, P_DLT, P_COND, P_EQVAR, P_BSCLAME = range(6)
def __init__(self, conf, nom, type_potentiel):
self.type_potentiel = type_potentiel
self.conf = conf
self.nom = nom
def init_cycle(self):
pass
def passe_calcul(self, solutions, index):
pass
def update(self):
pass
def etat(self):
raise NotImplementedError
def coherence(self):
raise NotImplementedError
def eq_elts(self):
"""
Retourne les équipotentiels
Par défaut, un seul équipotentiel
"""
return [self]
def get_potentiel(self, direction):
"""
Par défaut, un seul potentiel quel que soit la direction
"""
return self
class Potentiel(Element):
"""
Potentiel à 24V ou à 0V
"""
def __init__(self, conf, nom, u=0.0, voisins=None):
super().__init__(conf, nom, self.P_CST)
self._u = u
if voisins is None:
voisins = []
self._voisins = voisins
def add_voisins(self, voisins):
self._voisins += voisins
def voisins(self):
return self._voisins
def u(self):
return self._u
def i(self):
raise WrongElecPropertyException
def coherence(self):
pass
def etat(self):
return self.u() >= self.conf['USEUIL']
class PotPulse(Potentiel):
def __init__(self, conf, nom, u=0.0, periode=None, voisins=None):
super().__init__(conf, nom, u, voisins)
if periode is None:
periode = self.conf['PULSE_PERIODE']
self.periode = periode / self.conf['DT']
self.u_max = u
self.actif = True
self.compteur = 0
def update(self):
self.compteur += 1
if self.actif:
if self.compteur >= self.periode:
self.compteur = 0
self._u = 0.
self.actif = False
else:
if self.compteur >= self.periode:
self.compteur = 0
self._u = self.u_max
self.actif = True
class Noeud(Element):
"""
Nœud du graphe
self._voisins: liste de (Graphe, polarité) avec polarité = +1 ou -1 pour les branches
"""
def __init__(self, conf, nom, voisins=None):
super().__init__(conf, nom, self.P_NOEUD)
self._u = None
if voisins is None:
voisins = []
self._voisins = voisins
def add_voisins(self, voisins):
self._voisins += voisins
def voisins(self):
return self._voisins
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self._u = vect[index]
def u(self):
return self._u
def coherence(self):
if abs(self.u()) >= self.conf['UMAX']:
raise SurtensionException
def etat(self):
return self.u() >= self.conf['USEUIL']
class Branche(Element):
"""
Branche du graphe.
La branche contient un certain nombre de composants en série, qui peuvent être des relais, tempos, résistances
ou contacts (équation). N'est pas utilisable pour les condensateurs.
"""
def __init__(self, conf, nom, composants):
super().__init__(conf, nom, self.P_DLT)
self.composants = composants
self.amont = None
self.aval = None
self._i = 0.0
def add_voisins(self, amont, aval):
self.amont = amont
self.aval = aval
def r(self):
return sum([x.r for x in self.composants]) + self.conf['RMIN']
def init_cycle(self):
super().init_cycle()
[x.init_cycle() for x in self.composants]
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self._i = vect[index] # Important de mettre à jour i avant de mettre à jour les composants
[x.passe_calcul() for x in self.composants]
def update(self):
super().update()
[x.update() for x in self.composants]
def i(self):
return self._i
def coherence(self):
if abs(self.i()) >= self.conf['IMAX']:
raise SurintensiteException(f"Dans la branche {self.nom}")
def etat(self):
return self.i() >= self.conf['ISEUIL']
class Condensateur(Element):
"""
Condensateur.
La seule truande est que la tension au borne est en réalité calculée avec la charge du cycle précédent.
"""
def __init__(self, conf, nom, capacite, coef_mul_tension):
super().__init__(conf, nom, self.P_COND)
self.capacite = capacite
self.amont = None
self.aval = None
self._i = 0.0
self.q = 0.0
self.q_prec = 0.0
self.coef_mul_tension = coef_mul_tension
def add_voisins(self, amont, aval):
self.amont = amont
self.aval = aval
def r(self):
raise WrongElecPropertyException
def init_cycle(self):
super().init_cycle()
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self._i = vect[index] # Important de mettre à jour i avant de mettre à jour les composants
def update(self):
super().update()
self.q_prec = self.q
q = self.q + self.i() * self.conf['DT']
self.q = q
def i(self):
return self._i
def coherence(self):
if abs(self.i()) >= self.conf['IMAX']:
raise SurintensiteException
def etat(self):
return bool(self.i() >= self.conf['ISEUIL'])
class ContactBasculeur(Noeud):
"""
Nœud du graphe
self._voisins: liste de (Graphe, polarité) avec polarité = +1 ou -1 pour les branches
"""
UMAX = 24.5
class PotentielLocal(Element):
def __init__(self, conf, nom, voisins=None):
self.lame = None
super().__init__(conf, nom, self.P_NOEUD)
self._u = None
if voisins is None:
voisins = []
self._voisins = voisins
self.etat = False
def set_lame(self, lame):
self.lame = lame
def add_voisins(self, voisins):
self._voisins += voisins
def set_etat(self, etat):
self.etat = etat
def voisins(self):
return self._voisins + ([(self.lame, +1, "foo")] if self.etat else [])
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self._u = vect[index]
def u(self):
return self._u
def coherence(self):
if abs(self.u()) >= self.conf['UMAX']:
raise SurtensionException
class Lame(Element):
def __init__(self, conf, nom, contact, gauche, droite):
self.amont = contact
self.aval = None
self.gauche = gauche
self.droite = droite
self.position = None
super().__init__(conf, nom, self.P_DLT)
self._i = None
def bascule(self, position):
self.position = position
if position == Dir.GAUCHE:
self.aval = self.gauche
else:
self.aval = self.droite
def i(self):
return self._i
def r(self):
return self.conf['RMIN']
# Classe principale
def __init__(self, conf, nom, graphe, voisins=None):
self.graphe = graphe
self.position = None
self.potentiel_gauche = self.PotentielLocal(conf, nom + ".G")
self.potentiel_droit = self.PotentielLocal(conf, nom + ".D")
self.lame = self.Lame(conf, nom + ".L", self, self.potentiel_gauche, self.potentiel_droit)
self.potentiel_gauche.set_lame(self.lame)
self.potentiel_droit.set_lame(self.lame)
self._voisins = [(self.lame, -1, "foo")] + voisins if voisins is not None else []
super().__init__(conf, nom, self.P_NOEUD)
self.bascule_gauche()
def eq_elts(self):
return [self, self.potentiel_gauche, self.potentiel_droit, self.lame]
def add_voisins(self, voisins):
for vois_tuple in voisins:
_, _, connecteur = vois_tuple
if connecteur == 'b':
self._voisins = [vois_tuple]
else:
# Les autres connecteurs doivent être câblés vers les ConnecteursLocaux
raise "Invalid connector for RelaisBasculeur"
def voisins(self):
return self._voisins
def bascule_gauche(self):
self.position = Dir.GAUCHE
self.lame.bascule(self.position)
self.potentiel_gauche.set_etat(True)
self.potentiel_droit.set_etat(False)
def bascule_droite(self):
self.position = Dir.DROITE
self.lame.bascule(self.position)
self.potentiel_gauche.set_etat(False)
self.potentiel_droit.set_etat(True)
def get_potentiel(self, direction):
"""
Par défaut, un seul potentiel quel que soit la direction
"""
if direction == "b":
return self
elif direction == "g":
return self.potentiel_gauche
elif direction == "d":
return self.potentiel_droit
else:
assert False
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self.potentiel_droit.passe_calcul(vect, self.graphe.vecteur.index(self.potentiel_droit))
self.potentiel_gauche.passe_calcul(vect, self.graphe.vecteur.index(self.potentiel_gauche))
self._u = vect[index]
def u(self):
return self._u
def etat(self):
return self.lame.position
def coherence(self):
if abs(self.u()) >= self.conf['UMAX']:
raise SurtensionException
self.potentiel_droit.coherence()
self.potentiel_gauche.coherence()
class ContactDouble(Noeud):
"""
Nœud du graphe
self._voisins: liste de (Graphe, polarité) avec polarité = +1 ou -1 pour les branches
"""
UMAX = 24.5
class PotentielLocal(Element):
def __init__(self, conf, nom, voisins=None):
self.lame = None
super().__init__(conf, nom, self.P_NOEUD)
self._u = None
if voisins is None:
voisins = []
self._voisins = voisins
self.etat = False
def set_lame(self, lame):
self.lame = lame
def add_voisins(self, voisins):
self._voisins += voisins
def set_etat(self, etat):
self.etat = etat
def voisins(self):
return self._voisins + ([(self.lame, +1, "foo")] if self.etat else [])
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self._u = vect[index]
def u(self):
return self._u
def coherence(self):
if abs(self.u()) >= self.conf['UMAX']:
raise SurtensionException
class Lame(Element):
def __init__(self, conf, nom, contact, gauche, droite):
self.amont = contact
self.aval = None
self.repos = gauche
self.travail = droite
self.position = False # Travail = True
super().__init__(conf, nom, self.P_DLT)
self._i = None
def set_position(self, position):
self.position = position
if position:
self.aval = self.travail
else:
self.aval = self.repos
def i(self):
return self._i
def r(self):
return self.conf['RMIN']
# Classe principale
def __init__(self, conf, nom, graphe, voisins=None, orientation=0):
self.graphe = graphe
self.orientation = orientation
self.potentiel_repos = self.PotentielLocal(conf, nom + ".repos")
self.potentiel_travail = self.PotentielLocal(conf, nom + ".travail")
self.lame = self.Lame(conf, nom + ".L", self, self.potentiel_repos, self.potentiel_travail)
self.potentiel_repos.set_lame(self.lame)
self.potentiel_travail.set_lame(self.lame)
self._voisins = [(self.lame, -1, "foo")] + voisins if voisins is not None else []
super().__init__(conf, nom, self.P_NOEUD)
self.lame.set_position(False)
def eq_elts(self):
return [self, self.potentiel_repos, self.potentiel_travail, self.lame]
def add_voisins(self, voisins):
for vois_tuple in voisins:
_, _, connecteur = vois_tuple
if (self.orientation == 0 and connecteur == 'd') \
or (self.orientation == 180 and connecteur == 'g'):
self._voisins = [vois_tuple]
else:
# Les autres connecteurs doivent être câblés vers les ConnecteursLocaux
raise "Invalid connector for ContactDouble"
def voisins(self):
return self._voisins
def get_potentiel(self, direction):
"""
Par défaut, un seul potentiel quel que soit la direction
"""
if self.orientation == 0:
if direction == "d":
return self
elif direction == "bg":
return self.potentiel_repos
elif direction == "hg":
return self.potentiel_travail
else:
assert False
elif self.orientation == 180:
if direction == "g":
return self
elif direction == "bd":
return self.potentiel_repos
elif direction == "hd":
return self.potentiel_travail
else:
assert False
else:
assert False
def passe_calcul(self, vect, index):
super().passe_calcul(vect, index)
self.potentiel_travail.passe_calcul(vect, self.graphe.vecteur.index(self.potentiel_travail))
self.potentiel_repos.passe_calcul(vect, self.graphe.vecteur.index(self.potentiel_repos))
self._u = vect[index]
def u(self):
return self._u
def etat(self):
return self.lame.position
def coherence(self):
if abs(self.u()) >= self.conf['UMAX']:
raise SurtensionException
self.potentiel_travail.coherence()
self.potentiel_repos.coherence()
def active(self):
self.lame.set_position(True)
self.potentiel_travail.set_etat(True)
self.potentiel_repos.set_etat(False)
def desactive(self):
self.lame.set_position(False)
self.potentiel_travail.set_etat(False)
self.potentiel_repos.set_etat(True)

22
modele/exceptions.py Normal file
View File

@ -0,0 +1,22 @@
from enum import IntEnum
class WrongElecPropertyException(Exception):
pass
class NonPolariseException(Exception):
pass
class SurtensionException(Exception):
pass
class SurintensiteException(Exception):
pass
class Dir(IntEnum):
GAUCHE = 1
DROITE = 2

171
modele/graphe.py Normal file
View File

@ -0,0 +1,171 @@
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()]

57
modele/matrice.py Normal file
View File

@ -0,0 +1,57 @@
import numpy as np
class Matrice(object):
"""
Le système d'équation est construit sur la base d'une matrice A et un vecteur B modélisant le système, tels que
A.X = B
Chaque ligne de la matrice correspond à une équation, correspondant elle-même à un élément du graphe.
Les équations sont dans le même ordre que les éléments du graphe.
Chaque colonne correspond à une inconnue, également prise dans le même ordre que les éléments du graphe.
Si l'élément est un Potentiel ou un noeud, l'inconnue est une tension.
Si l'élément est une branche, l'inconnue est l'intensité parcourant la branche.
"""
def __init__(self, graphe):
self.vecteur = graphe.vecteur
self.mat_A = None
self.mat_B = None # Equation matricielle AX = B
self.n = len(self.vecteur)
def init_mat(self):
self.mat_A = np.zeros((self.n, self.n))
self.mat_B = np.zeros(self.n)
for ligne, element in enumerate(self.vecteur): # Potentiel constant
# assert ligne == self.vecteur.index(element)
if element.type_potentiel == element.P_CST:
# Potentiel constant : on ajoute une équation indiquant la valeur de la tension pour cette variable
self.mat_A[ligne][ligne] = 1.0 # à noter que par construction, ligne == index
self.mat_B[ligne] = element.u()
elif element.type_potentiel == element.P_NOEUD: # On applique la loi des noeuds
# Noeud : on ajoute une équation sur la somme des intensités
for (voisin, polarite, _) in element.voisins():
self.mat_A[ligne][self.vecteur.index(voisin)] = polarite
self.mat_B[ligne] = 0.0
elif element.type_potentiel == element.P_DLT: # On applique la loi d'Ohm
self.mat_A[ligne][ligne] = 1.0
self.mat_A[ligne][self.vecteur.index(element.amont)] = -1.0 / element.r()
self.mat_A[ligne][self.vecteur.index(element.aval)] = 1.0 / element.r()
self.mat_B[ligne] = 0.0
elif element.type_potentiel == element.P_COND: # DU = q/C
self.mat_A[ligne][self.vecteur.index(element.amont)] = 1.0
self.mat_A[ligne][self.vecteur.index(element.aval)] = -1.0
self.mat_B[ligne] = element.coef_mul_tension * element.q / element.capacite
else:
assert False, "Rien à faire là"
def solve(self):
"""
Résout le système d'équation et retourne le vecteur solution.
"""
return np.linalg.solve(self.mat_A, self.mat_B)

View File

@ -0,0 +1,3 @@
numpy>=1.24.3
flask>=2.3.2
Flask-Cors>=4.0.0

6
run.py
View File

@ -0,0 +1,6 @@
from api_server.app import main
import sys
if __name__ == "__main__":
main(sys.argv)

1
schemas_v1/basculeur.ccs Normal file
View File

@ -0,0 +1 @@
{"blocs":{"p24-1":{"type":"P24","valeur":24,"x":0,"y":526},"b1":{"type":"Bouton","x":100,"y":526,"orientation":0},"rbas":{"type":"RelaisBasculeur","x":200,"y":520,"orientation":0},"b2":{"type":"Bouton","x":350,"y":526,"orientation":180},"p24-2":{"type":"P24","valeur":24,"x":450,"y":526,"orientation":180},"p0-1":{"type":"P0","x":0,"y":512,"orientation":180},"p0-2":{"type":"P0","x":450,"y":512,"orientation":0},"p0-3":{"type":"P0","x":0,"y":299,"orientation":180},"p0-4":{"type":"P0","x":450,"y":299,"orientation":0},"l3":{"type":"Lampe","x":100,"y":299,"orientation":0},"l4":{"type":"Lampe","x":350,"y":299,"orientation":0},"rbas.basc":{"type":"ContactBasculeur","relais":"rbas","x":200,"y":285,"orientation":0},"p24-3":{"type":"P24","x":150,"y":258.2}},"cables":[["p24-1","d","b1","g"],["b1","d","rbas","hg"],["p0-1","d","rbas","bg"],["p24-2","g","b2","d"],["b2","g","rbas","hd"],["p0-2","g","rbas","bd"],["p0-3","d","l3","g"],["p0-4","g","l4","d"],["l3","d","rbas.basc","g"],["l4","g","rbas.basc","d"],["p24-3","d","rbas.basc","b"]]}

104
schemas_v1/condensateur.ccs Normal file
View File

@ -0,0 +1,104 @@
{
"blocs": {
"p24-1": {
"type": "P24",
"valeur": 24.0,
"x": 0,
"y": 500
},
"p0-1": {
"type": "P0",
"valeur": 0.0,
"x": 1200,
"y": 500
},
"p0-2": {
"type": "P0",
"valeur": 0.0,
"x": 1200,
"y": 300
},
"p0-3": {
"type": "P0",
"valeur": 0.0,
"x": 600,
"y": 300
},
"xx": {
"type": "Noeud",
"x": 300,
"y": 500
},
"yy": {
"type": "Coude",
"x": 300,
"y": 300
},
"k1": {
"type": "Condensateur",
"capacite": 0.4,
"coef_mul_tension": 24,
"x": 400,
"y": 500
},
"r2": {
"type": "Relais",
"x": 1000,
"y": 500
},
"c3": {
"type": "Bouton",
"x": 200,
"y": 500,
"orientation": 180
},
"r2.travail": {
"type": "ContactTravail",
"relais": "r2",
"x": 1000,
"y": 300
},
"w1": {
"type": "Lampe",
"x": 600,
"y": 500
},
"n1": {
"type": "Noeud",
"x": 800,
"y": 500
},
"coude1": {
"type": "Coude",
"x": 800,
"y": 300
},
"b2": {
"type": "Bouton",
"x": 400,
"y": 300
},
"w2": {
"type": "Resistance",
"valeur": 20,
"x": 500,
"y": 300
}
},
"cables": [
["p24-1", "d", "c3", "g"],
["c3", "d", "xx", "m"],
["xx", "m", "k1", "g"],
["k1", "d", "w1", "g"],
["w1", "d", "n1", "m"],
["n1", "m", "r2", "g"],
["r2", "d", "p0-1", "g"],
["n1", "m", "coude1", "m"],
["coude1", "m", "r2.travail", "g"],
["r2.travail", "d", "p0-2", "g"],
["xx", "m", "yy", "m"],
["yy", "m", "b2", "g"],
["b2", "d", "w2", "g"],
["w2", "d", "p0-3", "g"]
]
}

Some files were not shown because too many files have changed in this diff Show More