Jelajahi Sumber

Integrated Firmware updater with new way of fetching firmware and motor driver versions

Thokoop 1 tahun lalu
induk
melakukan
704433b365

+ 23 - 18
app.py

@@ -31,12 +31,12 @@ pause_condition = threading.Condition()
 
 # Global variables to store device information
 arduino_table_name = None
-arduino_driver_type = None
+arduino_driver_type = 'Unknown'
 
 # Table status
 current_playing_file = None
 execution_progress = None
-firmware_version = None
+firmware_version = 'Unknown'
 current_playing_index = None
 current_playlist = None
 is_clearing = False
@@ -46,9 +46,9 @@ serial_lock = threading.Lock()
 PLAYLISTS_FILE = os.path.join(os.getcwd(), "playlists.json")
 
 MOTOR_TYPE_MAPPING = {
-    "TMC2209": "./arduino_code_TMC2209/arduino_code_TMC2209.ino",
-    "DRV8825": "./arduino_code/arduino_code.ino",
-    "esp32": "./esp32/esp32.ino"
+    "TMC2209": "./firmware/arduino_code_TMC2209/arduino_code_TMC2209.ino",
+    "DRV8825": "./firmware/arduino_code/arduino_code.ino",
+    "esp32": "./firmware/esp32/esp32.ino"
 }
 
 # Ensure the file exists and contains at least an empty JSON object
@@ -109,7 +109,7 @@ def list_serial_ports():
 
 def connect_to_serial(port=None, baudrate=115200):
     """Automatically connect to the first available serial port or a specified port."""
-    global ser, ser_port, arduino_table_name, arduino_driver_type
+    global ser, ser_port, arduino_table_name, arduino_driver_type, firmware_version
 
     try:
         if port is None:
@@ -985,7 +985,8 @@ def get_firmware_info():
     """
     Compare the installed firmware version and motor type with the one in the .ino file.
     """
-    global ser
+    global firmware_version, arduino_driver_type, ser
+
     if ser is None or not ser.is_open:
         return jsonify({"success": False, "error": "Arduino not connected or serial port not open"}), 400
 
@@ -997,12 +998,8 @@ def get_firmware_info():
             ser.write(b"GET_VERSION\n")
             time.sleep(0.5)
 
-            installed_version = 'Unknown'
-            installed_type = 'Unknown'
-            if ser.in_waiting > 0:
-                response = ser.readline().decode().strip()
-                if " | " in response:
-                    installed_version, installed_type = response.split(" | ", 1)
+            installed_version = firmware_version
+            installed_type = arduino_driver_type
 
             # If Arduino provides valid details, proceed with comparison
             if installed_version != 'Unknown' and installed_type != 'Unknown':
@@ -1034,16 +1031,23 @@ def get_firmware_info():
                 "updateAvailable": False
             })
 
-        if request.method == "POST":
+        elif request.method == "POST":
             motor_type = request.json.get("motorType", None)
             if not motor_type or motor_type not in MOTOR_TYPE_MAPPING:
-                return jsonify({"success": False, "error": "Invalid or missing motor type"}), 400
+                return jsonify({
+                    "success": False,
+                    "error": "Invalid or missing motor type"
+                }), 400
 
-            ino_path = MOTOR_TYPE_MAPPING.get(motor_type)
+            # Fetch firmware details for the given motor type
+            ino_path = MOTOR_TYPE_MAPPING[motor_type]
             firmware_details = get_ino_firmware_details(ino_path)
 
-            if not firmware_details or not firmware_details.get("version") or not firmware_details.get("motorType"):
-                return jsonify({"success": False, "error": "Failed to retrieve .ino firmware details"}), 500
+            if not firmware_details:
+                return jsonify({
+                    "success": False,
+                    "error": "Failed to retrieve .ino firmware details"
+                }), 500
 
             return jsonify({
                 "success": True,
@@ -1053,6 +1057,7 @@ def get_firmware_info():
                 "inoType": firmware_details["motorType"],
                 "updateAvailable": True
             })
+
     except Exception as e:
         return jsonify({"success": False, "error": str(e)}), 500
 

+ 0 - 8
arduino_code/arduino_code.ino → firmware/arduino_code/arduino_code.ino

@@ -194,14 +194,6 @@ void appMode()
             return;
         }
 
-        if (input == "GET_VERSION")
-        {
-            Serial.print(firmwareVersion);
-            Serial.print(" | ");
-            Serial.println(motorType);
-            return;
-        }
-
         if (input == "RESET_THETA")
         {
             resetTheta(); // Reset currentTheta

+ 0 - 8
arduino_code_TMC2209/arduino_code_TMC2209.ino → firmware/arduino_code_TMC2209/arduino_code_TMC2209.ino

@@ -194,14 +194,6 @@ void appMode()
             return;
         }
 
-        if (input == "GET_VERSION")
-        {
-            Serial.print(firmwareVersion);
-            Serial.print(" | ");
-            Serial.println(motorType);
-            return;
-        }
-
         if (input == "RESET_THETA")
         {
             resetTheta(); // Reset currentTheta

+ 0 - 9
esp32/esp32.ino → firmware/esp32/esp32.ino

@@ -88,15 +88,6 @@ void loop()
             return;
         }
 
-        if (input == "GET_VERSION")
-        {
-            Serial.print(firmwareVersion);
-            Serial.print(" | ");
-            Serial.println(motorType);
-            return;
-        }
-
-
         // Example: The user calls "SET_SPEED 60" => 60% of maxSpeed
         if (input.startsWith("SET_SPEED"))
         {

+ 31 - 3
static/main.js

@@ -702,11 +702,11 @@ async function fetchFirmwareInfo(motorType = null) {
                 }
             }
         } else {
-            logMessage("Error fetching firmware info.", LOG_TYPE.ERROR);
+            logMessage("Could not fetch firmware info.", LOG_TYPE.WARNING);
             logMessage(data.error, LOG_TYPE.DEBUG);
         }
     } catch (error) {
-        logMessage("Error fetching firmware info.", LOG_TYPE.ERROR);
+        logMessage("Could not fetch firmware info.", LOG_TYPE.WARNING);
         logMessage(error.message, LOG_TYPE.DEBUG);
     } finally {
         // Re-enable the button after fetching
@@ -762,7 +762,9 @@ async function updateFirmware() {
 
             // Display "You're up to date" message if versions match
             const newVersionElement = document.getElementById("new_firmware_version");
-            newVersionElement.textContent = "You're up to date!";
+            const currentVersionElement = document.getElementById("current_firmware_version");
+            currentVersionElement.textContent = newVersionElement.innerHTML
+            newVersionElement.textContent = "You are up to date!";
             const motorSelectionDiv = document.getElementById("motor_selection");
             motorSelectionDiv.style.display = "none";
         } else {
@@ -848,6 +850,9 @@ function openPlaylistEditor(playlistName) {
 function clearSchedule() {
     document.getElementById("start_time").value = "";
     document.getElementById("end_time").value = "";
+    document.getElementById('clear_time').style.display = 'none';
+    setCookie('start_time', null, 7);
+    setCookie('end_time', null, 7);
 }
 
 // Function to run the selected playlist with specified parameters
@@ -1499,6 +1504,12 @@ function saveSettingsToCookies() {
     const clearAction = document.getElementById('clear_action_label').textContent.trim();
     setCookie('clear_action', clearAction, 7);
 
+    // Save start and end times
+    const startTime = document.getElementById('start_time').value;
+    const endTime = document.getElementById('end_time').value;
+    setCookie('start_time', startTime, 7);
+    setCookie('end_time', endTime, 7);
+
     logMessage('Settings saved.');
 }
 
@@ -1550,6 +1561,20 @@ function loadSettingsFromCookies() {
         }
     }
 
+    // Load start and end times
+    const startTime = getCookie('start_time');
+    if (startTime !== null) {
+        document.getElementById('start_time').value = startTime;
+    }
+    const endTime = getCookie('end_time');
+    if (endTime !== null) {
+        document.getElementById('end_time').value = endTime;
+    }
+
+    if (startTime !== null || endTime !== null ) {
+        document.getElementById('clear_time').style.display = 'block';
+    }
+
     logMessage('Settings loaded from cookies.');
 }
 
@@ -1563,6 +1588,8 @@ function attachSettingsSaveListeners() {
     });
     document.getElementById('shuffle_playlist').addEventListener('change', saveSettingsToCookies);
     document.getElementById('pre_execution').addEventListener('change', saveSettingsToCookies);
+    document.getElementById('start_time').addEventListener('change', saveSettingsToCookies);
+    document.getElementById('end_time').addEventListener('change', saveSettingsToCookies);
 }
 
 
@@ -1607,4 +1634,5 @@ document.addEventListener('DOMContentLoaded', () => {
     loadAllPlaylists(); // Load all playlists on page load
     attachSettingsSaveListeners(); // Attach event listeners to save changes
     attachFullScreenListeners();
+    fetchFirmwareInfo();
 });

+ 5 - 5
static/style.css

@@ -233,7 +233,7 @@ input, select {
 }
 
 .dropdown-content button:hover {
-    background-color: var(--background-primary);
+    background-color: var(--background-tertiary);
 }
 
 
@@ -448,9 +448,9 @@ section .header .add-button {
     gap: 10px;
 }
 
-.playlist-parameters .row {
-    display: flex;
-    gap: 10px;
+.playlist-parameters .control-group button.small.cancel {
+    align-self: flex-end;
+    margin-bottom: 4px;
 }
 
 #clear_pattern {
@@ -507,7 +507,7 @@ section .header .add-button {
 }
 
 .file-list li:hover {
-    background-color: var(--background-primary);
+    background-color: var(--background-tertiary);
 }
 
 .file-list li.selected {

+ 4 - 5
templates/index.html

@@ -131,9 +131,8 @@
                         <label for="end_time">End time</label>
                         <input type="time" id="end_time" min="00:00" max="24:00">
                     </div>
+                    <button id="clear_time" onclick="clearSchedule()" style="display: none" class="small cancel">Clear</button>
                 </div>
-                <button onclick="clearSchedule()" class="cancel">Clear</button>
-
             </div>
         </section>
 
@@ -182,9 +181,9 @@
                         <span id="dropdown_toggle" class="dropdown-toggle" onclick="toggleClearDropdown(event)">▼</span>
                     </button>
                     <div id="clear_dropdown" class="dropdown-content" style="display: none;">
-                        <button onclick="updateClearAction('From Center', 'runClearIn')">Clear From Center</button>
-                        <button onclick="updateClearAction('From Perimeter', 'runClearOut')">Clear From Perimeter</button>
-                        <button onclick="updateClearAction('Sideways', 'runClearSide')">Clear Sideways</button>
+                        <button class="no-bg" onclick="updateClearAction('From Center', 'runClearIn')">Clear From Center</button>
+                        <button class="no-bg" onclick="updateClearAction('From Perimeter', 'runClearOut')">Clear From Perimeter</button>
+                        <button class="no-bg" onclick="updateClearAction('Sideways', 'runClearSide')">Clear Sideways</button>
                     </div>
                 </div>
                 <button onclick="moveToCenter()">Move to Center</button>