Skip to content

Commit

Permalink
- Device listing workz
Browse files Browse the repository at this point in the history
- ATM broken figuring out exposing the availabledevicesmodel to QML
properly
  • Loading branch information
martonmiklos committed Apr 2, 2021
1 parent f9e81b4 commit 24cc6ce
Show file tree
Hide file tree
Showing 16 changed files with 472 additions and 110 deletions.
7 changes: 3 additions & 4 deletions abstract_rc_car.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ class AbstractRC_Car : public QObject
* @brief setThrottle
* @param throttle -1 to 1 range
*/
virtual void setThrottle(float throttle) = 0;
Q_INVOKABLE virtual void setThrottle(float throttle) = 0;

/**
* @brief setSteer
* @param steer
*/
virtual void setSteer(float steer) = 0;
Q_INVOKABLE virtual void setSteer(float steer) = 0;

/**
* @brief batteryVoltage
Expand All @@ -44,8 +44,7 @@ class AbstractRC_Car : public QObject
virtual bool isFeatureSupported(Feature feature) const = 0;
virtual bool setFeature(Feature feature, const QVariant &value) = 0;

virtual QString imagePath() const = 0;

virtual QString name() const = 0;
signals:
void batteryVoltageUpdated();
void connectionStateChanged(ConnectionState oldState, ConnectionState newState);
Expand Down
126 changes: 106 additions & 20 deletions availabledevicesmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,132 @@
#include "availabledevicesmodel.h"

#include "shell_rc_car.h"

AvailableDevicesModel::AvailableDevicesModel(QObject *parent)
: QAbstractItemModel(parent)
: QAbstractListModel(parent)
{
//! [les-devicediscovery-1]
m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
//discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
connect(m_discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
this, SLOT(deviceDiscovered(const QBluetoothDeviceInfo&)));
connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(deviceScanFinished()));
}

QVariant AvailableDevicesModel::headerData(int section, Qt::Orientation orientation, int role) const
int AvailableDevicesModel::rowCount(const QModelIndex &parent) const
{
// FIXME: Implement me!
Q_UNUSED(parent)
return m_devices.count();
}

QModelIndex AvailableDevicesModel::index(int row, int column, const QModelIndex &parent) const
int AvailableDevicesModel::columnCount(const QModelIndex &parent) const
{
// FIXME: Implement me!
Q_UNUSED(parent)
return 1;
}

QModelIndex AvailableDevicesModel::parent(const QModelIndex &index) const
QVariant AvailableDevicesModel::data(const QModelIndex &index, int role) const
{
// FIXME: Implement me!
if (!index.isValid())
return QVariant();

switch (static_cast<Role>(role)) {
case AvailableDevicesModel::Name:
return m_devices.at(index.row()).name();
case AvailableDevicesModel::TypeName:
return m_devices.at(index.row()).typeName;
case AvailableDevicesModel::ImagePath:
return m_devices.at(index.row()).imagePath;
case AvailableDevicesModel::Index:
return index.row();
}
return QVariant();
}

int AvailableDevicesModel::rowCount(const QModelIndex &parent) const
void AvailableDevicesModel::detectDevices()
{
if (!parent.isValid())
return 0;
beginResetModel();
endResetModel();
m_devices.clear();
setScanInProgress(true);
m_discoveryAgent->start();
}

// FIXME: Implement me!
void AvailableDevicesModel::deviceDiscovered(const QBluetoothDeviceInfo & info)
{
if (Shell_RC_Car::isDevice(info)) {
DetectedDevice d;
d.info = info;
d.typeName = tr("Shell Bluetooth RC car");
d.imagePath = Shell_RC_Car::imagePath();
d.type = Shell;
beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count() + 1);
m_devices.append(d);
endInsertRows();
}
}

int AvailableDevicesModel::columnCount(const QModelIndex &parent) const
void AvailableDevicesModel::deviceScanFinished()
{
if (!parent.isValid())
return 0;
setScanInProgress(false);
}

// FIXME: Implement me!
void AvailableDevicesModel::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
{
setScanInProgress(false);
}

QVariant AvailableDevicesModel::data(const QModelIndex &index, int role) const
void AvailableDevicesModel::setScanInProgress(bool scanInProgress)
{
if (!index.isValid())
return QVariant();
if (m_scanInProgress != scanInProgress) {
m_scanInProgress = scanInProgress;
emit scanStateChanged();
}
}

// FIXME: Implement me!
return QVariant();
AbstractRC_Car *AvailableDevicesModel::currentDevice() const
{
return m_currentDevice;
}

QObject *AvailableDevicesModel::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)

static AvailableDevicesModel instance;
return &instance;
}

bool AvailableDevicesModel::scanInProgress() const
{
return m_scanInProgress;
}

QHash<int, QByteArray> AvailableDevicesModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[TypeName] = QByteArrayLiteral("TypeName");
roles[ImagePath] = QByteArrayLiteral("ImagePath");
roles[Name] = QByteArrayLiteral("Name");
roles[Index] = QByteArrayLiteral("Index");
return roles;
}

void AvailableDevicesModel::useDevice(int deviceIndex)
{
if (deviceIndex < m_devices.count()) {
if (m_currentDevice) {
delete m_currentDevice;
}
switch (m_devices.at(deviceIndex).type) {
case Shell:
auto shell = new Shell_RC_Car(this);
shell->connectToDevice(m_devices.at(deviceIndex).info);
m_currentDevice = shell;
break;
}
}
}
70 changes: 57 additions & 13 deletions availabledevicesmodel.h
Original file line number Diff line number Diff line change
@@ -1,29 +1,73 @@
#ifndef AVAILABLEDEVICESMODEL_H
#define AVAILABLEDEVICESMODEL_H
#pragma once

#include <QAbstractItemModel>
#include "abstract_rc_car.h"

class AvailableDevicesModel : public QAbstractItemModel
#include <QAbstractListModel>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QLowEnergyController>
#include <QQmlEngine>

class AvailableDevicesModel : public QAbstractListModel
{
Q_OBJECT

Q_PROPERTY(bool scanInProgress READ scanInProgress NOTIFY scanStateChanged)
public:
explicit AvailableDevicesModel(QObject *parent = nullptr);
enum Role {
Name = Qt::UserRole + 1,
TypeName,
ImagePath,
Index
};

// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
enum DeviceType {
Shell,
};

// Basic functionality:
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
class DetectedDevice {
public:
DetectedDevice() = default;
QString imagePath, typeName;
QBluetoothDeviceInfo info;
DeviceType type;
QString name() const
{
return info.name();
}
};

explicit AvailableDevicesModel(QObject *parent = nullptr);

int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

Q_INVOKABLE void detectDevices();

bool scanInProgress() const;
QHash<int, QByteArray> roleNames() const override;

Q_INVOKABLE void useDevice(int deviceIndex);

Q_INVOKABLE AbstractRC_Car *currentDevice() const;

static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);

private slots:
// QBluetoothDeviceDiscoveryAgent related
void deviceDiscovered(const QBluetoothDeviceInfo&);
void deviceScanFinished();
void deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error);

Q_SIGNALS:
void scanStateChanged();

private:
void setScanInProgress(bool scanInProgress);

QBluetoothDeviceDiscoveryAgent *m_discoveryAgent = nullptr;
QList<DetectedDevice> m_devices;
bool m_scanInProgress = false;
AbstractRC_Car *m_currentDevice = nullptr;
};

#endif // AVAILABLEDEVICESMODEL_H
53 changes: 53 additions & 0 deletions ble_rc_car.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,56 @@ BLE_RC_Car::BLE_RC_Car(QObject *parent) :
{

}

bool BLE_RC_Car::connectToDevice(const QBluetoothDeviceInfo &info)
{
if (m_controller) {
disconnect(m_controller, nullptr, this, nullptr);
m_controller->disconnectFromDevice();
m_controller->deleteLater();
}
m_controller = new QLowEnergyController(info);
connect(m_controller, &QLowEnergyController::connected, this, &BLE_RC_Car::deviceConnected);
connect(m_controller, &QLowEnergyController::disconnected, this, &BLE_RC_Car::deviceDisconnected);


connect(m_controller, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(errorReceived(QLowEnergyController::Error)));

connect(m_controller, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(addLowEnergyService(QBluetoothUuid)));
connect(m_controller, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
m_controller->setRemoteAddressType(QLowEnergyController::PublicAddress);
m_controller->connectToDevice();
setConnectionState(Connecting);
return true;
}

void BLE_RC_Car::deviceConnected()
{
m_controller->discoverServices();
}

void BLE_RC_Car::deviceDisconnected()
{
setConnectionState(Disconnected);
}

void BLE_RC_Car::serviceScanDone()
{
setConnectionState(Connected);
}

void BLE_RC_Car::errorReceived(QLowEnergyController::Error error)
{

}

QString BLE_RC_Car::errorString() const
{
return m_errorString;
}



20 changes: 19 additions & 1 deletion ble_rc_car.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,31 @@
#include "abstract_rc_car.h"

#include <QBluetoothDeviceInfo>
#include <QLowEnergyController>

class BLE_RC_Car : public AbstractRC_Car
{
Q_OBJECT
public:
BLE_RC_Car(QObject *parent = nullptr);

virtual bool isDevice(const QBluetoothDeviceInfo & info) = 0;
virtual bool connectToDevice(const QBluetoothDeviceInfo &info);

QString errorString() const;

protected slots:
virtual void send() = 0;

void deviceConnected();
void deviceDisconnected();

virtual void addLowEnergyService(const QBluetoothUuid &uuid) = 0;
virtual void serviceScanDone();

void errorReceived(QLowEnergyController::Error error);

protected:
QLowEnergyController *m_controller = nullptr;
QString m_errorString;
};

38 changes: 37 additions & 1 deletion qml/pages/DiscoveredRCItem.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
import QtQuick 2.0
import Sailfish.Silica 1.0

Item {
ListItem {
id: detectedDevice
property string name : ""
property string typeName : ""
property string image : ""
property int index: -1

onClicked: {
AvailableDevicesModel.useDevice(index)
pageStack.push(Qt.resolvedUrl("DrivePage.qml"))
}

Row {
id: row
Column {
Text {
id: nameText
text: detectedDevice.name
font.pixelSize: Theme.fontSizeLarge
}

Text {
id: typeNameText
text: detectedDevice.typeName
font.pixelSize: Theme.fontSizeSmall
}
width: (detectedDevice.width - row.height - Theme.paddingLarge)
}
Image {
id: name
source: detectedDevice.image
height: row.height
width: row.height
fillMode: Image.PreserveAspectFit
}

}
}
Loading

0 comments on commit 24cc6ce

Please sign in to comment.