From 5536a21b5ee0b673df8db0f0dd7145d63593c02d Mon Sep 17 00:00:00 2001
From: Joao Curti <jpcurti@users.noreply.github.com>
Date: Sun, 26 May 2024 22:37:58 +0200
Subject: [PATCH 1/2] Configure rotary encoder button via klipper menu_keys
 module

---
 klippy/extras/e3v3se_display.py | 64 +++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 klippy/extras/e3v3se_display.py

diff --git a/klippy/extras/e3v3se_display.py b/klippy/extras/e3v3se_display.py
new file mode 100644
index 000000000000..41a73567ea75
--- /dev/null
+++ b/klippy/extras/e3v3se_display.py
@@ -0,0 +1,64 @@
+import logging
+import time
+from .display import menu_keys
+
+
+class E3v3seDisplay:
+    def __init__(self, config):
+        self.printer = config.get_printer()
+        self.config = config
+        self.mutex = self.printer.get_reactor().mutex()
+        self.name = config.get_name()
+        self.reactor = self.printer.get_reactor()
+        self._logging = config.getboolean("logging", False)
+        self.gcode = self.printer.lookup_object("gcode")
+        self.printer.register_event_handler("klippy:ready", self.handle_ready)
+
+        # register for key events
+        menu_keys.MenuKeys(config, self.key_event)
+
+        self._update_interval = 1
+        self._update_timer = self.reactor.register_timer(self._screen_update)
+
+    def key_event(self, key, eventtime):
+        if key == 'click':
+            self.log("click pressed.")
+        elif key == 'long_click':
+            self.log("long_click pressed.")
+        elif key == 'up':
+             self.log("up pressed ")
+        elif key == 'down':
+             self.log("down pressed ")
+
+    def _screen_update(self, eventtime):
+        #self.log("Display update: ")
+        return eventtime + self._update_interval
+
+    def _screen_init(self, eventtime):
+        self.reactor.update_timer(
+            self._update_timer, eventtime + self._update_interval)
+        return self.reactor.NEVER
+
+    def handle_ready(self):
+        self.reactor.register_timer(
+            self._reset_screen, self.reactor.monotonic())
+        
+    def _reset_screen(self, eventtime):
+        self.log("Reset")
+        self.reactor.register_timer(
+            self._screen_init, self.reactor.monotonic() + 2.)
+        return self.reactor.NEVER
+
+    def log(self, msg, *args, **kwargs):
+        if self._logging:
+            logging.info("E3V3SE Display: " + str(msg))
+
+    def error(self, msg, *args, **kwargs):
+        logging.error("E3V3SE Display: " + str(msg))
+
+    def get_encoder_state(self):
+        return self.encoder.getValue()
+
+def load_config(config):
+    return E3v3seDisplay(config)
+

From f4e7cc69b328f0ba163b050f11dcff6e8cac1eb1 Mon Sep 17 00:00:00 2001
From: Joao Curti <jpcurti@users.noreply.github.com>
Date: Sun, 26 May 2024 23:27:54 +0200
Subject: [PATCH 2/2] Map encoder states to same structure as expected by the
 display interface

---
 klippy/extras/e3v3se_display.py | 36 +++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/klippy/extras/e3v3se_display.py b/klippy/extras/e3v3se_display.py
index 41a73567ea75..891e07a43e91 100644
--- a/klippy/extras/e3v3se_display.py
+++ b/klippy/extras/e3v3se_display.py
@@ -2,8 +2,15 @@
 import time
 from .display import menu_keys
 
-
 class E3v3seDisplay:
+    
+    ENCODER_DIFF_NO = 0  # no state
+    ENCODER_DIFF_CW = 1  # clockwise rotation
+    ENCODER_DIFF_CCW = 2  # counterclockwise rotation
+    ENCODER_DIFF_ENTER = 3  # click
+
+    EncoderRateLimit = True
+
     def __init__(self, config):
         self.printer = config.get_printer()
         self.config = config
@@ -13,6 +20,7 @@ def __init__(self, config):
         self._logging = config.getboolean("logging", False)
         self.gcode = self.printer.lookup_object("gcode")
         self.printer.register_event_handler("klippy:ready", self.handle_ready)
+        self.encoder_state = self.ENCODER_DIFF_NO
 
         # register for key events
         menu_keys.MenuKeys(config, self.key_event)
@@ -22,13 +30,28 @@ def __init__(self, config):
 
     def key_event(self, key, eventtime):
         if key == 'click':
-            self.log("click pressed.")
+            self.log("click")
+            self.encoder_state = self.ENCODER_DIFF_ENTER
         elif key == 'long_click':
-            self.log("long_click pressed.")
+            self.log("long_click")
+            self.encoder_state = self.ENCODER_DIFF_ENTER
         elif key == 'up':
-             self.log("up pressed ")
+            self.log("up")
+            self.encoder_state = self.ENCODER_DIFF_CCW
         elif key == 'down':
-             self.log("down pressed ")
+            self.log("down")
+            self.encoder_state = self.ENCODER_DIFF_CW
+
+        self.encoder_has_data()
+
+    def get_encoder_state(self):
+        last_state = self.encoder_state
+        self.encoder_state = self.ENCODER_DIFF_NO
+        return  last_state
+
+    def encoder_has_data(self):
+        self.log("Key event")
+        return 
 
     def _screen_update(self, eventtime):
         #self.log("Display update: ")
@@ -56,9 +79,6 @@ def log(self, msg, *args, **kwargs):
     def error(self, msg, *args, **kwargs):
         logging.error("E3V3SE Display: " + str(msg))
 
-    def get_encoder_state(self):
-        return self.encoder.getValue()
-
 def load_config(config):
     return E3v3seDisplay(config)