From 37342c06858b31515709681df12a52a4192b75a2 Mon Sep 17 00:00:00 2001
From: grokbeer <1428380+grokbeer@users.noreply.github.com>
Date: Fri, 8 May 2020 21:58:26 +1200
Subject: [PATCH 01/15] Have watchdog plugin reboot system rather than restart
 application

Signed-off-by: grokbeer <1428380+grokbeer@users.noreply.github.com>
---
 pwnagotchi/plugins/default/watchdog.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pwnagotchi/plugins/default/watchdog.py b/pwnagotchi/plugins/default/watchdog.py
index 6a370eb..8ebb6b8 100644
--- a/pwnagotchi/plugins/default/watchdog.py
+++ b/pwnagotchi/plugins/default/watchdog.py
@@ -33,4 +33,4 @@ class Watchdog(plugins.Plugin):
             logging.info('[WATCHDOG] Blind-Bug detected. Restarting.')
             mode = 'MANU' if agent.mode == 'manual' else 'AUTO'
             import pwnagotchi
-            pwnagotchi.restart(mode=mode)
+            pwnagotchi.reboot(mode=mode)

From 552df65422627c7efb53b75bb52629a91d7f3f24 Mon Sep 17 00:00:00 2001
From: Yeri Tiete <yeri@superuser.one>
Date: Fri, 4 Sep 2020 17:49:41 +0800
Subject: [PATCH 02/15] Make sure IPv4 works when eth0 is connected

Resolves an issue where IPv4 traffic would not work when eth0 is connected (i.e. usb-ethernet adapter over OTG). The static route for usb0 precedes the DHCP route for eth0. Only IPv6 traffic would work, but not IPv4 until the metric for usb0 is increase and thus lowered in priority. If no eth0 is plugged in, internet works fine over usb0.
---
 builder/data/etc/network/interfaces.d/usb0-cfg | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/builder/data/etc/network/interfaces.d/usb0-cfg b/builder/data/etc/network/interfaces.d/usb0-cfg
index 445ed90..18c428d 100644
--- a/builder/data/etc/network/interfaces.d/usb0-cfg
+++ b/builder/data/etc/network/interfaces.d/usb0-cfg
@@ -4,4 +4,5 @@ iface usb0 inet static
   netmask 255.255.255.0
   network 10.0.0.0
   broadcast 10.0.0.255
-  gateway 10.0.0.1
\ No newline at end of file
+  gateway 10.0.0.1
+  metric 20

From 1aea0b95b156ba7a6fe8660ea0afb27e4e1d89c8 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Fri, 18 Sep 2020 02:11:37 +0200
Subject: [PATCH 03/15] Small gps fixes + memtemp rework

---
 pwnagotchi/plugins/default/gps.py     |  19 ++--
 pwnagotchi/plugins/default/memtemp.py | 132 +++++++++++++++++++++-----
 2 files changed, 117 insertions(+), 34 deletions(-)

diff --git a/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py
index d9c992b..1fb7030 100644
--- a/pwnagotchi/plugins/default/gps.py
+++ b/pwnagotchi/plugins/default/gps.py
@@ -57,7 +57,7 @@ class GPS(plugins.Plugin):
     def on_ui_setup(self, ui):
         # add coordinates for other displays
         if ui.is_waveshare_v2():
-            lat_pos = (127, 75)
+            lat_pos = (127, 74)
             lon_pos = (122, 84)
             alt_pos = (127, 94)
         elif ui.is_waveshare_v1():
@@ -66,21 +66,21 @@ class GPS(plugins.Plugin):
             alt_pos = (130, 90)
         elif ui.is_inky():
             lat_pos = (127, 60)
-            lon_pos = (127, 70)
+            lon_pos = (122, 70)
             alt_pos = (127, 80)
         elif ui.is_waveshare144lcd():
             # guessed values, add tested ones if you can
             lat_pos = (67, 73)
             lon_pos = (62, 83)
             alt_pos = (67, 93)
-        elif ui.is_dfrobot_v2: 
-            lat_pos = (127, 75)
+        elif ui.is_dfrobot_v2():
+            lat_pos = (127, 74)
             lon_pos = (122, 84)
             alt_pos = (127, 94)
         elif ui.is_waveshare27inch():
-            lat_pos = (6,120)
-            lon_pos = (1,135)
-            alt_pos = (6,150)
+            lat_pos = (6, 120)
+            lon_pos = (1, 135)
+            alt_pos = (6, 150)
         else:
             # guessed values, add tested ones if you can
             lat_pos = (127, 51)
@@ -126,7 +126,6 @@ class GPS(plugins.Plugin):
             ),
         )
 
-
     def on_unload(self, ui):
         with ui._lock:
             ui.remove_element('latitude')
@@ -141,5 +140,5 @@ class GPS(plugins.Plugin):
             # last char is sometimes not completely drawn ¯\_(ツ)_/¯
             # using an ending-whitespace as workaround on each line
             ui.set("latitude", f"{self.coordinates['Latitude']:.4f} ")
-            ui.set("longitude", f" {self.coordinates['Longitude']:.4f} ")
-            ui.set("altitude", f" {self.coordinates['Altitude']:.1f}m ")
+            ui.set("longitude", f"{self.coordinates['Longitude']:.4f} ")
+            ui.set("altitude", f"{self.coordinates['Altitude']:.1f}m ")
diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index f64e287..4f00ccc 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -17,7 +17,7 @@
 # - Added horizontal and vertical orientation
 #
 ###############################################################
-from pwnagotchi.ui.components import LabeledValue
+from pwnagotchi.ui.components import LabeledValue, Text
 from pwnagotchi.ui.view import BLACK
 import pwnagotchi.ui.fonts as fonts
 import pwnagotchi.plugins as plugins
@@ -40,39 +40,118 @@ class MemTemp(plugins.Plugin):
     def cpu_load(self):
         return int(pwnagotchi.cpu_load() * 100)
 
+    @staticmethod
+    def pad_text(width, data, symbol):
+        data = str(data) + symbol
+        return " " * (width - len(data)) + data
+
     def on_ui_setup(self, ui):
         if ui.is_waveshare_v2():
-            h_pos = (180, 80)
-            v_pos = (180, 61)
+            h_pos_line1 = (178, 84)
+            h_pos_line2 = (178, 94)
+            v_pos_line1 = (202, 74)  # (127, 75)
+            v_pos_line2 = (202, 84)  # (122, 84)
+            v_pos_line3 = (197, 94)  # (127, 94)
         elif ui.is_waveshare_v1():
-            h_pos = (170, 80)
-            v_pos = (170, 61)
+            h_pos_line1 = (170, 80)
+            h_pos_line2 = (170, 90)
+            v_pos_line1 = (170, 61)  # (130, 70)
+            v_pos_line2 = (170, 71)  # (125, 80)
+            v_pos_line3 = (165, 81)  # (130, 90)
         elif ui.is_waveshare144lcd():
-            h_pos = (53, 77)
-            v_pos = (78, 67)
+            h_pos_line1 = (53, 77)
+            h_pos_line2 = (53, 87)
+            v_pos_line1 = (78, 67)  # (67, 73)
+            v_pos_line2 = (78, 77)  # (62, 83)
+            v_pos_line3 = (73, 87)  # (67, 93)
         elif ui.is_inky():
-            h_pos = (140, 68)
-            v_pos = (165, 54)
+            h_pos_line1 = (140, 68)
+            h_pos_line2 = (140, 78)
+            v_pos_line1 = (165, 54)  # (127, 60)
+            v_pos_line2 = (165, 64)  # (122, 70)
+            v_pos_line3 = (160, 74)  # (127, 80)
         elif ui.is_waveshare27inch():
-            h_pos = (192, 138)
-            v_pos = (216, 122)
+            h_pos_line1 = (192, 138)
+            h_pos_line2 = (192, 148)
+            v_pos_line1 = (216, 122)  # (6,120)
+            v_pos_line2 = (216, 132)  # (1,135)
+            v_pos_line3 = (211, 142)  # (6,150)
         else:
-            h_pos = (155, 76)
-            v_pos = (180, 61)
+            h_pos_line1 = (155, 76)
+            h_pos_line2 = (155, 86)
+            v_pos_line1 = (180, 61)  # (127, 51)
+            v_pos_line2 = (180, 71)  # (127, 56)
+            v_pos_line3 = (175, 81)  # (102, 71)
+
+        label_spacing = 0
 
         if self.options['orientation'] == "vertical":
-            ui.add_element('memtemp', LabeledValue(color=BLACK, label='', value=' mem:-\n cpu:-\ntemp:-',
-                                                   position=v_pos,
-                                                   label_font=fonts.Small, text_font=fonts.Small))
+            ui.add_element(
+                'memtemp_line1',
+                LabeledValue(
+                    color=BLACK,
+                    label='mem:',
+                    value='-',
+                    position=v_pos_line1,
+                    label_font=fonts.Small,
+                    text_font=fonts.Small,
+                    label_spacing=label_spacing,
+                )
+            )
+            ui.add_element(
+                'memtemp_line2',
+                LabeledValue(
+                    color=BLACK,
+                    label='cpu:',
+                    value='-',
+                    position=v_pos_line2,
+                    label_font=fonts.Small,
+                    text_font=fonts.Small,
+                    label_spacing=label_spacing,
+                )
+            )
+            ui.add_element(
+                'memtemp_line3',
+                LabeledValue(
+                    color=BLACK,
+                    label='temp:',
+                    value='-',
+                    position=v_pos_line3,
+                    label_font=fonts.Small,
+                    text_font=fonts.Small,
+                    label_spacing=label_spacing,
+                )
+            )
         else:
             # default to horizontal
-            ui.add_element('memtemp', LabeledValue(color=BLACK, label='', value='mem cpu temp\n - -  -',
-                                                   position=h_pos,
-                                                   label_font=fonts.Small, text_font=fonts.Small))
+            ui.add_element(
+                'memtemp_line1',
+                Text(
+                    color=BLACK,
+                    value=' mem  cpu temp',
+                    position=h_pos_line1,
+                    font=fonts.Small,
+                )
+            )
+            ui.add_element(
+                'memtemp_line2',
+                Text(
+                    color=BLACK,
+                    value='   -    -    -',
+                    position=h_pos_line2,
+                    font=fonts.Small,
+                )
+            )
 
     def on_unload(self, ui):
         with ui._lock:
-            ui.remove_element('memtemp')
+            if self.options['orientation'] == "vertical":
+                ui.remove_element('memtemp_line1')
+                ui.remove_element('memtemp_line2')
+                ui.remove_element('memtemp_line3')
+            else:
+                ui.remove_element('memtemp_line1')
+                ui.remove_element('memtemp_line2')
 
     def on_ui_update(self, ui):
         if self.options['scale'] == "fahrenheit":
@@ -87,9 +166,14 @@ class MemTemp(plugins.Plugin):
             symbol = "c"
 
         if self.options['orientation'] == "vertical":
-            ui.set('memtemp',
-                   " mem:%s%%\n cpu:%s%%\ntemp:%s%s" % (self.mem_usage(), self.cpu_load(), temp, symbol))
+            ui.set('memtemp_line1', f"{self.mem_usage()}%")
+            ui.set('memtemp_line2', f"{self.cpu_load()}%")
+            ui.set('memtemp_line3', f"{temp}{symbol}")
         else:
             # default to horizontal
-            ui.set('memtemp',
-                   " mem cpu temp\n %s%% %s%%  %s%s" % (self.mem_usage(), self.cpu_load(), temp, symbol))
+            ui.set(
+                'memtemp_line2',
+                self.pad_text(4, self.mem_usage(), "%") +
+                self.pad_text(5, self.cpu_load(), "%") +
+                self.pad_text(5, temp, symbol)
+            )

From 6d0e29527691b8c00df77c6fdfb8c6e72878829f Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Fri, 18 Sep 2020 02:12:36 +0200
Subject: [PATCH 04/15] Version bumps

---
 pwnagotchi/plugins/default/gps.py     | 2 +-
 pwnagotchi/plugins/default/memtemp.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py
index 1fb7030..7b6b8f6 100644
--- a/pwnagotchi/plugins/default/gps.py
+++ b/pwnagotchi/plugins/default/gps.py
@@ -10,7 +10,7 @@ from pwnagotchi.ui.view import BLACK
 
 class GPS(plugins.Plugin):
     __author__ = "evilsocket@gmail.com"
-    __version__ = "1.0.0"
+    __version__ = "1.0.1"
     __license__ = "GPL3"
     __description__ = "Save GPS coordinates whenever an handshake is captured."
 
diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index 4f00ccc..b8d4e81 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -27,7 +27,7 @@ import logging
 
 class MemTemp(plugins.Plugin):
     __author__ = 'https://github.com/xenDE'
-    __version__ = '1.0.1'
+    __version__ = '1.0.2'
     __license__ = 'GPL3'
     __description__ = 'A plugin that will display memory/cpu usage and temperature'
 

From b886b4e6739d986f96411dcf1a2d70162c591475 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sat, 19 Sep 2020 23:43:24 +0200
Subject: [PATCH 05/15] Added more configurable fields

---
 pwnagotchi/plugins/default/memtemp.py | 255 +++++++++++++-------------
 1 file changed, 130 insertions(+), 125 deletions(-)

diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index b8d4e81..3450562 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -1,6 +1,6 @@
 # memtemp shows memory infos and cpu temperature
 #
-# mem usage, cpu load, cpu temp
+# mem usage, cpu load, cpu temp, cpu frequency
 #
 ###############################################################
 #
@@ -16,6 +16,13 @@
 # - Added CPU load
 # - Added horizontal and vertical orientation
 #
+# 19-09-2020 by crahan <crahan@n00.be>
+# - Added CPU frequency
+# - Made field types and order configurable (max 3 fields)
+# - Made line spacing and position configurable
+# - Refactored to dynamically generate UI elements
+# - Changed horizontal UI elements to Text
+# - Updated to version 1.0.2
 ###############################################################
 from pwnagotchi.ui.components import LabeledValue, Text
 from pwnagotchi.ui.view import BLACK
@@ -31,129 +38,27 @@ class MemTemp(plugins.Plugin):
     __license__ = 'GPL3'
     __description__ = 'A plugin that will display memory/cpu usage and temperature'
 
+    ALLOWED_FIELDS = {
+        'mem': 'mem_usage',
+        'cpu': 'cpu_load',
+        'temp': 'cpu_temp',
+        'freq': 'cpu_freq'
+    }
+    DEFAULT_FIELDS = ['mem', 'cpu', 'temp']
+    LINE_SPACING = 10
+    LABEL_SPACING = 0
+    FIELD_WIDTH = 4
+
     def on_loaded(self):
         logging.info("memtemp plugin loaded.")
 
     def mem_usage(self):
-        return int(pwnagotchi.mem_usage() * 100)
+        return f"{int(pwnagotchi.mem_usage() * 100)}%"
 
     def cpu_load(self):
-        return int(pwnagotchi.cpu_load() * 100)
+        return f"{int(pwnagotchi.cpu_load() * 100)}%"
 
-    @staticmethod
-    def pad_text(width, data, symbol):
-        data = str(data) + symbol
-        return " " * (width - len(data)) + data
-
-    def on_ui_setup(self, ui):
-        if ui.is_waveshare_v2():
-            h_pos_line1 = (178, 84)
-            h_pos_line2 = (178, 94)
-            v_pos_line1 = (202, 74)  # (127, 75)
-            v_pos_line2 = (202, 84)  # (122, 84)
-            v_pos_line3 = (197, 94)  # (127, 94)
-        elif ui.is_waveshare_v1():
-            h_pos_line1 = (170, 80)
-            h_pos_line2 = (170, 90)
-            v_pos_line1 = (170, 61)  # (130, 70)
-            v_pos_line2 = (170, 71)  # (125, 80)
-            v_pos_line3 = (165, 81)  # (130, 90)
-        elif ui.is_waveshare144lcd():
-            h_pos_line1 = (53, 77)
-            h_pos_line2 = (53, 87)
-            v_pos_line1 = (78, 67)  # (67, 73)
-            v_pos_line2 = (78, 77)  # (62, 83)
-            v_pos_line3 = (73, 87)  # (67, 93)
-        elif ui.is_inky():
-            h_pos_line1 = (140, 68)
-            h_pos_line2 = (140, 78)
-            v_pos_line1 = (165, 54)  # (127, 60)
-            v_pos_line2 = (165, 64)  # (122, 70)
-            v_pos_line3 = (160, 74)  # (127, 80)
-        elif ui.is_waveshare27inch():
-            h_pos_line1 = (192, 138)
-            h_pos_line2 = (192, 148)
-            v_pos_line1 = (216, 122)  # (6,120)
-            v_pos_line2 = (216, 132)  # (1,135)
-            v_pos_line3 = (211, 142)  # (6,150)
-        else:
-            h_pos_line1 = (155, 76)
-            h_pos_line2 = (155, 86)
-            v_pos_line1 = (180, 61)  # (127, 51)
-            v_pos_line2 = (180, 71)  # (127, 56)
-            v_pos_line3 = (175, 81)  # (102, 71)
-
-        label_spacing = 0
-
-        if self.options['orientation'] == "vertical":
-            ui.add_element(
-                'memtemp_line1',
-                LabeledValue(
-                    color=BLACK,
-                    label='mem:',
-                    value='-',
-                    position=v_pos_line1,
-                    label_font=fonts.Small,
-                    text_font=fonts.Small,
-                    label_spacing=label_spacing,
-                )
-            )
-            ui.add_element(
-                'memtemp_line2',
-                LabeledValue(
-                    color=BLACK,
-                    label='cpu:',
-                    value='-',
-                    position=v_pos_line2,
-                    label_font=fonts.Small,
-                    text_font=fonts.Small,
-                    label_spacing=label_spacing,
-                )
-            )
-            ui.add_element(
-                'memtemp_line3',
-                LabeledValue(
-                    color=BLACK,
-                    label='temp:',
-                    value='-',
-                    position=v_pos_line3,
-                    label_font=fonts.Small,
-                    text_font=fonts.Small,
-                    label_spacing=label_spacing,
-                )
-            )
-        else:
-            # default to horizontal
-            ui.add_element(
-                'memtemp_line1',
-                Text(
-                    color=BLACK,
-                    value=' mem  cpu temp',
-                    position=h_pos_line1,
-                    font=fonts.Small,
-                )
-            )
-            ui.add_element(
-                'memtemp_line2',
-                Text(
-                    color=BLACK,
-                    value='   -    -    -',
-                    position=h_pos_line2,
-                    font=fonts.Small,
-                )
-            )
-
-    def on_unload(self, ui):
-        with ui._lock:
-            if self.options['orientation'] == "vertical":
-                ui.remove_element('memtemp_line1')
-                ui.remove_element('memtemp_line2')
-                ui.remove_element('memtemp_line3')
-            else:
-                ui.remove_element('memtemp_line1')
-                ui.remove_element('memtemp_line2')
-
-    def on_ui_update(self, ui):
+    def cpu_temp(self):
         if self.options['scale'] == "fahrenheit":
             temp = (pwnagotchi.temperature() * 9 / 5) + 32
             symbol = "f"
@@ -164,16 +69,116 @@ class MemTemp(plugins.Plugin):
             # default to celsius
             temp = pwnagotchi.temperature()
             symbol = "c"
+        return f"{temp}{symbol}"
+
+    def cpu_freq(self):
+        with open('/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq', 'rt') as fp:
+            return f"{round(float(fp.readline())/1000000, 1)}G"
+
+    def pad_text(self, data):
+        return " " * (self.FIELD_WIDTH - len(data)) + data
+
+    def on_ui_setup(self, ui):
+        try:
+            # Configure field list
+            self.fields = self.options['fields'].split(',')
+            self.fields = [x.strip() for x in self.fields if x.strip() in self.ALLOWED_FIELDS.keys()]
+            self.fields = self.fields[:3]  # limit to the first 3 fields
+        except Exception:
+            # Set default value
+            self.fields = self.DEFAULT_FIELDS
+
+        try:
+            # Configure line_spacing
+            line_spacing = int(self.options['linespacing'])
+        except Exception:
+            # Set default value
+            line_spacing = self.LINE_SPACING
+
+        try:
+            # Configure position
+            pos = self.options['position'].split(',')
+            pos = [int(x.strip()) for x in pos]
+            if self.options['orientation'] == "vertical":
+                v_pos = (pos[0], pos[1])
+            else:
+                h_pos = (pos[0], pos[1])
+        except Exception:
+            # Set default position based on screen type
+            if ui.is_waveshare_v2():
+                h_pos = (178, 84)
+                v_pos = (197, 74)
+            elif ui.is_waveshare_v1():
+                h_pos = (170, 80)
+                v_pos = (165, 61)
+            elif ui.is_waveshare144lcd():
+                h_pos = (53, 77)
+                v_pos = (73, 67)
+            elif ui.is_inky():
+                h_pos = (140, 68)
+                v_pos = (160, 54)
+            elif ui.is_waveshare27inch():
+                h_pos = (192, 138)
+                v_pos = (211, 122)
+            else:
+                h_pos = (155, 76)
+                v_pos = (175, 61)
 
         if self.options['orientation'] == "vertical":
-            ui.set('memtemp_line1', f"{self.mem_usage()}%")
-            ui.set('memtemp_line2', f"{self.cpu_load()}%")
-            ui.set('memtemp_line3', f"{temp}{symbol}")
+            for idx, field in enumerate(self.fields):
+                v_pos_x = v_pos[0]
+                v_pos_y = v_pos[1] + ((len(self.fields) - 3) * -1 * line_spacing)
+                ui.add_element(
+                    f"memtemp_{field}",
+                    LabeledValue(
+                        color=BLACK,
+                        label=f"{self.pad_text(field)}:",
+                        value="-",
+                        position=(v_pos_x, v_pos_y + (idx * line_spacing)),
+                        label_font=fonts.Small,
+                        text_font=fonts.Small,
+                        label_spacing=self.LABEL_SPACING,
+                    )
+                )
+                logging.info(f"memtemp: created '{field}'")
         else:
             # default to horizontal
-            ui.set(
-                'memtemp_line2',
-                self.pad_text(4, self.mem_usage(), "%") +
-                self.pad_text(5, self.cpu_load(), "%") +
-                self.pad_text(5, temp, symbol)
+            h_pos_x = h_pos[0]
+            h_pos_y = h_pos[1]
+            ui.add_element(
+                'memtemp_header',
+                Text(
+                    color=BLACK,
+                    value=" ".join([self.pad_text(x) for x in self.fields]),
+                    position=(h_pos_x, h_pos_y),
+                    font=fonts.Small,
+                )
             )
+            ui.add_element(
+                'memtemp_data',
+                Text(
+                    color=BLACK,
+                    value=" ".join([self.pad_text("-") for x in self.fields]),
+                    position=(h_pos_x, h_pos_y + line_spacing),
+                    font=fonts.Small,
+                )
+            )
+
+    def on_unload(self, ui):
+        with ui._lock:
+            if self.options['orientation'] == "vertical":
+                for idx, field in enumerate(self.fields):
+                    ui.remove_element(f"memtemp_{field}")
+            else:
+                # default to horizontal
+                ui.remove_element('memtemp_header')
+                ui.remove_element('memtemp_data')
+
+    def on_ui_update(self, ui):
+        if self.options['orientation'] == "vertical":
+            for idx, field in enumerate(self.fields):
+                ui.set(f"memtemp_{field}", getattr(self, self.ALLOWED_FIELDS[field])())
+        else:
+            # default to horizontal
+            data = " ".join([self.pad_text(getattr(self, self.ALLOWED_FIELDS[x])()) for x in self.fields])
+            ui.set('memtemp_data', data)

From c124a9751478ca8c0bc2d21828c4d0b8edbce0cc Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sun, 20 Sep 2020 00:25:52 +0200
Subject: [PATCH 06/15] Changelog update.

---
 pwnagotchi/plugins/default/memtemp.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index 3450562..5b8f3eb 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -20,7 +20,7 @@
 # - Added CPU frequency
 # - Made field types and order configurable (max 3 fields)
 # - Made line spacing and position configurable
-# - Refactored to dynamically generate UI elements
+# - Updated code to dynamically generate UI elements
 # - Changed horizontal UI elements to Text
 # - Updated to version 1.0.2
 ###############################################################

From 1c4df7a1c43daa407f8177d89965ac6a606bfbc8 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sun, 20 Sep 2020 00:27:26 +0200
Subject: [PATCH 07/15] Additional comments

---
 pwnagotchi/plugins/default/memtemp.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index 5b8f3eb..d7be552 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -125,6 +125,7 @@ class MemTemp(plugins.Plugin):
                 v_pos = (175, 61)
 
         if self.options['orientation'] == "vertical":
+            # Dynamically create the required LabeledValue objects
             for idx, field in enumerate(self.fields):
                 v_pos_x = v_pos[0]
                 v_pos_y = v_pos[1] + ((len(self.fields) - 3) * -1 * line_spacing)

From 72878454f91f4837e914e7d53b49b93f0abf5959 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sun, 20 Sep 2020 00:29:33 +0200
Subject: [PATCH 08/15] Removed debug line.

---
 pwnagotchi/plugins/default/memtemp.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index d7be552..59bac6d 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -141,7 +141,6 @@ class MemTemp(plugins.Plugin):
                         label_spacing=self.LABEL_SPACING,
                     )
                 )
-                logging.info(f"memtemp: created '{field}'")
         else:
             # default to horizontal
             h_pos_x = h_pos[0]

From 1a0083eb382db12a2fd6d58f02fd44ca493bee82 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sun, 20 Sep 2020 01:43:52 +0200
Subject: [PATCH 09/15] Fix correct x positioning

Align fields right when less than 3 fields are shown in horizontal mode, using a 5-pixel character width with a 5-character width for each field (i.e. 25 pixels per field).
---
 pwnagotchi/plugins/default/memtemp.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pwnagotchi/plugins/default/memtemp.py b/pwnagotchi/plugins/default/memtemp.py
index 59bac6d..898df2f 100644
--- a/pwnagotchi/plugins/default/memtemp.py
+++ b/pwnagotchi/plugins/default/memtemp.py
@@ -143,7 +143,7 @@ class MemTemp(plugins.Plugin):
                 )
         else:
             # default to horizontal
-            h_pos_x = h_pos[0]
+            h_pos_x = h_pos[0] + ((len(self.fields) - 3) * -1 * 25)
             h_pos_y = h_pos[1]
             ui.add_element(
                 'memtemp_header',

From 7da3cc5565283b3e5bae403fc204275adec60b07 Mon Sep 17 00:00:00 2001
From: Thomas Bouve <crahan@n00.be>
Date: Sun, 20 Sep 2020 20:25:25 +0200
Subject: [PATCH 10/15] Revert. Changes are handled in a separate branch

---
 pwnagotchi/plugins/default/gps.py | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py
index 7b6b8f6..d9c992b 100644
--- a/pwnagotchi/plugins/default/gps.py
+++ b/pwnagotchi/plugins/default/gps.py
@@ -10,7 +10,7 @@ from pwnagotchi.ui.view import BLACK
 
 class GPS(plugins.Plugin):
     __author__ = "evilsocket@gmail.com"
-    __version__ = "1.0.1"
+    __version__ = "1.0.0"
     __license__ = "GPL3"
     __description__ = "Save GPS coordinates whenever an handshake is captured."
 
@@ -57,7 +57,7 @@ class GPS(plugins.Plugin):
     def on_ui_setup(self, ui):
         # add coordinates for other displays
         if ui.is_waveshare_v2():
-            lat_pos = (127, 74)
+            lat_pos = (127, 75)
             lon_pos = (122, 84)
             alt_pos = (127, 94)
         elif ui.is_waveshare_v1():
@@ -66,21 +66,21 @@ class GPS(plugins.Plugin):
             alt_pos = (130, 90)
         elif ui.is_inky():
             lat_pos = (127, 60)
-            lon_pos = (122, 70)
+            lon_pos = (127, 70)
             alt_pos = (127, 80)
         elif ui.is_waveshare144lcd():
             # guessed values, add tested ones if you can
             lat_pos = (67, 73)
             lon_pos = (62, 83)
             alt_pos = (67, 93)
-        elif ui.is_dfrobot_v2():
-            lat_pos = (127, 74)
+        elif ui.is_dfrobot_v2: 
+            lat_pos = (127, 75)
             lon_pos = (122, 84)
             alt_pos = (127, 94)
         elif ui.is_waveshare27inch():
-            lat_pos = (6, 120)
-            lon_pos = (1, 135)
-            alt_pos = (6, 150)
+            lat_pos = (6,120)
+            lon_pos = (1,135)
+            alt_pos = (6,150)
         else:
             # guessed values, add tested ones if you can
             lat_pos = (127, 51)
@@ -126,6 +126,7 @@ class GPS(plugins.Plugin):
             ),
         )
 
+
     def on_unload(self, ui):
         with ui._lock:
             ui.remove_element('latitude')
@@ -140,5 +141,5 @@ class GPS(plugins.Plugin):
             # last char is sometimes not completely drawn ¯\_(ツ)_/¯
             # using an ending-whitespace as workaround on each line
             ui.set("latitude", f"{self.coordinates['Latitude']:.4f} ")
-            ui.set("longitude", f"{self.coordinates['Longitude']:.4f} ")
-            ui.set("altitude", f"{self.coordinates['Altitude']:.1f}m ")
+            ui.set("longitude", f" {self.coordinates['Longitude']:.4f} ")
+            ui.set("altitude", f" {self.coordinates['Altitude']:.1f}m ")

From 3bd9cd4f183b7a33d02eb07a0d2cb2410c6b10ee Mon Sep 17 00:00:00 2001
From: HeroCC <herocc@herocc.com>
Date: Sat, 3 Oct 2020 17:01:42 +0200
Subject: [PATCH 11/15] Tweak Wigle plugin

Adds a new 'donate' option to allow Wigle to include data for commercial use.

Also changes data header to reflect this is a pwnagotchi plugin.

Signed-off-by: HeroCC <herocc@herocc.com>
---
 pwnagotchi/defaults.toml            |  1 +
 pwnagotchi/plugins/default/wigle.py | 16 ++++++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/pwnagotchi/defaults.toml b/pwnagotchi/defaults.toml
index 40a4240..e471659 100644
--- a/pwnagotchi/defaults.toml
+++ b/pwnagotchi/defaults.toml
@@ -52,6 +52,7 @@ main.plugins.wpa-sec.whitelist = []
 main.plugins.wigle.enabled = false
 main.plugins.wigle.api_key = ""
 main.plugins.wigle.whitelist = []
+main.plugins.wigle.donate = true
 
 main.plugins.bt-tether.enabled = false
 
diff --git a/pwnagotchi/plugins/default/wigle.py b/pwnagotchi/plugins/default/wigle.py
index f281757..103e7db 100644
--- a/pwnagotchi/plugins/default/wigle.py
+++ b/pwnagotchi/plugins/default/wigle.py
@@ -9,6 +9,7 @@ from datetime import datetime
 from pwnagotchi.utils import WifiInfo, FieldNotFoundError, extract_from_pcap, StatusFile, remove_whitelisted
 from threading import Lock
 from pwnagotchi import plugins
+from pwnagotchi._version import __version__ as __pwnagotchi_version__
 
 
 def _extract_gps_data(path):
@@ -34,14 +35,14 @@ def _format_auth(data):
     return out
 
 
-def _transform_wigle_entry(gps_data, pcap_data):
+def _transform_wigle_entry(gps_data, pcap_data, plugin_version):
     """
     Transform to wigle entry in file
     """
     dummy = StringIO()
     # write kismet header
     dummy.write(
-        "WigleWifi-1.4,appRelease=20190201,model=Kismet,release=2019.02.01.{},device=kismet,display=kismet,board=kismet,brand=kismet\n")
+        "WigleWifi-1.4,appRelease={},model=pwnagotchi,release={},device=pwnagotchi,display=kismet,board=kismet,brand=pwnagotchi\n".format(plugin_version, __pwnagotchi_version__))
     dummy.write(
         "MAC,SSID,AuthMode,FirstSeen,Channel,RSSI,CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type")
 
@@ -62,7 +63,7 @@ def _transform_wigle_entry(gps_data, pcap_data):
     return dummy.getvalue()
 
 
-def _send_to_wigle(lines, api_key, timeout=30):
+def _send_to_wigle(lines, api_key, donate=True, timeout=30):
     """
     Uploads the file to wigle-net
     """
@@ -76,7 +77,7 @@ def _send_to_wigle(lines, api_key, timeout=30):
 
     headers = {'Authorization': f"Basic {api_key}",
                'Accept': 'application/json'}
-    data = {'donate': 'false'}
+    data = {'donate': 'on' if donate else 'false'}
     payload = {'file': dummy, 'type': 'text/csv'}
 
     try:
@@ -112,6 +113,9 @@ class Wigle(plugins.Plugin):
         if not 'whitelist' in self.options:
             self.options['whitelist'] = list()
 
+        if not 'donate' in self.options:
+            self.options['donate'] = True
+
         self.ready = True
 
     def on_internet_available(self, agent):
@@ -172,14 +176,14 @@ class Wigle(plugins.Plugin):
                     logging.debug("WIGLE: %s", sc_e)
                     self.skip.append(gps_file)
                     continue
-                new_entry = _transform_wigle_entry(gps_data, pcap_data)
+                new_entry = _transform_wigle_entry(gps_data, pcap_data, self.__version__)
                 csv_entries.append(new_entry)
                 no_err_entries.append(gps_file)
             if csv_entries:
                 display.set('status', "Uploading gps-data to wigle.net ...")
                 display.update(force=True)
                 try:
-                    _send_to_wigle(csv_entries, self.options['api_key'])
+                    _send_to_wigle(csv_entries, self.options['api_key'], donate=self.options['donate'])
                     reported += no_err_entries
                     self.report.update(data={'reported': reported})
                     logging.info("WIGLE: Successfully uploaded %d files", len(no_err_entries))

From 2ddf040facb1485d9dc6e928bb548d25b515428c Mon Sep 17 00:00:00 2001
From: Andrew Jaswa <andrew.jaswa@bonus.ly>
Date: Fri, 9 Oct 2020 21:13:31 -0600
Subject: [PATCH 12/15] swap out header file for one that doesn't tie up gpio
 pins 14 and 15 for waveshare_2

Signed-off-by: Andrew Jaswa <andrew.jaswa@bonus.ly>
---
 builder/pwnagotchi.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builder/pwnagotchi.yml b/builder/pwnagotchi.yml
index a294153..6625e50 100644
--- a/builder/pwnagotchi.yml
+++ b/builder/pwnagotchi.yml
@@ -178,7 +178,7 @@
       chdir: /usr/local/src/gratis
       target: rpi
       params:
-        EPD_IO: epd_io.h
+        EPD_IO: epd_io_free_uart.h
         PANEL_VERSION: 'V231_G2'
     when: gratisgit.changed
 
@@ -187,7 +187,7 @@
       chdir: /usr/local/src/gratis
       target: rpi-install
       params:
-        EPD_IO: epd_io.h
+        EPD_IO: epd_io_free_uart.h
         PANEL_VERSION: 'V231_G2'
     when: gratisgit.changed
 

From 6430a408473551ae7dada49fddc02fa1445ef7c2 Mon Sep 17 00:00:00 2001
From: centraliota <altercation@gmail.com>
Date: Tue, 17 Nov 2020 18:01:52 -0700
Subject: [PATCH 13/15] Update wpa-sec.py logging

Added logging.info message for plugin loading, to keep consistent with behaviour of other plugins.
---
 pwnagotchi/plugins/default/wpa-sec.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pwnagotchi/plugins/default/wpa-sec.py b/pwnagotchi/plugins/default/wpa-sec.py
index 5c14018..53ff3c3 100644
--- a/pwnagotchi/plugins/default/wpa-sec.py
+++ b/pwnagotchi/plugins/default/wpa-sec.py
@@ -82,6 +82,7 @@ class WpaSec(plugins.Plugin):
             self.options['whitelist'] = list()
 
         self.ready = True
+        logging.info("WPA_SEC: plugin loaded")
 
     def on_webhook(self, path, request):
         from flask import make_response, redirect

From c472e60615d602963c40f9fabc4b3c237f1ad9fa Mon Sep 17 00:00:00 2001
From: Brigham Campbell <me@brighamcampbell.com>
Date: Sun, 14 Mar 2021 11:46:04 -0600
Subject: [PATCH 14/15] Fix bug in gps module

Fix a bug caused by using a function in a conditional instead of the
return value of the function itself.

Signed-off-by: Brigham Campbell <me@brighamcampbell.com>
---
 pwnagotchi/plugins/default/gps.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py
index d9c992b..2caa35b 100644
--- a/pwnagotchi/plugins/default/gps.py
+++ b/pwnagotchi/plugins/default/gps.py
@@ -73,7 +73,7 @@ class GPS(plugins.Plugin):
             lat_pos = (67, 73)
             lon_pos = (62, 83)
             alt_pos = (67, 93)
-        elif ui.is_dfrobot_v2: 
+        elif ui.is_dfrobot_v2():
             lat_pos = (127, 75)
             lon_pos = (122, 84)
             alt_pos = (127, 94)

From 34c2c8a06e4015ab19df108797d6f3541908ce7c Mon Sep 17 00:00:00 2001
From: Philip Howard <phil@gadgetoid.com>
Date: Fri, 9 Apr 2021 10:17:20 +0100
Subject: [PATCH 15/15] Add support for SSD1608 variant 250x122 pixel Inky
 pHATs

Running `python3 -m inky.eeprom` should show display variant. Variants 10, 11 and 12 are SSD1608 based.

This patch adds support for auto-detecting and using them when "ui.display.color" is set to "auto".

Fixes #980 and #941

Signed-off-by: Philip Howard <phil@gadgetoid.com>
---
 pwnagotchi/ui/hw/inky.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/pwnagotchi/ui/hw/inky.py b/pwnagotchi/ui/hw/inky.py
index bb02fd7..7f71b7a 100644
--- a/pwnagotchi/ui/hw/inky.py
+++ b/pwnagotchi/ui/hw/inky.py
@@ -42,6 +42,12 @@ class Inky(DisplayImpl):
             from pwnagotchi.ui.hw.libs.inkyphat.inkyphatfast import InkyPHATFast
             self._display = InkyPHATFast('black')
             self._display.set_border(InkyPHATFast.BLACK)
+        elif self.config['color'] == 'auto':
+            from inky.auto import auto
+            self._display = auto()
+            self._display.set_border(self._display.BLACK)
+            self._layout['width'] = self._display.WIDTH
+            self._layout['height'] = self._display.HEIGHT
         else:
             from inky import InkyPHAT
             self._display = InkyPHAT(self.config['color'])