From 4ab5a162c4abdab2c3241644d30ca02b211b4827 Mon Sep 17 00:00:00 2001 From: marios8543 Date: Mon, 21 Apr 2025 19:04:52 +0300 Subject: [PATCH] Switch to opendsh openauto --- autoapp/UI/MainWindow.cpp | 154 ++++++- autoapp/UI/mainwindow.ui | 704 ++++++++++++++++++++---------- autoapp/assets/album.png | Bin 0 -> 896 bytes autoapp/assets/artist.png | Bin 0 -> 935 bytes autoapp/assets/bluetooth.png | Bin 0 -> 931 bytes autoapp/assets/radio.png | Bin 0 -> 816 bytes autoapp/assets/resources.qrc | 19 +- autoapp/assets/song.png | Bin 0 -> 821 bytes include/autoapp/UI/MainWindow.hpp | 45 +- 9 files changed, 656 insertions(+), 266 deletions(-) create mode 100644 autoapp/assets/album.png create mode 100644 autoapp/assets/artist.png create mode 100644 autoapp/assets/bluetooth.png create mode 100644 autoapp/assets/radio.png create mode 100644 autoapp/assets/song.png diff --git a/autoapp/UI/MainWindow.cpp b/autoapp/UI/MainWindow.cpp index 44bd961..2936a26 100644 --- a/autoapp/UI/MainWindow.cpp +++ b/autoapp/UI/MainWindow.cpp @@ -17,29 +17,157 @@ */ #include +#include +#include +#include +#include +#include +#include + #include "autoapp/UI/MainWindow.hpp" #include "ui_mainwindow.h" namespace autoapp { -namespace ui -{ + namespace ui + { -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui_(new Ui::MainWindow) -{ - ui_->setupUi(this); - connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); - connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); - connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); - connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); + MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui_(new Ui::MainWindow), webSocket(new QWebSocket), + reconnectTimer(new QTimer(this)), + metadataTimer(new QTimer(this)), + shuttingDown(false) + { + ui_->setupUi(this); + connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); + connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); + connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); + connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); + + // BT NOW PLAYING UPDATE + connect(metadataTimer, &QTimer::timeout, this, &MainWindow::updateNowPlaying); + metadataTimer->start(1000); // refresh every 5 seconds + + // RADIO WEBSOCKET STUFF + reconnectTimer->setSingleShot(true); + reconnectTimer->setInterval(3000); + + connect(reconnectTimer, &QTimer::timeout, this, &MainWindow::connectWebSocket); + + connect(webSocket, &QWebSocket::connected, this, [this]() + { + qDebug() << "WebSocket connected"; + webSocket->sendTextMessage(QStringLiteral("Hello from MainWindow WebSocket!")); }); + + connect(webSocket, &QWebSocket::textMessageReceived, this, [this](const QString &message) + { + qDebug() << "Message received:" << message; + handleIncomingMessage(message); }); + + connect(webSocket, &QWebSocket::disconnected, this, [this]() + { + qDebug() << "WebSocket disconnected"; + if (!shuttingDown) { + qDebug() << "Attempting to reconnect in 3 seconds..."; + reconnectTimer->start(); + } }); + + connect(webSocket, QOverload::of(&QWebSocket::error), + this, [this](QAbstractSocket::SocketError) + { qDebug() << "WebSocket error:" << webSocket->errorString(); }); + + connectWebSocket(); + } + + MainWindow::~MainWindow() + { + shuttingDown = true; + webSocket->abort(); + webSocket->deleteLater(); + delete ui_; + } + + } } -MainWindow::~MainWindow() +void f1x::openauto::autoapp::ui::MainWindow::updateBtNowPlaying() { - delete ui_; + QDBusInterface manager( + "org.bluez", + "/", + "org.freedesktop.DBus.ObjectManager", + QDBusConnection::systemBus()); + + if (!manager.isValid()) + { + qDebug() << "Failed to connect to BlueZ D-Bus"; + return; + } + + QDBusReply reply = manager.call("GetManagedObjects"); + + if (!reply.isValid()) + { + qDebug() << "D-Bus call failed:" << reply.error().message(); + return; + } + + QVariantMap allObjects = reply.value(); + + for (auto it = allObjects.begin(); it != allObjects.end(); ++it) + { + QString path = it.key(); + QVariantMap interfaces = it.value().toMap(); + + if (interfaces.contains("org.bluez.MediaPlayer1")) + { + qDebug() << "Found MediaPlayer at:" << path; + + QDBusInterface mediaPlayer( + "org.bluez", + path, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + QDBusReply trackReply = mediaPlayer.call("Get", "org.bluez.MediaPlayer1", "Track"); + if (trackReply.isValid()) + { + QVariantMap track = trackReply.value().toMap(); + QString artist = track["Artist"].toString(); + QString title = track["Title"].toString(); + QString album = track["Album"].toString(); + + QString status = statusReply.value().toString(); + + qDebug() << "Now playing:" << artist << "-" << title << "from" << album; + qDebug() << "Status:" << status; + + if (status == "Playing") + { + ui_->stackedWidget->setCurrentIndex(0); + ui_->btSongName->setText(title); + ui_->btArtistName->setText(artist); + ui_->btAlbumName->setText(album); + } + else + { + ui_->stackedWidget->setCurrentIndex(1); + } + } + break; + } + } } +void f1x::openauto::autoapp::ui::MainWindow::connectWebSocket() +{ + QUrl url(QStringLiteral("ws://127.0.0.1:5000")); // Change to your real server + qDebug() << "Connecting to WebSocket:" << url; + webSocket->open(url); } + +void f1x::openauto::autoapp::ui::MainWindow::handleIncomingMessage(const QString &message) +{ + // Your custom message processing logic here + qDebug() << "[Handler] Processing message:" << message; } diff --git a/autoapp/UI/mainwindow.ui b/autoapp/UI/mainwindow.ui index 2ef2c5b..a89e95e 100644 --- a/autoapp/UI/mainwindow.ui +++ b/autoapp/UI/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 800 - 480 + 1046 + 571 @@ -18,231 +18,477 @@ color: rgb(238, 238, 236); - - - - 290 - 30 - 281 - 41 - - - - <html><head/><body><p><span style=" font-size:22pt; font-weight:600; font-style:italic; color:#3465a4;">Waiting for device...</span></p></body></html> - - - - - - 180 - 20 - 101 - 101 - - - - <html><head/><body><p><img src=":/ico_androidauto.png"/></p></body></html> - - - - - - 630 - 330 - 161 - 41 - - - - Settings - - - false - - - false - - - - - - 630 - 380 - 161 - 41 - - - - Exit - - - false - - - - - - 340 - 70 - 301 - 31 - - - - <html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html> - - - - - - 10 - 440 - 271 - 31 - - - - <html><head/><body><p><a href="https://github.com/f1xpl/openauto"><span style=" text-decoration: underline; color:#007af4;">https://github.com/f1xpl/openauto</span></a></p></body></html> - - - - - - 30 - 170 - 31 - 41 - - - - <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> - - - - - - 80 - 130 - 531 - 101 - - - - <html><head/><body><p align="center"><span style=" color:#ef2929;">WARNING!</span></p><p><span style=" color:#ef2929;">Distraction may cause accidents. Do not attempt to operate while driving. Always concentrate on driving and obey Traffic Regulations. You assume total responsibility and risk for using this software.</span></p></body></html> - - - true - - - - - - 80 - 240 - 531 - 121 - - - - <html><head/><body><p><span style=" color:#ef2929;">This software is not certified by Google Inc. It is created for R&amp;D purposes and may not work as expected by the original authors. Do not use while driving.</span></p><p><span style=" color:#ef2929;">You use this software at your own risk.</span></p></body></html> - - - true - - - - - - 30 - 270 - 31 - 41 - - - - <html><head/><body><p><img src=":/ico_warning.png"/></p></body></html> - - - - - - 410 - 440 - 21 - 31 - - - - <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> - - - - - - 440 - 440 - 351 - 31 - - - - <html><head/><body><p><span style=" font-style:italic;">AndroidAuto is registered trademark of Google Inc.</span></p></body></html> - - - - - - 630 - 230 - 161 - 41 - - - - Toggle cursor - - - false - - - false - - - - - - 630 - 280 - 161 - 41 - - - - Wireless connection - - - false - - - false - - - - - - 50 - 370 - 551 - 61 - - - - <html><head/><body><p align="center"><span style=" font-weight:600;">If you are looking for a Raspberry PI compatible 12V power supply equipped with an ignition switch, visit </span><a href="https://bluewavestudio.io/"><span style=" text-decoration: underline; color:#007af4;">https://bluewavestudio.io</span></a></p></body></html> - - - true - - + + + + + + 1024 + 500 + + + + + 1024 + 500 + + + + 1 + + + + + + 0 + 0 + 1021 + 500 + + + + + 0 + 500 + + + + + 1024 + 500 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 16777215 + 300 + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + :/bluetooth.png + + + true + + + + + + + + 16777215 + 300 + + + + + 10 + + + + + + + + 60 + 60 + + + + + + + :/song.png + + + true + + + + + + + + 24 + + + + Lorem Ipsum Dorem + + + + + + + + + + + + 60 + 60 + + + + + 60 + 60 + + + + + + + :/artist.png + + + true + + + + + + + + 16 + + + + Example Artist + + + + + + + + + + + + 60 + 60 + + + + + + + :/album.png + + + true + + + + + + + + 16 + + + + Example Album + + + + + + + + + + + + + + + + 16777215 + 50 + + + + + 24 + + + + ABCD,EFGH + + + + + + + + + + + + + + 0 + 0 + 1024 + 550 + + + + + 0 + 550 + + + + + 1024 + 550 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + :/radio.png + + + true + + + + + + + + + + + + 40 + + + + ABCD,EFGH + + + + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + + 20 + + + + 0 + + + + + + + + + + 16777215 + 50 + + + + + 16 + + + + Tuner List + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 1024 + 30 + + + + + 1024 + 50 + + + + + 0 + 30 + + + + + 5 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Exit + + + false + + + + + + + Settings + + + false + + + false + + + + + + + Wireless connection + + + false + + + false + + + + + + + Toggle cursor + + + false + + + false + + + + + + + @@ -251,6 +497,8 @@ color: rgb(238, 238, 236); pushButtonSettings pushButtonExit - + + + diff --git a/autoapp/assets/album.png b/autoapp/assets/album.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f6937401682d5fa5c3c11338ac1676fcb8b99d GIT binary patch literal 896 zcmV-`1AqL9P)EX>4Tx04R}tkv&MmKp2MKrj?3RI+#J!AwzYti;6gwDi*;)X)CnqU~=gnG-*jv zTpR`0f`dPcRR)s#Kpat9cGs>_D#NPb#Eu?W1M(KqFRp<7^J&Fx#~9H$RJmU^{(0~{Oz z6D7)C_jq@IZ{Pl{>Gbahmq&87CE=s*00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru=>!xM6ecj}-{t@S0ewkCK~#9!?OV$d!ypLEI{yDJ z+f!#cX_};l#TCh2WS2((6&v|$t+glX0f4C=6hV8E0d>%9GB6u(Ya%c!a4RAZ0sIpZ z5CwcM35Wu`mk2}z{|^a>3jQt$hz$M?31wUSLv-t3c>z`ce?|gU0so7H%mFJ||Huof zVs++e2zYGT+o^fzR23|KwVp{t^#p$x$bKyV(8g>GhW7w^n$En_HJ zRKa_ZP*|~LDVM2ZVOXD`@TW{mFIc`5E;Cr4=>^MsKpnL)`yVgu0f&PL@+okJKoXDy z=n!y}@J1!UVSfRY@mq#~a-Hr`ai#~TcWdl^qp)1oQZ7?R(-2@xZ`eJ9c@D57!J}cK z_3@Ttai)IML55ZAGIgU?f^WqYkH)@2z+*#|!_i@$0pp^1A%YMT|w&nNMb-l(fA~S3aAYy}=pwaB?&eGEZkc$&h|L%_4(+apDE6 WH6VBq+tMij0000EX>4Tx04R}tkv&MmKp2MKrj?3RI+#J!AwzYti;6gwDi*;)X)CnqU~=gnG-*jv zTpR`0f`dPcRR)s#Kpat9cGs>_D#NPb#Eu?W1M(KqFRp<7^J&Fx#~9H$RJmU^{(0~{Oz z6D7)C_jq@IZ{Pl{>Gbahmq&87CE=s*00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru=>!xM6fa3MXF>n~0i;PpK~#9!?ORI{Lm>!j81H{& zyYEa}6#~)cTep&A5Q87Q$Y1Zhd;SjqOnguzohb&?NwdYkZp5R7z^=rjgun^pJtE)~ z@~a{sgZOHCX2b*wNc57$!hq<&Y~vD*2Ro5x;A*N4Z6sbqL55f5Z1T}Ku`~GyyvQW4 zIQEhNvjA7;DkIKM0hGvRiD1=Ws(pyDJbvVOOl-zdc9(|8R8v1|Dzu6g_ZzrO9KH7r z0G6HlzsAdqwX_PH_?h|+4|^KeDV2Yf!<_6jli@F3ipuFZqAdEn?gm9&J|b z>5GWY-_Hs%eT2qJYlVA)Be)*FB^G{2sdiEFA2!>iZDnQ9<8O*Sz8$`orCEjNnCtSD zD}&5~2{r#8>O6O8e_5G!pUtUw^eX3hpU$fJ_4Fo7&9-J6t2a?EY>kF}7o7kA002ov JPDHLkV1hS$pK<^I literal 0 HcmV?d00001 diff --git a/autoapp/assets/bluetooth.png b/autoapp/assets/bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed25eec27c6f09923611e22fff8b36179012c04 GIT binary patch literal 931 zcmV;U16=%xP)EX>4Tx04R}tkv&MmKp2MKrj?3RI+#J!AwzYti;6gwDi*;)X)CnqU~=gnG-*jv zTpR`0f`dPcRR)s#Kpat9cGs>_D#NPb#Eu?W1M(KqFRp<7^J&Fx#~9H$RJmU^{(0~{Oz z6D7)C_jq@IZ{Pl{>Gbahmq&87CE=s*00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru=>!xM6gbM~;)MVJ0ia1lK~!ko?VG_4gD?z3n`r<4 z%iU!MG{JzxP8~F^6Q!?CgA-O8;A_q~vtyWai9f=o!65M@C+V&7D~v?KR><{?`!1|(ukXoxaWeRfPoheWzb^mTtW zY@M-h!VMxY94tf;kPJBJ9?U?t@uCsPz2A{eiZVFEQ%0XnaWc_KGCVNNs@m^4IT@rEl?Fsr6Ow>O-f}OKw(F`z zjdP2xTDB^X?W!S59tNbVz_B1*367Cn=@tFzMf1#RZ6B-%H^vw*l}Z5tw>O5w#~0>a z_9w#~0#?;;6#* z@lRdUyi9fFQH%cgV+E}ahD5f@|7ec_XePEX>4Tx04R}tkv&MmKp2MKrj?3RI+#J!AwzYti;6gwDi*;)X)CnqU~=gnG-*jv zTpR`0f`dPcRR)s#Kpat9cGs>_D#NPb#Eu?W1M(KqFRp<7^J&Fx#~9H$RJmU^{(0~{Oz z6D7)C_jq@IZ{Pl{>Gbahmq&87CE=s*00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru=>!xM6$@-EveEzm0WC>HK~#9!?V3>!!ypKRi}C;e zW%p#WEZJ66@R0L$&D#486jZqqjMiHF_M2oAd@KNs=wkqkiVh24h2U@iEJQ;Cuoip^ z7ZDf$9-_Nomj1QzgiHa?kmMYI2w+9{ zqNYHNE`TX;A^^{n - - ico_androidauto.png - ico_warning.png - ico_setting.png - ico_info.png - aa_video.qml - + + radio.png + album.png + artist.png + bluetooth.png + song.png + ico_androidauto.png + ico_warning.png + ico_setting.png + ico_info.png + aa_video.qml + diff --git a/autoapp/assets/song.png b/autoapp/assets/song.png new file mode 100644 index 0000000000000000000000000000000000000000..38b31836945aa93aab5bcc50de6ee53418097ae0 GIT binary patch literal 821 zcmV-51Iqk~P)EX>4Tx04R}tkv&MmKp2MKrj?3RI+#J!AwzYti;6gwDi*;)X)CnqU~=gnG-*jv zTpR`0f`dPcRR)s#Kpat9cGs>_D#NPb#Eu?W1M(KqFRp<7^J&Fx#~9H$RJmU^{(0~{Oz z6D7)C_jq@IZ{Pl{>Gbahmq&87CE=s*00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru=>!xM6$Jc~uR{O;0WwKMK~#9!?VHOEgD?yPZIu82 z<@C~4eLyR~4&Lng3XL*@BSYM{O&-1XzIDyr-I;(_B``uyA>a%&q<|=3C;?f}r3H+D zE+t?za0vldLti4G67&!ORe@6lpg@NUKm-pHfDCVDwitOxfCNZ@1WXxzkAL^I*`W9S zrZGZ83y9vxZH&+m0!D4wH#Xo>0xC3S8YA>j0oB`YdKH!c36KB@kO1O<{TzAWSkN3m#*_WI&{Z*Ri0MK!k+PF<}27vHNt`hCJ9k!KfucUj+`OQ-vC?H^ImZ z$jAbeW4WI3IgE5B`D>zQC7>P1-kfYyovj`>;o^XNXbAEx00000NkvXXu0mjfyS`qK literal 0 HcmV?d00001 diff --git a/include/autoapp/UI/MainWindow.hpp b/include/autoapp/UI/MainWindow.hpp index 52e3c62..7c16f60 100644 --- a/include/autoapp/UI/MainWindow.hpp +++ b/include/autoapp/UI/MainWindow.hpp @@ -20,33 +20,42 @@ #include #include +#include namespace Ui { -class MainWindow; + class MainWindow; } namespace autoapp { -namespace ui -{ + namespace ui + { -class MainWindow : public QMainWindow -{ - Q_OBJECT -public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow() override; + class MainWindow : public QMainWindow + { + Q_OBJECT + public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; -signals: - void exit(); - void openSettings(); - void toggleCursor(); - void openConnectDialog(); + signals: + void exit(); + void openSettings(); + void toggleCursor(); + void openConnectDialog(); -private: - Ui::MainWindow* ui_; -}; + private slots: + void connectWebSocket(); + void handleIncomingMessage(const QString &message); + void updateBtNowPlaying(); -} + private: + Ui::MainWindow *ui_; + QWebSocket *webSocket; + QTimer *reconnectTimer; + bool shuttingDown; + }; + + } }