Merge pull request #104 from Orange-OpenSource/path_resquest_rundemo

Path resquest rundemo
This commit is contained in:
James
2018-09-24 12:47:12 -07:00
committed by GitHub
11 changed files with 360 additions and 184 deletions

View File

@@ -189,7 +189,7 @@ Service sheet must contain 11 columns::
route id ; Source ; Destination ; TRX type ; Mode ; System: spacing ; System: input power (dBm) ; System: nb of channels ; routing: disjoint from ; routing: path ; routing: is loose?
- **route id** is mandatory. It must be unique. It is the identifier of the request. It must be an integer value (TODO: relax this format in future development to accept any strings)
- **route id** is mandatory. It must be unique. It is the identifier of the request. It can be an integer or a string (do not use blank or dash)
- **Source** is mandatory. It is the name of the source node (as listed in Nodes sheet). Source MUST be a ROADM node. (TODO: relax this and accept trx entries)

View File

@@ -53,7 +53,16 @@ class Element:
class Request_element(Element):
def __init__(self,Request,eqpt_filename):
self.request_id = int(Request.request_id)
# request_id is str
# excel has automatic number formatting that adds .0 on integer values
# the next lines recover the pure int value, assuming this .0 is unwanted
if not isinstance(Request.request_id,str):
value = str(int(Request.request_id))
if value.endswith('.0'):
value = value[:-2]
self.request_id = value
else:
self.request_id = Request.request_id
self.source = Request.source
self.destination = Request.destination
self.srctpid = f'trx {Request.source}'
@@ -61,21 +70,27 @@ class Request_element(Element):
# test that trx_type belongs to eqpt_config.json
# if not replace it with a default
equipment = load_equipment(eqpt_filename)
if equipment['Transceiver'][Request.trx_type]:
self.trx_type = Request.trx_type
self.mode = Request.mode
else:
#TODO : this case must raise an error instead of using Voyager
self.trx_type = 'Voyager_16QAM'
print(f'Transceiver type {Request.trx_type} is not defined in {eqpt_filename}')
print('replaced by Voyager_16QAM')
try :
if equipment['Transceiver'][Request.trx_type]:
self.trx_type = Request.trx_type
if [mode for mode in equipment['Transceiver'][Request.trx_type].mode]:
self.mode = Request.mode
except KeyError:
msg = f'could not find tsp : {Request.trx_type} with mode: {Request.mode} in eqpt library \nComputation stopped.'
#print(msg)
logger.critical(msg)
exit()
# excel input are in GHz and dBm
self.spacing = Request.spacing * 1e9
self.power = db2lin(Request.power) * 1e-3
self.nb_channel = int(Request.nb_channel)
if isinstance(Request.disjoint_from,str):
self.disjoint_from = [int(n) for n in Request.disjoint_from.split()]
if not isinstance(Request.disjoint_from,str):
value = str(int(Request.disjoint_from))
if value.endswith('.0'):
value = value[:-2]
else:
self.disjoint_from = [int(Request.disjoint_from)]
value = Request.disjoint_from
self.disjoint_from = [n for n in value.split()]
self.nodes_list = []
if Request.nodes_list :
self.nodes_list = Request.nodes_list.split(' | ')
@@ -83,7 +98,7 @@ class Request_element(Element):
self.nodes_list.remove(self.source)
msg = f'{self.source} removed from explicit path node-list'
logger.info(msg)
print(msg)
# print(msg)
except ValueError:
msg = f'{self.source} already removed from explicit path node-list'
logger.info(msg)
@@ -92,7 +107,7 @@ class Request_element(Element):
self.nodes_list.remove(self.destination)
msg = f'{self.destination} removed from explicit path node-list'
logger.info(msg)
print(msg)
# print(msg)
except ValueError:
msg = f'{self.destination} already removed from explicit path node-list'
logger.info(msg)

View File

@@ -21,7 +21,7 @@
{
"type_variety": "std_low_gain",
"type_def": "variable_gain",
"gain_flatmax": 17,
"gain_flatmax": 16,
"gain_min": 8,
"p_max": 22,
"nf_min": 6.5,
@@ -36,7 +36,7 @@
"gain_min": 20,
"p_max": 21,
"nf0": 5.5,
"allowed_for_design": true
"allowed_for_design": false
},
{
"type_variety": "test",
@@ -90,6 +90,20 @@
"max": 196.1e12
},
"mode":[
{
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15
},
{
"format": "mode 2",
"baud_rate": 66e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15
},
{
"format": "PS_SP64_1",
"baud_rate": 32e9,
@@ -107,6 +121,30 @@
]
},
{
"type_variety": "Voyager",
"frequency":{
"min": 191.35e12,
"max": 196.1e12
},
"mode":[
{
"format": "16QAM",
"baud_rate": 32e9,
"OSNR": 19,
"bit_rate": 200e9,
"roll_off": 0.15
},
{
"format": "QPSK",
"baud_rate": 32e9,
"OSNR": 12,
"bit_rate": 100e9,
"roll_off": 0.15
}
]
},
{
"type_variety": "Voyager_16QAM",
"frequency":{
"min": 191.35e12,
@@ -119,7 +157,15 @@
"OSNR": 19,
"bit_rate": 200e9,
"roll_off": 0.15
},
{
"format": "QPSK",
"baud_rate": 32e9,
"OSNR": 12,
"bit_rate": 100e9,
"roll_off": 0.15
}
]
}
]

Binary file not shown.

View File

@@ -30,7 +30,7 @@ from gnpy.core.network import load_network, build_network, set_roadm_loss
from gnpy.core.equipment import load_equipment, trx_mode_params
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate
from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate, jsontocsv
from copy import copy, deepcopy
#EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json'
@@ -97,14 +97,15 @@ def compute_path(network, equipment, pathreqlist):
#we assume that the destination is a strict constraint
pathreq.loose_list.append('strict')
print(f'Computing path from {pathreq.source} to {pathreq.destination}')
print(f'with explicit path: {[pathreq.source]+pathreq.nodes_list}') #adding first node to be clearer on the output
print(f'with path constraint: {[pathreq.source]+pathreq.nodes_list}') #adding first node to be clearer on the output
total_path = compute_constrained_path(network, pathreq)
print(f'Computed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}\n')
# for debug
# print(f'{pathreq.baud_rate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}')
total_path = propagate(total_path,pathreq,equipment, show=False)
if total_path :
total_path = propagate(total_path,pathreq,equipment, show=False)
else:
total_path = []
# we record the last tranceiver object in order to have th whole
# information about spectrum. Important Note: since transceivers
# attached to roadms are actually logical elements to simulate
@@ -136,16 +137,32 @@ if __name__ == '__main__':
print(pths)
test = compute_path(network, equipment, pths)
if args.output is None:
#TODO write results
print("demand\t\t\t\tsnr@bandwidth\tsnr@0.1nm")
for i, p in enumerate(test):
print(f'{pths[i].source} to {pths[i].destination} : {round(mean(p[-1].snr),2)} ,\
{round(mean(p[-1].snr+lin2db(pths[i].baud_rate/(12.5e9))),2)}')
else:
#TODO write results
header = ['demand','snr@bandwidth','snr@0.1nm','Receiver minOSNR']
data = []
data.append(header)
for i, p in enumerate(test):
if p:
line = [f'{pths[i].source} to {pths[i].destination} : ', f'{round(mean(p[-1].snr),2)}',\
f'{round(mean(p[-1].snr+lin2db(pths[i].baud_rate/(12.5e9))),2)}',\
f'{pths[i].OSNR}']
else:
line = [f'no path from {pths[i].source} to {pths[i].destination} ']
data.append(line)
col_width = max(len(word) for row in data for word in row) # padding
for row in data:
print(''.join(word.ljust(col_width) for word in row))
if args.output :
result = []
for p in test:
result.append(Result_element(pths[test.index(p)],p))
with open(args.output, 'w') as f:
f.write(dumps(path_result_json(result), indent=2))
f.write(dumps(path_result_json(result), indent=2))
fnamecsv = next(s for s in args.output.split('.')) + '.csv'
with open(fnamecsv,"w") as fcsv :
jsontocsv(path_result_json(result),equipment,fcsv)

View File

@@ -14,80 +14,26 @@ and write results in an CSV file
"""
from sys import exit
from csv import writer
from argparse import ArgumentParser
from pathlib import Path
from json import dumps, loads
from json import loads
from gnpy.core.equipment import load_equipment
from gnpy.core.utils import lin2db
START_LINE = 5
from gnpy.core.request import jsontocsv
parser = ArgumentParser(description = 'A function that writes json path results in an excel sheet.')
parser.add_argument('filename', nargs='?', type = Path)
parser.add_argument('eqpt_filename', nargs='?', type = Path)
parser.add_argument('output_filename', nargs='?', type = Path)
parser.add_argument('eqpt_filename', nargs='?', type = Path, default=Path(__file__).parent / 'eqpt_config.json')
if __name__ == '__main__':
args = parser.parse_args()
print(f'coucou {args.output_filename}')
with open(args.output_filename,"w") as file :
mywriter = writer(file)
mywriter.writerow(('path-id','source','destination','transponder-type',\
'transponder-mode','baud rate (Gbaud)', 'input power (dBm)','path','OSNR@bandwidth','OSNR@0.1nm','SNR@bandwidth','SNR@0.1nm','Pass?'))
with open(args.filename) as f:
print(f'Reading {args.filename}')
json_data = loads(f.read())
equipment = load_equipment(args.eqpt_filename)
tspjsondata = equipment['Transceiver']
#print(tspjsondata)
for p in json_data['path']:
path_id = int(p['path-id'])
source = p['path-properties']['path-route-objects'][0]\
['path-route-object']['unnumbered-hop']['node-id']
destination = p['path-properties']['path-route-objects'][-1]\
['path-route-object']['unnumbered-hop']['node-id']
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
for e in p['path-properties']['path-route-objects']])
print(f'Writing in {args.output_filename}')
jsontocsv(json_data,equipment,file)
[tsp,mode] = p['path-properties']['path-route-objects'][0]\
['path-route-object']['unnumbered-hop']['hop-type'].split(' - ')
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
try:
[minosnr, baud_rate] = next([m['OSNR'] , m['baud_rate']]
for m in equipment['Transceiver'][tsp].mode if m['format']==mode)
# for debug
# print(f'coucou {baud_rate}')
except IndexError:
msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library'
raise ValueError(msg)
output_snr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm')
output_snrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth')
output_osnr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm')
output_osnrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth')
power = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
mywriter.writerow((path_id,
source,
destination,
tsp,
mode,
baud_rate*1e-9,
round(lin2db(power)+30,2),
pth,
output_osnrbandwidth,
output_osnr,
output_snrbandwidth,
output_snr,
output_snr >= minosnr
))

View File

@@ -137,7 +137,7 @@ def target_power(network, node, equipment): #get_fiber_dp
exit()
if isinstance(node, Roadm) or not power_mode:
dp = 0
print(f'{repr(node)} delta power in:\n{dp}dB')
# print(f'{repr(node)} delta power in:\n{dp}dB')
return dp
@@ -252,6 +252,7 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db):
prev_dp = dp
prev_node = node
node = next_node
# print(f'{node.uid}')
next_node = next(n for n in network.successors(node))

View File

@@ -25,6 +25,10 @@ from gnpy.core.network import set_roadm_loss
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
from copy import copy, deepcopy
from csv import writer
logger = getLogger(__name__)
RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+
' trx_mode nodes_list loose_list spacing power nb_channel frequency format baud_rate OSNR bit_rate roll_off')
@@ -55,17 +59,19 @@ class Path_request:
f'destination: {self.destination}'])
def __repr__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.request_id}',
f'source: {self.source}',
f'destination: {self.destination}',
f'trx type: {self.tsp}',
f'baud_rate: {self.baud_rate}',
f'spacing: {self.spacing}',
f'power: {self.power}'
f'source: \t{self.source}',
f'destination:\t{self.destination}',
f'trx type:\t{self.tsp}',
f'trx mode:\t{self.tsp_mode}',
f'baud_rate:\t{self.baud_rate * 1e-9} Gbaud',
f'bit_rate:\t{self.bit_rate * 1e-9} Gb/s',
f'spacing:\t{self.spacing * 1e-9} GHz',
f'power: \t{round(lin2db(self.power)+30,2)} dBm'
'\n'])
class Result_element(Element):
def __init__(self,path_request,computed_path):
self.path_id = int(path_request.request_id)
self.path_id = path_request.request_id
self.path_request = path_request
self.computed_path = computed_path
hop_type = []
@@ -78,56 +84,125 @@ class Result_element(Element):
uid = property(lambda self: repr(self))
@property
def pathresult(self):
return {
'path-id': self.path_id,
'path-properties':{
'path-metric': [
{
'metric-type': 'SNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].snr),2)
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].snr+lin2db(self.path_request.baud_rate/12.5e9)),2)
},
{
'metric-type': 'OSNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase),2)
},
{
'metric-type': 'OSNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm),2)
},
{
'metric-type': 'reference_power',
'accumulative-value': self.path_request.power
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': self.computed_path.index(n),
'unnumbered-hop': {
'node-id': n.uid,
'link-tp-id': n.uid,
'hop-type': self.hop_type[self.computed_path.index(n)],
'direction': 'not used'
if not self.computed_path:
return {
'path-id': self.path_id,
'path-properties':{
'path-metric': [
{
'metric-type': 'SNR@bandwidth',
'accumulative-value': 'None'
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': 'None'
},
{
'metric-type': 'OSNR@bandwidth',
'accumulative-value': 'None'
},
{
'metric-type': 'OSNR@0.1nm',
'accumulative-value': 'None'
},
{
'metric-type': 'reference_power',
'accumulative-value': self.path_request.power
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': 0,
'unnumbered-hop': {
'node-id': self.path_request.source,
'link-tp-id': self.path_request.source,
'hop-type': ' - '.join([self.path_request.tsp, self.path_request.tsp_mode]),
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
{
'path-route-object': {
'index': 1,
'unnumbered-hop': {
'node-id': self.path_request.destination,
'link-tp-id': self.path_request.destination,
'hop-type': ' - '.join([self.path_request.tsp, self.path_request.tsp_mode]),
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
}
} for n in self.computed_path
]
]
}
}
else:
return {
'path-id': self.path_id,
'path-properties':{
'path-metric': [
{
'metric-type': 'SNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].snr),2)
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].snr+lin2db(self.path_request.baud_rate/12.5e9)),2)
},
{
'metric-type': 'OSNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase),2)
},
{
'metric-type': 'OSNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm),2)
},
{
'metric-type': 'reference_power',
'accumulative-value': self.path_request.power
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': self.computed_path.index(n),
'unnumbered-hop': {
'node-id': n.uid,
'link-tp-id': n.uid,
'hop-type': self.hop_type[self.computed_path.index(n)],
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
} for n in self.computed_path
]
}
}
}
@property
def json(self):
@@ -139,6 +214,8 @@ def compute_constrained_path(network, req):
edfa = [n for n in network.nodes() if isinstance(n, Edfa)]
source = next(el for el in trx if el.uid == req.source)
# start the path with its source
# TODO : avoid loops due to constraints , guess name base on string,
# avoid crashing if on req is not correct
total_path = [source]
for n in req.nodes_list:
# print(n)
@@ -170,7 +247,16 @@ def compute_constrained_path(network, req):
else:
msg = f'could not find a path from {source.uid} to node : {n} in network topology'
logger.critical(msg)
raise ValueError(msg)
#raise ValueError(msg)
print(msg)
total_path = []
# preparing disjonction feature
# for p in all_simple_paths(network,\
# source=next(el for el in trx if el.uid == req.source),\
# target=next(el for el in trx if el.uid == req.destination)):
# print([e.uid for e in p if isinstance(e,Roadm)])
return total_path
def propagate(path, req, equipment, show=False):
@@ -183,4 +269,69 @@ def propagate(path, req, equipment, show=False):
si = el(si)
if show :
print(el)
return path
return path
def jsontocsv(json_data,equipment,fileout):
# read json path result file in accordance with:
# Yang model for requesting Path Computation
# draft-ietf-teas-yang-path-computation-01.txt.
# and write results in an CSV file
mywriter = writer(fileout)
mywriter.writerow(('path-id','source','destination','transponder-type',\
'transponder-mode','baud rate (Gbaud)', 'input power (dBm)','path',\
'OSNR@bandwidth','OSNR@0.1nm','SNR@bandwidth','SNR@0.1nm','Pass?'))
tspjsondata = equipment['Transceiver']
#print(tspjsondata)
for p in json_data['path']:
path_id = p['path-id']
source = p['path-properties']['path-route-objects'][0]\
['path-route-object']['unnumbered-hop']['node-id']
destination = p['path-properties']['path-route-objects'][-1]\
['path-route-object']['unnumbered-hop']['node-id']
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
for e in p['path-properties']['path-route-objects']])
[tsp,mode] = p['path-properties']['path-route-objects'][0]\
['path-route-object']['unnumbered-hop']['hop-type'].split(' - ')
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
try:
[minosnr, baud_rate] = next([m['OSNR'] , m['baud_rate']]
for m in equipment['Transceiver'][tsp].mode if m['format']==mode)
# for debug
# print(f'coucou {baud_rate}')
except IndexError:
msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library'
raise ValueError(msg)
output_snr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm')
output_snrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth')
output_osnr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm')
output_osnrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth')
power = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
if isinstance(output_snr, str):
isok = ''
else:
isok = output_snr >= minosnr
mywriter.writerow((path_id,
source,
destination,
tsp,
mode,
baud_rate*1e-9,
round(lin2db(power)+30,2),
pth,
output_osnrbandwidth,
output_osnr,
output_snrbandwidth,
output_snr,
isok
))

View File

@@ -1,7 +1,7 @@
{
"path-request": [
{
"request-id": 0,
"request-id": "0",
"source": "BREST_KLA",
"destination": "Vannes_KBE",
"src-tp-id": "trx BREST_KLA",
@@ -27,7 +27,7 @@
}
},
{
"request-id": 1,
"request-id": "1",
"source": "Lorient_KMA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Lorient_KMA",
@@ -55,26 +55,26 @@
],
"synchronisation": [
{
"synchonization-id": 0,
"synchonization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
0,
1
"0",
"1"
]
}
},
{
"synchonization-id": 1,
"synchonization-id": "1",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
1,
0
"1",
"0"
]
}
}

View File

@@ -1,7 +1,7 @@
{
"path-request": [
{
"request-id": 0,
"request-id": "0",
"source": "Lorient_KMA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Lorient_KMA",
@@ -27,7 +27,7 @@
}
},
{
"request-id": 1,
"request-id": "1",
"source": "Brest_KLA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Brest_KLA",
@@ -84,7 +84,7 @@
}
},
{
"request-id": 3,
"request-id": "3",
"source": "Lannion_CAS",
"destination": "Rennes_STA",
"src-tp-id": "trx Lannion_CAS",
@@ -110,7 +110,7 @@
}
},
{
"request-id": 4,
"request-id": "4",
"source": "Rennes_STA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Rennes_STA",
@@ -136,7 +136,7 @@
}
},
{
"request-id": 5,
"request-id": "5",
"source": "Lorient_KMA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Lorient_KMA",
@@ -180,38 +180,38 @@
],
"synchronisation": [
{
"synchonization-id": 0,
"synchonization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
0,
0
"0",
"0"
]
}
},
{
"synchonization-id": 3,
"synchonization-id": "3",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
3,
4
"3",
"4"
]
}
},
{
"synchonization-id": 5,
"synchonization-id": "5",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
5,
0
"5",
"0"
]
}
}

View File

@@ -1,7 +1,7 @@
{
"path-request": [
{
"request-id": 0,
"request-id": "0",
"source": "Lorient_KMA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Lorient_KMA",
@@ -27,7 +27,7 @@
}
},
{
"request-id": 1,
"request-id": "1",
"source": "Brest_KLA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Brest_KLA",
@@ -84,7 +84,7 @@
}
},
{
"request-id": 3,
"request-id": "3",
"source": "Lannion_CAS",
"destination": "Rennes_STA",
"src-tp-id": "trx Lannion_CAS",
@@ -110,7 +110,7 @@
}
},
{
"request-id": 4,
"request-id": "4",
"source": "Rennes_STA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Rennes_STA",
@@ -136,7 +136,7 @@
}
},
{
"request-id": 5,
"request-id": "5",
"source": "Lorient_KMA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Lorient_KMA",
@@ -180,38 +180,38 @@
],
"synchronisation": [
{
"synchonization-id": 0,
"synchonization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
0,
0
"0",
"0"
]
}
},
{
"synchonization-id": 3,
"synchonization-id": "3",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
3,
4
"3",
"4"
]
}
},
{
"synchonization-id": 5,
"synchonization-id": "5",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
5,
0
"5",
"0"
]
}
}