from DEVS import *
from infinity import INFINITY

class Operator(AtomicDEVS):
        def __init__(self, name="Operator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"op_out": self.addOutPort("op_out"), "op_in": self.addInPort("op_in")}
        def initialState(self):
                return {'name': 'waiting', 'req_queue': [], 'query_queue': [], 'requester': None}
        def timeAdvance(self):
                if self.state['query_queue']:
                        return 0
                elif self.state['name'] == 'waiting':
                        return INFINITY
                elif self.state['name'] == 'requested':
                        return 0
                elif self.state['name'] == 'allocating':
                        return 0
                elif self.state['name'] == 'allocated':
                        return INFINITY
        def outputFnc(self):
                output = {}
                if self.state['query_queue']:
                        output[self.my_ports['op_out']] = []
                        for it in self.state['query_queue']:
                                output[self.my_ports['op_out']].append({'type': 'response', 'req_name': it, 'op_name': id(self), 'free': self.state['name'] == 'waiting'})
                if self.state['name'] == 'allocating':
                        if self.my_ports['op_out'] in output:
                                output[self.my_ports['op_out']].append({'type': 'allocate', 'req_name': self.state['requester'], 'op_name': id(self)})
                        else:
                                output[self.my_ports['op_out']] = [({'type': 'allocate', 'req_name': self.state['requester'], 'op_name': id(self)})]
                return output
        def intTransition(self):
                if self.state['name'] == 'requested':
                        self.state['name'] = 'allocating'
                        self.state['requester'] = self.state['req_queue'].pop()
                elif self.state['name'] == 'allocating':
                        self.state['name'] = 'allocated'
                if self.state['query_queue']:
                        self.state['query_queue'] = []
                return self.state
        def extTransition(self, my_inputs):
                msgs = my_inputs[self.my_ports['op_in']]
                release_msgs = [it for it in msgs if it['type'] == 'release' and it['op_name'] == id(self)]
                req_msgs = [it for it in msgs if it['type'] == 'request' and it['op_name'] == id(self)]
                query_msgs = [it for it in msgs if it['type'] == 'query']

                if release_msgs:
                        self.state['name'] = 'requested' if self.state['req_queue'] else 'waiting'
                for r_m in req_msgs:
                        self.state['req_queue'].append(r_m['req_name'])
                        self.state['name'] = 'requested'
                for q_m in query_msgs:
                        self.state['query_queue'].append(q_m['req_name'])
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class ConveyorBelt(AtomicDEVS):
        def __init__(self, name="ConveyorBelt"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"conv_out": self.addOutPort("conv_out"), "conv_in": self.addInPort("conv_in")}
        def initialState(self):
                return {'name': 'waiting', 'product': None}
        def timeAdvance(self):
                if self.state['name'] == 'waiting':
                        return INFINITY
                elif self.state['name'] == 'transporting':
                        return 1
        def outputFnc(self):
                return {self.my_ports['conv_out']: [self.state['product']]}
        def intTransition(self):
                if self.state['name'] == 'transporting':
                        self.state['name'] == 'waiting'
                return self.state
        def extTransition(self, my_inputs):
                if self.state['name'] == 'waiting':
                        self.state['product'] = my_inputs[self.my_ports['conv_in']][0]
                        self.state['name'] = 'transporting'
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class WheelsGenerator(AtomicDEVS):
        def __init__(self, name="WheelsGenerator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"g_out": self.addOutPort("g_out")}
        def initialState(self):
                return {'name': 'generating'}
        def timeAdvance(self):
                if self.state['name'] == 'generating':
                        return 1
        def outputFnc(self):
                if self.state['name'] == 'generating':
                        return {self.my_ports['g_out']: [{'type': 'Wheels', 'broken': False}]}
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                return AtomicDEVS.extTransition(self, my_inputs)
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class TracksGenerator(AtomicDEVS):
        def __init__(self, name="TracksGenerator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"g_out": self.addOutPort("g_out")}
        def initialState(self):
                return {'name': 'generating'}
        def timeAdvance(self):
                if self.state['name'] == 'generating':
                        return 1
        def outputFnc(self):
                if self.state['name'] == 'generating':
                        return {self.my_ports['g_out']: [{'type': 'Tracks', 'broken': False}]}
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                return AtomicDEVS.extTransition(self, my_inputs)
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class BodyGenerator(AtomicDEVS):
        def __init__(self, name="BodyGenerator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"g_out": self.addOutPort("g_out")}
        def initialState(self):
                return {'name': 'generating'}
        def timeAdvance(self):
                if self.state['name'] == 'generating':
                        return 1
        def outputFnc(self):
                if self.state['name'] == 'generating':
                        return {self.my_ports['g_out']: [{'type': 'Body', 'broken': False}]}
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                return AtomicDEVS.extTransition(self, my_inputs)
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class MachineGunGenerator(AtomicDEVS):
        def __init__(self, name="MachineGunGenerator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"g_out": self.addOutPort("g_out")}
        def initialState(self):
                return {'name': 'generating'}
        def timeAdvance(self):
                if self.state['name'] == 'generating':
                        return 1
        def outputFnc(self):
                if self.state['name'] == 'generating':
                        return {self.my_ports['g_out']: [{'type': 'MachineGun', 'broken': False}]}
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                return AtomicDEVS.extTransition(self, my_inputs)
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class WaterCannonGenerator(AtomicDEVS):
        def __init__(self, name="WaterCannonGenerator"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"g_out": self.addOutPort("g_out")}
        def initialState(self):
                return {'name': 'generating'}
        def timeAdvance(self):
                if self.state['name'] == 'generating':
                        return 1
        def outputFnc(self):
                if self.state['name'] == 'generating':
                        return {self.my_ports['g_out']: [{'type': 'WaterCannon', 'broken': False}]}
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                return AtomicDEVS.extTransition(self, my_inputs)
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class collector(AtomicDEVS):
        def __init__(self, name="collector"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"c_in": self.addInPort("c_in")}
        def initialState(self):
                return {'name': 'collecting', 'WarAPCs': 0, 'RiotAPCS': 0}
        def timeAdvance(self):
                if self.state['name'] == 'collecting':
                        return INFINITY
        def outputFnc(self):
                return AtomicDEVS.outputFnc(self)
        def intTransition(self):
                return AtomicDEVS.intTransition(self)
        def extTransition(self, my_inputs):
                if (my_inputs[self.my_ports['c_in']][0]['type'] == 'WarAPC'):
                        self.state['WarAPCs'] += 1
                elif (my_inputs[self.my_ports['c_in']][0]['type'] == 'RiotAPC'):
                        self.state['RiotAPCs'] += 1
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class assembler(AtomicDEVS):
        def __init__(self, name="assembler"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"ass_op_out": self.addOutPort("ass_op_out"), "ass_out": self.addOutPort("ass_out"), "ass_op_in": self.addInPort("ass_op_in"), "ass_in": self.addInPort("ass_in")}
        def initialState(self):
                return {'name': 'waiting', 'queue': [], 'finishedProduct': None, 'op_name': None, 'op_to_send': None}
        def timeAdvance(self):
                if self.state['name'] == 'waiting':
                        return INFINITY
                elif self.state['name'] == 'looking_for_op':
                        return 0
                elif self.state['name'] == 'sending_req_to_op':
                        return 0
                elif self.state['name'] == 'waiting_for_op':
                        return INFINITY
                elif self.state['name'] == 'producing':
                        return self.wait_time
        def outputFnc(self):
                if self.state['name'] == 'producing':
                        return {self.my_ports['ass_out']: [self.state['finishedProduct']], self.my_ports['ass_op_out']: [{'type': 'release', 'op_name': self.state['op_name']}]}
                elif self.state['name'] == 'looking_for_op':
                        return {self.my_ports['ass_op_out']: [{'type': 'query', 'req_name': id(self)}]}
                elif self.state['name'] == 'sending_req_to_op':
                        return {self.my_ports['ass_op_out']: [{'type': 'request', 'req_name': id(self), 'op_name': self.state['op_to_send']}]}
                else:
                        return AtomicDEVS.outputFnc(self)
        def intTransition(self):
                if self.state['name'] == 'producing':
                        self.state['name'] = 'waiting'
                elif self.state['name'] == 'sending_req_to_op':
                        self.state['name'] = 'waiting_for_op'
                return self.state
        def extTransition(self, my_inputs):
                if self.state['name'] == 'producing':
                        self.wait_time -= self.elapsed

                import helpers, random
                if self.my_ports['ass_in'] in my_inputs:
                        self.state['queue'].extend(my_inputs[self.my_ports['ass_in']])
                        if (self.state['name'] == 'waiting' and (helpers.canWarAPC(self.state['queue']) or helpers.canRiotAPC(self.state['queue']))):
                                self.state['name'] = 'looking_for_op'
                if self.state['name'] == 'looking_for_op' and self.my_ports['ass_op_in'] in my_inputs:
                        msgs = my_inputs[self.my_ports['ass_op_in']]
                        free = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and msg['free']]
                        notfree = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and not msg['free']]
                        if free:
                                self.state['op_to_send'] = free[0]
                        else:
                                self.state['op_to_send'] = notfree[0]
                        self.state['name'] = 'sending_req_to_op'
                elif self.state['name'] == 'waiting_for_op' and self.my_ports['ass_op_in'] in my_inputs:
                        forme = [msg for msg in my_inputs[self.my_ports['ass_op_in']] if msg['req_name'] == id(self) and msg['type'] == 'allocate']
                        if forme:
                                self.state['op_name'] = my_inputs[self.my_ports['ass_op_in']][0]['op_name']
                                if helpers.isWarAPC(self.state['queue']):
                                        self.state['finishedProduct'] = {'type': 'WarAPC', 'broken': (random.random() < 0.05)}
                                elif helpers.isRiotAPC(self.state['queue']):
                                        self.state['finishedProduct'] = {'type': 'RiotAPC', 'broken': (random.random() < 0.05)}
                                self.state['name'] = 'producing'
                                self.wait_time = 2
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class repair(AtomicDEVS):
        def __init__(self, name="repair"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"rep_op_out": self.addOutPort("rep_op_out"), "rep_out": self.addOutPort("rep_out"), "rep_op_in": self.addInPort("rep_op_in"), "rep_in": self.addInPort("rep_in")}
        def initialState(self):
                return {'name': 'waiting', 'item': None, 'op_to_send': None, 'op_name': None}
        def timeAdvance(self):
                if self.state['name'] == 'waiting':
                        return INFINITY
                elif self.state['name'] == 'looking_for_op':
                        return 0
                elif self.state['name'] == 'sending_req_to_op':
                        return 0
                elif self.state['name'] == 'waiting_for_op':
                        return INFINITY
                elif self.state['name'] == 'repairing':
                        return self.wait_time
        def outputFnc(self):
                if self.state['name'] == 'repairing':
                        return {self.my_ports['rep_out']: [self.state['item']], self.my_ports['rep_op_out']: [{'type': 'release', 'op_name': self.state['op_name']}]}
                elif self.state['name'] == 'looking_for_op':
                        return {self.my_ports['rep_op_out']: [{'type': 'query', 'req_name': id(self)}]}
                elif self.state['name'] == 'sending_req_to_op':
                        return {self.my_ports['rep_op_out']: [{'type': 'request', 'req_name': id(self), 'op_name': self.state['op_to_send']}]}
                else:
                        return AtomicDEVS.outputFnc(self)
        def intTransition(self):
                if self.state['name'] == 'repairing':
                        self.state['name'] = 'waiting'
                elif self.state['name'] == 'sending_req_to_op':
                        self.state['name'] = 'waiting_for_op'
                return self.state
        def extTransition(self, my_inputs):
                if self.state['name'] == 'repairing':
                        self.wait_time -= self.elapsed

                if self.state['name'] == 'waiting' and self.my_ports['rep_in'] in my_inputs:
                        self.state['item'] = my_inputs[self.my_ports['rep_in']][0]
                        self.state['name'] = 'looking_for_op'
                elif self.state['name'] == 'looking_for_op' and self.my_ports['rep_op_in'] in my_inputs:
                        msgs = my_inputs[self.my_ports['rep_op_in']]
                        free = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and msg['free']]
                        notfree = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and not msg['free']]
                        if free:
                                self.state['op_to_send'] = free[0]
                        else:
                                self.state['op_to_send'] = notfree[0]
                        self.state['name'] = 'sending_req_to_op'
                elif self.state['name'] == 'waiting_for_op' and self.my_ports['rep_op_in'] in my_inputs:
                        forme = [msg for msg in my_inputs[self.my_ports['rep_op_in']] if msg['req_name'] == id(self) and msg['type'] == 'allocate']
                        if forme:
                                self.state['op_name'] = my_inputs[self.my_ports['rep_op_in']][0]['op_name']
                                self.state['item']['broken'] = False
                                self.state['name'] = 'repairing'
                                self.wait_time = 2
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class qualitycontrol(AtomicDEVS):
        def __init__(self, name="qualitycontrol"):
                AtomicDEVS.__init__(self, name)
                self.state = self.initialState()
                self.my_ports = {"qc_op_out": self.addOutPort("qc_op_out"), "qc_out_working": self.addOutPort("qc_out_working"), "qc_out_broken": self.addOutPort("qc_out_broken"), "qc_op_in": self.addInPort("qc_op_in"), "qc_in": self.addInPort("qc_in")}
        def initialState(self):
                return {'name': 'waiting', 'item': None}
        def timeAdvance(self):
                if self.state['name'] == 'waiting':
                        return INFINITY
                elif self.state['name'] == 'looking_for_op':
                        return 0
                elif self.state['name'] == 'sending_req_to_op':
                        return 0
                elif self.state['name'] == 'waiting_for_op_query_answer':
                        return INFINITY
                elif self.state['name'] == 'waiting_for_op':
                        return INFINITY
                elif self.state['name'] == 'checking':
                        return self.wait_time
        def outputFnc(self):
                if self.state['name'] == 'checking':
                        if self.state['item']['broken']:
                                return {self.my_ports['qc_out_broken']: [self.state['item']], self.my_ports['qc_op_out']: [{'type': 'release', 'op_name': self.state['op_name']}]}
                        else:
                                return {self.my_ports['qc_out_working']: [self.state['item']], self.my_ports['qc_op_out']: [{'type': 'release', 'op_name': self.state['op_name']}]}
                elif self.state['name'] == 'looking_for_op':
                        return {self.my_ports['qc_op_out']: [{'type': 'query', 'req_name': id(self)}]}
                elif self.state['name'] == 'sending_req_to_op':
                        return {self.my_ports['qc_op_out']: [{'type': 'request', 'req_name': id(self), 'op_name': self.state['op_to_send']}]}
                else:
                        return AtomicDEVS.outputFnc(self)
        def intTransition(self):
                if self.state['name'] == 'checking':
                        self.state['name'] = 'waiting'
                elif self.state['name'] == 'looking_for_op':
                        self.state['name'] = 'waiting_for_op_query_answer'
                elif self.state['name'] == 'sending_req_to_op':
                        self.state['name'] = 'waiting_for_op'
                return self.state
        def extTransition(self, my_inputs):
                if self.state['name'] == 'repairing':
                        self.wait_time -= self.elapsed

                if self.state['name'] == 'waiting' and self.my_ports['qc_in'] in my_inputs:
                        self.state['item'] = my_inputs[self.my_ports['qc_in']][0]
                        self.state['name'] = 'looking_for_op'
                elif self.state['name'] == 'waiting_for_op_query_answer' and self.my_ports['qc_op_in'] in my_inputs:
                        msgs = my_inputs[self.my_ports['qc_op_in']]
                        free = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and msg['free']]
                        notfree = [msg['op_name'] for msg in msgs if msg['req_name'] == id(self) and msg['type'] == 'response' and not msg['free']]
                        if free:
                                self.state['op_to_send'] = free[0]
                        else:
                                self.state['op_to_send'] = notfree[0]
                        self.state['name'] = 'sending_req_to_op'
                elif self.state['name'] == 'waiting_for_op' and self.my_ports['qc_op_in'] in my_inputs:
                        forme = [msg for msg in my_inputs[self.my_ports['qc_op_in']] if msg['req_name'] == id(self) and msg['type'] == 'allocate']
                        if forme:
                                self.state['name'] = 'checking'
                return self.state
        def confTransition(self, my_inputs):
                return AtomicDEVS.confTransition(self, my_inputs)
class Root(CoupledDEVS):
        def __init__(self, name="Root"):
                CoupledDEVS.__init__(self, name)
                self.my_ports = {}
                self.submodels = {"WheelsGenerator_i": self.addSubModel(WheelsGenerator(name="WheelsGenerator_i")), "TracksGenerator_i": self.addSubModel(TracksGenerator(name="TracksGenerator_i")), "BodyGenerator_i": self.addSubModel(BodyGenerator(name="BodyGenerator_i")), "MachineGunGenerator_i": self.addSubModel(MachineGunGenerator(name="MachineGunGenerator_i")), "WaterCannonGenerator_i": self.addSubModel(WaterCannonGenerator(name="WaterCannonGenerator_i")), "collector_i": self.addSubModel(collector(name="collector_i")), "assembler_i": self.addSubModel(assembler(name="assembler_i")), "repair_i": self.addSubModel(repair(name="repair_i")), "qualitycontrol_i": self.addSubModel(qualitycontrol(name="qualitycontrol_i")), "op1_i": self.addSubModel(Operator(name="op1_i")), "op2_i": self.addSubModel(Operator(name="op2_i")), "w_g_to_assembler_i1": self.addSubModel(ConveyorBelt(name="w_g_to_assembler_i1")), "t_g_to_assembler_i1": self.addSubModel(ConveyorBelt(name="t_g_to_assembler_i1")), "b_g_to_assembler_i1": self.addSubModel(ConveyorBelt(name="b_g_to_assembler_i1")), "mg_g_to_assembler_i1": self.addSubModel(ConveyorBelt(name="mg_g_to_assembler_i1")), "wc_g_to_assembler_i1": self.addSubModel(ConveyorBelt(name="wc_g_to_assembler_i1")), "assembler_to_qualitycontrol_i1": self.addSubModel(ConveyorBelt(name="assembler_to_qualitycontrol_i1")), "qualitycontrol_broken_to_repair_i1": self.addSubModel(ConveyorBelt(name="qualitycontrol_broken_to_repair_i1")), "qualitycontrol_to_collector_i1": self.addSubModel(ConveyorBelt(name="qualitycontrol_to_collector_i1")), "repair_to_collector_i1": self.addSubModel(ConveyorBelt(name="repair_to_collector_i1")), "w_g_to_assembler_i2": self.addSubModel(ConveyorBelt(name="w_g_to_assembler_i2")), "t_g_to_assembler_i2": self.addSubModel(ConveyorBelt(name="t_g_to_assembler_i2")), "b_g_to_assembler_i2": self.addSubModel(ConveyorBelt(name="b_g_to_assembler_i2")), "mg_g_to_assembler_i2": self.addSubModel(ConveyorBelt(name="mg_g_to_assembler_i2")), "wc_g_to_assembler_i2": self.addSubModel(ConveyorBelt(name="wc_g_to_assembler_i2")), "assembler_to_qualitycontrol_i2": self.addSubModel(ConveyorBelt(name="assembler_to_qualitycontrol_i2")), "qualitycontrol_broken_to_repair_i2": self.addSubModel(ConveyorBelt(name="qualitycontrol_broken_to_repair_i2")), "qualitycontrol_to_collector_i2": self.addSubModel(ConveyorBelt(name="qualitycontrol_to_collector_i2")), "repair_to_collector_i2": self.addSubModel(ConveyorBelt(name="repair_to_collector_i2"))}
                self.connectPorts(self.submodels["WheelsGenerator_i"].my_ports["g_out"], self.submodels["w_g_to_assembler_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["TracksGenerator_i"].my_ports["g_out"], self.submodels["t_g_to_assembler_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["BodyGenerator_i"].my_ports["g_out"], self.submodels["b_g_to_assembler_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["MachineGunGenerator_i"].my_ports["g_out"], self.submodels["mg_g_to_assembler_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["WaterCannonGenerator_i"].my_ports["g_out"], self.submodels["wc_g_to_assembler_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["assembler_i"].my_ports["ass_op_out"], self.submodels["op1_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["assembler_i"].my_ports["ass_op_out"], self.submodels["op2_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["assembler_i"].my_ports["ass_out"], self.submodels["assembler_to_qualitycontrol_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["repair_i"].my_ports["rep_op_out"], self.submodels["op1_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["repair_i"].my_ports["rep_op_out"], self.submodels["op2_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["repair_i"].my_ports["rep_out"], self.submodels["repair_to_collector_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["qualitycontrol_i"].my_ports["qc_op_out"], self.submodels["op1_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["qualitycontrol_i"].my_ports["qc_op_out"], self.submodels["op2_i"].my_ports["op_in"])
                self.connectPorts(self.submodels["qualitycontrol_i"].my_ports["qc_out_working"], self.submodels["qualitycontrol_to_collector_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["qualitycontrol_i"].my_ports["qc_out_broken"], self.submodels["qualitycontrol_broken_to_repair_i1"].my_ports["conv_in"])
                self.connectPorts(self.submodels["op1_i"].my_ports["op_out"], self.submodels["assembler_i"].my_ports["ass_op_in"])
                self.connectPorts(self.submodels["op1_i"].my_ports["op_out"], self.submodels["qualitycontrol_i"].my_ports["qc_op_in"])
                self.connectPorts(self.submodels["op1_i"].my_ports["op_out"], self.submodels["repair_i"].my_ports["rep_op_in"])
                self.connectPorts(self.submodels["op2_i"].my_ports["op_out"], self.submodels["assembler_i"].my_ports["ass_op_in"])
                self.connectPorts(self.submodels["op2_i"].my_ports["op_out"], self.submodels["qualitycontrol_i"].my_ports["qc_op_in"])
                self.connectPorts(self.submodels["op2_i"].my_ports["op_out"], self.submodels["repair_i"].my_ports["rep_op_in"])
                self.connectPorts(self.submodels["w_g_to_assembler_i1"].my_ports["conv_out"], self.submodels["w_g_to_assembler_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["t_g_to_assembler_i1"].my_ports["conv_out"], self.submodels["t_g_to_assembler_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["b_g_to_assembler_i1"].my_ports["conv_out"], self.submodels["b_g_to_assembler_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["mg_g_to_assembler_i1"].my_ports["conv_out"], self.submodels["mg_g_to_assembler_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["wc_g_to_assembler_i1"].my_ports["conv_out"], self.submodels["wc_g_to_assembler_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["assembler_to_qualitycontrol_i1"].my_ports["conv_out"], self.submodels["assembler_to_qualitycontrol_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["qualitycontrol_broken_to_repair_i1"].my_ports["conv_out"], self.submodels["qualitycontrol_broken_to_repair_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["qualitycontrol_to_collector_i1"].my_ports["conv_out"], self.submodels["qualitycontrol_to_collector_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["repair_to_collector_i1"].my_ports["conv_out"], self.submodels["repair_to_collector_i2"].my_ports["conv_in"])
                self.connectPorts(self.submodels["w_g_to_assembler_i2"].my_ports["conv_out"], self.submodels["assembler_i"].my_ports["ass_in"])
                self.connectPorts(self.submodels["t_g_to_assembler_i2"].my_ports["conv_out"], self.submodels["assembler_i"].my_ports["ass_in"])
                self.connectPorts(self.submodels["b_g_to_assembler_i2"].my_ports["conv_out"], self.submodels["assembler_i"].my_ports["ass_in"])
                self.connectPorts(self.submodels["mg_g_to_assembler_i2"].my_ports["conv_out"], self.submodels["assembler_i"].my_ports["ass_in"])
                self.connectPorts(self.submodels["wc_g_to_assembler_i2"].my_ports["conv_out"], self.submodels["assembler_i"].my_ports["ass_in"])
                self.connectPorts(self.submodels["assembler_to_qualitycontrol_i2"].my_ports["conv_out"], self.submodels["qualitycontrol_i"].my_ports["qc_in"])
                self.connectPorts(self.submodels["qualitycontrol_broken_to_repair_i2"].my_ports["conv_out"], self.submodels["repair_i"].my_ports["rep_in"])
                self.connectPorts(self.submodels["qualitycontrol_to_collector_i2"].my_ports["conv_out"], self.submodels["collector_i"].my_ports["c_in"])
                self.connectPorts(self.submodels["repair_to_collector_i2"].my_ports["conv_out"], self.submodels["collector_i"].my_ports["c_in"])
