diff --git a/.gitignore b/.gitignore
index 3833e98..0cac4ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 *.img.bmap
 *.pcap
 *.po~
+preview.png
 __pycache__
 _backups
 _emulation
@@ -10,3 +11,7 @@ config.laptop.yml
 .idea
 packer_cache
 output-pwnagotchi
+.DS_Store
+build
+dist
+pwnagotchi.egg-info
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..55e0a5d
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,8 @@
+exclude *.pyc .DS_Store .gitignore MANIFEST.in
+include setup.py
+include distribute_setup.py
+include README.md
+include LICENSE
+recursive-include bin *
+recursive-include pwnagotchi *.py
+recursive-include pwnagotchi *.yml
diff --git a/README.md b/README.md
index f492955..4fb4153 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,10 @@
   <p align="center">
     <a href="https://github.com/evilsocket/pwnagotchi/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/evilsocket/pwnagotchi.svg?style=flat-square"></a>
     <a href="https://github.com/evilsocket/pwnagotchi/blob/master/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-GPL3-brightgreen.svg?style=flat-square"></a>
+    <a href="https://github.com/evilsocket/pwnagotchi/graphs/contributors"><img alt="Contributors" src="https://img.shields.io/github/contributors/evilsocket/pwnagotchi"/></a>
     <a href="https://travis-ci.org/evilsocket/pwnagotchi"><img alt="Travis" src="https://img.shields.io/travis/evilsocket/pwnagotchi/master.svg?style=flat-square"></a>
     <a href="https://pwnagotchi.herokuapp.com/"><img alt="Slack" src="https://pwnagotchi.herokuapp.com/badge.svg"></a>
+    <a href="https://twitter.com/intent/follow?screen_name=pwnagotchi"><img src="https://img.shields.io/twitter/follow/pwnagotchi?style=social&logo=twitter" alt="follow on Twitter"></a>
   </p>
 </p>
 
diff --git a/bin/pwnagotchi b/bin/pwnagotchi
new file mode 100755
index 0000000..4733105
--- /dev/null
+++ b/bin/pwnagotchi
@@ -0,0 +1,106 @@
+#!/usr/bin/python3
+if __name__ == '__main__':
+    import argparse
+    import time
+    import os
+    import logging
+
+    import pwnagotchi
+    import pwnagotchi.utils as utils
+    import pwnagotchi.plugins as plugins
+
+    from pwnagotchi.log import SessionParser
+    from pwnagotchi.agent import Agent
+    from pwnagotchi.ui.display import Display
+
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument('-C', '--config', action='store', dest='config',
+                        default=os.path.join(os.path.abspath(os.path.dirname(pwnagotchi.__file__)), '/defaults.yml'),
+                        help='Main configuration file.')
+    parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/etc/pwnagotchi/config.yml',
+                        help='If this file exists, configuration will be merged and this will override default values.')
+
+    parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
+    parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
+                        help="Clear the ePaper display and exit.")
+
+    parser.add_argument('--debug', dest="debug", action="store_true", default=False,
+                        help="Enable debug logs.")
+
+    args = parser.parse_args()
+    config = utils.load_config(args)
+    utils.setup_logging(args, config)
+
+    plugins.load(config)
+
+    display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
+    agent = Agent(view=display, config=config)
+
+    logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent._identity, pwnagotchi.version))
+
+    for _, plugin in plugins.loaded.items():
+        logging.debug("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
+
+    if args.do_clear:
+        logging.info("clearing the display ...")
+        display.clear()
+
+    elif args.do_manual:
+        logging.info("entering manual mode ...")
+
+        log = SessionParser(config)
+        logging.info(
+            "the last session lasted %s (%d completed epochs, trained for %d), average reward:%s (min:%s max:%s)" % (
+                log.duration_human,
+                log.epochs,
+                log.train_epochs,
+                log.avg_reward,
+                log.min_reward,
+                log.max_reward))
+
+        while True:
+            display.on_manual_mode(log)
+            time.sleep(1)
+
+            if Agent.is_connected():
+                plugins.on('internet_available', display, config, log)
+
+    else:
+        logging.info("entering auto mode ...")
+
+        agent.start()
+
+        while True:
+            try:
+                # recon on all channels
+                agent.recon()
+                # get nearby access points grouped by channel
+                channels = agent.get_access_points_by_channel()
+                # check for free channels to use
+                agent.check_channels(channels)
+                # for each channel
+                for ch, aps in channels:
+                    agent.set_channel(ch)
+
+                    if not agent.is_stale() and agent.any_activity():
+                        logging.info("%d access points on channel %d" % (len(aps), ch))
+
+                    # for each ap on this channel
+                    for ap in aps:
+                        # send an association frame in order to get for a PMKID
+                        agent.associate(ap)
+                        # deauth all client stations in order to get a full handshake
+                        for sta in ap['clients']:
+                            agent.deauth(ap, sta)
+
+                # An interesting effect of this:
+                #
+                # From Pwnagotchi's perspective, the more new access points
+                # and / or client stations nearby, the longer one epoch of
+                # its relative time will take ... basically, in Pwnagotchi's universe,
+                # WiFi electromagnetic fields affect time like gravitational fields
+                # affect ours ... neat ^_^
+                agent.next_epoch()
+            except Exception as e:
+                logging.exception("main loop exception")
diff --git a/builder/pwnagotchi.yml b/builder/pwnagotchi.yml
index a8dca14..2fe3ff9 100644
--- a/builder/pwnagotchi.yml
+++ b/builder/pwnagotchi.yml
@@ -16,7 +16,6 @@
     services:
       enable:
         - dphys-swapfile.service
-        - getty@ttyGS0.service
       disable:
         - apt-daily.timer
         - apt-daily.service
@@ -245,6 +244,37 @@
         #!/usr/bin/env bash
         free -m | awk '/Mem/ { printf( "%d %", $3 / $2 * 100 + 0.5 ) }'
 
+  - name: create bootblink script
+    copy:
+      dest: /usr/bin/bootblink
+      mode: 0755
+      content: |
+        #!/usr/bin/env bash
+        for i in $(seq 1 "$1");
+        do
+        echo 0 >/sys/class/leds/led0/brightness
+        sleep 0.3
+        echo 1 >/sys/class/leds/led0/brightness
+        sleep 0.3
+        done
+        echo 0 >/sys/class/leds/led0/brightness
+        sleep 0.3
+
+  - name: create pwnagotchi-launcher script
+    copy:
+      dest: /usr/bin/pwnagotchi-launcher
+      mode: 0755
+      content: |
+        #!/usr/bin/env bash
+        # blink 10 times to signal ready state
+        /usr/bin/bootblink 10 &
+        # start a detached screen session with bettercap
+        if ifconfig | grep usb0 | grep RUNNING; then
+          /usr/bin/pwnagotchi --manual
+        else
+          /usr/bin/pwnagotchi
+        fi
+
   - name: create monstart script
     copy:
       dest: /usr/bin/monstart
@@ -261,6 +291,22 @@
         #!/usr/bin/env bash
         ifconfig mon0 down && iw dev mon0 del
 
+  - name: create hdmion script
+    copy:
+      dest: /usr/bin/hdmion
+      mode: 0755
+      content: |
+        #!/usr/bin/env bash
+        sudo /opt/vc/bin/tvservice -p
+
+  - name: create hdmioff script
+    copy:
+      dest: /usr/bin/hdmioff
+      mode: 0755
+      content: |
+        #!/usr/bin/env bash
+        sudo /opt/vc/bin/tvservice -o
+
   - name: configure rc.local
     blockinfile:
       path: /etc/rc.local
@@ -271,6 +317,13 @@
         fi
         /root/pwnagotchi/scripts/startup.sh &
 
+  - name: create /etc/pwnagotchi/config.yml
+    blockinfile:
+      path: /etc/pwnagotchi/config.yml
+      create: yes
+      block: |
+        # put here your custom configuration overrides
+
   - name: configure lo interface
     blockinfile:
       path: /etc/network/interfaces.d/lo-cfg
@@ -335,7 +388,7 @@
       state: present
       backup: no
       regexp: '(.*)$'
-      line: '\1 modules-load=dwc2,g_cdc'
+      line: '\1 modules-load=dwc2,g_ether'
 
   - name: configure ssh
     lineinfile:
diff --git a/docs/dev.md b/docs/dev.md
index 75b7ea0..534b398 100644
--- a/docs/dev.md
+++ b/docs/dev.md
@@ -26,7 +26,7 @@ usage: ./scripts/create_sibling.sh [OPTIONS]
 
 `GLib-ERROR **: 20:50:46.361: getauxval () failed: No such file or directory`
 
-- Affected DEB & Versions: QEMU <= 2.11 
+- Affected DEB & Versions: QEMU <= 2.11
 - Fix: Upgrade QEMU to >= 3.1
 - Bug Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923289
 
@@ -55,7 +55,6 @@ If you changed the `voice.py`- File, the translations need an update. Do it like
 Now you can use the `preview.py`-script to preview the changes:
 
 ```shell
-./scripts/preview.py --lang it --display ws2 --port 8080 &
-./scripts/preview.py --lang it --display inky --port 8081 &
-# Now open http://localhost:8080 and http://localhost:8081
+./scripts/preview.py --lang it --display ws1 ws2 inky --output preview.png
+# Now open preview.png
 ```
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/__init__.py b/pwnagotchi/__init__.py
similarity index 98%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/__init__.py
rename to pwnagotchi/__init__.py
index dd6c38a..9905b0f 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/__init__.py
+++ b/pwnagotchi/__init__.py
@@ -1,6 +1,6 @@
 import subprocess
 
-version = '1.0.0plz3'
+version = '1.0.0plz4'
 
 _name = None
 
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py b/pwnagotchi/agent.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py
rename to pwnagotchi/agent.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/__init__.py b/pwnagotchi/ai/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/__init__.py
rename to pwnagotchi/ai/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/epoch.py b/pwnagotchi/ai/epoch.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/epoch.py
rename to pwnagotchi/ai/epoch.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/featurizer.py b/pwnagotchi/ai/featurizer.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/featurizer.py
rename to pwnagotchi/ai/featurizer.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/gym.py b/pwnagotchi/ai/gym.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/gym.py
rename to pwnagotchi/ai/gym.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/parameter.py b/pwnagotchi/ai/parameter.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/parameter.py
rename to pwnagotchi/ai/parameter.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/reward.py b/pwnagotchi/ai/reward.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/reward.py
rename to pwnagotchi/ai/reward.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/train.py b/pwnagotchi/ai/train.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/train.py
rename to pwnagotchi/ai/train.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/utils.py b/pwnagotchi/ai/utils.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ai/utils.py
rename to pwnagotchi/ai/utils.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/bettercap.py b/pwnagotchi/bettercap.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/bettercap.py
rename to pwnagotchi/bettercap.py
diff --git a/sdcard/rootfs/root/pwnagotchi/config.yml b/pwnagotchi/defaults.yml
similarity index 99%
rename from sdcard/rootfs/root/pwnagotchi/config.yml
rename to pwnagotchi/defaults.yml
index a93a7e8..cceac71 100644
--- a/sdcard/rootfs/root/pwnagotchi/config.yml
+++ b/pwnagotchi/defaults.yml
@@ -153,8 +153,8 @@ bettercap:
     scheme: http
     hostname: localhost
     port: 8081
-    username: user
-    password: pass
+    username: pwnagotchi
+    password: pwnagotchi
     # folder where bettercap stores the WPA handshakes, given that
     # wifi.handshakes.aggregate will be set to false and individual
     # pcap files will be created in order to minimize the chances
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/de/LC_MESSAGES/voice.mo b/pwnagotchi/locale/de/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/de/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/de/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/de/LC_MESSAGES/voice.po b/pwnagotchi/locale/de/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/de/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/de/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/el/LC_MESSAGES/voice.mo b/pwnagotchi/locale/el/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/el/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/el/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/el/LC_MESSAGES/voice.po b/pwnagotchi/locale/el/LC_MESSAGES/voice.po
similarity index 97%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/el/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/el/LC_MESSAGES/voice.po
index f113ce1..b1cfa69 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/el/LC_MESSAGES/voice.po
+++ b/pwnagotchi/locale/el/LC_MESSAGES/voice.po
@@ -33,11 +33,11 @@ msgid "AI ready."
 msgstr "ΤΝ έτοιμη."
 
 msgid "The neural network is ready."
-msgstr "Το νευρωνικό δίκτυοείναι έτοιμο."
+msgstr "Το νευρωνικό δίκτυο είναι έτοιμο."
 
 #, python-brace-format
 msgid "Hey, channel {channel} is free! Your AP will say thanks."
-msgstr "Ε, το κανάλι {channel} είναιελεύθερο! Το AP σου θαείναι ευγνώμων."
+msgstr "Ε, το κανάλι {channel} είναιελεύθερο! Το AP σου θα είναι ευγνώμων."
 
 msgid "I'm bored ..."
 msgstr "Βαριέμαι ..."
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/fr/LC_MESSAGES/voice.mo b/pwnagotchi/locale/fr/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/fr/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/fr/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/fr/LC_MESSAGES/voice.po b/pwnagotchi/locale/fr/LC_MESSAGES/voice.po
similarity index 89%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/fr/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/fr/LC_MESSAGES/voice.po
index 1172f7f..1d061f7 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/fr/LC_MESSAGES/voice.po
+++ b/pwnagotchi/locale/fr/LC_MESSAGES/voice.po
@@ -25,20 +25,20 @@ msgid "Hi, I'm Pwnagotchi! Starting ..."
 msgstr "Bonjour, je suis Pwnagotchi! Démarrage ..."
 
 msgid "New day, new hunt, new pwns!"
-msgstr "Nouvelle journée, nouvelle chasse, nouveau pwns!"
+msgstr "Nouveau jour, nouvelle chasse, nouveaux pwns !"
 
 msgid "Hack the Planet!"
 msgstr "Hack la planète!"
 
 msgid "AI ready."
-msgstr "IA prête."
+msgstr "L'IA est prête."
 
 msgid "The neural network is ready."
 msgstr "Le réseau neuronal est prêt."
 
 #, python-brace-format
 msgid "Hey, channel {channel} is free! Your AP will say thanks."
-msgstr "Hey, le channel {channel} est libre! Ton AP va dis merci."
+msgstr "Hey, le channel {channel} est libre! Ton point d'accès va te remercier."
 
 msgid "I'm bored ..."
 msgstr "Je m'ennuie ..."
@@ -68,17 +68,17 @@ msgid "I pwn therefore I am."
 msgstr "Je pwn donc je suis."
 
 msgid "So many networks!!!"
-msgstr "Autant de réseaux!!!"
+msgstr "Tellement de réseaux!!!"
 
 msgid "I'm having so much fun!"
 msgstr "Je m'amuse tellement!"
 
 msgid "My crime is that of curiosity ..."
-msgstr "Mon crime est celui de la curiosité ..."
+msgstr "Mon crime, c'est la curiosité ..."
 
 #, python-brace-format
 msgid "Hello {name}! Nice to meet you. {name}"
-msgstr "Bonjour {name}! Ravis de te rencontrer. {name}"
+msgstr "Bonjour {name}! Ravi de te rencontrer. {name}"
 
 #, python-brace-format
 msgid "Unit {name} is nearby! {name}"
@@ -145,7 +145,7 @@ msgstr ""
 
 #, python-brace-format
 msgid "Just decided that {mac} needs no WiFi!"
-msgstr "Décidé à l'instant que {mac} n'a pas besoin de WiFi!"
+msgstr "Je viens de décider que {mac} n'a pas besoin de WiFi!"
 
 #, python-brace-format
 msgid "Deauthenticating {mac}"
@@ -153,11 +153,11 @@ msgstr "Désauthentification de {mac}"
 
 #, python-brace-format
 msgid "Kickbanning {mac}!"
-msgstr ""
+msgstr "Je kick et je bannis {mac}!"
 
 #, python-brace-format
 msgid "Cool, we got {num} new handshake{plural}!"
-msgstr "Cool, nous avons {num} nouveaux handshake{plural}!"
+msgstr "Cool, on a {num} nouveaux handshake{plural}!"
 
 msgid "Ops, something went wrong ... Rebooting ..."
 msgstr "Oups, quelque chose s'est mal passé ... Redémarrage ..."
@@ -188,7 +188,7 @@ msgid ""
 "#pwnlog #pwnlife #hacktheplanet #skynet"
 msgstr ""
 "J'ai pwn durant {duration} et kick {deauthed} clients! J'ai aussi rencontré "
-"{associated} nouveaux amis and mangé {handshakes} handshakes! #pwnagotchi "
+"{associated} nouveaux amis et dévoré {handshakes} handshakes! #pwnagotchi "
 "#pwnlog #pwnlife #hacktheplanet #skynet"
 
 msgid "hours"
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/it/LC_MESSAGES/voice.mo b/pwnagotchi/locale/it/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/it/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/it/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/it/LC_MESSAGES/voice.po b/pwnagotchi/locale/it/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/it/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/it/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/mk/LC_MESSAGES/voice.mo b/pwnagotchi/locale/mk/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/mk/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/mk/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/mk/LC_MESSAGES/voice.po b/pwnagotchi/locale/mk/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/mk/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/mk/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/nl/LC_MESSAGES/voice.mo b/pwnagotchi/locale/nl/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/nl/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/nl/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/nl/LC_MESSAGES/voice.po b/pwnagotchi/locale/nl/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/nl/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/nl/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/ru/LC_MESSAGES/voice.mo b/pwnagotchi/locale/ru/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/ru/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/ru/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/ru/LC_MESSAGES/voice.po b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/ru/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/ru/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/se/LC_MESSAGES/voice.mo b/pwnagotchi/locale/se/LC_MESSAGES/voice.mo
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/se/LC_MESSAGES/voice.mo
rename to pwnagotchi/locale/se/LC_MESSAGES/voice.mo
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/se/LC_MESSAGES/voice.po b/pwnagotchi/locale/se/LC_MESSAGES/voice.po
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/se/LC_MESSAGES/voice.po
rename to pwnagotchi/locale/se/LC_MESSAGES/voice.po
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/voice.pot b/pwnagotchi/locale/voice.pot
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/locale/voice.pot
rename to pwnagotchi/locale/voice.pot
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/log.py b/pwnagotchi/log.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/log.py
rename to pwnagotchi/log.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/__init__.py b/pwnagotchi/mesh/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/__init__.py
rename to pwnagotchi/mesh/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/advertise.py b/pwnagotchi/mesh/advertise.py
similarity index 99%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/advertise.py
rename to pwnagotchi/mesh/advertise.py
index ff797a3..84286d2 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/advertise.py
+++ b/pwnagotchi/mesh/advertise.py
@@ -152,7 +152,7 @@ class Advertiser(object):
         if self._is_broadcasted_advertisement(dot11):
             try:
                 dot11elt = p.getlayer(Dot11Elt)
-                if dot11elt.ID == wifi.Dot11ElemID_Identity:
+                if dot11elt.ID == wifi.Dot11ElemID_Whisper:
                     self._parse_identity(p[RadioTap], dot11, dot11elt)
 
                 else:
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/peer.py b/pwnagotchi/mesh/peer.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/peer.py
rename to pwnagotchi/mesh/peer.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/utils.py b/pwnagotchi/mesh/utils.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/utils.py
rename to pwnagotchi/mesh/utils.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/wifi.py b/pwnagotchi/mesh/wifi.py
similarity index 90%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/wifi.py
rename to pwnagotchi/mesh/wifi.py
index 6a9a00a..6fe231e 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/mesh/wifi.py
+++ b/pwnagotchi/mesh/wifi.py
@@ -1,6 +1,6 @@
 SignatureAddress = 'de:ad:be:ef:de:ad'
 BroadcastAddress = 'ff:ff:ff:ff:ff:ff'
-Dot11ElemID_Identity = 222
+Dot11ElemID_Whisper = 222
 NumChannels = 140
 
 def freq_to_channel(freq):
@@ -30,7 +30,7 @@ def encapsulate(payload, addr_from, addr_to=BroadcastAddress):
     while data_left > 0:
         sz = min(chunk_size, data_left)
         chunk = payload[data_off: data_off + sz]
-        frame /= Dot11Elt(ID=Dot11ElemID_Identity, info=chunk, len=sz)
+        frame /= Dot11Elt(ID=Dot11ElemID_Whisper, info=chunk, len=sz)
         data_off += sz
         data_left -= sz
 
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py b/pwnagotchi/plugins/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py
rename to pwnagotchi/plugins/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/auto-backup.py b/pwnagotchi/plugins/default/auto-backup.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/auto-backup.py
rename to pwnagotchi/plugins/default/auto-backup.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/auto-update.py b/pwnagotchi/plugins/default/auto-update.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/auto-update.py
rename to pwnagotchi/plugins/default/auto-update.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py b/pwnagotchi/plugins/default/example.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py
rename to pwnagotchi/plugins/default/example.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py
rename to pwnagotchi/plugins/default/gps.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py
rename to pwnagotchi/plugins/default/memtemp.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/onlinehashcrack.py b/pwnagotchi/plugins/default/onlinehashcrack.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/onlinehashcrack.py
rename to pwnagotchi/plugins/default/onlinehashcrack.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py b/pwnagotchi/plugins/default/twitter.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py
rename to pwnagotchi/plugins/default/twitter.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py b/pwnagotchi/plugins/default/ups_lite.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py
rename to pwnagotchi/plugins/default/ups_lite.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py b/pwnagotchi/plugins/default/wpa-sec.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
rename to pwnagotchi/plugins/default/wpa-sec.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/__init__.py b/pwnagotchi/ui/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/__init__.py
rename to pwnagotchi/ui/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/components.py b/pwnagotchi/ui/components.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/components.py
rename to pwnagotchi/ui/components.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/display.py b/pwnagotchi/ui/display.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/display.py
rename to pwnagotchi/ui/display.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/faces.py b/pwnagotchi/ui/faces.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/faces.py
rename to pwnagotchi/ui/faces.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/fonts.py b/pwnagotchi/ui/fonts.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/fonts.py
rename to pwnagotchi/ui/fonts.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/__init__.py b/pwnagotchi/ui/papirus/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/__init__.py
rename to pwnagotchi/ui/papirus/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/epd.py b/pwnagotchi/ui/papirus/epd.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/epd.py
rename to pwnagotchi/ui/papirus/epd.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/lm75b.py b/pwnagotchi/ui/papirus/lm75b.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/papirus/lm75b.py
rename to pwnagotchi/ui/papirus/lm75b.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py b/pwnagotchi/ui/state.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py
rename to pwnagotchi/ui/state.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py b/pwnagotchi/ui/view.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py
rename to pwnagotchi/ui/view.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/__init__.py b/pwnagotchi/ui/waveshare/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/__init__.py
rename to pwnagotchi/ui/waveshare/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/__init__.py b/pwnagotchi/ui/waveshare/v1/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/__init__.py
rename to pwnagotchi/ui/waveshare/v1/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/epd2in13.py b/pwnagotchi/ui/waveshare/v1/epd2in13.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/epd2in13.py
rename to pwnagotchi/ui/waveshare/v1/epd2in13.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/epdconfig.py b/pwnagotchi/ui/waveshare/v1/epdconfig.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v1/epdconfig.py
rename to pwnagotchi/ui/waveshare/v1/epdconfig.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v2/__init__.py b/pwnagotchi/ui/waveshare/v2/__init__.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v2/__init__.py
rename to pwnagotchi/ui/waveshare/v2/__init__.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v2/waveshare.py b/pwnagotchi/ui/waveshare/v2/waveshare.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/waveshare/v2/waveshare.py
rename to pwnagotchi/ui/waveshare/v2/waveshare.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/utils.py b/pwnagotchi/utils.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/utils.py
rename to pwnagotchi/utils.py
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py b/pwnagotchi/voice.py
similarity index 100%
rename from sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py
rename to pwnagotchi/voice.py
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..f364dbc
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,15 @@
+crypto==1.4.1
+requests==2.21.0
+PyYAML==5.1
+scapy==2.4.3
+gym==0.14.0
+stable-baselines==2.7.0
+tensorflow==1.13.1
+tensorflow-estimator==1.14.0
+tweepy==3.6.0
+file-read-backwards==2.0.0
+numpy==1.17.2
+inky==0.0.5
+smbus2==0.3.0
+Pillow==5.4.1
+spidev==3.4
\ No newline at end of file
diff --git a/scripts/create_sibling.sh b/scripts/create_sibling.sh
index 02537cd..650d40c 100755
--- a/scripts/create_sibling.sh
+++ b/scripts/create_sibling.sh
@@ -94,9 +94,8 @@ function provide_raspbian() {
 function setup_raspbian(){
   # Detect the ability to create sparse files
   if [ "${OPT_SPARSE}" -eq 0 ]; then
-    if [ which bmaptool -eq 0 ]; then
+    if ! type "bmaptool" > /dev/null; then
       echo "[!] bmaptool not available, not creating a sparse image"
-      
     else
       echo "[+] Defaulting to sparse image generation as bmaptool is available"
       OPT_SPARSE=1
diff --git a/scripts/preview.py b/scripts/preview.py
index 2b45933..4f69a3d 100755
--- a/scripts/preview.py
+++ b/scripts/preview.py
@@ -1,77 +1,35 @@
 #!/usr/bin/env python3
-
 import sys
 import os
-import time
 import argparse
-from http.server import HTTPServer
-import shutil
-import logging
 import yaml
 
 sys.path.insert(0,
                 os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                             '../sdcard/rootfs/root/pwnagotchi/scripts/'))
+                             '../'))
 
 from pwnagotchi.ui.display import Display, VideoHandler
+from PIL import Image
 
 
 class CustomDisplay(Display):
 
+    def __init__(self, config, state):
+        self.last_image = None
+        super(CustomDisplay, self).__init__(config, state)
+
     def _http_serve(self):
-        if self._video_address is not None:
-            self._httpd = HTTPServer((self._video_address, self._video_port),
-                                     CustomVideoHandler)
-            logging.info("ui available at http://%s:%d/" % (self._video_address,
-                                                        self._video_port))
-            self._httpd.serve_forever()
-        else:
-            logging.info("could not get ip of usb0, video server not starting")
+        # do nothing
+        pass
 
     def _on_view_rendered(self, img):
-        CustomVideoHandler.render(img)
+        self.last_image = img
 
-        if self._enabled:
-            self.canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
-            if self._render_cb is not None:
-                self._render_cb()
-
-
-class CustomVideoHandler(VideoHandler):
-
-    @staticmethod
-    def render(img):
-        with CustomVideoHandler._lock:
-            try:
-                img.save("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), format='PNG')
-            except BaseException:
-                logging.exception("could not write preview")
-
-    def do_GET(self):
-        if self.path == '/':
-            self.send_response(200)
-            self.send_header('Content-type', 'text/html')
-            self.end_headers()
-            try:
-                self.wfile.write(
-                    bytes(
-                        self._index %
-                        ('localhost', 1000), "utf8"))
-            except BaseException:
-                pass
-
-        elif self.path.startswith('/ui'):
-            with self._lock:
-                self.send_response(200)
-                self.send_header('Content-type', 'image/png')
-                self.end_headers()
-                try:
-                    with open("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), 'rb') as fp:
-                        shutil.copyfileobj(fp, self.wfile)
-                except BaseException:
-                    logging.exception("could not open preview")
-        else:
-            self.send_response(404)
+    def get_image(self):
+        """
+        Return the saved image
+        """
+        return self.last_image
 
 
 class DummyPeer:
@@ -80,20 +38,44 @@ class DummyPeer:
         return "beta"
 
 
+def append_images(images, horizontal=True, xmargin=0, ymargin=0):
+    w, h = zip(*(i.size for i in images))
+
+    if horizontal:
+        t_w = sum(w)
+        t_h = max(h)
+    else:
+        t_w = max(w)
+        t_h = sum(h)
+
+    result = Image.new('RGB', (t_w, t_h))
+
+    x_offset = 0
+    y_offset = 0
+
+    for im in images:
+        result.paste(im, (x_offset, y_offset))
+        if horizontal:
+            x_offset += im.size[0] + xmargin
+        else:
+            y_offset += im.size[1] + ymargin
+
+    return result
+
+
 def main():
     parser = argparse.ArgumentParser(description="This program emulates\
                                      the pwnagotchi display")
-    parser.add_argument('--display', help="Which display to use.",
+    parser.add_argument('--displays', help="Which displays to use.", nargs="+",
                         default="waveshare_2")
-    parser.add_argument('--port', help="Which port to use",
-                        default=8080)
-    parser.add_argument('--sleep', type=int, help="Time between emotions",
-                        default=2)
     parser.add_argument('--lang', help="Language to use",
                         default="en")
+    parser.add_argument('--output', help="Path to output image (PNG)", default="preview.png")
+    parser.add_argument('--xmargin', type=int, default=5)
+    parser.add_argument('--ymargin', type=int, default=5)
     args = parser.parse_args()
 
-    CONFIG = yaml.load('''
+    config_template = '''
     main:
         lang: {lang}
     ui:
@@ -107,64 +89,79 @@ def main():
             video:
                 enabled: true
                 address: "0.0.0.0"
-                port: {port}
-    '''.format(display=args.display,
-               port=args.port,
-               lang=args.lang))
+                port: 8080
+    '''
 
-    DISPLAY = CustomDisplay(config=CONFIG, state={'name': '%s>' % 'preview'})
+    list_of_displays = list()
+    for display_type in args.displays:
+        config = yaml.safe_load(config_template.format(display=display_type,
+                                                       lang=args.lang))
+        display = CustomDisplay(config=config, state={'name': f"{display_type}>"})
+        list_of_displays.append(display)
 
-    while True:
-        DISPLAY.on_starting()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_ai_ready()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_normal()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_new_peer(DummyPeer())
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_lost_peer(DummyPeer())
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_free_channel('6')
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.wait(args.sleep)
-        DISPLAY.update()
-        DISPLAY.on_bored()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_sad()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_motivated(1)
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_demotivated(-1)
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_excited()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_miss('test')
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_lonely()
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_handshakes(1)
-        DISPLAY.update()
-        time.sleep(args.sleep)
-        DISPLAY.on_rebooting()
-        DISPLAY.update()
-        time.sleep(args.sleep)
+    columns = list()
+
+    for display in list_of_displays:
+        emotions = list()
+        # Starting
+        display.on_starting()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_ai_ready()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_normal()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_new_peer(DummyPeer())
+        display.update()
+        emotions.append(display.get_image())
+        display.on_lost_peer(DummyPeer())
+        display.update()
+        emotions.append(display.get_image())
+        display.on_free_channel('6')
+        display.update()
+        emotions.append(display.get_image())
+        display.wait(2)
+        display.update()
+        emotions.append(display.get_image())
+        display.on_bored()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_sad()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_motivated(1)
+        display.update()
+        emotions.append(display.get_image())
+        display.on_demotivated(-1)
+        display.update()
+        emotions.append(display.get_image())
+        display.on_excited()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
+        display.update()
+        emotions.append(display.get_image())
+        display.on_miss('test')
+        display.update()
+        emotions.append(display.get_image())
+        display.on_lonely()
+        display.update()
+        emotions.append(display.get_image())
+        display.on_handshakes(1)
+        display.update()
+        emotions.append(display.get_image())
+        display.on_rebooting()
+        display.update()
+        emotions.append(display.get_image())
+
+        # append them all together (vertical)
+        columns.append(append_images(emotions, horizontal=False, xmargin=args.xmargin, ymargin=args.ymargin))
+
+    # append columns side by side
+    final_image = append_images(columns, horizontal=True, xmargin=args.xmargin, ymargin=args.ymargin)
+    final_image.save(args.output, 'PNG')
 
 
 if __name__ == '__main__':
diff --git a/scripts/pypi_upload.sh b/scripts/pypi_upload.sh
new file mode 100755
index 0000000..4a71125
--- /dev/null
+++ b/scripts/pypi_upload.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+rm -rf build dist ergo_nn.egg-info &&
+  python3 setup.py sdist bdist_wheel &&
+  clear &&
+  twine upload dist/*
diff --git a/sdcard/boot/cmdline.txt b/sdcard/boot/cmdline.txt
deleted file mode 100755
index 6c44ae3..0000000
--- a/sdcard/boot/cmdline.txt
+++ /dev/null
@@ -1 +0,0 @@
-dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether
diff --git a/sdcard/boot/config.txt b/sdcard/boot/config.txt
deleted file mode 100755
index 4d69af8..0000000
--- a/sdcard/boot/config.txt
+++ /dev/null
@@ -1,1202 +0,0 @@
-################################################################################
-##  Raspberry Pi Configuration Settings
-##
-##  Revision 17, 2018/04/22
-##
-##  Details taken from the eLinux wiki
-##  For up-to-date information please refer to wiki page.
-##
-##  Wiki Location : http://elinux.org/RPiconfig
-##
-##
-##  Description:
-##    Details of each setting are described with each section that begins with
-##    a double hashed comment ('##')
-##    It is up to the user to remove the single hashed comment ('#') from each
-##    option they want to enable, and to set the specific value of that option.
-##
-##  Overclock settings will be disabled at runtime if the SoC reaches temp_limit
-##
-##  Originally based off https://github.com/Evilpaul/RPi-config/ with minor
-##  update because display_rotate is deprecated.
-##
-################################################################################
-
-################################################################################
-##  Standard Definition Video Settings
-################################################################################
-
-## sdtv_mode
-##     defines the TV standard for composite output
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Normal NTSC (Default)
-##     1        Japanese version of NTSC - no pedestal
-##     2        Normal PAL
-##     3        Brazilian version of PAL - 525/60 rather than 625/50, different
-##              subcarrier
-##
-#sdtv_mode=0
-
-## sdtv_aspect
-##     defines the aspect ratio for composite output
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     1        4:3 (Default)
-##     2        14:9
-##     3        16:9
-##
-#sdtv_aspect=1
-
-## sdtv_disable_colourburst
-##     Disables colour burst on composite output. The picture will be
-##     monochrome, but possibly sharper
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Colour burst is enabled (Default)
-##     1        Colour burst is disabled
-##
-#sdtv_disable_colourburst=1
-
-################################################################################
-##  High Definition Video Settings
-################################################################################
-
-## hdmi_safe
-##     Use "safe mode" settings to try to boot with maximum hdmi compatibility.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Disabled (Default)
-##     1        Enabled (this does: hdmi_force_hotplug=1,
-##                                  hdmi_ignore_edid=0xa5000080,
-##                                  config_hdmi_boost=4, hdmi_group=2,
-##                                  hdmi_mode=4, disable_overscan=0,
-##                                  overscan_left=24, overscan_right=24,
-##                                  overscan_top=24, overscan_bottom=24)
-##
-#hdmi_safe=1
-
-## hdmi_force_hotplug
-##     Pretends HDMI hotplug signal is asserted so it appears a HDMI display
-##     is attached
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Disabled (Default)
-##     1        Use HDMI mode even if no HDMI monitor is detected
-##
-#hdmi_force_hotplug=1
-
-## hdmi_ignore_hotplug
-##     Pretends HDMI hotplug signal is not asserted so it appears a HDMI
-##     display is not attached
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Disabled (Default)
-##     1        Use composite mode even if HDMI monitor is detected
-##
-#hdmi_ignore_hotplug=1
-
-## hdmi_drive
-##     chooses between HDMI and DVI modes
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     1        Normal DVI mode (No sound)
-##     2        Normal HDMI mode (Sound will be sent if supported and enabled)
-##
-#hdmi_drive=2
-
-## hdmi_ignore_edid
-##     Enables the ignoring of EDID/display data
-##
-#hdmi_ignore_edid=0xa5000080
-
-## hdmi_edid_file
-##     Read the EDID data from the edid.dat file instead of from the attached
-##     device
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Read EDID data from attached device (Default)
-##     1        Read EDID data from edid.txt file
-##
-#hdmi_edid_file=1
-
-## hdmi_ignore_edid_audio
-##     Pretends all audio formats are unsupported by display. This means ALSA
-##     will default to analogue.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use EDID provided values (Default)
-##     1        Pretend all audio formats are unsupported
-##
-#hdmi_ignore_edid_audio=1
-
-## hdmi_force_edid_audio
-##     Pretends all audio formats are supported by display, allowing
-##     passthrough of DTS/AC3 even when not reported as supported.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use EDID provided values (Default)
-##     1        Pretend all audio formats are supported
-##
-#hdmi_force_edid_audio=1
-
-## hdmi_force_edid_3d
-##     Pretends all CEA modes support 3D even when edid doesn't indicate
-##     support for them.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use EDID provided values (Default)
-##     1        Pretend 3D mode is supported
-##
-#hdmi_force_edid_3d=1
-
-## avoid_edid_fuzzy_match
-##     Avoid fuzzy matching of modes described in edid.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use fuzzy matching (Default)
-##     1        Avoid fuzzy matching
-##
-#avoid_edid_fuzzy_match=1
-
-## hdmi_pixel_encoding
-##     Force the pixel encoding mode.
-##     By default it will use the mode requested from edid so shouldn't
-##     need changing.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use EDID provided values (Default)
-##     1        RGB limited   (16-235)
-##     2        RGB full      ( 0-255)
-##     3        YCbCr limited (16-235)
-##     4        YCbCr limited ( 0-255)
-##
-#hdmi_pixel_encoding=1
-
-## hdmi_group
-##     Defines the HDMI type
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Use the preferred group reported by the edid (Default)
-##     1        CEA
-##     2        DMT
-##
-#hdmi_group=1
-
-## hdmi_mode
-##     defines screen resolution in CEA or DMT format
-##
-##     H means 16:9 variant (of a normally 4:3 mode).
-##     2x means pixel doubled (i.e. higher clock rate, with each pixel repeated
-##                                  twice)
-##     4x means pixel quadrupled (i.e. higher clock rate, with each pixel
-##                                     repeated four times)
-##     reduced blanking means fewer bytes are used for blanking within the data
-##                      stream (i.e. lower clock rate, with fewer wasted bytes)
-##
-##     Value    hdmi_group=CEA                  hdmi_group=DMT
-##     -------------------------------------------------------------------------
-##     1        VGA                             640x350   85Hz
-##     2        480p  60Hz                      640x400   85Hz
-##     3        480p  60Hz  H                   720x400   85Hz
-##     4        720p  60Hz                      640x480   60Hz
-##     5        1080i 60Hz                      640x480   72Hz
-##     6        480i  60Hz                      640x480   75Hz
-##     7        480i  60Hz  H                   640x480   85Hz
-##     8        240p  60Hz                      800x600   56Hz
-##     9        240p  60Hz  H                   800x600   60Hz
-##     10       480i  60Hz  4x                  800x600   72Hz
-##     11       480i  60Hz  4x H                800x600   75Hz
-##     12       240p  60Hz  4x                  800x600   85Hz
-##     13       240p  60Hz  4x H                800x600   120Hz
-##     14       480p  60Hz  2x                  848x480   60Hz
-##     15       480p  60Hz  2x H                1024x768  43Hz  DO NOT USE
-##     16       1080p 60Hz                      1024x768  60Hz
-##     17       576p  50Hz                      1024x768  70Hz
-##     18       576p  50Hz  H                   1024x768  75Hz
-##     19       720p  50Hz                      1024x768  85Hz
-##     20       1080i 50Hz                      1024x768  120Hz
-##     21       576i  50Hz                      1152x864  75Hz
-##     22       576i  50Hz  H                   1280x768        reduced blanking
-##     23       288p  50Hz                      1280x768  60Hz
-##     24       288p  50Hz  H                   1280x768  75Hz
-##     25       576i  50Hz  4x                  1280x768  85Hz
-##     26       576i  50Hz  4x H                1280x768  120Hz reduced blanking
-##     27       288p  50Hz  4x                  1280x800        reduced blanking
-##     28       288p  50Hz  4x H                1280x800  60Hz
-##     29       576p  50Hz  2x                  1280x800  75Hz
-##     30       576p  50Hz  2x H                1280x800  85Hz
-##     31       1080p 50Hz                      1280x800  120Hz reduced blanking
-##     32       1080p 24Hz                      1280x960  60Hz
-##     33       1080p 25Hz                      1280x960  85Hz
-##     34       1080p 30Hz                      1280x960  120Hz reduced blanking
-##     35       480p  60Hz  4x                  1280x1024 60Hz
-##     36       480p  60Hz  4x H                1280x1024 75Hz
-##     37       576p  50Hz  4x                  1280x1024 85Hz
-##     38       576p  50Hz  4x H                1280x1024 120Hz reduced blanking
-##     39       1080i 50Hz  reduced blanking    1360x768  60Hz
-##     40       1080i 100Hz                     1360x768  120Hz reduced blanking
-##     41       720p  100Hz                     1400x1050       reduced blanking
-##     42       576p  100Hz                     1400x1050 60Hz
-##     43       576p  100Hz H                   1400x1050 75Hz
-##     44       576i  100Hz                     1400x1050 85Hz
-##     45       576i  100Hz H                   1400x1050 120Hz reduced blanking
-##     46       1080i 120Hz                     1440x900        reduced blanking
-##     47       720p  120Hz                     1440x900  60Hz
-##     48       480p  120Hz                     1440x900  75Hz
-##     49       480p  120Hz H                   1440x900  85Hz
-##     50       480i  120Hz                     1440x900  120Hz reduced blanking
-##     51       480i  120Hz H                   1600x1200 60Hz
-##     52       576p  200Hz                     1600x1200 65Hz
-##     53       576p  200Hz H                   1600x1200 70Hz
-##     54       576i  200Hz                     1600x1200 75Hz
-##     55       576i  200Hz H                   1600x1200 85Hz
-##     56       480p  240Hz                     1600x1200 120Hz reduced blanking
-##     57       480p  240Hz H                   1680x1050       reduced blanking
-##     58       480i  240Hz                     1680x1050 60Hz
-##     59       480i  240Hz H                   1680x1050 75Hz
-##     60                                       1680x1050 85Hz
-##     61                                       1680x1050 120Hz reduced blanking
-##     62                                       1792x1344 60Hz
-##     63                                       1792x1344 75Hz
-##     64                                       1792x1344 120Hz reduced blanking
-##     65                                       1856x1392 60Hz
-##     66                                       1856x1392 75Hz
-##     67                                       1856x1392 120Hz reduced blanking
-##     68                                       1920x1200       reduced blanking
-##     69                                       1920x1200 60Hz
-##     70                                       1920x1200 75Hz
-##     71                                       1920x1200 85Hz
-##     72                                       1920x1200 120Hz reduced blanking
-##     73                                       1920x1440 60Hz
-##     74                                       1920x1440 75Hz
-##     75                                       1920x1440 120Hz reduced blanking
-##     76                                       2560x1600       reduced blanking
-##     77                                       2560x1600 60Hz
-##     78                                       2560x1600 75Hz
-##     79                                       2560x1600 85Hz
-##     80                                       2560x1600 120Hz reduced blanking
-##     81                                       1366x768  60Hz
-##     82                                       1080p     60Hz
-##     83                                       1600x900        reduced blanking
-##     84                                       2048x1152       reduced blanking
-##     85                                       720p      60Hz
-##     86                                       1366x768        reduced blanking
-##
-#hdmi_mode=1
-
-## config_hdmi_boost
-##     configure the signal strength of the HDMI interface.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        (Default)
-##     1
-##     2
-##     3
-##     4        Try if you have interference issues with HDMI
-##     5
-##     6
-##     7        Maximum
-##
-#config_hdmi_boost=0
-
-## hdmi_ignore_cec_init
-##     Doesn't sent initial active source message.  Avoids bringing
-##     (CEC enabled) TV out of standby and channel switch when rebooting.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Normal behaviour (Default)
-##     1        Doesn't sent initial active source message
-##
-#hdmi_ignore_cec_init=1
-
-## hdmi_ignore_cec
-##     Pretends CEC is not supported at all by TV.
-##     No CEC functions will be supported.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Normal behaviour (Default)
-##     1        Pretend CEC is not supported by TV
-##
-#hdmi_ignore_cec=1
-
-################################################################################
-##  Overscan Video Settings
-################################################################################
-
-## overscan_left
-##     Number of pixels to skip on left
-##
-#overscan_left=0
-
-## overscan_right
-##     Number of pixels to skip on right
-##
-#overscan_right=0
-
-## overscan_top
-##     Number of pixels to skip on top
-##
-#overscan_top=0
-
-## overscan_bottom
-##     Number of pixels to skip on bottom
-##
-#overscan_bottom=0
-
-## disable_overscan
-##     Set to 1 to disable overscan
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Overscan Enabled (Default)
-##     1        Overscan Disabled
-##
-#disable_overscan=1
-
-################################################################################
-##  Framebuffer Video Settings
-################################################################################
-
-## framebuffer_width
-##     Console framebuffer width in pixels. Default is display width minus
-##     overscan.
-##
-#framebuffer_width=0
-
-## framebuffer_height
-##     Console framebuffer height in pixels. Default is display height minus
-##     overscan.
-##
-#framebuffer_height=0
-
-## framebuffer_depth
-##     Console framebuffer depth in bits per pixel.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     8        Valid, but default RGB palette makes an unreadable screen
-##     16       (Default)
-##     24       Looks better but has corruption issues as of 2012/06/15
-##     32       Has no corruption issues but needs framebuffer_ignore_alpha=1
-##              and shows the wrong colors as of 2012/06/15
-##
-#framebuffer_depth=16
-
-## framebuffer_ignore_alpha
-##     Set to 1 to disable alpha channel. Helps with 32bit.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Enable Alpha Channel (Default)
-##     1        Disable Alpha Channel
-##
-#framebuffer_ignore_alpha=0
-
-################################################################################
-##  General Video Settings
-################################################################################
-
-## display_rotate
-##     Rotate the display clockwise or flip the display.
-##     The 90 and 270 degrees rotation options require additional memory on GPU,
-##     so won't work with the 16M GPU split.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        0 degrees (Default)
-##     1        90 degrees
-##     2        180 degrees
-##     3        270 degrees
-##     0x10000  Horizontal flip
-##     0x20000  Vertical flip
-##
-##    Note: latest firmware deprecates display_rotate so use these instead.
-#display_hdmi_rotate=0
-#display_lcd_rotate=0
-
-## dispmanx_offline
-##     Set to "1" to enable offline compositing
-##
-##     Default 0
-##
-#dispmanx_offline=0
-
-################################################################################
-##  Licensed Codecs
-##
-##  Hardware decoding of additional codecs can be enabled by purchasing a
-##  license that is locked to the CPU serial number of your Raspberry Pi.
-##
-##  Up to 8 licenses per CODEC can be specified as a comma seperated list.
-##
-################################################################################
-
-## decode_MPG2
-##     License key to allow hardware MPEG-2 decoding.
-##
-#decode_MPG2=0x12345678
-
-## decode_WVC1
-##     License key to allow hardware VC-1 decoding.
-##
-#decode_WVC1=0x12345678
-
-################################################################################
-##  Camera Settings
-################################################################################
-
-## start_x
-##     Set to "1" to enable the camera module.
-##
-##     Enabling the camera requires gpu_mem option to be specified with a value
-##     of at least 128.
-##
-##     Default 0
-##
-#start_x=0
-
-## disable_camera_led
-##     Turn off the red camera led when recording video or taking a still
-##     picture.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        LED enabled (Default)
-##     1        LED disabled
-##
-#disable_camera_led=1
-
-################################################################################
-##  Test Settings
-################################################################################
-
-## test_mode
-##     Enable test sound/image during boot for manufacturing test.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Disable Test Mod (Default)
-##     1        Enable Test Mode
-##
-#test_mode=0
-
-################################################################################
-##  Memory Settings
-################################################################################
-
-## disable_l2cache
-##     Disable arm access to GPU's L2 cache. Needs corresponding L2 disabled
-##     kernel.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Enable L2 Cache (Default)
-##     1        Disable L2 cache
-##
-#disable_l2cache=0
-
-## gpu_mem
-##     GPU memory allocation in MB for all board revisions.
-##
-##     Default 64
-##
-#gpu_mem=128
-
-## gpu_mem_256
-##     GPU memory allocation in MB for 256MB board revision.
-##     This option overrides gpu_mem.
-##
-#gpu_mem_256=192
-
-## gpu_mem_512
-##     GPU memory allocation in MB for 512MB board revision.
-##     This option overrides gpu_mem.
-##
-#gpu_mem_512=448
-
-## gpu_mem_1024
-##     GPU memory allocation in MB for 1024MB board revision.
-##     This option overrides gpu_mem.
-##
-#gpu_mem_1024=944
-
-## disable_pvt
-##     Disable adjusting the refresh rate of RAM every 500ms
-##     (measuring RAM temparature).
-##
-#disable_pvt=1
-
-################################################################################
-##  CMA - Dynamic Memory Split
-##
-##  CMA enables dynamic management of the ARM and GPU memory split at runtime.
-##
-##  The following options need to be in cmdline.txt for CMA to work:
-##    coherent_pool=6M smsc95xx.turbo_mode=N
-##
-################################################################################
-
-## cma_lwm
-##     When GPU has less than cma_lwm (low water mark) memory available it
-##     will request some from ARM.
-##
-#cma_lwm=16
-
-## cma_hwm
-##     When GPU has more than cma_hwm (high water mark) memory available it
-##     will release some to ARM.
-##
-#cma_hwm=32
-
-################################################################################
-##  Boot Option Settings
-################################################################################
-
-## disable_commandline_tags
-##     Stop start.elf from filling in ATAGS (memory from 0x100) before
-##     launching kernel
-##
-#disable_commandline_tags=0
-
-## cmdline (string)
-##     Command line parameters. Can be used instead of cmdline.txt file
-##
-#cmdline=""
-
-## kernel (string)
-##     Alternative name to use when loading kernel.
-##
-#kernel=""
-
-## kernel_address
-##     Address to load kernel.img file at
-##
-#kernel_address=0x00000000
-
-## kernel_old
-##     Support loading old kernels
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Disabled (Default)
-##     1        Load kernel at address 0x00000000
-##
-#kernel_old=1
-
-## ramfsfile (string)
-##     ramfs file to load
-##
-#ramfsfile=""
-
-## ramfsaddr
-##     Address to load ramfs file at
-##
-#ramfsaddr=0x00000000
-
-## initramfs (string address)
-##     ramfs file and address to load it at (it's like ramfsfile+ramfsaddr in
-##     one option).
-##
-##     NOTE: this option uses different syntax than all other options - you
-##           should not use "=" character here.
-##
-#initramfs initramf.gz 0x00800000
-
-## device_tree_address
-##     Address to load device_tree at
-##
-#device_tree_address=0x00000000
-
-## init_uart_baud
-##     Initial uart baud rate.
-##
-##     Default 115200
-##
-#init_uart_baud=115200
-
-## init_uart_clock
-##     Initial uart clock.
-##
-##     Default 3000000 (3MHz)
-##
-#init_uart_clock=3000000
-
-## init_emmc_clock
-##     Initial emmc clock, increasing this can speedup your SD-card.
-##
-##     Default 100000000 (100mhz)
-##
-#init_emmc_clock=100000000
-
-## boot_delay
-##     Wait for a given number of seconds in start.elf before loading
-##     kernel.img.
-##
-##     delay = (1000 * boot_delay) + boot_delay_ms
-##
-##     Default 1
-##
-#boot_delay=0
-
-## boot_delay_ms
-##     Wait for a given number of milliseconds in start.elf before loading
-##     kernel.img.
-##
-##     delay = (1000 * boot_delay) + boot_delay_ms
-##
-##     Default 0
-##
-#boot_delay_ms=0
-
-## avoid_safe_mode
-##     Adding a jumper between pins 5 & 6 of P1 enables a recovery Safe Mode.
-##     If pins 5 & 6 are used for connecting to external devices (e.g. GPIO),
-##     then this setting can be used to ensure Safe Mode is not triggered.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Respect Safe Mode input (Default)
-##     1        Ignore Safe Mode input
-##
-#avoid_safe_mode=1
-
-## disable_splash
-##     Avoids the rainbow splash screen on boot.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Splash screen enabled (Default)
-##     1        Splash screen disabled
-##
-#disable_splash=1
-
-################################################################################
-##  Overclocking Settings
-##
-##  ARM, SDRAM and GPU each have their own PLLs and can have unrelated
-##  frequencies.
-##
-##  The GPU core, h264, v3d and isp share a PLL, so need to have related
-##  frequencies.
-##  pll_freq = floor(2400 / (2 * core_freq)) * (2 * core_freq)
-##  gpu_freq = pll_freq / [even number]
-##
-##  The effective gpu_freq is automatically rounded to nearest even integer, so
-##  asking for core_freq = 500 and gpu_freq = 300 will result in divisor of
-##  2000/300 = 6.666 => 6 and so 333.33MHz.
-##
-##
-##  Standard Profiles:
-##                  arm_freq    core_freq    sdram_freq    over_voltage
-##     -------------------------------------------------------------------------
-##     None         700         250          400           0
-##     Modest       800         300          400           0
-##     Medium       900         333          450           2
-##     High         950         450          450           6
-##     Turbo        1000        500          500           6
-##
-################################################################################
-
-## force_turbo
-##     Control the kernel "ondemand" governor. It has no effect if no overclock
-##     settings are specified.
-##     May set warrany bit.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Enable dynamic clocks and voltage for the ARM core, GPU core and
-##              SDRAM (Default).
-##              Overclocking of h264_freq, v3d_freq and isp_freq is ignored.
-##     1        Disable dynamic clocks and voltage for the ARM core, GPU core
-##              and SDRAM.
-##              Overclocking of h264_freq, v3d_freq and isp_freq is allowed.
-##
-#force_turbo=0
-
-## initial_turbo
-##     Enables turbo mode from boot for the given value in seconds (up to 60)
-##     or until cpufreq sets a frequency. Can help with sdcard corruption if
-##     overclocked.
-##
-##     Default 0
-##
-#initial_turbo=0
-
-## temp_limit
-##     Overheat protection. Sets clocks and voltages to default when the SoC
-##     reaches this Celsius value.
-##     Setting this higher than default voids warranty.
-##
-##     Default 85
-##
-#temp_limit=85
-
-## arm_freq
-##     Frequency of ARM in MHz.
-##
-##     Default 700.
-##
-#arm_freq=700
-
-## arm_freq_min
-##     Minimum frequency of ARM in MHz (used for dynamic clocking).
-##
-##     Default 700.
-##
-#arm_freq_min=700
-
-## gpu_freq
-##     Sets core_freq, h264_freq, isp_freq, v3d_freq together.
-##
-##     Default 250.
-##
-#gpu_freq=250
-
-## core_freq
-##     Frequency of GPU processor core in MHz. It has an impact on ARM
-##     performance since it drives L2 cache.
-##
-##     Default 250.
-##
-#core_freq=250
-
-## core_freq_min
-##     Minimum frequency of GPU processor core in MHz (used for dynamic
-##     clocking). It has an impact on ARM performance since it drives L2 cache.
-##
-##     Default 250.
-##
-#core_freq_min=250
-
-## h264_freq
-##     Frequency of hardware video block in MHz.
-##
-##     Default 250.
-##
-#h264_freq=250
-
-## isp_freq
-##     Frequency of image sensor pipeline block in MHz.
-##
-##     Default 250.
-##
-#isp_freq=250
-
-## v3d_freq
-##     Frequency of 3D block in MHz.
-##
-##     Default 250.
-##
-#v3d_freq=250
-
-## sdram_freq
-##     Frequency of SDRAM in MHz.
-##
-##     Default 400.
-##
-#sdram_freq=400
-
-## sdram_freq_min
-##     Minimum frequency of SDRAM in MHz (used for dynamic clocking).
-##
-##     Default 400.
-##
-#sdram_freq_min=400
-
-## avoid_pwm_pll
-##     Don't dedicate a pll to PWM audio. This will reduce analogue audio
-##     quality slightly. The spare PLL allows the core_freq to be set
-##     independently from the rest of the gpu allowing more control over
-##     overclocking.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     0        Linked core_freq (Default)
-##     1        Unlinked core_freq
-##
-#avoid_pwm_pll=1
-
-################################################################################
-##  Voltage Settings
-################################################################################
-
-## current_limit_override
-##     Disables SMPS current limit protection. Can help if you are currently
-##     hitting a reboot failure when overclocking too high.
-##     May set warrany bit.
-##
-#current_limit_override=0x5A000020
-
-## over_voltage
-##     ARM/GPU core voltage adjust.
-##     May set warrany bit.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V (requires force_turbo=1 or current_limit_override)
-##     8        1.4   V (requires force_turbo=1 or current_limit_override)
-##
-#over_voltage=0
-
-## over_voltage_min
-##     Minimum ARM/GPU core voltage adjust (used for dynamic clocking).
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V (requires force_turbo=1)
-##     8        1.4   V (requires force_turbo=1)
-##
-#over_voltage_min=0
-
-## over_voltage_sdram
-##     Sets over_voltage_sdram_c, over_voltage_sdram_i, over_voltage_sdram_p
-##     together
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V
-##     8        1.4   V
-##
-#over_voltage_sdram=0
-
-## over_voltage_sdram_c
-##     SDRAM controller voltage adjust.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V
-##     8        1.4   V
-##
-#over_voltage_sdram_c=0
-
-## over_voltage_sdram_i
-##     SDRAM I/O voltage adjust.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V
-##     8        1.4   V
-##
-#over_voltage_sdram_i=0
-
-## over_voltage_sdram_p
-##     SDRAM phy voltage adjust.
-##
-##     Value    Description
-##     -------------------------------------------------------------------------
-##     -16      0.8   V
-##     -15      0.825 V
-##     -14      0.85  V
-##     -13      0.875 V
-##     -12      0.9   V
-##     -11      0.925 V
-##     -10      0.95  V
-##     -9       0.975 V
-##     -8       1.0   V
-##     -7       1.025 V
-##     -6       1.05  V
-##     -5       1.075 V
-##     -4       1.1   V
-##     -3       1.125 V
-##     -2       1.15  V
-##     -1       1.175 V
-##     0        1.2   V (Default)
-##     1        1.225 V
-##     2        1.25  V
-##     3        1.275 V
-##     4        1.3   V
-##     5        1.325 V
-##     6        1.35  V
-##     7        1.375 V
-##     8        1.4   V
-##
-#over_voltage_sdram_p=0
-
-################################################################################
-##  USB Power
-################################################################################
-
-## max_usb_current
-##     When set to 1, change the output current limit (for all 4 USB
-##     ports combined) from 600mA to double that, 1200mA.
-##
-##     This option is not available for Model A/B boards.
-##
-##     Default 0.
-##
-#max_usb_current=0
-
-################################################################################
-##  Base Device Tree Parameters
-################################################################################
-
-## audio
-##     Enable the onboard ALSA audio
-##
-##     Default off.
-##
-#dtparam=audio=off
-
-## i2c_arm
-##     Enable the ARM's i2c interface
-##
-##     Default off.
-##
-#dtparam=i2c_arm=off
-
-## i2c_vc
-##     Enable the i2c interface
-##
-##     Usually reserved for the VideoCore processor
-##
-##     Default off.
-##
-#dtparam=i2c_vc=off
-
-## i2c_arm_baudrate
-##     Set the baudrate of the ARM's i2c interface
-##
-##     Default 100000.
-##
-#dtparam=i2c_arm_baudrate=100000
-
-## i2c_vc_baudrate
-##     Set the baudrate of the VideoCore i2c interface
-##
-##     Default 100000.
-##
-#dtparam=i2c_vc_baudrate=100000
-
-## i2s
-##     Set to "on" to enable the i2s interface
-##
-##     Default off.
-##
-#dtparam=i2s=off
-
-## spi
-##     Set to "on" to enable the spi interfaces
-##
-##     Default off.
-##
-#dtparam=spi=off
-
-## random
-##     Set to "on" to enable the hardware random
-##
-##     Default off.
-##
-#dtparam=random=off
-
-## uart0
-##     Set to "off" to disable uart0
-##
-##     Default on.
-##
-#dtparam=uart0=on
-
-## watchdog
-##     Set to "on" to enable the hardware watchdog
-##
-##     Default off.
-##
-#dtparam=watchdog=off
-
-## act_led_trigger
-##     Choose which activity the LED tracks.
-##
-##     Use "heartbeat" for a nice load indicator.
-##
-##     Default mmc.
-##
-#dtparam=act_led_trigger=mmc
-
-## act_led_activelow
-##     Set to "on" to invert the sense of the LED
-##
-##     Default off.
-##
-#dtparam=act_led_activelow=off
-
-## act_led_gpio
-##     Set which GPIO to use for the activity LED
-##
-##     In case you want to connect it to an external device
-##
-##     Default 16 on a non-Plus board, 47 on a Plus or Pi 2.
-##
-#dtparam=act_led_gpio=47
-
-## pwr_led_trigger
-##     Choose which activity the LED tracks.
-##
-##     Use "heartbeat" for a nice load indicator.
-##
-##     Not available on Model A/B boards.
-##
-##     Default mmc.
-##
-#dtparam=pwr_led_trigger=mmc
-
-## pwr_led_activelow
-##     Set to "on" to invert the sense of the LED
-##
-##     Not available on Model A/B boards.
-##
-##     Default off.
-##
-#dtparam=pwr_led_activelow=off
-
-## pwr_led_gpio
-##     Set which GPIO to use for the PWR LED
-##
-##     In case you want to connect it to an external device
-##
-##     Not available on Model A/B boards.
-##
-##     Default 35.
-##
-#dtparam=pwr_led_gpio=35
-
-dtoverlay=dwc2
-dtparam=spi=on
-dtoverlay=spi1-3cs
-
-# Disable bluetooth
-dtoverlay=pi3-disable-bt
-# Disable audio
-dtparam=audio=off
-
diff --git a/sdcard/boot/ssh b/sdcard/boot/ssh
deleted file mode 100644
index e69de29..0000000
diff --git a/sdcard/rootfs/etc/hostname b/sdcard/rootfs/etc/hostname
deleted file mode 100644
index 4a58007..0000000
--- a/sdcard/rootfs/etc/hostname
+++ /dev/null
@@ -1 +0,0 @@
-alpha
diff --git a/sdcard/rootfs/etc/hosts b/sdcard/rootfs/etc/hosts
deleted file mode 100644
index 02498b0..0000000
--- a/sdcard/rootfs/etc/hosts
+++ /dev/null
@@ -1,6 +0,0 @@
-127.0.0.1       localhost alpha alpha.local
-::1             localhost ip6-localhost ip6-loopback
-fe00::0         ip6-localnet
-ff00::0         ip6-mcastprefix
-ff02::1         ip6-allnodes
-ff02::2         ip6-allrouters
diff --git a/sdcard/rootfs/etc/motd b/sdcard/rootfs/etc/motd
deleted file mode 100644
index 6c86778..0000000
--- a/sdcard/rootfs/etc/motd
+++ /dev/null
@@ -1 +0,0 @@
-(◕‿‿◕) alpha (pwnagotchi)
diff --git a/sdcard/rootfs/etc/network/interfaces b/sdcard/rootfs/etc/network/interfaces
deleted file mode 100644
index 2c84f3c..0000000
--- a/sdcard/rootfs/etc/network/interfaces
+++ /dev/null
@@ -1,17 +0,0 @@
-auto lo
-
-iface lo inet loopback
-
-allow-hotplug wlan0
-iface wlan0 inet static
-
-allow-hotplug eth0
-iface eth0 inet dhcp
-
-allow-hotplug usb0
-iface usb0 inet static
-        address 10.0.0.2
-        netmask 255.255.255.0
-        network 10.0.0.0
-        broadcast 10.0.0.255
-        gateway 10.0.0.1
diff --git a/sdcard/rootfs/etc/rc.local b/sdcard/rootfs/etc/rc.local
deleted file mode 100755
index bab03e6..0000000
--- a/sdcard/rootfs/etc/rc.local
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh -e
-#
-# rc.local
-#
-# This script is executed at the end of each multiuser runlevel.
-# Make sure that the script will "exit 0" on success or any other
-# value on error.
-#
-# In order to enable or disable this script just change the execution
-# bits.
-#
-# By default this script does nothing.
-# Powersave (Disable HDMI) ~30ma
-sleep 10
-if ! /opt/vc/bin/tvservice -s | grep HDMI; then
-  /opt/vc/bin/tvservice -o
-fi
-/root/pwnagotchi/scripts/startup.sh &
-exit 0
diff --git a/sdcard/rootfs/etc/ssh/sshd_config b/sdcard/rootfs/etc/ssh/sshd_config
deleted file mode 100644
index e2f34f6..0000000
--- a/sdcard/rootfs/etc/ssh/sshd_config
+++ /dev/null
@@ -1,121 +0,0 @@
-#	$OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
-
-# This is the sshd server system-wide configuration file.  See
-# sshd_config(5) for more information.
-
-# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
-
-# The strategy used for options in the default sshd_config shipped with
-# OpenSSH is to specify options with their default value where
-# possible, but leave them commented.  Uncommented options override the
-# default value.
-
-#Port 22
-#AddressFamily any
-#ListenAddress 0.0.0.0
-#ListenAddress ::
-
-#HostKey /etc/ssh/ssh_host_rsa_key
-#HostKey /etc/ssh/ssh_host_ecdsa_key
-#HostKey /etc/ssh/ssh_host_ed25519_key
-
-# Ciphers and keying
-#RekeyLimit default none
-
-# Logging
-#SyslogFacility AUTH
-#LogLevel INFO
-
-# Authentication:
-
-#LoginGraceTime 2m
-PermitRootLogin yes
-#StrictModes yes
-#MaxAuthTries 6
-#MaxSessions 10
-
-#PubkeyAuthentication yes
-
-# Expect .ssh/authorized_keys2 to be disregarded by default in future.
-#AuthorizedKeysFile	.ssh/authorized_keys .ssh/authorized_keys2
-
-#AuthorizedPrincipalsFile none
-
-#AuthorizedKeysCommand none
-#AuthorizedKeysCommandUser nobody
-
-# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
-#HostbasedAuthentication no
-# Change to yes if you don't trust ~/.ssh/known_hosts for
-# HostbasedAuthentication
-#IgnoreUserKnownHosts no
-# Don't read the user's ~/.rhosts and ~/.shosts files
-#IgnoreRhosts yes
-
-# To disable tunneled clear text passwords, change to no here!
-#PasswordAuthentication yes
-#PermitEmptyPasswords no
-
-# Change to yes to enable challenge-response passwords (beware issues with
-# some PAM modules and threads)
-ChallengeResponseAuthentication no
-
-# Kerberos options
-#KerberosAuthentication no
-#KerberosOrLocalPasswd yes
-#KerberosTicketCleanup yes
-#KerberosGetAFSToken no
-
-# GSSAPI options
-#GSSAPIAuthentication no
-#GSSAPICleanupCredentials yes
-#GSSAPIStrictAcceptorCheck yes
-#GSSAPIKeyExchange no
-
-# Set this to 'yes' to enable PAM authentication, account processing,
-# and session processing. If this is enabled, PAM authentication will
-# be allowed through the ChallengeResponseAuthentication and
-# PasswordAuthentication.  Depending on your PAM configuration,
-# PAM authentication via ChallengeResponseAuthentication may bypass
-# the setting of "PermitRootLogin without-password".
-# If you just want the PAM account and session checks to run without
-# PAM authentication, then enable this but set PasswordAuthentication
-# and ChallengeResponseAuthentication to 'no'.
-UsePAM yes
-
-#AllowAgentForwarding yes
-#AllowTcpForwarding yes
-#GatewayPorts no
-X11Forwarding yes
-#X11DisplayOffset 10
-#X11UseLocalhost yes
-#PermitTTY yes
-PrintMotd no
-#PrintLastLog yes
-#TCPKeepAlive yes
-#PermitUserEnvironment no
-#Compression delayed
-#ClientAliveInterval 0
-#ClientAliveCountMax 3
-#UseDNS no
-#PidFile /var/run/sshd.pid
-#MaxStartups 10:30:100
-#PermitTunnel no
-#ChrootDirectory none
-#VersionAddendum none
-
-# no default banner path
-#Banner none
-
-# Allow client to pass locale environment variables
-AcceptEnv LANG LC_*
-
-# override default of no subsystems
-Subsystem	sftp	/usr/lib/openssh/sftp-server
-
-# Example of overriding settings on a per-user basis
-#Match User anoncvs
-#	X11Forwarding no
-#	AllowTcpForwarding no
-#	PermitTTY no
-#	ForceCommand cvs server
diff --git a/sdcard/rootfs/root/pwnagotchi/data/images/face_happy.bmp b/sdcard/rootfs/root/pwnagotchi/data/images/face_happy.bmp
deleted file mode 100644
index 8f3e857..0000000
Binary files a/sdcard/rootfs/root/pwnagotchi/data/images/face_happy.bmp and /dev/null differ
diff --git a/sdcard/rootfs/root/pwnagotchi/data/screenrc.auto b/sdcard/rootfs/root/pwnagotchi/data/screenrc.auto
deleted file mode 100644
index 9319672..0000000
--- a/sdcard/rootfs/root/pwnagotchi/data/screenrc.auto
+++ /dev/null
@@ -1,49 +0,0 @@
-defutf8 on
-
-shell -${SHELL}
-defscrollback 1024
-startup_message off
-altscreen on
-autodetach on
-zombie kr
-
-activity        "activity in %n (%t)"
-bell_msg        "bell in %n (%t)"
-
-vbell           on
-vbell_msg       "WTF DUDE ??!!"
-vbellwait       1
-
-# set terminal emulator to xterm mode
-term xterm
-# Make the output buffer large for (fast) xterms.
-termcapinfo xterm* ti@:te@
-# tell screen how to set colors
-termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
-# allow bold colors
-attrcolor b ".I"
-# erase background with current bg color
-defbce "on"
-
-# ctrl + { left, right }
-bindkey ^[[1;5D prev
-bindkey ^[[1;5C next
-bindkey ^[[5D prev
-bindkey ^[[5C next
-bindkey ^[b prev
-bindkey ^[f next
-bindkey ^[[D prev
-bindkey ^[[C next
-
-screen -t shell
-screen -t auto-mode /bin/bash -c "/root/pwnagotchi/scripts/main.py"
-screen -t bettercap /usr/bin/bettercap -caplet http-ui -eval "!/usr/bin/monstart; set wifi.interface mon0"
-
-select log
-
-backtick 1 0 0 cpuusage
-backtick 2 5 5 memusage
-
-hardstatus alwayslastline
-hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][cpu %1`][mem %2`][%{B} %m-%d %{W}%c %{g}]'
-
diff --git a/sdcard/rootfs/root/pwnagotchi/data/screenrc.manual b/sdcard/rootfs/root/pwnagotchi/data/screenrc.manual
deleted file mode 100644
index 1d62528..0000000
--- a/sdcard/rootfs/root/pwnagotchi/data/screenrc.manual
+++ /dev/null
@@ -1,49 +0,0 @@
-defutf8 on
-
-shell -${SHELL}
-defscrollback 1024
-startup_message off
-altscreen on
-autodetach on
-zombie kr
-
-activity        "activity in %n (%t)"
-bell_msg        "bell in %n (%t)"
-
-vbell           on
-vbell_msg       "WTF DUDE ??!!"
-vbellwait       1
-
-# set terminal emulator to xterm mode
-term xterm
-# Make the output buffer large for (fast) xterms.
-termcapinfo xterm* ti@:te@
-# tell screen how to set colors
-termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
-# allow bold colors
-attrcolor b ".I"
-# erase background with current bg color
-defbce "on"
-
-# ctrl + { left, right }
-bindkey ^[[1;5D prev
-bindkey ^[[1;5C next
-bindkey ^[[5D prev
-bindkey ^[[5C next
-bindkey ^[b prev
-bindkey ^[f next
-bindkey ^[[D prev
-bindkey ^[[C next
-
-screen -t shell
-screen -t manual-mode /bin/bash -c "/root/pwnagotchi/scripts/main.py --manual"
-screen -t bettercap /usr/bin/bettercap -caplet http-ui -eval "!/usr/bin/monstart; set wifi.interface mon0"
-
-select log
-
-backtick 1 0 0 cpuusage
-backtick 2 5 5 memusage
-
-hardstatus alwayslastline
-hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][cpu %1`][mem %2`][%{B} %m-%d %{W}%c %{g}]'
-
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/blink.sh b/sdcard/rootfs/root/pwnagotchi/scripts/blink.sh
deleted file mode 100755
index 6ad62a3..0000000
--- a/sdcard/rootfs/root/pwnagotchi/scripts/blink.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-
-for i in $(seq 1 "$1");
-do
-	echo 0 >/sys/class/leds/led0/brightness
-	sleep 0.3
-	echo 1 >/sys/class/leds/led0/brightness
-	sleep 0.3
-done
-
-echo 0 >/sys/class/leds/led0/brightness
-sleep 0.3
\ No newline at end of file
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/main.py b/sdcard/rootfs/root/pwnagotchi/scripts/main.py
deleted file mode 100755
index 60469e8..0000000
--- a/sdcard/rootfs/root/pwnagotchi/scripts/main.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/python3
-import argparse
-import time
-import logging
-
-import pwnagotchi
-import pwnagotchi.utils as utils
-import pwnagotchi.plugins as plugins
-
-from pwnagotchi.log import SessionParser
-from pwnagotchi.agent import Agent
-from pwnagotchi.ui.display import Display
-
-parser = argparse.ArgumentParser()
-
-parser.add_argument('-C', '--config', action='store', dest='config', default='/root/pwnagotchi/config.yml',
-                    help='Main configuration file.')
-parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/root/custom.yml',
-                    help='If this file exists, configuration will be merged and this will override default values.')
-
-parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
-parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
-                    help="Clear the ePaper display and exit.")
-
-parser.add_argument('--debug', dest="debug", action="store_true", default=False,
-                    help="Enable debug logs.")
-
-args = parser.parse_args()
-config = utils.load_config(args)
-utils.setup_logging(args, config)
-
-plugins.load(config)
-
-display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
-agent = Agent(view=display, config=config)
-
-logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent._identity, pwnagotchi.version))
-
-for _, plugin in plugins.loaded.items():
-    logging.debug("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
-
-if args.do_clear:
-    logging.info("clearing the display ...")
-    display.clear()
-
-elif args.do_manual:
-    logging.info("entering manual mode ...")
-
-    log = SessionParser(config)
-    logging.info(
-        "the last session lasted %s (%d completed epochs, trained for %d), average reward:%s (min:%s max:%s)" % (
-            log.duration_human,
-            log.epochs,
-            log.train_epochs,
-            log.avg_reward,
-            log.min_reward,
-            log.max_reward))
-
-    while True:
-        display.on_manual_mode(log)
-        time.sleep(1)
-
-        if Agent.is_connected():
-            plugins.on('internet_available', display, config, log)
-
-else:
-    logging.info("entering auto mode ...")
-
-    agent.start()
-
-    while True:
-        try:
-            # recon on all channels
-            agent.recon()
-            # get nearby access points grouped by channel
-            channels = agent.get_access_points_by_channel()
-            # check for free channels to use
-            agent.check_channels(channels)
-            # for each channel
-            for ch, aps in channels:
-                agent.set_channel(ch)
-
-                if not agent.is_stale() and agent.any_activity():
-                    logging.info("%d access points on channel %d" % (len(aps), ch))
-
-                # for each ap on this channel
-                for ap in aps:
-                    # send an association frame in order to get for a PMKID
-                    agent.associate(ap)
-                    # deauth all client stations in order to get a full handshake
-                    for sta in ap['clients']:
-                        agent.deauth(ap, sta)
-
-            # An interesting effect of this:
-            #
-            # From Pwnagotchi's perspective, the more new access points
-            # and / or client stations nearby, the longer one epoch of
-            # its relative time will take ... basically, in Pwnagotchi's universe,
-            # WiFi electromagnetic fields affect time like gravitational fields
-            # affect ours ... neat ^_^
-            agent.next_epoch()
-        except Exception as e:
-            logging.exception("main loop exception")
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/requirements.txt b/sdcard/rootfs/root/pwnagotchi/scripts/requirements.txt
deleted file mode 100644
index 8fa5e8a..0000000
--- a/sdcard/rootfs/root/pwnagotchi/scripts/requirements.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Crypto
-requests
-pyyaml
-scapy
-gym
-stable-baselines
-tensorflow
-tweepy
-file_read_backwards
-numpy
-inky
-smbus
-pillow
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/startup.sh b/sdcard/rootfs/root/pwnagotchi/scripts/startup.sh
deleted file mode 100755
index 58b681c..0000000
--- a/sdcard/rootfs/root/pwnagotchi/scripts/startup.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-
-# blink 10 times to signal ready state
-/root/pwnagotchi/scripts/blink.sh 10 &
-
-# start a detached screen session with bettercap
-if ifconfig | grep usb0 | grep RUNNING; then
-    sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.manual
-else
-    sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto
-fi
diff --git a/sdcard/rootfs/usr/bin/cpuusage b/sdcard/rootfs/usr/bin/cpuusage
deleted file mode 100755
index ea9e63a..0000000
--- a/sdcard/rootfs/usr/bin/cpuusage
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/gawk -f
-#-------------------------------------------------------------------------------
-# ~/bin/cpustat :   display cpu utilization
-#
-# usage         :   normally used as a GNU/screen backtick
-#
-# notes         :   1. Works on the assumption that /proc/stat's first line
-#               :      has the total "jiffies" since boot up used by the
-#               :      different types of tasks in the system. See the
-#               :      filesystems/proc.txt document in kernel source tree
-#               :
-#               :   2. Displays a total CPU% (user+system+nice) as well as
-#               :      user CPU% system CPU% and nice CPU%
-#-------------------------------------------------------------------------------
-BEGIN {
-  file = "/proc/stat"
-  while (getline < file) {                        # read first line
-                                                  # extract jiffies:
-      user=$2-user_saved;                         # . user
-      nice=$3-nice_saved;                         # . nice user
-      syst=$4-syst_saved;                         # . system
-      idle=$5-idle_saved;                         # . idle
-      wait=$6-wait_saved;                         # . iowait
-      irqs=$7-irqs_saved;                         # . irq
-      sirq=$8-sirq_saved;                         # . softirq
-
-      cact=user+syst+nice;                        # what counts
-      ctot=user+nice+syst+idle+wait+irqs+sirq;    # total activity
-
-      tcpu=cact/ctot*100;                         # total  % cpu utilization
-      ucpu=user/ctot*100;                         # user   % cpu utilization
-      scpu=syst/ctot*100;                         # system % cpu utilization
-      ncpu=nice/ctot*100;                         # nice   % cpu utilization
-
-      printf "%.1f %%\n",tcpu
-
-
-      user_saved=$2;                              # save the current jiffies
-      nice_saved=$3;                              # values for the next loop
-      syst_saved=$4;
-      idle_saved=$5;
-      wait_saved=$6;
-      irqs_saved=$7;
-      sirq_saved=$8;
-
-      close(file)                                 # re-read file
-
-      system("sleep 3")
-    }
-}
-
diff --git a/sdcard/rootfs/usr/bin/memusage b/sdcard/rootfs/usr/bin/memusage
deleted file mode 100755
index 14efdb1..0000000
--- a/sdcard/rootfs/usr/bin/memusage
+++ /dev/null
@@ -1 +0,0 @@
-free -m | grep Mem | awk {'printf( "%.1f %", $3 / $2 * 100 )'}
diff --git a/sdcard/rootfs/usr/bin/monstart b/sdcard/rootfs/usr/bin/monstart
deleted file mode 100755
index 112c65e..0000000
--- a/sdcard/rootfs/usr/bin/monstart
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-iw phy phy0 interface add mon0 type monitor && ifconfig mon0 up
diff --git a/sdcard/rootfs/usr/bin/monstop b/sdcard/rootfs/usr/bin/monstop
deleted file mode 100755
index 8ca7f89..0000000
--- a/sdcard/rootfs/usr/bin/monstop
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-ifconfig mon0 down && iw dev mon0 del
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..41d7475
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+from setuptools import setup, find_packages
+import pwnagotchi
+
+required = []
+with open('requirements.txt') as fp:
+    for line in fp:
+        line = line.strip()
+        if line != "":
+            required.append(line)
+
+setup(name='pwnagotchi',
+      version=pwnagotchi.version,
+      description='(⌐■_■) - Deep Reinforcement Learning instrumenting bettercap for WiFI pwning.',
+      author='evilsocket && the dev team',
+      author_email='evilsocket@gmail.com',
+      url='https://pwnagotchi.ai/',
+      license='GPL',
+      install_requires=required,
+      scripts=['bin/pwnagotchi'],
+      package_data={'pwnagotchi': ('pwnagotchi/defaults.yml',)},
+      packages=find_packages(),
+      classifiers=[
+          'Programming Language :: Python :: 3',
+          'Development Status :: 5 - Production/Stable',
+          'License :: OSI Approved :: GNU General Public License (GPL)',
+          'Environment :: Console',
+      ])