diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 896da6ffc6..3e68ff0367 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -203,10 +203,16 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { setSpacing(50); addItem(new LabelControl(tr("Dongle ID"), getDongleId().value_or(tr("N/A")))); addItem(new LabelControl(tr("Serial"), params.get("HardwareSerial").c_str())); - QFile f("/data/otp/otp.conf"); - f.open(QIODevice::ReadOnly | QIODevice::Text); - QString pin = f.readAll(); - addItem(new LabelControl(tr("Fleet Manager PIN"), pin)); + + fleetManagerPin = new LabelControl(tr("Fleet Manager PIN"), pin); + addItem(fleetManagerPin); + + fs_watch = new QFileSystemWatcher(this); + connect(fs_watch, &QFileSystemWatcher::fileChanged, this, &DevicePanel::onPinFileChanged); + + QString pin_path = "/data/otp/otp.conf"; + fs_watch->addPath(pin_path); + refreshPin(); // Error Troubleshoot auto errorBtn = new ButtonControl( @@ -305,6 +311,22 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(power_layout); } +void DevicePanel::onPinFileChanged(const QString &file_path) { + if (file_path == "/data/otp/otp.conf") { + refreshPin(); + } +} + +void DevicePanel::refreshPin() { + QFile f("/data/otp/otp.conf"); + if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { + pin = f.readAll(); + f.close(); + setSpacing(50); + fleetManagerPin->setText(pin); + } +} + void DevicePanel::updateCalibDescription() { QString desc = tr("sunnypilot requires the device to be mounted within 4° left or right and " diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index ba758414da..a7c1dfff02 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -47,9 +48,15 @@ private slots: void poweroff(); void reboot(); void updateCalibDescription(); + void onPinFileChanged(const QString &file_path); + void refreshPin(); private: Params params; + + LabelControl *fleetManagerPin; + QString pin; + QFileSystemWatcher *fs_watch; }; class TogglesPanel : public ListWidget { diff --git a/system/fleetmanager/fleet_manager.py b/system/fleetmanager/fleet_manager.py index 755f04d4c7..bf1ed190a8 100755 --- a/system/fleetmanager/fleet_manager.py +++ b/system/fleetmanager/fleet_manager.py @@ -2,6 +2,8 @@ import os import random import secrets +import threading +import time from flask import Flask, render_template, Response, request, send_from_directory, session, redirect, url_for import system.fleetmanager.helpers as fleet from system.loggerd.config import ROOT as REALDATA @@ -131,14 +133,28 @@ def open_error_log(file_name): return render_template("error_log.html", file_name=file_name, file_content=error) -def main(): +def generate_pin(): if not os.path.exists(fleet.PIN_PATH): os.makedirs(fleet.PIN_PATH) pin = str(random.randint(100000, 999999)) with open(fleet.PIN_PATH + "otp.conf", "w") as file: file.write(pin) + +def schedule_pin_generate(): + pin_thread = threading.Thread(target=update_pin) + pin_thread.start() + + +def update_pin(): + while True: + generate_pin() + time.sleep(30) + + +def main(): app.secret_key = secrets.token_hex(32) + schedule_pin_generate() app.run(host="0.0.0.0", port=5050)