def initialize(self): Queue.initialize(self) # if the station shares resources and the capacity is not defined in this # then read it from some other of the sharing stations if not self.intervalCapacity and self.sharedResources: for stationId in self.sharedResources.get('stationIds', []): import dream.simulation.Globals as Globals station = Globals.findObjectById(stationId) if station.intervalCapacity: self.intervalCapacity = station.intervalCapacity break # initialize variables self.remainingIntervalCapacity = list(self.intervalCapacity) for i in range(self.intervalCapacityStart): self.remainingIntervalCapacity.pop(0) self.isLocked = True self.utilisationDict = [ ] # a list of dicts for the utilization results self.detailedWorkPlan = [] # a list of dicts to keep detailed data from dream.simulation.Globals import G if hasattr(G, 'CapacityStationList'): G.CapacityStationList.append(self) else: G.CapacityStationList = [] G.CapacityStationList.append(self)
def initialize(self): Queue.initialize(self) import dream.simulation.Globals as Globals # identify the notRequiredOperations # input gives only stationId, buffer and exit should be identified notRequiredOperations=[] for id in self.notRequiredOperations: station=Globals.findObjectById(id) notRequiredOperations.append(station.id) bufferId=station.previous[0].id notRequiredOperations.append(bufferId) exitId=station.next[0].id notRequiredOperations.append(exitId) self.notRequiredOperations=notRequiredOperations self.isLocked=True
def initialize(self): Queue.initialize(self) import dream.simulation.Globals as Globals # identify the notRequiredOperations # input gives only stationId, buffer and exit should be identified notRequiredOperations = [] for id in self.notRequiredOperations: station = Globals.findObjectById(id) notRequiredOperations.append(station.id) bufferId = station.previous[0].id notRequiredOperations.append(bufferId) exitId = station.next[0].id notRequiredOperations.append(exitId) self.notRequiredOperations = notRequiredOperations self.isLocked = True
def initialize(self): Queue.initialize(self) # if the station shares resources and the capacity is not defined in this # then read it from some other of the sharing stations if not self.intervalCapacity and self.sharedResources: for stationId in self.sharedResources.get('stationIds',[]): import dream.simulation.Globals as Globals station=Globals.findObjectById(stationId) if station.intervalCapacity: self.intervalCapacity=station.intervalCapacity break # initialize variables self.remainingIntervalCapacity=list(self.intervalCapacity) for i in range(self.intervalCapacityStart): self.remainingIntervalCapacity.pop(0) self.isLocked=True self.utilisationDict=[] # a list of dicts for the utilization results self.detailedWorkPlan=[] # a list of dicts to keep detailed data from dream.simulation.Globals import G if hasattr(G, 'CapacityStationList'): G.CapacityStationList.append(self) else: G.CapacityStationList=[] G.CapacityStationList.append(self)
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)
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)
def calculateWhatIsToBeProcessed(self): import dream.simulation.Globals as Globals # calculate what space is available availableSpace = self.assemblySpace - self.calculateConsumedSpace() assert availableSpace >= 0, 'negative available space' # list to hold the buffers that are already considered (due to shared resources) alreadyConsideredBuffers = [] # loop through the capacity station buffers for buffer in G.CapacityStationBufferList: # if the buffer was considered before (due to shared resources) continue if buffer in alreadyConsideredBuffers: continue alreadyConsideredBuffers.append(buffer) sharedBuffers = [] station = buffer.next[0] # get the station # find the stations that share resources with the one considered now if station.sharedResources: sharedStations = station.sharedResources.get('stationIds', []) for element in sharedStations: s = Globals.findObjectById(element) b = s.previous[0] sharedBuffers.append(b) activeObjectQueue = buffer.getActiveObjectQueue() # the entities considered should be the entities in the current buffer plus the ones in buffers # of stations that share resources with the current one entitiesConsidered = list(activeObjectQueue) for b in sharedBuffers: entitiesConsidered += b.getActiveObjectQueue() alreadyConsideredBuffers.append(b) # sort entities according to due date of the project that each belongs to entitiesConsidered.sort(key=lambda x: x.capacityProject.dueDate) totalAvailableCapacity = station.remainingIntervalCapacity[ 0] # get the available capacity of the station # for this interval # list to keep entities that have not been already allocated entitiesNotAllocated = list(entitiesConsidered) allCapacityConsumed = False # if there is no available capacity no need to do anything if totalAvailableCapacity == 0: continue while not allCapacityConsumed: # list to keep entities that are within a threshold from the EDD entitiesWithinThreshold = [] # list to keep entities that are outside a threshold from the EDD entitiesOutsideThreshold = [] # get the EDD EDD = float('inf') for entity in entitiesNotAllocated: entityBuffer = entity.currentStation entityStation = entity.currentStation.next[0] # consider only projects that can get into station if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): if EDD > entity.capacityProject.dueDate: EDD = entity.capacityProject.dueDate # put the entities in the corresponding list according to their due date for entity in entitiesNotAllocated: if entity.capacityProject.dueDate - EDD <= self.dueDateThreshold: entitiesWithinThreshold.append(entity) else: entitiesOutsideThreshold.append(entity) # calculate the total capacity that is requested totalRequestedCapacity = 0 # do not to count projects that cannot move due to space limitations # so check according to considered capacity consideredSpace = float(availableSpace) for entity in entitiesWithinThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer = entity.currentStation entityStation = entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, consideredSpace): consideredSpace -= entity.capacityProject.assemblySpaceRequirement totalRequestedCapacity += entity.requiredCapacity # if there is enough capacity for all the entities set them that they all should move if totalRequestedCapacity <= totalAvailableCapacity: for entity in entitiesWithinThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer = entity.currentStation entityStation = entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): entity.shouldMove = True # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace -= entity.capacityProject.assemblySpaceRequirement assert availableSpace >= 0, 'negative available space' # remove the entity from the none allocated ones entitiesNotAllocated.remove(entity) # check if all the capacity is consumed to update the flag and break the loop if totalRequestedCapacity == totalAvailableCapacity: # the capacity will be 0 since we consumed it all totalAvailableCapacity = 0 allCapacityConsumed = True # if we still have available capacity else: # check in the entities outside the threshold if there is one or more that can be moved haveMoreEntitiesToAllocate = False for entity in entitiesOutsideThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer = entity.currentStation entityStation = entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): haveMoreEntitiesToAllocate = True break # otherwise we have to calculate the capacity for next loop # the remaining capacity will be decreased by the one that was originally requested totalAvailableCapacity -= totalRequestedCapacity # if we have more entities break if not haveMoreEntitiesToAllocate: break if station.notProcessOutsideThreshold: break # else calculate the capacity for every entity and create the entities else: allCapacityConsumed = True entitiesToBeBroken = list(entitiesWithinThreshold) # we sort the entities so the ones that can finish in current period (if any) go in front entitiesToBeBroken.sort(key=lambda \ x: self.checkIfAProjectCanBeFinishedInStation(x,x.currentStation.next[0], totalAvailableCapacity) \ and self.prioritizeIfCanFinish, reverse=True) # loop through the entities for entity in entitiesToBeBroken: # get buffer where the entity is and the station it requests to get in entityBuffer = entity.currentStation entityStation = entity.currentStation.next[0] # consider only entities that can move - not those waiting for assembly or earliest start if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer)) and\ self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): # if we prioritize an entity that can completely finish then check for this if self.checkIfAProjectCanBeFinishedInStation(entity, entityStation, totalAvailableCapacity)\ and self.prioritizeIfCanFinish: # set that the entity can move entity.shouldMove = True # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace -= entity.capacityProject.assemblySpaceRequirement assert availableSpace >= 0, 'negative available space' # update the values totalAvailableCapacity -= entity.requiredCapacity totalRequestedCapacity -= entity.requiredCapacity # else break the entity according to rule else: if self.breakEntity(entity, entityBuffer, entityStation, totalAvailableCapacity, totalRequestedCapacity): # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace -= entity.capacityProject.assemblySpaceRequirement assert availableSpace >= 0, 'negative available space'
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)
def calculateWhatIsToBeProcessed(self): import dream.simulation.Globals as Globals # calculate what space is available availableSpace=self.assemblySpace-self.calculateConsumedSpace() assert availableSpace>=0, 'negative available space' # list to hold the buffers that are already considered (due to shared resources) alreadyConsideredBuffers = [] # loop through the capacity station buffers for buffer in G.CapacityStationBufferList: pr = False # if the buffer was considered before (due to shared resources) continue if buffer in alreadyConsideredBuffers: continue alreadyConsideredBuffers.append(buffer) sharedBuffers = [] station=buffer.next[0] # get the station # find the stations that share resources with the one considered now if station.sharedResources: sharedStations = station.sharedResources.get('stationIds',[]) for element in sharedStations: s = Globals.findObjectById(element) b = s.previous[0] sharedBuffers.append(b) activeObjectQueue=buffer.getActiveObjectQueue() # the entities considered should be the entities in the current buffer plus the ones in buffers # of stations that share resources with the current one entitiesConsidered=list(activeObjectQueue) for b in sharedBuffers: entitiesConsidered+=b.getActiveObjectQueue() alreadyConsideredBuffers.append(b) # sort entities according to due date of the project that each belongs to entitiesConsidered.sort(key=lambda x: x.capacityProject.dueDate) totalAvailableCapacity=station.remainingIntervalCapacity[0] # get the available capacity of the station # for this interval # list to keep entities that have not been already allocated entitiesNotAllocated=list(entitiesConsidered) allCapacityConsumed=False # if there is no available capacity no need to do anything if totalAvailableCapacity==0: continue while not allCapacityConsumed: # list to keep entities that are within a threshold from the EDD entitiesWithinThreshold=[] # list to keep entities that are outside a threshold from the EDD entitiesOutsideThreshold=[] # get the EDD EDD=float('inf') for entity in entitiesNotAllocated: entityBuffer=entity.currentStation entityStation=entity.currentStation.next[0] # consider only projects that can get into station if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): if EDD>entity.capacityProject.dueDate: EDD=entity.capacityProject.dueDate # put the entities in the corresponding list according to their due date for entity in entitiesNotAllocated: if entity.capacityProject.dueDate-EDD<=self.dueDateThreshold: entitiesWithinThreshold.append(entity) else: entitiesOutsideThreshold.append(entity) # calculate the total capacity that is requested totalRequestedCapacity=0 # do not to count projects that cannot move due to space limitations # so check according to considered capacity consideredSpace=float(availableSpace) for entity in entitiesWithinThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer=entity.currentStation entityStation=entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, consideredSpace): if not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer): consideredSpace-=entity.capacityProject.assemblySpaceRequirement totalRequestedCapacity+=entity.requiredCapacity # if there is enough capacity for all the entities set them that they all should move if totalRequestedCapacity<=totalAvailableCapacity: availableCapacity=float(totalAvailableCapacity) for entity in entitiesWithinThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer=entity.currentStation entityStation=entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace) and\ entity.requiredCapacity<=availableCapacity: entity.shouldMove=True availableCapacity-=entity.requiredCapacity assert availableCapacity>=0, 'negative available capacity' # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace-=entity.capacityProject.assemblySpaceRequirement assert availableSpace>=0, 'negative available space' # remove the entity from the none allocated ones entitiesNotAllocated.remove(entity) # check if all the capacity is consumed to update the flag and break the loop if totalRequestedCapacity==totalAvailableCapacity: # the capacity will be 0 since we consumed it all totalAvailableCapacity=0 allCapacityConsumed=True # if we still have available capacity else: # check in the entities outside the threshold if there is one or more that can be moved haveMoreEntitiesToAllocate=False for entity in entitiesOutsideThreshold: # get buffer where the entity is and the station it requests to get in entityBuffer=entity.currentStation entityStation=entity.currentStation.next[0] if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer))\ and self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): haveMoreEntitiesToAllocate=True break # otherwise we have to calculate the capacity for next loop # the remaining capacity will be decreased by the one that was originally requested totalAvailableCapacity-=totalRequestedCapacity # if we have more entities break if not haveMoreEntitiesToAllocate: break if station.notProcessOutsideThreshold: break # else calculate the capacity for every entity and create the entities else: allCapacityConsumed=True entitiesToBeBroken=list(entitiesWithinThreshold) # we sort the entities so the ones that can finish in current period (if any) go in front entitiesToBeBroken.sort(key=lambda \ x: self.checkIfAProjectCanBeFinishedInStation(x,x.currentStation.next[0], totalAvailableCapacity) \ and self.prioritizeIfCanFinish, reverse=True) # loop through the entities for entity in entitiesToBeBroken: # get buffer where the entity is and the station it requests to get in entityBuffer=entity.currentStation entityStation=entity.currentStation.next[0] # consider only entities that can move - not those waiting for assembly or earliest start if self.checkIfProjectCanStartInStation(entity.capacityProject, entityStation) and\ (not self.checkIfProjectNeedsToBeAssembled(entity.capacityProject, entityBuffer)) and\ self.checkIfThereIsEnoughSpace(entity, entityBuffer, availableSpace): # if we prioritize an entity that can completely finish then check for this if self.checkIfAProjectCanBeFinishedInStation(entity, entityStation, totalAvailableCapacity)\ and self.prioritizeIfCanFinish: # set that the entity can move entity.shouldMove=True # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace-=entity.capacityProject.assemblySpaceRequirement assert availableSpace>=0, 'negative available space' # update the values totalAvailableCapacity-=entity.requiredCapacity totalRequestedCapacity-=entity.requiredCapacity # else break the entity according to rule else: if self.breakEntity(entity, entityBuffer, entityStation, totalAvailableCapacity, totalRequestedCapacity): # reduce the available space if there is need to if entityBuffer.requireFullProject and \ (not self.checkIfProjectConsumesAssemblySpace(entity, entityBuffer)): availableSpace-=entity.capacityProject.assemblySpaceRequirement assert availableSpace>=0, 'negative available space'