[docs]classReceiveACLBehaviour(CyclicBehaviour):""" This class implements the behaviour that handles all the ACL messages that the SMIA PE will receive from the others SMIAs in the I4.0 System. If some of these messages are responses to previous SMIA PE requests, the associated BPMNPerformerBehaviour will be unlocked to continue execution of the production plan. """def__init__(self,agent_object):""" The constructor method is rewritten to add the object of the agent Args: agent_object (spade.Agent): the SPADE agent object of the SMIA agent. """# The constructor of the inherited class is executed.super().__init__()# The SPADE agent object is stored as a variable of the behaviour classself.myagent=agent_object
[docs]asyncdefon_start(self):""" This method implements the initialization process of this behaviour. """_logger.info("ReceiveACLBehaviour starting...")
[docs]asyncdefrun(self):""" This method implements the logic of the behaviour. """# Wait for a message with the standard ACL template to arrive.msg=awaitself.receive(timeout=10)# Timeout set to 10 seconds so as not to continuously execute the behavior.ifmsg:# This method will receive all ACL messages to the SMIA PE, so it will check if some of them are responses to# previous SMIA PE requests to unlock the associated BPMNPerformerBehaviour_logger.aclinfo("Analyzing ACL message... Checking if it is a response from previous SMIA PE message... ""Unlocking SMIA PE...")# Let's check if the BPMN performer behaviour is waiting for a responseforbehaviourinself.myagent.behaviours:ifstr(behaviour.__class__.__name__)=='BPMNPerformerBehaviour':forthread,contentinbehaviour.acl_messages_responses.items():ifthread==msg.threadandcontentisNone:# In this case, the behaviour is waiting for the content_logger.aclinfo("BPMNPerformerBehaviour is waiting for a content [{}] that has arrived with"" thread [{}] from [{}].".format(msg.body,msg.thread,msg.sender))self.myagent.smia_pe_info['ReceivedACLmsg']+=1msg_parsed_body=acl_smia_messages_utils.get_parsed_body_from_acl_msg(msg)if(msg.get_metadata(FIPAACLInfo.FIPA_ACL_PERFORMATIVE_ATTRIB)==FIPAACLInfo.FIPA_ACL_PERFORMATIVE_FAILURE):_logger.error("SMIA PE has received a Failure for the thread [{}], so it cannot continue. ""Reason: {}".format(thread,msg_parsed_body['reason']))# The information to be displayed in the GUI is also addedself.myagent.smia_pe_info['InteractionsDict'].append({'type':'acl_recv','response_type':msg.get_metadata(FIPAACLInfo.FIPA_ACL_PERFORMATIVE_ATTRIB),'title':'FIPA-ACL failure response received ...','response_title':'FIPA-ACL failure response received from {}'.format(acl_smia_messages_utils.get_sender_from_acl_msg(msg)),'response_msg':msg_parsed_body['reason']})_logger.error('SMIA PE cannot continue due to a received FAILURE ACL message. ''Reason: {}'.format(msg_parsed_body['reason']))_logger.warning("BPMNPerformerBehaviour will remain blocked due to the receipt of an ""ACL failure message.... ")if(msg.get_metadata(FIPAACLInfo.FIPA_ACL_PERFORMATIVE_ATTRIB)==FIPAACLInfo.FIPA_ACL_PERFORMATIVE_INFORM):# In this case the content is validbehaviour.acl_messages_responses[thread]=msg# Now the behaviour can be unlockedbehaviour.acl_request_event.set()_logger.info("BPMNPerformerBehaviour unlocked and added the response content data.")# The information to be displayed in the GUI is also addedself.myagent.smia_pe_info['InteractionsDict'].append({'type':'acl_recv','response_type':msg.get_metadata(FIPAACLInfo.FIPA_ACL_PERFORMATIVE_ATTRIB),'title':'FIPA-ACL response received ...','response_title':'FIPA-ACL response ''received from {}'.format(acl_smia_messages_utils.get_sender_from_acl_msg(msg)),'response_msg':msg.body})else:_logger.info(" - No message received within 10 seconds on SMIA PE (ReceiveACLBehaviour)")