8 Commits

Author SHA1 Message Date
3e9c1cc20b Added drivers, removed icons. 2026-01-04 02:30:49 +01:00
e118fa4a20 Add missing files. 2026-01-04 02:06:27 +01:00
2c9e9be6b3 HAIL TO THE KING! Finally Fixed Transmisson BUG! 2026-01-04 01:46:25 +01:00
c36e9053c4 Try to Fix read errors. 2026-01-04 00:40:53 +01:00
193579e798 Changed copyright notice. 2026-01-03 23:51:14 +01:00
3a132bb584 Reworked driver code, again. 2026-01-03 20:10:30 +01:00
68680db6b4 Fixed value loading. 2026-01-03 13:15:15 +01:00
56ab0fbc0f Merge branch 'drop-value-type' 2026-01-03 12:49:01 +01:00
65 changed files with 664 additions and 566 deletions

View File

@@ -27,12 +27,13 @@ windows
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
aalegacy.cpp \
bc.cpp \
bcanimateddelegate.cpp \
bcdeviceview.cpp \
bcdriver.cpp \
bcdrivertinycan.cpp \
bclegacy.cpp \
bcguihelpers.cpp \
bctransmitter.cpp \
bcvalue.cpp \
bcvaluemodel.cpp \
@@ -47,6 +48,7 @@ HEADERS += \
bcdeviceview.h \
bcdriver.h \
bcdrivertinycan.h \
bcguihelpers.h \
bcmainwindow.h \
bctransmitter.h \
bcvalue.h \

View File

@@ -185,102 +185,7 @@ double gSetSpeedLimit = -1, gSetMinSpeedLimit = -1, gSetThrottleSpeedLimit = -1;
#define BATTERY 3
#define BIB 4
/*
class ThemeSwitchButton : public QPushButton {
Q_OBJECT
public:
explicit ThemeSwitchButton(QWidget *parent = nullptr)
: QPushButton(parent), m_isDarkMode(true)
{
// 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor
setFlat(true);
setCursor(Qt::PointingHandCursor);
setFixedSize(32, 24); // Kleiner Footprint im StatusBar
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
setStyleSheet(R"(
QPushButton {
border: none;
background-color: transparent;
font-size: 14pt;
}
QPushButton:hover {
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
border-radius: 4px;
}
)");
// 2. Initialer Status (Startet im Dark Mode -> zeigt Mond)
updateIcon();
// 3. Klick verbinden
connect(this, &QPushButton::clicked, this, &ThemeSwitchButton::toggle);
}
signals:
void themeChanged(bool isDark);
private slots:
void toggle() {
m_isDarkMode = !m_isDarkMode;
updateIcon();
emit themeChanged(m_isDarkMode);
}
private:
void updateIcon() {
// Logik:
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
// Hier: Zeige das Symbol des AKTUELLEN Modus.
setText(m_isDarkMode ? "🌙" : "☀️");
setToolTip(m_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode");
}
bool m_isDarkMode;
};
*/
/*
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
setWindowTitle("Fluent Theme Switcher");
resize(800, 600);
// --- STATUSBAR SETUP ---
QStatusBar *statBar = statusBar();
// Optional: Normale Nachricht links
statBar->showMessage("Ready");
// 1. Unseren Switcher erstellen
ThemeSwitchButton *themeBtn = new ThemeSwitchButton(this);
// 2. WICHTIG: Rechts hinzufügen
statBar->addPermanentWidget(themeBtn);
// 3. Signal verbinden: Button klick -> Theme ändern
connect(themeBtn, &ThemeSwitchButton::themeChanged, this, [this](bool isDark){
if (isDark) {
applyFluentDarkTheme(*qApp); // Funktion von vorhin
statusBar()->showMessage("Dark Mode Activated", 3000);
} else {
applyFluentLightTheme(*qApp); // Funktion von vorhin
statusBar()->showMessage("Light Mode Activated", 3000);
}
});
// Initiale Anwendung (Dark Mode)
applyFluentDarkTheme(*qApp);
}
};
*/
char *getNodeName(unsigned char id)
{
@@ -727,24 +632,30 @@ int xmain(int argc, char **argv)
CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR);
CanGetDeviceStatus(0, &status);
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN) {
if (status.CanStatus == CAN_STATUS_BUS_OFF) {
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN)
{
if (status.CanStatus == CAN_STATUS_BUS_OFF)
{
printf("CAN Status BusOff" _NL);
CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE);
}
} else {
}
else
{
printf("error: could not open device" _NL);
goto error;
}
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
if (consoleInSlaveMode) {
if (consoleInSlaveMode)
{
printf("console already in salve mode. good!" _NL _NL);
} else {
if (gConsoleSetSlaveMode) {
}
else
{
if (gConsoleSetSlaveMode)
{
int retry = 20;
printf("putting console in salve mode ... ");
@@ -756,16 +667,21 @@ int xmain(int argc, char **argv)
doSleep(500); // give the console some time to settle
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
} else
}
else
{
printf("console not in slave mode" _NL _NL);
}
}
if (gAssistInitLevel != -1) {
if (gAssistInitLevel != -1)
{
printf("setting initial assistance level to %d" _NL, gAssistInitLevel);
setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel);
}
if (gSetSpeedLimit > 0) {
if (gSetSpeedLimit > 0)
{
printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit);
setSpeedLimit(gSetSpeedLimit);
doShutdown = 1;

2
bc.cpp
View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

2
bc.h
View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -78,8 +78,8 @@ void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueLis
}
void BCDeviceView::onValueUpdated(int index, BCValue::State state, const QString& newVisibleValue )
{
_valueModel.onValueUpdated( index,state,newVisibleValue);
{
_valueModel.onValueUpdated( index, state, newVisibleValue);
_itemDelegate->onHighlightRow( index );
}

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -37,12 +37,6 @@
BCDriver::BCDriver(QObject* parent )
: QObject{ parent }
{
}
BCDriver::DriverState BCDriver::getDriverState() const
{
return _driverState;
@@ -59,47 +53,16 @@ BCDriver::DriverState BCDriver::getDriverState() const
* aber die Console noch nicht eingeschaltet war.
*/
void BCDriverDummy::onStartDriver()
BCDriver::DriverStateResult BCDriverDummy::loadAndStartDriver()
{
_driverState = DriverState::DeviceReady;
emit driverStateChanged( DriverState::DeviceReady, "Driver Ready." );
return _driverState;
}
// __Fix
/*
try
{
// erstmal die Dll Laden: State::sIdle -> State::sLoaded
if( _driverState == DriverState::NotPresent)
_driverState = loadAndInitDriver();
emit stateChanged( _driverState );
}
catch( std::exception& except )
{
//::CanDownDriver();
//::UnloadAndInitDriver();
emit statusHint( except.what() );
}
*/
/// -----------------------------------------------------------------------------------
/// -----------------------------------------------------------------------------------
/**
* @brief BCDriverDummy::BCDriverDummy
* @param parent
*/
BCDriverDummy::BCDriverDummy( QObject* parent )
: BCDriver(parent)
{
}
TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
{

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -84,17 +84,17 @@ class BCDriverStatus;
*/
class BCDriver : public QObject
class BCDriver
{
Q_OBJECT
Q_GADGET
public:
// Die möglichen Zustände beim Laden
// des CAN-Bus Treibers.
enum class DriverState
{
enum class DriverState : uint8_t
{
NotPresent,
Error,
Loaded,
@@ -107,9 +107,11 @@ public:
// Enthält den Treiberzustand oder einen Fehlerstring
using DriverStateResult = std::expected<DriverState,QString>;
explicit BCDriver( QObject* parent = nullptr );
explicit BCDriver() = default;
virtual ~BCDriver() = default;
virtual BCDriver::DriverStateResult loadAndStartDriver() = 0;
// Gibt den aktuelle Zustand des Treibers zurück. Der DriverState
// muss auf DeviceReady stehen, um Werte lesen & schreiben zu können.
// Dazu muss das Bionx-System eingeschaltet sein.
@@ -122,14 +124,6 @@ public:
virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;
public slots:
virtual void onStartDriver() = 0;
signals:
void driverStateChanged( DriverState state, const QString& message="" ) const;
protected:
DriverState _driverState{DriverState::NotPresent};
@@ -137,20 +131,22 @@ protected:
};
/// -----------------------------------------------------------------------------------
/// -----------------------------------------------------------------------------------
class BCDriverDummy : public BCDriver
{
Q_OBJECT
public:
explicit BCDriverDummy( QObject* parent = nullptr );
BCDriver::DriverStateResult loadAndStartDriver() override;
TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots:
virtual void onStartDriver() override;
};
#endif // BCDRIVER_H

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -36,44 +36,56 @@
#include <can_drv.h>
/**
* @brief Destruktor. Entlädt den CAN-Bus Treiber wieder.
*/
BCDriverTinyCan::BCDriverTinyCan( QObject* parent )
: BCDriver(parent )
BCDriverTinyCan::~BCDriverTinyCan()
{
resetDriver();
}
/**
* @brief BCDriverTinyCan::loadAndStartDriver
* @return
*/
void BCDriverTinyCan::onStartDriver()
BCDriver::DriverStateResult BCDriverTinyCan::loadAndStartDriver()
{
DriverStateResult result;
if( _driverState < DriverState::Opened)
loadDriver();
result = loadDriver();
if( _driverState == DriverState::Opened)
_driverState = connectDriver();
result = setConsoleSlaveMode();
return result;
}
void BCDriverTinyCan::loadDriver()
/**
* @brief BCDriverTinyCan::loadDriver
* @return
*/
BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
{
auto callLoadDriver = []() -> DriverStateResult
auto callLoadDriver = [&]() -> DriverStateResult
{
if( ::LoadDriver( NULL ) < 0 )
return std::unexpected(QString("Driver Error: 'LoadDriver'"));
return DriverState::Loaded;
_driverState = DriverState::Loaded;
return _driverState;
};
auto callInitDriver = [](DriverState state) -> DriverStateResult
auto callInitDriver = [&](DriverState state) -> DriverStateResult
{
Q_UNUSED(state)
if( ::CanInitDriver( NULL ) < 0 )
return std::unexpected(QString("Driver Error: 'InitDriver'"));
return DriverState::Initialized;
_driverState = DriverState::Initialized;
return _driverState;
};
auto callOpenDevice = [](DriverState state) -> DriverStateResult
auto callOpenDevice = [&](DriverState state) -> DriverStateResult
{
Q_UNUSED(state)
if( ::CanDeviceOpen( 0, NULL ) < 0 )
@@ -90,48 +102,65 @@ void BCDriverTinyCan::loadDriver()
if( deviceStatus.CanStatus == CAN_STATUS_BUS_OFF )
{
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
}
return DriverState::Opened;
_driverState = DriverState::Opened;
return _driverState;
};
// #1. erstmal komplett zurücksetzen
resetDriver();
// #2. Treiber laden, initialisieren und
// mit dem tinyCan Interface verbinden.
auto newDriverState = callLoadDriver()
.and_then( callInitDriver )
.and_then( callOpenDevice );
_driverState = DriverState::Error;
QString message("Driver Ready.");
// success:
if(newDriverState)
_driverState = *newDriverState;
else
message = newDriverState.error();
{
// return 'DriverState::Opened'
return _driverState;
}
// return driver error message,
// _driverState ist irgendwo unter DriverState::Opened
return newDriverState;
emit driverStateChanged( _driverState, message );
}
// __fix
BCDriver::DriverState BCDriverTinyCan::connectDriver()
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
{
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
uint8_t slaveFlag = static_cast<uint8_t>(BC::ID::Cons_Status_Slave);
uint8_t slaveFlag = static_cast<uint8_t> (BC::ID::Cons_Status_Slave);
qDebug() << "XXX BCDriverTinyCan::Driver Init: putting Console in slave mode ... ";
// Console already in slave mode. good!
if( readRawByte( console, slaveFlag ) )
return DriverState::DeviceReady;
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;
emit driverStateChanged( _driverState, "Driver Init: putting Console in slave mode ... " );
TransmitResult isSlave = 0;
do
{
writeRawByte( console, slaveFlag, 1 );
isSlave = readRawByte( console, slaveFlag );
isSlave = readRawByte( console, slaveFlag );
bc::delay_millis( 200 );
} while( retry-- && !(*isSlave) );
@@ -145,20 +174,15 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
}
/*
try
{
initBCDevice::ID::Console();
}
catch( std::exception& except )
{
::CanDownDriver();
::UnloadDriver();
}
*/
void BCDriverTinyCan::resetDriver()
{
if( _driverState > DriverState::NotPresent )
{
::CanDownDriver();
::UnloadDriver();
_driverState = DriverState::NotPresent;
}
}
/**
* @brief BCDriverTinyCan::readRawByte
@@ -170,17 +194,75 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
{
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " TRY! ";
struct TCanMsg msg;
int err, retry = 20;
int timeout = 80;
unsigned char receipient = (unsigned char) deviceID;
unsigned char reg = (unsigned char) registerID;
msg.MsgFlags = 0L;
msg.Id = receipient;
msg.MsgLen = 2;
msg.MsgData[0] = 0x00;
msg.MsgData[1] = reg;
CanTransmit(0, &msg, 1);
while(timeout-- && CanTransmitGetCount(0))
bc::delay_millis( cTIMEOUT_MS );
if (timeout == -1)
qDebug() << "error: could not send value to node ";
retry:
timeout = 80;
while(timeout-- && !CanReceiveGetCount(0))
bc::delay_millis( cTIMEOUT_MS );
if (timeout == -1)
{
qDebug() << "error: no response from node";
return 0;
}
if ((err = CanReceive(0, &msg, 1)) > 0)
{
qDebug() << " retry: " << retry << " BIB:" << BC::ID::ID_Bib << " msg.Id: " << msg.Id << " msg.MsgLen: " << msg.MsgLen << " msg.MsgData[1]: " << msg.MsgData[1] << " reg: " << reg;
if (--retry && (msg.Id != (uint32_t)BC::ID::ID_Bib|| msg.MsgLen != 4 || msg.MsgData[1] != reg))
goto retry;
if (!retry)
{
qDebug() << "XXX error: no response from node: " << err;
return 0;
}
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " BYTE: " << (uint32_t) msg.MsgData[3];
return (unsigned int) msg.MsgData[3];
}
else
{
qDebug() << "Error:" <<err;
}
return 0;
/*
//TransmitResult
qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState();
if( getDriverState() != DriverState::DeviceReady)
if( _driverState <DriverState::Opened )
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
unsigned char receipient = (unsigned char ) deviceID;
::TCanMsg msg;
// msg verpacken
msg.MsgFlags = 0L;
msg.Id = deviceID;
msg.Id = receipient;//deviceID;
msg.MsgLen = 2;
msg.MsgData[0] = 0x00;
msg.MsgData[1] = registerID;
@@ -212,15 +294,15 @@ retry:
// message empfangen
int err = ::CanReceive( 0, &msg, 1 );
qDebug() << "HÄÄ ?" << err << "reg: "<< registerID <<" timeOuts: " << timeOuts;
//qDebug() << "HÄÄ ?" << err << "reg: "<< registerID <<" timeOuts: " << timeOuts;
if( err < 0 )
//throw BCException( "getValue error: could not receive value" );
qDebug( "getValue error: could not receive value" );
qDebug() << "HÄÄ 2" <<msg.Id;
qDebug() << "HÄÄ 2" <<msg.MsgLen;
qDebug() << "HÄÄ 2" <<msg.MsgData[1];
//qDebug() << "HÄÄ 2" <<msg.Id;
//qDebug() << "HÄÄ 2" <<msg.MsgLen;
//qDebug() << "HÄÄ 2" <<msg.MsgData[1];
//if( err > 0 )
if( --retries && ( msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != registerID ) )
@@ -229,23 +311,25 @@ retry:
if( !timeOuts )
return std::unexpected(QString("CAN response errror: timeout" ));
qDebug() << " --- CAN Read Byte: " << (uint32_t) msg.MsgData[3] << " Device:: "<< deviceID << " register: " << registerID;
return (uint32_t) msg.MsgData[3];
*/
}
// void BCDriverTinyCan::setValue( unsigned char receipient, unsigned char reg, unsigned char value )
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
{
if( getDriverState() != DriverState::DeviceReady)
return std::unexpected(QString("writeRawValue error: driver not loaded." ) );
if( _driverState <DriverState::Opened )
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
::TCanMsg msg;
int timeout_count = cTIMEOUT_COUNT;
msg.MsgFlags = 0L;
msg.Id = deviceID;
msg.MsgLen = 4;

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -37,24 +37,23 @@
class BCDriverTinyCan : public BCDriver
{
Q_OBJECT
public:
explicit BCDriverTinyCan( QObject* parent=nullptr );
virtual ~BCDriverTinyCan() = default;
virtual ~BCDriverTinyCan();
BCDriver::DriverStateResult loadAndStartDriver() override;
void resetDriver();
TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots:
private:
void onStartDriver() override;
BCDriver::DriverStateResult loadDriver();
BCDriver::DriverStateResult setConsoleSlaveMode();
protected:
void loadDriver();
DriverState connectDriver();
//const char* CBCDLL_LIN = "libmhstcan.so";
//const char* CBCDLL_WIN = "mhstcan.dll";
@@ -64,9 +63,6 @@ protected:
static constexpr int cTIMEOUT_MS = 10; // 10ms
static constexpr int cTIMEOUT_COUNT = 10;
//const unsigned int BATTERY = 0x010;
//const unsigned int MOTOR = 0x020;
const unsigned int BIB = 0x048;
};

188
bcguihelpers.cpp Normal file
View File

@@ -0,0 +1,188 @@
/***************************************************************************
BionxControl
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
mhs_can_drv.c
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
Klaus Demlehner, klaus@mhs-elektronik.de
@see www.mhs-elektronik.de
Based on Bionx data type descriptions from:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#include <bcguihelpers.h>
BCThemeSwitchButton::BCThemeSwitchButton(QWidget *parent )
: QPushButton(parent), _isDarkMode(true)
{
// 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor
setFlat(true);
setCursor(Qt::PointingHandCursor);
setFixedSize(24, 24); // Kleiner Footprint im StatusBar
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
setStyleSheet(R"(
QPushButton {
border: none;
background-color: transparent;
font-size: 11pt;
}
QPushButton:hover {
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
border-radius: 24px;
}
)");
// 2. Initialer Status (Startet im Dark Mode -> zeigt Mond)
updateIcon();
// 3. Klick verbinden
connect(this, &QPushButton::clicked, this, &BCThemeSwitchButton::toggle);
}
void BCThemeSwitchButton::toggle()
{
_isDarkMode = !_isDarkMode;
updateIcon();
emit themeChanged(_isDarkMode);
}
void BCThemeSwitchButton::updateIcon()
{
// Logik:
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
// Hier: Zeige das Symbol des AKTUELLEN Modus.
setText(_isDarkMode ? "🌙" : "☀️");
setToolTip(_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode");
}
/// -----------------------------------------------------------------------------------
/// -----------------------------------------------------------------------------------
BCDriverStateWidget::BCDriverStateWidget(QWidget* parent)
: QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(10, 2, 10, 2);
layout->setSpacing(8);
_label = new QLabel(this);
_label->setStyleSheet("font-weight: 500;"); // Medium weight
_led = new QLabel(this);
_led->setFixedSize(12, 12);
layout->addWidget(_label);
layout->addWidget(_led);
// Startzustand
onDriverStateChanged(BCDriver::DriverState::NotPresent, "Not Present");
}
// Hauptfunktion zum Setzen des Status
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
void BCDriverStateWidget::onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage)
{
_state = state;
qDebug() << " --- StateWidget: " << state << " - " << customMessage;
// Standard-Texte, falls keine Nachricht übergeben wurde
QString text = customMessage;
if (text.isEmpty())
{
switch (_state)
{
case BCDriver::DriverState::DeviceReady:
text = "Device Ready";
break;
case BCDriver::DriverState::Error:
text = "Driver Error";
break;
default:
text = "Not Present";
break;
}
}
_label->setText(text);
updateStyle();
}
void BCDriverStateWidget::updateStyle()
{
QString ledStyle;
QString labelColor;
QString toolTipText;
switch (_state)
{
case BCDriver::DriverState::DeviceReady:
// 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 BCDriver::DriverState::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;
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)
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
// Textfarbe setzen
_label->setStyleSheet(QString("color: %1; font-weight: %2;")
.arg(labelColor)
.arg(_state == BCDriver::DriverState::DeviceReady ? "bold" : "normal"));
setToolTip(toolTipText);
}

97
bcguihelpers.h Normal file
View File

@@ -0,0 +1,97 @@
/***************************************************************************
BionxControl
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
mhs_can_drv.c
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
Klaus Demlehner, klaus@mhs-elektronik.de
@see www.mhs-elektronik.de
Based on Bionx data type descriptions from:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
#ifndef BCGUIHELPERS_H
#define BCGUIHELPERS_H
#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <bcdriver.h>
class BCThemeSwitchButton : public QPushButton
{
Q_OBJECT
public:
explicit BCThemeSwitchButton(QWidget *parent = nullptr);
signals:
void themeChanged(bool isDark);
private slots:
void toggle();
private:
void updateIcon();
bool _isDarkMode;
};
/// -----------------------------------------------------------------------------------
/// -----------------------------------------------------------------------------------
class BCDriverStateWidget : public QWidget
{
Q_OBJECT
public:
explicit BCDriverStateWidget(QWidget *parent = nullptr);
public slots:
// Hauptfunktion zum Setzen des Status
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
void onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage = QString());
private:
void updateStyle();
QLabel* _led;
QLabel* _label;
BCDriver::DriverState _state;
};
#endif // BCGUIHELPERS_H

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -36,7 +36,7 @@
#include <bcmainwindow.h>
#include <bcanimateddelegate.h>
#include <ui_bcmainwindow.h>
#include <bcguihelpers.h>
/**
* @brief Das Mainwindow erzeugen
@@ -141,20 +141,21 @@ void BCMainWindow::initMainWindow()
fitzeButton->setStyleSheet(style);
*/
// besser: model::emit dataChanged
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleConnectionState );
initStatusBar();
// besser: model::emit dataChanged
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
_transmitter.moveToThread(&_worker);
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::enqueueValue);
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
// transmitter starten
_transmitter.moveToThread(&_worker);
_worker.start();
// die Daten des eBikes laden
@@ -167,30 +168,19 @@ void BCMainWindow::initMainWindow()
void BCMainWindow::initStatusBar()
{
// __fix
QStatusBar *statBar = statusBar();
// Optional: Normale Nachricht links
BCDriverStateWidget* connector = new BCDriverStateWidget(this);
connect( &_transmitter, &BCTransmitter::driverStateChanged, connector, &BCDriverStateWidget::onDriverStateChanged );
statBar->addPermanentWidget(connector);
statBar->showMessage("Ready");
// 1. Unseren Switcher erstellen
ThemeSwitchButton *themeBtn = new ThemeSwitchButton(this);
// 2. WICHTIG: Rechts hinzufügen
BCThemeSwitchButton *themeBtn = new BCThemeSwitchButton(this);
statBar->addPermanentWidget(themeBtn);
// 3. Signal verbinden: Button klick -> Theme ändern
connect(themeBtn, &ThemeSwitchButton::themeChanged, this, [this](bool isDark){
if (isDark)
{
//applyFluentDarkTheme(*qApp); // Funktion von vorhin
statusBar()->showMessage("Dark Mode Activated", 3000);
}
else
{
//applyFluentLightTheme(*qApp); // Funktion von vorhin
statusBar()->showMessage("Light Mode Activated", 3000);
}
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
{
QString message = isDark ? "Dark Mode Activated" : "Light Mode Activated";
statusBar()->showMessage( message, 3000);
});
}
@@ -216,6 +206,7 @@ void BCMainWindow::autoConnect()
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
{
qDebug() << " --- on DriverStatusChanged: " << state << ":" << message;
_statusbar->showMessage( message, 8000 );
}
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -92,170 +92,4 @@ protected:
};
class ThemeSwitchButton : public QPushButton
{
Q_OBJECT
public:
explicit ThemeSwitchButton(QWidget *parent = nullptr)
: QPushButton(parent), m_isDarkMode(true)
{
// 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor
setFlat(true);
setCursor(Qt::PointingHandCursor);
setFixedSize(24, 24); // Kleiner Footprint im StatusBar
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
setStyleSheet(R"(
QPushButton {
border: none;
background-color: transparent;
font-size: 11pt;
}
QPushButton:hover {
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
border-radius: 24px;
}
)");
// 2. Initialer Status (Startet im Dark Mode -> zeigt Mond)
updateIcon();
// 3. Klick verbinden
connect(this, &QPushButton::clicked, this, &ThemeSwitchButton::toggle);
}
signals:
void themeChanged(bool isDark);
private slots:
void toggle() {
m_isDarkMode = !m_isDarkMode;
updateIcon();
emit themeChanged(m_isDarkMode);
}
private:
void updateIcon() {
// Logik:
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
// Hier: Zeige das Symbol des AKTUELLEN Modus.
setText(m_isDarkMode ? "🌙" : "☀️");
setToolTip(m_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode");
}
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

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -35,37 +35,78 @@
#include <bctransmitter.h>
/**
* @brief Kosntruktion. Aktiviert erstmal den Dummy-Driver.
*/
BCTransmitter::BCTransmitter(QObject *parent)
: QObject(parent), _isBusy(false)
{
//_canDriver = new BCDriverTinyCan{this};
_canDriver = new BCDriverDummy{this};
// forward driver state
connect( _canDriver, &BCDriver::driverStateChanged, this, &BCTransmitter::driverStateChanged );
_canDriver = &_dummyDriver;
}
/**
* @brief Steuert die Verbindung mit dem 'echten' CAN-Bus Treiber.
* @param connect true: Vesuche den CAN-Bus Treiber zu laden und zu verbinden
* false: Disconnect & Cleanup
*/
void BCTransmitter::onToggleConnectionState( bool connect )
void BCTransmitter::onToggleDriverConnection( bool connect )
{
if( connect )
{
if( _canDriver->getDriverState() != BCDriver::DriverState::DeviceReady )
_canDriver->onStartDriver();
qDebug() << " --- onToggleDriverConnection: " << connect;
// FIX! Ende der current op abwarten!
// __fix!
TransmitResult hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
if(!hwVersion)
// Hier sind wir noch in GUI Thread
QMutexLocker locker(&_mutex);
// weitere operation stoppen
_isBusy = true;
connect ? connectCanDriver() : disconnectCanDriver();
_isBusy = false;
}
void BCTransmitter::connectCanDriver()
{
// hier gehts nur um den echten Treiber
// Treiber laden und/oder starten:
BCDriver::DriverStateResult result; //(defaults to 'NotPresent')
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() )
{
qDebug() << "Console not responding";
message = " ---- HAIL to the king!";
qDebug() << message;
// swap driver
_canDriver = &_tinyCanDriver;
}
else
{
qDebug() << "Console not responding";
}
qDebug() << " ---HAIL to the kings: " << hwVersion.value();
}
else
{
message = result.error();
}
emit driverStateChanged( _tinyCanDriver.getDriverState(), message );
}
void BCTransmitter::disconnectCanDriver()
{
_tinyCanDriver.resetDriver();
_canDriver = &_dummyDriver;
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected" );
}
@@ -163,7 +204,7 @@ void BCTransmitter::processValue()
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
{
qDebug() << " --- YES: Read ByteValue: " << registerID;
//qDebug() << " --- YES: Read ByteValue: " << registerID;
// Wir lesen nur ein Byte und gut.
return _canDriver->readRawByte( deviceID, registerID );
}
@@ -171,7 +212,7 @@ TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t register
TransmitResult BCTransmitter::readWordValue( uint32_t deviceID, uint8_t registerID )
{
qDebug() << " --- YES: Read WordValue: " << registerID;
//qDebug() << " --- YES: Read WordValue: " << registerID;
uint32_t result{};
// hi byte Leseversuch.

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -60,12 +60,9 @@ public:
explicit BCTransmitter(QObject *parent = nullptr);
//TransmitResult readByte( uint32_t deviceID, uint8_t registerID ) const override;
//TransmitResult writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots:
void onToggleConnectionState( bool connect );
void onToggleDriverConnection( bool connect );
void enqueueValue(BCValuePtrConst value );
void processValue();
@@ -76,11 +73,11 @@ signals:
private:
void connectCanDriver();
void disconnectCanDriver();
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
//TransmitResult writeByteValue( uint32_t deviceID, uint8_t registerID );
//TransmitResult writeWordValue( uint32_t deviceID, uint8_t registerID );
using BCDataQueue = QQueue<BCValuePtrConst>;
@@ -88,8 +85,10 @@ private:
QMutex _mutex;
std::atomic<bool> _isBusy{ false };
// __fix! set two
BCDriver* _canDriver{};
// __fix!
BCDriver* _canDriver{};
BCDriverTinyCan _tinyCanDriver{};
BCDriverDummy _dummyDriver{};
};

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -44,42 +44,6 @@ BCValue::BCValue( BCDevice::ID deviceID_, BC::ID registerID_)
visibleValue = "--";
}
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
mhs_can_drv.c
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
Klaus Demlehner, klaus@mhs-elektronik.de
@see www.mhs-elektronik.de
Based on Bionx data type descriptions from:
BigXionFlasher USB V 0.2.4 rev. 97
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
@see www.bigxionflasher.org
Bionx Bike Info
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
@see www.ts-soft.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
@see https://github.com/bikemike/bionx-bikeinfo
***************************************************************************/
QString BCValue::formatValue( uint32_t value ) const
{
if( factor == 1 )
@@ -89,5 +53,14 @@ QString BCValue::formatValue( uint32_t value ) const
return QString::number(result, 'f', 2);
}
void BCValue::dumpValue() const
{
qDebug() << "DeviceID: " << deviceID << " Register: " << registerID << " state:" " << state << " << " label: " << label;
qDebug() << "visibleValue: " << visibleValue << " min: " << min << " max: " << max << " factor: " << factor << " ValueType: " << (char)valueType << " ";
qDebug() << "indexRow: " << indexRow << " isWord: " << isWord;
qDebug();
}
/// ----

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -56,8 +56,6 @@
-
*/
using OptDouble = std::optional<double>;
// Enthält den gelesenen Wert oder einen Fehlerstring
@@ -65,8 +63,6 @@ using TransmitResult = std::expected<uint32_t,QString>;
// Funktionsobject, um Werte aus der Transmitterschicht zu holden
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;
class BCValue
{
@@ -98,6 +94,7 @@ public:
BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );
QString formatValue( uint32_t value ) const;
void dumpValue() const;
mutable States state{BCValue::State::ReadOnly};
BCDevice::ID deviceID{BCDevice::ID::Invalid};

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -82,17 +82,26 @@ void BCValueModel::takeValueList(BCValueList& newValueList)
*/
void BCValueModel::onValueUpdated( int row, BCValue::State state, const QString& newVisisbleValue )
{
qDebug() << " BCValueModel::onValueUpdated update: " << newVisisbleValue;
{
if( row > -1 && row < _valueList.size() )
{
BCValuePtr value = _valueList[row];
BCValue& value = *(_valueList[row].get());
QModelIndex idx = index(row,1);
value->state = state;
if( !newVisisbleValue.isEmpty() && newVisisbleValue != value->visibleValue )
//qDebug();
//qDebug() << " --- OLD:"<< newVisisbleValue;
//value.dumpValue();
value.state = state;
if( !newVisisbleValue.isEmpty() && newVisisbleValue != value.visibleValue )
{
value->visibleValue = newVisisbleValue;
value.visibleValue = newVisisbleValue;
}
//qDebug() << " --- NEW: " << newVisisbleValue;
//value.dumpValue();
// wir schicken auf jeden fall einen update request
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::EditRole});
}

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:
@@ -224,14 +224,13 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
BCValuePtr newValuePtr = std::make_shared<BCValue>( deviceID, static_cast<BC::ID>(IDVal) );
BCValue& newValue = *newValuePtr.get();
setIfExists( params.Factor, newValue.factor );
setIfExists( params.Min, newValue.min );
setIfExists( params.Max, newValue.max );
setIfExists( params.IsWord, newValue.isWord );
newValue.label = params.Label;
newValue.label = params.UnitLabel;
newValue.label = params.Label;
newValue.unitLabel = params.UnitLabel;
if( s_valueTypes.contains( params.ValueType ) )
newValue.valueType = s_valueTypes[params.ValueType];
@@ -245,9 +244,10 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
QString Max;
QString IsWord;
QString ValueType;
*/
*/
qDebug() << " --- created: " << params.Label;
newValue.dumpValue();
return std::optional<BCValuePtr>( newValuePtr );
}

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

BIN
doc/Challenges.docx Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -1,7 +1,52 @@
Challenges
-------------------------------------------------------------------------------------------------
BionxControl
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
xtree
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
znode
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
libPigPio
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
supportware
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
raDIYo
Aufgabe:
@@ -9,34 +54,7 @@ Ansatz:
-------------------------------------------------------------------------------------------------
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
miniCash.connect
Aufgabe:

BIN
doc/~$allenges.docx Normal file

Binary file not shown.

BIN
doc/~WRL0643.tmp Normal file

Binary file not shown.

View File

@@ -1,7 +1,7 @@
/***************************************************************************
BionxControl
Copyright © 2025 christoph holzheuer
© 2025 -2026 christoph holzheuer
christoph.holzheuer@gmail.com
Using:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

BIN
resources/TinyCan_812.exe Normal file

Binary file not shown.

View File

@@ -1,24 +1,17 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
QString ID;
QString Label;
QString UnitLabel;
QString Factor;
QString Min;
QString Max;
QString IsWord;
QString ValueType;
-->
<Bike name='franken-wheeler'>
<Device Type="Console">
<Value ID='Cons_Rev_Hw' Label='Hardware Version' />
<Value ID='Cons_Rev_Sw' Label='Software Version' />
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='1'/>
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='1'/>
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' IsWord='1' />
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Min='0' Max='4'/>
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
@@ -37,6 +30,7 @@ QString ValueType;
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Factor='1.5625' />
</Device>
<!--
<Device Type="Motor">
<Value ID='Motor_Rev_Hw' Label='Hardware Version' />
<Value ID='Motor_Rev_Sw' Label='Software Version' />
@@ -52,7 +46,7 @@ QString ValueType;
<Value ID='Battery_Rev_Hw' Label='Hardware Version' />
<Value ID='Battery_Rev_Sw' Label='Software Version' />
</Device>
-->
</Bike>
<!--

Binary file not shown.

Binary file not shown.