diff --git a/bcmainwindow.h b/bcmainwindow.h index 3aadbfb..4217c94 100644 --- a/bcmainwindow.h +++ b/bcmainwindow.h @@ -147,4 +147,112 @@ private: bool m_isDarkMode; }; + +class BCConnectionWidget : public QWidget +{ + Q_OBJECT + +public: + // Definition der 3 Zustände + enum class State + { + Disconnected, // Grau: Offline / Standby + Connected, // Grün: Alles OK + Error // Rot: Fehler / Timeout / Abbruch + }; + Q_ENUM(State) // Damit Qt das Enum kennt (optional, gut für Debugging) + + explicit BCConnectionWidget(QWidget *parent = nullptr) + : QWidget(parent) + { + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(10, 2, 10, 2); + layout->setSpacing(8); + + // 1. Die LED + m_led = new QLabel(this); + m_led->setFixedSize(12, 12); + + // 2. Der Text + m_label = new QLabel(this); + m_label->setStyleSheet("font-weight: 500;"); // Medium weight + + layout->addWidget(m_led); + layout->addWidget(m_label); + + // Startzustand + setState(State::Disconnected, "Offline"); + } + +public slots: + + // Hauptfunktion zum Setzen des Status + // 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen. + void setState(State state, const QString &customMessage = QString()) + { + m_state = state; + + // Standard-Texte, falls keine Nachricht übergeben wurde + QString text = customMessage; + if (text.isEmpty()) { + switch (state) { + case State::Connected: text = "Online"; break; + case State::Disconnected: text = "Not Connected"; break; + case State::Error: text = "Connection Error"; break; + } + } + m_label->setText(text); + + updateStyle(); + } + +private: + + void updateStyle() + { + QString ledStyle; + QString labelColor; + QString toolTipText; + + switch (m_state) { + case State::Connected: + // FLUENT GREEN (Success) + ledStyle = "background-color: #107C10; border: 1px solid #0E600E;#FF5F1F; #FF8C00;<- das isses #FF6700"; + labelColor = "#FFFFFF"; // Weiß (Hervorgehoben) + toolTipText = "Verbindung erfolgreich hergestellt."; + break; + + case State::Error: + // FLUENT RED (Critical) + ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;"; + labelColor = "#FF99A4"; // Ein helleres Rot für Text, damit es auf Dunkel lesbar ist + toolTipText = "Kritischer Fehler bei der Verbindung!"; + break; + + case State::Disconnected: + default: + // FLUENT GRAY (Neutral) + // Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look + ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;"; + labelColor = "#9E9E9E"; // Ausgegrauter Text + toolTipText = "System ist offline."; + break; + } + + // Styles anwenden (immer rund machen) + m_led->setStyleSheet(ledStyle + "border-radius: 6px;"); + + // Textfarbe setzen + m_label->setStyleSheet(QString("color: %1; font-weight: %2;") + .arg(labelColor) + .arg(m_state == State::Connected ? "bold" : "normal")); + + setToolTip(toolTipText); + } + + QLabel *m_led; + QLabel *m_label; + State m_state; +}; + #endif // BCMAINWINDOW_H diff --git a/bcvalue.cpp b/bcvalue.cpp index e45b418..28181c6 100644 --- a/bcvalue.cpp +++ b/bcvalue.cpp @@ -52,10 +52,12 @@ QString BCValue::readRawValueX( const BCAbstractTransmitter& transmitter ) const uint8_t regID = static_cast (registerID); // wir sind hier im anderen thread! nicht einfach so reinschreiben - //visibleValue = valueType->createStringValue( transmitter, devID, regID ); - - return valueType->createStringValue( transmitter, devID, regID ); - + if( valueType->readValueFunc ) + { + uint32_t result = valueType->readValueFunc( transmitter, devID, regID ); + return valueType->formatValue( result ); + } + return QString(); } void BCValue::writeRawValueX( const BCAbstractTransmitter& transmitter ) const diff --git a/bcvalue.h b/bcvalue.h index 1db18f6..495fe6d 100644 --- a/bcvalue.h +++ b/bcvalue.h @@ -83,29 +83,28 @@ public: ReadValue, WriteValue, }; - //Q_ENUM(OpID) - // __fix! flags draus machen ? enum class State : uint8_t { - Invalid, - Locked, - Failed, - InSync, - OK + NoState = 0x0, + ReadOnly = 0x1, + Locked = 0x2, + Failed = 0x4, + InSync = 0x8, + OK = 0x10 }; - //Q_ENUM(State) + Q_DECLARE_FLAGS(States, State ) BCValue( const BCValueType* valueType_, BCDevice::ID deviceID_, BC::ID registerID_ ); QString readRawValueX( const BCAbstractTransmitter& transmitter ) const; - void writeRawValueX( const BCAbstractTransmitter& transmitter ) const; + void writeRawValueX( const BCAbstractTransmitter& transmitter ) const; // void reset() -// später +// später vielleicht //protected: - mutable State state{BCValue::State::Invalid}; + mutable States state{BCValue::State::NoState}; //const BCValueType& valueType; //BCValueTypeCRef valueType; const BCValueType* valueType{}; @@ -123,7 +122,7 @@ public: //mutable std::optional rawValue; }; - +Q_DECLARE_OPERATORS_FOR_FLAGS(BCValue::States) Q_DECLARE_METATYPE(const BCValue*) //Q_DECLARE_METATYPE(const BCValue&) diff --git a/bcvaluetype.cpp b/bcvaluetype.cpp index 173feb8..e9875f0 100644 --- a/bcvaluetype.cpp +++ b/bcvaluetype.cpp @@ -34,6 +34,46 @@ #include +/// reader functions + + + +uint32_t readByteValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) +{ + return transmitter.readByte( deviceID, registerID ); +} + + +uint32_t readWordValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) +{ + //getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)), + // hi byte + uint32_t result = transmitter.readByte( deviceID, registerID ) << 8; + // low byte, use followup register: +1 + result += transmitter.readByte( deviceID, registerID+1 ); + return result; + +} + +uint32_t readODOValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) +{ + return 0x0; +} + +uint32_t readVoltValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) +{ + return 0x0; +} + +uint32_t readCircValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) +{ + return 0x0; +} + +/** + * @brief BCValueType::BCValueType + */ + BCValueType::BCValueType() { @@ -69,26 +109,52 @@ QString BCValueType::formatValue( uint32_t value ) const _dataTypes.insert( "Assist", new Fatz{{ "%" }} ); //_dataTypes.insert( "Date", { BCValueType::TypeID::Date } ); */ + +std::optional BCValueType::fetchReadValueFunction( const QString& unitTypeKey ) +{ + static QHash s_bcReadValueFunctions + { + { "Byte", readByteValue }, + { "Word", readWordValue }, + { "Percent",readByteValue }, + { "KWh", readByteValue }, + { "Watt", readByteValue }, + { "Km", readByteValue }, + { "Kmh", readByteValue }, + { "Mm", readByteValue }, + { "Sec", readByteValue }, + { "Degree", readByteValue }, + { "SoC", readByteValue }, + { "Odo", readByteValue }, + { "Assist", readByteValue }, + { "Assist", readByteValue }, + }; + + if( !s_bcReadValueFunctions.contains( unitTypeKey ) ) + return std::nullopt; + + return s_bcReadValueFunctions[unitTypeKey]; +} + std::optional BCValueType::fetchValueType( const QString& unitTypeKey ) { static QHash s_bcDataTypes { - { "Byte", new BCValueTypeWord( "", 1.5625F) }, - { "Word", new BCValueTypeWord( "", 1.5625F) }, - - { "Float", new BCValueTypeWord( "", 1.5625F) }, - { "Percent",new BCValueTypeWord( "%", 1.5625 ) }, - { "KWh", new BCValueTypeWord( "kwh", 1.5625 ) }, - { "Watt", new BCValueTypeWord( "w", 1.5625 ) }, - { "Km", new BCValueTypeWord( "km", 1.5625 ) }, - { "Kmh", new BCValueTypeWord( "km/h", 0.1 ) }, - { "Mm", new BCValueTypeWord( "mm", 1.5625 ) }, - { "Sec", new BCValueTypeWord( "s", 1.5625 ) }, - { "Degree", new BCValueTypeByte( "°C", 1.0 ) }, - { "SoC", new BCValueTypeWord( "%", 1.5625 ) }, - { "Odo", new BCValueTypeWord( "km", 1.5625 ) }, - { "Assist", new BCValueTypeWord( "", 0 ,4 ) }, - { "Assist", new BCValueTypeWord( "%" ) }, + { "Byte", new BCValueType( "", 1.5625F) }, + { "Word", new BCValueType( "", 1.5625F) }, + { "Float", new BCValueType( "", 1.5625F) }, + { "Percent",new BCValueType( "%", 1.5625 ) }, + { "KWh", new BCValueType( "kwh", 1.5625 ) }, + { "Watt", new BCValueType( "w", 1.5625 ) }, + { "Km", new BCValueType( "km", 1.5625 ) }, + { "Kmh", new BCValueType( "km/h", 0.1 ) }, + { "Mm", new BCValueType( "mm", 1.5625 ) }, + { "Sec", new BCValueType( "s", 1.5625 ) }, + { "Degree", new BCValueType( "°C", 1.0 ) }, + { "SoC", new BCValueType( "%", 1.5625 ) }, + { "Odo", new BCValueType( "km", 1.5625 ) }, + { "Assist", new BCValueType( "", 0 ,4 ) }, + { "Assist", new BCValueType( "%" ) }, }; if( !s_bcDataTypes.contains( unitTypeKey ) ) @@ -100,47 +166,3 @@ std::optional BCValueType::fetchValueType( const QString& unitType /// ---- -BCValueTypeByte::BCValueTypeByte( QString unitLabel_, double factor_, optDouble min_, optDouble max_ ) - : BCValueType{ unitLabel_, factor_, min_, max_} -{ - -} - -QString BCValueTypeByte::createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const -{ - uint8_t result = transmitter.readByte( deviceID, registerID ); - return formatValue( result ); -} - -/// ---- - -BCValueTypeWord::BCValueTypeWord( QString unitLabel_, double factor_, optDouble min_, optDouble max_ ) - : BCValueType{ unitLabel_, factor_, min_, max_} -{ - -} - -QString BCValueTypeWord::createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const -{ - //getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)), - // hi byte - uint8_t result = transmitter.readByte( deviceID, registerID ) << 8; - // low byte, use followup register: +1 - result += transmitter.readByte( deviceID, registerID+1 ); - - return formatValue( result ); -} - -/// ---- - -BCValueTypeODO::BCValueTypeODO( QString unitLabel_, double factor_, optDouble min_, optDouble max_ ) - : BCValueType{ unitLabel_, factor_, min_, max_} -{ - -} - -QString BCValueTypeODO::createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const -{ - return "0x0"; -} - diff --git a/bcvaluetype.h b/bcvaluetype.h index b7ba5d3..c4217b1 100644 --- a/bcvaluetype.h +++ b/bcvaluetype.h @@ -44,6 +44,7 @@ class BCAbstractTransmitter; class BCValue; using optDouble = std::optional; +using ReadValueFunc = std::function; struct BCValueType { @@ -59,46 +60,16 @@ public: double factor; optDouble min; optDouble max; - - virtual QString createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const = 0; - //virtual void writeValue( const BCAbstractTransmitter& transmitter, BCValue& value ) = 0; + ReadValueFunc readValueFunc; virtual QString formatValue( uint32_t value ) const; - static std::optional fetchValueType( const QString& unitTypeKey ); + static std::optional fetchValueType( const QString& unitTypeKey ); + static std::optional fetchReadValueFunction( const QString& unitTypeKey ); }; -struct BCValueTypeByte : BCValueType -{ - BCValueTypeByte( QString unitLabel_, double factor_= 1.0, optDouble min_=std::nullopt, optDouble max_= std::nullopt ); - - QString createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const override; -}; - -struct BCValueTypeWord : public BCValueType -{ - BCValueTypeWord( QString unitLabel_, double factor_= 1.0, optDouble min_=std::nullopt, optDouble max_= std::nullopt ); - - QString createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const override; -}; - -struct BCValueTypeODO : public BCValueType -{ - BCValueTypeODO( QString unitLabel_, double factor_= 1.0, optDouble min_=std::nullopt, optDouble max_= std::nullopt ); - - QString createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const override; -}; - -/* -struct BCValueTypeVolt : public BCValueType -{ - BCValueTypeODO( QString unitLabel_, double factor_= 1.0, optDouble min_=std::nullopt, optDouble max_= std::nullopt ); - - QString createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) override; -}; -*/ //using BCTypeVariant = std::variant; diff --git a/resources/bikeinfo.xml b/resources/bikeinfo.xml index 5f5a8d3..43d6e8c 100644 --- a/resources/bikeinfo.xml +++ b/resources/bikeinfo.xml @@ -4,47 +4,47 @@ - - - - + + + + - - - - - + + + + + - - + + - - + + - - + + - - + + - - - - - - - + + + + + + + - - + + @@ -66,106 +66,106 @@ - - - - + + + + - - - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + + - - - - - + + + + + - + - - + + - + - - + + - - - - - - - - + + + + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - + + + + - - + + - - + + - + - - - + + + - - - - - - + + + + + + - - + + -->