From 78131380634899807c9b33e77e2fdbbafb6904f4 Mon Sep 17 00:00:00 2001 From: Simone Margaritelli Date: Thu, 3 Oct 2019 12:50:55 +0200 Subject: [PATCH] new: if ui.fps is set to 0, the display will only be updated for major data changes --- sdcard/rootfs/root/pwnagotchi/config.yml | 5 +++- .../pwnagotchi/scripts/pwnagotchi/agent.py | 6 ++--- .../pwnagotchi/scripts/pwnagotchi/ui/state.py | 25 ++++++++++++++++-- .../pwnagotchi/scripts/pwnagotchi/ui/view.py | 26 ++++++++++++------- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/sdcard/rootfs/root/pwnagotchi/config.yml b/sdcard/rootfs/root/pwnagotchi/config.yml index 7cf1c6f7..cc2ea20f 100644 --- a/sdcard/rootfs/root/pwnagotchi/config.yml +++ b/sdcard/rootfs/root/pwnagotchi/config.yml @@ -91,7 +91,10 @@ personality: # ui configuration ui: - # ePaper display can update every 3 secs anyway + # ePaper display can update every 3 secs anyway, set to 0 to only refresh for major data changes + # IMPORTANT: The lifespan of an eINK display depends on the cumulative amount of refreshes. If you want to + # preserve your display over time, you should set this value to 0.0 so that the display will be refreshed only + # if any of the important data fields changed (the uptime and blinking cursor won't trigger a refresh). fps: 0.3 display: enabled: true diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py index 739d6ed4..9dcb7fb1 100644 --- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py +++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/agent.py @@ -347,13 +347,13 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer): if key not in self._handshakes: self._handshakes[key] = h new_shakes += 1 - apsta = self._find_ap_sta_in(sta_mac, ap_mac, s) - if apsta is None: + ap_and_station = self._find_ap_sta_in(sta_mac, ap_mac, s) + if ap_and_station is None: core.log("!!! captured new handshake: %s !!!" % key) self._last_pwnd = ap_mac plugins.on('handshake', self, filename, ap_mac, sta_mac) else: - (ap, sta) = apsta + (ap, sta) = ap_and_station self._last_pwnd = ap['hostname'] if ap['hostname'] != '' and ap[ 'hostname'] != '' else ap_mac core.log("!!! captured new handshake on channel %d: %s (%s) -> %s [%s (%s)] !!!" % ( \ diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py index c5b66be3..0a9e37a6 100644 --- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py +++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/state.py @@ -6,9 +6,11 @@ class State(object): self._state = state self._lock = Lock() self._listeners = {} + self._changes = {} def add_element(self, key, elem): self._state[key] = elem + self._changes[key] = True def add_listener(self, key, cb): with self._lock: @@ -22,10 +24,29 @@ class State(object): with self._lock: return self._state[key].value if key in self._state else None + def reset(self): + with self._lock: + self._changes = {} + + def changes(self, ignore=()): + with self._lock: + changes = [] + for change in self._changes.keys(): + if change not in ignore: + changes.append(change) + return changes + + def has_changes(self): + with self._lock: + return len(self._changes) > 0 + def set(self, key, value): with self._lock: if key in self._state: prev = self._state[key].value self._state[key].value = value - if key in self._listeners and self._listeners[key] is not None and prev != value: - self._listeners[key](prev, value) + + if prev != value: + self._changes[key] = True + if key in self._listeners and self._listeners[key] is not None: + self._listeners[key](prev, value) diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py index 82c52ad3..0c5eb8a7 100644 --- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py +++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py @@ -78,7 +78,6 @@ class View(object): label_font=fonts.Bold, text_font=fonts.Medium), - 'line1': Line([0, int(self._height * .12), self._width, int(self._height * .12)], color=BLACK), 'line2': Line( [0, self._height - int(self._height * .12), self._width, self._height - int(self._height * .12)], @@ -111,7 +110,12 @@ class View(object): plugins.on('ui_setup', self) - _thread.start_new_thread(self._refresh_handler, ()) + if config['ui']['fps'] > 0.0: + _thread.start_new_thread(self._refresh_handler, ()) + self._ignore_changes = () + else: + core.log("ui.fps is 0, the display will only update for major changes") + self._ignore_changes = ('uptime', 'name') def add_element(self, key, elem): self._state.add_element(key, elem) @@ -311,13 +315,17 @@ class View(object): def update(self): with self._lock: - self._canvas = Image.new('1', (self._width, self._height), WHITE) - drawer = ImageDraw.Draw(self._canvas) + changes = self._state.changes(ignore=self._ignore_changes) + if len(changes): + self._canvas = Image.new('1', (self._width, self._height), WHITE) + drawer = ImageDraw.Draw(self._canvas) - plugins.on('ui_update', self) + plugins.on('ui_update', self) - for key, lv in self._state.items(): - lv.draw(self._canvas, drawer) + for key, lv in self._state.items(): + lv.draw(self._canvas, drawer) - for cb in self._render_cbs: - cb(self._canvas) + for cb in self._render_cbs: + cb(self._canvas) + + self._state.reset()