diff --git a/README.md b/README.md index b102b6bad92712d0b1274a6957f048058b5355b9..a5a4a618b793787b85c16359319ebec30303fa91 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,21 @@ # IoTAMAK-core +- [IoTAMAK-core](#iotamak-core) +- [Reseau](#reseau) +- [Random note](#random-note) +- [Agent Cycle](#agent-cycle) +- [Shared work](#shared-work) +- [Wait function](#wait-function) +- [Experience format](#experience-format) +- [Topics](#topics) + - [Agent](#agent) + - [Scheduler](#scheduler) + - [Amas](#amas) + - [Env](#env) +- [Mosquitto (Windows)](#mosquitto-windows) +- [Mosquitto (Linux) Didn't work](#mosquitto-linux-didnt-work) + + requirement : * paho-mqtt @@ -22,7 +38,7 @@ SSH activé avec hostname et mdp WSL (pour pouvoir démarer l'amas) -# ? +# Random note Start procédure : 1. start broker @@ -142,6 +158,27 @@ while not condition: Solution a trouvé ! +# Experience format + +``` +/experienceNameFolder/ + /agent.py + /amas.py + /env.py + /... +``` + +Les noms amas, agent et env sont obligatoire et ne peuvent pas etre modifier + +Ils doivent contenir un code de la sorte : +```py +if __name__ == '__main__': + a = MyAgent(int(sys.argv[1]), ...) #MyAmas() MyEnv() + a.run() +``` + +Pour ajouter des attributs a l'initialisation aux agents il suffit de rajouter des `type(sys.argv[x])`. + # Topics ## Agent diff --git a/amas.py b/amas.py index d11c697974fb062758bbd8d6fabfbaab61fcaf16..35e947d9aaf22b22b8065a2a19eb3b1653b44e28 100644 --- a/amas.py +++ b/amas.py @@ -5,15 +5,17 @@ from ast import literal_eval from pexpect import pxssh from schedulable import Schedulable +from ssh_client import SSHClient, Cmd -class Amas(Schedulable): +class Amas(Schedulable, SSHClient): """ Amas class """ def __init__(self): Schedulable.__init__(self, client_id="Amas") + SSHClient.__init__(self) self.subscribe("scheduler/schedulable/wakeup", self.wake_up) @@ -29,28 +31,20 @@ class Amas(Schedulable): def on_initial_agents_creation(self): pass - def add_agent(self): - try: - s = pxssh.pxssh() - hostname = "192.168.123.18" - username = "pi" - password = "raspberry" - s.login(hostname, username, password) - - s.sendline('nohup python \"Desktop/mqtt_goyon/iotamak-core/agent.py\" ' + str(self.next_id) + " &") - s.prompt() - print(s.before.decode('utf-8')) + def add_agent(self, agent_to_create): + agents = [] + for _ in range(agent_to_create): + agents.append(Cmd( + cmd='nohup python \"Desktop/mqtt_goyon/iotamak-core/agent.py\" ' + str(self.next_id) + " &" + )) self.subscribe("agent/" + str(self.next_id) + "/metric", self.agent_metric) self.subscribe("agent/" + str(self.next_id) + "/log", self.agent_log) self.client.publish("amas/agent/new", self.next_id) self.next_id += 1 - s.logout() - except pxssh.ExceptionPxssh as e: - print("pxssh failed on login.") - print(e) + self.run_cmd(0, agents) def agent_log(self, client, userdata, message): print("[Log] " + str(message.payload.decode("utf-8")) + " on topic " + message.topic) diff --git a/ihm.py b/ihm.py index f7300fcad5257262070b53eae013e302ec4e2c1c..82ece822684ace85b10419a90063b6183b90ad82 100644 --- a/ihm.py +++ b/ihm.py @@ -1,28 +1,106 @@ +import subprocess +import sys +from os import path from time import sleep from mqtt_client import MqttClient +from ssh_client import SSHClient, Cmd, RemoteClient +from update import VersionManager -class Ihm(MqttClient): +class Ihm(MqttClient, SSHClient): def __init__(self): MqttClient.__init__(self, "Ihm") + SSHClient.__init__(self) def run(self): exit_bool = False + experiment_folder = "" while not exit_bool: - cmd = input() + print("\n") + cmd = input(">") if cmd.lower() == "exit": self.client.publish("ihm/exit") exit_bool = True + if cmd.lower() == "kill": + + commands = [ + Cmd( + cmd="ps -ef | grep 'python '", + prefix="[BEFORE]" + ), + Cmd( + cmd="for pid in $(ps -ef | grep 'python ' | awk '{print $2}'); do kill $pid; done", + do_print=False + ), + Cmd( + cmd="ps -ef | grep 'python '", + prefix="[AFTER]" + ) + ] + + for i_client in range(len(self.clients)): + print("Hostname :", self.clients[i_client].hostname, " User :", self.clients[i_client].user) + self.run_cmd(i_client, commands) + + if cmd.lower() == "agent": + commands = [ + Cmd( + cmd="ps -ef | grep 'python '" + )] + + for i_client in range(len(self.clients)): + print("Hostname :", self.clients[i_client].hostname, " User :", self.clients[i_client].user) + self.run_cmd(i_client, commands) + + if cmd.lower() == "update": + r = RemoteClient("192.168.105.18", "pi", "raspberry") + updater = VersionManager(r) + updater.update() + + if cmd.lower() == "load": + print("Give Path to experiment folder(relavive)") + cmd = input(">") + # check if exist + print("Check experiment:") + print(" | -> folder : ", path.exists(cmd)) + print(" | -> agent.py : ", path.exists(cmd + "/agent.py")) + print(" | -> amas.py : ", path.exists(cmd + "/amas.py")) + print(" | -> env.py : ", path.exists(cmd + "/env.py")) + if path.exists(cmd) and path.exists(cmd + "/agent.py") and path.exists( + cmd + "/amas.py") and path.exists(cmd + "/env.py"): + experiment_folder = cmd + print("Experiment loaded") + + if cmd.lower() == "start": + + if experiment_folder != "": + + # choose exec + + # start subprocess scheduler + subprocess.Popen([sys.executable, 'scheduler.py']) + # wait(1) + # start subprocess amas + subprocess.Popen([sys.executable, experiment_folder+'/amas.py']) + # start subprocess env + subprocess.Popen([sys.executable, experiment_folder+'/env.py']) + + if cmd.lower() == "pause": + pass + + if cmd.lower() == "unpause": + pass + sleep(2) if __name__ == '__main__': a = Ihm() - a.run() \ No newline at end of file + a.run() diff --git a/mqtt_client.py b/mqtt_client.py index f7f2dfe84b44573fbaa1ed7a7bb4fc0e7ba8bdae..3c565787f9574bfe06a9afcb608a262426859f2a 100644 --- a/mqtt_client.py +++ b/mqtt_client.py @@ -6,7 +6,7 @@ class MqttClient: def __init__(self, client_id: str = None): self.client = Client(client_id=client_id) self.client.username_pw_set(username="goyon", password="mosquitto") - self.client.connect("192.168.199.209", 1883, 60) + self.client.connect("192.168.105.209", 1883, 60) self.client.loop_start() def subscribe(self, topic, fun): diff --git a/philosophers/phi_agent.py b/philosophers/agent.py similarity index 98% rename from philosophers/phi_agent.py rename to philosophers/agent.py index 37340d7bb9bd5d5488c3da0b34325b27bfef011c..a939a3aed4abc926675041ff30b969a23fcc109a 100644 --- a/philosophers/phi_agent.py +++ b/philosophers/agent.py @@ -63,7 +63,7 @@ class PhiAgent(Agent): self.fork_wait = True def on_decide(self): - # super().on_decide() + super().on_decide() if self.right_fork.tanken_by == -1: self.ask_spoon(False) @@ -78,7 +78,7 @@ class PhiAgent(Agent): self.ask_spoon(True) def on_act(self): - # super().on_act() + super().on_act() if self.state == 0: self.log("Is Thinking") diff --git a/philosophers/amas.py b/philosophers/amas.py new file mode 100644 index 0000000000000000000000000000000000000000..e5bc0edf81a7305de43a334a357e8253ef987283 --- /dev/null +++ b/philosophers/amas.py @@ -0,0 +1,37 @@ +import sys +import pathlib + +sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) + +from amas import Amas +from ssh_client import Cmd + +class PhiAmas(Amas): + + def __init__(self, nbr_agent): + self.agent_to_create = nbr_agent + super().__init__() + + def on_initial_agents_creation(self): + + self.add_agent(self.agent_to_create) + + def add_agent(self, agent_to_create): + + agents = [] + for _ in range(agent_to_create): + agents.append(Cmd( + cmd='nohup python \"Desktop/mqtt_goyon/iotamak-core/philosophers/agent.py\" ' + str(self.next_id) + + " " + str(self.agent_to_create) + " &" + )) + self.subscribe("agent/" + str(self.next_id) + "/log", self.agent_log) + + self.client.publish("amas/agent/new", self.next_id) + self.next_id += 1 + + self.run_cmd(0, agents) + # self.run_cmd(1, agents[2:]) + +if __name__ == '__main__': + s = PhiAmas(3) + s.run() \ No newline at end of file diff --git a/philosophers/phi_env.py b/philosophers/env.py similarity index 100% rename from philosophers/phi_env.py rename to philosophers/env.py diff --git a/philosophers/phi_amas.py b/philosophers/phi_amas.py deleted file mode 100644 index ab9679da6b0ed2e23b0009c44c7bac6e35eb3af4..0000000000000000000000000000000000000000 --- a/philosophers/phi_amas.py +++ /dev/null @@ -1,46 +0,0 @@ -from pexpect import pxssh - -import sys -import pathlib - -sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) - -from amas import Amas - -class PhiAmas(Amas): - - def __init__(self, nbr_agent): - self.agent_to_create = nbr_agent - super().__init__() - - def on_initial_agents_creation(self): - - for _ in range(self.agent_to_create): - self.add_agent() - - def add_agent(self): - try: - s = pxssh.pxssh() - hostname = "192.168.199.18" - username = "pi" - password = "raspberry" - s.login(hostname, username, password) - - s.sendline('nohup python \"Desktop/mqtt_goyon/iotamak-core/philosophers/phi_agent.py\" ' + str(self.next_id) - + " " + str(self.agent_to_create) + " &") - s.prompt() - print(s.before.decode('utf-8')) - - self.subscribe("agent/" + str(self.next_id) + "/log", self.agent_log) - - self.client.publish("amas/agent/new", self.next_id) - self.next_id += 1 - - s.logout() - except pxssh.ExceptionPxssh as e: - print("pxssh failed on login.") - print(e) - -if __name__ == '__main__': - s = PhiAmas(3) - s.run() \ No newline at end of file diff --git a/schedulable.py b/schedulable.py index 7b1fe6fa26c070b3ec3b6c1477ed6a1c609da5ad..16a2150cacae02a6f620168a90490d516818e808 100644 --- a/schedulable.py +++ b/schedulable.py @@ -23,7 +23,7 @@ class Schedulable(MqttClient): def wake_up(self, client, userdata, message): self.wake_up_token += 1 - print("Waked up") + # print("Waked up") def wait(self): # print("Waiting") diff --git a/scheduler.py b/scheduler.py index 888c10e67712bab28c167b78c10753f232c7b35b..0995b4322cc6ffb32f384117953b6ff166043fd7 100644 --- a/scheduler.py +++ b/scheduler.py @@ -95,7 +95,7 @@ class Scheduler(Schedulable): self.last_part() # sleep(self.sleep_between_cycle) - input() + # input() self.nbr_cycle += 1 self.client.publish("scheduler/schedulable/wakeup", "") diff --git a/ssh_client.py b/ssh_client.py new file mode 100644 index 0000000000000000000000000000000000000000..47faa58c9d180ff38ea510c60c741ee03c0957f6 --- /dev/null +++ b/ssh_client.py @@ -0,0 +1,43 @@ +from pexpect import pxssh + + +class Cmd: + + def __init__(self, cmd: str, do_print: bool = True, prefix: str = ""): + self.cmd = cmd + self.do_print = do_print + self.prefix = prefix + + +class RemoteClient: + + def __init__(self, hostname, user, password): + self.hostname = hostname + self.user = user + self.password = password + + +class SSHClient: + + def __init__(self): + self.clients = [ + RemoteClient("192.168.105.18", "pi", "raspberry")# , + # RemoteClient("192.168.199.75", "pi", "raspberry") + ] + + def run_cmd(self, client: int, cmd: list): + try: + s = pxssh.pxssh() + dest = self.clients[client] + s.login(dest.hostname, dest.user, dest.password) + + for command in cmd: + s.sendline(command.cmd) + s.prompt() + if command.do_print: + print(command.prefix, s.before.decode('utf-8')) + + s.logout() + except pxssh.ExceptionPxssh as e: + print("pxssh failed on login.") + print(e) diff --git a/update.py b/update.py new file mode 100644 index 0000000000000000000000000000000000000000..43d43e2bc570d9103bc0ecb8b084a8af375d7d84 --- /dev/null +++ b/update.py @@ -0,0 +1,49 @@ +import paramiko +import os + +from ssh_client import RemoteClient + + +class VersionManager: + + def __init__(self, remote_client: RemoteClient): + self.client = remote_client + + def update(self): + + # TODO: rm previous files + transport = paramiko.Transport((self.client.hostname, 22)) + transport.connect(username=self.client.user, password=self.client.password) + sftp = MySFTPClient.from_transport(transport) + sftp.mkdir("./Desktop/mqtt_goyon/iotamak-core", ignore_existing=True) + sftp.put_dir("/mnt/d/work/stage m1/iotamak-core", "./Desktop/mqtt_goyon/iotamak-core") + sftp.close() + + +class MySFTPClient(paramiko.SFTPClient): + def put_dir(self, source, target): + ''' Uploads the contents of the source directory to the target path. The + target directory needs to exists. All subdirectories in source are + created under target. + ''' + for item in os.listdir(source): + if os.path.isfile(os.path.join(source, item)): + self.put(os.path.join(source, item), '%s/%s' % (target, item)) + print(os.path.join(source, item)) + else: + if any([i in item for i in [".git", "__pycache__", ".idea", ".vscode"]]): + pass + else: + self.mkdir('%s/%s' % (target, item), ignore_existing=True) + self.put_dir(os.path.join(source, item), '%s/%s' % (target, item)) + print(os.path.join(source, item)) + + def mkdir(self, path, mode=511, ignore_existing=False): + ''' Augments mkdir by adding an option to not fail if the folder exists ''' + try: + super(MySFTPClient, self).mkdir(path, mode) + except IOError: + if ignore_existing: + pass + else: + raise