class StateMachineModel: def __init__(self, host, port, sim): self.initiate_adapter(host, port) self.adapter.start() self.sim = sim self.initiate_dataitems() self.initiate_interfaces() self.system = [] self.cycle_time = 10 self.load_time_limit(20) self.unload_time_limit(20) self.load_failed_time_limit(2) self.unload_failed_time_limit(2) self.next_sequence = str(1) self.events = [] self.master_tasks = {} self.device_uuid = "cnc1" self.master_uuid = str() self.is_coordinator = False self.is_collaborator = False self.system_normal = True self.has_material = False self.fail_next = False #long pull dict for maintaining agent threads for other devices self.lp = {} self.mock_value = None self.wait_for_completion = False self.initial_execution_state() self.set_priority() self.initiate_pull_thread() def set_priority(self): self.priority = None self.priority = priority(self, self.cnc_binding) def initial_execution_state(self): self.execution = {} self.execution['cnc1'] = None self.execution['conv1'] = None self.execution['r1'] = None def initiate_cnc_client(self): if self.sim == False: configFile = open('configFiles/clients.cfg', 'r') device = json.loads( configFile.read())['devices'][self.device_uuid] self.cnc_client = pocketNCAdapter(str(device['host']), int(device['port'])) elif self.sim == 'Mock': self.cnc_client = Mock() self.cnc_client._exec.value = MagicMock( side_effect=self.side_effect) def side_effect(self, val=None): if val is not None: self.mock_value = val return val else: return self.mock_value def initiate_interfaces(self): self.material_load_interface = MaterialLoad(self) self.material_unload_interface = MaterialUnload(self) def initiate_adapter(self, host, port): self.adapter = Adapter((host, port)) self.mode1 = Event('mode') self.adapter.add_data_item(self.mode1) self.e1 = Event('exec') self.adapter.add_data_item(self.e1) self.avail1 = Event('avail') self.adapter.add_data_item(self.avail1) self.binding_state_material = Event('binding_state_material') self.adapter.add_data_item(self.binding_state_material) self.cnc_binding = Event('cnc_binding') self.adapter.add_data_item(self.cnc_binding) self.tool_state = Event('tool_state') self.adapter.add_data_item(self.tool_state) self.chuck_state = Event('chuck_state') self.adapter.add_data_item(self.chuck_state) self.door_state = Event('door_state') self.adapter.add_data_item(self.door_state) self.door_lock_state = Event('door_lock_state') self.adapter.add_data_item(self.door_lock_state) self.material_load = Event('material_load') self.adapter.add_data_item(self.material_load) self.material_unload = Event('material_unload') self.adapter.add_data_item(self.material_unload) def initiate_dataitems(self): self.adapter.begin_gather() self.door_lock_state.set_value("UNLOCKED") self.door_state.set_value("CLOSED") self.chuck_state.set_value("OPEN") self.tool_state.set_value("AVAILABLE") self.avail1.set_value("AVAILABLE") self.e1.set_value("READY") self.mode1.set_value("AUTOMATIC") self.binding_state_material.set_value("INACTIVE") self.material_load.set_value("NOT_READY") self.material_unload.set_value("NOT_READY") self.adapter.complete_gather() def initiate_pull_thread(self): #Pull MTconnect data from other devices self.thread = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread.start() self.thread2 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread2.start() self.thread3 = Thread(target=self.initiate_cnc_client) self.thread3.start() def start_pull(self, addr, request, func, stream=True): response = requests.get(addr + request + "&from=" + self.next_sequence, stream=stream) self.lp[request.split('/')[1]] = None self.lp[request.split('/')[1]] = LongPull(response, addr, self) self.lp[request.split('/')[1]].long_pull(func) def start_pull_asset(self, addr, request, assetId, stream_root): response = urllib2.urlopen(addr + request).read() from_long_pull_asset(self, response, stream_root) def CNC_NOT_READY(self): self.material_load_interface.superstate.DEACTIVATE() self.material_unload_interface.superstate.DEACTIVATE() def ACTIVATE(self): if self.mode1.value() == "AUTOMATIC" and self.avail1.value( ) == "AVAILABLE": self.make_operational() elif self.system_normal: self.still_not_ready() else: self.faulted() def OPERATIONAL(self): if self.has_material: self.unloading() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str(uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.cnc_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.coordinator_task = "MoveMaterial_2" self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCnc" self.coordinator.superstate.unavailable() elif self.has_material == False: self.loading() self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadCnc" self.collaborator.superstate.unavailable() self.priority.collab_check() else: self.start() def IDLE(self): if self.has_material: self.material_unload_interface.superstate.IDLE() else: self.material_load_interface.superstate.IDLE() def CYCLING(self): if self.fail_next: self.system.append([ 'cnc', 'Device', 'SYSTEM', 'FAULT', 'Cycle failed to start', 'CYCLE' ]) self.cnc_fault() self.fail_next = False elif self.door_state.value() != "CLOSED" or self.chuck_state.value( ) != "CLOSED": self.system.append([ 'cnc', 'Device', 'SYSTEM', 'FAULT', 'Door or Chuck in invalid state', 'CYCLE' ]) self.cnc_fault() else: def func(self=self): if self.is_coordinator: return self.cnc_execution_ready() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str( uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.coordinator_task = "MoveMaterial_2" self.adapter.begin_gather() self.cnc_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCnc" self.coordinator.superstate.unavailable() self.adapter.begin_gather() self.e1.set_value("READY") self.adapter.complete_gather() if self.sim == True: self.adapter.begin_gather() self.e1.set_value("ACTIVE") self.adapter.complete_gather() if not self.cycle_time: return func() timer_cycling = Timer(self.cycle_time, func) timer_cycling.daemon = True timer_cycling.start() else: while self.cnc_client._exec.value() != 'ACTIVE': time.sleep(2) pass time.sleep(1) self.adapter.begin_gather() self.e1.set_value("ACTIVE") self.adapter.complete_gather() while self.cnc_client._exec.value() == 'ACTIVE': time.sleep(2) pass time.sleep(1) func() def LOADING(self): if not self.has_material: self.material_load_interface.superstate.idle() def UNLOADING(self): if self.has_material: self.material_unload_interface.superstate.idle() def load_time_limit(self, limit): self.material_load_interface.superstate.processing_time_limit = limit def load_failed_time_limit(self, limit): self.material_load_interface.superstate.fail_time_limit = limit def unload_time_limit(self, limit): self.material_unload_interface.superstate.processing_time_limit = limit def unload_failed_time_limit(self, limit): self.material_unload_interface.superstate.fail_time_limit = limit def interface_type(self, value=None, subtype=None): self.interfaceType = value def COMPLETED(self): if self.interfaceType == "Request": self.complete() elif "Response" in self.interfaceType: pass def EXITING_IDLE(self): if self.has_material: self.unloading() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str(uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.cnc_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.coordinator_task = "MoveMaterial_2" self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCnc" self.coordinator.superstate.unavailable() else: self.loading() self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name='cnc1') self.collaborator.superstate.task_name = "LoadCnc" self.collaborator.superstate.unavailable() self.priority.collab_check() def LOADED(self): self.has_material = True self.material_load_interface.superstate.DEACTIVATE() self.adapter.begin_gather() self.chuck_state.set_value("CLOSED") self.door_state.set_value("CLOSED") self.door_lock_state.set_value("LOCKED") self.adapter.complete_gather() if self.sim is not True: while self.cnc_client._exec.value() != 'ACTIVE': time.sleep(2) pass def IN_TRANSITION(self): pass def EXIT_TRANSITION(self): if self.has_material == False: self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadCnc" self.collaborator.superstate.unavailable() self.priority.collab_check() def UNLOADED(self): self.has_material = False self.material_unload_interface.superstate.DEACTIVATE() self.adapter.begin_gather() self.chuck_state.set_value("CLOSED") self.door_state.set_value("CLOSED") self.door_lock_state.set_value("LOCKED") self.adapter.complete_gather() def FAILED(self): if "Request" in self.interfaceType: self.failed() elif "Response" in self.interfaceType: self.fault() def void(self): pass def event(self, source, comp, name, value, code=None, text=None): self.events.append([source, comp, name, value, code, text]) action = value.lower() if action == "fail": action = "failure" if comp == "Coordinator" and value.lower() == 'preparing': self.priority.event_list( [source, comp, name, value, code, text]) if comp == "Task_Collaborator" and action != 'unavailable': self.coordinator.superstate.event(source, comp, name, value, code, text) elif comp == "Coordinator" and action != 'unavailable': if value.lower() == 'committed': self.collaborator.superstate.event(source, comp, name, value, code, text) if 'ToolChange' in str( self.master_tasks[self.master_uuid]): self.event('robot', 'ToolInterface', 'SubTask_ToolChange', 'ACTIVE', self.master_uuid, 'r1') elif value.lower() != 'preparing': self.collaborator.superstate.event(source, comp, name, value, code, text) elif 'SubTask' in name and action != 'unavailable': if self.is_coordinator == True: self.coordinator.superstate.event(source, comp, name, value, code, text) elif self.is_collaborator == True: self.collaborator.superstate.event(source, comp, name, value, code, text) elif "Open" in name and action != 'unavailable': if 'door' in name.lower(): eval('self.open_door_interface.superstate.' + action + '()') if not self.sim and action == 'active': openDoor_completion = self.cnc_client.load_run_pgm( tasks.openDoor) if openDoor_completion == True: time.sleep(2) eval( 'self.open_door_interface.superstate.complete()' ) elif openDoor_completion == False: time.sleep(2) eval( 'self.open_door_interface.superstate.DEFAULT()' ) if 'chuck' in name.lower(): eval('self.open_chuck_interface.superstate.' + action + '()') if not self.sim and action == 'active': openChuck_completion = self.cnc_client.load_run_pgm( tasks.openChuck) if openChuck_completion == True: time.sleep(2) eval( 'self.open_chuck_interface.superstate.complete()' ) elif openChuck_completion == False: time.sleep(2) eval( 'self.open_chuck_interface.superstate.DEFAULT()' ) elif "Close" in name and action != 'unavailable': if 'door' in name.lower(): eval('self.close_door_interface.superstate.' + action + '()') if not self.sim and action == 'active': closeDoor_completion = self.cnc_client.load_run_pgm( tasks.closeDoor) if closeDoor_completion == True: time.sleep(1) eval( 'self.close_door_interface.superstate.complete()' ) elif closeDoor_completion == False: time.sleep(1) eval( 'self.close_door_interface.superstate.DEFAULT()' ) if 'chuck' in name.lower(): eval('self.close_chuck_interface.superstate.' + action + '()') if not self.sim and action == 'active': closeChuck_completion = self.cnc_client.load_run_pgm( tasks.closeChuck) if closeChuck_completion == True: time.sleep(1) eval( 'self.close_chuck_interface.superstate.complete()' ) elif closeChuck_completion == False: time.sleep(1) eval( 'self.close_chuck_interface.superstate.DEFAULT()' ) elif name == "MaterialLoad" and action != 'unavailable': try: if action == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_load_ready()') eval('self.material_load_interface.superstate.' + action + '()') except Exception as e: print("Incorrect event") print(e) elif name == "MaterialUnload" and action != 'unavailable': try: if action == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_unload_ready()') eval('self.material_unload_interface.superstate.' + action + '()') except Exception as e: print("incorrect event") print(e) elif name == "ChangeTool" and action != 'unavailable': eval('self.change_tool_interface.superstate.' + action + '()') if not self.sim and action == 'active': toolChange_completion = self.cnc_client.load_run_pgm( tasks.toolChange) if toolChange_completion == True: time.sleep(2) eval( 'self.change_tool_interface.superstate.complete()') elif toolChange_completion == False: time.sleep(2) eval('self.change_tool_interface.superstate.DEFAULT()') elif comp == "Controller": if name == "ControllerMode": if source.lower() == 'cnc': self.adapter.begin_gather() self.mode1.set_value(value.upper()) self.adapter.complete_gather() elif name == "Execution": if source.lower() == 'cnc': self.adapter.begin_gather() self.e1.set_value(value.upper()) self.adapter.complete_gather() elif text in self.execution: self.execution[text] = value.lower() elif comp == "Device": if name == "SYSTEM" and action != 'unavailable': try: eval('self.' + source.lower() + '_system_' + value.lower() + '()') except Exception as e: print("Not a valid Device trigger", e) elif name == "Availability": if source.lower() == 'cnc': self.adapter.begin_gather() self.avail1.set_value(value.upper()) self.adapter.complete_gather()
class StateMachineModel: def __init__(self, host, port, sim, cell_part): self.initiate_adapter(host, port) self.adapter.start() self.sim = sim self.cell_part = cell_part self.initiate_dataitems() self.initiate_interfaces() self.system = [] self.cycle_time = 10 self.load_time_limit(20) self.unload_time_limit(20) self.next_sequence = str(1) self.load_failed_time_limit(2) self.unload_failed_time_limit(2) self.events = [] self.master_tasks = {} self.device_uuid = "cmm1" self.master_uuid = str() self.is_coordinator = False self.is_collaborator = False self.system_normal = True self.has_material = False self.fail_next = False self.part_quality = None #List for part's expected quality sequence; IMTS self.pt_ql_seq = [] #long pull dict for maintaining agent threads for other devices self.lp = {} self.part_quality_sequence() self.initial_execution_state() self.set_priority() self.initiate_cmm_client() self.initiate_pull_thread() def set_priority(self): self.priority = None self.priority = priority(self, self.cmm_binding) def part_quality_sequence(self): self.pt_ql_seq = [] self.pt_ql_seq.append(['good', False]) self.pt_ql_seq.append(['bad', False]) self.pt_ql_seq.append(['rework', False]) self.pt_ql_seq.append(['good', False]) self.pt_ql_seq.append(['reworked', False]) def part_quality_next(self, index=None): if index != None: self.pt_ql_seq[index][1] = True else: output = None for i, x in enumerate(self.pt_ql_seq): if not x[1]: output = [i, x[0]] self.pt_ql_seq[i][1] = True break if output: return output else: self.part_quality_sequence() return self.part_quality_next() def initial_execution_state(self): self.execution = {} self.execution['cnc1'] = None self.execution['cmm1'] = None self.execution['b1'] = None self.execution['conv1'] = None self.execution['r1'] = None def initiate_cmm_client(self): if not self.sim: configFile = open('configFiles/clients.cfg', 'r') device = json.loads( configFile.read())['devices'][self.device_uuid] self.cmm_client = hexagonClient(str(device['host']), int(device['port']), int(device['port'])) self.cmm_client.connect() def initiate_interfaces(self): self.material_load_interface = MaterialLoad(self) self.material_unload_interface = MaterialUnload(self) def initiate_adapter(self, host, port): self.adapter = Adapter((host, port)) self.mode1 = Event('mode') self.adapter.add_data_item(self.mode1) self.e1 = Event('exec') self.adapter.add_data_item(self.e1) self.avail1 = Event('avail') self.adapter.add_data_item(self.avail1) self.binding_state_material = Event('binding_state_material') self.adapter.add_data_item(self.binding_state_material) self.cmm_binding = Event('cmm_binding') self.adapter.add_data_item(self.cmm_binding) self.material_load = Event('material_load') self.adapter.add_data_item(self.material_load) self.material_unload = Event('material_unload') self.adapter.add_data_item(self.material_unload) def initiate_dataitems(self): self.adapter.begin_gather() self.avail1.set_value("AVAILABLE") self.e1.set_value("READY") self.mode1.set_value("AUTOMATIC") self.binding_state_material.set_value("INACTIVE") self.material_load.set_value("NOT_READY") self.material_unload.set_value("NOT_READY") self.adapter.complete_gather() def initiate_pull_thread(self): #Pull MTConnect data from other devices self.thread = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread.start() self.thread2 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread2.start() self.thread3 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread3.start() self.thread4 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread4.start() def start_pull(self, addr, request, func, stream=True): response = requests.get(addr + request + "&from=" + self.next_sequence, stream=stream) self.lp[request.split('/')[1]] = None self.lp[request.split('/')[1]] = LongPull(response, addr, self) self.lp[request.split('/')[1]].long_pull(func) def start_pull_asset(self, addr, request, assetId, stream_root): response = urllib2.urlopen(addr + request).read() from_long_pull_asset(self, response, stream_root) def CMM_NOT_READY(self): self.material_load_interface.superstate.DEACTIVATE() self.material_unload_interface.superstate.DEACTIVATE() def ACTIVATE(self): if self.mode1.value() == "AUTOMATIC" and self.avail1.value( ) == "AVAILABLE": self.make_operational() elif self.system_normal: self.still_not_ready() else: self.faulted() def OPERATIONAL(self): if self.has_material: self.unloading() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str(uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.cmm_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.part_quality = self.part_quality_next()[1] if self.part_quality: if self.part_quality == 'rework': self.coordinator_task = "MoveMaterial_5" else: self.coordinator_task = "MoveMaterial_4" + "_" + self.part_quality self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCmm" self.coordinator.superstate.unavailable() elif self.has_material == False: self.loading() self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadCmm" self.collaborator.superstate.unavailable() self.priority.collab_check() else: self.start() def IDLE(self): if self.has_material: self.material_unload_interface.superstate.IDLE() else: self.material_load_interface.superstate.IDLE() def CYCLING(self): if self.fail_next: self.system.append([ 'cmm', 'Device', 'SYSTEM', 'FAULT', 'Cycle failed to start', 'CYCLE' ]) self.cmm_fault() self.fail_next = False else: self.adapter.begin_gather() self.e1.set_value("ACTIVE") self.adapter.complete_gather() def func(self=self): self.cmm_execution_ready() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str( uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.cmm_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.part_quality = self.part_quality_next()[1] if self.part_quality: if self.part_quality == 'rework': self.coordinator_task = "MoveMaterial_5" else: self.coordinator_task = "MoveMaterial_4" + "_" + self.part_quality self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCmm" self.coordinator.superstate.unavailable() self.adapter.begin_gather() self.e1.set_value("READY") self.adapter.complete_gather() if self.sim: if not self.cycle_time: func() else: timer_cycling = Timer(self.cycle_time, func) timer_cycling.daemon = True timer_cycling.start() else: if self.part_quality in [None, 'good', 'reworked']: cycle = self.cmm_client.load_run_pgm( taskcmm.startProgramA) elif self.part_quality == 'bad': cycle = self.cmm_client.load_run_pgm( taskcmm.startProgramB) elif self.part_quality == 'rework': cycle = self.cmm_client.load_run_pgm( taskcmm.startProgramC) time.sleep(30) status = (self.cmm_client.load_run_pgm( taskcmm.getStatus)).lower() print("State before Completion", status) while ('good' or 'bad' or 'rework') not in status: status = (self.cmm_client.load_run_pgm( taskcmm.getStatus)).lower() time.sleep(3) print("State after completion", status) func() def LOADING(self): if not self.has_material: self.material_load_interface.superstate.idle() def UNLOADING(self): if self.has_material: self.material_unload_interface.superstate.idle() def load_time_limit(self, limit): self.material_load_interface.superstate.processing_time_limit = limit def load_failed_time_limit(self, limit): self.material_load_interface.superstate.fail_time_limit = limit def unload_time_limit(self, limit): self.material_unload_interface.superstate.processing_time_limit = limit def unload_failed_time_limit(self, limit): self.material_unload_interface.superstate.fail_time_limit = limit def interface_type(self, value=None, subtype=None): self.interfaceType = value def COMPLETED(self): if self.interfaceType == "Request": self.complete() def EXITING_IDLE(self): if self.has_material: self.unloading() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str(uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.cmm_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.part_quality = self.part_quality_next()[1] if self.part_quality: if self.part_quality == 'rework': self.coordinator_task = "MoveMaterial_5" else: self.coordinator_task = "MoveMaterial_4" + "_" + self.part_quality self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadCmm" self.coordinator.superstate.unavailable() else: self.loading() self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadCmm" self.collaborator.superstate.unavailable() self.priority.collab_check() def LOADED(self): self.has_material = True self.material_load_interface.superstate.DEACTIVATE() def UNLOADED(self): self.has_material = False self.material_unload_interface.superstate.DEACTIVATE() def IN_TRANSITION(self): pass def EXIT_TRANSITION(self): if self.has_material == False: self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadCmm" self.collaborator.superstate.unavailable() self.priority.collab_check() def FAILED(self): if "Request" in self.interfaceType: self.failed() def void(self): pass def event(self, source, comp, name, value, code=None, text=None): self.events.append([source, comp, name, value, code, text]) action = value.lower() if action == "fail": action = "failure" if comp == "Coordinator" and value.lower() == 'preparing': self.priority.event_list( [source, comp, name, value, code, text]) #tool_change: to be updated elif self.is_coordinator and self.binding_state_material.value( ).lower() == "committed" and text == 'r1': if value.lower() == 'inactive' and 'ToolChange' in str( self.master_tasks[self.master_uuid]): self.master_tasks[self.master_uuid]['coordinator'][ self.device_uuid]['SubTask']['cnc1'][1] = 'COMPLETE' self.coordinator.superstate.task.superstate.success() self.complete() if comp == "Task_Collaborator" and action != 'unavailable': self.coordinator.superstate.event(source, comp, name, value, code, text) elif comp == "Coordinator" and action != 'unavailable': if value.lower() != 'preparing': self.collaborator.superstate.event(source, comp, name, value, code, text) elif 'SubTask' in name and action != 'unavailable': if self.is_coordinator == True: self.coordinator.superstate.event(source, comp, name, value, code, text) elif self.is_collaborator == True: self.collaborator.superstate.event(source, comp, name, value, code, text) elif name == "MaterialLoad" and action != 'unavailable': try: if value.lower( ) == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_load_ready()') eval('self.material_load_interface.superstate.' + action + '()') except Exception as e: print("Incorrect event") print(e) elif name == "MaterialUnload" and action != 'unavailable': try: if action == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_unload_ready()') eval('self.material_unload_interface.superstate.' + action + '()') except Exception as e: print("incorrect event") print(e) elif comp == "Controller": if name == "ControllerMode": if source.lower() == 'cmm': self.adapter.begin_gather() self.mode1.set_value(value.upper()) self.adapter.complete_gather() elif name == "Execution": if source.lower() == 'cmm': self.adapter.begin_gather() self.e1.set_value(value.upper()) self.adapter.complete_gather() elif text in self.execution: self.execution[text] = value.lower() elif comp == "Device": if name == "SYSTEM" and action != 'unavailable': try: eval('self.' + source.lower() + '_system_' + value.lower() + '()') except Exception as e: print("Not a valid Device trigger", e) elif name == "Availability": if source.lower() == 'cmm': self.adapter.begin_gather() self.avail1.set_value(value.upper()) self.adapter.complete_gather()
class StateMachineModel: """The model for MTConnect behavior in the robot.""" def __init__(self,host,port,parent,sim): self.parent = parent self.sim = sim self.initiate_adapter(host,port) self.adapter.start() self.initiate_dataitems() self.initiate_interfaces() self.events = [] #long pull dict for maintaining agent threads for other devices self.lp = {} self.master_tasks = {} self.next_sequence = str(1) self.device_uuid = "r1" # Maximum amount of time for material handling to complete before marking it complete regardless self.material_load_interface.superstate.simulated_duration = 900 self.material_unload_interface.superstate.simulated_duration = 900 self.master_uuid = str() self.is_coordinator = False self.is_collaborator = True self.fail_next = False self.reset_required = False self.initial_execution_state() self.set_priority() self.initiate_pull_thread() def set_priority(self): self.priority = None self.priority = priority(self, self.robot_binding) def initial_execution_state(self): self.execution = {} self.execution['cnc1'] = None self.execution['cmm1'] = None self.execution['b1'] = None self.execution['conv1'] = None self.execution['r1'] = None def initiate_interfaces(self): self.material_load_interface = MaterialLoadResponse(self, self.sim) self.material_unload_interface = MaterialUnloadResponse(self, self.sim) self.open_chuck_interface = OpenChuckRequest(self) self.close_chuck_interface = CloseChuckRequest(self) self.open_door_interface = OpenDoorRequest(self) self.close_door_interface = CloseDoorRequest(self) self.change_tool_interface = ChangeToolRequest(self) def initiate_adapter(self, host, port): self.adapter = Adapter((host,port)) self.mode1 = Event('mode') self.adapter.add_data_item(self.mode1) self.e1 = Event('exec') self.adapter.add_data_item(self.e1) self.avail1 = Event('avail') self.adapter.add_data_item(self.avail1) self.binding_state_material = Event('binding_state_material') self.adapter.add_data_item(self.binding_state_material) self.robot_binding = Event('robot_binding') self.adapter.add_data_item(self.robot_binding) self.open_chuck = Event('open_chuck') self.adapter.add_data_item(self.open_chuck) self.close_chuck = Event('close_chuck') self.adapter.add_data_item(self.close_chuck) self.open_door = Event('open_door') self.adapter.add_data_item(self.open_door) self.close_door = Event('close_door') self.adapter.add_data_item(self.close_door) self.change_tool = Event('change_tool') self.adapter.add_data_item(self.change_tool) self.material_load = Event('material_load') self.adapter.add_data_item(self.material_load) self.material_unload = Event('material_unload') self.adapter.add_data_item(self.material_unload) self.material_state = Event('material_state') self.adapter.add_data_item(self.material_state) def initiate_dataitems(self): self.adapter.begin_gather() self.avail1.set_value("AVAILABLE") self.e1.set_value("READY") self.mode1.set_value("AUTOMATIC") self.binding_state_material.set_value("INACTIVE") self.open_chuck.set_value("NOT_READY") self.close_chuck.set_value("NOT_READY") self.open_door.set_value("NOT_READY") self.close_door.set_value("NOT_READY") self.change_tool.set_value("NOT_READY") self.material_load.set_value("NOT_READY") self.material_unload.set_value("NOT_READY") self.material_state.set_value("UNLOADED") self.adapter.complete_gather() def initiate_pull_thread(self): #Pull MTConnect data from other devices self.thread= Thread( target = self.start_pull, args=( "http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull ) ) self.thread.start() self.thread2= Thread( target = self.start_pull, args=( "http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull ) ) self.thread2.start() def interface_type(self, value = None, subtype = None): self.interfaceType = value def start_pull(self,addr,request, func, stream = True): response = requests.get(addr+request+"&from="+self.next_sequence, stream=stream) self.lp[request.split('/')[1]] = None self.lp[request.split('/')[1]] = LongPull(response, addr, self) self.lp[request.split('/')[1]].long_pull(func) def start_pull_asset(self, addr, request, assetId, stream_root): response = urllib2.urlopen(addr+request).read() from_long_pull_asset(self, response, stream_root) def ACTIVATE(self): self.make_operational() self.open_chuck_interface.superstate.start() self.close_chuck_interface.superstate.start() self.open_door_interface.superstate.start() self.close_door_interface.superstate.start() self.change_tool_interface.superstate.start() def FAULT(self): self.collaborator.superstate.unavailable() self.open_chuck_interface.superstate.DEACTIVATE() self.close_chuck_interface.superstate.DEACTIVATE() self.open_door_interface.superstate.DEACTIVATE() self.close_door_interface.superstate.DEACTIVATE() self.material_load_interface.superstate.DEACTIVATE() self.material_unload_interface.superstate.DEACTIVATE() self.change_tool_interface.superstate.DEACTIVATE() def OPERATIONAL(self): self.make_idle() def IDLE(self): if self.binding_state_material.value() == 'COMMITTED': self.TRANSITION() self.LOADING() return if not self.check_tool_change_req(): self.adapter.begin_gather() self.e1.set_value("READY") self.adapter.complete_gather() if self.reset_required: time.sleep(2) self.reset_statemachine() self.reset_required = False if not self.check_tool_change_req() or getattr(self,'collaborator',None) == None: self.material_unload_interface.superstate.not_ready() self.material_load_interface.superstate.not_ready() self.collaborator = collaborator( parent = self, interface = self.binding_state_material, collaborator_name = self.device_uuid ) self.collaborator.superstate.unavailable() self.priority.collab_check() def check_tool_change_req(self): if self.master_uuid in self.master_tasks and 'ToolChange' in str(self.master_tasks[self.master_uuid]): return True else: return def LOADING(self): if self.state == 'base:operational:loading': if self.collaborator.superstate.currentSubTaskType == "MaterialLoad": self.material_load_interface.superstate.ready() def UNLOADING(self): self.material_unload_interface.superstate.ready() self.adapter.begin_gather() self.e1.set_value("ACTIVE") self.adapter.complete_gather() def LOADING_COMPLETE(self): coordinator = self.master_tasks[self.master_uuid]['coordinator'].keys()[0] for k,v in self.master_tasks[self.master_uuid]['coordinator'][coordinator]['SubTask'].iteritems(): if 'MaterialLoad' in v: self.priority.binding_state(k,has_material = True) break self.material_load_interface.superstate.not_ready() def IN_TRANSITION(self): if 'ToolChange' not in str(self.master_tasks[self.master_uuid]): self.complete() def TRANSITION(self): if self.collaborator.superstate.currentSubTask == 'ToolChange': self.event('robot','ToolInterface','SubTask_ToolChange','ACTIVE',self.master_uuid,'r1') def EXIT_TRANSITION(self): coordinator = self.master_tasks[self.master_uuid]['coordinator'].keys()[0] #imts_demo part rotation: reset after every cycle: good->bad->rework part cycle if coordinator == 'cmm1' and self.master_tasks[self.master_uuid]['part_quality'] == 'rework': self.reset_required = True #imts_demo part rotation: method to reset statemachine after a 3-part cycle is completed def reset_statemachine(self): coordinator = self.master_tasks[self.master_uuid]['coordinator'].keys()[0] uuid = copy.deepcopy(self.master_uuid) if coordinator == 'cmm1' and self.master_tasks[uuid]['part_quality'] == 'rework': print ("Resetting Robot") self.events = [] for k,v in self.master_tasks.iteritems(): if k != uuid: self.master_tasks[k] = None for k,v in self.lp.iteritems(): self.lp[k]._response = None nextsequence_string = urllib2.urlopen("http://localhost:5000/current").read() nextsequence_root = ET.fromstring(nextsequence_string) nextsequence = nextsequence_root[0].attrib['nextSequence'] self.next_sequence = nextsequence self.priority = None self.set_priority() try: self.FAULT() except Exception as e: print ("Error resetting interfaces",e) self.adapter.removeAllAsset('Task') self.initiate_pull_thread() print ("robot reset") def UNLOADING_COMPLETE(self): self.priority.binding_state(self.master_tasks[self.master_uuid]['coordinator'].keys()[0],has_material = False) self.material_unload_interface.superstate.not_ready() def COMPLETED(self): if "request" in self.interfaceType.lower(): pass elif "response" in self.interfaceType.lower() and "material" in self.interfaceType.lower(): if "unloaded" not in self.interfaceType.lower(): self.event(self.device_uuid, 'material_interface', 'SubTask_'+'MaterialUnload','COMPLETE') elif "unloaded" in self.interfaceType.lower(): self.event(self.device_uuid, 'material_interface', 'SubTask_'+'MaterialLoad','COMPLETE') def FAILED(self): pass def event(self, source, comp, name, value, code = None, text = None): ev = RobotEvent(source, comp, name, value, code, text) self.events.append(ev) action = value.lower() if comp == "Coordinator" and value.lower() == 'preparing': self.priority.event_list([source, comp, name, value, code, text]) if action == "fail": action = "failure" if "Collaborator" in comp and action!='unavailable': try: self.coordinator.superstate.event(source, comp, name, value, code, text) except Exception as e: print ("Error in Coordinator event: sending back to the event method for a retry") print(e) time.sleep(0.2) self.event(source, comp, name, value, code, text) elif "Coordinator" in comp and action!='unavailable': try: if value.lower() != 'preparing': self.collaborator.superstate.event(source, comp, name, value, code, text) if 'binding_state' in name and value.lower() == 'committed': if self.material_state.value() == "LOADED": self.material_load_ready() else: self.material_unload_ready() except Exception as e: print ("Error in Collaborator event: sending back to the event method for a retry in 0.2 s.") print (e) time.sleep(0.2) self.event(source, comp, name, value, code, text) elif 'SubTask' in name and action!='unavailable': try: if comp == 'interface_initialization' and source == self.device_uuid: if 'CloseChuck' in name: print ("CloseChuck Request to cnc1") elif 'CloseDoor' in name: print ("CloseDoor Request to cnc1") elif 'OpenChuck' in name: print ("OpenChuck Request to cnc1") elif 'OpenDoor' in name: print ("OpenDoor Request to cnc1") elif 'ChangeTool' in name: print ("ChangeTool Request to cnc1") if self.is_coordinator: self.coordinator.superstate.event(source, comp, name, value, code, text) elif self.is_collaborator: self.collaborator.superstate.event(source, comp, name, value, code, text) except Exception as e: print ("Error in SubTask event: sending back to the event method for a retry in 0.5 s.") time.sleep(0.5) self.event(source, comp, name, value, code, text) elif ev.name.startswith('Material') and action!='unavailable': self.material_event(ev) elif ev.name.startswith('ToolChange') and action!='unavailable': if comp == 'interface_completion': self.complete() elif comp == 'internal_event': self.internal_event(ev) elif ('Chuck' in name or 'Door' in name or 'ChangeTool' in name) and action!='unavailable': time.sleep(2) elif ev.component.startswith('Controller'): self.controller_event(ev) else: pass def internal_event(self, ev): status = None action = ev.value.lower() if ev.name == "MoveIn": print ("Moving In " + ev.text) status = self.parent.move_in(ev.text, self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Moved in") elif "MoveInCT" in ev.name: print ("Moving In cnc1_t1") status = self.parent.move_in('cnc1_t1', self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Moved in") elif ev.name == "MoveOut": print ("Moving Out From " + ev.text) status = self.parent.move_out(ev.text, self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Moved out") elif "MoveOutCT" in ev.name: print ("Moving Out From cnc1_t1") status = self.parent.move_out('cnc1_t1', self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Moved out") elif ev.name == "PickUpTool": print ("Picking Up Tool") status = self.internal_event(RobotEvent('ToolHolder', ev.component, 'MoveIn', ev.value, ev.code, 't1')) if status != True: self.fault() if status == True: status = self.internal_event(RobotEvent('ToolHolder', ev.component, 'GrabPart', ev.value, ev.code, 't1')) if status != True: self.fault() if status == True: status = self.internal_event(RobotEvent('ToolHolder', ev.component, 'MoveOut', ev.value, ev.code, 't1')) if status != True: self.fault() elif ev.name == "DropOffTool": print ("Droping Off Tool") status = self.internal_event(RobotEvent('ToolHolder', ev.component, 'MoveIn', ev.value, ev.code, 't1')) if status != True: self.fault() if status == True: self.internal_event(RobotEvent('ToolHolder', ev.component, 'ReleasePart', ev.value, ev.code, 't1')) if status != True: self.fault() if status == True: self.internal_event(RobotEvent('ToolHolder', ev.component, 'MoveOut', ev.value, ev.code, 't1')) if status != True: self.fault() if status == True: self.collaborator.superstate.subTask['ToolChange'].superstate.success() self.adapter.begin_gather() self.e1.set_value("READY") self.adapter.complete_gather() else: self.fault() elif ev.name == "ReleasePart": print ("Releasing the Part onto " + ev.text) status = self.parent.release(ev.text, self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Released") elif ev.name == "GrabPart": print ("Grabbing Part from " + ev.text) status = self.parent.grab(ev.text, self.master_tasks[self.master_uuid]['part_quality']) if status != True: self.fault() print ("Grabbed") else: print (ev.name) time.sleep(2) status = True return status def material_event(self, ev): action = ev.value.lower() timeout = 2.0 if action == "fail": action = "failure" if ev.name == "MaterialLoad": eval('self.material_load_interface.superstate.'+action+'()') if ev.value.lower() == 'complete' and ev.component != "interface_completion": self.complete() elif ev.name == "MaterialUnload": eval('self.material_unload_interface.superstate.'+action+'()') if ev.value.lower() == 'complete' and ev.component != "interface_completion": self.complete() else: pass def controller_event(self, ev): if ev.name == "ControllerMode": if ev.source.lower() == 'robot': self.adapter.begin_gather() self.mode1.set_value(ev.value.upper()) self.adapter.complete_gather() elif ev.name == "Execution": if ev.source.lower() == 'robot': self.adapter.begin_gather() self.e1.set_value(ev.value.upper()) self.adapter.complete_gather() elif ev.text in self.execution: self.execution[ev.text] = ev.value.lower() else: pass def device_event(self, ev): if ev.name == 'Availability': if ev.source.lower() == 'robot': self.adapter.begin_gather() self.avail1.set_value(ev.value.upper()) self.adapter.complete_gather() else: raise(Exception('Unknown Device event: ' + str(ev)))
class StateMachineModel: def __init__(self, host, port): self.initiate_adapter(host, port) self.adapter.start() self.initiate_dataitems() self.initiate_interfaces() self.system = [] self.load_time_limit(15) self.unload_time_limit(15) self.next_sequence = str(1) self.load_failed_time_limit(2) self.unload_failed_time_limit(2) self.events = [] self.master_tasks = {} self.device_uuid = "b1" self.buffer = [] #long pull dict for maintaining agent threads for other devices self.lp = {} self.buffer_size = 100 self.master_uuid = str() self.is_coordinator = False self.is_collaborator = False self.system_normal = True self.has_material = False self.fail_next = False self.timer_check = str() self.initial_execution_state() self.set_priority() self.initiate_pull_thread() def set_priority(self): self.priority = None self.priority = priority(self, self.buffer_binding) def initial_execution_state(self): self.execution = {} self.execution['cnc1'] = None self.execution['cmm1'] = None self.execution['b1'] = None self.execution['conv1'] = None self.execution['r1'] = None def initiate_interfaces(self): self.material_load_interface = MaterialLoad(self) self.material_unload_interface = MaterialUnload(self) def initiate_adapter(self, host, port): self.adapter = Adapter((host, port)) self.mode1 = Event('mode') self.adapter.add_data_item(self.mode1) self.e1 = Event('exec') self.adapter.add_data_item(self.e1) self.avail1 = Event('avail') self.adapter.add_data_item(self.avail1) self.binding_state_material = Event('binding_state_material') self.adapter.add_data_item(self.binding_state_material) self.buffer_binding = Event('buffer_binding') self.adapter.add_data_item(self.buffer_binding) self.material_load = Event('material_load') self.adapter.add_data_item(self.material_load) self.material_unload = Event('material_unload') self.adapter.add_data_item(self.material_unload) def initiate_dataitems(self): self.adapter.begin_gather() self.avail1.set_value("AVAILABLE") self.e1.set_value("READY") self.mode1.set_value("AUTOMATIC") self.binding_state_material.set_value("INACTIVE") self.material_load.set_value("NOT_READY") self.material_unload.set_value("NOT_READY") self.adapter.complete_gather() def initiate_pull_thread(self): #Pull MTConnect data from other devices self.thread = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread.start() self.thread2 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread2.start() self.thread3 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread3.start() def start_pull(self, addr, request, func, stream=True): response = requests.get(addr + request + "&from=" + self.next_sequence, stream=stream) self.lp[request.split('/')[1]] = None self.lp[request.split('/')[1]] = LongPull(response, addr, self) self.lp[request.split('/')[1]].long_pull(func) def start_pull_asset(self, addr, request, assetId, stream_root): response = urllib2.urlopen(addr + request).read() from_long_pull_asset(self, response, stream_root) def BUFFER_NOT_READY(self): self.material_load_interface.superstate.DEACTIVATE() self.material_unload_interface.superstate.DEACTIVATE() def ACTIVATE(self): if self.mode1.value() == "AUTOMATIC": self.make_operational() elif self.system_normal: self.still_not_ready() else: self.faulted() def buffer_append(self): if len(self.buffer) < 100: self.buffer.append([len(self.buffer) + 1]) def buffer_pop(self): if len(self.buffer) > 0: self.buffer.pop(0) def OPERATIONAL(self): self.make_idle() def IDLE(self): if len(self.buffer) > 0: self.has_material = True else: self.has_material = False if self.binding_state_material.value() != "COMMITTED": if self.has_material: self.is_coordinator = True self.is_collaborator = False self.material_load_interface.superstate.DEACTIVATE() else: self.is_coordinator = False self.is_collaborator = True self.material_unload_interface.superstate.DEACTIVATE() if not self.has_material: self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadBuffer" self.collaborator.superstate.unavailable() self.material_load_interface.superstate.IDLE() self.priority.collab_check() if self.has_material: if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str( uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.coordinator_task = "MoveMaterial_3" self.adapter.begin_gather() self.buffer_binding.set_value(master_task_uuid) self.adapter.complete_gather() self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadBuffer" self.coordinator.superstate.unavailable() self.material_unload_interface.superstate.IDLE() def load_time_limit(self, limit): self.material_load_interface.superstate.processing_time_limit = limit def load_failed_time_limit(self, limit): self.material_load_interface.superstate.fail_time_limit = limit def unload_time_limit(self, limit): self.material_unload_interface.superstate.processing_time_limit = limit def unload_failed_time_limit(self, limit): self.material_unload_interface.superstate.fail_time_limit = limit def status(self): pass def interface_type(self, value=None, subtype=None): self.interfaceType = value def COMPLETED(self): if self.interfaceType == "Request": self.complete() def LOADED(self): self.buffer_append() self.material_load_interface.superstate.DEACTIVATE() def UNLOADED(self): self.buffer_pop() self.material_unload_interface.superstate.DEACTIVATE() def IN_TRANSITION(self): if self.buffer: self.complete() def EXIT_TRANSITION(self): pass def FAILED(self): if "Request" in self.interfaceType: self.failed() def void(self): pass def event(self, source, comp, name, value, code=None, text=None): self.events.append([source, comp, name, value, code, text]) action = value.lower() if action == "fail": action = "failure" if comp == "Coordinator" and value.lower() == 'preparing': self.priority.event_list( [source, comp, name, value, code, text]) if comp == "Task_Collaborator" and self.is_coordinator == True: self.coordinator.superstate.event(source, comp, name, value, code, text) elif comp == "Coordinator" and self.is_collaborator == True: if value.lower() != 'preparing': self.collaborator.superstate.event(source, comp, name, value, code, text) if value.lower() == 'inactive': self.IDLE() elif 'SubTask' in name: if self.is_coordinator == True: self.coordinator.superstate.event(source, comp, name, value, code, text) elif self.is_collaborator == True: self.collaborator.superstate.event(source, comp, name, value, code, text) elif name == "MaterialLoad": try: if value.lower( ) == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_load_ready()') eval('self.material_load_interface.superstate.' + action + '()') except Exception as e: print("Incorrect Event") print(e) elif name == "MaterialUnload": try: if value.lower( ) == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_unload_ready()') eval('self.material_unload_interface.superstate.' + action + '()') except Exception as e: print("Incorrect Event") print(e) elif comp == "Controller": if name == "ControllerMode": if source == 'Buffer': self.adapter.begin_gather() self.mode1.set_value(value.upper()) self.adapter.complete_gather() elif name == "Execution": if source == 'Buffer': self.adapter.begin_gather() self.e1.set_value(value.upper()) self.adapter.complete_gather() elif text in self.execution: self.execution[text] = value.lower() elif comp == "Device": if name == "SYSTEM": eval('self.' + source + '_system_' + value.lower() + '()') elif name == "Availability": if source == 'Buffer': self.adapter.begin_gather() self.avail1.set_value(value.upper()) self.adapter.complete_gather()
class StateMachineModel: def __init__(self, host, port, cell_part): self.initiate_adapter(host, port) self.adapter.start() self.initiate_dataitems() self.cell_part = cell_part self.initiate_interfaces() self.system = [] self.load_time_limit(15) self.unload_time_limit(15) self.next_sequence = str(1) self.load_failed_time_limit(2) self.unload_failed_time_limit(2) self.events = [] #long pull dict for maintaining agent threads for other devices self.lp = {} self.master_tasks = {} self.device_uuid = "conv1" self.master_uuid = str() self.is_coordinator = False self.is_collaborator = False self.system_normal = True self.has_material = False self.fail_next = False self.internal_buffer = {} self.current_part = None self.cycle_count = 0 self.initial_execution_state() self.set_priority() self.initiate_internal_buffer() self.initiate_pull_thread() def set_priority(self): self.priority = None self.priority = priority(self, self.conv1_binding) def initial_execution_state(self): self.execution = {} self.execution['cnc1'] = None self.execution['cmm1'] = None self.execution['b1'] = None self.execution['conv1'] = None self.execution['r1'] = None def initiate_interfaces(self): self.material_load_interface = MaterialLoad(self) self.material_unload_interface = MaterialUnload(self) def initiate_internal_buffer(self): self.internal_buffer['good'] = True self.internal_buffer['bad'] = True self.internal_buffer['rework'] = True def initiate_adapter(self, host, port): self.adapter = Adapter((host, port)) self.mode1 = Event('mode') self.adapter.add_data_item(self.mode1) self.e1 = Event('exec') self.adapter.add_data_item(self.e1) self.avail1 = Event('avail') self.adapter.add_data_item(self.avail1) self.binding_state_material = Event('binding_state_material') self.adapter.add_data_item(self.binding_state_material) self.conv1_binding = Event('conv1_binding') self.adapter.add_data_item(self.conv1_binding) self.material_load = Event('material_load') self.adapter.add_data_item(self.material_load) self.material_unload = Event('material_unload') self.adapter.add_data_item(self.material_unload) def initiate_dataitems(self): self.adapter.begin_gather() self.avail1.set_value("AVAILABLE") self.e1.set_value("READY") self.mode1.set_value("AUTOMATIC") self.binding_state_material.set_value("INACTIVE") self.material_load.set_value("NOT_READY") self.material_unload.set_value("NOT_READY") self.adapter.complete_gather() def initiate_pull_thread(self): #Pull MTConnect data from other devices self.thread = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread.start() self.thread2 = Thread( target=self.start_pull, args= ("http://*****:*****@category="EVENT"]&interval=10&count=1000""", from_long_pull)) self.thread2.start() def start_pull(self, addr, request, func, stream=True): response = requests.get(addr + request + "&from=" + self.next_sequence, stream=stream) self.lp[request.split('/')[1]] = None self.lp[request.split('/')[1]] = LongPull(response, addr, self) self.lp[request.split('/')[1]].long_pull(func) def start_pull_asset(self, addr, request, assetId, stream_root): response = urllib2.urlopen(addr + request).read() from_long_pull_asset(self, response, stream_root) def InputConveyor_NOT_READY(self): self.material_load_interface.superstate.DEACTIVATE() self.material_unload_interface.superstate.DEACTIVATE() def ACTIVATE(self): if self.mode1.value() == "AUTOMATIC" and self.avail1.value( ) == "AVAILABLE": self.make_operational() elif self.system_normal: self.still_not_ready() else: self.faulted() def part_order(self): #scripted sequence of part order tasks part_quality_list = [ self.internal_buffer['good'], self.internal_buffer['bad'], self.internal_buffer['rework'] ] if self.cycle_count == 1: self.current_part = "reset" time.sleep(1) if part_quality_list == [True, True, True ] and self.current_part == None: self.current_part = 'good' return "coordinator" elif part_quality_list == [False, True, True ] and self.current_part == 'good': self.current_part = 'good' return "collaborator" elif part_quality_list == [True, True, True ] and self.current_part == 'good': self.current_part = 'good' time.sleep(2) print("Cycle completed!") return "coordinator" else: return None def OPERATIONAL(self): part_order = self.part_order() if part_order == "coordinator": self.unloading() self.is_coordinator = True self.is_collaborator = False if self.master_uuid in self.master_tasks: del self.master_tasks[self.master_uuid] self.master_uuid = self.device_uuid + '_' + str(uuid.uuid4()) master_task_uuid = copy.deepcopy(self.master_uuid) self.adapter.begin_gather() self.conv1_binding.set_value(self.master_uuid) self.adapter.complete_gather() self.coordinator_task = "MoveMaterial_1" self.coordinator = coordinator( parent=self, master_task_uuid=master_task_uuid, interface=self.binding_state_material, coordinator_name=self.device_uuid) self.coordinator.superstate.task_name = "UnloadConv" self.coordinator.superstate.unavailable() elif part_order == "collaborator": self.loading() self.is_coordinator = False self.is_collaborator = True self.collaborator = collaborator( parent=self, interface=self.binding_state_material, collaborator_name=self.device_uuid) self.collaborator.superstate.task_name = "LoadConv" self.collaborator.superstate.unavailable() self.priority.collab_check() else: if part_order == None: self.cell_part(current_part="reset") else: self.cell_part(current_part=self.current_part) def IDLE(self): if False not in self.internal_buffer.values(): self.material_load_interface.superstate.DEACTIVATE() elif False in self.internal_buffer.values( ) and True in self.internal_buffer.values(): self.material_unload_interface.superstate.DEACTIVATE() def LOADING(self): self.material_load_interface.superstate.IDLE() def UNLOADING(self): self.material_unload_interface.superstate.IDLE() def EXIT_LOADING(self): self.has_material = True self.internal_buffer[self.current_part] = True if self.current_part == 'rework': self.cycle_count = self.cycle_count + 1 self.cell_part(cycle_count=True) self.material_load_interface.superstate.DEACTIVATE() def EXIT_UNLOADING(self): self.has_material = False self.material_unload_interface.superstate.DEACTIVATE() self.internal_buffer[self.current_part] = False def load_time_limit(self, limit): self.material_load_interface.superstate.processing_time_limit = limit def load_failed_time_limit(self, limit): self.material_load_interface.superstate.fail_time_limit = limit def unload_time_limit(self, limit): self.material_unload_interface.superstate.processing_time_limit = limit def unload_failed_time_limit(self, limit): self.material_unload_interface.superstate.fail_time_limit = limit def interface_type(self, value=None, subtype=None): self.interfaceType = value def COMPLETED(self): if self.interfaceType == "Request": self.complete() def EXITING_IDLE(self): if self.has_material: self.has_material = False def LOADED(self): self.has_material = True def UNLOADED(self): self.has_material = False def IN_TRANSITION(self): if self.is_collaborator and 'ToolChange' not in str( self.master_tasks[self.master_uuid]): self.complete() def EXIT_TRANSITION(self): pass def FAILED(self): if "Request" in self.interfaceType: self.failed() def void(self): pass def event(self, source, comp, name, value, code=None, text=None): self.events.append([source, comp, name, value, code, text]) action = value.lower() if action == "fail": action = "failure" if comp == "Coordinator" and value.lower() == 'preparing': self.priority.event_list( [source, comp, name, value, code, text]) if comp == "Task_Collaborator" and action != 'unavailable': self.coordinator.superstate.event(source, comp, name, value, code, text) if value == 'INACTIVE' and self.state == 'base:operational:in_transition': self.COMPLETED() elif comp == "Coordinator" and action != 'unavailable': if value.lower() != 'preparing': self.collaborator.superstate.event(source, comp, name, value, code, text) if value.lower() == 'inactive' and 'ToolChange' in str( self.master_tasks[self.master_uuid]): if self.state == "base:operational:in_transition": self.COMPLETED() elif 'SubTask' in name and action != 'unavailable': if self.is_coordinator == True: self.coordinator.superstate.event(source, comp, name, value, code, text) elif self.is_collaborator == True: self.collaborator.superstate.event(source, comp, name, value, code, text) elif name == "MaterialLoad" and action != 'unavailable': if value.lower( ) == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_load_ready()') eval('self.material_load_interface.superstate.' + action + '()') elif name == "MaterialUnload" and action != 'unavailable': if value.lower( ) == 'ready' and self.state == 'base:operational:idle': eval('self.robot_material_unload_ready()') eval('self.material_unload_interface.superstate.' + action + '()') elif comp == "Controller": if name == "ControllerMode": if source.lower() == 'conv': self.adapter.begin_gather() self.mode1.set_value(value.upper()) self.adapter.complete_gather() elif name == "Execution": if source.lower() == 'conv': self.adapter.begin_gather() self.e1.set_value(value.upper()) self.adapter.complete_gather() elif text in self.execution: self.execution[text] = value.lower() elif comp == "Device": if name == "SYSTEM" and action != 'unavailable': try: eval('self.' + source.lower() + '_system_' + value.lower() + '()') except Exception as e: print("Not a valid Device trigger", e) elif name == "Availability": if source.lower() == 'conv': self.adapter.begin_gather() self.avail1.set_value(value.upper()) self.adapter.complete_gather()