Add clear DTC codes button to Pi DTC page (FEAT-15)

This commit is contained in:
Mathieu Moran
2026-08-13 16:40:15 -04:00
parent b39faadf58
commit e873db918d
8 changed files with 187 additions and 2 deletions
+43
View File
@@ -406,6 +406,49 @@ def _persist_dtc_state():
print("Failed to persist DTC state to SQLite:", error)
def clear_dtc_codes():
"""Clear stored DTCs on the ECU (OBD mode 04) and reset local state.
Returns a dict with a "status" key ("cleared", "not_connected", or
"error") so the HTTP route can map it to a status code. Never raises —
the serial path can fail in normal use (e.g. adapter yanked mid-request).
"""
with _connection_lock:
candidate = connection
if candidate is None or not _is_car_connected(candidate):
return {
"status": "not_connected",
"error": "OBD is not connected to the car ECU.",
}
global dtc_codes, mil_on, dtc_updated_at, mil_updated_at
try:
with _query_lock:
candidate.query(obd.commands.CLEAR_DTC)
except Exception as error:
_mark_connection_lost(candidate, "CLEAR_DTC", error)
return {"status": "error", "error": str(error)}
# Reset the live snapshot so the UI reflects the cleared state immediately.
# If a fault is still physically present, the next sensor poll (within a
# few seconds) re-populates these — which is the correct behavior.
dtc_codes = []
dtc_updated_at = time.monotonic()
mil_on = False
mil_updated_at = time.monotonic()
app_events.socketio.emit("obd_dtc", [])
app_events.socketio.emit("obd_mil", {"on": False, "dtc_count": 0})
# Also clear the persisted snapshot so it doesn't show stale active codes.
try:
from modules import app_sql
app_sql.clear_dtc_state()
except Exception as error:
print("Failed to clear persisted DTC state:", error)
return {"status": "cleared"}
def obd_sensors():
with obd_sensor_lock:
while not stop_sensors.is_set() and _is_car_connected():
+27
View File
@@ -280,6 +280,33 @@ def save_dtc_state(mil_on, dtc_codes, recorded_at=None):
print("Failed to persist DTC state:", e)
def clear_dtc_state(recorded_at=None):
"""Mark every active DTC as cleared and reset the persisted MIL flag.
Called after the user explicitly clears codes on the ECU (OBD mode 04) so
the persisted snapshot stops showing stale active codes. Cleared codes
keep their history rows (IS_SET = 0), like a normal "no longer detected"
poll would.
"""
conn = get_conn()
if conn is None:
return
now_str = (recorded_at or datetime.now()).isoformat()
with _conn_lock:
try:
conn.execute(
"INSERT INTO settings (key, value) VALUES ('dtc_mil', '0') "
"ON CONFLICT(key) DO UPDATE SET value = excluded.value"
)
conn.execute(
"UPDATE dtc SET IS_SET = 0, LAST_SEEN_AT = ? WHERE IS_SET = 1",
(now_str,),
)
conn.commit()
except sqlite3.Error as e:
print("Failed to clear DTC state:", e)
def get_persisted_dtc_state():
"""Return the last-persisted MIL + DTC codes for display when OBD is offline."""
conn = get_conn()