Add clear DTC codes button to Pi DTC page (FEAT-15)
This commit is contained in:
@@ -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():
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user