From d9f8225feb1c187ea64c1de2a997bda4f0ae0f3d Mon Sep 17 00:00:00 2001
From: shinedday <shinedday@gmail.com>
Date: Wed, 8 Jun 2022 08:57:34 +0200
Subject: [PATCH] Version : IoTAMAK-0.0.7

Major change :
 * completly revamp the core structure

Add Async classes (Amas, Env, Agent) that can live without a scheduler
---
 dist/iotAmak-0.0.7-py3-none-any.whl           | Bin 0 -> 31645 bytes
 iotAmak/{tool => agent}/__init__.py           |   0
 iotAmak/agent/agent.py                        |  68 +++++++++++
 iotAmak/agent/async_agent.py                  |  57 +++++++++
 iotAmak/agent/async_communicating_agent.py    |  16 +++
 iotAmak/{agent.py => agent/base_agent.py}     | 111 ++++-------------
 .../base_communicating_agent.py}              |  15 +--
 iotAmak/agent/communicating_agent.py          |  16 +++
 iotAmak/{tool => agent}/mail.py               |   0
 iotAmak/amas/__init__.py                      |   0
 iotAmak/amas/amas.py                          |  79 ++++++++++++
 iotAmak/amas/async_amas.py                    | 114 ++++++++++++++++++
 iotAmak/{amas.py => amas/base_amas.py}        | 110 +++++------------
 iotAmak/base/__init__.py                      |   0
 iotAmak/base/async_controlable.py             |  92 ++++++++++++++
 iotAmak/{tool => base}/mqtt_client.py         |   0
 iotAmak/{tool => base}/schedulable.py         |   5 +-
 iotAmak/env/__init__.py                       |   0
 iotAmak/env/async_env.py                      |  36 ++++++
 iotAmak/env/base_env.py                       |  13 ++
 iotAmak/{ => env}/environment.py              |  19 +--
 iotAmak/ihm/__init__.py                       |   0
 iotAmak/{tool => ihm}/confi_reader.py         |   2 +-
 iotAmak/{ => ihm}/ihm.py                      |  12 +-
 iotAmak/scheduler/__init__.py                 |   0
 iotAmak/{ => scheduler}/scheduler.py          |   5 +-
 iotAmak/ssh_module/__init__.py                |   0
 iotAmak/{tool => ssh_module}/remote_client.py |   0
 iotAmak/{tool => ssh_module}/ssh_client.py    |  14 +--
 setup.py                                      |   2 +-
 30 files changed, 572 insertions(+), 214 deletions(-)
 create mode 100644 dist/iotAmak-0.0.7-py3-none-any.whl
 rename iotAmak/{tool => agent}/__init__.py (100%)
 create mode 100644 iotAmak/agent/agent.py
 create mode 100644 iotAmak/agent/async_agent.py
 create mode 100644 iotAmak/agent/async_communicating_agent.py
 rename iotAmak/{agent.py => agent/base_agent.py} (52%)
 rename iotAmak/{communicating_agent.py => agent/base_communicating_agent.py} (86%)
 create mode 100644 iotAmak/agent/communicating_agent.py
 rename iotAmak/{tool => agent}/mail.py (100%)
 create mode 100644 iotAmak/amas/__init__.py
 create mode 100644 iotAmak/amas/amas.py
 create mode 100644 iotAmak/amas/async_amas.py
 rename iotAmak/{amas.py => amas/base_amas.py} (63%)
 create mode 100644 iotAmak/base/__init__.py
 create mode 100644 iotAmak/base/async_controlable.py
 rename iotAmak/{tool => base}/mqtt_client.py (100%)
 rename iotAmak/{tool => base}/schedulable.py (89%)
 create mode 100644 iotAmak/env/__init__.py
 create mode 100644 iotAmak/env/async_env.py
 create mode 100644 iotAmak/env/base_env.py
 rename iotAmak/{ => env}/environment.py (83%)
 create mode 100644 iotAmak/ihm/__init__.py
 rename iotAmak/{tool => ihm}/confi_reader.py (90%)
 rename iotAmak/{ => ihm}/ihm.py (93%)
 create mode 100644 iotAmak/scheduler/__init__.py
 rename iotAmak/{ => scheduler}/scheduler.py (97%)
 create mode 100644 iotAmak/ssh_module/__init__.py
 rename iotAmak/{tool => ssh_module}/remote_client.py (100%)
 rename iotAmak/{tool => ssh_module}/ssh_client.py (91%)

diff --git a/dist/iotAmak-0.0.7-py3-none-any.whl b/dist/iotAmak-0.0.7-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..6b8729469c70282fe1274145a88acef11cfe9f1a
GIT binary patch
literal 31645
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
JU}(z&@c@6#pRxb|

literal 0
HcmV?d00001

diff --git a/iotAmak/tool/__init__.py b/iotAmak/agent/__init__.py
similarity index 100%
rename from iotAmak/tool/__init__.py
rename to iotAmak/agent/__init__.py
diff --git a/iotAmak/agent/agent.py b/iotAmak/agent/agent.py
new file mode 100644
index 0000000..4af7fb9
--- /dev/null
+++ b/iotAmak/agent/agent.py
@@ -0,0 +1,68 @@
+"""
+Agent class file
+"""
+import json
+import sys
+import pathlib
+from typing import Dict
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.base.schedulable import Schedulable
+from iotAmak.agent.base_agent import BaseAgent
+
+
+class Agent(Schedulable, BaseAgent):
+    """
+    base class for agent
+    """
+
+    def __init__(self, arguments: str) -> None:
+
+        arguments: Dict = json.loads(arguments)
+
+        broker_ip: str = arguments.get("broker_ip")
+        identifier: int = int(arguments.get("identifier"))
+        seed: int = int(arguments.get("seed"))
+        broker_username: str = str(arguments.get("broker_username"))
+        broker_password: str = str(arguments.get("broker_password"))
+
+        Schedulable.__init__(self, broker_ip, "Agent" + str(identifier), broker_username, broker_password)
+        BaseAgent.__init__(self, identifier, seed)
+
+        self.subscribe("scheduler/agent/wakeup", self.wake_up)
+
+        self.on_initialization()
+
+        self.publish("cycle_done", "")
+
+    def publish(self, topic: str, message) -> None:
+        """
+        publish a message on the topic
+        :param topic: str
+        :param message: content of the message
+        """
+        self.client.publish("agent/" + str(self.id) + "/" + topic, message)
+
+    def run(self) -> None:
+        """
+        Main method of the agent
+        """
+        while not self.exit_bool:
+
+            self.wait()
+            if self.exit_bool:
+                return
+
+            self.on_cycle_begin()
+
+            self.on_perceive()
+
+            self.on_decide()
+
+            self.on_act()
+
+            self.on_cycle_end()
+
+            self.publish("metric", str(self.send_metric()))
+            self.publish("cycle_done", "")
+            self.nbr_cycle += 1
diff --git a/iotAmak/agent/async_agent.py b/iotAmak/agent/async_agent.py
new file mode 100644
index 0000000..a2653d5
--- /dev/null
+++ b/iotAmak/agent/async_agent.py
@@ -0,0 +1,57 @@
+"""
+AsyncAgent class file
+"""
+import pathlib
+import sys
+import json
+from typing import Dict
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.base.async_controlable import AsyncControlable
+from iotAmak.agent.base_agent import BaseAgent
+
+
+class AsyncAgent(AsyncControlable, BaseAgent):
+    """
+    Async class for agent
+    """
+
+    def __init__(self, arguments: str) -> None:
+
+        arguments: Dict = json.loads(arguments)
+
+        broker_ip: str = arguments.get("broker_ip")
+        identifier: int = int(arguments.get("identifier"))
+        seed: int = int(arguments.get("seed"))
+        broker_username: str = str(arguments.get("broker_username"))
+        broker_password: str = str(arguments.get("broker_password"))
+        wait_delay: float = float(arguments.get("wait_delay"))
+
+        AsyncControlable.__init__(
+            self,
+            broker_ip,
+            "Agent" + str(identifier),
+            broker_username,
+            broker_password,
+            wait_delay
+        )
+        BaseAgent.__init__(self, identifier, seed)
+
+        self.on_initialization()
+
+    def publish(self, topic: str, message) -> None:
+        """
+        publish a message on the topic
+        :param topic: str
+        :param message: content of the message
+        """
+        self.client.publish("agent/" + str(self.id) + "/" + topic, message)
+
+    def behaviour(self) -> None:
+        self.on_cycle_begin()
+        self.on_perceive()
+        self.on_decide()
+        self.on_act()
+        self.on_cycle_end()
+        self.publish("metric", str(self.send_metric()))
+
diff --git a/iotAmak/agent/async_communicating_agent.py b/iotAmak/agent/async_communicating_agent.py
new file mode 100644
index 0000000..fb221b4
--- /dev/null
+++ b/iotAmak/agent/async_communicating_agent.py
@@ -0,0 +1,16 @@
+import pathlib
+import sys
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.agent.async_agent import AsyncAgent
+from iotAmak.agent.base_communicating_agent import BaseCommunicatingAgent
+
+
+class AsyncCommunicatingAgent(AsyncAgent, BaseCommunicatingAgent):
+    """
+    Agent class that can communicate
+    """
+
+    def __init__(self, arguments: str) -> None:
+        AsyncAgent.__init__(self, arguments)
+        BaseCommunicatingAgent.__init__(self)
diff --git a/iotAmak/agent.py b/iotAmak/agent/base_agent.py
similarity index 52%
rename from iotAmak/agent.py
rename to iotAmak/agent/base_agent.py
index 8ccb58e..4d31dd2 100644
--- a/iotAmak/agent.py
+++ b/iotAmak/agent/base_agent.py
@@ -1,140 +1,81 @@
 """
-Agent class file
+Base Agent class file
 """
-import json
 import random
 from ast import literal_eval
 from typing import Dict, List
 
-import sys
-import pathlib
 
-sys.path.insert(0, str(pathlib.Path(__file__).parent))
-
-from iotAmak.tool.schedulable import Schedulable
-
-
-class Agent(Schedulable):
+class BaseAgent:
     """
     base class for agent
     """
 
-    def __init__(self, arguments: str) -> None:
-
-        arguments: Dict = json.loads(arguments)
-
-        broker_ip: str = arguments.get("broker_ip")
-        identifier: int = int(arguments.get("identifier"))
-        seed: int = int(arguments.get("seed"))
-        broker_username: str = str(arguments.get("broker_username"))
-        broker_password: str = str(arguments.get("broker_password"))
-
+    def __init__(self, identifier: int, seed: int) -> None:
         self.id: int = identifier
-
         random.seed(seed + 10 + self.id)
 
-        Schedulable.__init__(self, broker_ip, "Agent" + str(self.id), broker_username, broker_password)
-
-        self.subscribe("scheduler/agent/wakeup", self.wake_up)
-
         self.neighbors: List[Dict] = []
         self.next_neighbors: List[Dict] = []
         self.subscribe("amas/agent/" + str(self.id) + "/neighbor", self.add_neighbor)
 
-        self.on_initialization()
-
-        self.publish("cycle_done", "")
-        print("init done")
-
     def on_initialization(self) -> None:
         """
         This method will be executed at the end of __init__()
         """
         pass
 
-    def add_neighbor(self, client, userdata, message) -> None:
-        """
-        Called when the agent, receive metrics
-        put the metric in a list that will be rad during on_perceive
-        param message: metric (dict) of the neighbor
-        """
-        result: Dict = literal_eval(message.payload.decode("utf-8"))
-        self.next_neighbors.append(result)
-
-    def log(self, message: str) -> None:
-        """
-        Convenient method to log things (will be printed in the amas's stdout
-        :param message:
-        """
-        self.client.publish(
-            "agent/" + str(self.id) + "/log",
-            "[AGENT] " + str(self.id) + " : " + message
-        )
-
-    def publish(self, topic: str, message) -> None:
-        """
-        publish a message on the topic
-        :param topic: str
-        :param message: content of the message
-        """
-        self.client.publish("agent/" + str(self.id) + "/" + topic, message)
-
     def on_cycle_begin(self) -> None:
         """
         This method will be executed at the start of each cycle
         """
-        self.log("on_cycle_begin")
+        pass
 
     def on_perceive(self) -> None:
         """
         Method that should be used to open the neighbor metrics and use them
         """
-        self.log("on_perceive")
+        pass
 
     def on_decide(self) -> None:
         """
         Should be override
         """
-        self.log("on_decide")
+        pass
 
     def on_act(self) -> None:
         """
         Should be override
         """
-        self.log("on_act")
+        pass
 
     def on_cycle_end(self) -> None:
         """
         This method will be executed at the end of each cycle
         """
-        self.log("on_cycle_end")
+        pass
 
-    def send_metric(self) -> Dict:
+    def add_neighbor(self, client, userdata, message) -> None:
         """
-        Should be override if the neighbor need to be aware of any other info, should be a dict
+        Called when the agent, receive metrics
+        put the metric in a list that will be rad during on_perceive
+        param message: metric (dict) of the neighbor
         """
-        return {"id": self.id}
+        result: Dict = literal_eval(message.payload.decode("utf-8"))
+        self.next_neighbors.append(result)
 
-    def run(self) -> None:
+    def log(self, message: str) -> None:
         """
-        Main method of the agent
+        Convenient method to log things (will be printed in the amas's stdout
+        :param message:
         """
-        while not self.exit_bool:
-
-            self.wait()
-            if self.exit_bool:
-                return
-
-            self.on_cycle_begin()
-
-            self.on_perceive()
-
-            self.on_decide()
-
-            self.on_act()
-
-            self.on_cycle_end()
+        self.client.publish(
+            "agent/" + str(self.id) + "/log",
+            "[AGENT] " + str(self.id) + " : " + message
+        )
 
-            self.publish("metric", str(self.send_metric()))
-            self.publish("cycle_done", "")
-            self.nbr_cycle += 1
+    def send_metric(self) -> Dict:
+        """
+        Should be override if the neighbor need to be aware of any other info, should be a dict
+        """
+        return {"id": self.id}
diff --git a/iotAmak/communicating_agent.py b/iotAmak/agent/base_communicating_agent.py
similarity index 86%
rename from iotAmak/communicating_agent.py
rename to iotAmak/agent/base_communicating_agent.py
index 0600ea9..81cc8d1 100644
--- a/iotAmak/communicating_agent.py
+++ b/iotAmak/agent/base_communicating_agent.py
@@ -4,20 +4,17 @@ import sys
 from ast import literal_eval
 from typing import List, Any
 
-sys.path.insert(0, str(pathlib.Path(__file__).parent))
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.agent.mail import Mail
 
-from iotAmak.agent import Agent
-from iotAmak.tool.mail import Mail
 
-
-class CommunicatingAgent(Agent):
+class BaseCommunicatingAgent:
     """
     Agent class that can communicate
     """
 
-    def __init__(self, arguments: str) -> None:
+    def __init__(self) -> None:
         self.mailbox: List[Mail] = []
-        Agent.__init__(self, arguments)
         self.subscribe("agent/" + str(self.id) + "/mail", self.receive_mail)
 
     def receive_mail(self, client, userdata, message) -> None:
@@ -57,7 +54,3 @@ class CommunicatingAgent(Agent):
         put the mail in the front of the mailbox
         """
         self.mailbox = [mail] + self.mailbox
-
-
-
-
diff --git a/iotAmak/agent/communicating_agent.py b/iotAmak/agent/communicating_agent.py
new file mode 100644
index 0000000..8cebdfa
--- /dev/null
+++ b/iotAmak/agent/communicating_agent.py
@@ -0,0 +1,16 @@
+import pathlib
+import sys
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.agent.agent import Agent
+from iotAmak.agent.base_communicating_agent import BaseCommunicatingAgent
+
+
+class CommunicatingAgent(Agent, BaseCommunicatingAgent):
+    """
+    Agent class that can communicate
+    """
+
+    def __init__(self, arguments: str) -> None:
+        Agent.__init__(self, arguments)
+        BaseCommunicatingAgent.__init__(self)
diff --git a/iotAmak/tool/mail.py b/iotAmak/agent/mail.py
similarity index 100%
rename from iotAmak/tool/mail.py
rename to iotAmak/agent/mail.py
diff --git a/iotAmak/amas/__init__.py b/iotAmak/amas/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/amas/amas.py b/iotAmak/amas/amas.py
new file mode 100644
index 0000000..391bdbb
--- /dev/null
+++ b/iotAmak/amas/amas.py
@@ -0,0 +1,79 @@
+"""
+Amas class
+"""
+import json
+from ast import literal_eval
+
+import sys
+import pathlib
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.ssh_module.remote_client import RemoteClient
+from iotAmak.base.schedulable import Schedulable
+from iotAmak.amas.base_amas import BaseAmas
+
+
+class Amas(Schedulable, BaseAmas):
+    """
+    Amas class
+    """
+
+    def __init__(self, arguments: str) -> None:
+
+        arguments = json.loads(arguments)
+
+        broker_ip: str = arguments.get("broker_ip")
+        clients: str = arguments.get("clients")
+        seed: int = int(arguments.get("seed"))
+        broker_username: str = str(arguments.get("broker_username"))
+        broker_password: str = str(arguments.get("broker_password"))
+        iot_path: str = str(arguments.get("iot_path"))
+        true_client = [RemoteClient(i.get("hostname"), i.get("user"), i.get("password")) for i in literal_eval(clients)]
+
+        Schedulable.__init__(self, broker_ip, "Amas", broker_username, broker_password)
+        self.subscribe("scheduler/schedulable/wakeup", self.wake_up)
+        BaseAmas.__init__(self,
+                          broker_ip,
+                          broker_username,
+                          broker_password,
+                          seed,
+                          iot_path,
+                          true_client)
+
+        self.client.publish("amas/action_done", "")
+
+    def on_cycle_begin(self) -> None:
+        """
+        This method will be executed at the start of each cycle
+        """
+        pass
+
+    def on_cycle_end(self) -> None:
+        """
+        This method will be executed at the end of each cycle
+        """
+        pass
+
+    def run(self) -> None:
+        """
+        Main function of the amas class
+        """
+        self.push_agent()
+
+        while not self.exit_bool:
+
+            self.wait()
+            if self.exit_bool:
+                return
+
+            self.publish("amas/all_metric", str(self.agents_metric))
+            self.on_cycle_begin()
+            self.client.publish("amas/action_done", "")
+
+            # agent cycle
+
+            self.wait()
+            self.on_cycle_end()
+            self.client.publish("amas/action_done", "")
+
+            self.nbr_cycle += 1
diff --git a/iotAmak/amas/async_amas.py b/iotAmak/amas/async_amas.py
new file mode 100644
index 0000000..34abb21
--- /dev/null
+++ b/iotAmak/amas/async_amas.py
@@ -0,0 +1,114 @@
+import pathlib
+import sys
+import json
+from ast import literal_eval
+from typing import List
+
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.amas.base_amas import BaseAmas
+from iotAmak.base.async_controlable import AsyncControlable
+from iotAmak.ssh_module.remote_client import RemoteClient
+from iotAmak.ssh_module.ssh_client import Cmd
+
+
+class AsyncAmas(AsyncControlable, BaseAmas):
+    """
+    Amas class
+    """
+
+    def __init__(self, arguments: str) -> None:
+
+        arguments = json.loads(arguments)
+
+        broker_ip: str = arguments.get("broker_ip")
+        clients: str = arguments.get("clients")
+        seed: int = int(arguments.get("seed"))
+        broker_username: str = str(arguments.get("broker_username"))
+        broker_password: str = str(arguments.get("broker_password"))
+        iot_path: str = str(arguments.get("iot_path"))
+        wait_delay: float = float(arguments.get("wait_delay"))
+
+        true_client = [RemoteClient(i.get("hostname"), i.get("user"), i.get("password")) for i in literal_eval(clients)]
+
+        AsyncControlable.__init__(
+            self,
+            broker_ip,
+            "Amas",
+            broker_username,
+            broker_password,
+            wait_delay
+        )
+        BaseAmas.__init__(self,
+                          broker_ip,
+                          broker_username,
+                          broker_password,
+                          seed,
+                          iot_path,
+                          true_client)
+
+        self.push_agent()
+
+    def on_metric(self) -> None:
+        """
+        This method will be executed everytime a metric is send
+        """
+        pass
+
+    def add_agent(
+            self,
+            experience_name: str,
+            client_ip: str = None,
+            agent_name: str = "agent.py",
+            args: List = None
+    ) -> None:
+        """
+        Function that need to be called to create a new agent
+        :param experience_name: name of the experience folder
+        :param client_ip: if the agent should be created in a specific device, you can specify an ip address,
+        otherwise the Amas will try to share the work between the devices
+        :param agent_name: if using multiple kind of agent, you can specify the relative path in the experiment
+        directory to the agent file to use
+        :param args: if any argument is needed to initiate the new agent
+        :return: None
+        """
+        if args is None:
+            args = []
+
+        arg_dict = {
+            "broker_ip": str(self.broker_ip),
+            "seed": self.seed,
+            "identifier": self.next_id,
+            "broker_username": self.broker_username,
+            "broker_password": self.broker_password,
+            "wait_delay": self.wait_delay
+        }
+
+        command = "nohup python "
+        command += "\'" + self.iot_path + experience_name + "/" + agent_name + "\' \'"
+        command += json.dumps(arg_dict) + "\' "
+        for arg in args:
+            command += str(arg) + " "
+        command += "&"
+
+        if client_ip is None:
+            # find the most suitable pi
+            i_min = 0
+            for elem in range(len(self.clients)):
+                if len(self.agents_cmd[i_min]) > len(self.agents_cmd[elem]):
+                    i_min = elem
+            self.agents_cmd[i_min].append(Cmd(command))
+        else:
+            have_found = False
+            for i_client in range(len(self.clients)):
+                if self.clients[i_client].hostname == client_ip:
+                    self.agents_cmd[i_client].append(Cmd(command))
+                    have_found = True
+                    break
+            if not have_found:
+                self.agents_cmd[0].append(Cmd(command))
+
+        self.subscribe("agent/" + str(self.next_id) + "/metric", self.agent_metric)
+
+        self.client.publish("amas/agent/new", self.next_id)
+        self.next_id += 1
\ No newline at end of file
diff --git a/iotAmak/amas.py b/iotAmak/amas/base_amas.py
similarity index 63%
rename from iotAmak/amas.py
rename to iotAmak/amas/base_amas.py
index d335985..c3da4e0 100644
--- a/iotAmak/amas.py
+++ b/iotAmak/amas/base_amas.py
@@ -1,56 +1,48 @@
-"""
-Amas class
-"""
 import json
-from ast import literal_eval
-from typing import List, Dict
-
+import random
 import sys
 import pathlib
-import random
-
-sys.path.insert(0, str(pathlib.Path(__file__).parent))
-
-from iotAmak.tool.remote_client import RemoteClient
-from iotAmak.tool.schedulable import Schedulable
-from iotAmak.tool.ssh_client import SSHClient, Cmd
+from ast import literal_eval
+from typing import List, Dict
 
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.ssh_module.ssh_client import SSHClient, Cmd
+from iotAmak.ssh_module.remote_client import RemoteClient
 
-class Amas(Schedulable, SSHClient):
-    """
-    Amas class
-    """
 
-    def __init__(self, arguments: str) -> None:
+class BaseAmas(SSHClient):
 
-        arguments = json.loads(arguments)
+    def __init__(
+            self,
+            broker_ip: str,
+            broker_username: str,
+            broker_password: str,
+            seed: int,
+            iot_path: str,
+            clients: List[RemoteClient]
+    ):
+        self.broker_ip: str = broker_ip
+        self.broker_username: str = broker_username
+        self.broker_password: str = broker_password
 
-        self.broker_ip: str = arguments.get("broker_ip")
-        clients: str = arguments.get("clients")
-        self.seed: int = int(arguments.get("seed"))
-        self.broker_username: str = str(arguments.get("broker_username"))
-        self.broker_password: str = str(arguments.get("broker_password"))
-        iot_path: str = str(arguments.get("iot_path"))
+        self.next_id: int = 0
 
+        self.seed: int = seed
         random.seed(self.seed)
 
-        Schedulable.__init__(self, self.broker_ip, "Amas", self.broker_username, self.broker_password)
+        self.agents_cmd: List[List[Cmd]] = [[] for _ in range(len(clients))]
 
-        true_client = [RemoteClient(i.get("hostname"), i.get("user"), i.get("password")) for i in literal_eval(clients)]
-
-        SSHClient.__init__(self, true_client, iot_path)
-
-        self.subscribe("scheduler/schedulable/wakeup", self.wake_up)
-
-        self.next_id: int = 0
-
-        self.agents_cmd: List[List[Cmd]] = [[] for _ in range(len(self.clients))]
+        SSHClient.__init__(self, clients, iot_path)
 
         self.on_initialization()
         self.on_initial_agents_creation()
         self.agents_metric: List[Dict] = [{} for _ in range(self.next_id)]
 
-        self.client.publish("amas/action_done", "")
+    def on_initialization(self) -> None:
+        """
+        This method will be executed at the end of __init__()
+        """
+        pass
 
     def on_initial_agents_creation(self) -> None:
         """
@@ -83,11 +75,11 @@ class Amas(Schedulable, SSHClient):
             "seed": self.seed,
             "identifier": self.next_id,
             "broker_username": self.broker_username,
-            "broker_password":  self.broker_password
+            "broker_password": self.broker_password
         }
 
         command = "nohup python "
-        command += "\'" + self.iot_path + experience_name + "/"+agent_name+"\' \'"
+        command += "\'" + self.iot_path + experience_name + "/" + agent_name + "\' \'"
         command += json.dumps(arg_dict) + "\' "
         for arg in args:
             command += str(arg) + " "
@@ -138,45 +130,3 @@ class Amas(Schedulable, SSHClient):
         result = literal_eval(message.payload.decode("utf-8"))
         agent_id = result.get("id")
         self.agents_metric[agent_id] = result
-
-    def on_initialization(self) -> None:
-        """
-        This method will be executed at the end of __init__()
-        """
-        pass
-
-    def on_cycle_begin(self) -> None:
-        """
-        This method will be executed at the start of each cycle
-        """
-        pass
-
-    def on_cycle_end(self) -> None:
-        """
-        This method will be executed at the end of each cycle
-        """
-        pass
-
-    def run(self) -> None:
-        """
-        Main function of the amas class
-        """
-        self.push_agent()
-
-        while not self.exit_bool:
-
-            self.wait()
-            if self.exit_bool:
-                return
-
-            self.publish("amas/all_metric", str(self.agents_metric))
-            self.on_cycle_begin()
-            self.client.publish("amas/action_done", "")
-
-            # agent cycle
-
-            self.wait()
-            self.on_cycle_end()
-            self.client.publish("amas/action_done", "")
-
-            self.nbr_cycle += 1
diff --git a/iotAmak/base/__init__.py b/iotAmak/base/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/base/async_controlable.py b/iotAmak/base/async_controlable.py
new file mode 100644
index 0000000..c0c71b8
--- /dev/null
+++ b/iotAmak/base/async_controlable.py
@@ -0,0 +1,92 @@
+"""
+MQTT client class file
+"""
+import sys
+import pathlib
+from threading import Semaphore
+from time import sleep
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.base.mqtt_client import MqttClient
+
+
+class AsyncControlable(MqttClient):
+    """
+    Base class to any instance that need to interact with the broker
+    """
+
+    def __init__(
+            self,
+            broker_ip: str,
+            client_id: str,
+            broker_username: str,
+            broker_password: str,
+            wait_delay: float
+    ):
+        MqttClient.__init__(self, broker_ip, client_id, broker_username, broker_password)
+
+        # exit
+        self.exit_bool: bool = False
+        self.subscribe("ihm/exit", self.exit_procedure)
+
+        # pause
+        self.paused: bool = True
+        self.pause_semaphore = Semaphore(0)
+        self.subscribe("ihm/pause", self.pause)
+        self.subscribe("ihm/unpause", self.unpause)
+
+        # time to wait
+        self.wait_delay: float = wait_delay
+
+        self.nbr_cycle: int = 0
+
+    def exit_procedure(self, client, userdata, message) -> None:
+        """
+        Called by the Ihm to exit as soon as possible
+        """
+        self.exit_bool = True
+
+    def pause(self, client, userdata, message) -> None:
+        """
+        Function called when the IHM pause the scheduler
+        """
+        self.paused = True
+
+    def unpause(self, client, userdata, message) -> None:
+        """
+        Function called when the IHM unpause the scheduler
+        """
+        self.paused = False
+        self.pause_semaphore.release()
+
+    def wait(self) -> None:
+        """
+        If the element is paused, wait until unpause was received
+        """
+        if not self.paused:
+            return
+        self.pause_semaphore.acquire()
+
+    def behaviour(self) -> None:
+        """
+        method to override
+        """
+        return
+
+    def run(self) -> None:
+        """
+        Main method of the client
+        """
+
+        while not self.exit_bool:
+            # wait to be unpause
+            self.wait()
+
+            # check the need to exit
+            if self.exit_bool:
+                return
+
+            self.behaviour()
+
+            sleep(self.wait_delay)
+            self.nbr_cycle += 1
diff --git a/iotAmak/tool/mqtt_client.py b/iotAmak/base/mqtt_client.py
similarity index 100%
rename from iotAmak/tool/mqtt_client.py
rename to iotAmak/base/mqtt_client.py
diff --git a/iotAmak/tool/schedulable.py b/iotAmak/base/schedulable.py
similarity index 89%
rename from iotAmak/tool/schedulable.py
rename to iotAmak/base/schedulable.py
index 0a27304..33ec1ff 100644
--- a/iotAmak/tool/schedulable.py
+++ b/iotAmak/base/schedulable.py
@@ -8,7 +8,7 @@ import threading
 
 sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
 
-from iotAmak.tool.mqtt_client import MqttClient
+from iotAmak.base.mqtt_client import MqttClient
 
 
 class Schedulable(MqttClient):
@@ -31,15 +31,12 @@ class Schedulable(MqttClient):
         Called by the scheduler to wake up the schedulable
         """
         self.semaphore.release()
-        # print("Waked up")
 
     def wait(self) -> None:
         """
         Basic wait method
         """
-        # print("Waiting")
         self.semaphore.acquire()
-        # print("End wait")
 
     def exit_procedure(self, client, userdata, message) -> None:
         """
diff --git a/iotAmak/env/__init__.py b/iotAmak/env/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/env/async_env.py b/iotAmak/env/async_env.py
new file mode 100644
index 0000000..6d0fced
--- /dev/null
+++ b/iotAmak/env/async_env.py
@@ -0,0 +1,36 @@
+"""
+Environment class
+"""
+import json
+import sys
+import pathlib
+
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.env.base_env import BaseEnv
+from iotAmak.base.async_controlable import AsyncControlable
+
+
+class AsyncEnvironment(BaseEnv, AsyncControlable):
+    """
+    Environment class
+    """
+
+    def __init__(self, arguments: str) -> None:
+
+        arguments = json.loads(arguments)
+
+        broker_ip: str = arguments.get("broker_ip")
+        seed: int = int(arguments.get("seed"))
+        broker_username: str = str(arguments.get("broker_username"))
+        broker_password: str = str(arguments.get("broker_password"))
+        wait_delay: float = float(arguments.get("wait_delay"))
+
+        AsyncControlable.__init__(
+            self,
+            broker_ip,
+            "Env",
+            broker_username,
+            broker_password,
+            wait_delay
+        )
+        BaseEnv.__init__(self, seed)
diff --git a/iotAmak/env/base_env.py b/iotAmak/env/base_env.py
new file mode 100644
index 0000000..905f8fe
--- /dev/null
+++ b/iotAmak/env/base_env.py
@@ -0,0 +1,13 @@
+import random
+
+
+class BaseEnv:
+    def __init__(self, seed: int) -> None:
+        random.seed(seed + 1)
+        self.on_initialization()
+
+    def on_initialization(self) -> None:
+        """
+        This method will be executed at the end of __init__()
+        """
+        pass
diff --git a/iotAmak/environment.py b/iotAmak/env/environment.py
similarity index 83%
rename from iotAmak/environment.py
rename to iotAmak/env/environment.py
index b054cbc..68bbbc1 100644
--- a/iotAmak/environment.py
+++ b/iotAmak/env/environment.py
@@ -7,11 +7,11 @@ import sys
 import pathlib
 
 sys.path.insert(0, str(pathlib.Path(__file__).parent))
+from iotAmak.env.base_env import BaseEnv
+from iotAmak.base.schedulable import Schedulable
 
-from iotAmak.tool.schedulable import Schedulable
 
-
-class Environment(Schedulable):
+class Environment(Schedulable, BaseEnv):
     """
     Environment class
     """
@@ -25,22 +25,11 @@ class Environment(Schedulable):
         broker_username: str = str(arguments.get("broker_username"))
         broker_password: str = str(arguments.get("broker_password"))
 
-        random.seed(seed + 1)
-
         Schedulable.__init__(self, broker_ip, "Env", broker_username, broker_password)
-
         self.subscribe("scheduler/schedulable/wakeup", self.wake_up)
-
-        self.on_initialization()
-
+        BaseEnv.__init__(self, seed)
         self.client.publish("env/action_done", "")
 
-    def on_initialization(self) -> None:
-        """
-        This method will be executed at the end of __init__()
-        """
-        pass
-
     def on_cycle_begin(self) -> None:
         """
         This method will be executed at the start of each cycle
diff --git a/iotAmak/ihm/__init__.py b/iotAmak/ihm/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/tool/confi_reader.py b/iotAmak/ihm/confi_reader.py
similarity index 90%
rename from iotAmak/tool/confi_reader.py
rename to iotAmak/ihm/confi_reader.py
index 5070707..f761a9c 100644
--- a/iotAmak/tool/confi_reader.py
+++ b/iotAmak/ihm/confi_reader.py
@@ -4,7 +4,7 @@ import pathlib
 
 sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
 
-from iotAmak.tool.remote_client import RemoteClient
+from iotAmak.ssh_module.remote_client import RemoteClient
 
 
 def read_ssh(path):
diff --git a/iotAmak/ihm.py b/iotAmak/ihm/ihm.py
similarity index 93%
rename from iotAmak/ihm.py
rename to iotAmak/ihm/ihm.py
index 11b4f19..5032f41 100644
--- a/iotAmak/ihm.py
+++ b/iotAmak/ihm/ihm.py
@@ -9,9 +9,9 @@ import pathlib
 
 sys.path.insert(0, str(pathlib.Path(__file__).parent))
 
-from iotAmak.tool.confi_reader import read_ssh, read_broker
-from iotAmak.tool.mqtt_client import MqttClient
-from iotAmak.tool.ssh_client import SSHClient, Cmd
+from iotAmak.ihm.confi_reader import read_ssh, read_broker
+from iotAmak.base.mqtt_client import MqttClient
+from iotAmak.ssh_module.ssh_client import SSHClient, Cmd
 
 
 class Ihm(MqttClient, SSHClient):
@@ -29,10 +29,10 @@ class Ihm(MqttClient, SSHClient):
     def loading(self):
         print("[LOADING]")
         print("Check experiment:")
-        print(" | -> agent.py : ", path.exists("./agent.py"))
-        print(" | -> amas.py : ", path.exists("./amas.py"))
+        print(" | -> agent.py : ", path.exists("../agent/agent.py"))
+        print(" | -> amas.py : ", path.exists("../amas/amas.py"))
         print(" | -> env.py : ", path.exists("./env.py"))
-        if path.exists("./agent.py") and path.exists("./amas.py") and path.exists("./env.py"):
+        if path.exists("../agent/agent.py") and path.exists("../amas/amas.py") and path.exists("./env.py"):
             self.experiment_loaded = True
             print("Experiment loaded")
         else:
diff --git a/iotAmak/scheduler/__init__.py b/iotAmak/scheduler/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/scheduler.py b/iotAmak/scheduler/scheduler.py
similarity index 97%
rename from iotAmak/scheduler.py
rename to iotAmak/scheduler/scheduler.py
index 19e21ea..d5f2237 100644
--- a/iotAmak/scheduler.py
+++ b/iotAmak/scheduler/scheduler.py
@@ -7,9 +7,8 @@ from time import sleep, time
 import sys
 import pathlib
 
-sys.path.insert(0, str(pathlib.Path(__file__).parent))
-
-from iotAmak.tool.schedulable import Schedulable
+sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
+from iotAmak.base.schedulable import Schedulable
 
 
 class Scheduler(Schedulable):
diff --git a/iotAmak/ssh_module/__init__.py b/iotAmak/ssh_module/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/iotAmak/tool/remote_client.py b/iotAmak/ssh_module/remote_client.py
similarity index 100%
rename from iotAmak/tool/remote_client.py
rename to iotAmak/ssh_module/remote_client.py
diff --git a/iotAmak/tool/ssh_client.py b/iotAmak/ssh_module/ssh_client.py
similarity index 91%
rename from iotAmak/tool/ssh_client.py
rename to iotAmak/ssh_module/ssh_client.py
index 858df6d..a208519 100644
--- a/iotAmak/tool/ssh_client.py
+++ b/iotAmak/ssh_module/ssh_client.py
@@ -9,8 +9,7 @@ from pexpect import pxssh
 
 sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
 
-from iotAmak.tool.remote_client import RemoteClient
-
+from iotAmak.ssh_module.remote_client import RemoteClient
 
 class Cmd:
 
@@ -19,15 +18,14 @@ class Cmd:
         self.do_print = do_print
         self.prefix = prefix
 
-
 class SSHClient:
 
     def __init__(self, clients: List[RemoteClient], iot_path: str):
-        self.clients = clients
-        self.iot_path = iot_path
+        self.clients: List[RemoteClient] = clients
+        self.iot_path: str = iot_path
 
-    def run_cmd(self, client: int, cmd: list, repeat: bool = False) -> list[str]:
-        ret = []
+    def run_cmd(self, client: int, cmd: list, repeat: bool = False) -> List[str]:
+        ret: List[str] = []
         try:
             s = pxssh.pxssh()
             dest = self.clients[client]
@@ -48,7 +46,7 @@ class SSHClient:
                 self.run_cmd(client, cmd, True)
         return ret
 
-    def update(self, experiment_name, path_to_experiment):
+    def update(self, experiment_name: str, path_to_experiment: str):
         for client in self.clients:
             transport = paramiko.Transport((client.hostname, 22))
             transport.connect(username=client.user, password=client.password)
diff --git a/setup.py b/setup.py
index c884117..fc4ebef 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
 setup(
     name='iotAmak',
     packages=find_packages(),
-    version='0.0.6',
+    version='0.0.7',
     description='AmakFramework in python',
     author='SMAC - GOYON Sebastien',
     install_requires=[
-- 
GitLab