diff --git a/README.md b/README.md index 218998cb..8f629f09 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,23 @@ -# OpenDash +# astraDash -OpenDash is a Qt-based infotainment center for your Linux OpenAuto installation! -The OpenDash project includes OpenAuto, AASDK, and Dash. +astraDash is a Qt-based infotainment center for my Opel Astra H GTC Linux setup! +The astraDash project includes OpenAuto, AASDK, and OpenDash. -Main features of Dash include: +Main added features of astraDash include: -* Embedded OpenAuto `Windowed/Fullscreen` -* Wireless OpenAuto Capability -* On-screen Volume, Brightness, & Theme Control -* Responsive Scalable UI `Adjustable for screen size` -* Bluetooth Media Control -* Real-Time Vehicle OBD-II Data & SocketCAN Capabilities -* Theming `Dark/Light mode` `Customizable RGB Accent Color` -* True Raspberry Pi 7” Official Touchscreen Brightness Control -* App-Launcher built in -* Camera Access `Streaming/Local` `Backup` `Dash` -* Keyboard Shortcuts `GPIO Triggerable` +* Read CanBus frames from localhost +* Camera size fix and brightness control +* Fix clima bar +* Read SWC, Clima, Temps, Speed, oil level, fuel level, and more. -![](docs/imgs/opendash-ui.gif) -# Getting Started -## Video walk through -_steps may be slightly different such as ia (intelligent-auto) has been renamed to dash, the UI has changed, etc..._ +![VirtualBox_Raspberry_15_09_2023_17_28_48](https://github.com/Gioee/astraDash/assets/48024736/cc016721-bed5-4a62-a9d0-ec41741e3f75) -https://youtu.be/CIdEN2JNAzw +![VirtualBox_Raspberry_15_09_2023_17_29_05](https://github.com/Gioee/astraDash/assets/48024736/859c11ee-af64-4587-9a68-9535dddefcbb) -## Install Script +![VirtualBox_Raspberry_15_09_2023_17_29_18](https://github.com/Gioee/astraDash/assets/48024736/0e7b7945-c339-4613-9159-b08777a23825) -Dash can be built automatically utilizing an included script. +![VirtualBox_Raspberry_15_09_2023_17_29_27](https://github.com/Gioee/astraDash/assets/48024736/d01e0933-ddb3-4da1-bf81-2d1f71bbdc3f) -The install script included in the dash repo will install all the required packages and compile all portions of the OpenDash project. - -### 1. Clone the repo, Run the install script -``` -git clone https://github.com/openDsh/dash - -cd dash - -./install.sh -``` +![VirtualBox_Raspberry_15_09_2023_17_29_36](https://github.com/Gioee/astraDash/assets/48024736/ab18e7df-929a-46ed-b63c-08c1ce8a1979) diff --git a/include/app/action.hpp b/include/app/action.hpp index a3997bdb..c2099e8e 100644 --- a/include/app/action.hpp +++ b/include/app/action.hpp @@ -96,18 +96,18 @@ class ActionEventFilter : public QObject { Q_OBJECT - public: - ActionEventFilter(){}; - bool eventFilter(QObject* obj, QEvent* event); - static ActionEventFilter *get_instance(); - QMap eventFilterMap; - - void enable() { this->disabled = false; } - void disable() { this->disabled = true; } - - private: - std::mutex mutex_; - bool disabled = false; + public: + ActionEventFilter(){}; + bool eventFilter(QObject* obj, QEvent* event); + static ActionEventFilter *get_instance(); + QMap eventFilterMap; + + void enable() { this->disabled = false; } + void disable() { this->disabled = true; } + + private: + std::mutex mutex_; + bool disabled = false; }; diff --git a/include/app/arbiter.hpp b/include/app/arbiter.hpp index d9b33bdb..9c00c847 100644 --- a/include/app/arbiter.hpp +++ b/include/app/arbiter.hpp @@ -45,6 +45,7 @@ class Arbiter : public QObject { void increase_volume(uint8_t val); void set_cursor(bool enabled); void set_action(Action *action, QString key); + void send_vehicle_data(QString gauge_id, double value); QMainWindow *window(); QSettings &settings() { return this->session_.settings_; } @@ -77,4 +78,5 @@ class Arbiter : public QObject { void volume_changed(uint8_t volume); void cursor_changed(bool enabled); void action_changed(Action *action, QString key); + void vehicle_update_data(QString gauge_id, double value); }; diff --git a/include/app/config.hpp b/include/app/config.hpp index 2c19face..db9d0600 100644 --- a/include/app/config.hpp +++ b/include/app/config.hpp @@ -1,7 +1,6 @@ #pragma once #include "openauto/Configuration/Configuration.hpp" -#include "canbus/ICANBus.hpp" #include #include @@ -64,8 +63,8 @@ class Config : public QObject { emit si_units_changed(this->si_units); } - inline ICANBus::VehicleBusType get_vehicle_can_bus() { return this->vehicle_can_bus; } - inline void set_vehicle_can_bus(ICANBus::VehicleBusType vehicle_can_bus) + inline bool get_vehicle_can_bus() { return this->vehicle_can_bus; } + inline void set_vehicle_can_bus(bool vehicle_can_bus) { this->vehicle_can_bus = vehicle_can_bus; this->settings.setValue("Pages/Vehicle/can_bus", this->vehicle_can_bus); @@ -186,7 +185,7 @@ class Config : public QObject { QString radio_plugin; QString media_home; bool si_units; - ICANBus::VehicleBusType vehicle_can_bus; + bool vehicle_can_bus; QString vehicle_interface; QString vehicle_plugin; QString cam_network_url; @@ -205,6 +204,6 @@ class Config : public QObject { void si_units_changed(bool si_units); void cam_autoconnect_changed(bool enabled); void cam_overlay_changed(bool enabled); - void vehicle_can_bus_changed(ICANBus::VehicleBusType state); + void vehicle_can_bus_changed(bool state); void vehicle_interface_changed(QString interface); -}; +}; \ No newline at end of file diff --git a/include/app/pages/vehicle.hpp b/include/app/pages/vehicle.hpp index 0401dcc3..deda45f6 100644 --- a/include/app/pages/vehicle.hpp +++ b/include/app/pages/vehicle.hpp @@ -3,60 +3,114 @@ #include #include #include -#include #include "canbus/socketcanbus.hpp" #include "obd/message.hpp" -#include "obd/command.hpp" +#include "obd/conversions.hpp" + #include "app/widgets/selector.hpp" #include "app/widgets/dialog.hpp" - #include "app/pages/page.hpp" class Arbiter; -typedef std::function obd_decoder_t; typedef QPair units_t; +struct font_size_t +{ + int label; + int value; + int unit; +}; +typedef std::function unit_converter_t; + +struct GaugeConfig +{ + QString id; + QString description; + units_t units; + font_size_t font_size; + int precision; + unit_converter_t converter; +}; -class Gauge : public QWidget { +// typedef QList Gauges; +struct GaugesConfig +{ + GaugeConfig AUTONOMIA; + GaugeConfig COOLANT_TEMP; + GaugeConfig RPM; + GaugeConfig SPEED; + GaugeConfig INTAKE_TEMP; + GaugeConfig EXT_TEMP; + GaugeConfig VOLT; + GaugeConfig MAF; + GaugeConfig MAP; + GaugeConfig APP; + GaugeConfig TPAPWM; + GaugeConfig INJ; + GaugeConfig TVENT; + GaugeConfig TANK; + GaugeConfig IGNANGLE; + GaugeConfig BATT; + GaugeConfig RITCYL1; + GaugeConfig RITCYL2; + GaugeConfig RITCYL3; + GaugeConfig RITCYL4; + GaugeConfig SFT; + GaugeConfig LMB1; + GaugeConfig LMB2; + GaugeConfig LSOIL; + GaugeConfig LSLVLCOOLANT; + GaugeConfig LSBENZ; + GaugeConfig LSVOLT; + GaugeConfig LSINIEZS; + GaugeConfig LSINIEZH; + GaugeConfig LSINIEZKM; +}; + +class Gauge : public QWidget +{ Q_OBJECT - public: - enum Orientation { BOTTOM, RIGHT }; +public: + enum Orientation + { + BOTTOM, + RIGHT + }; - Gauge(units_t units, QFont value_font, QFont unit_font, Orientation orientation, int rate, - std::vector cmds, int precision, obd_decoder_t decoder, QWidget *parent = nullptr); + Gauge(GaugeConfig cfg, QFont value_font, QFont unit_font, Orientation orientation, QWidget *parent = nullptr); - inline void start() { this->timer->start(this->rate); } - inline void stop() { this->timer->stop(); } - void can_callback(QByteArray payload); + inline QString get_id() { return this->id; }; + void set_value(double value); - private: +private: QString format_value(double value); QString null_value(); QLabel *value_label; - obd_decoder_t decoder; - std::vector cmds; + unit_converter_t converter; + QString id; bool si; - int rate; int precision; - QTimer *timer; + units_t units; - signals: +signals: void toggle_unit(bool si); }; -class VehiclePage : public QTabWidget, public Page { +class VehiclePage : public QTabWidget, public Page +{ Q_OBJECT - public: +public: VehiclePage(Arbiter &arbiter, QWidget *parent = nullptr); + QWidget *obd; void init() override; - private: +private: void get_plugins(); void load_plugin(); QWidget *dialog_body(); @@ -67,26 +121,83 @@ class VehiclePage : public QTabWidget, public Page { QMap plugins; QStringList can_devices; QStringList serial_devices; - QMap paired_bt_devices; QPluginLoader *active_plugin; Selector *plugin_selector; Config *config; }; -class DataTab : public QWidget { +class DataTab : public QWidget +{ Q_OBJECT - public: +public: DataTab(Arbiter &arbiter, QWidget *parent = nullptr); - private: +private: Arbiter &arbiter; QWidget *speedo_tach_widget(); - // QWidget *mileage_data_widget(); QWidget *engine_data_widget(); - QWidget *coolant_temp_widget(); - QWidget *engine_load_widget(); + QWidget *vehicle_data_widget(GaugeConfig cfg); + + std::vector gauges; +}; + +class Obd1Tab : public QWidget +{ + Q_OBJECT + +public: + Obd1Tab(Arbiter &arbiter, QWidget *parent = nullptr); + +private: + Arbiter &arbiter; + QWidget *obd_data_widget(int colonna); + QWidget *vehicle_data_widget(GaugeConfig cfg); + + std::vector gauges; +}; + +class Obd2Tab : public QWidget +{ + Q_OBJECT + +public: + Obd2Tab(Arbiter &arbiter, QWidget *parent = nullptr); + +private: + Arbiter &arbiter; + QWidget *obd_data_widget(int colonna); + QWidget *vehicle_data_widget(GaugeConfig cfg); + + std::vector gauges; +}; + +class LSTab : public QWidget +{ + Q_OBJECT + +public: + LSTab(Arbiter &arbiter, QWidget *parent = nullptr); + +private: + Arbiter &arbiter; + QWidget *ls_data_widget(int colonna); + QWidget *vehicle_data_widget(GaugeConfig cfg); std::vector gauges; }; +class ACTab : public QWidget +{ + Q_OBJECT + +public: + ACTab(Arbiter &arbiter, QWidget *parent = nullptr); + +private: + Arbiter &arbiter; + QWidget *aq_row_widget(); + QWidget *aq_selector_widget(); + QWidget *ac_row_widget(); + QWidget *ac_switch_widget(); +}; diff --git a/include/app/widgets/climate.hpp b/include/app/widgets/climate.hpp index 43ee3403..17670dba 100644 --- a/include/app/widgets/climate.hpp +++ b/include/app/widgets/climate.hpp @@ -13,7 +13,9 @@ enum Airflow : uint8_t OFF = 0, DEFROST = (1 << 0), BODY = (1 << 1), - FEET = (1 << 2) + FEET = (1 << 2), + RECIRCULATE = (1 << 3), + AC = (1 << 4) }; class ClimateSnackBar : public SnackBar { @@ -22,8 +24,8 @@ class ClimateSnackBar : public SnackBar { public: ClimateSnackBar(Arbiter &arbiter); - void set_left_temp(int temp); - void set_right_temp(int temp); + void set_left_temp(QString temp); + void set_right_temp(QString temp); void set_airflow(uint8_t airflow); void set_max_fan_speed(int max_speed); void set_fan_speed(int speed); @@ -49,17 +51,17 @@ class Climate : public QWidget { void fan_speed(int fan_speed); uint8_t airflow() const { return this->airflow_; } void airflow(uint8_t airflow); - int left_temp() const { return this->left_temp_; } - void left_temp(int left_temp); - int right_temp() const { return this->right_temp_; } - void right_temp(int right_temp); + QString left_temp() const { return this->left_temp_; } + void left_temp(QString left_temp); + QString right_temp() const { return this->right_temp_; } + void right_temp(QString right_temp); private: int max_fan_speed_ = 0; int fan_speed_ = 0; uint8_t airflow_ = Airflow::OFF; - int left_temp_ = 0; - int right_temp_ = 0; + QString left_temp_; + QString right_temp_; ClimateSnackBar *snack_bar; }; diff --git a/include/canbus/ICANBus.hpp b/include/canbus/ICANBus.hpp index af617584..65b0ba0d 100644 --- a/include/canbus/ICANBus.hpp +++ b/include/canbus/ICANBus.hpp @@ -6,8 +6,6 @@ class ICANBus : public QObject { Q_OBJECT public: - virtual bool writeFrame(QCanBusFrame frame) = 0; - virtual void registerFrameHandler(int id, std::function callback) = 0; - enum VehicleBusType { SocketCAN, ELM327USB, ELM327BT }; + enum VehicleBusType { SocketCAN}; Q_ENUM(VehicleBusType) }; \ No newline at end of file diff --git a/include/canbus/elm327.hpp b/include/canbus/elm327.hpp deleted file mode 100644 index 6a15625b..00000000 --- a/include/canbus/elm327.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#include "DashLog.hpp" -#include "canbus/ICANBus.hpp" -#include "app/config.hpp" - -class elm327 : public ICANBus -{ - Q_OBJECT - public: - elm327(QString canInterface = "/dev/pts/1", bool bluetooth=false); - ~elm327(); - static elm327 *get_usb_instance(); - static elm327 *get_bt_instance(); - void registerFrameHandler(int id, std::function callback) override; - bool writeFrame(QCanBusFrame frame) override; - void connect(QString dev_path, speed_t baudrate); - void initialize(); - inline bool is_connected() { return this->connected; } - enum OBDType {USB, BT}; - inline OBDType get_adapter_type(){return this->adapterType;} - private: - bool connected; - OBDType adapterType; - QBluetoothSocket* btSocket; - int fd; - std::mutex elm_mutex; - std::map>> callbacks; - QTimer* bluetooth_watchdog; - - void connect(std::string dev_path, speed_t baudrate); - void handleFrame(QCanBusFrame frame); - std::string _read(); - QCanBusFrame receive(); - int _write(std::string str); - bool is_failed_response(std::string str); - inline std::string raw_query(std::string cmd) { return (this->_write(cmd) > 0) ? this->_read() : ""; } - - public slots: - void btConnected(); - void socketChanged(QBluetoothSocket::SocketState state); - -}; - diff --git a/include/canbus/socketcanbus.hpp b/include/canbus/socketcanbus.hpp index e8339fbc..f747494a 100644 --- a/include/canbus/socketcanbus.hpp +++ b/include/canbus/socketcanbus.hpp @@ -1,34 +1,27 @@ #pragma once -#include +#include #include #include #include #include +#include +#include +#include +#include #include "DashLog.hpp" -#include "canbus/ICANBus.hpp" #include "app/config.hpp" -class SocketCANBus : public ICANBus +class SocketCANBus : public QObject { Q_OBJECT - public: - SocketCANBus(QString canInterface = "can0"); - ~SocketCANBus(); - static SocketCANBus *get_instance(); - void registerFrameHandler(int id, std::function callback) override; - bool writeFrame(QCanBusFrame frame) override; +public: + SocketCANBus(QObject *parent = 0, QString canInterface = "can0"); + ~SocketCANBus(); + static SocketCANBus *get_instance(); + QTcpSocket socket; - private: - bool socketCANAvailable = false; - QCanBusDevice *bus; - std::map>> callbacks; - QList filterList; - - QVector readAllFrames(int numFrames); - - - private slots: - void framesAvailable(); +private: + bool socketCANAvailable = false; + QCanBusDevice *bus; }; - diff --git a/include/obd/command.hpp b/include/obd/command.hpp index b0ed59cc..e996945e 100644 --- a/include/obd/command.hpp +++ b/include/obd/command.hpp @@ -2,22 +2,28 @@ #include #include +#include #include #include "obd/message.hpp" +typedef std::function decoder_t; + struct Command { - std::string description; + QString id; QCanBusFrame frame; - std::function decoder; + decoder_t decoder; + QTimer *timer; + int rate; }; -struct Commands { - Command LOAD; - Command COOLANT_TEMP; - Command RPM; - Command SPEED; - Command INTAKE_TEMP; - Command MAF; -}; +typedef QList Commands; +// struct Commands { +// Command LOAD; +// Command COOLANT_TEMP; +// Command RPM; +// Command SPEED; +// Command INTAKE_TEMP; +// Command MAF; +// }; extern Commands cmds; diff --git a/include/obd/conversions.hpp b/include/obd/conversions.hpp index 82d13f5f..617a426c 100644 --- a/include/obd/conversions.hpp +++ b/include/obd/conversions.hpp @@ -1,9 +1,15 @@ #pragma once -double kph_to_mph(double val) { return val * 0.621371; } +class Conversion +{ +public: + static double kph_to_mph(double val) { return val * 0.621371; }; -double c_to_f(double val) { return (val * 9 / 5) + 32; } + static double c_to_f(double val) { return (val * 9 / 5) + 32; }; -double gps_to_gph(double val) { return val * 0.0805; } + static double gps_to_gph(double val) { return val * 0.0805; }; -double gps_to_lph(double val) { return val * 3.6; } + static double gps_to_lph(double val) { return val * 3.6; }; + + static double l100km_to_mpg(double val) { return (val == 0 ? 0 : (235.214583 / val)); }; +}; \ No newline at end of file diff --git a/include/plugins/vehicle_plugin.hpp b/include/plugins/vehicle_plugin.hpp index 91ce03b6..3db45ff0 100644 --- a/include/plugins/vehicle_plugin.hpp +++ b/include/plugins/vehicle_plugin.hpp @@ -7,7 +7,7 @@ class VehiclePlugin : public Plugin { public: VehiclePlugin() { this->settings.beginGroup("Vehicle"); } virtual ~VehiclePlugin() = default; - virtual bool init(ICANBus* canbus) = 0; + virtual bool init(SocketCANBus* canbus) = 0; }; #define VehiclePlugin_iid "openDsh.plugins.VehiclePlugin" diff --git a/plugins/brightness/x/x.cpp b/plugins/brightness/x/x.cpp index 2bbb2468..ddcf5d33 100644 --- a/plugins/brightness/x/x.cpp +++ b/plugins/brightness/x/x.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "x.hpp" @@ -11,14 +12,7 @@ X::X() bool X::supported() { - if (this->screen != nullptr) { - // Check that we can execute xrandr - QProcess process(this); - process.start(QString("xrandr --version")); - process.waitForFinished(); - return process.exitCode() == 0; - } - return false; + return true; } uint8_t X::priority() @@ -30,7 +24,7 @@ void X::set(int brightness) { if (this->screen != nullptr) { QProcess process(this); - process.start(QString("xrandr --output %1 --brightness %2").arg(this->screen->name()).arg(brightness / 255.0)); + process.start(QString("/home/gioele/lum.sh %1").arg(brightness)); process.waitForFinished(); } } diff --git a/plugins/vehicle/test/test.cpp b/plugins/vehicle/test/test.cpp index af806311..e6a429e4 100644 --- a/plugins/vehicle/test/test.cpp +++ b/plugins/vehicle/test/test.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include "test.hpp" @@ -19,133 +22,601 @@ QList Test::widgets() return tabs; } -bool Test::init(ICANBus*) +bool Test::init(SocketCANBus *bus) { - if (this->arbiter) { + if (this->arbiter) + { this->vehicle = new Vehicle(*this->arbiter); - this->vehicle->pressure_init("psi", 35); + this->vehicle->pressure_init("km", 35); this->vehicle->disable_sensors(); this->vehicle->rotate(270); this->climate = new Climate(*this->arbiter); - this->climate->max_fan_speed(4); - - auto timer = new QTimer(this); - connect(timer, &QTimer::timeout, [this]{ - static bool toggle = false; - - switch(rand() % 50) { - case 0: - this->climate->airflow(Airflow::OFF); - break; - case 1: - this->climate->airflow(Airflow::DEFROST); - break; - case 2: - this->climate->airflow(Airflow::BODY); - break; - case 3: - this->climate->airflow(Airflow::FEET); - break; - case 4: - this->climate->airflow(Airflow::DEFROST | Airflow::BODY); - break; - case 5: - this->climate->airflow(Airflow::DEFROST | Airflow::FEET); - break; - case 6: - this->climate->airflow(Airflow::BODY | Airflow::FEET); - break; - case 7: - this->climate->airflow(Airflow::DEFROST | Airflow::BODY | Airflow::FEET); - break; - case 8: - this->climate->fan_speed((rand() % 4) + 1); - break; - case 9: - this->vehicle->sensor(Position::FRONT_LEFT, rand() % 5); - break; - case 10: - this->vehicle->sensor(Position::FRONT_MIDDLE_LEFT, rand() % 5); - break; - case 11: - this->vehicle->sensor(Position::FRONT_MIDDLE_RIGHT, rand() % 5); - break; - case 12: - this->vehicle->sensor(Position::FRONT_RIGHT, rand() % 5); - break; - case 13: - this->vehicle->sensor(Position::BACK_LEFT, rand() % 5); - break; - case 14: - this->vehicle->sensor(Position::BACK_MIDDLE_LEFT, rand() % 5); - break; - case 15: - this->vehicle->sensor(Position::BACK_MIDDLE_RIGHT, rand() % 5); - break; - case 16: - this->vehicle->sensor(Position::BACK_RIGHT, rand() % 5); - break; - case 17: - this->vehicle->door(Position::FRONT_LEFT, toggle); - break; - case 18: - this->vehicle->door(Position::BACK_LEFT, toggle); - break; - case 19: - this->vehicle->door(Position::FRONT_RIGHT, toggle); - break; - case 20: - this->vehicle->door(Position::BACK_RIGHT, toggle); - break; - case 21: - this->vehicle->headlights(toggle); - break; - case 22: - this->vehicle->taillights(toggle); - break; - case 23: - this->vehicle->pressure(Position::BACK_RIGHT, (rand() % 21) + 30); - break; - case 24: - this->vehicle->pressure(Position::BACK_LEFT, (rand() % 21) + 30); - break; - case 25: - this->vehicle->pressure(Position::FRONT_RIGHT, (rand() % 21) + 30); - break; - case 26: - this->vehicle->pressure(Position::FRONT_LEFT, (rand() % 21) + 30); - break; - case 27: - this->vehicle->wheel_steer((rand() % 10) * ((rand() % 2) ? 1 : -1)); - break; - case 28: - this->vehicle->indicators(Position::LEFT, toggle); - break; - case 29: - this->vehicle->indicators(Position::RIGHT, toggle); - break; - case 30: - this->vehicle->hazards(toggle); - break; - default: - toggle = !toggle; - break; - } - }); - timer->start(1000); - - auto timer2 = new QTimer(this); - connect(timer2, &QTimer::timeout, [this]{ - if (rand() % 10 == 1) { - this->climate->left_temp((rand() % 20) + 60); - this->climate->right_temp((rand() % 20) + 60); - } - }); - timer2->start(1000); + this->climate->max_fan_speed(7); + /* + + static bool toggle = false; + + switch(rand() % 50) { + case 0: + this->climate->airflow(Airflow::OFF); + break; + case 10: + this->vehicle->sensor(Position::FRONT_MIDDLE_LEFT, rand() % 5); + break; + case 11: + this->vehicle->sensor(Position::FRONT_MIDDLE_RIGHT, rand() % 5); + break; + case 13: + this->vehicle->sensor(Position::BACK_LEFT, rand() % 5); + break; + case 14: + this->vehicle->sensor(Position::BACK_MIDDLE_LEFT, rand() % 5); + break; + case 15: + this->vehicle->sensor(Position::BACK_MIDDLE_RIGHT, rand() % 5); + break; + case 16: + this->vehicle->sensor(Position::BACK_RIGHT, rand() % 5); + break; + case 17: + this->vehicle->door(Position::FRONT_LEFT, toggle); + break; + case 18: + this->vehicle->door(Position::BACK_LEFT, toggle); + break; + case 19: + this->vehicle->door(Position::FRONT_RIGHT, toggle); + break; + case 20: + this->vehicle->door(Position::BACK_RIGHT, toggle); + break; + case 21: + this->vehicle->headlights(toggle); + break; + case 22: + this->vehicle->taillights(toggle); + break; + case 27: + this->vehicle->wheel_steer((rand() % 10) * ((rand() % 2) ? 1 : -1)); + break; + case 28: + this->vehicle->indicators(Position::LEFT, toggle); + break; + case 29: + this->vehicle->indicators(Position::RIGHT, toggle); + break; + case 30: + this->vehicle->hazards(toggle); + break; + default: + toggle = !toggle; + break; + } + */ + socketcan(bus); + QObject::connect(&bus->socket, &QTcpSocket::readyRead, this, &Test::readFrame); return true; } return false; } + +void Test::readFrame() +{ + + while (bus->socket.canReadLine()) + { + + QString linea = QString(bus->socket.readLine()); + // DASH_LOG(info) << "[PLUGIN] CAN-BUS = " << linea.toStdString() << "\n"; + + if (linea.contains(" ") && linea.contains("-")) // checks to avoid a split crash + { + + QString canbus = linea.split(" ")[0]; + QString id = linea.split(" ")[1].split("-")[0]; + QString data = linea.split(" ")[1].split("-")[1]; + + uint8_t canMsg[8]; + + QString duo; + + int j = 0; + bool ok; + for (int i = 0; i < data.length(); i++) + { + if (i % 2 == 0 && i != 0) + { + canMsg[j] = duo.toUInt(&ok, 16); + duo = ""; + j++; + } + duo.append(data[i]); + } + + // MS-CAN + + if (canbus == "RX1") + { + + // Esempio RX1 04E8-460F0D18000001 + + if (id == "04E8") + { + int rpm = (int)(((canMsg[2] << 8) + canMsg[3]) >> 2); // tachometer=((2_byte<<8)+3_byte)>>2 + int velocita = (int)(((canMsg[4] << 1) & 0xFE) + ((canMsg[5] >> 7) & 0x01)); // speed=((5_bytes<<1)&0xFE)+((6_bytes>>7)&0x01) + + if (velocita != velsalvata) + { + this->arbiter->vehicle_update_data("speed", velocita); + velsalvata = velocita; + } + if (rpm != rpmsalvati) + { + this->arbiter->vehicle_update_data("rpm", rpm); + rpmsalvati = rpm; + } + + // DASH_LOG(info) << "VELOCITA:" << QString::number(velocita).toStdString() << "\r\n"; + // DASH_LOG(info) << "RPM:" << QString::number(rpm).toStdString() << "\r\n"; + } + + // Esempio RX1 0206-008401 + + if (id == "0206") + { + + if (canMsg[0] == 0x01 && canMsg[2] > 4 && premuto == false) + { + premuto = true; + + switch (canMsg[1]) + { + case 0x81: + this->arbiter->set_curr_page(0); + // DASH_LOG(info) << "PREMUTO pulsante in alto a sinistra\r\n"; + break; + case 0x82: + this->arbiter->set_curr_page(3); + // DASH_LOG(info) << "PREMUTO Pulsante giù a sinistra\r\n"; + break; + case 0x84: + // non usare temp + DASH_LOG(info) << "PREMUTO Pulsante manopola sinistra\r\n"; + break; + case 0x91: + this->arbiter->android_auto().handler->injectButtonPressHelper(aasdk::proto::enums::ButtonCode::MICROPHONE_1, Action::ActionState::Triggered); + // DASH_LOG(info) << "PREMUTO Pulsante destro in alto (successivo)\r\n"; + break; + case 0x92: + this->arbiter->android_auto().handler->injectButtonPressHelper(aasdk::proto::enums::ButtonCode::TOGGLE_PLAY, Action::ActionState::Triggered); + // DASH_LOG(info) << "PREMUTO Pulsante in basso a destra\r\n"; + break; + } + } + + if (canMsg[0] == 0x00) + { + if (premuto == false) + { + switch (canMsg[1]) + { + case 0x81: + // DASH_LOG(info) << "pulsante in alto a sinistra\r\n"; + this->arbiter->android_auto().handler->injectButtonPressHelper(aasdk::proto::enums::ButtonCode::ENTER, Action::ActionState::Triggered); + break; + case 0x82: // DASH_LOG(info) << "Pulsante giù a sinistra\r\n"; + this->arbiter->set_curr_page(this->arbiter->layout().next_enabled_page(this->arbiter->layout().curr_page)); + break; + case 0x84: + // non usare temp + DASH_LOG(info) << "Pulsante manopola sinistra\r\n"; + break; + case 0x91: + this->arbiter->android_auto().handler->injectButtonPressHelper(aasdk::proto::enums::ButtonCode::NEXT, Action::ActionState::Triggered); + // DASH_LOG(info) << "Pulsante destro in alto (successivo)\r\n"; + break; + case 0x92: + this->arbiter->android_auto().handler->injectButtonPressHelper(aasdk::proto::enums::ButtonCode::PREV, Action::ActionState::Triggered); + // DASH_LOG(info) << "Pulsante in basso a destra\r\n"; + break; + } + } + else + { + premuto = false; + } + } + + if (canMsg[0] == 0x08) + { + if (canMsg[1] == 0x83) + { + if (canMsg[2] == 0xFF) + { + this->arbiter->android_auto().handler->injectButtonPress(aasdk::proto::enums::ButtonCode::SCROLL_WHEEL, openauto::projection::WheelDirection::RIGHT); + // DASH_LOG(info) << "Manopola sinistra SU\r\n"; + } + else + { + this->arbiter->android_auto().handler->injectButtonPress(aasdk::proto::enums::ButtonCode::SCROLL_WHEEL, openauto::projection::WheelDirection::LEFT); + // DASH_LOG(info) << "Manopola sinistra GIU\r\n"; + } + } + + if (canMsg[1] == 0x93) + { + if (canMsg[2] == 0xFF) + { + // DASH_LOG(info) << "Manopola destra (Volume) GIU\r\n"; + this->arbiter->decrease_volume(10); + } + else + { + // DASH_LOG(info) << "Manopola destra (Volume) SU\r\n"; + this->arbiter->increase_volume(10); + } + } + } + } + + if (id == "02B0") + { + if((canMsg[0] == 0x46) && (canMsg[1] == 0x0C) && (canMsg[2] == 0x00) && (canMsg[3] == 0xC8)){ + bloccato = false; + } else { + bloccato = true; + } + } + + if (id == "0208") + { + if((canMsg[0] == 0x01) && (canMsg[1] == 0x17) && (canMsg[2] == 0x00) && bloccato == false){ + usleep(200000); + bus->socket.write(QString("CAN USER TX CH1 0208 081601000000\r\n").toUtf8()); //turn right + bus->socket.flush(); + usleep(200000); + bus->socket.write(QString("CAN USER TX CH1 0208 011700000000\r\n").toUtf8()); //button press + bus->socket.flush(); + usleep(70000); + bus->socket.write(QString("CAN USER TX CH1 0208 001700000000\r\n").toUtf8()); //button release + bus->socket.flush(); + usleep(200000); + bus->socket.write(QString("CAN USER TX CH1 0208 0816FF000000\r\n").toUtf8()); //turn left + bus->socket.flush(); + usleep(30000); + bus->socket.write(QString("CAN USER TX CH1 0208 0816FF000000\r\n").toUtf8()); //turn left + bus->socket.flush(); + usleep(200000); + bus->socket.write(QString("CAN USER TX CH1 0208 0816FF000000\r\n").toUtf8()); //turn left + bus->socket.flush(); + usleep(30000); + bus->socket.write(QString("CAN USER TX CH1 0208 0816FF000000\r\n").toUtf8()); //turn left + bus->socket.flush(); + usleep(200000); + bus->socket.write(QString("CAN USER TX CH1 0208 011700000000\r\n").toUtf8()); //button press + bus->socket.flush(); + usleep(70000); + bus->socket.write(QString("CAN USER TX CH1 0208 001700000000\r\n").toUtf8()); //button release + bus->socket.flush(); + usleep(200000); + } + } + + // Esempio RX1 0450-460706FF + + if (id == "0450") + { + int valore_ws = (int)(canMsg[3] / 25.5); + + if (valore_ws != lumws) + { + // DASH_LOG(info) << "NUOVA LUMINOSITA:" << QString::number(valore_ws).toStdString() << "\r\n"; + this->arbiter->set_brightness(canMsg[3]); + lumws = valore_ws; + } + } + + // Esempio RX1 04EE-46030130 + + if (id == "04EE") + { + int valore_km = 0; + + if (canMsg[2] == 0x10) + { + valore_km = canMsg[3] / 2; + } + else + { + valore_km = (int)(((canMsg[2] << 8) + canMsg[3]) / 2); + } + + if (valore_km != kmsalvati) + { + // DASH_LOG(info) << "NUOVA AUTONOMIA:" << QString::number(valore_km).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("autonomia", valore_km); + kmsalvati = valore_km; + } + } + + // Esempio RX1 0682-46017A + + if (id == "0682") + { + double temp = ((double)canMsg[2]) / 2 - 40; + + if (temp != tempsalvata) + { + // DASH_LOG(info) << "Temperatura esterna:" << QString::number(temp).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("ext_temp", temp); + tempsalvata = temp; + } + } + + // Esempio RX1 04EC-46075A2C00 + + if (id == "04EC") + { + + int tempCoolant = ((int)canMsg[2]) - 40; + + if (ttCool != tempCoolant) + { + // DASH_LOG(info) << "Antigelo:" << QString::number(tempCoolant).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("coolant_temp", tempCoolant); + ttCool = tempCoolant; + } + } + + // Esempio RX1 06C8-21004800692401E0 + + if (id == "06C8") + { + + switch (canMsg[0]) // mode? + { + case 0x21: // normal mode, change flow direction + if (canMsg[1] == 0xE0) + { + switch (canMsg[2]) + { + case 0x52: // all: + this->climate->airflow(Airflow::DEFROST | Airflow::BODY | Airflow::FEET); + break; + case 0x53: // up: + this->climate->airflow(Airflow::DEFROST); + break; + case 0x54: // up_middle: + this->climate->airflow(Airflow::DEFROST | Airflow::BODY); + break; + case 0x55: // middle: + this->climate->airflow(Airflow::BODY); + break; + case 0x56: // middle_down: + this->climate->airflow(Airflow::BODY | Airflow::FEET); + break; + case 0x57: // down: + this->climate->airflow(Airflow::FEET); + break; + case 0x58: // up_down: + this->climate->airflow(Airflow::DEFROST | Airflow::FEET); + break; + case 0x59: // dir_auto: + //DASH_LOG(info) << "AC AUTO \r\n"; + this->climate->right_temp("AUTO1"); + break; + } + } + break; + + case 0x22: // normal mode, change flow speed or temperature + switch (canMsg[1]) + { + case 0x03: + tempAC = 10 * (canMsg[3] - 0x30) + (canMsg[5] - 0x30); + this->climate->left_temp(QString("%1°").arg(tempAC)); + break; + + case 0x4C: + this->climate->left_temp(QString("LOW")); + break; + + case 0x48: + this->climate->left_temp(QString("HIGH")); + break; + case 0x36: + this->climate->airflow(Airflow::DEFROST); + break; + case 0x50: // fan set. canMsg[3] = canMsg[4] = ascii + fanAC = canMsg[3] - 0x30; + this->climate->fan_speed(fanAC); + break; + } + if(canMsg[4] == 0x25){ + if(canMsg[5] == 0x01){ + ac = true; + } + if(canMsg[5] == 0x03){ + ac = false; + } + + if(acprev!=ac){ + this->climate->right_temp(QString("AC %1").arg(ac?"ON":"OFF")); + acprev=ac; + } + } + if(canMsg[2] == 0xE0){ + //this->climate->right_temp("AUTO2");climauto flowauto + } + break; + + case 0x24: // normal mode, auto flow? status 4 is speed, 30 - 37 + /*fanAC = canMsg[3] - 0x30; + DASH_LOG(info) << "VENTOLE:" << QString::number(fanAC).toStdString() << "\r\n"; + this->climate->fan_speed(fanAC);*/ + break; + + case 0x25: // normal mode, auto flow speed, status + // [4] is E0 = full auto speed, 41 = manual flow direction + break; + + case 0x26: // air distribution mode, + // [7] is flow direction , 52 - 59 + break; + } + } + } + + // HS-CAN + + if (canbus == "RX2") + { + + // Esempio RX2 0510-0442432E + + if (id == "0510") + { + + int tempCoolant = ((int)canMsg[1]) - 40; + + if (ttCool != tempCoolant) + { + // DASH_LOG(info) << "Antigelo:" << QString::number(tempCoolant).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("coolant_temp", tempCoolant); + ttCool = tempCoolant; + } + } + + //LSCAN + + if(id == "0110"){ + double leftWheel = ((canMsg[1] << 8 | canMsg[2])*1.5748)*0.00001; + double rightWheel = ((canMsg[3] << 8 | canMsg[4]) * 1.5748) * 0.00001; + dist = (leftWheel + rightWheel) /2; + + if (ttrightWheel != rightWheel) + { + this->vehicle->sensor(Position::FRONT_RIGHT, rightWheel); + ttrightWheel = rightWheel; + } + + if (ttleftWheel != leftWheel) + { + this->vehicle->sensor(Position::FRONT_LEFT, leftWheel); + ttleftWheel = leftWheel; + } + + } + + if(id == "0145") + { + int tempCoolant = ((int)canMsg[3]) - 40; + ign = canMsg[1]; + + if (ttCool != tempCoolant) + { + // DASH_LOG(info) << "Antigelo:" << QString::number(tempCoolant).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("coolant_temp", tempCoolant); + ttCool = tempCoolant; + } + + int tempOil = ((int)canMsg[2]); + + if (ttOil != tempOil) + { + this->arbiter->vehicle_update_data("lsoil", tempOil); + ttOil = tempOil; + } + } + + if(id=="0350") + { + int templvlCoolant = (int)(canMsg[1] & 8); //se 0b....1... allora and con 8 = 8 e coolant basso, altrimenti coolant alto + + if (ttlvlCool != templvlCoolant) + { + this->arbiter->vehicle_update_data("lslvlcoolant", templvlCoolant); + ttlvlCool = templvlCoolant; + } + /* + double temp = ((((canMsg[1] & 0x03) << 8) + canMsg[2])/ 8.0) - 40.0; + + if (temp != tempsalvata) + { + // DASH_LOG(info) << "Temperatura esterna:" << QString::number(temp).toStdString() << "\r\n"; + this->arbiter->vehicle_update_data("ext_temp", temp); + tempsalvata = temp; + } + */ + } + + if (id == "0375") + { + double tempBenz = 94 - (((int)canMsg[1])/2); + //double tempBenz = (((int)((canMsg[1] & 255) | (canMsg[0] << 8))) * (-0.6)) + 100.0; + //double tempBenz = codBenz[((int)canMsg[1])-80]; + + if (ttBenz != tempBenz) + { + this->arbiter->vehicle_update_data("lsbenz", tempBenz); + ttBenz = tempBenz; + } + } + + if (id == "0500") + { + + //double tempVolt = (((canMsg[0] << 8) + canMsg[1])-28.0)/10.0; + double tempVolt = 2.8+canMsg[1]*0.1; + + if (ttVolt != tempVolt) + { + this->arbiter->vehicle_update_data("lsvolt", tempVolt); + ttVolt = tempVolt; + } + } + + if (id == "0130") + { + double cons = (canMsg[1]<<8)+canMsg[2]; + double tempcons; + double hcons; + + if(ign!=0){ + + if(cons != lastcons){ + + if(conslastcons){ + tempcons = (cons - lastcons) * 0.03054; + hcons = tempcons * 3.6; + } + + lastcons = cons; + } + + if (ttlastconss != tempcons) + { + this->arbiter->vehicle_update_data("lsiniezs", tempcons); + ttlastconss = tempcons; + } + + if (ttlastconsh != hcons) + { + this->arbiter->vehicle_update_data("lsiniezh", hcons); + ttlastconsh = hcons; + } + + } + } + } + } + } +} diff --git a/plugins/vehicle/test/test.hpp b/plugins/vehicle/test/test.hpp index 51495288..96123091 100644 --- a/plugins/vehicle/test/test.hpp +++ b/plugins/vehicle/test/test.hpp @@ -1,23 +1,62 @@ #pragma once #include +#include #include "plugins/vehicle_plugin.hpp" #include "app/widgets/climate.hpp" #include "app/widgets/vehicle.hpp" #include "canbus/socketcanbus.hpp" +#include "app/arbiter.hpp" -class Test : public QObject, VehiclePlugin { +class Test : public QObject, VehiclePlugin +{ Q_OBJECT Q_PLUGIN_METADATA(IID VehiclePlugin_iid FILE "test.json") Q_INTERFACES(VehiclePlugin) - public: - Test() {}; +public: + Test(){}; ~Test(); QList widgets() override; - bool init(ICANBus*) override; + bool init(SocketCANBus *bus) override; - private: + inline void socketcan(SocketCANBus *bus) + { + if (!this->bus) + this->bus = bus; + } + +private: Climate *climate; Vehicle *vehicle; + int lumws = 0; + int tempAC = 0; + int fanAC = 0; + int ttCool = 0; + int ttlvlCool = 0; + int kmsalvati = 0; + int rpmsalvati = 0; + int velsalvata = 0; + double tempsalvata = 0; + double lastcons = 0; + double ttlastconss = 0; + double ttlastconsh = 0; + int ttOil = 0; + int ign = 0; + double ttleftWheel=0; + double ttrightWheel=0; + double dist = 0; + double ttVolt = 0; + double ttBenz = 0; + //double codBenz [100] = {52.0, 52.0, 52.0, 52.0, 52.0, 51.2, 50.5, 49.8, 49.1, 48.4, 47.7, 47.0, 46.2, 45.2, 44.8, 44.1, 43.4, 42.7, 42.0, 41.3, 40.7, 40.1, 39.5, 38.8, 38.2, 37.6, 37.0, 36.3, 35.7, 35.1, 34.5, 33.8, 33.2, 32.6, 32.0, 31.3, 30.6, 30.0, 29.3, 28.6, 28.0, 27.3, 26.6, 26.0, 25.3, 24.6, 24.0, 23.3, 22.6, 22.0, 21.3, 20.7, 20.0, 19.4, 18.7, 18.1, 17.5, 16.8, 16.2, 15.5, 14.9, 14.2, 13.6, 13.0, 12.5, 12.1, 11.6, 11.2, 10.8, 10.3, 9.9, 9.5, 9.0, 8.6, 8.1, 7.7, 7.3, 6.8, 6.4, 6.0, 5.7, 5.4, 5.1, 4.8, 4.5, 4.2, 4.0, 3.7, 3.4, 3.1, 2.8, 2.5, 2.2, 2.0, 1.7, 1.4, 1.1, 0.8, 0.5, 0.2}; + bool premuto = false; + bool bloccato = false; + bool ac = false; + bool acprev = false; + SocketCANBus *bus = nullptr; + +signals: + +private slots: + void readFrame(); }; diff --git a/src/app/arbiter.cpp b/src/app/arbiter.cpp index 2c8c6302..33db8d78 100644 --- a/src/app/arbiter.cpp +++ b/src/app/arbiter.cpp @@ -85,7 +85,7 @@ void Arbiter::set_curr_page(Page *page) { if (this->layout().page_id(page) < 0 || !page->enabled()) return; - + if (this->layout().fullscreen.enabled) this->layout().curr_page->container()->reset(); @@ -198,12 +198,12 @@ void Arbiter::set_brightness(uint8_t brightness) void Arbiter::decrease_brightness(uint8_t val) { - this->set_brightness(std::min(std::max(76, this->system().brightness.value - val), 255)); + this->set_brightness(std::min(std::max(0, this->system().brightness.value - val), 255)); } void Arbiter::increase_brightness(uint8_t val) { - this->set_brightness(std::min(std::max(76, this->system().brightness.value + val), 255)); + this->set_brightness(std::min(std::max(0, this->system().brightness.value + val), 255)); } void Arbiter::set_volume(uint8_t volume) @@ -259,3 +259,9 @@ QMainWindow *Arbiter::window() { return this->window_; } + + +void Arbiter::send_vehicle_data(QString gauge_id, double value) +{ + emit vehicle_update_data(gauge_id, value); +} \ No newline at end of file diff --git a/src/app/config.cpp b/src/app/config.cpp index bb9f4a24..e7baeee3 100644 --- a/src/app/config.cpp +++ b/src/app/config.cpp @@ -14,10 +14,7 @@ Config::Config() this->radio_plugin = this->settings.value("Pages/Media/Radio/plugin", "unloader").toString(); this->media_home = this->settings.value("Pages/Media/Local/home", QDir().absolutePath()).toString(); this->si_units = this->settings.value("Pages/Vehicle/si_units", false).toBool(); - // 0 - SocketCAN - // 1 - Elm 327 USB - // 2 - Elm 327 Bluetooth - this->vehicle_can_bus = (ICANBus::VehicleBusType)(this->settings.value("Pages/Vehicle/can_bus", ICANBus::VehicleBusType::SocketCAN).toInt()); + this->vehicle_can_bus = this->settings.value("Pages/Vehicle/can_bus", false).toBool(); this->vehicle_interface = this->settings.value("Pages/Vehicle/interface", "disabled").toString(); this->vehicle_plugin = this->settings.value("Pages/Vehicle/plugin", "unloader").toString(); this->cam_network_url = this->settings.value("Pages/Camera/stream_url", QString()).toString(); diff --git a/src/app/pages/camera.cpp b/src/app/pages/camera.cpp index dd1de836..3b6547c8 100644 --- a/src/app/pages/camera.cpp +++ b/src/app/pages/camera.cpp @@ -582,10 +582,12 @@ void CameraPage::connect_local_stream() qDebug() << "camera status: " << this->local_cam->status(); QSize res = this->choose_video_resolution(); + + qDebug() << "RES=" << res; DASH_LOG(info) << "[CameraPage] Creating GStreamer pipeline with " << this->config->get_cam_local_device().toStdString(); std::string pipeline = "v4l2src device=" + this->config->get_cam_local_device().toStdString() + - " ! capsfilter caps=\"video/x-raw,width=" + std::to_string(res.width()) + ",height=" + std::to_string(res.height()) + ";image/jpeg,width=" + std::to_string(res.width()) + ",height=" + std::to_string(res.height()) + "\"" + + " ! capsfilter caps=\"video/x-raw,width=" + std::to_string(res.width()) + ",height=" + std::to_string(res.height()) + ",colorimetry=bt601;image/jpeg,width=" + std::to_string(res.width()) + ",height=" + std::to_string(res.height()) + "\"" + " ! decodebin"; init_gstreamer_pipeline(pipeline); //emit the connected signal before we resize anything, so that videoContainer has had time to resize to the proper dimensions @@ -646,7 +648,8 @@ QSize CameraPage::choose_video_resolution() QSize window_size = this->size(); QCameraImageCapture imageCapture(this->local_cam); int min_gap = 10000, xgap, ygap; - QSize max_fit; + QSize max_fit, min_fit; + bool first = true; qDebug() << "camera: " << this->local_cam; qDebug() << "resolutions: " << imageCapture.supportedResolutions(); @@ -657,13 +660,21 @@ QSize CameraPage::choose_video_resolution() min_gap = xgap + ygap; max_fit = resolution; } + else{ + if(first){ + first=false; + min_fit=resolution; + } + } } if (max_fit.isValid()) { qDebug() << "Local cam auto resolution" << max_fit << "to fit in" << window_size; this->local_cam_settings.setResolution(max_fit); } else { - qDebug() << "No suitable resolutions found to fit in" << window_size; + qDebug() << "No suitable resolutions found to fit in" << window_size << ". I'll try with the lowest one " << min_fit; + this->local_cam_settings.setResolution(min_fit); + max_fit=min_fit; } if (this->config->get_cam_local_format_override() > 0) { diff --git a/src/app/pages/vehicle.cpp b/src/app/pages/vehicle.cpp index 1193568e..4b2244ea 100644 --- a/src/app/pages/vehicle.cpp +++ b/src/app/pages/vehicle.cpp @@ -4,45 +4,273 @@ #include "app/config.hpp" #include "app/pages/vehicle.hpp" #include "app/window.hpp" -#include "obd/conversions.hpp" -#include "canbus/elm327.hpp" #include "plugins/vehicle_plugin.hpp" -Gauge::Gauge(units_t units, QFont value_font, QFont unit_font, Gauge::Orientation orientation, int rate, - std::vector cmds, int precision, obd_decoder_t decoder, QWidget *parent) -: QWidget(parent) +GaugesConfig gauges_cfg = + { + {"autonomia", "Autonomia", {"Miles", "Km"}, {10, 16, 12}, 0, [](double x, bool _) + { return x; }}, + {"coolant_temp", "Antigelo", {"°F", "°C"}, {10, 16, 12}, 0, [](double x, bool si) + { return si ? x : Conversion::c_to_f(x); }}, + {"rpm", "Giri al Minuto (RPM)", {"rpm", "rpm"}, {0, 24, 12}, 0, [](double x, bool _) + { return x; }}, + {"speed", "Velocità", {"mph", "km/h"}, {0, 36, 16}, 0, [](double x, bool si) + { return si ? x : Conversion::kph_to_mph(x); }}, + {"intake_temp", "Aspirazione", {"°F", "°C"}, {8, 18, 10}, 1, [](double x, bool si) + { return si ? x : Conversion::c_to_f(x); }}, + {"ext_temp", "Temperatura Esterna", {"°F", "°C"}, {10, 16, 12}, 1, [](double x, bool si) + { return si ? x : Conversion::c_to_f(x); }}, + {"volt", "Batteria", {"V", "V"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"maf", "Debimetro", {"g/s", "g/s"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"map", "Pressione Aspirazione (MAP)", {"kPa", "kPa"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"app", "Acceleratore", {"%", "%"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"tpapwm", "Corpo Farfallato", {"%", "%"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"inj", "Iniezione", {"ms", "ms"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"tvent", "Pompa Benzina", {"%", "%"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"tank", "Serbatoio Benzina", {"L", "L"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"ignangle", "A. Accensione", {"°CA", "°CA"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"batt", "Sensore di Detonazione", {"V", "V"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"ritcyl1", "R. Scoppio C1", {"°CA", "°CA"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"ritcyl2", "R. Scoppio C2", {"°CA", "°CA"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"ritcyl3", "R. Scoppio C3", {"°CA", "°CA"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"ritcyl4", "R. Scoppio C4", {"°CA", "°CA"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"sft", "Taglio Benzina (Carburazione)", {"%", "%"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"lmb1", "Sonda Lambda 1", {"V", "V"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"lmb2", "Sonda Lambda 2", {"V", "V"}, {8, 18, 10}, 1, [](double x, bool si) + { return x; }}, + {"lsoil", "Olio motore", {"lvl", "lvl"}, {10, 16, 12}, 0, [](double x, bool si) + { return x; }}, + {"lslvlcoolant", "Livello Antigelo", {"lvl", "lvl"}, {10, 16, 12}, 0, [](double x, bool si) + { return x; }}, + {"lsbenz", "Benzina", {"L", "L"}, {10, 16, 12}, 1, [](double x, bool si) + { return x; }}, + {"lsvolt", "Tensione Batteria", {"V", "V"}, {10, 16, 12}, 1, [](double x, bool si) + { return x; }}, + {"lsiniezs", "Cons. inst.", {"ml/s", "ml/s"}, {10, 16, 12}, 2, [](double x, bool si) + { return x; }}, + {"lsiniezh", "Cons. orari", {"L", "L"}, {10, 16, 12}, 1, [](double x, bool si) + { return x; }}, + {"lsiniezkm", "Cons. ogni 100km", {"L", "L"}, {10, 16, 12}, 1, [](double x, bool si) + { return x; }} + }; + +Obd1Tab::Obd1Tab(Arbiter &arbiter, QWidget *parent) + : QWidget(parent), arbiter(arbiter) { - Config *config = Config::get_instance(); - ICANBus *bus; - switch(config->get_vehicle_can_bus()){ - //ELM327 USB - case ICANBus::VehicleBusType::ELM327USB: - bus = (ICANBus *)elm327::get_usb_instance(); - break; - //ELM327 Bluetooth - case ICANBus::VehicleBusType::ELM327BT: - bus = (ICANBus *)elm327::get_bt_instance(); - break; - //SocketCAN - case ICANBus::VehicleBusType::SocketCAN: - default: - bus = (ICANBus *)SocketCANBus::get_instance(); - break; - } + QHBoxLayout *layout = new QHBoxLayout(this); + + // QWidget *driving_data = this->speedo_tach_widget(); + // layout->addWidget(driving_data); + // layout->addWidget(Session::Forge::br(true)); + + QWidget *obd_data1 = this->obd_data_widget(1); + layout->addWidget(obd_data1); + layout->addWidget(Session::Forge::br(true)); + QWidget *obd_data2 = this->obd_data_widget(2); + layout->addWidget(obd_data2); + layout->addWidget(Session::Forge::br(true)); + QWidget *obd_data3 = this->obd_data_widget(3); + layout->addWidget(obd_data3); + + // QSizePolicy sp_left(QSizePolicy::Preferred, QSizePolicy::Preferred); + // sp_left.setHorizontalStretch(5); + // driving_data->setSizePolicy(sp_left); + QSizePolicy sp_right(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp_right.setHorizontalStretch(2); + obd_data1->setSizePolicy(sp_right); + obd_data2->setSizePolicy(sp_right); + obd_data3->setSizePolicy(sp_right); + + connect(&this->arbiter, &Arbiter::vehicle_update_data, [this](QString gauge_id, double value) + { + // DASH_LOG(info)<<"[Gauges] arbiter update: "<gauges) { + if(gauge->get_id() == gauge_id){ + // DASH_LOG(info)<<"[Gauges] Found: "<get_id(); + gauge->set_value(value); + } + } }); +} + +Obd2Tab::Obd2Tab(Arbiter &arbiter, QWidget *parent) + : QWidget(parent), arbiter(arbiter) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + + // QWidget *driving_data = this->speedo_tach_widget(); + // layout->addWidget(driving_data); + // layout->addWidget(Session::Forge::br(true)); + + QWidget *obd_data1 = this->obd_data_widget(1); + layout->addWidget(obd_data1); + layout->addWidget(Session::Forge::br(true)); + QWidget *obd_data2 = this->obd_data_widget(2); + layout->addWidget(obd_data2); + layout->addWidget(Session::Forge::br(true)); + QWidget *obd_data3 = this->obd_data_widget(3); + layout->addWidget(obd_data3); + + // QSizePolicy sp_left(QSizePolicy::Preferred, QSizePolicy::Preferred); + // sp_left.setHorizontalStretch(5); + // driving_data->setSizePolicy(sp_left); + QSizePolicy sp_right(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp_right.setHorizontalStretch(2); + obd_data1->setSizePolicy(sp_right); + obd_data2->setSizePolicy(sp_right); + obd_data3->setSizePolicy(sp_right); + + connect(&this->arbiter, &Arbiter::vehicle_update_data, [this](QString gauge_id, double value) + { + // DASH_LOG(info)<<"[Gauges] arbiter update: "<gauges) { + if(gauge->get_id() == gauge_id){ + // DASH_LOG(info)<<"[Gauges] Found: "<get_id(); + gauge->set_value(value); + } + } }); +} + +LSTab::LSTab(Arbiter &arbiter, QWidget *parent) + : QWidget(parent), arbiter(arbiter) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + + // QWidget *driving_data = this->speedo_tach_widget(); + // layout->addWidget(driving_data); + // layout->addWidget(Session::Forge::br(true)); + + QWidget *ls_data1 = this->ls_data_widget(1); + layout->addWidget(ls_data1); + layout->addWidget(Session::Forge::br(true)); + QWidget *ls_data2 = this->ls_data_widget(2); + layout->addWidget(ls_data2); + layout->addWidget(Session::Forge::br(true)); + QWidget *ls_data3 = this->ls_data_widget(3); + layout->addWidget(ls_data3); + + // QSizePolicy sp_left(QSizePolicy::Preferred, QSizePolicy::Preferred); + // sp_left.setHorizontalStretch(5); + // driving_data->setSizePolicy(sp_left); + QSizePolicy sp_right(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp_right.setHorizontalStretch(2); + ls_data1->setSizePolicy(sp_right); + ls_data2->setSizePolicy(sp_right); + ls_data3->setSizePolicy(sp_right); + + connect(&this->arbiter, &Arbiter::vehicle_update_data, [this](QString gauge_id, double value) + { + // DASH_LOG(info)<<"[Gauges] arbiter update: "<gauges) { + if(gauge->get_id() == gauge_id){ + // DASH_LOG(info)<<"[Gauges] Found: "<get_id(); + gauge->set_value(value); + } + } }); +} + +ACTab::ACTab(Arbiter &arbiter, QWidget *parent) + : QWidget(parent), arbiter(arbiter) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + layout->addWidget(this->aq_row_widget(), 1); + layout->addWidget(Session::Forge::br(), 1); + layout->addWidget(this->ac_row_widget(), 1); +} + +QWidget *ACTab::aq_row_widget() +{ + QWidget *widget = new QWidget(this); + QHBoxLayout *layout = new QHBoxLayout(widget); + + QLabel *label = new QLabel("Ventilazione automatica", widget); + layout->addWidget(label, 1); - using namespace std::placeholders; - std::function callback = std::bind(&Gauge::can_callback, this, std::placeholders::_1); + layout->addWidget(this->aq_selector_widget(), 1); - bus->registerFrameHandler(cmds[0].frame.frameId()+0x9, callback); - DASH_LOG(info)<<"[Gauges] Registered frame handler for id "<<(cmds[0].frame.frameId()+0x9); + return widget; +} + +QWidget *ACTab::ac_row_widget() +{ + QWidget *widget = new QWidget(this); + QHBoxLayout *layout = new QHBoxLayout(widget); + + QLabel *label = new QLabel("Aria Condizionata", widget); + layout->addWidget(label, 1); + + layout->addWidget(this->ac_switch_widget(), 1); + + return widget; +} +QWidget *ACTab::aq_selector_widget() +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + + QList autoblower = {"bassa","media","alta"}; + + Selector *selector = new Selector(autoblower, "alta", this->arbiter.forge().font(14), this->arbiter, widget, "high"); + //connect(selector, &Selector::item_changed, [this](QString item){ this->arbiter.set_brightness_plugin(item); }); + + layout->addWidget(selector, 1); + + Switch *toggle = new Switch(widget); + toggle->scale(this->arbiter.layout().scale); + /*toggle->setChecked(this->arbiter.core().cursor); + connect(toggle, &Switch::stateChanged, [this](bool state){ + this->arbiter.set_cursor(state); + });*/ + layout->addWidget(toggle, 1, Qt::AlignHCenter); + + return widget; +} + +QWidget *ACTab::ac_switch_widget() +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + + Switch *toggle = new Switch(widget); + toggle->scale(this->arbiter.layout().scale); + /*toggle->setChecked(this->arbiter.core().cursor); + connect(toggle, &Switch::stateChanged, [this](bool state){ + this->arbiter.set_cursor(state); + });*/ + layout->addWidget(toggle, 1, Qt::AlignHCenter); + + return widget; +} + +Gauge::Gauge(GaugeConfig cfg, QFont value_font, QFont unit_font, Gauge::Orientation orientation, QWidget *parent) + : QWidget(parent) +{ + Config *config = Config::get_instance(); + + this->id = cfg.id; this->si = config->get_si_units(); - this->rate = rate; - this->precision = precision; + this->precision = cfg.precision; - this->cmds = cmds; - this->decoder = decoder; + this->units = cfg.units; + this->converter = cfg.converter; QBoxLayout *layout; if (orientation == BOTTOM) @@ -54,22 +282,15 @@ Gauge::Gauge(units_t units, QFont value_font, QFont unit_font, Gauge::Orientatio value_label->setFont(value_font); value_label->setAlignment(Qt::AlignCenter); - QLabel *unit_label = new QLabel(this->si ? units.second : units.first, this); + QLabel *unit_label = new QLabel(this->si ? this->units.second : this->units.first, this); unit_label->setFont(unit_font); unit_label->setAlignment(Qt::AlignCenter); - this->timer = new QTimer(this); - connect(this->timer, &QTimer::timeout, [this, bus, cmds]() { - for (auto cmd : cmds) { - bus->writeFrame(cmd.frame); - } - }); - - connect(config, &Config::si_units_changed, [this, units, unit_label](bool si) { + connect(config, &Config::si_units_changed, [this, unit_label](bool si) + { this->si = si; - unit_label->setText(this->si ? units.second : units.first); - value_label->setText(this->null_value()); - }); + unit_label->setText(this->si ? this->units.second : this->units.first); + value_label->setText(this->null_value()); }); layout->addStretch(6); layout->addWidget(value_label); @@ -78,13 +299,10 @@ Gauge::Gauge(units_t units, QFont value_font, QFont unit_font, Gauge::Orientatio layout->addStretch(4); } -void Gauge::can_callback(QByteArray payload){ - Response resp = Response(payload); - for(auto cmd : cmds){ - if(cmd.frame.payload().at(2) == resp.PID){ - value_label->setText(this->format_value(this->decoder(cmd.decoder(resp), this->si))); - } - } +void Gauge::set_value(double value) +{ + DASH_LOG(debug) << "[Gauges] set_value: " << std::to_string(value); + value_label->setText(this->format_value(this->converter(value, this->si))); } QString Gauge::format_value(double value) @@ -107,14 +325,17 @@ QString Gauge::null_value() } VehiclePage::VehiclePage(Arbiter &arbiter, QWidget *parent) - : QTabWidget(parent) - , Page(arbiter, "Vehicle", "directions_car", true, this) + : QTabWidget(parent), Page(arbiter, "AUTO", "directions_car", true, this) { } void VehiclePage::init() { - this->addTab(new DataTab(this->arbiter, this), "Data"); + this->addTab(new DataTab(this->arbiter, this), "CAN1"); + this->addTab(new LSTab(this->arbiter, this), "CAN2"); + this->addTab(new Obd1Tab(this->arbiter, this), "OBD1"); + this->addTab(new Obd2Tab(this->arbiter, this), "OBD2"); + this->addTab(new ACTab(this->arbiter, this), "AC"); this->config = Config::get_instance(); for (auto device : QCanBus::instance()->availableDevices("socketcan")) @@ -123,27 +344,20 @@ void VehiclePage::init() for (auto port : QSerialPortInfo::availablePorts()) this->serial_devices.append(port.systemLocation()); - connect(&this->arbiter.system().bluetooth, &Bluetooth::init, [this]{ - for (auto device: this->arbiter.system().bluetooth.get_devices()) - { - if(device->isPaired()){ - this->paired_bt_devices.insert(device->name(), device->address()); - } - } - }); - this->get_plugins(); this->active_plugin = new QPluginLoader(this); Dialog *dialog = new Dialog(this->arbiter, true, this->window()); dialog->set_body(this->dialog_body()); QPushButton *load_button = new QPushButton("load"); - connect(load_button, &QPushButton::clicked, [this]() { this->load_plugin(); }); + connect(load_button, &QPushButton::clicked, [this]() + { this->load_plugin(); }); dialog->set_button(load_button); QPushButton *settings_button = new QPushButton(this); settings_button->setFlat(true); this->arbiter.forge().iconize("settings", settings_button, 24); - connect(settings_button, &QPushButton::clicked, [dialog]() { dialog->open(); }); + connect(settings_button, &QPushButton::clicked, [dialog]() + { dialog->open(); }); this->setCornerWidget(settings_button); this->load_plugin(); @@ -161,62 +375,13 @@ QWidget *VehiclePage::dialog_body() layout->addWidget(Session::Forge::br(), 1); layout->addWidget(this->can_bus_toggle_row(), 1); - QStringList devices; - switch(config->get_vehicle_can_bus()){ - //ELM327 USB - case ICANBus::VehicleBusType::ELM327USB: - devices = this->serial_devices; - break; - //ELM327 Bluetooth - case ICANBus::VehicleBusType::ELM327BT: - - break; - //SocketCAN - case ICANBus::VehicleBusType::SocketCAN: - default: - devices = this->can_devices; - break; - } - + QStringList devices = this->config->get_vehicle_can_bus() ? this->can_devices : this->serial_devices; Selector *interface_selector = new Selector(devices, this->config->get_vehicle_interface(), this->arbiter.forge().font(14), this->arbiter, widget, "disabled"); - interface_selector->setVisible((this->can_devices.size() > 0) || (this->serial_devices.size() > 0) || (this->paired_bt_devices.size() > 0)); - connect(interface_selector, &Selector::item_changed, [this](QString item){ - if(this->config->get_vehicle_can_bus()==ICANBus::VehicleBusType::ELM327BT && item != QString("disabled")) - { - this->config->set_vehicle_interface(this->paired_bt_devices[item]); - } - else - { - this->config->set_vehicle_interface(item); - } - }); - connect(this->config, &Config::vehicle_can_bus_changed, [this, interface_selector](int state){ - switch(state){ - //ELM327 USB - case ICANBus::VehicleBusType::ELM327USB: - interface_selector->set_options(this->serial_devices); - break; - //ELM327 Bluetooth - case ICANBus::VehicleBusType::ELM327BT: - interface_selector->set_options(this->paired_bt_devices.keys()); - break; - //SocketCAN - case ICANBus::VehicleBusType::SocketCAN: - default: - interface_selector->set_options(this->can_devices); - break; - } - }); - connect(&this->arbiter.system().bluetooth, &Bluetooth::init, [this, interface_selector]{ - interface_selector->setVisible((this->can_devices.size() > 0) || (this->serial_devices.size() > 0) || (this->paired_bt_devices.size() > 0)); - if(this->config->get_vehicle_can_bus()==ICANBus::VehicleBusType::ELM327BT){ - QString current = this->config->get_vehicle_interface(); - interface_selector->set_options(this->paired_bt_devices.keys()); - if(current != "disabled") - interface_selector->set_current(this->paired_bt_devices.key(current)); - - } - }); + interface_selector->setVisible((this->can_devices.size() > 0) || (this->serial_devices.size() > 0)); + connect(interface_selector, &Selector::item_changed, [config = this->config](QString item) + { config->set_vehicle_interface(item); }); + connect(this->config, &Config::vehicle_can_bus_changed, [this, interface_selector](bool state) + { interface_selector->set_options(state ? this->can_devices : this->serial_devices); }); layout->addWidget(interface_selector, 1); layout->addWidget(Session::Forge::br(), 1); @@ -236,34 +401,13 @@ QWidget *VehiclePage::can_bus_toggle_row() QGroupBox *group = new QGroupBox(); QVBoxLayout *group_layout = new QVBoxLayout(group); - ICANBus::VehicleBusType can_bus_selected = this->config->get_vehicle_can_bus(); QRadioButton *socketcan_button = new QRadioButton("SocketCAN", group); - socketcan_button->setChecked(can_bus_selected==ICANBus::VehicleBusType::SocketCAN); + socketcan_button->setChecked(this->config->get_vehicle_can_bus()); socketcan_button->setEnabled(this->can_devices.size() > 0); - connect(socketcan_button, &QRadioButton::clicked, [config = this->config]{ - config->set_vehicle_can_bus(ICANBus::VehicleBusType::SocketCAN); - }); + connect(socketcan_button, &QRadioButton::clicked, [config = this->config] + { config->set_vehicle_can_bus(true); }); group_layout->addWidget(socketcan_button); - QRadioButton *elm_usb_button = new QRadioButton("ELM327 (USB)", group); - elm_usb_button->setChecked(can_bus_selected==ICANBus::VehicleBusType::ELM327USB); - elm_usb_button->setEnabled(this->serial_devices.size() > 0); - connect(elm_usb_button, &QRadioButton::clicked, [config = this->config]{ - config->set_vehicle_can_bus(ICANBus::VehicleBusType::ELM327USB); - }); - group_layout->addWidget(elm_usb_button); - - QRadioButton *elm_bt_button = new QRadioButton("ELM327 (Bluetooth)", group); - elm_bt_button->setChecked(can_bus_selected==ICANBus::VehicleBusType::ELM327BT); - elm_bt_button->setEnabled(false); - connect(elm_bt_button, &QRadioButton::clicked, [config = this->config]{ - config->set_vehicle_can_bus(ICANBus::VehicleBusType::ELM327BT); - }); - connect(&this->arbiter.system().bluetooth, &Bluetooth::init, [this, elm_bt_button]{ - elm_bt_button->setEnabled(this->paired_bt_devices.size() > 0); - }); - group_layout->addWidget(elm_bt_button); - layout->addWidget(group, 1, Qt::AlignHCenter); return widget; @@ -280,7 +424,8 @@ QWidget *VehiclePage::si_units_row_widget() Switch *toggle = new Switch(widget); toggle->scale(this->arbiter.layout().scale); toggle->setChecked(this->config->get_si_units()); - connect(toggle, &Switch::stateChanged, [config = this->config](bool state) { config->set_si_units(state); }); + connect(toggle, &Switch::stateChanged, [config = this->config](bool state) + { config->set_si_units(state); }); layout->addWidget(toggle, 1, Qt::AlignHCenter); return widget; @@ -288,7 +433,8 @@ QWidget *VehiclePage::si_units_row_widget() void VehiclePage::get_plugins() { - for (const QFileInfo &plugin : Session::plugin_dir("vehicle").entryInfoList(QDir::Files)) { + for (const QFileInfo &plugin : Session::plugin_dir("vehicle").entryInfoList(QDir::Files)) + { if (QLibrary::isLibrary(plugin.absoluteFilePath())) this->plugins[Session::fmt_plugin(plugin.baseName())] = plugin; } @@ -300,26 +446,14 @@ void VehiclePage::load_plugin() this->active_plugin->unload(); QString key = this->plugin_selector->get_current(); - if (!key.isNull()) { + if (!key.isNull()) + { this->active_plugin->setFileName(this->plugins[key].absoluteFilePath()); - if (VehiclePlugin *plugin = qobject_cast(this->active_plugin->instance())) { + if (VehiclePlugin *plugin = qobject_cast(this->active_plugin->instance())) + { plugin->dashize(&this->arbiter); - switch(config->get_vehicle_can_bus()){ - //ELM327 USB - case ICANBus::VehicleBusType::ELM327USB: - plugin->init((ICANBus *)elm327::get_usb_instance()); - break; - //ELM327 Bluetooth - case ICANBus::VehicleBusType::ELM327BT: - plugin->init((ICANBus *)elm327::get_bt_instance()); - break; - //SocketCAN - case ICANBus::VehicleBusType::SocketCAN: - default: - plugin->init((ICANBus *)SocketCANBus::get_instance()); - break; - } + plugin->init(((SocketCANBus *)SocketCANBus::get_instance())); for (QWidget *tab : plugin->widgets()) this->addTab(tab, tab->objectName()); } @@ -328,8 +462,7 @@ void VehiclePage::load_plugin() } DataTab::DataTab(Arbiter &arbiter, QWidget *parent) - : QWidget(parent) - , arbiter(arbiter) + : QWidget(parent), arbiter(arbiter) { QHBoxLayout *layout = new QHBoxLayout(this); @@ -346,8 +479,16 @@ DataTab::DataTab(Arbiter &arbiter, QWidget *parent) QSizePolicy sp_right(QSizePolicy::Preferred, QSizePolicy::Preferred); sp_right.setHorizontalStretch(2); engine_data->setSizePolicy(sp_right); - for (auto &gauge : this->gauges) - gauge->start(); + + connect(&this->arbiter, &Arbiter::vehicle_update_data, [this](QString gauge_id, double value) + { + // DASH_LOG(info)<<"[Gauges] arbiter update: "<gauges) { + if(gauge->get_id() == gauge_id){ + // DASH_LOG(info)<<"[Gauges] Found: "<get_id(); + gauge->set_value(value); + } + } }); } QWidget *DataTab::speedo_tach_widget() @@ -357,142 +498,319 @@ QWidget *DataTab::speedo_tach_widget() layout->setContentsMargins(0, 0, 0, 0); layout->addStretch(3); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.SPEED)); + layout->addStretch(2); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.RPM)); + layout->addStretch(1); - QFont speed_value_font(this->arbiter.forge().font(36, true)); + return widget; +} - QFont speed_unit_font(this->arbiter.forge().font(16)); - speed_unit_font.setWeight(QFont::Light); - speed_unit_font.setItalic(true); +QWidget *DataTab::engine_data_widget() +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); - Gauge *speed = new Gauge({"mph", "km/h"}, speed_value_font, speed_unit_font, - Gauge::BOTTOM, 100, {cmds.SPEED}, 0, - [](double x, bool si) { return si ? x : kph_to_mph(x); }, widget); - layout->addWidget(speed); - this->gauges.push_back(speed); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.COOLANT_TEMP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.AUTONOMIA)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.EXT_TEMP)); + layout->addStretch(); - layout->addStretch(2); + return widget; +} - QFont tach_value_font(this->arbiter.forge().font(24, true)); +QWidget *Obd1Tab::obd_data_widget(int colonna) +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); - QFont tach_unit_font(this->arbiter.forge().font(12)); - tach_unit_font.setWeight(QFont::Light); - tach_unit_font.setItalic(true); + switch (colonna) + { + case 1: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.INTAKE_TEMP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.VOLT)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.MAF)); + layout->addStretch(); + break; + case 2: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.MAP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.APP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.TPAPWM)); + layout->addStretch(); + break; + case 3: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.INJ)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.TVENT)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.TANK)); + layout->addStretch(); + break; + } - Gauge *rpm = new Gauge({"x1000rpm", "x1000rpm"}, tach_value_font, - tach_unit_font, Gauge::BOTTOM, 100, {cmds.RPM}, 1, - [](double x, bool _) { return x / 1000.0; }, widget); - layout->addWidget(rpm); - this->gauges.push_back(rpm); + return widget; +} - layout->addStretch(1); +QWidget *Obd2Tab::obd_data_widget(int colonna) +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + switch (colonna) + { + case 1: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.IGNANGLE)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.BATT)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.RITCYL1)); + layout->addStretch(); + break; + case 2: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.RITCYL2)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.RITCYL3)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.RITCYL4)); + layout->addStretch(); + break; + case 3: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.SFT)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LMB1)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LMB2)); + layout->addStretch(); + break; + } return widget; } -/* socketcan/elm327 rewrite right now only has support for one PID per gauge, so we can't calculate milage at this point. - This is because gauges act more as event handlers now for each PID. - Multi-PID gauges could feasibly be reimplemented if there was a helper method that stored received values, and only calls - the gauge update once all values have been updated since last gauge update. - -*/ - -// QWidget *DataTab::mileage_data_widget() -// { -// QWidget *widget = new QWidget(this); -// QHBoxLayout *layout = new QHBoxLayout(widget); -// -// QFont value_font(Theme::font_36); -// value_font.setFamily("Titillium Web"); -// -// QFont unit_font(Theme::font_14); -// unit_font.setWeight(QFont::Light); -// unit_font.setItalic(true); -// -// Gauge *mileage = new Gauge({"mpg", "km/L"}, value_font, unit_font, -// Gauge::BOTTOM, 100, {cmds.SPEED, cmds.MAF}, 1, -// [](std::vector x, bool si) { -// return (si ? x[0] : kph_to_mph(x[0])) / (si ? gps_to_lph(x[1]) : gps_to_gph(x[1])); -// }, -// widget); -// layout->addWidget(mileage); -// this->gauges.push_back(mileage); - -// return widget; -// } +QWidget *LSTab::ls_data_widget(int colonna) +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); -QWidget *DataTab::engine_data_widget() + switch (colonna) + { + case 1: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.COOLANT_TEMP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSOIL)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSLVLCOOLANT)); + layout->addStretch(); + break; + case 2: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.EXT_TEMP)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSBENZ)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSVOLT)); + layout->addStretch(); + break; + case 3: + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSINIEZS)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSINIEZH)); + layout->addStretch(); + layout->addWidget(Session::Forge::br()); + layout->addStretch(); + layout->addWidget(this->vehicle_data_widget(gauges_cfg.LSINIEZKM)); + layout->addStretch(); + break; + } + + return widget; +} + +QWidget *DataTab::vehicle_data_widget(GaugeConfig cfg) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(widget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - layout->addStretch(); - layout->addWidget(this->coolant_temp_widget()); - layout->addStretch(); - layout->addWidget(Session::Forge::br()); - layout->addStretch(); - layout->addWidget(this->engine_load_widget()); - layout->addStretch(); + QFont value_font(this->arbiter.forge().font(cfg.font_size.value, true)); + + QFont unit_font(this->arbiter.forge().font(cfg.font_size.unit)); + unit_font.setWeight(QFont::Light); + unit_font.setItalic(true); + + Gauge *gauge = new Gauge(cfg, + value_font, unit_font, Gauge::RIGHT, widget); + layout->addWidget(gauge); + this->gauges.push_back(gauge); + + if (cfg.font_size.label > 0) + { + QFont label_font(this->arbiter.forge().font(cfg.font_size.label)); + label_font.setWeight(QFont::Light); + + QLabel *gauge_label = new QLabel(cfg.description, widget); + gauge_label->setFont(label_font); + gauge_label->setAlignment(Qt::AlignHCenter); + layout->addWidget(gauge_label); + } return widget; } -QWidget *DataTab::coolant_temp_widget() +QWidget *Obd1Tab::vehicle_data_widget(GaugeConfig cfg) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(widget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - QFont value_font(this->arbiter.forge().font(16, true)); + QFont value_font(this->arbiter.forge().font(cfg.font_size.value, true)); - QFont unit_font(this->arbiter.forge().font(12)); + QFont unit_font(this->arbiter.forge().font(cfg.font_size.unit)); unit_font.setWeight(QFont::Light); unit_font.setItalic(true); - Gauge *coolant_temp = new Gauge( - {"°F", "°C"}, value_font, unit_font, Gauge::RIGHT, 5000, - {cmds.COOLANT_TEMP}, 1, [](double x, bool si) { return si ? x : c_to_f(x); }, widget); - layout->addWidget(coolant_temp); - this->gauges.push_back(coolant_temp); + Gauge *gauge = new Gauge(cfg, + value_font, unit_font, Gauge::RIGHT, widget); + layout->addWidget(gauge); + this->gauges.push_back(gauge); - QFont label_font(this->arbiter.forge().font(10)); - label_font.setWeight(QFont::Light); + if (cfg.font_size.label > 0) + { + QFont label_font(this->arbiter.forge().font(cfg.font_size.label)); + label_font.setWeight(QFont::Light); - QLabel *coolant_temp_label = new QLabel("coolant", widget); - coolant_temp_label->setFont(label_font); - coolant_temp_label->setAlignment(Qt::AlignHCenter); - layout->addWidget(coolant_temp_label); + QLabel *gauge_label = new QLabel(cfg.description, widget); + gauge_label->setFont(label_font); + gauge_label->setAlignment(Qt::AlignHCenter); + layout->addWidget(gauge_label); + } return widget; } -QWidget *DataTab::engine_load_widget() +QWidget *Obd2Tab::vehicle_data_widget(GaugeConfig cfg) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(widget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - QFont value_font(this->arbiter.forge().font(16, true)); + QFont value_font(this->arbiter.forge().font(cfg.font_size.value, true)); - QFont unit_font(this->arbiter.forge().font(12)); + QFont unit_font(this->arbiter.forge().font(cfg.font_size.unit)); unit_font.setWeight(QFont::Light); unit_font.setItalic(true); - Gauge *engine_load = - new Gauge({"%", "%"}, value_font, unit_font, Gauge::RIGHT, - 500, {cmds.LOAD}, 1, [](double x, bool _) { return x; }, widget); - layout->addWidget(engine_load); - this->gauges.push_back(engine_load); + Gauge *gauge = new Gauge(cfg, + value_font, unit_font, Gauge::RIGHT, widget); + layout->addWidget(gauge); + this->gauges.push_back(gauge); + + if (cfg.font_size.label > 0) + { + QFont label_font(this->arbiter.forge().font(cfg.font_size.label)); + label_font.setWeight(QFont::Light); - QFont label_font(this->arbiter.forge().font(10)); - label_font.setWeight(QFont::Light); + QLabel *gauge_label = new QLabel(cfg.description, widget); + gauge_label->setFont(label_font); + gauge_label->setAlignment(Qt::AlignHCenter); + layout->addWidget(gauge_label); + } - QLabel *engine_load_label = new QLabel("load", widget); - engine_load_label->setFont(label_font); - engine_load_label->setAlignment(Qt::AlignHCenter); - layout->addWidget(engine_load_label); return widget; } + +QWidget *LSTab::vehicle_data_widget(GaugeConfig cfg) +{ + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + QFont value_font(this->arbiter.forge().font(cfg.font_size.value, true)); + + QFont unit_font(this->arbiter.forge().font(cfg.font_size.unit)); + unit_font.setWeight(QFont::Light); + unit_font.setItalic(true); + + Gauge *gauge = new Gauge(cfg, + value_font, unit_font, Gauge::RIGHT, widget); + layout->addWidget(gauge); + this->gauges.push_back(gauge); + + if (cfg.font_size.label > 0) + { + QFont label_font(this->arbiter.forge().font(cfg.font_size.label)); + label_font.setWeight(QFont::Light); + + QLabel *gauge_label = new QLabel(cfg.description, widget); + gauge_label->setFont(label_font); + gauge_label->setAlignment(Qt::AlignHCenter); + layout->addWidget(gauge_label); + } + + return widget; +} \ No newline at end of file diff --git a/src/app/session.cpp b/src/app/session.cpp index b7b23139..c05fcc96 100644 --- a/src/app/session.cpp +++ b/src/app/session.cpp @@ -313,7 +313,7 @@ QWidget *Session::Forge::brightness_slider(bool buttons) const auto slider = new QSlider(Qt::Orientation::Horizontal); slider->setTracking(false); - slider->setRange(76, 255); + slider->setRange(0, 255); slider->setValue(this->arbiter_.system().brightness.value); QObject::connect(slider, &QSlider::sliderReleased, [this, slider]{ this->arbiter_.set_brightness(slider->sliderPosition()); diff --git a/src/app/widgets/climate.cpp b/src/app/widgets/climate.cpp index 890c8b49..bcf46dd6 100644 --- a/src/app/widgets/climate.cpp +++ b/src/app/widgets/climate.cpp @@ -51,15 +51,15 @@ QLayout *ClimateSnackBar::state() return layout; } -void ClimateSnackBar::set_left_temp(int temp) +void ClimateSnackBar::set_left_temp(QString temp) { - this->left_temp->setText(QString("%1°").arg(temp)); + this->left_temp->setText(temp); this->open(3000); } -void ClimateSnackBar::set_right_temp(int temp) +void ClimateSnackBar::set_right_temp(QString temp) { - this->right_temp->setText(QString("%1°").arg(temp)); + this->right_temp->setText(temp); this->open(3000); } @@ -107,13 +107,13 @@ void Climate::airflow(uint8_t airflow) this->snack_bar->set_airflow(this->airflow_); } -void Climate::left_temp(int left_temp) +void Climate::left_temp(QString left_temp) { this->left_temp_ = left_temp; this->snack_bar->set_left_temp(this->left_temp_); } -void Climate::right_temp(int right_temp) +void Climate::right_temp(QString right_temp) { this->right_temp_ = right_temp; this->snack_bar->set_right_temp(this->right_temp_); diff --git a/src/app/widgets/step_meter.cpp b/src/app/widgets/step_meter.cpp index 31ae4e7b..8a1fdfd0 100644 --- a/src/app/widgets/step_meter.cpp +++ b/src/app/widgets/step_meter.cpp @@ -38,7 +38,7 @@ void StepMeter::paintEvent(QPaintEvent *event) QPainterPath path; path.addPolygon(bar); - painter.fillPath(path, (this->bars >= i) ? QBrush(this->bar_color) : QBrush(this->base_color)); + painter.fillPath(path, (this->bars > i) ? QBrush(this->bar_color) : QBrush(this->base_color)); } } diff --git a/src/canbus/elm327.cpp b/src/canbus/elm327.cpp deleted file mode 100755 index 7f9eed36..00000000 --- a/src/canbus/elm327.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "canbus/elm327.hpp" - -elm327::elm327(QString canInterface, bool bluetooth) -{ - DASH_LOG(info)<<"[ElM327] Attempting to connect to elm device: "<adapterType = BT; - btSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); - QObject::connect(btSocket, &QBluetoothSocket::connected, this, &elm327::btConnected); - QObject::connect(btSocket, &QBluetoothSocket::stateChanged, this, &elm327::socketChanged); - btSocket->connectToService(QBluetoothAddress(canInterface), QBluetoothUuid(QString("00001101-0000-1000-8000-00805F9B34FB")), QIODevice::ReadWrite); - bluetooth_watchdog = new QTimer(this); - } - else{ - this->connect(canInterface, B115200); - if (this->connected) this->initialize(); - } - -} -elm327::~elm327() -{ - this->raw_query("ATZ"); - sleep(1); - close(this->fd); - this->connected = false; -} - -elm327 *elm327::get_usb_instance() -{ - static elm327 elm_usb(Config::get_instance()->get_vehicle_interface()); - return &elm_usb; -} - -elm327 *elm327::get_bt_instance() -{ - static elm327 elm_bt(Config::get_instance()->get_vehicle_interface(), true); - return &elm_bt; -} - -void elm327::btConnected() -{ - this->connected=true; - this->initialize(); -} - -void elm327::socketChanged(QBluetoothSocket::SocketState state) -{ - switch(state){ - case(QBluetoothSocket::UnconnectedState): - DASH_LOG(info)<<"[ElM327][Bluetooth] Unconnected"; - break; - case(QBluetoothSocket::ConnectingState): - DASH_LOG(info)<<"[ElM327][Bluetooth] Connecting"; - break; - case(QBluetoothSocket::ConnectedState): - DASH_LOG(info)<<"[ElM327][Bluetooth] Connected"; - break; - case(QBluetoothSocket::ServiceLookupState): - DASH_LOG(info)<<"[ElM327][Bluetooth] Looking up Services"; - break; - default: - DASH_LOG(info)<<"[ElM327][Bluetooth] Unimplemented"; - } -} - -int elm327::_write(std::string str) -{ - str += '\r'; - int size; - if ((size = (adapterType==BT)?(::send(btSocket->socketDescriptor(), str.c_str(), str.length(), 0)):(write(this->fd, str.c_str(), str.length()))) < 0) - { - DASH_LOG(error) << "[ELM327] failed write" << std::endl; - this->connected = false; - return 0; - } - - return size; -} - - -void elm327::connect(QString dev_path, speed_t baudrate) -{ - if (this->connected) return; - - this->fd = open(dev_path.toStdString().c_str(), O_RDWR | O_NOCTTY | O_NDELAY); - if (this->fd == -1) { - this->connected = false; - return; - } - - fcntl(this->fd, F_SETFL, 0); - - struct termios options; - tcgetattr(this->fd, &options); - - options.c_cflag |= (CLOCAL | CREAD); - options.c_lflag &= !(ICANON | ECHO | ECHOE | ISIG); - options.c_oflag &= !(OPOST); - options.c_cc[VMIN] = 0; - options.c_cc[VTIME] = 100; - - tcflush(this->fd, TCIOFLUSH); - tcsetattr(this->fd, TCSANOW, &options); - - cfsetispeed(&options, baudrate); - cfsetospeed(&options, baudrate); - tcsetattr(this->fd, TCSANOW, &options); - tcflush(this->fd, TCIOFLUSH); - - this->connected = true; -} -void elm327::initialize() -{ - DASH_LOG(info)<<"[ELM327] Initializing elm"; - - std::vector cmds = {"ATD", "ATZ", "ATE0", "ATL0", "ATS0", "AT H0", "ATSP0", "0100"}; - for (auto const cmd : cmds) { - this->raw_query(cmd); - usleep(500000); - } -} - - -bool elm327::writeFrame(QCanBusFrame frame) -{ - if(!this->connected) return false; - std::lock_guard guard(this->elm_mutex); - std::stringstream ss; - - //this is an obd message, so we can send it with the elm327 - if(frame.frameId() == 0x7df){ - ss << std::hex << std::uppercase << std::setfill('0'); - for(int i = 1; i<=frame.payload().at(0); i++){ - ss << std::setw(2) << static_cast(frame.payload().at(i)); - } - if(this->_write(ss.str())>=0){ - QCanBusFrame retFrame = this->receive(); - if(retFrame.frameType()!=QCanBusFrame::ErrorFrame){ - handleFrame(retFrame); - } - } - else{ - DASH_LOG(error) << "[ELM327] Unable to send command"; - } - - - } - else{ - //not implementing elm327 support to send frames - return false; - } - - return true; -} - -bool elm327::is_failed_response(std::string str) -{ - std::vector failed_msgs = { - "UNABLE TO CONNECT", "BUS INIT...ERROR", "NO DATA", "STOPPED", "ERROR", "?"}; - - for (auto const &msg : failed_msgs) - if (str.find(msg) != std::string::npos) return true; - - return false; -} - -QCanBusFrame elm327::receive() -{ - QCanBusFrame *retFrame = new QCanBusFrame(); - std::string resp_str = this->_read(); - - if (is_failed_response(resp_str)){ - retFrame->setFrameType(QCanBusFrame::ErrorFrame); - return *retFrame; - } - - std::string searching_phrase = "SEARCHING..."; - std::string::size_type i = resp_str.find(searching_phrase); - if (i != std::string::npos) resp_str.erase(i, searching_phrase.length()); - resp_str.erase( - std::remove_if(resp_str.begin(), resp_str.end(), [](auto const &c) -> bool { return !std::isalnum(c); }), - resp_str.end()); - - retFrame->setFrameId(0x7E8); - QByteArray payload = QByteArray::fromHex("0000000000000000"); - for( uint i=0; i < resp_str.length()/2; i++){ - payload[i+1] = std::stoi(resp_str.substr(2*i, 2), nullptr, 16); - } - payload[0] = resp_str.length()/2; - retFrame->setPayload(payload); - return *retFrame; -} -void elm327::handleFrame(QCanBusFrame frame) -{ - - if (callbacks.find(frame.frameId()) != callbacks.end()) - { - for(auto callback : callbacks[frame.frameId()]){ - callback(frame.payload()); - } - } - -} - - -void elm327::registerFrameHandler(int id, std::function callback) -{ - callbacks[id].push_back(callback); -} - -std::string elm327::_read() -{ - char buf[1]; - std::string str; - - if(adapterType==BT) - bluetooth_watchdog->start(5000); - - while (true) { - - if (((adapterType==BT)?(::recv(btSocket->socketDescriptor(), (void *) buf, 1, 0)):(read(this->fd, (void *)buf, 1))) != 1) - { - if(adapterType != BT) - { - DASH_LOG(error) << "[ELM327] failed read"; - this->connected = false; - return ""; - } - else - { - if(bluetooth_watchdog->remainingTime() == 0) - { - DASH_LOG(error) << "[ELM327] Bluetooth watchdog expired, disconnecting"; - this->connected = false; - return ""; - } - continue; - } - } - if (buf[0] == '>') - break; - else - str += buf[0]; - // feed watchdog - if(adapterType==BT) - bluetooth_watchdog->start(5000); - } - - return str; -} diff --git a/src/canbus/socketcanbus.cpp b/src/canbus/socketcanbus.cpp index 7d59a760..64112322 100644 --- a/src/canbus/socketcanbus.cpp +++ b/src/canbus/socketcanbus.cpp @@ -1,79 +1,167 @@ +#include +#include +#include +#include #include "canbus/socketcanbus.hpp" +#include -SocketCANBus::SocketCANBus(QString canInterface) +SocketCANBus::SocketCANBus(QObject *parent, QString canInterface) : QObject(parent), socket(this) { - if (QCanBus::instance()->plugins().contains(QStringLiteral("socketcan"))) { + if (QCanBus::instance()->plugins().contains(QStringLiteral("socketcan"))) + { DASH_LOG(info) << "[SocketCANBus] 'socketcan' Available"; socketCANAvailable = true; - QString errorString; - bus = QCanBus::instance()->createDevice( - QStringLiteral("socketcan"), canInterface, &errorString); - if (!bus) { - DASH_LOG(error) <<"[SocketCANBus] Error creating CAN device, " << errorString.toStdString(); - } else { - DASH_LOG(info) <<"[SocketCANBus] Connecting CAN interface "<connectDevice(); - connect(bus, &QCanBusDevice::framesReceived, - this, &SocketCANBus::framesAvailable); + + this->socket.connectToHost("127.0.0.1", 7070); + this->socket.waitForConnected(); + + if (this->socket.state() == QAbstractSocket::ConnectedState) + { + usleep(200000); + + QString allineamento = "CAN USER ALIGN RIGHT\r\n"; + this->socket.write(allineamento.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString aperturaMS = "CAN USER OPEN CH1 95K2\r\n"; + this->socket.write(aperturaMS.toUtf8()); + + this->socket.flush(); + usleep(200000); + + //QString aperturaHS = "CAN USER OPEN CH2 500K\r\n"; + //this->socket.write(aperturaHS.toUtf8()); + + QString mascheraMS = "CAN USER MASK CH1 0FFF\r\n"; + this->socket.write(mascheraMS.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_0 = "CAN USER FILTER CH1 0 0206\r\n"; + this->socket.write(filtroCH1_0.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_1 = "CAN USER FILTER CH1 1 0450\r\n"; + this->socket.write(filtroCH1_1.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_2 = "CAN USER FILTER CH1 2 04EE\r\n"; + this->socket.write(filtroCH1_2.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_3 = "CAN USER FILTER CH1 3 04E8\r\n"; + this->socket.write(filtroCH1_3.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_4 = "CAN USER FILTER CH1 4 0682\r\n"; + this->socket.write(filtroCH1_4.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_5 = "CAN USER FILTER CH1 5 06C8\r\n"; + this->socket.write(filtroCH1_5.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_6 = "CAN USER FILTER CH1 6 04EC\r\n"; + this->socket.write(filtroCH1_6.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_7 = "CAN USER FILTER CH1 7 0208\r\n"; + this->socket.write(filtroCH1_7.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH1_8 = "CAN USER FILTER CH1 8 02B0\r\n"; + this->socket.write(filtroCH1_8.toUtf8()); + + this->socket.flush(); + usleep(200000); + + //QString filtroTempAntigeloRX2 = "CAN USER FILTER CH2 0 0510\r\n"; + //this->socket.write(filtroTempAntigeloRX2.toUtf8()); + + QString aperturaLS = "CAN USER OPEN CH2 33K3 GMLAN\r\n"; + this->socket.write(aperturaLS.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString mascheraHS = "CAN USER MASK CH2 0FFF\r\n"; + this->socket.write(mascheraHS.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_0 = "CAN USER FILTER CH2 0 0110\r\n"; + this->socket.write(filtroCH2_0.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_1 = "CAN USER FILTER CH2 1 0145\r\n"; + this->socket.write(filtroCH2_1.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_2 = "CAN USER FILTER CH2 2 0350\r\n"; + this->socket.write(filtroCH2_2.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_3 = "CAN USER FILTER CH2 3 0375\r\n"; + this->socket.write(filtroCH2_3.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_4 = "CAN USER FILTER CH2 4 0500\r\n"; + this->socket.write(filtroCH2_4.toUtf8()); + + this->socket.flush(); + usleep(200000); + + QString filtroCH2_5 = "CAN USER FILTER CH2 5 0130\r\n"; + this->socket.write(filtroCH2_5.toUtf8()); + + this->socket.flush(); + + DASH_LOG(info) << "[SocketCANBus] Connesso a Carberry"; + } + else + { + DASH_LOG(error) << "[SocketCANBus] Errore di connessione a Carberry"; } } } SocketCANBus::~SocketCANBus() { - DASH_LOG(info) << "[SocketCANBus] Disconnecting and deleting bus"; - if(bus->state() == QCanBusDevice::ConnectedState){ - bus->disconnectDevice(); - } -} + DASH_LOG(info) << "[SocketCANBus] Disconnessione da Carberry"; -bool SocketCANBus::writeFrame(QCanBusFrame frame) -{ - return bus->writeFrame(frame); + this->socket.close(); } SocketCANBus *SocketCANBus::get_instance() { - static SocketCANBus bus(Config::get_instance()->get_vehicle_interface()); + static SocketCANBus bus(NULL, Config::get_instance()->get_vehicle_interface()); return &bus; -} - -// QSerialBus readAllFrames introduced in 5.12 - Pi OS is stuck on 5.11, so implement our own -QVector SocketCANBus::readAllFrames(int numFrames){ - QVector frames = QVector(); - for(int i = 0; ireadFrame()); - } - return frames; -} - -void SocketCANBus::framesAvailable() -{ - int numFrames = bus->framesAvailable(); - if(numFrames>0){ - QVector frames = readAllFrames(numFrames); - for(int i = 0; i callback) -{ - callbacks[id].push_back(callback); - QCanBusDevice::Filter filter; - filter.frameId = id; - filter.frameIdMask = 0xFFF; - filter.format=QCanBusDevice::Filter::MatchBaseAndExtendedFormat; - filter.type = QCanBusFrame::InvalidFrame; - filterList.append(filter); - bus->setConfigurationParameter(QCanBusDevice::RawFilterKey, QVariant::fromValue(filterList)); -} +} \ No newline at end of file