Crash protection. part I
This commit is contained in:
@@ -26,9 +26,9 @@ windows
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
bc.cpp \
|
bc.cpp \
|
||||||
bcdatamodel.cpp \
|
|
||||||
bcitemdelegate.cpp \
|
bcitemdelegate.cpp \
|
||||||
bctransmitter.cpp \
|
bctransmitter.cpp \
|
||||||
|
bcvaluemodel.cpp \
|
||||||
lib/can_drv_win.c \
|
lib/can_drv_win.c \
|
||||||
bccandriver.cpp \
|
bccandriver.cpp \
|
||||||
bccandrivertinycan.cpp \
|
bccandrivertinycan.cpp \
|
||||||
@@ -41,12 +41,12 @@ HEADERS += \
|
|||||||
bc.h \
|
bc.h \
|
||||||
bccandriver.h \
|
bccandriver.h \
|
||||||
bccandrivertinycan.h \
|
bccandrivertinycan.h \
|
||||||
bcdatamodel.h \
|
|
||||||
bcitemdelegate.h \
|
bcitemdelegate.h \
|
||||||
bcmainwindow.h \
|
bcmainwindow.h \
|
||||||
bctransmitter.h \
|
bctransmitter.h \
|
||||||
bcvalue.h \
|
bcvalue.h \
|
||||||
bcvaluemanager.h
|
bcvaluemanager.h \
|
||||||
|
bcvaluemodel.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
bcmainwindow.ui
|
bcmainwindow.ui
|
||||||
|
|||||||
12
bc.h
12
bc.h
@@ -35,7 +35,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject> // Nötig für Q_GADGET/Q_ENUM Makros
|
#include <QObject> // Nötig für Q_GADGET/Q_ENUM Makros
|
||||||
|
|
||||||
namespace cbc
|
namespace bc
|
||||||
{
|
{
|
||||||
[[maybe_unused]] constexpr static double UNLIMITED_SPEED_VALUE = 70; // Km/h
|
[[maybe_unused]] constexpr static double UNLIMITED_SPEED_VALUE = 70; // Km/h
|
||||||
// UNLIMITED_MIN_SPEED_VALUE = 30; // Km/h
|
// UNLIMITED_MIN_SPEED_VALUE = 30; // Km/h
|
||||||
@@ -63,9 +63,10 @@ namespace cbc
|
|||||||
void delay_seconds( uint32_t );
|
void delay_seconds( uint32_t );
|
||||||
void delay_millis( uint32_t );
|
void delay_millis( uint32_t );
|
||||||
void delay_micros( uint32_t );
|
void delay_micros( uint32_t );
|
||||||
|
void processEventsFor(int milliseconds);
|
||||||
|
|
||||||
QString formatInt( int count, int len );
|
QString formatInt( int count, int len );
|
||||||
} // namespace cbc
|
} // namespace bc
|
||||||
|
|
||||||
// abbreviations:
|
// abbreviations:
|
||||||
// SOC = State Of Charge
|
// SOC = State Of Charge
|
||||||
@@ -102,6 +103,13 @@ struct BC
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum class OpID : uint8_t
|
||||||
|
{
|
||||||
|
ReadValue,
|
||||||
|
WriteValue,
|
||||||
|
};
|
||||||
|
Q_ENUM(OpID)
|
||||||
|
|
||||||
enum class ID : uint8_t
|
enum class ID : uint8_t
|
||||||
{
|
{
|
||||||
//{%Region Console}
|
//{%Region Console}
|
||||||
|
|||||||
@@ -272,7 +272,8 @@ void BCItemDelegate::clearAllHighlights()
|
|||||||
|
|
||||||
void BCItemDelegate::updateRow(int row)
|
void BCItemDelegate::updateRow(int row)
|
||||||
{
|
{
|
||||||
if (_view && row >= 0) {
|
if (_view && _view->model() && row >= 0)
|
||||||
|
{
|
||||||
QModelIndex idx = _view->model()->index(row, 0);
|
QModelIndex idx = _view->model()->index(row, 0);
|
||||||
QRect rect = _view->visualRect(idx);
|
QRect rect = _view->visualRect(idx);
|
||||||
if (!rect.isEmpty()) {
|
if (!rect.isEmpty()) {
|
||||||
|
|||||||
@@ -55,11 +55,12 @@ BCMainWindow::BCMainWindow(QWidget *parent)
|
|||||||
|
|
||||||
// Highlight mit Fade-Out:
|
// Highlight mit Fade-Out:
|
||||||
_delegate->onHighlightRow(2); // 2 Sekunden Fade
|
_delegate->onHighlightRow(2); // 2 Sekunden Fade
|
||||||
|
BCTransmitter* transmitter = _valueManager.getTransmitter();
|
||||||
|
|
||||||
// besser: model::emit dataChanged
|
// besser: model::emit dataChanged
|
||||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||||
connect( &_valueManager, &BCValueManager::valueTouched, _delegate, &BCItemDelegate::onHighlightRow );
|
connect( &_valueManager, &BCValueManager::valueTouched, _delegate, &BCItemDelegate::onHighlightRow );
|
||||||
connect( _connectButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onToggleConnectionState );
|
connect( _connectButton, &QPushButton::clicked, transmitter, &BCTransmitter::onToggleConnectionState );
|
||||||
connect( _syncButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onSyncFromDevice );
|
connect( _syncButton, &QPushButton::clicked, &_valueManager, &BCValueManager::onSyncFromDevice );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
36
bcvalue.cpp
36
bcvalue.cpp
@@ -31,27 +31,25 @@
|
|||||||
|
|
||||||
#include <bcvalue.h>
|
#include <bcvalue.h>
|
||||||
|
|
||||||
|
BCValueType::BCValueType()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BCValue::BCValue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCValue::BCValue(const BCValueType& valueType_, BCDevice::ID deviceID_, BC::ID targetID_)
|
||||||
|
: valueType{valueType_}, deviceID{deviceID_}, targetID{targetID_}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
BCValueType::BCValueType( TypeID ID_, QString unitLabel_, optDouble factor_, optDouble min_, optDouble max_ )
|
BCValueType::BCValueType( TypeID ID_, QString unitLabel_, optDouble factor_, optDouble min_, optDouble max_ )
|
||||||
: ID{ID_}, unitLabel{unitLabel_},factor{factor_},min{min_},max{max_}
|
: ID{ID_}, unitLabel{unitLabel_}, factor{factor_}, min{min_}, max{max_}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BCValue::BCValue(BCDevice::ID deviceID_, BC::ID targetID_)
|
|
||||||
: deviceID{deviceID_}, targetID{targetID_}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCValue::setLongValue( uint8_t value)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t BCValue::getLongValue()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
40
bcvalue.h
40
bcvalue.h
@@ -31,6 +31,7 @@
|
|||||||
#ifndef BCVALUE_H
|
#ifndef BCVALUE_H
|
||||||
#define BCVALUE_H
|
#define BCVALUE_H
|
||||||
|
|
||||||
|
#include "qnamespace.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -68,6 +69,9 @@ public:
|
|||||||
Text,
|
Text,
|
||||||
Number,
|
Number,
|
||||||
Float,
|
Float,
|
||||||
|
Byte,
|
||||||
|
Word,
|
||||||
|
Quad,
|
||||||
Percent,
|
Percent,
|
||||||
KWh,
|
KWh,
|
||||||
Watt,
|
Watt,
|
||||||
@@ -83,9 +87,10 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(TypeID)
|
Q_ENUM(TypeID)
|
||||||
|
|
||||||
|
BCValueType();
|
||||||
BCValueType( TypeID ID_, QString unitLabel_="", optDouble factor_=std::nullopt, optDouble min_=std::nullopt, optDouble max_= std::nullopt );
|
BCValueType( TypeID ID_, QString unitLabel_="", optDouble factor_=std::nullopt, optDouble min_=std::nullopt, optDouble max_= std::nullopt );
|
||||||
|
|
||||||
TypeID ID;
|
TypeID ID{TypeID::Invalid};
|
||||||
QString unitLabel;
|
QString unitLabel;
|
||||||
optDouble factor;
|
optDouble factor;
|
||||||
optDouble min;
|
optDouble min;
|
||||||
@@ -93,26 +98,28 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using BCValueTypeCRef = std::optional<std::reference_wrapper<const BCValueType>>;
|
||||||
|
|
||||||
|
|
||||||
class BCValue
|
class BCValue
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BCValue() = default;
|
BCValue();
|
||||||
BCValue( BCDevice::ID deviceID, BC::ID targetID );
|
BCValue( const BCValueType& valueType_, BCDevice::ID deviceID_, BC::ID targetID_ );
|
||||||
|
|
||||||
void setLongValue( uint8_t value);
|
BCValueTypeCRef valueType;
|
||||||
uint8_t getLongValue();
|
BCDevice::ID deviceID{BCDevice::ID::Invalid};
|
||||||
|
BC::ID targetID{BC::ID::Invalid};
|
||||||
|
int rowInModel{-1};
|
||||||
|
QString label;
|
||||||
|
QVariant value;
|
||||||
|
QVariant defaultValue;
|
||||||
|
bool inSync{false};
|
||||||
|
bool readOnly{false};
|
||||||
|
|
||||||
BCDevice::ID deviceID{BCDevice::ID::Invalid};
|
// void reset()
|
||||||
BC::ID targetID{BC::ID::Invalid};
|
|
||||||
BCValueType::TypeID typeID{BCValueType::TypeID::Invalid};;
|
|
||||||
int rowInModel{-1};
|
|
||||||
QString label;
|
|
||||||
QVariant value;
|
|
||||||
QVariant defaultValue;
|
|
||||||
bool inSync{false};
|
|
||||||
bool readOnly{false};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
// Damit QVariant dieses Struct transportieren kann:
|
// Damit QVariant dieses Struct transportieren kann:
|
||||||
@@ -124,12 +131,7 @@ struct BCValueParams
|
|||||||
QString ID;
|
QString ID;
|
||||||
QString Label;
|
QString Label;
|
||||||
QString Default;
|
QString Default;
|
||||||
QString Current;
|
|
||||||
QString Enabled;
|
|
||||||
QString UnitType;
|
QString UnitType;
|
||||||
QString Min;
|
|
||||||
QString Max;
|
|
||||||
QString Factor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// abbreviations:
|
// abbreviations:
|
||||||
|
|||||||
@@ -43,20 +43,11 @@
|
|||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
|
||||||
void processEventsFor(int milliseconds)
|
|
||||||
{
|
|
||||||
QElapsedTimer timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
while (timer.elapsed() < milliseconds) {
|
|
||||||
QApplication::processEvents(QEventLoop::AllEvents, 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BCValueManager::BCValueManager(QObject *parent)
|
BCValueManager::BCValueManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
loadTypeData();
|
createValueTypes();
|
||||||
|
|
||||||
qRegisterMetaType<BCValue>("BCValue");
|
qRegisterMetaType<BCValue>("BCValue");
|
||||||
|
|
||||||
@@ -65,7 +56,7 @@ BCValueManager::BCValueManager(QObject *parent)
|
|||||||
// 4. Verbindungen herstellen (Signal/Slot über Thread-Grenzen)
|
// 4. Verbindungen herstellen (Signal/Slot über Thread-Grenzen)
|
||||||
|
|
||||||
// A) Befehl senden (Manager -> Runner)
|
// A) Befehl senden (Manager -> Runner)
|
||||||
connect(this, &BCValueManager::valueCreated, &_transmitter, &BCTransmitter::enqueueValue);
|
connect(this, &BCValueManager::sendValueCommand, &_transmitter, &BCTransmitter::enqueueValueCommand);
|
||||||
|
|
||||||
// B) Ergebnisse empfangen (Runner -> Manager)
|
// B) Ergebnisse empfangen (Runner -> Manager)
|
||||||
//connect(&_transmitter, &BCTransmitter::commandFinished, this, &BCValueManager::onCommandFinished);
|
//connect(&_transmitter, &BCTransmitter::commandFinished, this, &BCValueManager::onCommandFinished);
|
||||||
@@ -88,6 +79,49 @@ BCValueManager::~BCValueManager()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValueManager::createValueTypes()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Invalid = 0x0,
|
||||||
|
"Text"
|
||||||
|
"Number"
|
||||||
|
"Float"
|
||||||
|
"Percent"
|
||||||
|
"KWh"
|
||||||
|
"Watt"
|
||||||
|
"Km"
|
||||||
|
"Kmh"
|
||||||
|
"Mm"
|
||||||
|
"Sec"
|
||||||
|
"SoC"
|
||||||
|
"Odo"
|
||||||
|
"Date"
|
||||||
|
|
||||||
|
*/
|
||||||
|
//_valueTypes.insert( { BCValueType::TypeID::Invalid, "Invalid" } );
|
||||||
|
|
||||||
|
_valueTypes.insert( "Invalid", { BCValueType::TypeID::Invalid, "Invalid" } );
|
||||||
|
_valueTypes.insert( "Text", { BCValueType::TypeID::Text } );
|
||||||
|
_valueTypes.insert( "Number", { BCValueType::TypeID::Number } );
|
||||||
|
|
||||||
|
_valueTypes.insert( "Byte", { BCValueType::TypeID::Byte } );
|
||||||
|
_valueTypes.insert( "Word", { BCValueType::TypeID::Word } );
|
||||||
|
_valueTypes.insert( "Quad", { BCValueType::TypeID::Quad } );
|
||||||
|
|
||||||
|
_valueTypes.insert( "Float", { BCValueType::TypeID::Float, "", 1.5625} );
|
||||||
|
_valueTypes.insert( "Percent",{ BCValueType::TypeID::Percent, "%", 1.5625 } );
|
||||||
|
_valueTypes.insert( "KWh", { BCValueType::TypeID::KWh, "kwh", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Watt", { BCValueType::TypeID::Watt, "w", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Km", { BCValueType::TypeID::Km, "km", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Kmh", { BCValueType::TypeID::Kmh, "km/h", 0.1 } );
|
||||||
|
_valueTypes.insert( "Mm", { BCValueType::TypeID::Mm, "mm", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Sec", { BCValueType::TypeID::Sec, "s", 1.5625 } );
|
||||||
|
_valueTypes.insert( "SoC", { BCValueType::TypeID::SoC, "%", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Odo", { BCValueType::TypeID::Odo, "km", 1.5625 } );
|
||||||
|
_valueTypes.insert( "Assist", { BCValueType::TypeID::Assist, "", 0 ,4 } );
|
||||||
|
_valueTypes.insert( "Assist", { BCValueType::TypeID::AssistFac, "%" } );
|
||||||
|
_valueTypes.insert( "Date", { BCValueType::TypeID::Date } );
|
||||||
|
}
|
||||||
|
|
||||||
void BCValueManager::onCommandFinished(int id, bool success)
|
void BCValueManager::onCommandFinished(int id, bool success)
|
||||||
{
|
{
|
||||||
@@ -100,75 +134,40 @@ void BCValueManager::onRunnerMessage(const QString &msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCValueManager::onToggleConnectionState( bool connect )
|
|
||||||
{
|
|
||||||
if( connect )
|
|
||||||
{
|
|
||||||
if( BCCanDriver::sIdle == _canDriver.getState() )
|
|
||||||
_canDriver.onStartDriver();
|
|
||||||
|
|
||||||
int hwVersion = _canDriver.getValue( BCDevice::ID::Console, BC::ID::Cons_Rev_Hw);
|
|
||||||
|
|
||||||
if (hwVersion == 0)
|
|
||||||
{
|
|
||||||
qDebug() << "Console not responding";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
swVersion = getValue(CONSOLE, CONSOLE_REF_SW);
|
|
||||||
printf( "Console information:" _NL
|
|
||||||
" hardware version ........: %02d" _NL
|
|
||||||
" software version ........: %02d" _NL
|
|
||||||
" assistance level ........: %d" _NL,
|
|
||||||
hwVersion, swVersion,
|
|
||||||
getValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!gNoSerialNumbers)
|
|
||||||
printf( " part number .............: %05d" _NL
|
|
||||||
" item number .............: %05d" _NL _NL,
|
|
||||||
((getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)),
|
|
||||||
((getValue(CONSOLE, CONSOLE_SN_ITEM_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_ITEM_LO))
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << " ---HAIL to the kings: " << hwVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BCValueManager::onSyncFromDevice()
|
void BCValueManager::onSyncFromDevice()
|
||||||
{
|
{
|
||||||
qDebug() << " ---Syncing";
|
qDebug() << " ---Syncing";
|
||||||
if( _currentDeviceID != BCDevice::ID::Invalid)
|
if( _currentDeviceID != BCDevice::ID::Invalid )
|
||||||
{
|
{
|
||||||
|
if( _valueModels.contains(_currentDeviceID) )
|
||||||
BCValueList& currentList = _valueModels[_currentDeviceID]->getValueList();
|
|
||||||
|
|
||||||
BCValue& value = currentList[4];
|
|
||||||
|
|
||||||
for( const BCValue& value : currentList )
|
|
||||||
{
|
{
|
||||||
qDebug() << " --- value: " << value.label;
|
|
||||||
|
|
||||||
// statt '_transmitter.enqueueValue( value )' entkoppeln
|
BCValueModel* model = _valueModels[_currentDeviceID];
|
||||||
// wir das eleganter über emit valueCreated()
|
BCValueList& currentList = model->getValueList();
|
||||||
|
|
||||||
//_transmitter.enqueueValue( value );
|
//BCValue& value = currentList[4];
|
||||||
emit valueCreated(value);
|
|
||||||
|
|
||||||
emit valueTouched( value.rowInModel );
|
for( const BCValue& value : currentList )
|
||||||
|
{
|
||||||
|
qDebug() << " --- value: " << value.label;
|
||||||
|
|
||||||
processEventsFor(500);
|
// statt '_transmitter.enqueueValueCommand( value )' entkoppeln
|
||||||
//QApplication::processEvents();
|
// wir das eleganter über emit sendValueCommand()
|
||||||
// Thread schlafen lassen (Simulation einer blockierenden Operation)
|
|
||||||
//QThread::msleep(500);
|
|
||||||
|
|
||||||
}
|
//_transmitter.enqueueValueCommand( value );
|
||||||
|
emit sendValueCommand( BC::OpID::ReadValue, value);
|
||||||
|
|
||||||
|
emit valueTouched( value.rowInModel );
|
||||||
|
|
||||||
|
bc::processEventsFor(500);
|
||||||
|
|
||||||
|
//QApplication::processEvents();
|
||||||
|
// Thread schlafen lassen (Simulation einer blockierenden Operation)
|
||||||
|
//QThread::msleep(500);
|
||||||
|
|
||||||
|
}
|
||||||
|
} // if contains
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +178,11 @@ std::optional<BCValueModel*> BCValueManager::getModel(BCDevice::ID deviceID )
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BCTransmitter* BCValueManager::getTransmitter()
|
||||||
|
{
|
||||||
|
return &_transmitter;
|
||||||
|
};
|
||||||
|
|
||||||
void BCValueManager::loadBikeData()
|
void BCValueManager::loadBikeData()
|
||||||
{
|
{
|
||||||
auto printAttrs = [](const QXmlStreamReader& xml)
|
auto printAttrs = [](const QXmlStreamReader& xml)
|
||||||
@@ -229,7 +233,7 @@ void BCValueManager::loadBikeData()
|
|||||||
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType << " : " << deviceID;
|
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType << " : " << deviceID;
|
||||||
|
|
||||||
_currentDeviceID = BCDevice::ID( deviceID.value() );
|
_currentDeviceID = BCDevice::ID( deviceID.value() );
|
||||||
BCValueList parsedValues;
|
BCValueList parsedValues;
|
||||||
loadDeviceData( parsedValues );
|
loadDeviceData( parsedValues );
|
||||||
if( parsedValues.count() )
|
if( parsedValues.count() )
|
||||||
{
|
{
|
||||||
@@ -288,19 +292,16 @@ void BCValueManager::loadDeviceData( BCValueList& parsedValues )
|
|||||||
.ID = id,
|
.ID = id,
|
||||||
.Label = _xml.attributes().value(BCTags::Label).toString(),
|
.Label = _xml.attributes().value(BCTags::Label).toString(),
|
||||||
.Default = _xml.attributes().value(BCTags::Default).toString(),
|
.Default = _xml.attributes().value(BCTags::Default).toString(),
|
||||||
.Current = _xml.attributes().value(BCTags::Current).toString(),
|
|
||||||
.Enabled = _xml.attributes().value(BCTags::Enabled).toString(),
|
|
||||||
.UnitType = _xml.attributes().value(BCTags::UnitType).toString(),
|
.UnitType = _xml.attributes().value(BCTags::UnitType).toString(),
|
||||||
.Min = _xml.attributes().value(BCTags::Min).toString(),
|
|
||||||
.Max = _xml.attributes().value(BCTags::Max).toString(),
|
|
||||||
.Factor = _xml.attributes().value(BCTags::Factor).toString()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// __fix! können ungültige werte erzeugt werden ?
|
// __fix! können ungültige werte erzeugt werden ?
|
||||||
//BCValue newValue = BCValue::makeValue( _currentDeviceID, params );
|
//BCValue newValue = BCValue::makeValue( _currentDeviceID, params );
|
||||||
//if(newValue)
|
//if(newValue)
|
||||||
// parsedValues.push_back( newValue );
|
// parsedValues.push_back( newValue );
|
||||||
parsedValues.push_back( makeValue( _currentDeviceID, params ) );
|
std::optional<BCValue> newValue = makeValue( _currentDeviceID, params );
|
||||||
|
if(newValue)
|
||||||
|
parsedValues.push_back( *newValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
//printAttrs (_xml);
|
//printAttrs (_xml);
|
||||||
@@ -308,48 +309,57 @@ void BCValueManager::loadDeviceData( BCValueList& parsedValues )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BCValueManager::loadTypeData()
|
std::optional<BCValue> BCValueManager::makeValue( BCDevice::ID deviceID, const BCValueParams& params )
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Invalid = 0x0,
|
auto setIfExists = [&]( QStringView source, optDouble& target )
|
||||||
"Text"
|
{
|
||||||
"Number"
|
if( !source.isEmpty() )
|
||||||
"Float"
|
{
|
||||||
"Percent"
|
bool ok;
|
||||||
"KWh"
|
double testVal = source.toDouble(&ok);
|
||||||
"Watt"
|
if (ok)
|
||||||
"Km"
|
target = testVal;
|
||||||
"Kmh"
|
}
|
||||||
"Mm"
|
};
|
||||||
"Sec"
|
*/
|
||||||
"SoC"
|
|
||||||
"Odo"
|
static QMetaEnum s_bcValueEnum{QMetaEnum::fromType<BC::ID>()};
|
||||||
"Date"
|
|
||||||
|
/*
|
||||||
|
Wir brauchen:
|
||||||
|
- einen gültige ID String um die enum ID herauszufinden.
|
||||||
|
- einen gültige UnitType String um den ValueType herauszufinden.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
//_valueTypes.insert( { BCValueType::TypeID::Invalid, "Invalid" } );
|
|
||||||
|
|
||||||
_valueTypes.insert( "Invalid", { BCValueType::TypeID::Invalid, "Invalid" } );
|
std::optional<BCValue> newValue;
|
||||||
_valueTypes.insert( "Text", { BCValueType::TypeID::Text } );
|
|
||||||
_valueTypes.insert( "Number", { BCValueType::TypeID::Number } );
|
|
||||||
|
|
||||||
_valueTypes.insert( "Float", { BCValueType::TypeID::Float, "", 1.5625} );
|
std::optional<quint64> IDVal = s_bcValueEnum.keyToValue64( params.ID.toLatin1().constData() );
|
||||||
_valueTypes.insert( "Percent",{ BCValueType::TypeID::Percent, "%", 1.5625 } );
|
if( IDVal.has_value() )
|
||||||
_valueTypes.insert( "KWh", { BCValueType::TypeID::KWh, "kwh", 1.5625 } );
|
{
|
||||||
_valueTypes.insert( "Watt", { BCValueType::TypeID::Watt, "w", 1.5625 } );
|
if( _valueTypes.contains( params.UnitType ) )
|
||||||
_valueTypes.insert( "Km", { BCValueType::TypeID::Km, "km", 1.5625 } );
|
{
|
||||||
_valueTypes.insert( "Kmh", { BCValueType::TypeID::Kmh, "km/h", 0.1 } );
|
|
||||||
_valueTypes.insert( "Mm", { BCValueType::TypeID::Mm, "mm", 1.5625 } );
|
|
||||||
_valueTypes.insert( "Sec", { BCValueType::TypeID::Sec, "s", 1.5625 } );
|
|
||||||
_valueTypes.insert( "SoC", { BCValueType::TypeID::SoC, "%", 1.5625 } );
|
|
||||||
_valueTypes.insert( "Odo", { BCValueType::TypeID::Odo, "km", 1.5625 } );
|
|
||||||
_valueTypes.insert( "Assist", { BCValueType::TypeID::Assist, "", 0 ,4 } );
|
|
||||||
_valueTypes.insert( "Assist", { BCValueType::TypeID::AssistFac, "%" } );
|
|
||||||
_valueTypes.insert( "Date", { BCValueType::TypeID::Date } );
|
|
||||||
|
|
||||||
|
const BCValueType& valueType = _valueTypes[params.UnitType];
|
||||||
|
newValue = BCValue( valueType, deviceID, static_cast<BC::ID>(IDVal.value()) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
setIfExists( params.Factor, newValue.factor );
|
||||||
|
setIfExists( params.Min, newValue.min );
|
||||||
|
setIfExists( params.Max, newValue.max );
|
||||||
|
*/
|
||||||
|
newValue->label = params.Label;
|
||||||
|
newValue->defaultValue = params.Default;
|
||||||
|
/*
|
||||||
|
|
||||||
|
//qDebug() << " --- created: " << params.Label;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- NEU: Speichern mit QXmlStreamWriter ---
|
// --- NEU: Speichern mit QXmlStreamWriter ---
|
||||||
@@ -394,43 +404,3 @@ void BCValueManager::saveBikeData()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
BCValue BCValueManager::makeValue( BCDevice::ID deviceID, const BCValueParams& params )
|
|
||||||
{
|
|
||||||
|
|
||||||
auto setIfExists = [&]( QStringView source, optDouble& target )
|
|
||||||
{
|
|
||||||
if( !source.isEmpty() )
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
double testVal = source.toDouble(&ok);
|
|
||||||
if (ok)
|
|
||||||
target = testVal;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static QMetaEnum s_bcValueEnum{QMetaEnum::fromType<BC::ID>()};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Wir brauchen:
|
|
||||||
- eine gültige ID
|
|
||||||
|
|
||||||
*/
|
|
||||||
BCValue newValue{};
|
|
||||||
|
|
||||||
auto IDVal = s_bcValueEnum.keyToValue64( params.ID.toLatin1().constData() );
|
|
||||||
if( IDVal.has_value() )
|
|
||||||
{
|
|
||||||
newValue = BCValue( deviceID, BC::ID( IDVal.value() ) );
|
|
||||||
/*
|
|
||||||
setIfExists( params.Factor, newValue.factor );
|
|
||||||
setIfExists( params.Min, newValue.min );
|
|
||||||
setIfExists( params.Max, newValue.max );
|
|
||||||
*/
|
|
||||||
newValue.defaultValue.setValue( params.Label );
|
|
||||||
newValue.value.setValue( params.Current );
|
|
||||||
newValue.label = params.Label;
|
|
||||||
//qDebug() << " --- created: " << params.Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newValue;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <bcdatamodel.h>
|
#include <bcvaluemodel.h>
|
||||||
#include <bccandrivertinycan.h>
|
|
||||||
#include <bctransmitter.h>
|
#include <bctransmitter.h>
|
||||||
|
|
||||||
class BCValueManager : public QObject
|
class BCValueManager : public QObject
|
||||||
@@ -51,20 +51,20 @@ public:
|
|||||||
virtual ~BCValueManager();
|
virtual ~BCValueManager();
|
||||||
|
|
||||||
std::optional<BCValueModel*> getModel(BCDevice::ID deviceID );
|
std::optional<BCValueModel*> getModel(BCDevice::ID deviceID );
|
||||||
|
BCTransmitter* getTransmitter();
|
||||||
|
|
||||||
BCValue makeValue(BCDevice::ID deviceID, const BCValueParams& params );
|
std::optional<BCValue> makeValue( BCDevice::ID deviceID, const BCValueParams& params );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void loadBikeData();
|
void loadBikeData();
|
||||||
void saveBikeData();
|
void saveBikeData();
|
||||||
void onToggleConnectionState( bool connect );
|
|
||||||
void onSyncFromDevice();
|
void onSyncFromDevice();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
// Internes Signal, um Daten an den Worker Thread zu senden
|
// Internes Signal, um Daten an den Worker Thread zu senden
|
||||||
void valueCreated(const BCValue& cmd);
|
void sendValueCommand( BC::OpID, const BCValue& cmd);
|
||||||
//void valuedTouched(const BCValue& cmd);
|
//void valuedTouched(const BCValue& cmd);
|
||||||
void valueTouched(int rowInModel );
|
void valueTouched(int rowInModel );
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ private slots:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void loadTypeData();
|
void createValueTypes();
|
||||||
void loadDeviceData( BCValueList& parsedValues );
|
void loadDeviceData( BCValueList& parsedValues );
|
||||||
|
|
||||||
using BCDeviceModels = QMap<BCDevice::ID, BCValueModel*>;
|
using BCDeviceModels = QMap<BCDevice::ID, BCValueModel*>;
|
||||||
@@ -88,8 +88,6 @@ protected:
|
|||||||
BCDevice::ID _currentDeviceID{BCDevice::ID::Invalid};
|
BCDevice::ID _currentDeviceID{BCDevice::ID::Invalid};
|
||||||
QMetaEnum _bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
QMetaEnum _bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
||||||
|
|
||||||
BCCanDriverTinyCan _canDriver;
|
|
||||||
|
|
||||||
QThread _worker;
|
QThread _worker;
|
||||||
BCTransmitter _transmitter;
|
BCTransmitter _transmitter;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <bcdatamodel.h>
|
#include <bcvaluemodel.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -77,21 +77,26 @@ QVariant BCValueModel::data(const QModelIndex& index, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Qt::ItemFlags BCValueModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags BCValueModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid()) return Qt::NoItemFlags;
|
if (!index.isValid())
|
||||||
// ItemIsEditable ist Pflicht für Persistent Editors
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
|
return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BCValueModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
bool BCValueModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
if (index.isValid() && role == Qt::EditRole) {
|
if (index.isValid() && role == Qt::EditRole)
|
||||||
|
{
|
||||||
BCValue item = _valueList[index.row()];
|
BCValue item = _valueList[index.row()];
|
||||||
|
|
||||||
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
||||||
// Checken ob Int oder Double
|
// Checken ob Int oder Double
|
||||||
if (value.canConvert<double>()) {
|
if (value.canConvert<double>())
|
||||||
|
{
|
||||||
item.value = value;
|
item.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCDATAMODEL_H
|
#ifndef BCVALUEMODEL_H
|
||||||
#define BCDATAMODEL_H
|
#define BCVALUEMODEL_H
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
@@ -62,4 +62,4 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCDATAMODEL_H
|
#endif // BCVALUEMODEL_H
|
||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
<Device Type="Console">
|
<Device Type="Console">
|
||||||
|
|
||||||
<Value ID='Cons_Rev_Hw' Label='Hardware Version' Default='' />
|
<Value ID='Cons_Rev_Hw' Label='Hardware Version' Default='' UnitType='Byte' />
|
||||||
<Value ID='Cons_Rev_Sw' Label='Software Version' Default='' />
|
<Value ID='Cons_Rev_Sw' Label='Software Version' Default='' UnitType='Byte' />
|
||||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' Default='' />
|
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' Default='' UnitType='Word'/>
|
||||||
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' Default='' />
|
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' Default='' UnitType='Word' />
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Default='' UnitType='Assist' />
|
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Default='' UnitType='Assist' />
|
||||||
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Default='' UnitType='Percent' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Default='' UnitType='Percent' Factor='1.5625'/>
|
||||||
@@ -15,17 +15,17 @@
|
|||||||
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Default='' UnitType='Percent' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Default='' UnitType='Percent' Factor='1.5625'/>
|
||||||
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' Default='' UnitType='Percent' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' Default='' UnitType='Percent' Factor='1.5625'/>
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' Default='' />
|
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' Default='' UnitType='Byte' />
|
||||||
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' Default='' UnitType='kmh' Factor='0.1'/>
|
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' Default='' UnitType='kmh' Factor='0.1'/>
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' Default='' />
|
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' Default='' UnitType='Byte' />
|
||||||
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' Default='' />
|
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' Default='' UnitType='kmh'/>
|
||||||
|
|
||||||
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' Default='' />
|
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' Default='' UnitType='Byte'/>
|
||||||
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' Default='' UnitType='kmh' Factor='0.1'/>
|
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' Default='' UnitType='kmh' Factor='0.1'/>
|
||||||
|
|
||||||
<Value ID='Cons_Geometry_Circ_Hi' Label='Wheel Circumference' Default='' UnitType='mm' />
|
<Value ID='Cons_Geometry_Circ_Hi' Label='Wheel Circumference' Default='' UnitType='mm' />
|
||||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' Default='' UnitType='Percent' Factor='1.5625' />
|
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' Default='' UnitType='Percent' Factor='1.5625' />
|
||||||
|
|
||||||
</Device>
|
</Device>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user