Driver fixes.

This commit is contained in:
2026-01-09 10:47:29 +01:00
parent c81c38f780
commit 2547ed6e1c
13 changed files with 101 additions and 146 deletions

View File

@@ -80,7 +80,6 @@ void BCAnimatedDelegate::setEditorData(QWidget *editor, const QModelIndex& index
void BCAnimatedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
{
qDebug() << "... SHUHU!";
// Daten vom Editor zurück ins Model speichern (Beim Schließen)
QSlider *slider = editor->findChild<QSlider*>("slider");
if (slider)
@@ -111,9 +110,7 @@ void BCAnimatedDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptio
0 // Unten: kein Offset
);
editor->setGeometry(sliderRect); // Slider nur über Progress Bar
//editor->setGeometry(option.rect);
// __fix!
//editor->setGeometry(option.rect);
}
QSize BCAnimatedDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex& index) const
@@ -143,13 +140,12 @@ void BCAnimatedDelegate::paint(QPainter *painter, const QStyleOptionViewItem& op
if( row>-1 && row <= _valueList.size() )
{
const BCValue& bcValue = *(_valueList[ index.row()].get());
//qDebug() << " --- paintSLider: " << bcValue.label << " type: " << (int)bcValue.valueType << " flags:" << bcValue.valueFlags.toInt() << " RO: " << bcValue.isReadOnly();
if( !bcValue.isReadOnly())
paintSliderIndicator(painter,option,bcValue);
paintSliderIndicator(painter,option,bcValue);
}
if(_rowOpacities.contains(row))
paintHighlightRow(painter,option,index.row());
paintHighlightRow(painter,option,index.row());
}
}

View File

@@ -47,15 +47,6 @@ BCDeviceView::BCDeviceView(QWidget *parent)
_itemDelegate = new BCAnimatedDelegate( _valueModel.getValueList(), this);
setItemDelegateForColumn( 1, _itemDelegate );
// Signal für Änderungen
connect(&_valueModel, &BCValueModel::dataChanged, this, [](const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (topLeft.column() ==1) {
int row = topLeft.row();
int value = topLeft.data(Qt::DisplayRole).toInt();
}
});
}
@@ -75,7 +66,7 @@ BCDevice::ID BCDeviceView::getDeviceID() const
* @brief Gibt eine Referenz auf der ValueList zurück.
*/
const BCValueList& BCDeviceView::getValueListX()
const BCValueList& BCDeviceView::getValueList()
{
return _valueModel.getValueList();
}

View File

@@ -51,7 +51,7 @@ public:
void setDeviceID( BCDevice::ID deviceID );
BCDevice::ID getDeviceID() const;
const BCValueList& getValueListX();
const BCValueList& getValueList();
bool firstExpose();
void updateValue(int index, BCValue::Flags newState, uint32_t rawValue );

View File

@@ -74,6 +74,8 @@ TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID
{
Q_UNUSED(deviceID)
Q_UNUSED(registerID)
// Tätigkeit simulieren
bc::delay_millis(200);
uint8_t myRandomByte = static_cast<uint8_t>(QRandomGenerator::global()->bounded(256));
return myRandomByte;
}
@@ -87,6 +89,7 @@ TransmitResult BCDriverDummy::writeRawByte( uint32_t deviceID, uint8_t registerI
{
Q_UNUSED(deviceID)
Q_UNUSED(registerID)
Q_UNUSED(value)
return 0;
}

View File

@@ -151,7 +151,7 @@ BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
return _driverState;
};
qDebug() << " --- DIRVER: " << cMHS_DRIVERNAME;
qDebug() << " --- DRIVER: " << cMHS_DRIVERNAME;
// #1. erstmal komplett zurücksetzen
resetDriver();
@@ -178,25 +178,18 @@ BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
{
// Wir versuchen ein Test-Byte zu lesen, hier: einfach die Hardware
// Revision der Console.
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
uint8_t slaveFlag = static_cast<uint8_t> (BC::ID::Cons_Status_Slave);
unsigned int retry = cTimeOuts;
TransmitResult isSlave = 0;
// Already slave?
isSlave = readRawByte( console, slaveFlag );
if( isSlave.has_value() )
{
//qDebug() << "Console responded: " << isSlave.value();
if( isSlave.value() == 1 )
{
//qDebug() << "Console already in slave mode. good!";
return DriverState::DeviceReady;
}
}
//qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... ";
unsigned int retry = cTimeOuts;
if( isSlave.has_value() && isSlave.value() == 1 )
goto happyEnd;
do
{
@@ -207,11 +200,17 @@ BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
} while( retry-- && !(*isSlave) );
bc::delay_millis( 500 ); // give the Console some time to settle
//if( !isSlave )
//emit statusHint( QString("putting Console in slave mode ") + (isSlave ? "done" : "failed") );
if( isSlave.has_value() && isSlave.value() == 1 )
goto happyEnd;
// ist das jetzt irgendwie schlimm, wenn wir keine slave Console haben
return isSlave ? DriverState::DeviceReady : DriverState::Opened;
return DriverState::Opened;
happyEnd:
_driverState = DriverState::DeviceReady;
return DriverState::DeviceReady;
}
@@ -239,8 +238,6 @@ TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t register
if( _driverState <DriverState::Opened )
return std::unexpected(QString("readRawValue error: Treiber nicht geladen." ) );
unsigned char receipient = (unsigned char ) deviceID;
::TCanMsg msg;
// msg verpacken

View File

@@ -113,6 +113,8 @@ BCDriverStateWidget::BCDriverStateWidget(QWidget* parent)
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
void BCDriverStateWidget::onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage)
{
qDebug() << " --- HELPER: " << state << " : " << customMessage;
Q_UNUSED(customMessage)
_state = state;
updateStyle();
}
@@ -122,14 +124,7 @@ void BCDriverStateWidget::updateStyle()
{
QString ledStyle;
QString toolTipText;
/*
NotPresent,
Error,
Loaded,
Initialized,
Opened, // bis hierher: dll vorhanden, Treiber geladen
DeviceReady
*/
switch (_state)
{
case BCDriver::DriverState::NotPresent:

View File

@@ -124,8 +124,6 @@ void BCMainWindow::initMainWindow()
_connectButton->setDefaultAction( _connectAction);
_syncButton->setDefaultAction( _syncAction);
// besser: model::emit dataChanged
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
connect( _connectAction, &QAction::triggered, &_transmitter, &BCTransmitter::onToggleDriverConnection );
connect( _syncAction, &QAction::triggered, this, &BCMainWindow::onSyncDeviceView );
connect( _exitButton, &QToolButton::clicked, qApp, &QCoreApplication::quit );
@@ -177,29 +175,28 @@ connectIcon.addFile(":/icons/plug_connected.svg", QSize(), QIcon::Normal, QIc
void BCMainWindow::initStatusBar()
{
QStatusBar *statBar = statusBar();
BCDriverStateWidget* conState = new BCDriverStateWidget(this);
connect( &_transmitter, &BCTransmitter::driverStateChanged, conState, &BCDriverStateWidget::onDriverStateChanged );
connect( conState, &BCDriverStateWidget::clicked, _connectAction, &QAction::trigger );
statBar->addPermanentWidget(conState);
_statusBar->addPermanentWidget(conState);
conState->installEventFilter(this);
BCThemeSwitchButton* themeBtn = new BCThemeSwitchButton(this);
statBar->addPermanentWidget(themeBtn);
_statusBar->addPermanentWidget(themeBtn);
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
{
QString message = isDark ? "DarkMode aktiviert" : "LightMode aktiviert";
statusBar()->showMessage( message, 3000);
_statusBar->showMessage( message, 3000);
setApplicationStyleSheet( isDark ? cDarkModeStyle : cLightModeStyle );
});
// Wir starten im light mode
//themeBtn->setDarkMode( false );
statBar->showMessage("Ready");
_statusBar->showMessage("Bereit. (Dummy-Treiber eingestellt)");
setApplicationStyleSheet(cLightModeStyle);
@@ -250,27 +247,21 @@ void BCMainWindow::setHeaderLabel( const QString& headerText)
_headerLabel->setText( " BionxControl: " + headerText );
}
void BCMainWindow::onShowMessage( const QString& message, int timeOut )
{
_statusbar->showMessage( message, timeOut );
_statusBar->showMessage( message, timeOut );
}
void BCMainWindow::autoConnect()
{
// __fix!
// if( !connect)
// fallBack
}
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
{
qDebug() << " --- on DriverStatusChanged: " << state << ":" << message;
_statusbar->showMessage( message, 8000 );
Q_UNUSED(state)
_statusBar->showMessage( message, 8000 );
}
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
{
qDebug() << " --- onShowDevicePanel:" << deviceID;
if( _devicePanels.contains( deviceID ) )
{
BCDeviceView* nxtPanel = _devicePanels[deviceID];
@@ -293,14 +284,12 @@ void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
}
void BCMainWindow::onConnectButtonToggled(bool checked )
{
//_dataManager.setDriverConnectionState( checked );
}
/**
* @brief SLOT, wird aufgerufen, wenn der Treiber eine frischen Wert abgeholt hat.
*/
void BCMainWindow::onValueUpdated(BCDevice::ID deviceID, int index, BCValue::Flags newState, uint32_t rawValue )
{
qDebug() << "Reply: from: " << deviceID << " at: " << index << "finished. Success:" << (uint8_t)newState << " on:" << rawValue;
if( _devicePanels.contains( deviceID ) )
{
BCDeviceView& panel = *_devicePanels[deviceID];
@@ -308,10 +297,15 @@ void BCMainWindow::onValueUpdated(BCDevice::ID deviceID, int index, BCValue::Fla
}
}
/**
* @brief SLOT, wird aufgerufen, wenn der Treiber die Datenübertrgeung beendet hat.
*/
void BCMainWindow::onEndOfProcessing()
{
qDebug() << " --- END sync";
_syncButton->setEnabled( true );
_statusBar->showMessage( "Synchronisation abgeschlossen.", 3000 );
}
/**
@@ -322,30 +316,27 @@ void BCMainWindow::onEndOfProcessing()
void BCMainWindow::onSyncDeviceView()
{
Q_ASSERT_X(_currentPanel, "onSyncDeviceView()", "_currentpanel ist null!");
const BCValueList& currentList =_currentPanel->getValueListX();
const BCValueList& currentList =_currentPanel->getValueList();
// wir schalten den Button hier ab,
// wir schalten den Sync-Button hier ab,
// wenn der Autrag bearbeitet wurde, wird der
// Button wieder eingeschaltet.
_syncButton->setEnabled( false );
QString devName = _currentPanel->property( cBCKeyHeaderLabel ).toString();
_statusBar->showMessage( "Lese: " + devName, 5000 );
for( const BCValuePtr& value : currentList )
{
qDebug() << " --- ### begin sync of value: " << QThread::currentThreadId() << " : " << value->label;
// wir setzen auf 'lesen'
value->valueFlags.setFlag( BCValue::Flag::ReadMe );
_syncButton->setEnabled( false );
// statt '_transmitter.onUpdateValue( value )' müssen wir hier
// über emit requestValueUpdate() zur Thread sysnchronisation
// entkoppeln,
emit requestValueUpdate( value);
}
qDebug() << " --- sending FORWARD EOT";
emit endOfTransmission();
}

View File

@@ -57,7 +57,6 @@ public slots:
//void onValueListReady( BCDevice::ID deviceID );
void onShowDevicePanel( BCDevice::ID deviceID );
void onConnectButtonToggled(bool active );
void onDriverStateChanged( BCDriver::DriverState state, const QString& message="" );
// Slots für Rückmeldungen vom Transmitter
@@ -78,7 +77,6 @@ protected:
bool setApplicationStyleSheet( QAnyStringView path );
void initMainWindow();
void initStatusBar();
void autoConnect();
//bool eventFilter(QObject *obj, QEvent *event) override;

View File

@@ -337,7 +337,7 @@
</item>
</layout>
</widget>
<widget class="QStatusBar" name="_statusbar"/>
<widget class="QStatusBar" name="_statusBar"/>
<action name="_motorAction">
<property name="checkable">
<bool>true</bool>
@@ -384,6 +384,9 @@
</property>
</action>
<action name="_connectAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="bionxcontrol.qrc">
<normaloff>:/connect.png</normaloff>:/connect.png</iconset>
@@ -407,7 +410,7 @@
<string>sync</string>
</property>
<property name="toolTip">
<string>Einstellugen vom eBike synchroniseren</string>
<string>Einstellungen vom eBike synchroniseren</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>

View File

@@ -56,33 +56,23 @@ BCTransmitter::BCTransmitter(QObject *parent)
void BCTransmitter::onToggleDriverConnection( bool connect )
{
//qDebug() << " --- onToggleDriverConnection: " << connect;
emit driverStateChanged(BCDriver::DriverState::Initialized, "BUSY!");
bc::delay_millis(350);
// kill all pending stuff
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
// FIX! Ende der current op abwarten!
if( connect )
emit driverStateChanged(BCDriver::DriverState::NotPresent, "Native Treiber wird geladen.");
/*
// kill all pending stuff
//QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
const QString& message = connect ? "Trying to connect" : " FAILED";
emit driverStateChanged(state, message);
return;
/*
// Hier sind wir noch in GUI Thread
QMutexLocker locker(&_mutex);
// weitere operation stoppen
_isBusy = true;
connect ? connectCanDriver() : disconnectCanDriver();
_isBusy = false;
*/
}
void BCTransmitter::onStartNativeDriver()
{
connect ? connectCanDriver() : disconnectCanDriver();
}
void BCTransmitter::connectCanDriver()
{
// hier gehts nur um den echten Treiber
@@ -92,38 +82,49 @@ void BCTransmitter::connectCanDriver()
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
result = _tinyCanDriver.loadAndStartDriver();
QString message("FitzeFatze!");
// hat geklappt
if( _tinyCanDriver.getDriverState() >= BCDriver::DriverState::Opened )
{
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
uint8_t hwRev = static_cast<uint8_t> (BC::ID::Cons_Rev_Hw);
TransmitResult hwVersion = _tinyCanDriver.readRawByte( console, hwRev);
if( hwVersion.has_value() )
QString message("Treiber geladen (nicht verbunden)");
// Der result-Wert im ERfolgsfall ist der driver state.
if(result.has_value() )
{
switch( result.value() )
{
message = " ---- HAIL to the king!";
//qDebug() << message;
// swap driver
_canDriver = &_tinyCanDriver;
}
else
{
//qDebug() << "Console not responding";
case BCDriver::DriverState::Opened:
message = "Treiber geladen (Device antwortet nicht)";
break;
case BCDriver::DriverState::DeviceReady:
message = "Treiber geladen und Device verbunden.";
// swap driver
_canDriver = &_tinyCanDriver;
break;
default:
break;
}
}
else
else // Fehlerfall, wir holen die Fehlermeldung
{
message = result.error();
}
emit driverStateChanged( _tinyCanDriver.getDriverState(), message );
}
/**
* @brief Native-Treiber zurücksetzen, Dummy-Treiber wieder aktivieren.
*/
void BCTransmitter::disconnectCanDriver()
{
_tinyCanDriver.resetDriver();
_canDriver = &_dummyDriver;
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected" );
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected, Dummy Treiber aktiviert." );
}
@@ -143,8 +144,6 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
// Kosmetik
const BCValue& value = *(valuePtr.get());
//qDebug() << "------- DE.-.QUEUE: " << QThread::currentThreadId() << ": " << value.label;
uint32_t devID = static_cast<uint32_t>(value.deviceID);
uint8_t regID = static_cast<uint8_t> (value.registerID);
@@ -167,6 +166,7 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
{
newState = BCValue::Flag::InSync;
newValue = result.value();
qDebug() << " ---- Wert empfangen: " << newValue;
}
}
@@ -174,7 +174,7 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
// __fix
//bc::processEventsFor(150);
bc::delay_millis(250);
//bc::delay_millis(150);
}
@@ -186,14 +186,12 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
void BCTransmitter::onEndOfTransmission()
{
qDebug() << " --- sending BACK EOT";
emit endOfProcessing();
}
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
{
////qDebug() << " --- YES: Read ByteValue: " << registerID;
// Wir lesen nur ein Byte und gut.
return _canDriver->readRawByte( deviceID, registerID );
}
@@ -201,8 +199,6 @@ TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t register
TransmitResult BCTransmitter::readWordValue( uint32_t deviceID, uint8_t registerID )
{
////qDebug() << " --- YES: Read WordValue: " << registerID;
uint32_t result{};
// hi byte Leseversuch.
TransmitResult value = _canDriver->readRawByte( deviceID, registerID );

View File

@@ -63,7 +63,6 @@ public slots:
void onToggleDriverConnection( bool connect );
void onUpdateValue(BCValuePtrConst valuePtr );
void onStartNativeDriver();
void onEndOfTransmission();
signals:
@@ -80,11 +79,6 @@ private:
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
//using BCDataQueue = QQueue<BCValuePtrConst>;
//BCDataQueue _valueQueue;
//QMutex _mutex;
//std::atomic<bool> _isBusy{ false };
BCDriver* _canDriver{};
BCDriverTinyCan _tinyCanDriver{};
BCDriverDummy _dummyDriver{};

View File

@@ -92,11 +92,10 @@ void BCValueModel::updateValue(int row, BCValue::Flags newState, uint32_t rawVal
//value.valueFlags = state;
value.rawValue = rawValue;
QModelIndex idx1 = index(row,1);
QModelIndex idx2 = index(row,2);
QModelIndex idx = index(row,1);
// wir schicken auf jeden fall einen update request
emit dataChanged(idx1, idx2, {Qt::DisplayRole, Qt::EditRole});
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::EditRole});
}
}
@@ -182,7 +181,6 @@ Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
bool BCValueModel::setData(const QModelIndex& index, const QVariant& variant, int role)
{
qDebug() << " --- SET DATA: " << variant.toString();
if (index.isValid() && role == Qt::EditRole)
{

View File

@@ -51,6 +51,7 @@ BCXmlLoader::BCXmlLoader(QObject *parent)
void BCXmlLoader::loadXmlBikeData( const QString& fileName )
{
/*
auto printAttrs = [](const QXmlStreamReader& xml)
{
QStringList parts;
@@ -60,6 +61,7 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
}
qDebug().noquote() << parts.join(" ");
};
*/
QMetaEnum bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
@@ -83,10 +85,6 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
if (token == QXmlStreamReader::StartElement)
{
QString deviceType = _xml.attributes().value("Type"_L1).toString();
qDebug() << " --- FETCH 1: " << deviceType;
// Wir wollen die Device-ID aus dem XML Tag ermitteln
if( deviceType.isEmpty() )
continue;
@@ -99,7 +97,6 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
//if( optDeviceID.has_value())
if(!ok)
throw BCException( "Fehler", QString("Devicetype %1 existiert nicht.").arg(deviceType) );
qDebug() << " --- FETCH 2: Device: " << deviceType << " : " << optDeviceID;
//BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID.value() );
BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID );
loadXmlBikeDeviceData(currentDeviceID);
@@ -132,9 +129,7 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
while( _xml.readNextStartElement() )
{
if( _xml.attributes().hasAttribute(BCTags::ID) )
{
qDebug() << " --- found: " << _xml.name() << " : " << _xml.attributes().value(BCTags::ID);
{
// füllen des Parameter packs
BCValueParams params
{
@@ -206,7 +201,6 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
static QMetaEnum s_bcValueEnum{QMetaEnum::fromType<BC::ID>()};
QByteArray byteArray = params.ID.toUtf8();
int IDVal = s_bcValueEnum.keyToValue( params.ID.toUtf8().constData(), &ok );
qDebug() << " --- should create: " << params.Label;
//if( IDVal.has_value() )
if( !ok )
throw BCException( "Fehler", QString("Devicetype %1 existiert nicht.").arg(params.ID) );
@@ -233,8 +227,7 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
if( params.ReadOnly == "true")
newValue.valueFlags.setFlag( BCValue::Flag::ReadOnly, true );
qDebug() << " --- created: " << params.Label;
newValue.dumpValue();
//newValue.dumpValue();
return std::optional<BCValuePtr>( newValuePtr );