Compare commits
2 Commits
4b5518de5d
...
4545bf81c3
| Author | SHA1 | Date | |
|---|---|---|---|
| 4545bf81c3 | |||
| f5ad48faf2 |
117
bcmainwindow.cpp
117
bcmainwindow.cpp
@@ -52,6 +52,9 @@ BCMainWindow::BCMainWindow(QWidget *parent)
|
||||
|
||||
setupUi(this);
|
||||
|
||||
// den pimp-my-ride-button schalten wir vorerst aus.
|
||||
_pimpButton->hide();
|
||||
|
||||
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
||||
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
||||
// wenn das Fenster sichtbar ist.
|
||||
@@ -74,17 +77,6 @@ BCMainWindow::~BCMainWindow()
|
||||
_worker.wait(); // Warten bis Thread wirklich fertig ist
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Setzt den Headerlabel ( == die Device-Bezeichnung )
|
||||
* @param headerLabel Der headerLabel
|
||||
*/
|
||||
|
||||
void BCMainWindow::setHeaderLabel( const QString& headerText)
|
||||
{
|
||||
_headerLabel->setText( " BionxControl: " + headerText );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialisiert alle Komponenten des MainWindows.
|
||||
*/
|
||||
@@ -95,63 +87,62 @@ void BCMainWindow::initMainWindow()
|
||||
// Lambda um die buttons mit ihren Actions zu verbinden
|
||||
auto configureAction = [&]( QToolButton* button, QAction* action, BCDevice::ID deviceID )
|
||||
{
|
||||
|
||||
// Action an den Button binden
|
||||
button->setDefaultAction( action);
|
||||
|
||||
// new way: die DeviceID muss aber explizit vom Lambda eingefanden werden.
|
||||
connect( action, &QAction::triggered, this, [this,deviceID]()
|
||||
{
|
||||
onShowDevicePanel( deviceID );
|
||||
});
|
||||
{
|
||||
onShowDevicePanel( deviceID );
|
||||
});
|
||||
|
||||
if( _devicePanels.contains(deviceID) )
|
||||
{
|
||||
BCDeviceView* currentPanel = _devicePanels[deviceID];
|
||||
// ... und ihre device ID
|
||||
currentPanel->setDeviceID( deviceID );
|
||||
// Wenn ein Device (entspricht einem Datenmodel) fertig eingelesen wurde,
|
||||
// wird es weitergereicht.
|
||||
// Problem: alle Panels bekommen alle Datenmodelle angeboten.
|
||||
connect( &_dataManager, &BCXmlLoader::valueListReady, currentPanel, &BCDeviceView::onValueListReady );
|
||||
}
|
||||
{
|
||||
BCDeviceView* currentPanel = _devicePanels[deviceID];
|
||||
// ... und ihre device ID
|
||||
currentPanel->setDeviceID( deviceID );
|
||||
// Wenn ein Device (entspricht einem Datenmodel) fertig eingelesen wurde,
|
||||
// wird es weitergereicht.
|
||||
// Problem: alle Panels bekommen alle Datenmodelle angeboten.
|
||||
connect( &_dataManager, &BCXmlLoader::valueListReady, currentPanel, &BCDeviceView::onValueListReady );
|
||||
}
|
||||
};
|
||||
|
||||
// Wir wollen die Devices den Views zuordnen können
|
||||
_devicePanels[BCDevice::ID::Console] = _consolePanel;
|
||||
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
||||
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
||||
_devicePanels[BCDevice::ID::Pimp] = _pimpPanel;
|
||||
//_devicePanels[BCDevice::ID::Pimp] = _pimpPanel;
|
||||
|
||||
// Die actions an die Buttons binden
|
||||
// Die actions an die Buttons binden
|
||||
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
||||
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
|
||||
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
||||
configureAction(_pimpButton, _pimpAction, BCDevice::ID::Pimp );
|
||||
//configureAction(_pimpButton, _pimpAction, BCDevice::ID::Pimp );
|
||||
|
||||
/*
|
||||
bool m_isDarkMode = false;
|
||||
QString icon = m_isDarkMode ? "☀️" : "🌙";
|
||||
fitzeButton->setText(icon);
|
||||
|
||||
QString style = QString(
|
||||
"QPushButton {"
|
||||
" background-color: %1;"
|
||||
" border: 1px solid %2;"
|
||||
" border-radius: 6px;"
|
||||
" font-size: 12pt;"
|
||||
" padding: 0px;"
|
||||
"}"
|
||||
"QPushButton:hover {"
|
||||
" background-color: %3;"
|
||||
"}"
|
||||
).arg(m_isDarkMode ? "#2B2B2B" : "#FFFFFF")
|
||||
.arg(m_isDarkMode ? "#3F3F3F" : "#E1DFDD")
|
||||
.arg(m_isDarkMode ? "#3A3A3A" : "#F9F9F9");
|
||||
"QPushButton {"
|
||||
" background-color: %1;"
|
||||
" border: 1px solid %2;"
|
||||
" border-radius: 6px;"
|
||||
" font-size: 12pt;"
|
||||
" padding: 0px;"
|
||||
"}"
|
||||
"QPushButton:hover {"
|
||||
" background-color: %3;"
|
||||
"}"
|
||||
).arg(m_isDarkMode ? "#2B2B2B" : "#FFFFFF")
|
||||
.arg(m_isDarkMode ? "#3F3F3F" : "#E1DFDD")
|
||||
.arg(m_isDarkMode ? "#3A3A3A" : "#F9F9F9");
|
||||
|
||||
fitzeButton->setStyleSheet(style);
|
||||
|
||||
// besser: model::emit dataChanged
|
||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||
*/
|
||||
// besser: model::emit dataChanged
|
||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleConnectionState );
|
||||
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
||||
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
||||
@@ -161,20 +152,25 @@ void BCMainWindow::initMainWindow()
|
||||
|
||||
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::enqueueValue);
|
||||
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
||||
|
||||
// transmitter starten
|
||||
_worker.start();
|
||||
|
||||
|
||||
|
||||
// die Daten des eBikes laden
|
||||
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
||||
_consoleAction->trigger();
|
||||
//_consoleAction->trigger();
|
||||
_batteryAction->trigger();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --- STATUSBAR SETUP ---
|
||||
void BCMainWindow::initStatusBar()
|
||||
{
|
||||
// __fix
|
||||
QStatusBar *statBar = statusBar();
|
||||
|
||||
// Optional: Normale Nachricht links
|
||||
// Optional: Normale Nachricht links
|
||||
statBar->showMessage("Ready");
|
||||
|
||||
// 1. Unseren Switcher erstellen
|
||||
@@ -199,6 +195,29 @@ void BCMainWindow::initMainWindow()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Setzt den Headerlabel ( == die Device-Bezeichnung )
|
||||
* @param headerLabel Der headerLabel
|
||||
*/
|
||||
|
||||
void BCMainWindow::setHeaderLabel( const QString& headerText)
|
||||
{
|
||||
_headerLabel->setText( " BionxControl: " + headerText );
|
||||
}
|
||||
|
||||
|
||||
void BCMainWindow::autoConnect()
|
||||
{
|
||||
// __fix!
|
||||
// if( !connect)
|
||||
// fallBack
|
||||
}
|
||||
|
||||
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
|
||||
{
|
||||
qDebug() << " --- on DriverStatusChanged: " << state << ":" << message;
|
||||
}
|
||||
|
||||
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
|
||||
{
|
||||
qDebug() << " --- onShowDevicePanel:" << deviceID;
|
||||
|
||||
@@ -56,6 +56,7 @@ 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 Runner
|
||||
void onValueUpdated( BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue="" );
|
||||
@@ -69,6 +70,8 @@ signals:
|
||||
protected:
|
||||
|
||||
void initMainWindow();
|
||||
void initStatusBar();
|
||||
void autoConnect();
|
||||
|
||||
BCXmlLoader _dataManager;
|
||||
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
BCTransmitter::BCTransmitter(QObject *parent)
|
||||
: QObject(parent), _isBusy(false)
|
||||
{
|
||||
_canDriver = new BCDriverTinyCan{this};
|
||||
//_canDriver = new BCDriverDummy{this};
|
||||
//_canDriver = new BCDriverTinyCan{this};
|
||||
_canDriver = new BCDriverDummy{this};
|
||||
// forward driver state
|
||||
connect( _canDriver, &BCDriver::driverStateChanged, this, &BCTransmitter::driverStateChanged );
|
||||
}
|
||||
|
||||
|
||||
@@ -82,11 +84,14 @@ void BCTransmitter::enqueueValue( BCValuePtrConst value)
|
||||
// invokeMethod mit QueuedConnection entkoppelt den Aufruf,
|
||||
// damit enqueueValue sofort zurückkehrt (non-blocking für den Aufrufer).
|
||||
|
||||
//QMetaObject::invokeMethod(this, "processValue", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "processValue", Qt::QueuedConnection);
|
||||
|
||||
/*
|
||||
QMetaObject::invokeMethod(this, [this]()
|
||||
{
|
||||
processValue();
|
||||
}, Qt::QueuedConnection );
|
||||
*/
|
||||
}
|
||||
|
||||
void BCTransmitter::processValue()
|
||||
@@ -114,13 +119,15 @@ void BCTransmitter::processValue()
|
||||
const BCValue& value = *(valuePtr.get());
|
||||
|
||||
// Value ist 'under construction'
|
||||
//emit valueUpdated( val.deviceID, val.indexRow, BCValue::State::Locked );
|
||||
|
||||
//emit valueUpdated( value.deviceID, value.indexRow, BCValue::State::Locked );
|
||||
|
||||
const BCValueType& valueType = *value.valueType;
|
||||
uint32_t devID = static_cast<uint32_t>(value.deviceID);
|
||||
uint8_t regID = static_cast<uint8_t> (value.registerID);
|
||||
|
||||
QString newVisibleValue;
|
||||
BCValue::State newState = BCValue::State::NoState;
|
||||
|
||||
if(value.state.testFlag( BCValue::State::WriteMe ) )
|
||||
{
|
||||
|
||||
@@ -135,11 +142,18 @@ void BCTransmitter::processValue()
|
||||
// wir sind hier im anderen thread! nicht einfach so reinschreiben, nur lesen
|
||||
TransmitResult result = valueType.readValueFunc( *this, devID, regID );
|
||||
if( result.has_value() )
|
||||
{
|
||||
newVisibleValue = valueType.formatValue( result.value() );
|
||||
//emit valueUpdated( value.deviceID, value.indexRow, BCValue::State::InSync, result );
|
||||
newState = BCValue::State::InSync;
|
||||
}
|
||||
else
|
||||
{
|
||||
newState = BCValue::State::Failed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// emit valueUpdated( value->deviceID, value->indexRow, BCValue::State::InSync, "fitze!");
|
||||
emit valueUpdated( value.deviceID, value.indexRow, newState, newVisibleValue );
|
||||
|
||||
// __fix
|
||||
bc::processEventsFor(50);
|
||||
|
||||
@@ -86,6 +86,7 @@ private:
|
||||
QMutex _mutex;
|
||||
std::atomic<bool> _isBusy{ false };
|
||||
|
||||
// __fix! set two
|
||||
BCDriver* _canDriver{};
|
||||
|
||||
};
|
||||
|
||||
@@ -102,6 +102,7 @@ BCValueType::BCValueType()
|
||||
|
||||
}
|
||||
|
||||
|
||||
BCValueType::BCValueType(QString unitKey_, QString unitLabel_, double factor_, optDouble min_, optDouble max_ )
|
||||
: unitLabel{unitLabel_}, factor{factor_}, min{min_}, max{max_}
|
||||
{
|
||||
@@ -110,28 +111,6 @@ BCValueType::BCValueType(QString unitKey_, QString unitLabel_, double factor_, o
|
||||
}
|
||||
|
||||
|
||||
QString BCValueType::readRawValueX(const BCAbstractTransmitter& transmitter , const BCValue& value) const
|
||||
{
|
||||
qDebug() << " --- READ X!";
|
||||
/*
|
||||
uint32_t devID = static_cast<uint32_t>(deviceID);
|
||||
uint8_t regID = static_cast<uint8_t> (registerID);
|
||||
|
||||
// wir sind hier im anderen thread! nicht einfach so reinschreiben, nur lesen
|
||||
if( valueType->readValueFunc )
|
||||
{
|
||||
uint32_t result = valueType->readValueFunc( transmitter, devID, regID );
|
||||
return valueType->formatValue( result );
|
||||
}
|
||||
*/
|
||||
return QString();
|
||||
}
|
||||
|
||||
void BCValueType::writeRawValueX( const BCAbstractTransmitter& transmitter, const BCValue& value ) const
|
||||
{
|
||||
qDebug() << " --- WRITE X!";
|
||||
}
|
||||
|
||||
QString BCValueType::formatValue( uint32_t value ) const
|
||||
{
|
||||
if( factor == 1 )
|
||||
@@ -147,17 +126,20 @@ std::optional<ReadValueFunc> BCValueType::fetchReadValueFunction( const QString&
|
||||
{
|
||||
{ "Byte", readByteValue },
|
||||
{ "Word", readWordValue },
|
||||
{ "Assist", readByteValue },
|
||||
|
||||
{ "Kmh", readByteValue },
|
||||
{ "Percent",readByteValue },
|
||||
{ "KWh", readByteValue },
|
||||
{ "Watt", readByteValue },
|
||||
{ "Km", readByteValue },
|
||||
{ "Kmh", readByteValue },
|
||||
|
||||
{ "Mm", readByteValue },
|
||||
{ "Sec", readByteValue },
|
||||
{ "Degree", readByteValue },
|
||||
{ "SoC", readByteValue },
|
||||
{ "Odo", readByteValue },
|
||||
{ "Assist", readByteValue }
|
||||
|
||||
};
|
||||
|
||||
if( !s_bcReadValueFunctions.contains( unitTypeKey ) )
|
||||
@@ -170,11 +152,12 @@ std::optional<BCValueType*> BCValueType::fetchValueType( const QString& unitType
|
||||
{
|
||||
static QHash<QString,BCValueType*> s_bcDataTypes
|
||||
{
|
||||
{ "Byte", new BCValueType( "Byte", "", 1.5625F) },
|
||||
{ "Word", new BCValueType( "Word", "", 1.5625F) }
|
||||
{ "Byte", new BCValueType( "Byte", "", 1.5625F) },
|
||||
{ "Word", new BCValueType( "Word", "", 1.5625F) },
|
||||
{ "Percent", new BCValueType( "Byte", "%", 1.5625 ) },
|
||||
{ "AssInit", new BCValueType( "Byte", "", 1.0, 0 ,4 ) },
|
||||
{ "Assist", new BCValueType( "Byte", "%", 0,400 ) }
|
||||
/*
|
||||
{ "Float", new BCValueType( "", 1.5625F) },
|
||||
{ "Percent",new BCValueType( "%", 1.5625 ) },
|
||||
{ "KWh", new BCValueType( "kwh", 1.5625 ) },
|
||||
{ "Watt", new BCValueType( "w", 1.5625 ) },
|
||||
{ "Km", new BCValueType( "km", 1.5625 ) },
|
||||
@@ -184,7 +167,7 @@ std::optional<BCValueType*> BCValueType::fetchValueType( const QString& unitType
|
||||
{ "Degree", new BCValueType( "°C", 1.0 ) },
|
||||
{ "SoC", new BCValueType( "%", 1.5625 ) },
|
||||
{ "Odo", new BCValueType( "km", 1.5625 ) },
|
||||
{ "Assist", new BCValueType( "", 0 ,4 ) },
|
||||
|
||||
{ "Assist", new BCValueType( "%" ) },
|
||||
*/
|
||||
};
|
||||
|
||||
@@ -76,9 +76,6 @@ public:
|
||||
BCValueType();
|
||||
BCValueType( QString unitKey_, QString unitLabel_, double factor_= 1.0, optDouble min_=std::nullopt, optDouble max_= std::nullopt );
|
||||
|
||||
QString readRawValueX ( const BCAbstractTransmitter& transmitter, const BCValue& value ) const;
|
||||
void writeRawValueX( const BCAbstractTransmitter& transmitter, const BCValue& value ) const;
|
||||
|
||||
virtual QString formatValue( uint32_t value ) const;
|
||||
|
||||
QString unitLabel;
|
||||
@@ -86,6 +83,8 @@ public:
|
||||
optDouble min;
|
||||
optDouble max;
|
||||
ReadValueFunc readValueFunc;
|
||||
//ReadValueFunc readValueFunc;
|
||||
|
||||
|
||||
static std::optional<BCValueType*> fetchValueType( const QString& unitTypeKey );
|
||||
static std::optional<ReadValueFunc> fetchReadValueFunction( const QString& unitTypeKey );
|
||||
|
||||
@@ -103,16 +103,6 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
||||
printAttrs (_xml);
|
||||
// Wir wollen die Device-ID aus dem XML Tag ermitteln
|
||||
const char* deviceKey = _xml.attributes().value("Type"_L1).toLatin1().constData();
|
||||
/*
|
||||
auto optDeviceID = bcDeviceEnum.keyToValue64(deviceKey);
|
||||
//_currentDeviceID = BCDevice::ID( deviceID.value_or( BCDevice::ID::Invalid ) );
|
||||
if( optDeviceID.has_value())
|
||||
{
|
||||
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType << " : " << optDeviceID;
|
||||
BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID.value() );
|
||||
loadXmlBikeDeviceData(currentDeviceID);
|
||||
}
|
||||
*/
|
||||
bool ok;
|
||||
auto optDeviceID = bcDeviceEnum.keyToValue(deviceKey,&ok);
|
||||
//_currentDeviceID = BCDevice::ID( deviceID.value_or( BCDevice::ID::Invalid ) );
|
||||
|
||||
BIN
doc/BigXionFlasher USB V 0.docx
Normal file
BIN
doc/BigXionFlasher USB V 0.docx
Normal file
Binary file not shown.
45
doc/challenges.txt
Normal file
45
doc/challenges.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
Challenges
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
@@ -3,53 +3,44 @@
|
||||
<Bike name='franken-wheeler'>
|
||||
|
||||
<Device Type="Console">
|
||||
|
||||
<Value ID='Cons_Rev_Hw' Label='Hardware Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Cons_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' ReadOnly='true' UnitType='Word'/>
|
||||
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' ReadOnly='true' UnitType='Word' />
|
||||
<Value ID='Cons_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' ReadOnly='true' UnitType='Word'/>
|
||||
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' ReadOnly='true' UnitType='Word' />
|
||||
|
||||
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' ReadOnly='true' UnitType='Assist' />
|
||||
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' ReadOnly='false' UnitType='AssInit'/>
|
||||
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' ReadOnly='true' UnitType='Percent' Factor='1.5625'/>
|
||||
|
||||
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' ReadOnly='true' UnitType='kmh' Factor='0.1'/>
|
||||
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' ReadOnly='false' UnitType='Byte' />
|
||||
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' ReadOnly='false' UnitType='Kmh' Factor='0.1'/>
|
||||
|
||||
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' ReadOnly='true' UnitType='kmh'/>
|
||||
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' ReadOnly='true' UnitType='Kmh'/>
|
||||
|
||||
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' ReadOnly='true' UnitType='Byte'/>
|
||||
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' ReadOnly='true' UnitType='kmh' Factor='0.1'/>
|
||||
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' ReadOnly='true' UnitType='kmh' Factor='0.1'/>
|
||||
|
||||
<Value ID='Cons_Geometry_Circ_Hi' Label='Wheel Circumference' ReadOnly='true' UnitType='mm' />
|
||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' ReadOnly='true' UnitType='Percent' Factor='1.5625' />
|
||||
|
||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' ReadOnly='true' UnitType='Percent' Factor='1.5625' />
|
||||
</Device>
|
||||
|
||||
<Device Type="Motor">
|
||||
<Value ID='Motor_Rev_Hw' Label='Hardware Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Motor_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Motor_Status_Temperature' Label='Motor Temperature' ReadOnly='true' UnitType='Degree'/>
|
||||
<Value ID='Motor_Assist_Maxspeed' Label='Motor max. Speed' ReadOnly='true' UnitType='Kmh' />
|
||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Part Number' ReadOnly='true' UnitType='Word'/>
|
||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Serial Number' ReadOnly='true' UnitType='Word' />
|
||||
<Value ID='Motor_Geometry_Circ_Hi' Label='Motor Gemetry' ReadOnly='true' UnitType='Mm' />
|
||||
</Device>
|
||||
|
||||
|
||||
|
||||
|
||||
<Device Type="Battery">
|
||||
<Value ID='Battery_Rev_Hw' Label='Hardware Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Battery_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
</Device>
|
||||
|
||||
<Device Type="Sensor">
|
||||
</Device>
|
||||
<Device Type="Motor">
|
||||
<Value ID='Motor_Rev_Hw' Label='Hardware Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Motor_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Motor_Status_Temperature' Label='Motor Temperature' ReadOnly='true' UnitType='Degree'/>
|
||||
<Value ID='Motor_Assist_Maxspeed' Label='Motor max. Speed' ReadOnly='true' UnitType='Kmh' />
|
||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Part Number' ReadOnly='true' UnitType='Word'/>
|
||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Serial Number' ReadOnly='true' UnitType='Word' />
|
||||
<Value ID='Motor_Geometry_Circ_Hi' Label='Motor Gemetry' ReadOnly='true' UnitType='Mm' />
|
||||
</Device>
|
||||
|
||||
<Device Type="Battery">
|
||||
<Value ID='Battery_Rev_Hw' Label='Hardware Version' ReadOnly='true' UnitType='Byte' />
|
||||
<Value ID='Battery_Rev_Sw' Label='Software Version' ReadOnly='true' UnitType='Byte' />
|
||||
</Device>
|
||||
|
||||
</Bike>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user