[docs]classSMIAAgent(Agent):""" This is the top level in the hierarchy of SPADE Agents. It extends the own class Agent of SPADE. The :term:`SMIA` Agent will be the generic and from which all other types of SMIAs will start. """acl_svc_requests={}#: Dictionary to save FIPA-ACL service requestsacl_svc_responses={}#: Dictionary to save FIPA-ACL service responsesnegotiations_data={}#: Dictionary to save negotiations related informationaas_model=None#: Object with the extended AAS modelcss_ontology=None#: Object with the Capability-Skill-Service ontologyasset_connections=None#: Class with the Asset Connection methodsagent_services=None#: Class with the all services of the Agentlock=None#: Asyncio Lock object for secure access to shared SMIA objects# def __init__(self, jid: str = None, password: str = None, verify_security: bool = False):# def __init__(self, jid: str = None, password: str = None, port: int = 5222, verify_security: bool = False): # For v4.0.0 and moredef__init__(self,jid:str=None,password:str=None,*args,**kwargs):# Generic constructor# The AAS_ID will be set in the associated ConfigMap, within the general-information of the AASifjidisNone:jid=properties_file_utils.get_dt_general_property('agentID')if'@'notinjid:# The XMPP server of the MAS will also be set in the associated ConfiMapxmpp_server=properties_file_utils.get_dt_general_property('xmpp-server')# Build the agent jid and passwordjid=jid+'@'+xmpp_serverifpasswordisNone:password=properties_file_utils.get_dt_general_property('password')super().__init__(jid,password,*args,**kwargs)# super().__init__(jid, password, port, verify_security) # For v4.0.0 and more# The banner of the program is printedGeneralUtils.print_smia_banner()self.initialize_smia_attributes()
[docs]definitialize_smia_attributes(self):""" This method initializes all the attributes of the SMIA. """# Objects to store the information related to ACL services are initializedself.acl_messages_id=0# It is resetself.acl_svc_requests={}self.acl_svc_responses={}# Object to store the information related to negotiations is initializedself.negotiations_data={}# The object with the CSS ontology and useful methods is initializedself.css_ontology=CapabilitySkillOntology()# The object with the Extended AAS model and useful methods is initializedself.aas_model=ExtendedAASModel()# The object with the AssetConnection class is initialized. At this point, as an empty JSONifself.asset_connectionsisNone:# With ExtensibleSMIA asset connections can be added beforeself.asset_connections={}# The class with all AgentServices is initializedifself.agent_servicesisNone:# With ExtensibleSMIA asset connections can be added beforeself.agent_services=AgentServices(self)# The Lock object is used to manage the access to global agent attributes (request and response dictionaries,# interaction id number...)self.lock=asyncio.Lock()
[docs]asyncdefsetup(self):""" This method performs the common setup of all types of :term:`SMIAs <SMIA>`. It defines the Finite State Machine (FSM) of the general SMIA Agent. """_logger.info(f"Setting up {self.jid} SMIA...")# First, the FSMBehaviour is instantiatedfsm_behaviour=AASFSMBehaviour()# TODO HACER AHORA PENSAR SI TIENE ESTADO IDLE SMIA GENERICO (en SMIAResource esta definido con IDLE)# A common SMIA has three statesfsm_behaviour.add_state(name=SMIAGeneralInfo.BOOTING_STATE_NAME,state=StateBooting(),initial=True)fsm_behaviour.add_state(name=SMIAGeneralInfo.RUNNING_STATE_NAME,state=StateRunning())fsm_behaviour.add_state(name=SMIAGeneralInfo.STOPPING_STATE_NAME,state=StateStopping())# Transitions are defined to determine from which state to which other state you are allowed to move to.fsm_behaviour.add_transition(source=SMIAGeneralInfo.BOOTING_STATE_NAME,dest=SMIAGeneralInfo.RUNNING_STATE_NAME)fsm_behaviour.add_transition(source=SMIAGeneralInfo.RUNNING_STATE_NAME,dest=SMIAGeneralInfo.STOPPING_STATE_NAME)# The FSM behaviour is added to the agentself.add_behaviour(fsm_behaviour)_logger.info(f"{self.jid} setup finished correctly.")
# ----------------------------------------------# Methods related to shared objects of the agent# ----------------------------------------------
[docs]asyncdefsave_new_acl_svc_request(self,thread,request_data):""" This method adds a new :term:`ACL <FIPA-ACL>` Service Request to the global acl service requests dictionary of the SMIA. Args: thread (str): thread of the ACL Service Request. request_data (dict): all the information of the ACL Service Request in JSON format. """asyncwithself.lock:# safe access to a shared object of the agentself.acl_svc_requests[thread]=request_data
[docs]asyncdefsave_acl_svc_response(self,thread,response_data):""" This method adds a specific :term:`Inter SMIA interaction` response to the global responses dictionary of the SMIA for this type of interaction. Args: thread (str): thread of the ACL Service response. response_data (dict): all the information of the ACL Service response in JSON format. """asyncwithself.lock:# safe access to a shared object of the agentself.acl_svc_responses[thread]=response_data
[docs]asyncdefremove_acl_svc_request(self,thread):""" This method removes an ACL Service Request from the global acl service requests dictionary of the SMIA. Args: thread (str): thread of the ACL Service Request. """asyncwithself.lock:# safe access to a shared object of the agentself.acl_svc_requests.pop(thread,None)
[docs]asyncdefget_acl_svc_request(self,thread):""" This method gets the information of an ACL Service Request from the global acl service requests dictionary of the SMIA using the thread. Args: thread (str): thread of the ACL Service Request. Returns: dict: all information of the ACL Service Request in JSON format (null if the thread does not exist). """asyncwithself.lock:# safe access to a shared object of the agentifthreadinself.acl_svc_requests:returnself.acl_svc_requests[thread]else:returnNone
[docs]asyncdefsave_negotiation_data(self,thread,neg_data):""" This method saves the information of a specific negotiation in which the SMIA has participated. The data is stored in the global object for all negotiations of the SMIA. Args: thread (str): thread of the negotiation neg_data (dict): all the information of the specific negotiation """asyncwithself.lock:# safe access to a shared object of the agentself.negotiations_data[thread]=neg_data
[docs]asyncdefsave_asset_connection_class(self,interface_reference,asset_connection):""" This method adds a new asset connection to the global variable of the agent. Args: interface_reference (basyx.aas.model.ModelReference): reference of the interface of the AssetConnection asset_connection: class with all information about the AssetConnection """asyncwithself.lock:# safe access to a shared object of the agentself.asset_connections[interface_reference]=asset_connection
[docs]asyncdefget_asset_connection_class_by_ref(self,asset_connection_ref):""" This method gets the asset connection class using its reference. Args: asset_connection_ref (basyx.aas.model.ModelReference): reference of the asset connection Returns: assetconnection.asset_connection: class of the asset connection """asyncwithself.lock:# safe access to a shared object of the agentforconn_ref,conn_classinself.asset_connections.items():ifconn_ref==asset_connection_ref:returnconn_classraiseAASModelReadingError("There is not asset connection class linked to {}".format(asset_connection_ref),asset_connection_ref,"MissingAssetConnectionClass")
[docs]asyncdefget_all_asset_connections(self):""" This method returns all asset connections of the agent. Returns: dict: dictionary wil all asset connections """asyncwithself.lock:# safe access to a shared object of the agentreturnself.asset_connections