def createWIP():
    G.JobList = []
    G.WipList = []
    G.EntityList = []
    G.PartList = []
    G.OrderComponentList = []
    G.DesignList = []  # list of the OrderDesigns in the system
    G.OrderList = []
    G.MouldList = []
    G.BatchList = []
    G.SubBatchList = []
    G.CapacityEntityList = []
    G.CapacityProjectList = []
    # entities that just finished processing in a station
    # and have to enter the next machine
    G.pendingEntities = []
    #Read the json data
    json_data = G.JSONData
    # read from the dictionary the dicts with key 'BOM' (if there are any)
    input = json_data.get('input', {})
    bom = input.get('BOM', None)
    if bom:
        orders = bom.get('productionOrders', [])
        # for every order in the productionOrders list
        for prodOrder in orders:
            orderClass = prodOrder.get('_class', None)
            orderType = Globals.getClassFromName(orderClass)
            # make sure that their type is Dream.Order
            if orderClass == 'Dream.Order':
                id = prodOrder.get('id', 'not found')
                name = prodOrder.get('name', 'not found')
                priority = int(prodOrder.get('priority', '0'))
                dueDate = float(prodOrder.get('dueDate', '0'))
                orderDate = float(prodOrder.get('orderDate', '0'))
                isCritical = bool(int(prodOrder.get('isCritical', '0')))
                componentsReadyForAssembly = bool(
                    (prodOrder.get('componentsReadyForAssembly', False)))
                componentsList = prodOrder.get('componentsList', {})
                # keep a reference of all extra properties passed to the job
                extraPropertyDict = {}
                for key, value in prodOrder.items():
                    if key not in ('_class', 'id'):
                        extraPropertyDict[key] = value
                # initiate the Order
                O = Order(
                    'G' + id,
                    'general ' + name,
                    route=[],
                    priority=priority,
                    dueDate=dueDate,
                    orderDate=orderDate,
                    isCritical=isCritical,
                    componentsList=componentsList,
                    componentsReadyForAssembly=componentsReadyForAssembly,
                    extraPropertyDict=extraPropertyDict)
                G.OrderList.append(O)
            else:
                productionOrderClass = prodOrder.get('_class', None)
                productionOrderType = Globals.getClassFromName(
                    productionOrderClass)
                inputDict = dict(prodOrder)
                inputDict.pop('_class')
                from dream.simulation.Entity import Entity
                if issubclass(productionOrderType, Entity):
                    entity = productionOrderType(**inputDict)
                    G.EntityList.append(entity)

    # read from the dictionary the dicts with key 'nodes'
    nodes = json_data["graph"]['node']
    for (element_id, element) in nodes.iteritems():
        element['id'] = element_id
        wip = element.get('wip', [])
        from dream.simulation.OrderDesign import OrderDesign
        for entity in wip:
            # if there is BOM defined
            if bom:
                # and production orders in it
                if bom.get('productionOrders', []):
                    # find which order has the entity in its componentsList
                    for order in G.OrderList:
                        if order.componentsList:
                            for componentDict in order.componentsList:
                                # if the entity has no parent order the following control will not be performed
                                if entity['id'] == componentDict['id']:
                                    entityCurrentSeq = int(
                                        entity['sequence']
                                    )  # the current seq number of the entity's  route
                                    entityRemainingProcessingTime = entity.get(
                                        'remainingProcessingTime', {})
                                    entityRemainingSetupTime = entity.get(
                                        'remainingSetupTime', {})
                                    ind = 0  # holder of the route index corresponding to the entityCurrentSeq
                                    solution = False  # flag to signal that the route step is found
                                    # find the step that corresponds to the entityCurrentSeq
                                    for i, step in enumerate(
                                            componentDict.get('route', [])):
                                        stepSeq = step[
                                            'sequence']  # the sequence of step i
                                        if stepSeq == '':
                                            stepSeq = 0  # if the seq is ''>OrderDecomposition then 0
                                        # if the entityCurrentSeq is found and the id of the holding Station is in the steps stationIdsList
                                        if int(
                                                stepSeq
                                        ) == entityCurrentSeq and element[
                                                'id'] in step['stationIdsList']:
                                            ind = i  # hold the index
                                            solution = True  # the solution isfound
                                            break
                                    # assert that there is solution
                                    assert solution, 'something is wrong with the initial step of ' + entity[
                                        'id']
                                    # the remaining route of the entity assuming that the given route doesn't start from the entityCurrentSeq
                                    entityRoute = componentDict.get(
                                        'route', [])[ind:]
                                    entity = dict(
                                        componentDict)  # copy the entity dict
                                    entity.pop('route')  # remove the old route
                                    entity[
                                        'route'] = entityRoute  # and hold the new one without the previous steps
                                    entity['order'] = order.id
                                    entity[
                                        'remainingProcessingTime'] = entityRemainingProcessingTime
                                    entity[
                                        'remainingSetupTime'] = entityRemainingSetupTime
                                    break

            entityClass = entity.get('_class', None)
            entityType = Globals.getClassFromName(entityClass)
            inputDict = dict(entity)
            inputDict.pop('_class')
            from dream.simulation.Entity import Entity
            if issubclass(entityType,
                          Entity) and (not entityClass == 'Dream.Order'):
                # if orders are provided separately (BOM) provide the parent order as argument
                if entity.get('order', None):
                    entityOrder = Globals.findObjectById(entity['order'])
                    inputDict.pop('order')
                    entity = entityType(order=entityOrder, **inputDict)
                    entity.routeInBOM = True
                else:
                    entity = entityType(**inputDict)
                G.EntityList.append(entity)
                object = Globals.findObjectById(element['id'])
                entity.currentStation = object

            # ToDo order is to defined in a new way
            if entityClass == 'Dream.Order':
                id = entity.get('id', 'not found')
                name = entity.get('name', 'not found')
                priority = int(entity.get('priority', '0'))
                dueDate = float(entity.get('dueDate', '0'))
                orderDate = float(entity.get('orderDate', '0'))
                isCritical = bool(int(entity.get('isCritical', '0')))
                basicsEnded = bool(int(entity.get('basicsEnded', '0')))
                componentsReadyForAssembly = bool(
                    (entity.get('componentsReadyForAssembly', False)))
                # read the manager ID
                manager = entity.get('manager', None)
                # if a manager ID is assigned then search for the operator with the corresponding ID
                # and assign it as the manager of the order
                if manager:
                    for operator in G.OperatorsList:
                        if manager == operator.id:
                            manager = operator
                            break
                componentsList = entity.get('componentsList', {})
                JSONRoute = entity.get(
                    'route',
                    [])  # dummy variable that holds the routes of the jobs
                #    the route from the JSON file
                #    is a sequence of dictionaries
                route = [x for x in JSONRoute]  #    copy JSONRoute

                # keep a reference of all extra properties passed to the job
                extraPropertyDict = {}
                for key, value in entity.items():
                    if key not in ('_class', 'id'):
                        extraPropertyDict[key] = value

                #Below it is to assign an order decomposition if it was not assigned in JSON
                #have to talk about it with NEX
                odAssigned = False
                for element in route:
                    elementIds = element.get('stationIdsList', [])
                    for obj in G.ObjList:
                        for elementId in elementIds:
                            if obj.id == elementId and obj.type == 'OrderDecomposition':
                                odAssigned = True
                if not odAssigned:
                    odId = None
                    for obj in G.ObjList:
                        if obj.type == 'OrderDecomposition':
                            odId = obj.id
                            break
                    if odId:
                        #                         route.append([odId, 0])
                        route.append({'stationIdsList':[odId],\
                                      'processingTime':\
                                            {'distributionType':'Fixed',\
                                             'mean':'0'}})
                # XXX dirty way to implement new approach were the order is abstract and does not run through the system
                # but the OrderDesign does
                # XXX initiate the Order and the OrderDesign
                O = Order(
                    'G' + id,
                    'general ' + name,
                    route=[],
                    priority=priority,
                    dueDate=dueDate,
                    orderDate=orderDate,
                    isCritical=isCritical,
                    basicsEnded=basicsEnded,
                    manager=manager,
                    componentsList=componentsList,
                    componentsReadyForAssembly=componentsReadyForAssembly,
                    extraPropertyDict=extraPropertyDict)
                # create the OrderDesign
                OD = OrderDesign(id,
                                 name,
                                 route,
                                 priority=priority,
                                 dueDate=dueDate,
                                 orderDate=orderDate,
                                 isCritical=isCritical,
                                 order=O,
                                 extraPropertyDict=extraPropertyDict)
                # add the order to the OrderList
                G.OrderList.append(O)
                # add the OrderDesign to the DesignList and the OrderComponentList
                G.OrderComponentList.append(OD)
                G.DesignList.append(OD)
                G.WipList.append(OD)
                G.EntityList.append(OD)
                G.JobList.append(OD)
def createObjectResourcesAndCoreObjects():

    json_data = G.JSONData
    #Read the json data
    # nodes = json_data['nodes']                      # read from the dictionary the dicts with key 'nodes'
    nodes = json_data['graph'][
        "node"]  # read from the dictionary the dicts with key 'nodes'
    edges = json_data['graph'][
        "edge"]  # read from the dictionary the dicts with key 'edges'
    '''
    getSuccesorList method to get the successor 
    list of object with ID = id
    XXX slow implementation
    '''
    def getSuccessorList(
            node_id,
            predicate=lambda source, destination, edge_class, edge_data: True):
        successor_list = [
        ]  # dummy variable that holds the list to be returned

        for edge in edges.values():
            source = edge["source"]
            destination = edge["destination"]
            edge_class = edge["_class"]
            edge_data = edge.get("data", {})
            if source == node_id:  # for the node_id argument
                if predicate(source, destination, edge_class,
                             edge_data):  # find its 'destinations' and
                    successor_list.append(
                        destination)  # append it to the successor list
        # XXX We should probably not need to sort, but there is a bug that
        # prevents Topology10 to work if this sort is not used.
        successor_list.sort()
        return successor_list

    '''
    define the lists of each object type
    '''
    G.SourceList = []
    G.MachineList = []
    G.ExitList = []
    G.QueueList = []
    G.RepairmanList = []
    G.AssemblyList = []
    G.DismantleList = []
    G.ConveyerList = []
    G.MachineJobShopList = []
    G.QueueJobShopList = []
    G.ExitJobShopList = []
    G.BatchDecompositionList = []
    G.BatchSourceList = []
    G.BatchReassemblyList = []
    G.RoutingQueueList = []
    G.LineClearanceList = []
    G.EventGeneratorList = []
    G.OperatorsList = []
    G.OperatorManagedJobsList = []
    G.OperatorPoolsList = []
    G.BrokersList = []
    G.OperatedMachineList = []
    G.BatchScrapMachineList = []
    G.OrderDecompositionList = []
    G.ConditionalBufferList = []
    G.MouldAssemblyBufferList = []
    G.MouldAssemblyList = []
    G.MachineManagedJobList = []
    G.QueueManagedJobList = []
    G.ObjectResourceList = []
    G.CapacityStationBufferList = []
    G.AllocationManagementList = []
    G.CapacityStationList = []
    G.CapacityStationExitList = []
    G.CapacityStationControllerList = []
    '''
    loop through all the model resources 
    search for repairmen and operators in order to create them
    read the data and create them
    '''

    for (element_id, element
         ) in nodes.iteritems():  # use an iterator to go through all the nodes
        element[
            'id'] = element_id  # create a new entry for the element (dictionary)
        element = element.copy()
        for k in ('element_id', 'top', 'left'):
            element.pop(k, None)
            # with key 'id' and value the the element_id
        resourceClass = element.pop(
            '_class')  # get the class type of the element

        objectType = Globals.getClassFromName(resourceClass)
        from dream.simulation.ObjectResource import ObjectResource  # operator pools to be created later since they use operators
        # ToDo maybe it is semantically diferent object
        if issubclass(
                objectType,
                ObjectResource) and not resourceClass == 'Dream.OperatorPool':
            inputDict = dict(element)
            # create the CoreObject
            objectResource = objectType(**inputDict)
            # if there already coreObjectsIds defined then append the successors to them
            if objectResource.coreObjectIds:
                for element in getSuccessorList(element['id']):
                    if not element in objectResource.coreObjectIds:
                        objectResource.coreObjectIds.append(element)
            else:
                objectResource.coreObjectIds = getSuccessorList(element['id'])
    '''
    loop through all the model resources 
    search for operatorPools in order to create them
    read the data and create them
    '''
    from dream.simulation.OperatorPool import OperatorPool
    for (element_id, element
         ) in nodes.iteritems():  # use an iterator to go through all the nodes
        # the key is the element_id and the second is the
        # element itself
        element = element.copy()
        element[
            'id'] = element_id  # create a new entry for the element (dictionary)
        for k in ('element_id', 'top', 'left'):
            element.pop(k, None)
            # with key 'id' and value the the element_id
        resourceClass = element.pop(
            '_class')  # get the class type of the element
        if resourceClass == 'Dream.OperatorPool':
            id = element.get(
                'id', 'not found'
            )  # get the id of the element   / default 'not_found'
            name = element.get(
                'name', 'not found'
            )  # get the name of the element / default 'not_found'
            capacity = int(element.get('capacity') or 1)
            operatorsList = []
            for operator in G.OperatorsList:  # find the operators assigned to the operatorPool
                if id in operator.coreObjectIds:
                    operatorsList.append(operator)
#             operatorsList = element.get('operatorsList', 'not found')
            if len(
                    operatorsList
            ) == 0:  # if the operatorsList is empty then assign no operators
                OP = OperatorPool(element_id, name,
                                  capacity)  # create a operatorPool object
            else:
                OP = OperatorPool(
                    element_id, name, capacity,
                    operatorsList)  # create a operatorPool object
            OP.coreObjectIds = getSuccessorList(
                id
            )  # update the list of objects that the operators of the operatorPool operate
            for operator in operatorsList:
                operator.coreObjectIds = OP.coreObjectIds  # update the list of objects that the operators operate
            G.OperatorPoolsList.append(
                OP)  # add the operatorPool to the RepairmanList
    '''
    loop through all the elements    
    read the data and create them
    '''
    for (element_id, element) in nodes.iteritems():
        element = element.copy()
        element['id'] = element_id
        element.setdefault('name', element_id)

        # XXX not sure about top & left.
        for k in ('element_id', 'top', 'left'):
            element.pop(k, None)
        objClass = element.pop('_class')
        objectType = Globals.getClassFromName(objClass)

        from dream.simulation.CoreObject import CoreObject
        if issubclass(objectType, CoreObject):
            # remove data that has to do with wip or object interruption. CoreObjects do not need it
            inputDict = dict(element)
            # create the CoreObject
            coreObject = objectType(**inputDict)
            # update the nextIDs list of the object
            coreObject.nextIds = getSuccessorList(element['id'])
            # (Below is only for Dismantle for now)
            # get the successorList for the 'Parts'
            coreObject.nextPartIds = getSuccessorList(
                element['id'], lambda source, destination, edge_class,
                edge_data: edge_data.get('entity', {}) == 'Part')
            # get the successorList for the 'Frames'
            coreObject.nextFrameIds = getSuccessorList(
                element['id'], lambda source, destination, edge_class,
                edge_data: edge_data.get('entity', {}) == 'Frame')

    #                    loop through all the core objects
    #                         to read predecessors
    for element in G.ObjList:
        #loop through all the nextIds of the object
        for nextId in element.nextIds:
            #loop through all the core objects to find the on that has the id that was read in the successorList
            for possible_successor in G.ObjList:
                if possible_successor.id == nextId:
                    possible_successor.previousIds.append(element.id)
def createObjectInterruptions():
    G.ObjectInterruptionList = []
    G.ScheduledMaintenanceList = []
    G.FailureList = []
    G.BreakList = []
    G.ShiftSchedulerList = []
    G.EventGeneratorList = []
    G.CapacityStationControllerList = []
    G.PeriodicMaintenanceList = []
    json_data = G.JSONData
    #Read the json data
    nodes = json_data['graph'][
        "node"]  # read from the dictionary the dicts with key 'nodes'

    #                loop through all the nodes to
    #            search for Event Generator and create them
    #                   this is put last, since the EventGenerator
    #                may take other objects as argument
    for (element_id, element
         ) in nodes.iteritems():  # use an iterator to go through all the nodes
        # the key is the element_id and the second is the
        # element itself
        element[
            'id'] = element_id  # create a new entry for the element (dictionary)
        # with key 'id' and value the the element_id
        objClass = element.get(
            '_class', 'not found')  # get the class type of the element
        from dream.simulation.ObjectInterruption import ObjectInterruption
        objClass = element.pop('_class')
        objectType = Globals.getClassFromName(objClass)
        # from CoreObject import CoreObject
        # if issubclass(objectType, CoreObject):

        if issubclass(objectType, ObjectInterruption):  # check the object type
            inputDict = dict(element)
            # create the ObjectInterruption
            objectInterruption = objectType(**inputDict)
            if not 'OperatorRouter' in str(objectType):
                G.ObjectInterruptionList.append(objectInterruption)

    # search inside the nodes for encapsulated ObjectInterruptions (failures etc)
    # ToDo this will be cleaned a lot if we update the JSON notation:
    # define ObjectInterruption echelon inside node
    # define interruptions' distribution better
    from dream.simulation.ScheduledMaintenance import ScheduledMaintenance
    from dream.simulation.Failure import Failure
    from dream.simulation.PeriodicMaintenance import PeriodicMaintenance
    from dream.simulation.ShiftScheduler import ShiftScheduler
    from dream.simulation.Break import Break
    for (element_id, element) in nodes.iteritems():
        element['id'] = element_id
        scheduledMaintenance = element.get('interruptions',
                                           {}).get('scheduledMaintenance', {})
        # if there is a scheduled maintenance initiate it and append it
        # to the interruptions- and scheduled maintenances- list
        if len(scheduledMaintenance):
            start = float(scheduledMaintenance.get('start', 0))
            duration = float(scheduledMaintenance.get('duration', 1))
            victim = Globals.findObjectById(element['id'])
            SM = ScheduledMaintenance(victim=victim,
                                      start=start,
                                      duration=duration)
            G.ObjectInterruptionList.append(SM)
            G.ScheduledMaintenanceList.append(SM)
        failure = element.get('interruptions', {}).get('failure', None)
        # if there are failures assigned
        # initiate them
        if failure:
            victim = Globals.findObjectById(element['id'])
            deteriorationType = failure.get('deteriorationType', 'constant')
            waitOnTie = failure.get('waitOnTie', False)
            F = Failure(victim=victim,
                        distribution=failure,
                        repairman=victim.repairman,
                        deteriorationType=deteriorationType,
                        waitOnTie=waitOnTie)
            G.ObjectInterruptionList.append(F)
            G.FailureList.append(F)
        # if there are periodic maintenances assigned
        # initiate them
        periodicMaintenance = element.get('interruptions',
                                          {}).get('periodicMaintenance', None)
        if periodicMaintenance:
            distributionType = periodicMaintenance.get('distributionType',
                                                       'No')
            victim = Globals.findObjectById(element['id'])
            PM = PeriodicMaintenance(victim=victim,
                                     distribution=periodicMaintenance,
                                     repairman=victim.repairman)
            G.ObjectInterruptionList.append(PM)
            G.PeriodicMaintenanceList.append(PM)
        # if there is a shift pattern defined
        # initiate them
        shift = element.get('interruptions', {}).get('shift', {})
        if len(shift):
            victim = Globals.findObjectById(element['id'])
            shiftPattern = list(shift.get('shiftPattern', []))
            # patch to correct if input has end of shift at the same time of start of next shift
            # TODO check if the backend should be able to handle this
            for index, record in enumerate(shiftPattern):
                if record is shiftPattern[-1]:
                    break
                next = shiftPattern[index + 1]
                if record[1] == next[0]:
                    record[1] = next[1]
                    shiftPattern.remove(next)
            endUnfinished = bool(int(shift.get('endUnfinished', 0)))
            receiveBeforeEndThreshold = float(
                shift.get('receiveBeforeEndThreshold', 0))
            thresholdTimeIsOnShift = bool(
                int(shift.get('thresholdTimeIsOnShift', 1)))
            rolling = bool(int(shift.get('rolling', 0)))
            lastOffShiftDuration = float(shift.get('lastOffShiftDuration', 10))
            SS = ShiftScheduler(
                victim=victim,
                shiftPattern=shiftPattern,
                endUnfinished=endUnfinished,
                receiveBeforeEndThreshold=receiveBeforeEndThreshold,
                thresholdTimeIsOnShift=thresholdTimeIsOnShift,
                rolling=rolling,
                lastOffShiftDuration=lastOffShiftDuration)
            G.ObjectInterruptionList.append(SS)
            G.ShiftSchedulerList.append(SS)
        br = element.get('interruptions', {}).get('break', None)
        # if there are breaks assigned
        # initiate them
        if br:
            victim = Globals.findObjectById(element['id'])
            endUnfinished = bool(int(br.get('endUnfinished', 1)))
            offShiftAnticipation = br.get('offShiftAnticipation', 0)
            BR = Break(victim=victim,
                       distribution=br,
                       endUnfinished=endUnfinished,
                       offShiftAnticipation=offShiftAnticipation)
            G.ObjectInterruptionList.append(BR)
            G.BreakList.append(BR)
def createObjectResourcesAndCoreObjects():

    json_data = G.JSONData
    #Read the json data
    # nodes = json_data['nodes']                      # read from the dictionary the dicts with key 'nodes'
    nodes = json_data['graph']["node"]                      # read from the dictionary the dicts with key 'nodes'
    edges = json_data['graph']["edge"]                      # read from the dictionary the dicts with key 'edges'


    '''
    getSuccesorList method to get the successor 
    list of object with ID = id
    XXX slow implementation
    '''
    def getSuccessorList(node_id, predicate=lambda source, destination, edge_class, edge_data: True):
      successor_list = []                           # dummy variable that holds the list to be returned
      
      for edge in edges.values():
          source = edge["source"]
          destination = edge["destination"]
          edge_class = edge["_class"]
          edge_data = edge.get("data", {})
          if source == node_id:                               # for the node_id argument
              if predicate(source, destination, edge_class, edge_data):     # find its 'destinations' and 
                successor_list.append(destination)              # append it to the successor list
      # XXX We should probably not need to sort, but there is a bug that
      # prevents Topology10 to work if this sort is not used.
      successor_list.sort()
      return successor_list
    '''
    define the lists of each object type
    '''
    G.SourceList=[]
    G.MachineList=[]
    G.ExitList=[]
    G.QueueList=[]    
    G.RepairmanList=[]
    G.AssemblyList=[]
    G.DismantleList=[]
    G.ConveyerList=[]
    G.MachineJobShopList=[]
    G.QueueJobShopList=[]
    G.ExitJobShopList=[]
    G.BatchDecompositionList=[]
    G.BatchSourceList=[]
    G.BatchReassemblyList=[]
    G.RoutingQueueList=[]
    G.LineClearanceList=[]
    G.EventGeneratorList=[]
    G.OperatorsList = []
    G.OperatorManagedJobsList = []
    G.OperatorPoolsList = []
    G.BrokersList = []
    G.OperatedMachineList = []
    G.BatchScrapMachineList=[]
    G.OrderDecompositionList=[]
    G.ConditionalBufferList=[]
    G.MouldAssemblyBufferList=[]
    G.MouldAssemblyList=[]
    G.MachineManagedJobList=[]
    G.QueueManagedJobList=[]
    G.ObjectResourceList=[]
    G.CapacityStationBufferList=[]
    G.AllocationManagementList=[]
    G.CapacityStationList=[]
    G.CapacityStationExitList=[]
    G.CapacityStationControllerList=[]

    '''
    loop through all the model resources 
    search for repairmen and operators in order to create them
    read the data and create them
    '''

    for (element_id, element) in nodes.iteritems():                 # use an iterator to go through all the nodes
        element['id'] = element_id                                  # create a new entry for the element (dictionary)
        element = element.copy()
        for k in ('element_id', 'top', 'left'):
          element.pop(k, None)
                                                                    # with key 'id' and value the the element_id
        resourceClass = element.pop('_class')                       # get the class type of the element
        
        objectType=Globals.getClassFromName(resourceClass)    
        from dream.simulation.ObjectResource import ObjectResource     # operator pools to be created later since they use operators
                                                      # ToDo maybe it is semantically diferent object  
        if issubclass(objectType, ObjectResource) and not resourceClass=='Dream.OperatorPool':
            inputDict=dict(element)
            # create the CoreObject
            objectResource=objectType(**inputDict)
            # if there already coreObjectsIds defined then append the successors to them
            if objectResource.coreObjectIds:
                for element in getSuccessorList(element['id']):
                    if not element in objectResource.coreObjectIds:
                        objectResource.coreObjectIds.append(element)
            else:
                objectResource.coreObjectIds=getSuccessorList(element['id'])

    '''
    loop through all the model resources 
    search for operatorPools in order to create them
    read the data and create them
    '''
    from dream.simulation.OperatorPool import OperatorPool
    for (element_id, element) in nodes.iteritems():                 # use an iterator to go through all the nodes
                                                                    # the key is the element_id and the second is the 
                                                                    # element itself 
        element = element.copy()
        element['id'] = element_id                                  # create a new entry for the element (dictionary)
        for k in ('element_id', 'top', 'left'):
          element.pop(k, None)
                                                                    # with key 'id' and value the the element_id
        resourceClass = element.pop('_class')          # get the class type of the element
        if resourceClass=='Dream.OperatorPool':
            id = element.get('id', 'not found')                     # get the id of the element   / default 'not_found'
            name = element.get('name', 'not found')                 # get the name of the element / default 'not_found'
            capacity = int(element.get('capacity') or 1)
            operatorsList=[]
            for operator in G.OperatorsList:                        # find the operators assigned to the operatorPool
                if id in operator.coreObjectIds:
                    operatorsList.append(operator)
#             operatorsList = element.get('operatorsList', 'not found')
            if len(operatorsList)==0:                               # if the operatorsList is empty then assign no operators
                OP = OperatorPool(element_id, name, capacity)       # create a operatorPool object
            else:
                OP = OperatorPool(element_id, name, capacity,operatorsList)     # create a operatorPool object
            OP.coreObjectIds=getSuccessorList(id)                   # update the list of objects that the operators of the operatorPool operate            
            for operator in operatorsList:
                operator.coreObjectIds=OP.coreObjectIds        		# update the list of objects that the operators operate
            G.OperatorPoolsList.append(OP)                          # add the operatorPool to the RepairmanList
    '''
    loop through all the elements    
    read the data and create them
    '''
    for (element_id, element) in nodes.iteritems():
        element = element.copy()
        element['id'] = element_id
        element.setdefault('name', element_id)

        # XXX not sure about top & left.
        for k in ('element_id', 'top', 'left'):
          element.pop(k, None)
        objClass = element.pop('_class')
        objectType=Globals.getClassFromName(objClass)  
  
        from dream.simulation.CoreObject import CoreObject
        if issubclass(objectType, CoreObject):
            # remove data that has to do with wip or object interruption. CoreObjects do not need it
            inputDict=dict(element)           
            # create the CoreObject
            coreObject=objectType(**inputDict)
            # update the nextIDs list of the object
            coreObject.nextIds=getSuccessorList(element['id'])           
            # (Below is only for Dismantle for now)
            # get the successorList for the 'Parts'
            coreObject.nextPartIds=getSuccessorList(element['id'], lambda source, destination, edge_class, edge_data: edge_data.get('entity',{}) == 'Part')
            # get the successorList for the 'Frames'
            coreObject.nextFrameIds=getSuccessorList(element['id'], lambda source, destination, edge_class, edge_data: edge_data.get('entity',{}) == 'Frame')
            
    #                    loop through all the core objects    
    #                         to read predecessors
    for element in G.ObjList:
        #loop through all the nextIds of the object
        for nextId in element.nextIds:
            #loop through all the core objects to find the on that has the id that was read in the successorList
            for possible_successor in G.ObjList:
                if possible_successor.id==nextId:
                    possible_successor.previousIds.append(element.id)            
def createWIP():
    G.JobList=[]
    G.WipList=[]
    G.EntityList=[]  
    G.PartList=[]
    G.OrderComponentList=[]
    G.DesignList=[]     # list of the OrderDesigns in the system
    G.OrderList=[]
    G.MouldList=[]
    G.BatchList=[]
    G.SubBatchList=[]
    G.CapacityEntityList=[]
    G.CapacityProjectList=[]
    # entities that just finished processing in a station 
    # and have to enter the next machine 
    G.pendingEntities=[]
    #Read the json data
    json_data = G.JSONData
    # read from the dictionary the dicts with key 'BOM' (if there are any)
    input=json_data.get('input',{})
    bom=input.get('BOM',None)
    if bom:
        orders=bom.get('productionOrders',[])
        # for every order in the productionOrders list
        for prodOrder in orders:
            orderClass=prodOrder.get('_class',None)
            orderType=Globals.getClassFromName(orderClass)
            # make sure that their type is Dream.Order
            if orderClass=='Dream.Order':
                id=prodOrder.get('id', 'not found')
                name=prodOrder.get('name', 'not found')
                priority=int(prodOrder.get('priority', '0'))
                dueDate=float(prodOrder.get('dueDate', '0'))
                orderDate=float(prodOrder.get('orderDate', '0'))
                isCritical=bool(int(prodOrder.get('isCritical', '0')))  
                componentsReadyForAssembly = bool((prodOrder.get('componentsReadyForAssembly', False)))
                componentsList=prodOrder.get('componentsList', {})
                # keep a reference of all extra properties passed to the job
                extraPropertyDict = {}
                for key, value in prodOrder.items():
                  if key not in ('_class', 'id'):
                    extraPropertyDict[key] = value
                # initiate the Order
                O=Order('G'+id, 'general '+name, route=[], priority=priority, dueDate=dueDate,orderDate=orderDate,
                        isCritical=isCritical, componentsList=componentsList,
                        componentsReadyForAssembly=componentsReadyForAssembly, extraPropertyDict=extraPropertyDict)
                G.OrderList.append(O)
            else:
                productionOrderClass=prodOrder.get('_class', None)
                productionOrderType=Globals.getClassFromName(productionOrderClass)
                inputDict=dict(prodOrder)
                inputDict.pop('_class')
                from dream.simulation.Entity import Entity
                if issubclass(productionOrderType, Entity):
                    entity=productionOrderType(**inputDict)
                    G.EntityList.append(entity)                   
                
    # read from the dictionary the dicts with key 'nodes'
    nodes = json_data["graph"]['node']
    for (element_id, element) in nodes.iteritems():
        element['id'] = element_id
        wip=element.get('wip', [])
        from dream.simulation.OrderDesign import OrderDesign
        for entity in wip:
            # if there is BOM defined
            if bom:
                # and production orders in it
                if bom.get('productionOrders',[]):
                    # find which order has the entity in its componentsList
                    for order in G.OrderList:
                        if order.componentsList:
                            for componentDict in order.componentsList:
                                # if the entity has no parent order the following control will not be performed
                                if entity['id']==componentDict['id']:
                                    entityCurrentSeq=int(entity['sequence'])# the current seq number of the entity's  route
                                    entityRemainingProcessingTime=entity.get('remainingProcessingTime',{})
                                    entityRemainingSetupTime=entity.get('remainingSetupTime',{})
                                    ind=0               # holder of the route index corresponding to the entityCurrentSeq
                                    solution=False      # flag to signal that the route step is found
                                    # find the step that corresponds to the entityCurrentSeq
                                    for i, step in enumerate(componentDict.get('route',[])):
                                        stepSeq=step['sequence']        # the sequence of step i
                                        if stepSeq=='':
                                            stepSeq=0                   # if the seq is ''>OrderDecomposition then 0
                                        # if the entityCurrentSeq is found and the id of the holding Station is in the steps stationIdsList
                                        if int(stepSeq)==entityCurrentSeq and element['id'] in step['stationIdsList']:
                                            ind=i                       # hold the index 
                                            solution=True               # the solution isfound
                                            break
                                    # assert that there is solution
                                    assert solution, 'something is wrong with the initial step of '+entity['id']
                                    # the remaining route of the entity assuming that the given route doesn't start from the entityCurrentSeq
                                    entityRoute=componentDict.get('route',[])[ind:]
                                    entity=dict(componentDict)          # copy the entity dict
                                    entity.pop('route')                 # remove the old route
                                    entity['route']=entityRoute         # and hold the new one without the previous steps
                                    entity['order']=order.id
                                    entity['remainingProcessingTime']=entityRemainingProcessingTime
                                    entity['remainingSetupTime']=entityRemainingSetupTime
                                    break
            
            entityClass=entity.get('_class', None)
            entityType=Globals.getClassFromName(entityClass)
            inputDict=dict(entity)
            inputDict.pop('_class')
            from dream.simulation.Entity import Entity
            if issubclass(entityType, Entity) and (not entityClass=='Dream.Order'):
                # if orders are provided separately (BOM) provide the parent order as argument  
                if entity.get('order',None):
                    entityOrder=Globals.findObjectById(entity['order'])
                    inputDict.pop('order')
                    entity=entityType(order=entityOrder,**inputDict)
                    entity.routeInBOM=True
                else:
                    entity=entityType(**inputDict)
                G.EntityList.append(entity)
                object=Globals.findObjectById(element['id'])
                entity.currentStation=object
                
            # ToDo order is to defined in a new way
            if entityClass=='Dream.Order':
                id=entity.get('id', 'not found')
                name=entity.get('name', 'not found')
                priority=int(entity.get('priority', '0'))
                dueDate=float(entity.get('dueDate', '0'))
                orderDate=float(entity.get('orderDate', '0'))
                isCritical=bool(int(entity.get('isCritical', '0')))  
                basicsEnded=bool(int(entity.get('basicsEnded', '0'))) 
                componentsReadyForAssembly = bool((entity.get('componentsReadyForAssembly', False)))
                # read the manager ID
                manager=entity.get('manager', None)
                # if a manager ID is assigned then search for the operator with the corresponding ID
                # and assign it as the manager of the order 
                if manager:
                    for operator in G.OperatorsList:
                        if manager==operator.id:
                            manager=operator
                            break
                componentsList=entity.get('componentsList', {})
                JSONRoute=entity.get('route', [])                  # dummy variable that holds the routes of the jobs
                                                                    #    the route from the JSON file 
                                                                    #    is a sequence of dictionaries
                route = [x for x in JSONRoute]       #    copy JSONRoute
                
                # keep a reference of all extra properties passed to the job
                extraPropertyDict = {}
                for key, value in entity.items():
                  if key not in ('_class', 'id'):
                    extraPropertyDict[key] = value

                #Below it is to assign an order decomposition if it was not assigned in JSON
                #have to talk about it with NEX
                odAssigned=False
                for element in route:
                    elementIds = element.get('stationIdsList',[])
                    for obj in G.ObjList:
                        for elementId in elementIds:
                            if obj.id==elementId and obj.type=='OrderDecomposition':
                                odAssigned=True 
                if not odAssigned:
                    odId=None
                    for obj in G.ObjList:
                        if obj.type=='OrderDecomposition':
                            odId=obj.id
                            break
                    if odId:
#                         route.append([odId, 0])
                        route.append({'stationIdsList':[odId],\
                                      'processingTime':\
                                            {'distributionType':'Fixed',\
                                             'mean':'0'}})
                # XXX dirty way to implement new approach were the order is abstract and does not run through the system 
                # but the OrderDesign does
                # XXX initiate the Order and the OrderDesign
                O=Order('G'+id, 'general '+name, route=[], priority=priority, dueDate=dueDate,orderDate=orderDate,
                        isCritical=isCritical, basicsEnded=basicsEnded, manager=manager, componentsList=componentsList,
                        componentsReadyForAssembly=componentsReadyForAssembly, extraPropertyDict=extraPropertyDict)
                # create the OrderDesign
                OD=OrderDesign(id, name, route, priority=priority, dueDate=dueDate,orderDate=orderDate,
                        isCritical=isCritical, order=O, extraPropertyDict=extraPropertyDict)
                # add the order to the OrderList
                G.OrderList.append(O)
                # add the OrderDesign to the DesignList and the OrderComponentList
                G.OrderComponentList.append(OD)
                G.DesignList.append(OD)
                G.WipList.append(OD)  
                G.EntityList.append(OD)
                G.JobList.append(OD)
def createObjectInterruptions():
    G.ObjectInterruptionList=[]
    G.ScheduledMaintenanceList=[]
    G.FailureList=[]
    G.BreakList=[]
    G.ShiftSchedulerList=[]
    G.EventGeneratorList=[]
    G.CapacityStationControllerList=[]
    G.PeriodicMaintenanceList=[]
    json_data = G.JSONData
    #Read the json data
    nodes = json_data['graph']["node"]                      # read from the dictionary the dicts with key 'nodes'
    
    #                loop through all the nodes to  
    #            search for Event Generator and create them
    #                   this is put last, since the EventGenerator 
    #                may take other objects as argument
    for (element_id, element) in nodes.iteritems():                 # use an iterator to go through all the nodes
                                                                    # the key is the element_id and the second is the 
                                                                    # element itself 
        element['id'] = element_id                                  # create a new entry for the element (dictionary)
                                                                    # with key 'id' and value the the element_id
        objClass = element.get('_class', 'not found')           # get the class type of the element
        from dream.simulation.ObjectInterruption import ObjectInterruption
        objClass = element.pop('_class')
        objectType=Globals.getClassFromName(objClass)    
        # from CoreObject import CoreObject
        # if issubclass(objectType, CoreObject):
    
        if issubclass(objectType,ObjectInterruption):   # check the object type
            inputDict=dict(element)        
            # create the ObjectInterruption
            objectInterruption=objectType(**inputDict)
            if not 'OperatorRouter' in str(objectType):
                G.ObjectInterruptionList.append(objectInterruption)
    
    # search inside the nodes for encapsulated ObjectInterruptions (failures etc)
    # ToDo this will be cleaned a lot if we update the JSON notation:
    # define ObjectInterruption echelon inside node
    # define interruptions' distribution better
    from dream.simulation.ScheduledMaintenance import ScheduledMaintenance    
    from dream.simulation.Failure import Failure
    from dream.simulation.PeriodicMaintenance import PeriodicMaintenance    
    from dream.simulation.ShiftScheduler import ShiftScheduler
    from dream.simulation.Break import Break
    for (element_id, element) in nodes.iteritems():
        element['id'] = element_id
        scheduledMaintenance=element.get('interruptions',{}).get('scheduledMaintenance', {})
        # if there is a scheduled maintenance initiate it and append it
        # to the interruptions- and scheduled maintenances- list
        if len(scheduledMaintenance):
            start=float(scheduledMaintenance.get('start', 0))
            duration=float(scheduledMaintenance.get('duration', 1))
            victim=Globals.findObjectById(element['id'])
            SM=ScheduledMaintenance(victim=victim, start=start, duration=duration)
            G.ObjectInterruptionList.append(SM)
            G.ScheduledMaintenanceList.append(SM)
        failure=element.get('interruptions',{}).get('failure', None)
        # if there are failures assigned 
        # initiate them   
        if failure:
            victim=Globals.findObjectById(element['id'])
            deteriorationType=failure.get('deteriorationType', 'constant')
            waitOnTie=failure.get('waitOnTie', False)
            F=Failure(victim=victim, distribution=failure, repairman=victim.repairman, deteriorationType=deteriorationType,
                      waitOnTie=waitOnTie)
            G.ObjectInterruptionList.append(F)
            G.FailureList.append(F)
        # if there are periodic maintenances assigned 
        # initiate them   
        periodicMaintenance=element.get('interruptions',{}).get('periodicMaintenance', None)
        if periodicMaintenance:
            distributionType=periodicMaintenance.get('distributionType', 'No')
            victim=Globals.findObjectById(element['id'])
            PM=PeriodicMaintenance(victim=victim, distribution=periodicMaintenance, repairman=victim.repairman)
            G.ObjectInterruptionList.append(PM)
            G.PeriodicMaintenanceList.append(PM)
        # if there is a shift pattern defined 
        # initiate them             
        shift=element.get('interruptions',{}).get('shift', {})
        if len(shift):
            victim=Globals.findObjectById(element['id'])
            shiftPattern=list(shift.get('shiftPattern', []))
            # patch to correct if input has end of shift at the same time of start of next shift
            # TODO check if the backend should be able to handle this
            for index, record in enumerate(shiftPattern):
                if record is shiftPattern[-1]:
                    break
                next = shiftPattern[index + 1]
                if record[1]==next[0]:
                    record[1]=next[1]
                    shiftPattern.remove(next)
            endUnfinished=bool(int(shift.get('endUnfinished', 0)))
            receiveBeforeEndThreshold=float(shift.get('receiveBeforeEndThreshold', 0))
            thresholdTimeIsOnShift=bool(int(shift.get('thresholdTimeIsOnShift', 1)))
            rolling=bool(int(shift.get('rolling', 0)))
            lastOffShiftDuration=float(shift.get('lastOffShiftDuration', 10))
            SS=ShiftScheduler(victim=victim, shiftPattern=shiftPattern, endUnfinished=endUnfinished, 
                              receiveBeforeEndThreshold=receiveBeforeEndThreshold,
                              thresholdTimeIsOnShift=thresholdTimeIsOnShift,
                              rolling=rolling, lastOffShiftDuration=lastOffShiftDuration)
            G.ObjectInterruptionList.append(SS)
            G.ShiftSchedulerList.append(SS)
        br=element.get('interruptions',{}).get('break', None)
        # if there are breaks assigned 
        # initiate them   
        if br:
            victim=Globals.findObjectById(element['id'])
            endUnfinished=bool(int(br.get('endUnfinished', 1)))
            offShiftAnticipation=br.get('offShiftAnticipation',0)
            BR=Break(victim=victim, distribution=br,endUnfinished=endUnfinished,
                     offShiftAnticipation=offShiftAnticipation)
            G.ObjectInterruptionList.append(BR)
            G.BreakList.append(BR)
Exemple #7
0
def createWIP():
    G.JobList=[]
    G.WipList=[]
    G.EntityList=[]  
    G.PartList=[]
    G.OrderComponentList=[]
    G.DesignList=[]     # list of the OrderDesigns in the system
    G.OrderList=[]
    G.MouldList=[]
    G.BatchList=[]
    G.SubBatchList=[]
    G.CapacityEntityList=[]
    G.CapacityProjectList=[]
    # entities that just finished processing in a station 
    # and have to enter the next machine 
    G.pendingEntities=[]
    json_data = G.JSONData
    #Read the json data
    nodes = json_data['nodes']                      # read from the dictionary the dicts with key 'nodes'
    for (element_id, element) in nodes.iteritems():
        element['id'] = element_id
        wip=element.get('wip', [])
        from dream.simulation.OrderDesign import OrderDesign
        from Order import Order
        for entity in wip:
            entityClass=entity.get('_class', None)
            entityType=Globals.getClassFromName(entityClass)
            inputDict=dict(entity)
            inputDict.pop('_class')
            from dream.simulation.Entity import Entity
            if issubclass(entityType, Entity) and (not entityClass=='Dream.Order'):
                entity=entityType(**inputDict)   
                G.EntityList.append(entity)    
                object=Globals.findObjectById(element['id'])
                entity.currentStation=object   
                
            # ToDo order is to defined in a new way
            if entityClass=='Dream.Order':
                id=entity.get('id', 'not found')
                name=entity.get('name', 'not found')
                priority=int(entity.get('priority', '0'))
                dueDate=float(entity.get('dueDate', '0'))
                orderDate=float(entity.get('orderDate', '0'))
                isCritical=bool(int(entity.get('isCritical', '0')))  
                basicsEnded=bool(int(entity.get('basicsEnded', '0'))) 
                componentsReadyForAssembly = bool((entity.get('componentsReadyForAssembly', '0')))
                # read the manager ID
                manager=entity.get('manager', None)
                # if a manager ID is assigned then search for the operator with the corresponding ID
                # and assign it as the manager of the order 
                if manager:
                    for operator in G.OperatorsList:
                        if manager==operator.id:
                            manager=operator
                            break
                componentsList=entity.get('componentsList', {})
                JSONRoute=entity.get('route', [])                  # dummy variable that holds the routes of the jobs
                                                                    #    the route from the JSON file 
                                                                    #    is a sequence of dictionaries
                route = [x for x in JSONRoute]       #    copy JSONRoute
                
                # keep a reference of all extra properties passed to the job
                extraPropertyDict = {}
                for key, value in entity.items():
                  if key not in ('_class', 'id'):
                    extraPropertyDict[key] = value

                #Below it is to assign an order decomposition if it was not assigned in JSON
                #have to talk about it with NEX
                odAssigned=False
                for element in route:
                    elementIds = element.get('stationIdsList',[])
                    for obj in G.ObjList:
                        for elementId in elementIds:
                            if obj.id==elementId and obj.type=='OrderDecomposition':
                                odAssigned=True 
                if not odAssigned:
                    odId=None
                    for obj in G.ObjList:
                        if obj.type=='OrderDecomposition':
                            odId=obj.id
                            break
                    if odId:
#                         route.append([odId, 0])
                        route.append({'stationIdsList':[odId],\
                                      'processingTime':\
                                            {'distributionType':'Fixed',\
                                             'mean':'0'}})
                # XXX dirty way to implement new approach were the order is abstract and does not run through the system 
                # but the OrderDesign does
                # XXX initiate the Order and the OrderDesign
                O=Order('G'+id, 'general '+name, route=[], priority=priority, dueDate=dueDate,orderDate=orderDate,
                        isCritical=isCritical, basicsEnded=basicsEnded, manager=manager, componentsList=componentsList,
                        componentsReadyForAssembly=componentsReadyForAssembly, extraPropertyDict=extraPropertyDict)
                # create the OrderDesign
                OD=OrderDesign(id, name, route, priority=priority, dueDate=dueDate,orderDate=orderDate,
                        isCritical=isCritical, order=O, extraPropertyDict=extraPropertyDict)
                # add the order to the OrderList
                G.OrderList.append(O)
                # add the OrderDesign to the DesignList and the OrderComponentList
                G.OrderComponentList.append(OD)
                G.DesignList.append(OD)
                G.WipList.append(OD)  
                G.EntityList.append(OD)
                G.JobList.append(OD)