修改连接模型。

This commit is contained in:
luocai 2024-08-20 09:29:49 +08:00
parent c9dd35fee8
commit 5adb0d783d
6 changed files with 157 additions and 55 deletions

View File

@ -38,8 +38,9 @@ void Application::setCurrentOpenDoorAreaWay(DeviceConnection::AreaWay way) {
} }
emit currentOpenDoorAreaWayChanged(); emit currentOpenDoorAreaWayChanged();
if (m_device != nullptr) { if (!m_device.expired()) {
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, m_currentOpenDoorAreaPoints); auto device = m_device.lock();
device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, m_currentOpenDoorAreaPoints);
} }
} }
@ -72,9 +73,9 @@ void Application::setCurrentShieldedAreaEnabled(bool enabled) {
m_currentShieldedAreaPoints << QPointF(6, 6) << QPointF(40, 60) << QPointF(590, 6) << QPointF(630, 60); m_currentShieldedAreaPoints << QPointF(6, 6) << QPointF(40, 60) << QPointF(590, 6) << QPointF(630, 60);
emit currentShieldedAreaPointsChanged(); emit currentShieldedAreaPointsChanged();
} }
if (!m_device.expired()) {
if (m_device != nullptr) { auto device = m_device.lock();
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints); device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints);
} }
} }
} }
@ -98,8 +99,9 @@ void Application::setCurrentAntiClipAreaEnabled(bool enabled) {
if (m_currentAntiClipAreaEnabled != enabled) { if (m_currentAntiClipAreaEnabled != enabled) {
m_currentAntiClipAreaEnabled = enabled; m_currentAntiClipAreaEnabled = enabled;
emit currentAntiClipAreaEnabledChanged(); emit currentAntiClipAreaEnabledChanged();
if (m_device != nullptr) { if (!m_device.expired()) {
m_device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints); auto device = m_device.lock();
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints);
} }
} }
} }
@ -116,52 +118,86 @@ void Application::setCurrentAntiClipAreaPoints(const QList<QPointF> &points) {
} }
void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) { void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
if (m_device != nullptr) { if (!m_device.expired()) {
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, points); auto device = m_device.lock();
device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, points);
} }
} }
void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) { void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) {
m_device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points); if (!m_device.expired()) {
auto device = m_device.lock();
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points);
}
} }
void Application::updateShieldedAreaPoints(const QList<QPointF> &points) { void Application::updateShieldedAreaPoints(const QList<QPointF> &points) {
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points); if (!m_device.expired()) {
auto device = m_device.lock();
device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points);
}
} }
void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
const QString &gateway) { const QString &gateway) {
LOG(info) << dhcp; if (!m_device.expired()) {
LOG(info) << ip.toStdString(); auto device = m_device.lock();
if (m_device != nullptr) { device->updateNetworkInfomation(dhcp, ip, netmask, gateway);
m_device->updateNetworkInfomation(dhcp, ip, netmask, gateway);
} }
} }
void Application::connectToDevice(const QString &address) { void Application::connectToDevice(int index) {
if (m_device != nullptr) { if (!m_device.expired()) {
m_device->deleteLater(); auto device = m_device.lock();
} disconnect(device.get(), &DeviceConnection::currentOpenDoorAreaChanged, this,
&Application::onDeviceOpenDoorArea);
m_device = new DeviceConnection(); disconnect(device.get(), &DeviceConnection::currentShieldedAreaChanged, this,
connect(m_device, &DeviceConnection::currentOpenDoorAreaChanged, this, &Application::onDeviceOpenDoorArea); &Application::onDeviceShieldedArea);
connect(m_device, &DeviceConnection::currentShieldedAreaChanged, this, &Application::onDeviceShieldedArea); disconnect(device.get(), &DeviceConnection::currentAntiClipAreaChanged, this,
connect(m_device, &DeviceConnection::currentAntiClipAreaChanged, this, &Application::onDeviceAntiClipArea); &Application::onDeviceAntiClipArea);
connect(m_device, &DeviceConnection::currentNetworkInfomationChanged, this, disconnect(device.get(), &DeviceConnection::currentNetworkInfomationChanged, this,
&Application::onDeviceNetworkInfomation); &Application::onDeviceNetworkInfomation);
m_device->connect(address); device->setH264FrameCallback(DeviceConnection::H264FrameCallback());
m_device->setH264FrameCallback([this](const char *data, uint32_t size) { device->setLiveStreamEnabled(false);
}
auto device = m_devices->device(index);
m_device = device;
connect(device.get(), &DeviceConnection::currentOpenDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
connect(device.get(), &DeviceConnection::currentShieldedAreaChanged, this, &Application::onDeviceShieldedArea);
connect(device.get(), &DeviceConnection::currentAntiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
connect(device.get(), &DeviceConnection::currentNetworkInfomationChanged, this,
&Application::onDeviceNetworkInfomation);
device->setH264FrameCallback([this](const char *data, uint32_t size) {
auto image = m_player->decode((const uint8_t *)data, size); auto image = m_player->decode((const uint8_t *)data, size);
if (image) { if (image) {
m_videoFrameProvider->setImage(*image); m_videoFrameProvider->setImage(*image);
emit newVideoFrame(); emit newVideoFrame();
} }
}); });
device->setLiveStreamEnabled(true);
auto area = device->area();
m_currentOpenDoorAreaWay = area.openDoorAreaWay;
m_currentOpenDoorAreaPoints = area.openDoorArea;
m_currentShieldedAreaEnabled = area.shieldedAreaEnabled;
m_currentShieldedAreaPoints = area.shieldedArea;
m_currentAntiClipAreaEnabled = area.antiClipAreaEnabled;
m_currentAntiClipAreaPoints = area.antiClipArea;
m_currentNetworkInfomation = device->networkInfomation();
emit currentOpenDoorAreaPointsChanged();
emit currentShieldedAreaPointsChanged();
emit currentAntiClipAreaPointsChanged();
emit currentOpenDoorAreaWayChanged();
emit currentShieldedAreaEnabledChanged();
emit currentAntiClipAreaEnabledChanged();
emit currentNetworkInfomationChanged();
} }
void Application::upgradeDevice(const QString &file) { void Application::upgradeDevice(const QString &file) {
if (m_device != nullptr) { if (!m_device.expired()) {
m_device->requestOta(file); auto device = m_device.lock();
device->requestOta(file);
} }
} }

View File

@ -63,7 +63,7 @@ public:
Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points); Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points);
Q_INVOKABLE void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, Q_INVOKABLE void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
const QString &gateway); const QString &gateway);
Q_INVOKABLE void connectToDevice(const QString &address); Q_INVOKABLE void connectToDevice(int index);
Q_INVOKABLE void upgradeDevice(const QString &file); Q_INVOKABLE void upgradeDevice(const QString &file);
int exec(); int exec();
@ -90,7 +90,7 @@ private:
std::shared_ptr<QGuiApplication> m_app; std::shared_ptr<QGuiApplication> m_app;
VideoFrameProvider *m_videoFrameProvider = nullptr; VideoFrameProvider *m_videoFrameProvider = nullptr;
std::shared_ptr<H264Palyer> m_player; std::shared_ptr<H264Palyer> m_player;
DeviceConnection *m_device = nullptr; std::weak_ptr<DeviceConnection> m_device;
DeviceListModel *m_devices = nullptr; DeviceListModel *m_devices = nullptr;
DeviceConnection::AreaWay m_currentOpenDoorAreaWay = DeviceConnection::Diabled; DeviceConnection::AreaWay m_currentOpenDoorAreaWay = DeviceConnection::Diabled;

View File

@ -1,5 +1,6 @@
#include "DeviceListModel.h" #include "DeviceListModel.h"
#include "BoostLog.h" #include "BoostLog.h"
#include "DeviceConnection.h"
#include <QNetworkDatagram> #include <QNetworkDatagram>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QTimer> #include <QTimer>
@ -17,14 +18,20 @@ int DeviceListModel::rowCount(const QModelIndex &parent) const {
QVariant DeviceListModel::data(const QModelIndex &index, int role) const { QVariant DeviceListModel::data(const QModelIndex &index, int role) const {
QVariant ret; QVariant ret;
auto row = index.row(); auto row = index.row();
if (row >= m_devices.size()) {
return ret;
}
auto info = m_devices.at(row)->infomation();
if (role == DeviceIdRole) { if (role == DeviceIdRole) {
ret = m_devices.at(row).deviceId; ret = info.deviceId;
} else if (role == FirmwareVersionRole) { } else if (role == FirmwareVersionRole) {
ret = m_devices.at(row).firmwareVersion; ret = info.firmwareVersion;
} else if (role == SoftwareVersionRole) { } else if (role == SoftwareVersionRole) {
ret = m_devices.at(row).softwareVersion; ret = info.softwareVersion;
} else if (role == IpRole) { } else if (role == IpRole) {
ret = m_devices.at(row).ip; ret = info.ip;
} else if (role == OnlineStatusRole) {
ret = m_devices.at(row)->isConnected();
} }
return ret; return ret;
} }
@ -35,26 +42,40 @@ QHash<int, QByteArray> DeviceListModel::roleNames() const {
roleNames.insert(FirmwareVersionRole, "firmwareVersion"); roleNames.insert(FirmwareVersionRole, "firmwareVersion");
roleNames.insert(SoftwareVersionRole, "softwareVersion"); roleNames.insert(SoftwareVersionRole, "softwareVersion");
roleNames.insert(IpRole, "ip"); roleNames.insert(IpRole, "ip");
roleNames.insert(OnlineStatusRole, "onlineStatus");
return roleNames; return roleNames;
} }
QVariantMap DeviceListModel::get(int index) const { QVariantMap DeviceListModel::get(int index) const {
QVariantMap map; QVariantMap map;
if (index >= 0 && index < m_devices.size()) { if (index >= 0 && index < m_devices.size()) {
map["firmwareVersion"] = m_devices[index].firmwareVersion; auto info = m_devices.at(index)->infomation();
map["softwareVersion"] = m_devices[index].softwareVersion; map["firmwareVersion"] = info.firmwareVersion;
map["deviceId"] = m_devices[index].deviceId; map["softwareVersion"] = info.softwareVersion;
map["ip"] = m_devices[index].ip; map["deviceId"] = info.deviceId;
map["ip"] = info.ip;
map["onlineStatus"] = m_devices.at(index)->isConnected();
} }
return map; return map;
} }
std::shared_ptr<DeviceConnection> DeviceListModel::device(int index) {
std::shared_ptr<DeviceConnection> ret;
if (index < m_devices.size()) {
ret = m_devices.at(index);
}
return ret;
}
void DeviceListModel::startSearchDevice() { void DeviceListModel::startSearchDevice() {
if (m_timerId >= 0) { if (m_timerId >= 0) {
LOG(error) << "app is searching device."; LOG(error) << "app is searching device.";
return; return;
} }
beginResetModel(); beginResetModel();
for (auto &device : m_devices) {
device->deleteLater();
}
m_devices.clear(); m_devices.clear();
endResetModel(); endResetModel();
auto interfaces = QNetworkInterface::allInterfaces(); auto interfaces = QNetworkInterface::allInterfaces();
@ -93,24 +114,58 @@ float DeviceListModel::searchProgress() const {
return static_cast<float>(m_retries) * 100 / RetryCount; return static_cast<float>(m_retries) * 100 / RetryCount;
} }
void DeviceListModel::onDeviceConnected() {
auto device = dynamic_cast<DeviceConnection *>(sender());
auto iterator =
std::find_if(m_devices.cbegin(), m_devices.cend(),
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
if (iterator != m_devices.cend()) {
QList<int> roles;
roles << OnlineStatusRole;
int row = std::distance(m_devices.cbegin(), iterator);
emit dataChanged(index(row), index(row), roles);
LOG(info) << "device " << row << " connected.";
}
}
void DeviceListModel::onDeviceDisconnected() {
auto device = dynamic_cast<DeviceConnection *>(sender());
auto iterator =
std::find_if(m_devices.cbegin(), m_devices.cend(),
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
if (iterator != m_devices.cend()) {
int row = std::distance(m_devices.cbegin(), iterator);
QList<int> roles;
roles << OnlineStatusRole;
emit dataChanged(index(row), index(row), roles);
LOG(info) << "device " << row << " disconnected.";
}
}
void DeviceListModel::onDeviceReplyReadyRead() { void DeviceListModel::onDeviceReplyReadyRead() {
auto udp = dynamic_cast<QUdpSocket *>(sender()); auto udp = dynamic_cast<QUdpSocket *>(sender());
while (udp->hasPendingDatagrams()) { while (udp->hasPendingDatagrams()) {
QNetworkDatagram datagram = udp->receiveDatagram(); QNetworkDatagram datagram = udp->receiveDatagram();
auto replyVale = boost::json::parse(datagram.data().toStdString()); auto replyVale = boost::json::parse(datagram.data().toStdString());
auto &reply = replyVale.as_object(); auto &reply = replyVale.as_object();
DeviceInfomation device; DeviceConnection::Infomation device;
device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string())); device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string()));
device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string())); device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string()));
device.softwareVersion = QString::fromStdString(std::string(reply.at("sw_ver").as_string())); device.softwareVersion = QString::fromStdString(std::string(reply.at("sw_ver").as_string()));
device.ip = datagram.senderAddress().toString(); device.ip = datagram.senderAddress().toString();
auto iterator = std::find_if(m_devices.cbegin(), m_devices.cend(), [&device](const DeviceInfomation &item) { auto iterator = std::find_if(m_devices.cbegin(), m_devices.cend(),
return item.deviceId == device.deviceId; [&device](const std::shared_ptr<DeviceConnection> &item) {
return item->infomation().deviceId == device.deviceId;
}); });
if (iterator == m_devices.cend()) { if (iterator == m_devices.cend()) {
auto connection = std::shared_ptr<DeviceConnection>(new DeviceConnection(),
[](DeviceConnection *self) { self->deleteLater(); });
connect(connection.get(), &DeviceConnection::connected, this, &DeviceListModel::onDeviceConnected);
connect(connection.get(), &DeviceConnection::disconnected, this, &DeviceListModel::onDeviceDisconnected);
connection->connect(device);
beginInsertRows(QModelIndex(), m_devices.size(), m_devices.size()); beginInsertRows(QModelIndex(), m_devices.size(), m_devices.size());
m_devices.push_back(device); m_devices.push_back(connection);
endInsertRows(); endInsertRows();
} }
LOG(info) << "Received datagram from " << datagram.senderAddress().toString().toStdString() << ":" LOG(info) << "Received datagram from " << datagram.senderAddress().toString().toStdString() << ":"
@ -129,8 +184,8 @@ void DeviceListModel::broadcast() {
for (const QNetworkAddressEntry &entry : entries) { for (const QNetworkAddressEntry &entry : entries) {
if (entry.broadcast().toIPv4Address()) { if (entry.broadcast().toIPv4Address()) {
m_broadcastSocket->writeDatagram(datagram, entry.broadcast(), BroadcastPort); m_broadcastSocket->writeDatagram(datagram, entry.broadcast(), BroadcastPort);
LOG(info) << "Broadcasted datagram: " << datagram.toStdString() << " to " // LOG(info) << "Broadcasted datagram: " << datagram.toStdString() << " to "
<< entry.broadcast().toString().toStdString() << ":" << BroadcastPort; // << entry.broadcast().toString().toStdString() << ":" << BroadcastPort;
} }
} }
} }

View File

@ -5,14 +5,7 @@
#include <QQmlEngine> #include <QQmlEngine>
class QUdpSocket; class QUdpSocket;
class DeviceConnection;
class DeviceInfomation {
public:
QString deviceId;
QString softwareVersion;
QString firmwareVersion;
QString ip;
};
class DeviceListModel : public QAbstractListModel { class DeviceListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
@ -30,12 +23,14 @@ public:
FirmwareVersionRole, FirmwareVersionRole,
SoftwareVersionRole, SoftwareVersionRole,
IpRole, IpRole,
OnlineStatusRole,
}; };
DeviceListModel(QObject *parent = nullptr); DeviceListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const final; int rowCount(const QModelIndex &parent = QModelIndex()) const final;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final;
QHash<int, QByteArray> roleNames() const final; QHash<int, QByteArray> roleNames() const final;
Q_INVOKABLE QVariantMap get(int index) const; Q_INVOKABLE QVariantMap get(int index) const;
std::shared_ptr<DeviceConnection> device(int index);
Q_INVOKABLE void startSearchDevice(); Q_INVOKABLE void startSearchDevice();
bool isSearching() const; bool isSearching() const;
float searchProgress() const; float searchProgress() const;
@ -45,13 +40,15 @@ signals:
void searchProgressChanged(); void searchProgressChanged();
protected: protected:
void onDeviceConnected();
void onDeviceDisconnected();
void onDeviceReplyReadyRead(); void onDeviceReplyReadyRead();
void broadcast(); void broadcast();
void stopSearchDevice(); void stopSearchDevice();
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
private: private:
std::vector<DeviceInfomation> m_devices; std::vector<std::shared_ptr<DeviceConnection>> m_devices;
std::list<QUdpSocket *> m_udpSockets; std::list<QUdpSocket *> m_udpSockets;
QUdpSocket *m_broadcastSocket = nullptr; QUdpSocket *m_broadcastSocket = nullptr;
int m_timerId = -1; int m_timerId = -1;

View File

@ -332,9 +332,11 @@ Item {
repeater.model = openDoorAreaPoints repeater.model = openDoorAreaPoints
} }
function onCurrentShieldedAreaPointsChanged() { function onCurrentShieldedAreaPointsChanged() {
shieldedAreaRepeater.model = shieldedAreaPoints
canvas.requestPaint() canvas.requestPaint()
} }
function onCurrentAntiClipAreaPointsChanged() { function onCurrentAntiClipAreaPointsChanged() {
antiAreaRepeater.model = antiClipAreaPoints
canvas.requestPaint() canvas.requestPaint()
} }
function onCurrentOpenDoorAreaWayChanged(){ function onCurrentOpenDoorAreaWayChanged(){

View File

@ -19,6 +19,9 @@ ApplicationWindow {
App.devices.startSearchDevice() App.devices.startSearchDevice()
} }
} }
Text {
text: `: ${deviceList.count}`
}
Row { Row {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Text { Text {
@ -49,12 +52,21 @@ ApplicationWindow {
anchors.fill: parent anchors.fill: parent
spacing: 10 spacing: 10
Text { Text {
anchors.verticalCenter: parent.verticalCenter
text: deviceId text: deviceId
} }
Item {} Item {}
Text { Text {
anchors.verticalCenter: parent.verticalCenter
text: ip text: ip
} }
Rectangle {
anchors.verticalCenter: parent.verticalCenter
color: onlineStatus ? "green":"black"
width: 10
height: 10
radius: 5
}
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -69,7 +81,7 @@ ApplicationWindow {
} }
onCurrentIndexChanged: { onCurrentIndexChanged: {
deviceVersion.text = App.devices.get(deviceList.currentIndex).softwareVersion; deviceVersion.text = App.devices.get(deviceList.currentIndex).softwareVersion;
App.connectToDevice(App.devices.get(deviceList.currentIndex).ip) App.connectToDevice(deviceList.currentIndex)
} }
ProgressBar { ProgressBar {
anchors.left: parent.left anchors.left: parent.left