Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
dream
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
dream
Commits
e8834d6a
Commit
e8834d6a
authored
Jan 14, 2014
by
Ioannis Papagiannopoulos
Committed by
Jérome Perrin
Jan 20, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Topology18 corrected - agreement with ulbranch, corresponding corrections to Objects
parent
6568104c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
155 additions
and
102 deletions
+155
-102
dream/simulation/Globals.py
dream/simulation/Globals.py
+13
-7
dream/simulation/JSONInputs/Topology18.json
dream/simulation/JSONInputs/Topology18.json
+21
-7
dream/simulation/LineGenerationJSON.py
dream/simulation/LineGenerationJSON.py
+0
-24
dream/simulation/Machine.py
dream/simulation/Machine.py
+2
-19
dream/simulation/MachineJobShop.py
dream/simulation/MachineJobShop.py
+51
-18
dream/simulation/Queue.py
dream/simulation/Queue.py
+4
-4
dream/simulation/QueueJobShop.py
dream/simulation/QueueJobShop.py
+43
-16
dream/tests/dump/Topology18.json.result
dream/tests/dump/Topology18.json.result
+21
-7
No files found.
dream/simulation/Globals.py
View file @
e8834d6a
...
...
@@ -125,12 +125,11 @@ def setWIP(entityList):
# if the entity is of type Job/OrderComponent/Order
elif
entity
.
type
==
'Job'
or
'OrderComponent'
or
'Order'
:
# find the list of starting station of the entity
objects
=
entity
.
remainingRoute
[
0
].
get
(
'stationIdsList'
,[])
# # # # # # object=findObjectById(entity.remainingRoute[0][0]) # find the object in the 'G.ObjList'
currentObjectIds
=
entity
.
remainingRoute
[
0
].
get
(
'stationIdsList'
,[])
# if the list of starting stations has length greater than one then there is a starting WIP definition error
try
:
if
len
(
object
s
)
==
1
:
objectId
=
object
s
[
0
]
if
len
(
currentObjectId
s
)
==
1
:
objectId
=
currentObjectId
s
[
0
]
else
:
raise
SetWipTypeError
(
'The starting station of the the entity is not defined uniquely'
)
except
SetWipTypeError
as
setWipError
:
...
...
@@ -146,10 +145,17 @@ def setWIP(entityList):
for
nextObjectId
in
nextObjectIds
:
nextObject
=
findObjectById
(
nextObjectId
)
nextObjects
.
append
(
nextObject
)
# update the receiver of the object
# update the receiver
and the next list
of the object
object
.
next
=
nextObjects
object
.
receiver
=
object
.
updateReceiverObject
()
# # # # # # object.receiver=findObjectById(entity.remainingRoute[1][0])
maxTimeWaiting
=
0
# dummy variable counting the time a successor is waiting
for
nextObject
in
object
.
next
:
if
(
nextObject
.
canAccept
(
object
)):
# if a successor can accept an object
timeWaiting
=
now
()
-
nextObject
.
timeLastEntityLeft
# the time it has been waiting is updated and stored in dummy variable timeWaiting
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting
=
timeWaiting
object
.
receiver
=
nextObject
# set the receiver as the longest waiting possible receiver
# in the next loops, check the other successors in the previous list
entity
.
remainingRoute
.
pop
(
0
)
# remove data from the remaining route.
entity
.
schedule
.
append
([
object
,
now
()])
#append the time to schedule so that it can be read in the result
entity
.
currentStation
=
object
# update the current station of the entity
...
...
dream/simulation/JSONInputs/Topology18.json
View file @
e8834d6a
...
...
@@ -34,7 +34,9 @@
"route"
:
[
{
"stepNumber"
:
"0"
,
"stationId"
:
"Q1"
,
"stationIdsList"
:
[
"Q1"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"0"
...
...
@@ -42,7 +44,9 @@
},
{
"stepNumber"
:
"1"
,
"stationId"
:
"M1"
,
"stationIdsList"
:
[
"M1"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"1"
...
...
@@ -50,7 +54,9 @@
},
{
"stepNumber"
:
"2"
,
"stationId"
:
"Q3"
,
"stationIdsList"
:
[
"Q3"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"0"
...
...
@@ -58,7 +64,9 @@
},
{
"stepNumber"
:
"3"
,
"stationId"
:
"M3"
,
"stationIdsList"
:
[
"M3"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"3"
...
...
@@ -66,7 +74,9 @@
},
{
"stepNumber"
:
"4"
,
"stationId"
:
"Q2"
,
"stationIdsList"
:
[
"Q2"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"0"
...
...
@@ -74,7 +84,9 @@
},
{
"stepNumber"
:
"5"
,
"stationId"
:
"M2"
,
"stationIdsList"
:
[
"M2"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"2"
...
...
@@ -82,7 +94,9 @@
},
{
"stepNumber"
:
"6"
,
"stationId"
:
"E1"
,
"stationIdsList"
:
[
"E1"
],
"processingTime"
:
{
"distributionType"
:
"Fixed"
,
"mean"
:
"0"
...
...
dream/simulation/LineGenerationJSON.py
View file @
e8834d6a
...
...
@@ -805,14 +805,6 @@ def createWIP():
for
routeentity
in
JSONRoute
:
# for each 'step' dictionary in the JSONRoute
stepNumber
=
int
(
routeentity
.
get
(
'stepNumber'
,
'0'
))
# get the stepNumber
routeentity
.
pop
(
'stepNumber'
,
None
)
# remove the stepNumber key from the dict
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route
[
stepNumber
]
=
routeentity
# keep a reference of all extra properties passed to the job
...
...
@@ -863,14 +855,6 @@ def createWIP():
for
routeentity
in
JSONRoute
:
# for each 'step' dictionary in the JSONRoute
stepNumber
=
int
(
routeentity
.
get
(
'stepNumber'
,
'0'
))
# get the stepNumber
routeentity
.
pop
(
'stepNumber'
,
None
)
# remove the stepNumber key
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route
[
stepNumber
]
=
routeentity
# keep a reference of all extra properties passed to the job
...
...
@@ -943,14 +927,6 @@ def createWIP():
for
routeentity
in
JSONRoute
:
# for each 'step' dictionary in the JSONRoute
stepNumber
=
int
(
routeentity
.
get
(
'stepNumber'
,
'0'
))
# get the stepNumber
routeentity
.
pop
(
'stepNumber'
,
None
)
# remove the stepNumber key
# nextIds=routeentity.get('stationIdsList', []) # the stationId
# processingTime=routeentity['processingTime'] # and the 'processingTime' dictionary
# distributionType=processingTime.get('distributionType', 'not found')# and from that dictionary
# # get the 'mean'
# mean=float(processingTime.get('mean', 'not found'))
# route[stepNumber]=[nextIds, mean] # finally add the 'nextId' and 'mean'
# # to the job route
route
[
stepNumber
]
=
routeentity
# keep a reference of all extra properties passed to the job
...
...
dream/simulation/Machine.py
View file @
e8834d6a
...
...
@@ -100,11 +100,6 @@ class Machine(CoreObject):
self
.
downTimeInCurrentEntity
=
0
#holds the total time that the
#object was down while holding current entity
print
'++++++++++++++++++++++++++++++++++++'
print
'time'
,
now
()
print
'object'
,
self
.
objName
,
'got entity'
,
self
.
currentEntity
.
name
print
'++++++++++++++++++++++++++++++++++++'
# this loop is repeated until the processing time is expired with no failure
# check when the processingEndedFlag switched to false
while
processingNotFinished
:
...
...
@@ -131,7 +126,6 @@ class Machine(CoreObject):
# it seems to be random which happens 1st
# this should not appear often to stochastic models though where times are random
interruption
=
True
print
'interruption'
# passivate the Machine for as long as there is no repair
# start counting the down time at breatTime dummy variable
breakTime
=
now
()
# dummy variable that the interruption happened
...
...
@@ -146,25 +140,16 @@ class Machine(CoreObject):
#if during the interruption the object became empty break
if
(
len
(
self
.
getActiveObjectQueue
())
==
0
and
self
.
shouldPreempt
):
print
'preemption'
break
# if no interruption occurred the processing in M1 is ended
else
:
processingNotFinished
=
False
print
'processing finished'
#if during the interruption the object became empty continue
if
(
len
(
self
.
getActiveObjectQueue
())
==
0
and
self
.
shouldPreempt
):
self
.
shouldPreempt
=
False
self
.
totalWorkingTime
+=
now
()
-
(
self
.
timeLastEntityEntered
)
continue
print
'////////////////////////////////////'
print
'time'
,
now
()
print
'object'
,
self
.
objName
,
'processed'
,
self
.
currentEntity
.
name
print
'////////////////////////////////////'
continue
# output to trace that the processing in the Machine self.objName ended
try
:
...
...
@@ -176,9 +161,7 @@ class Machine(CoreObject):
# update the total working time
self
.
totalWorkingTime
+=
self
.
totalProcessingTimeInCurrentEntity
# the total processing time for this entity
# is what the distribution initially gave
# update the variables keeping track of Entity related attributes of the machine
self
.
timeLastEntityEnded
=
now
()
# this holds the time that the last entity ended processing in Machine
self
.
nameLastEntityEnded
=
self
.
currentEntity
.
name
# this holds the name of the last entity that ended processing in Machine
...
...
dream/simulation/MachineJobShop.py
View file @
e8834d6a
...
...
@@ -29,25 +29,28 @@ from SimPy.Simulation import Process, Resource
from
SimPy.Simulation
import
activate
,
passivate
,
waituntil
,
now
,
hold
from
Machine
import
Machine
#the MachineJobShop object
# ===========================================================================
# the MachineJobShop object
# ===========================================================================
class
MachineJobShop
(
Machine
):
#set all the objects in previous and next
# =======================================================================
# set all the objects in previous and next
# =======================================================================
def
initialize
(
self
):
from
Globals
import
G
self
.
previous
=
G
.
ObjList
self
.
next
=
G
.
ObjList
Machine
.
initialize
(
self
)
#run default behaviour
#gets an entity from the predecessor that the predecessor index points to
# =======================================================================
# gets an entity from the predecessor that the predecessor index points to
# =======================================================================
def
getEntity
(
self
):
activeEntity
=
Machine
.
getEntity
(
self
)
#run the default code
# read the processing time from the corresponding remainingRoute entry
processingTime
=
activeEntity
.
remainingRoute
[
0
][
'processingTime'
]
self
.
distType
=
processingTime
.
get
(
'distributionType'
,
'not found'
)
self
.
procTime
=
processingTime
.
get
(
'mean'
,
0
)
self
.
procTime
=
float
(
processingTime
.
get
(
'mean'
,
0
)
)
# self.procTime=activeEntity.remainingRoute[0][1] #read the processing time from the entity
import
Globals
# read the list of next stations
...
...
@@ -61,35 +64,65 @@ class MachineJobShop(Machine):
# self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
activeEntity
.
remainingRoute
.
pop
(
0
)
#remove data from the remaining route of the entity
return
activeEntity
#calculates the processing time
# =======================================================================
# calculates the processing time
# =======================================================================
def
calculateProcessingTime
(
self
):
return
self
.
procTime
#this is the processing time for this unique entity
#checks if the Queue can accept an entity
#it checks also the next station of the Entity and returns true only if the active object is the next station
# =======================================================================
# checks if the Queue can accept an entity
# it checks also the next station of the Entity
# and returns true only if the active object is the next station
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
if
callerObject
!=
None
:
#check it the caller object holds an Entity that requests for current object
if
len
(
callerObject
.
getActiveObjectQueue
())
>
0
:
activeEntity
=
callerObject
.
getActiveObjectQueue
()[
0
]
# if the machine's Id is in the list of the entity's next stations
if
self
.
id
in
activeEntity
.
remainingRoute
[
0
].
get
(
'stationIdsList'
,[]):
if
self
.
id
in
activeEntity
.
remainingRoute
[
1
].
get
(
'stationIdsList'
,[]):
# if activeEntity.remainingRoute[0][0]==self.id:
return
len
(
self
.
getActiveObjectQueue
())
<
self
.
capacity
#return according to the state of the Queue
return
False
#checks if the Machine can dispose an entity. Returns True only to the potential receiver
# =======================================================================
# checks if the Machine can dispose an entity.
# Returns True only to the potential receiver
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
# get active object and its queue
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
# find the receiver waiting the most
activeObject
.
receiver
=
activeObject
.
updateReceiverObject
()
thecaller
=
callerObject
#if we have only one successor just check if machine waits to dispose and also is up
# this is done to achieve better (cpu) processing time
if
(
len
(
activeObject
.
next
)
==
1
or
callerObject
==
None
):
activeObject
.
receiver
=
activeObject
.
next
[
0
]
return
len
(
activeObjectQueue
)
>
0
\
and
activeObject
.
waitToDispose
\
and
activeObject
.
Up
\
and
thecaller
==
activeObject
.
receiver
thecaller
=
callerObject
# give the entity to the successor that is waiting for the most time.
# (plant simulation does not do this in every occasion!)
maxTimeWaiting
=
0
# dummy variable counting the time a successor is waiting
for
object
in
activeObject
.
next
:
if
(
object
.
canAccept
(
activeObject
)):
# if a successor can accept an object
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
# the time it has been waiting is updated and stored in dummy variable timeWaiting
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting
=
timeWaiting
activeObject
.
receiver
=
object
# set the receiver as the longest waiting possible receiver
# in the next loops, check the other successors in the previous list
#return True if the Machine in the state of disposing and the caller is the receiver
return
len
(
activeObjectQueue
)
>
0
and
activeObject
.
waitToDispose
\
and
activeObject
.
Up
and
(
callerObject
is
self
.
receiver
)
return
len
(
activeObjectQueue
)
>
0
\
and
activeObject
.
waitToDispose
\
and
activeObject
.
Up
\
and
(
thecaller
is
self
.
receiver
)
\ No newline at end of file
dream/simulation/Queue.py
View file @
e8834d6a
...
...
@@ -234,7 +234,7 @@ class Queue(CoreObject):
RPT
=
0
for
step
in
entity
.
remainingRoute
:
processingTime
=
step
[
'processingTime'
]
RPT
+=
processingTime
.
get
(
'mean'
,
0
)
RPT
+=
float
(
processingTime
.
get
(
'mean'
,
0
)
)
# RPT+=step[1]
entity
.
remainingProcessingTime
=
RPT
activeObjectQ
.
sort
(
key
=
lambda
x
:
x
.
remainingProcessingTime
,
reverse
=
True
)
...
...
@@ -243,7 +243,7 @@ class Queue(CoreObject):
for
entity
in
activeObjectQ
:
LPT
=
0
processingTime
=
entity
.
remainingRoute
[
0
][
'processingTime'
]
entity
.
processingTimeInNextStation
=
processingTime
.
get
(
'mean'
,
0
)
entity
.
processingTimeInNextStation
=
float
(
processingTime
.
get
(
'mean'
,
0
)
)
# entity.processingTimeInNextStation=entity.remainingRoute[0][1]
activeObjectQ
.
sort
(
key
=
lambda
x
:
x
.
processingTimeInNextStation
,
reverse
=
True
)
#if the schedulingRule is to sort Entities according to shortest processing time first in the next station
...
...
@@ -251,7 +251,7 @@ class Queue(CoreObject):
for
entity
in
activeObjectQ
:
LPT
=
0
processingTime
=
entity
.
remainingRoute
[
0
][
'processingTime'
]
entity
.
processingTimeInNextStation
=
processingTime
.
get
(
'mean'
,
0
)
entity
.
processingTimeInNextStation
=
float
(
processingTime
.
get
(
'mean'
,
0
)
)
# entity.processingTimeInNextStation=entity.remainingRoute[0][1]
activeObjectQ
.
sort
(
key
=
lambda
x
:
x
.
processingTimeInNextStation
)
#if the schedulingRule is to sort Entities based on the minimum slackness
...
...
@@ -260,7 +260,7 @@ class Queue(CoreObject):
RPT
=
0
for
step
in
entity
.
remainingRoute
:
processingTime
=
step
[
'processingTime'
]
RPT
+=
processingTime
.
get
(
'mean'
,
0
)
RPT
+=
float
(
processingTime
.
get
(
'mean'
,
0
)
)
# RPT+=step[1]
entity
.
remainingProcessingTime
=
RPT
activeObjectQ
.
sort
(
key
=
lambda
x
:
(
x
.
dueDate
-
x
.
remainingProcessingTime
))
...
...
dream/simulation/QueueJobShop.py
View file @
e8834d6a
...
...
@@ -30,53 +30,80 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from
Queue
import
Queue
#the QueueJobShop object
# ===========================================================================
# the QueueJobShop object
# ===========================================================================
class
QueueJobShop
(
Queue
):
#set all the objects in previous and next
# =======================================================================
# set all the objects in previous and next
# =======================================================================
def
initialize
(
self
):
from
Globals
import
G
self
.
previous
=
G
.
ObjList
self
.
next
=
G
.
ObjList
Queue
.
initialize
(
self
)
#run default behaviour
#checks if the Queue can accept an entity
#it checks also the next station of the Entity and returns true only if the active object is the next station
# =======================================================================
# checks if the Queue can accept an entity
# it checks also the next station of the Entity
# and returns true only if the active object is the next station
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
if
callerObject
!=
None
:
#check it the caller object holds an Entity that requests for current object
if
len
(
callerObject
.
getActiveObjectQueue
())
>
0
:
activeEntity
=
callerObject
.
getActiveObjectQueue
()[
0
]
# check if the object in the active entity's route next step
if
self
.
id
in
activeEntity
.
remainingRoute
[
0
].
get
(
'stationIdsList'
,[]):
if
self
.
id
in
activeEntity
.
remainingRoute
[
1
].
get
(
'stationIdsList'
,[]):
# if activeEntity.remainingRoute[0][0]==self.id:
return
len
(
self
.
getActiveObjectQueue
())
<
self
.
capacity
#return according to the state of the Queue
return
False
#checks if the Machine can dispose an entity. Returns True only to the potential receiver
# =======================================================================
# checks if the Machine can dispose an entity.
# Returns True only to the potential receiver
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
# get active object and its queue
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
# update the receiver object
activeObject
.
receiver
=
activeObject
.
updateReceiverObject
()
thecaller
=
callerObject
#if we have only one possible receiver just check if the Queue holds one or more entities
if
(
len
(
activeObject
.
next
)
==
1
or
callerObject
==
None
):
activeObject
.
receiver
=
activeObject
.
next
[
0
]
return
len
(
activeObjectQueue
)
>
0
\
and
thecaller
==
activeObject
.
receiver
#give the entity to the possible receiver that is waiting for the most time.
#plant does not do this in every occasion!
maxTimeWaiting
=
0
# loop through the object in the successor list
for
object
in
activeObject
.
next
:
if
(
object
.
canAccept
()):
# if the object can accept
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
# compare the time that it has been waiting
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# with the others'
maxTimeWaiting
=
timeWaiting
self
.
receiver
=
object
# and update the receiver to the index of this object
#return True if the Queue has Entities and the caller is the receiver
return
len
(
activeObjectQueue
)
>
0
and
(
callerObject
is
self
.
receiver
)
return
len
(
activeObjectQueue
)
>
0
and
(
thecaller
is
self
.
receiver
)
#gets an entity from the predecessor that the predecessor index points to
# =======================================================================
# gets an entity from the predecessor that the predecessor index points to
# =======================================================================
def
getEntity
(
self
):
activeObject
=
self
.
getActiveObject
()
activeEntity
=
Queue
.
getEntity
(
self
)
import
Globals
# read the possible receivers - update the next list
import
Globals
nextObjectIds
=
activeEntity
.
remainingRoute
[
1
].
get
(
'stationIdsList'
,[])
nextObjects
=
[]
for
nextObjectId
in
nextObjectIds
:
nextObject
=
Globals
.
findObjectById
(
nextObjectId
)
nextObjects
.
append
(
nextObject
)
activeObject
.
next
=
nextObjects
# self.next=Globals.findObjectById(activeEntity.remainingRoute[1].get('stationIdsList',[]))
# self.receiver=Globals.findObjectById(activeEntity.remainingRoute[1][0]) #read the next station
activeEntity
.
remainingRoute
.
pop
(
0
)
#remove data from the remaining route of the entity
return
activeEntity
...
...
dream/tests/dump/Topology18.json.result
View file @
e8834d6a
...
...
@@ -13,59 +13,73 @@
"extraPropertyDict": {
"route": [
{
"stationIdsList": [
"Q1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q1",
"stepNumber": "0"
},
{
"stationIdsList": [
"M1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
},
"stationId": "M1",
"stepNumber": "1"
},
{
"stationIdsList": [
"Q3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q3",
"stepNumber": "2"
},
{
"stationIdsList": [
"M3"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "3"
},
"stationId": "M3",
"stepNumber": "3"
},
{
"stationIdsList": [
"Q2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "Q2",
"stepNumber": "4"
},
{
"stationIdsList": [
"M2"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "2"
},
"stationId": "M2",
"stepNumber": "5"
},
{
"stationIdsList": [
"E1"
],
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
},
"stationId": "E1",
"stepNumber": "6"
}
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment