Un comportamiento es la tarea debe llevar a cabo un agente inteligente. Esta tarea es implementada a través de la clase jade.core.behaviours.Behaviour en donde se encuentran los metodos que permitiran su proceso y terminacion. Para relizar este proceso, la clase que extienda de Behaviour debe implementar los metodos: action() en donde se encontrarán las instrucciones a llevar a cabo por el agente mientras esta activo y done() que debera indicar cuando el comportamiento finalizó el proceso.
La estuctura general de una implementación de un comportamiento sería:
public class ComportamientoCiclico extends Behaviour {Para activar el comportamiento de un agente, este debe ser agregado através del metodo addBehaviour() encontrado en la clase Agent.
public void action() {
//instrucciones
}
public boolean done() {
return false;
}
}
En JADE, existen por defecto varios tipos de Comportamiento que ya vienen implementados, explicaremos brevemente como funcionan y mostraremos como se implemento uno de ellos en nuestro ejercicio.
- SimpleBehaviour (Comportamiento Simple): Es un comportamiento atomico que puede ser utilizado en comportamientos compuestos para hacer tareas sencillas (necesita implementar action() y done()).
- OneShotBehaviour (Comportamiento de Un Tiro): como su nombre lo indica se ejecuta una sola vez.
- WakerBehaviour (Comportamiento Despertador): se ejecuta una sola vez despues de esperar un tiempo determinado.
- ReceiverBehaviour (Comportamiento Receptor): se ejecuta cuando un tipo especifico de mensaje ha llegado.
- CyclicBehaviour (Comportamiento Ciclico): se ejecuta indefinidamente hasta que se programa para detenerse.
- TickerBehaviour (Comportamiento Periódico): se ejecuta cada N milisegundos.
- ParallelBehaviour (Comportamiento en Paralelo): realiza procesos de manera concurrente, puede terminar cuando todos los subcomportamientos terminan, cuando cualquiera termina o cuando un numero especifico termina.
- SequentialBehaviour (Comportamiento Secuencial): ejecuta varios comportamientos de manera secuencial segun se programen y termina cuando el ultimo finaliza su tarea.
- FSMBehaviour (Comportamiento de Maquinas de Estado): permite definir una Maquina de Estados Finita a traves de subcomportamientos, compuesta por estados inicial, final, intermedios y transiciones, termina cuando el estado final es alcanzado.
Teniendo en cuenta que el AgenteRegulador posee un contenedor al cual debe aumentarle o disminuirle la temperatura dependiendo si esta se ha salido fuera de los limites, el agente verificara periodicamente las condiciones en las cuales se encuentra el contenedor. Estos son los detalles del contenedor :
- Un nombre que permite identificarlo de manera unica.
- Una temperatura minima y una maxima que equivalen al rango en el cual debe permanecer la temperatura;
- La temperatura en la cual se encuentra el contenedor.
- El intervalo o periodo en el cual se debe aumentar o disminuir la temperatura
- Una variable que nos indica si el contenedor esta encendido o apagado.
public class AgenteRegulador extends Agent{
private Contenedor contenedor;
private AgenteReguladorGui miGui;
public void setup() {
//codigo de inicializacion
}
public void iniciarCalentamiento(Contenedor contenedor) {
this.contenedor = contenedor;
contenedor.setNombre(this.getLocalName());
addBehaviour(new ComportamientoRegulador(this));
}
Cuando se llama al metodo iniciarCalentamiento(), este inicia los valores del contenedor y el comportamiento que realizara la tarea. Este comportamiento es del tipo periodico (TickerBehaviour) y el periodo sera el valor que haya ingresado el usuario enla interfaz, los valores se iniciailzan el el constructor en donde se llama al constructor de la superclase (ComportamientoRegulador --> TickerBehaviour).
public class ComportamientoRegulador extends TickerBehaviour {
ACLMessage msgRequest=null;
public ComportamientoRegulador(AgenteRegulador agent) {
super(agent, agent.getContenedor().getIntervalo());
}
El metodo onTick() es donde se ejecutara la tarea cada periodo.
Primero verifica si esta encendido aumenta la temperatura de lo contrario lo disminuye; luego sabe si necesita enviar los datos al AgenteInformante o al AgenteSupervisor segun sea el caso.
@Override
protected void onTick() {
System.out.println("contenedor " + contenedor.isEncendido() + "- " + contenedor.getTemperaturaActual());
if (contenedor.isEncendido()) {
contenedor.setTemperaturaActual(contenedor.getTemperaturaActual() + 1);
} else {
contenedor.setTemperaturaActual(contenedor.getTemperaturaActual() - 1);
}
msgRequest = myAgent.receive();
if (msgRequest != null) {
String contenido = msgRequest.getContent();
System.out.println("contenido Regulador " + contenido + " Sender " + msgRequest.getSender().getLocalName() + " cola " + myAgent.getCurQueueSize());
if (contenido.equals("envieDatos")) {
ACLMessage reply = msgRequest.createReply();
reply.setPerformative(ACLMessage.REQUEST);
String mensaje = "";
if (contenedor != null) {
mensaje = contenedor.getNombre();
mensaje += (";" + contenedor.getTemperaturaActual());
mensaje += (";" + contenedor.getTemperaturaMinima());
mensaje += (";" + contenedor.getTemperaturaMaxima());
mensaje += (";" + contenedor.isEncendido());
mensaje += (";" + contenedor.getIntervalo());
reply.setContent(mensaje);
myAgent.send(reply);
} else {
System.out.println("Contenedor Nulo");
}
} else if (contenido.equals("enciendase")) {
contenedor.setEncendido(true);
informarCambioDeEstado(msgRequest, myAgent);
} else {
contenedor.setEncendido(false);
informarCambioDeEstado(msgRequest, myAgent);
}
}
}
}
//Resto del codigo
}