wip
This commit is contained in:
152
selfdrive/ui/qt/offroad/software_settings.cc
Executable file → Normal file
152
selfdrive/ui/qt/offroad/software_settings.cc
Executable file → Normal file
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <QDebug>
|
||||
@@ -18,13 +16,14 @@
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
#include "system/hardware/hw.h"
|
||||
|
||||
#include "selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h"
|
||||
|
||||
void SoftwarePanel::checkForUpdates() {
|
||||
std::system("pkill -SIGUSR1 -f selfdrive.updated");
|
||||
std::system("pkill -SIGUSR1 -f selfdrive.updated.updated");
|
||||
}
|
||||
|
||||
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off."));
|
||||
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent), scene(uiState()->scene) {
|
||||
onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off or in park."));
|
||||
onroadLbl->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; padding-top: 30px; padding-bottom: 30px;");
|
||||
addItem(onroadLbl);
|
||||
|
||||
@@ -32,40 +31,17 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
versionLbl = new LabelControl(tr("Current Version"), "");
|
||||
addItem(versionLbl);
|
||||
|
||||
// update scheduler
|
||||
std::vector<QString> scheduleOptions{tr("Manually"), tr("Daily"), tr("Weekly")};
|
||||
ButtonParamControl *preferredSchedule = new ButtonParamControl("UpdateSchedule", tr("Update Scheduler"),
|
||||
tr("Choose the update frequency for FrogPilot's automatic updates.\n\n"
|
||||
"This feature will handle the download, installation, and device reboot for a seamless 'Set and Forget' experience.\n\n"
|
||||
"Weekly updates start at midnight every Sunday."),
|
||||
"",
|
||||
scheduleOptions);
|
||||
schedule = params.getInt("UpdateSchedule");
|
||||
addItem(preferredSchedule);
|
||||
|
||||
updateTime = new ButtonControl(tr("Update Time"), tr("SELECT"));
|
||||
QStringList hours;
|
||||
for (int h = 0; h < 24; h++) {
|
||||
int displayHour = (h % 12 == 0) ? 12 : h % 12;
|
||||
QString meridiem = (h < 12) ? "AM" : "PM";
|
||||
hours << QString("%1:00 %2").arg(displayHour).arg(meridiem)
|
||||
<< QString("%1:30 %2").arg(displayHour).arg(meridiem);
|
||||
}
|
||||
QObject::connect(updateTime, &ButtonControl::clicked, [=]() {
|
||||
int currentHourIndex = params.getInt("UpdateTime");
|
||||
QString currentHourLabel = hours[currentHourIndex];
|
||||
|
||||
QString selection = MultiOptionDialog::getSelection(tr("Select a time to automatically update"), hours, currentHourLabel, this);
|
||||
if (!selection.isEmpty()) {
|
||||
int selectedHourIndex = hours.indexOf(selection);
|
||||
params.putInt("UpdateTime", selectedHourIndex);
|
||||
updateTime->setValue(selection);
|
||||
}
|
||||
// automatic updates toggle
|
||||
ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr("Automatically Update FrogPilot"),
|
||||
tr("FrogPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi."), "");
|
||||
connect(automaticUpdatesToggle, &ToggleControl::toggleFlipped, [this]() {
|
||||
std::thread([this]() {
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", true);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", false);
|
||||
}).detach();
|
||||
});
|
||||
time = params.getInt("UpdateTime");
|
||||
deviceShutdown = params.getInt("DeviceShutdown") * 3600;
|
||||
updateTime->setValue(hours[time]);
|
||||
addItem(updateTime);
|
||||
addItem(automaticUpdatesToggle);
|
||||
|
||||
// download update btn
|
||||
downloadBtn = new ButtonControl(tr("Download"), tr("CHECK"));
|
||||
@@ -74,8 +50,9 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
if (downloadBtn->text() == tr("CHECK")) {
|
||||
checkForUpdates();
|
||||
} else {
|
||||
std::system("pkill -SIGHUP -f selfdrive.updated");
|
||||
std::system("pkill -SIGHUP -f selfdrive.updated.updated");
|
||||
}
|
||||
paramsMemory.putBool("ManualUpdateInitiated", true);
|
||||
});
|
||||
addItem(downloadBtn);
|
||||
|
||||
@@ -92,6 +69,11 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
connect(targetBranchBtn, &ButtonControl::clicked, [=]() {
|
||||
auto current = params.get("GitBranch");
|
||||
QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(",");
|
||||
if (!Params("/persist/params").getBool("FrogsGoMoo")) {
|
||||
branches.removeAll("FrogPilot-Development");
|
||||
branches.removeAll("FrogPilot-New");
|
||||
branches.removeAll("MAKE-PRS-HERE");
|
||||
}
|
||||
for (QString b : {current.c_str(), "devel-staging", "devel", "nightly", "master-ci", "master"}) {
|
||||
auto i = branches.indexOf(b);
|
||||
if (i >= 0) {
|
||||
@@ -122,7 +104,7 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
addItem(uninstallBtn);
|
||||
|
||||
// error log button
|
||||
errorLogBtn = new ButtonControl(tr("Error Log"), tr("VIEW"), "View the error log for debugging purposes when openpilot crashes.");
|
||||
auto errorLogBtn = new ButtonControl(tr("Error Log"), tr("VIEW"), tr("View the error log for openpilot crashes."));
|
||||
connect(errorLogBtn, &ButtonControl::clicked, [=]() {
|
||||
std::string txt = util::read_file("/data/community/crashes/error.txt");
|
||||
ConfirmationDialog::rich(QString::fromStdString(txt), this);
|
||||
@@ -131,8 +113,6 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
|
||||
fs_watch = new ParamWatcher(this);
|
||||
QObject::connect(fs_watch, &ParamWatcher::paramChanged, [=](const QString ¶m_name, const QString ¶m_value) {
|
||||
schedule = params.getInt("UpdateSchedule");
|
||||
time = params.getInt("UpdateTime");
|
||||
updateLabels();
|
||||
});
|
||||
|
||||
@@ -141,8 +121,6 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
|
||||
updateLabels();
|
||||
});
|
||||
|
||||
QObject::connect(uiState(), &UIState::uiUpdate, this, &SoftwarePanel::automaticUpdate);
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
@@ -160,16 +138,15 @@ void SoftwarePanel::updateLabels() {
|
||||
fs_watch->addParam("UpdaterState");
|
||||
fs_watch->addParam("UpdateAvailable");
|
||||
|
||||
fs_watch->addParam("UpdateSchedule");
|
||||
fs_watch->addParam("UpdateTime");
|
||||
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// updater only runs offroad
|
||||
onroadLbl->setVisible(is_onroad);
|
||||
downloadBtn->setVisible(!is_onroad);
|
||||
// updater only runs offroad or when parked
|
||||
bool parked = scene.parked;
|
||||
|
||||
onroadLbl->setVisible(is_onroad && !parked);
|
||||
downloadBtn->setVisible(!is_onroad || parked);
|
||||
|
||||
// download update
|
||||
QString updater_state = QString::fromStdString(params.get("UpdaterState"));
|
||||
@@ -201,82 +178,9 @@ void SoftwarePanel::updateLabels() {
|
||||
versionLbl->setText(QString::fromStdString(params.get("UpdaterCurrentDescription")));
|
||||
versionLbl->setDescription(QString::fromStdString(params.get("UpdaterCurrentReleaseNotes")));
|
||||
|
||||
installBtn->setVisible(!is_onroad && params.getBool("UpdateAvailable"));
|
||||
installBtn->setVisible((!is_onroad || parked) && params.getBool("UpdateAvailable"));
|
||||
installBtn->setValue(QString::fromStdString(params.get("UpdaterNewDescription")));
|
||||
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes")));
|
||||
|
||||
updateTime->setVisible(params.getInt("UpdateSchedule"));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void SoftwarePanel::automaticUpdate() {
|
||||
static int timer = 0;
|
||||
static std::chrono::system_clock::time_point lastOffroadTime;
|
||||
|
||||
if (!is_onroad) {
|
||||
timer = (timer == 0) ? 0 : std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - lastOffroadTime).count();
|
||||
lastOffroadTime = std::chrono::system_clock::now();
|
||||
} else {
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
bool isWifiConnected = (*uiState()->sm)["deviceState"].getDeviceState().getNetworkType() == cereal::DeviceState::NetworkType::WIFI;
|
||||
if (schedule == 0 || is_onroad || !isWifiConnected || isVisible()) return;
|
||||
|
||||
static bool isDownloadCompleted = false;
|
||||
if (isDownloadCompleted && params.getBool("UpdateAvailable")) {
|
||||
params.putBool(timer > deviceShutdown ? "DoShutdown" : "DoReboot", true);
|
||||
return;
|
||||
}
|
||||
|
||||
int updateHour = time / 2;
|
||||
int updateMinute = (time % 2) * 30;
|
||||
|
||||
if (updateHour >= 1 && updateHour <= 11 && time >= 24) {
|
||||
updateHour += 12;
|
||||
} else if (updateHour == 12 && time < 24) {
|
||||
updateHour = 0;
|
||||
}
|
||||
|
||||
std::time_t currentTimeT = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
std::tm now = *std::localtime(¤tTimeT);
|
||||
|
||||
static bool updateCheckedToday = false;
|
||||
static int lastCheckedDay = now.tm_yday;
|
||||
if (lastCheckedDay != now.tm_yday) {
|
||||
updateCheckedToday = false;
|
||||
lastCheckedDay = now.tm_yday;
|
||||
}
|
||||
|
||||
if (now.tm_hour != updateHour || now.tm_min < updateMinute) return;
|
||||
|
||||
std::string lastUpdateStr = params.get("Updated");
|
||||
std::tm lastUpdate = {};
|
||||
std::istringstream iss(lastUpdateStr);
|
||||
|
||||
if (iss >> std::get_time(&lastUpdate, "%Y-%m-%d %H:%M:%S")) {
|
||||
lastUpdate.tm_year -= 1900;
|
||||
lastUpdate.tm_mon -= 1;
|
||||
}
|
||||
std::time_t lastUpdateTimeT = std::mktime(&lastUpdate);
|
||||
|
||||
if (lastUpdate.tm_yday == now.tm_yday) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDownloadCompleted) {
|
||||
std::chrono::hours durationSinceLastUpdate = std::chrono::duration_cast<std::chrono::hours>(std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t(lastUpdateTimeT));
|
||||
int daysSinceLastUpdate = durationSinceLastUpdate.count() / 24;
|
||||
|
||||
if ((schedule == 1 && daysSinceLastUpdate >= 1) || (schedule == 2 && (now.tm_yday / 7) != (std::localtime(&lastUpdateTimeT)->tm_yday / 7))) {
|
||||
if (downloadBtn->text() == tr("CHECK") && !updateCheckedToday) {
|
||||
checkForUpdates();
|
||||
updateCheckedToday = true;
|
||||
} else {
|
||||
std::system("pkill -SIGHUP -f selfdrive.updated");
|
||||
isDownloadCompleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user