ui: sunnypilot Terms of Service

This commit is contained in:
Jason Wen 2024-06-13 16:53:16 +00:00
parent 799488573a
commit 85d069044a
7 changed files with 74 additions and 8 deletions

View File

@ -258,6 +258,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"ForceOffroad", CLEAR_ON_MANAGER_START},
{"GmapKey", PERSISTENT | BACKUP},
{"HandsOnWheelMonitoring", PERSISTENT | BACKUP},
{"HasAcceptedTermsSP", PERSISTENT},
{"HideVEgoUi", PERSISTENT | BACKUP},
{"HkgSmoothStop", PERSISTENT | BACKUP},
{"HotspotOnBoot", PERSISTENT},
@ -311,6 +312,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"SunnylinkDongleId", PERSISTENT},
{"SunnylinkEnabled", PERSISTENT},
{"SunnylinkdPid", PERSISTENT},
{"TermsVersionSunnypilot", PERSISTENT},
{"TorqueDeadzoneDeg", PERSISTENT | BACKUP},
{"TorqueFriction", PERSISTENT | BACKUP},
{"TorqueMaxLatAccel", PERSISTENT | BACKUP},

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>sunnypilot Terms of Service</title>
<style type="text/css">
p {
margin: 45px 0;
}
</style>
</head>
<body>
<p>The Terms and Conditions below are effective for all users</p>
<p>Last Updated on June 13, 2024</p>
<p>Please read these Terms of Use (“Terms”) carefully before using sunnypilot which is software developed by SUNNYPILOT LLC, a Limited Liability Company organized under the laws of Virginia ("sunnypilot," “us,” “we,” or “our”). sunnypilot is a software forked from openpilot which is open-sourced software developed by Comma.ai, Inc., a corporation organized under the laws of Delaware (“comma”). sunnypilot builds upon the foundation of openpilot by incorporating additional features and improvements. openpilot can be found on https://github.com/commaai/openpilot</p>
<p><strong>Before using and by accessing sunnypilot, you indicate that you have read, understood, and agree to these Terms.</strong> These Terms apply to all users and others who access or use sunnypilot. If others use sunnypilot through your user account or vehicle, you are responsible to ensure that they only use sunnypilot when it is safe to do so, and in compliance with these Terms and with applicable law. If you disagree with any part of the Terms, you should not access or use sunnypilot.</p>
<h3 id="communications">Communications</h3>
<p>You agree that sunnypilot may contact you by email or telephone in connection with sunnypilot or for other business purposes. You may opt out of receiving email messages at any time by contacting us at support@sunnypilot.ai.</p>
<p>We collect, use, and share information from and about you and your vehicle in connection with sunnypilot. You consent to sunnypilot accessing the systems associated with sunnypilot, without additional notice or consent, for the purposes of providing sunnypilot, data collection, software updates, safety and cybersecurity, suspension or removal of your account, and as disclosed in the Privacy Policy (available at https://sunnypilot.ai/legal/privacy/).</p>
<h3 id="safety">Safety</h3>
<p>sunnypilot performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) designed for use in compatible motor vehicles. While using sunnypilot, it is your responsibility to obey all laws, traffic rules, and traffic regulations governing your vehicle and its operation. Access to and use of sunnypilot is at your own risk and responsibility, and sunnypilot should be accessed and/or used only when you can do so safely.</p>
<p>sunnypilot does not make your vehicle “autonomous” or capable of operation without the active monitoring of a licensed driver. It is designed to assist a licensed driver. A licensed driver must pay attention to the road, remain aware of navigation at all times, and be prepared to take immediate action. Failure to do so can cause damage, injury, or death.</p>
<h3 id="supported-locations-and-models">Supported Locations and Models</h3>
<p>sunnypilot is compatible only with particular makes and models of vehicles. For a complete list of currently supported vehicles, visit https://comma.ai. sunnypilot will not function properly when installed in an incompatible vehicle. sunnypilot is compatible only within the geographical boundaries of the United States of America.</p>
<h3 id="indemnification">Indemnification</h3>
<p><strong>To the maximum extent allowable by law, you agree to defend, indemnify and hold harmless sunnypilot, and its employees, partners, suppliers, contractors, investors, agents, officers, directors, and affiliates, from and against any and all claims, damages, causes of action, penalties, interest, demands, obligations, losses, liabilities, costs or debt, additional taxes, and expenses (including but not limited to attorneys fees), resulting from or arising out of (i) your use and access of, or inability to use or access, sunnypilot, (ii) your breach of these Terms, (iii) the inaccuracy of any information, representation or warranty made by you, (iv) activities of anyone other than you in connection with sunnypilot conducted through your comma or other compatible device or account, (v) any other of your activities under or in connection with these Terms or sunnypilot.</strong></p>
<h3 id="limitation-of-liability">Limitation of Liability</h3>
<p>In no event shall sunnypilot, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential or punitive damages, including without limitation, loss of profits, data, use, goodwill, or other intangible losses, resulting from (i) your access to or use of or inability to access or use of the Software; or (ii) any conduct or content of any third party on the Software whether based on warranty, contract, tort (including negligence) or any other legal theory, whether or not we have been informed of the possibility of such damage, and even if a remedy set forth herein is found to have failed of its essential purpose.</p>
<h3 id="no-warranty-or-obligations-to-maintain-or-service">No Warranty or Obligations to Maintain or Service</h3>
<p>sunnypilot provides sunnypilot without representations, conditions, or warranties of any kind. sunnypilot is provided on an “AS IS” and “AS AVAILABLE” basis, including with all faults and errors as may occur. To the extent permitted by law and unless prohibited by law, sunnypilot on behalf of itself and all persons and parties acting by, through, or for sunnypilot, explicitly disclaims all warranties or conditions, express, implied, or collateral, including any implied warranties of merchantability, satisfactory quality, and fitness for a particular purpose in respect of sunnypilot.</p>
<p>To the extent permitted by law, sunnypilot does not warrant the operation, performance, or availability of sunnypilot under all conditions. sunnypilot is not responsible for any failures caused by server errors, misdirected or redirected transmissions, failed internet connections, interruptions or failures in the transmission of data, any computer virus, or any acts or omissions of third parties that damage the network or impair wireless service.</p>
<p>We undertake reasonable measures to preserve and secure information collected through our sunnypilot. However, no data collection, transmission or storage system is 100% secure, and there is always a risk that your information may be intercepted without our consent. <em>In using sunnypilot, you acknowledge that sunnypilot is not responsible for intercepted information, and you hereby release us from any and all claims arising out of or related to the use of intercepted information in any unauthorized manner.</em></p>
<p>By providing sunnypilot, sunnypilot does not transfer or license its intellectual property or grant rights in its brand names, nor does sunnypilot make representations with respect to third-party intellectual property rights.</p>
<p>We are not obligated to provide any maintenance or support for sunnypilot, technical or otherwise. If we voluntarily provide any maintenance or support for sunnypilot, we may stop any such maintenance, support, or services at any time in our sole discretion.</p>
<h3 id="modification-of-software">Modification of Software</h3>
<p>In no event shall sunnypilot, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable if you choose to modify the software.</p>
<h3 id="changes">Changes</h3>
<p>We reserve the right, at our sole discretion, to modify or replace these Terms at any time. If a revision is material we will provide at least 15 days notice prior to any new terms taking effect. What constitutes a material change will be determined at our sole discretion.</p>
<p>By continuing to access or use our Software after any revisions become effective, you agree to be bound by the revised terms. If you do not agree to the new terms, you are no longer authorized to use the Software.</p>
<h3 id="contact-us">Contact Us</h3>
<p>If you have any questions about these Terms, please contact us at support@sunnypilot.ai.</p>
</body>
</html>

View File

@ -106,7 +106,8 @@ void TermsPage::showEvent(QShowEvent *event) {
text->setAttribute(Qt::WA_AlwaysStackOnTop);
text->setClearColor(QColor("#1B1B1B"));
QString text_view = util::read_file("../assets/offroad/tc.html").c_str();
std::string tc_text = sunnypilot_tc ? "../assets/offroad/sp_tc.html" : "../assets/offroad/tc.html";
QString text_view = util::read_file(tc_text).c_str();
text->rootContext()->setContextProperty("text_view", text_view);
text->setSource(QUrl::fromLocalFile("qt/offroad/text_view.qml"));
@ -158,7 +159,7 @@ void DeclinePage::showEvent(QShowEvent *event) {
main_layout->setSpacing(40);
QLabel *text = new QLabel(this);
text->setText(tr("You must accept the Terms and Conditions in order to use openpilot."));
text->setText(tr("You must accept the Terms and Conditions in order to use sunnypilot."));
text->setStyleSheet(R"(font-size: 80px; font-weight: 300; margin: 200px;)");
text->setWordWrap(true);
main_layout->addWidget(text, 0, Qt::AlignCenter);
@ -185,6 +186,8 @@ void OnboardingWindow::updateActiveScreen() {
setCurrentIndex(0);
} else if (!training_done) {
setCurrentIndex(1);
} else if (!accepted_terms_sp) {
setCurrentIndex(3);
} else {
emit onboardingDone();
}
@ -192,11 +195,13 @@ void OnboardingWindow::updateActiveScreen() {
OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) {
std::string current_terms_version = params.get("TermsVersion");
std::string current_terms_version_sp = params.get("TermsVersionSunnypilot");
std::string current_training_version = params.get("TrainingVersion");
accepted_terms = params.get("HasAcceptedTerms") == current_terms_version;
accepted_terms_sp = params.get("HasAcceptedTermsSP") == current_terms_version_sp;
training_done = params.get("CompletedTrainingVersion") == current_training_version;
TermsPage* terms = new TermsPage(this);
TermsPage* terms = new TermsPage(false, this);
addWidget(terms);
connect(terms, &TermsPage::acceptedTerms, [=]() {
params.put("HasAcceptedTerms", current_terms_version);
@ -217,6 +222,15 @@ OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) {
addWidget(declinePage);
connect(declinePage, &DeclinePage::getBack, [=]() { updateActiveScreen(); });
TermsPage* terms_sp = new TermsPage(true, this);
addWidget(terms_sp); // index = 3
connect(terms_sp, &TermsPage::acceptedTerms, [=]() {
params.put("HasAcceptedTermsSP", current_terms_version_sp);
accepted_terms_sp = true;
updateActiveScreen();
});
connect(terms_sp, &TermsPage::declinedTerms, [=]() { setCurrentIndex(2); });
setStyleSheet(R"(
* {
color: white;

View File

@ -63,7 +63,7 @@ class TermsPage : public QFrame {
Q_OBJECT
public:
explicit TermsPage(QWidget *parent = 0) : QFrame(parent) {}
explicit TermsPage(bool sunnypilot = false, QWidget *parent = 0) : QFrame(parent), sunnypilot_tc(sunnypilot) {}
public slots:
void enableAccept();
@ -72,6 +72,7 @@ private:
void showEvent(QShowEvent *event) override;
QPushButton *accept_btn;
bool sunnypilot_tc = false;
signals:
void acceptedTerms();
@ -97,13 +98,13 @@ class OnboardingWindow : public QStackedWidget {
public:
explicit OnboardingWindow(QWidget *parent = 0);
inline void showTrainingGuide() { setCurrentIndex(1); }
inline bool completed() const { return accepted_terms && training_done; }
inline bool completed() const { return accepted_terms && accepted_terms_sp && training_done; }
private:
void updateActiveScreen();
Params params;
bool accepted_terms = false, training_done = false;
bool accepted_terms = false, accepted_terms_sp = false, training_done = false;
signals:
void onboardingDone();

View File

@ -23,7 +23,7 @@ from openpilot.system.statsd import statlog
from openpilot.common.swaglog import cloudlog
from openpilot.system.hardware.power_monitoring import PowerMonitoring
from openpilot.system.hardware.fan_controller import TiciFanController
from openpilot.system.version import terms_version, training_version
from openpilot.system.version import terms_version, terms_version_sp, training_version
ThermalStatus = log.DeviceState.ThermalStatus
NetworkType = log.DeviceState.NetworkType
@ -298,6 +298,7 @@ def hardware_thread(end_event, hw_queue) -> None:
startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate")
startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall")
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version
startup_conditions["accepted_terms"] = params.get("HasAcceptedTermsSP") == terms_version_sp
# with 2% left, we killall, otherwise the phone will take a long time to boot
startup_conditions["free_space"] = msg.deviceState.freeSpacePercent > 2

View File

@ -18,7 +18,7 @@ from openpilot.system.manager.process_config import managed_processes
from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID, is_registered_device
from openpilot.common.swaglog import cloudlog, add_file_handler
from openpilot.system.hardware.hw import Paths
from openpilot.system.version import get_build_metadata, terms_version, training_version
from openpilot.system.version import get_build_metadata, terms_version, terms_version_sp, training_version
def manager_init() -> None:
@ -67,6 +67,7 @@ def manager_init() -> None:
("EnhancedScc", "0"),
("FeatureStatus", "1"),
("HandsOnWheelMonitoring", "0"),
("HasAcceptedTermsSP", "0"),
("HideVEgoUi", "0"),
("LastSpeedLimitSignTap", "0"),
("LkasToggle", "0"),
@ -135,6 +136,7 @@ def manager_init() -> None:
# set version params
params.put("Version", build_metadata.openpilot.version)
params.put("TermsVersion", terms_version)
params.put("TermsVersionSunnypilot", terms_version_sp)
params.put("TrainingVersion", training_version)
params.put("GitCommit", build_metadata.openpilot.git_commit)
params.put("GitCommitDate", build_metadata.openpilot.git_commit_date)

View File

@ -18,6 +18,7 @@ BUILD_METADATA_FILENAME = "build.json"
training_version: bytes = b"0.2.0"
terms_version: bytes = b"2"
terms_version_sp: bytes = b"1.0"
def get_version(path: str = BASEDIR) -> str:
@ -179,6 +180,7 @@ if __name__ == "__main__":
params = Params()
params.put("TermsVersion", terms_version)
params.put("TermsVersionSunnypilot", terms_version_sp)
params.put("TrainingVersion", training_version)
print(get_build_metadata())