This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
Michael Zanetti 22dd3fe27d intermediate commit.
Working pretty well now. No cleanup done. some broken menu entries related to
connect.

TBC
2019-02-06 03:00:43 +01:00

228 lines
7.1 KiB
C++

#include "nymeadiscovery.h"
#include "upnpdiscovery.h"
#include "zeroconfdiscovery.h"
#include "bluetoothservicediscovery.h"
#include "connection/awsclient.h"
#include "../nymeahost.h"
#include <QUuid>
#include <QBluetoothUuid>
#include <QUrlQuery>
#include <QSettings>
#include <QNetworkConfigurationManager>
#include <QNetworkSession>
NymeaDiscovery::NymeaDiscovery(QObject *parent) : QObject(parent)
{
m_nymeaHosts = new NymeaHosts(this);
loadFromDisk();
m_upnp = new UpnpDiscovery(m_nymeaHosts, this);
m_zeroConf = new ZeroconfDiscovery(m_nymeaHosts, this);
#ifndef Q_OS_IOS
m_bluetooth = new BluetoothServiceDiscovery(m_nymeaHosts, this);
#endif
m_cloudPollTimer.setInterval(5000);
connect(&m_cloudPollTimer, &QTimer::timeout, this, [this](){
if (m_awsClient && m_awsClient->isLoggedIn()) {
m_awsClient->fetchDevices();
}
});
}
NymeaDiscovery::~NymeaDiscovery()
{
}
bool NymeaDiscovery::discovering() const
{
return m_discovering;
}
void NymeaDiscovery::setDiscovering(bool discovering)
{
if (m_discovering == discovering)
return;
m_discovering = discovering;
// If we have zeroconf skip upnp. ZeroConf will not do an active discovery and if it's available it'll always have good data
if (!m_zeroConf->available()) {
if (discovering) {
m_upnp->discover();
} else {
m_upnp->stopDiscovery();
}
}
if (discovering) {
// If there's no Zeroconf, use UPnP instead
if (!m_zeroConf->available()) {
m_upnp->discover();
}
// Always start Bluetooth discovery if HW is available
if (m_bluetooth) {
m_bluetooth->discover();
}
// start polling cloud
m_cloudPollTimer.start();
// If we're logged in, poll right away
if (m_awsClient && m_awsClient->isLoggedIn()) {
m_awsClient->fetchDevices();
}
} else {
if (!m_zeroConf->available()) {
m_upnp->stopDiscovery();
}
if (m_bluetooth) {
m_bluetooth->stopDiscovery();
}
m_cloudPollTimer.stop();
}
emit discoveringChanged();
}
NymeaHosts *NymeaDiscovery::nymeaHosts() const
{
return m_nymeaHosts;
}
AWSClient *NymeaDiscovery::awsClient() const
{
return m_awsClient;
}
void NymeaDiscovery::setAwsClient(AWSClient *awsClient)
{
if (m_awsClient != awsClient) {
m_awsClient = awsClient;
emit awsClientChanged();
}
if (m_awsClient) {
m_awsClient->fetchDevices();
connect(m_awsClient, &AWSClient::devicesFetched, this, &NymeaDiscovery::syncCloudDevices);
}
}
void NymeaDiscovery::cacheHost(NymeaHost *host)
{
QSettings settings;
settings.beginGroup("HostCache");
settings.remove(host->uuid().toString());
settings.beginGroup(host->uuid().toString());
settings.setValue("name", host->name());
QList<Connection*> connections;
Connection *remoteConnection = host->connections()->bestMatch(Connection::BearerTypeCloud);
if (remoteConnection) {
connections.append(remoteConnection);
}
Connection *lanConnection = host->connections()->bestMatch(Connection::BearerTypeWifi | Connection::BearerTypeEthernet);
if (lanConnection) {
connections.append(lanConnection);
}
Connection *btConnection = host->connections()->bestMatch(Connection::BearerTypeBluetooth);
if (btConnection) {
connections.append(btConnection);
}
int i = 0;
foreach (Connection *connection, connections) {
settings.beginGroup(QString::number(i++));
settings.setValue("url", connection->url());
settings.setValue("bearerType", connection->bearerType());
settings.value("secure", connection->secure());
settings.setValue("displayName", connection->displayName());
settings.endGroup();
}
settings.endGroup();
}
void NymeaDiscovery::syncCloudDevices()
{
for (int i = 0; i < m_awsClient->awsDevices()->rowCount(); i++) {
AWSDevice *d = m_awsClient->awsDevices()->get(i);
NymeaHost *host = m_nymeaHosts->find(d->id());
if (!host) {
host = new NymeaHost();
host->setUuid(d->id());
host->setName(d->name());
qDebug() << "CloudDiscovery: Adding new host:" << host->name() << host->uuid().toString();
m_nymeaHosts->addHost(host);
}
QUrl url;
url.setScheme("cloud");
url.setHost(d->id());
Connection *conn = host->connections()->find(url);
if (!conn) {
conn = new Connection(url, Connection::BearerTypeCloud, true, d->id());
qDebug() << "CloudDiscovery: Adding new connection to host:" << host->name() << conn->url().toString();
host->connections()->addConnection(conn);
}
conn->setOnline(d->online());
}
QList<NymeaHost*> hostsToRemove;
for (int i = 0; i < m_nymeaHosts->rowCount(); i++) {
NymeaHost *host = m_nymeaHosts->get(i);
for (int j = 0; j < host->connections()->rowCount(); j++) {
if (host->connections()->get(j)->bearerType() == Connection::BearerTypeCloud) {
if (m_awsClient->awsDevices()->getDevice(host->uuid().toString()) == nullptr) {
host->connections()->removeConnection(j);
break;
}
}
}
if (host->connections()->rowCount() == 0) {
hostsToRemove.append(host);
}
}
while (!hostsToRemove.isEmpty()) {
m_nymeaHosts->removeHost(hostsToRemove.takeFirst());
}
}
void NymeaDiscovery::loadFromDisk()
{
QSettings settings;
settings.beginGroup("HostCache");
foreach (const QString &serverUuid, settings.childGroups()) {
settings.beginGroup(serverUuid);
NymeaHost* host = m_nymeaHosts->find(QUuid(serverUuid));
if (!host) {
host = new NymeaHost(m_nymeaHosts);
host->setName(settings.value("name").toString());
host->setUuid(QUuid(serverUuid));
m_nymeaHosts->addHost(host);
}
qDebug() << "Loaded Host from cache" << host->name() << host->uuid();
foreach (const QString &group, settings.childGroups()) {
settings.beginGroup(group);
QString url = settings.value("url").toString();
Connection* connection = host->connections()->find(url);
if (!connection) {
Connection::BearerType bearerType = static_cast<Connection::BearerType>(settings.value("bearerType").toInt());
bool secure = settings.value("secure").toBool();
QString displayName = settings.value("displayName").toString();
connection = new Connection(url, bearerType, secure, displayName, host);
host->connections()->addConnection(connection);
qDebug() << "|- Connection:" << group << connection->url() << connection->bearerType() << "secure:" << connection->secure();
}
settings.endGroup();
}
settings.endGroup();
}
}
void NymeaDiscovery::updateActiveBearers()
{
}