diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml
index 4e03e33..a64e7e0 100644
--- a/.github/workflows/build-deb.yml
+++ b/.github/workflows/build-deb.yml
@@ -2,7 +2,7 @@ name: Build and test deb package for linupdate
 
 on:
   push:
-    branches: [ devel ]
+    branches: [ python ]
   pull_request:
     push:
       branches: [ main ]
@@ -29,21 +29,19 @@ jobs:
           mkdir -p /tmp/linupdate-build/DEBIAN
           mkdir -p /tmp/linupdate-build/etc/linupdate/modules
           mkdir -p /tmp/linupdate-build/opt/linupdate
-          mkdir -p /tmp/linupdate-build/opt/linupdate/.src/
-          mkdir -p /tmp/linupdate-build/opt/linupdate/mods-available/
-          mkdir -p /tmp/linupdate-build/opt/linupdate/mods-enabled/
-          mkdir -p /tmp/linupdate-build/opt/linupdate/agents-available/
-          mkdir -p /tmp/linupdate-build/opt/linupdate/service/
-          mkdir -p /tmp/linupdate-build/lib/systemd/system/
+          mkdir -p /tmp/linupdate-build/opt/linupdate/src/
+# TODO: service not working for now
+#          mkdir -p /tmp/linupdate-build/opt/linupdate/service/
+#          mkdir -p /tmp/linupdate-build/lib/systemd/system/
 
       - name: Copy files to include in the build
         run: |
-          cp -r ${GITHUB_WORKSPACE}/src/* /tmp/linupdate-build/opt/linupdate/.src/
-          cp -r ${GITHUB_WORKSPACE}/mods-available/* /tmp/linupdate-build/opt/linupdate/mods-available/
-          cp -r ${GITHUB_WORKSPACE}/service/* /tmp/linupdate-build/opt/linupdate/service/
-          cp ${GITHUB_WORKSPACE}/linupdate /tmp/linupdate-build/opt/linupdate/linupdate
+          cp -r ${GITHUB_WORKSPACE}/src/* /tmp/linupdate-build/opt/linupdate/src/
+          cp ${GITHUB_WORKSPACE}/linupdate.py /tmp/linupdate-build/opt/linupdate/linupdate.py
           cp ${GITHUB_WORKSPACE}/version /tmp/linupdate-build/opt/linupdate/version
-          cp -r ${GITHUB_WORKSPACE}/service/linupdate.systemd.template /tmp/linupdate-build/lib/systemd/system/linupdate.service
+# TODO: service not working for now
+#          cp -r ${GITHUB_WORKSPACE}/service/* /tmp/linupdate-build/opt/linupdate/service/
+#          cp -r ${GITHUB_WORKSPACE}/service/linupdate.systemd.template /tmp/linupdate-build/lib/systemd/system/linupdate.service
 
       - name: Copy control file
         run: |
@@ -145,4 +143,4 @@ jobs:
       - name: Install package
         run: |
           sudo apt-get update -y
-          sudo apt-get install -y ./linupdate-test-build_${{ env.VERSION }}_all.deb
\ No newline at end of file
+          sudo apt-get install -y ./linupdate-test-build_${{ env.VERSION }}_all.deb
diff --git a/.github/workflows/packaging/deb/control b/.github/workflows/packaging/deb/control
index 5606d29..eeb0ce1 100644
--- a/.github/workflows/packaging/deb/control
+++ b/.github/workflows/packaging/deb/control
@@ -3,7 +3,7 @@ Version: __VERSION__
 Section: main
 Priority: optional
 Architecture: all
-Depends: curl, git, apt-transport-https, aptitude, mutt, locales, ngrep, inotify-tools, jq, virt-what, net-tools, dnsutils, locales-all
+Depends: apt-transport-https, locales, ngrep, inotify-tools, virt-what, net-tools, dnsutils, locales-all, python3-tabulate, python3-colorama, python3-dateutil
 Maintainer: Ludovic <repomanager@protonmail.com>
-Description: Linupdate package updater - Repomanager client side agent
+Description: Linupdate 3+ (python version) - A package updater and Repomanager's client side agent
 Homepage: https://github.com/lbr38/linupdate
diff --git a/.github/workflows/packaging/deb/postinst b/.github/workflows/packaging/deb/postinst
index cb17ecb..c03a742 100644
--- a/.github/workflows/packaging/deb/postinst
+++ b/.github/workflows/packaging/deb/postinst
@@ -4,18 +4,13 @@ DATA_DIR="/opt/linupdate"
 SERVICE="$DATA_DIR/service/linupdate-agent"
 
 # Restore configuration file if exists
-if [ -f "/tmp/linupdate.conf.debsave" ];then
-    rm -f /etc/linupdate/linupdate.conf
-    mv /tmp/linupdate.conf.debsave /etc/linupdate/linupdate.conf
+if [ -f "/tmp/linupdate.yml.debsave" ];then
+    rm -f /etc/linupdate/linupdate.yml
+    mv /tmp/linupdate.yml.debsave /etc/linupdate/linupdate.yml
 fi
 
 # Create a symlink to main script
-ln -sf /opt/linupdate/linupdate /usr/bin/linupdate
-
-# Delete old 'functions' directory if exists
-if [ -d "$DATA_DIR/functions" ];then
-    rm -rf "$DATA_DIR/functions"
-fi
+ln -sf /opt/linupdate/linupdate.py /usr/bin/linupdate
 
 # Install en_US.UTF-8 locale if not present
 if ! locale -a | grep -q "en_US.UTF-8";then
@@ -27,19 +22,20 @@ chmod 750 /etc/linupdate
 chmod 750 /opt/linupdate
 
 # Only if systemd is installed (not the case on github runners)
-if [ -f "/usr/bin/systemctl" ];then
-
-    # Enable service script by creating a symlink
-    ln -sf /lib/systemd/system/linupdate.service /etc/systemd/system/linupdate.service
-    chmod 550 "$SERVICE"
-    chown root:root "$SERVICE"
-
-    /usr/bin/systemctl --quiet daemon-reload
-
-    # Start service
-    if /usr/bin/systemctl is-active --quiet linupdate;then
-        /usr/bin/systemctl restart --quiet linupdate
-    else
-        /usr/bin/systemctl start --quiet linupdate
-    fi
-fi
\ No newline at end of file
+# TODO: service is not working for now
+# if [ -f "/usr/bin/systemctl" ];then
+
+#     # Enable service script by creating a symlink
+#     ln -sf /lib/systemd/system/linupdate.service /etc/systemd/system/linupdate.service
+#     chmod 550 "$SERVICE"
+#     chown root:root "$SERVICE"
+
+#     /usr/bin/systemctl --quiet daemon-reload
+
+#     # Start service
+#     if /usr/bin/systemctl is-active --quiet linupdate;then
+#         /usr/bin/systemctl restart --quiet linupdate
+#     else
+#         /usr/bin/systemctl start --quiet linupdate
+#     fi
+# fi
\ No newline at end of file
diff --git a/.github/workflows/packaging/deb/preinst b/.github/workflows/packaging/deb/preinst
index ad6e378..d656cf4 100644
--- a/.github/workflows/packaging/deb/preinst
+++ b/.github/workflows/packaging/deb/preinst
@@ -1,8 +1,8 @@
 #!/bin/bash
 
 # Save current configuration file if exists
-if [ -f "/etc/linupdate/linupdate.conf" ];then
-    cp /etc/linupdate/linupdate.conf /tmp/linupdate.conf.debsave
+if [ -f "/etc/linupdate/linupdate.yml" ];then
+    cp /etc/linupdate/linupdate.yml /tmp/linupdate.yml.debsave
 fi
 
 # Only if systemd is installed (not the case on github runners)
diff --git a/linupdate-agent.py b/linupdate-agent.py
new file mode 100644
index 0000000..a72569f
--- /dev/null
+++ b/linupdate-agent.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+# coding: utf-8
+
+# Import libraries
+import time
+
+# Import classes
+from src.controllers.App.Service import Service
+
+# Leave some time for the system to boot
+# TODO
+# time.sleep(60)
+
+# Instantiate Service class
+my_service = Service()
+
+# Execute main function
+my_service.main()
+
+exit(0)
diff --git a/service/linupdate.systemd.template b/service/linupdate.systemd.template
index 72fccef..7d099fa 100644
--- a/service/linupdate.systemd.template
+++ b/service/linupdate.systemd.template
@@ -3,7 +3,7 @@ Description=linupdate-agent
 
 [Service]
 Type=simple
-ExecStart=/opt/linupdate/service/linupdate-agent
+ExecStart=/opt/linupdate/service/linupdate-agent.py
 
 [Install]
 WantedBy=multi-user.target
\ No newline at end of file
diff --git a/src/controllers/Agent.py b/src/controllers/Agent.py
deleted file mode 100644
index 72ac5a2..0000000
--- a/src/controllers/Agent.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# coding: utf-8
-
-# Import libraries
-import time
-
-class Agent():
-    #-------------------------------------------------------------------------------------------------------------------
-    #
-    #   Agent main function
-    #
-    #-------------------------------------------------------------------------------------------------------------------
-    def main():
-        # Leave some time for the system to boot
-        time.sleep(60)
-
-        try:
-
-        except Exception as e:
-    
\ No newline at end of file
diff --git a/src/controllers/App/Service.py b/src/controllers/App/Service.py
new file mode 100644
index 0000000..936037d
--- /dev/null
+++ b/src/controllers/App/Service.py
@@ -0,0 +1,124 @@
+# coding: utf-8
+
+# Import libraries
+import subprocess
+import signal
+import sys
+import importlib
+import subprocess
+from pathlib import Path
+
+# Import classes
+from src.controllers.Module.Module import Module
+
+class Service:
+    def __init__(self):
+        self.child_processes = []
+        self.moduleController = Module()
+
+    #-------------------------------------------------------------------------------------------------------------------
+    #
+    #   Check if a restart of this service is needed, and restart it if needed
+    #
+    #-------------------------------------------------------------------------------------------------------------------
+    def restart_self_if_needed(self):
+        if Path('/tmp/linupdate-service.restart').is_file():
+            # Only restart the service if linupdate is not running otherwise it could cut off a running update...
+            if Path('/tmp/linupdate.lock').is_file():
+                return
+            
+            print('A restart of this service is required. Restarting...')
+            Path('/tmp/linupdate-service.restart').unlink()
+            subprocess.run(["systemctl", "restart", "linupdate.service"])
+
+            result = subprocess.run(
+                ["systemctl", "--quiet", "restart", "linupdate.service"],
+                capture_output = True,
+                text = True
+            )
+
+            # If service could not be restarted, print error and exit
+            if result.returncode != 0:
+                print('Error: could not restart linupdate service: ' + result.stderr)
+                exit(1)
+
+
+    #-------------------------------------------------------------------------------------------------------------------
+    #
+    #   Service main function
+    #
+    #-------------------------------------------------------------------------------------------------------------------
+    def main(self):
+        try:
+            # Check if a restart of this service is needed
+            self.restart_self_if_needed()
+
+            # Retrieve enabled modules
+            enabled_modules = self.moduleController.getEnabled()
+
+            # For each enabled module, check if its agent is enabled
+            for module in enabled_modules:
+                # Convert module name to uppercase first letter
+                module_name = module.capitalize()
+
+                # Import python module config class
+                module_import_path = importlib.import_module('src.controllers.Module.' + module_name + '.Config')
+                module_class = getattr(module_import_path, 'Config')
+
+                # Instantiate module and get module configuration
+                my_module = module_class()
+                module_configuration = my_module.getConf()
+
+                # Check if agent is enabled
+                if module_configuration['agent']['enabled']:
+                    print('Executing agent for module ' + module_name)
+
+                    # Import python module agent class
+                    module_import_path = importlib.import_module('src.controllers.Module.' + module_name + '.Agent')
+                    my_module_agent_class = getattr(module_import_path, 'Agent')()
+
+                    # Instantiate module and call module agent main method in a child process
+                    # process = subprocess.Popen(['python3', '-c', 'import src.controllers.Module.' + module_name + '.Agent; src.controllers.Module.' + module_name + '.Agent.main()'])
+                    # self.child_processes.append(process)
+
+        except Exception as e:
+            print('Linupdate service error:' + str(e))
+            exit(1)
+
+
+    #-------------------------------------------------------------------------------------------------------------------
+    #
+    #   Stop all child processes
+    #
+    #-------------------------------------------------------------------------------------------------------------------
+    def stop_child_processes(self):
+        for process in self.child_processes:
+            process.terminate()
+            try:
+                process.wait(timeout=5)
+            except subprocess.TimeoutExpired:
+                process.kill()
+
+
+#-------------------------------------------------------------------------------------------------------------------
+#
+#   Signal handler
+#   This function is called when the service receives a SIGTERM or SIGINT signal
+#
+#-------------------------------------------------------------------------------------------------------------------
+def signal_handler(sig, frame):
+    print('Linupdate service received signal ' + str(sig) + '. Stopping all child processes')
+    service.stop_child_processes()
+    sys.exit(0)
+
+
+#-------------------------------------------------------------------------------------------------------------------
+#
+#   Main
+#
+#-------------------------------------------------------------------------------------------------------------------
+if __name__ == "__main__":
+    service = Service()
+    signal.signal(signal.SIGTERM, signal_handler)
+    signal.signal(signal.SIGINT, signal_handler)
+    service.main()
diff --git a/src/controllers/Module/Reposerver/Agent.py b/src/controllers/Module/Reposerver/Agent.py
index 6de141e..fb42bbd 100644
--- a/src/controllers/Module/Reposerver/Agent.py
+++ b/src/controllers/Module/Reposerver/Agent.py
@@ -108,7 +108,7 @@ def setListenEnable(self, value: bool):
 
 
 
-
+    
 
 
 
@@ -187,17 +187,13 @@ def main(self):
             # This is checked every time in case that a configuration change has been made in the configuration file
             self.general_checks()
 
-            # Check if a restart of this service is needed
-            # TODO
-            # checkRestartNeeded
-
             # Regulary sending data to the Repomanager server (every hour)
             # 3600 / 5sec (sleep 5) = 720
             if counter == 0 or counter == 720:
                 # Sending full status
                 print('Periodically sending informations about this host to the repomanager server')
-                self.sendFullStatus()
-                self.reposerverStatusController.sendFullStatus()
+                self.reposerverStatusController.sendGeneralStatus()
+                self.reposerverStatusController.sendPackagesStatus()
 
                 # Reset counter
                 counter = 0
@@ -211,7 +207,7 @@ def main(self):
             # inotify_package_event()
 
             # If ngrep scans are enabled, then execute them in background
-            if configuration['agent']['listen']['enabled']:
+            # if configuration['agent']['listen']['enabled']:
                 # Monitor general informations sending requests
                 # TODO
                 # ngrep_general_update_request
@@ -223,7 +219,6 @@ def main(self):
                 # Monitor package update requests
                 # TODO
                 # ngrep_packages_update_requested
-                print('toto')
 
             time.sleep(5)
 
diff --git a/version b/version
index 3c3ae88..56fea8a 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.2.13
\ No newline at end of file
+3.0.0
\ No newline at end of file