Merge PR #374: Add support for allowed values in number type params
This commit is contained in:
commit
6a7c3e5e5d
@ -35,6 +35,7 @@
|
|||||||
#include "types/browseritem.h"
|
#include "types/browseritem.h"
|
||||||
#include "thinggroup.h"
|
#include "thinggroup.h"
|
||||||
#include "types/interface.h"
|
#include "types/interface.h"
|
||||||
|
#include "types/ioconnections.h"
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
|
DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
|
||||||
@ -43,6 +44,7 @@ DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
|
|||||||
m_plugins(new Plugins(this)),
|
m_plugins(new Plugins(this)),
|
||||||
m_devices(new Devices(this)),
|
m_devices(new Devices(this)),
|
||||||
m_deviceClasses(new DeviceClasses(this)),
|
m_deviceClasses(new DeviceClasses(this)),
|
||||||
|
m_ioConnections(new IOConnections(this)),
|
||||||
m_jsonClient(jsonclient)
|
m_jsonClient(jsonclient)
|
||||||
{
|
{
|
||||||
m_jsonClient->registerNotificationHandler(this, "notificationReceived");
|
m_jsonClient->registerNotificationHandler(this, "notificationReceived");
|
||||||
@ -54,6 +56,7 @@ void DeviceManager::clear()
|
|||||||
m_deviceClasses->clearModel();
|
m_deviceClasses->clearModel();
|
||||||
m_vendors->clearModel();
|
m_vendors->clearModel();
|
||||||
m_plugins->clearModel();
|
m_plugins->clearModel();
|
||||||
|
m_ioConnections->clearModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::init()
|
void DeviceManager::init()
|
||||||
@ -86,10 +89,21 @@ void DeviceManager::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a custom notification handler for the Integrations namespace for now.
|
||||||
|
if (m_jsonClient->ensureServerVersion("5.1")) {
|
||||||
|
if (!m_integrationsHandler) {
|
||||||
|
m_integrationsHandler = new IntegrationsHandler(this);
|
||||||
|
m_jsonClient->registerNotificationHandler(m_integrationsHandler, "notificationReceived");
|
||||||
|
connect(m_integrationsHandler, &IntegrationsHandler::onNotificationReceived, this, [this](const QVariantMap ¶ms){
|
||||||
|
notificationReceived(params);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_fetchingData = true;
|
m_fetchingData = true;
|
||||||
emit fetchingDataChanged();
|
emit fetchingDataChanged();
|
||||||
m_jsonClient->sendCommand("Devices.GetPlugins", this, "getPluginsResponse");
|
|
||||||
|
m_jsonClient->sendCommand("Devices.GetSupportedDevices", this, "getSupportedDevicesResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DeviceManager::nameSpace() const
|
QString DeviceManager::nameSpace() const
|
||||||
@ -117,6 +131,11 @@ DeviceClasses *DeviceManager::deviceClasses() const
|
|||||||
return m_deviceClasses;
|
return m_deviceClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOConnections *DeviceManager::ioConnections() const
|
||||||
|
{
|
||||||
|
return m_ioConnections;
|
||||||
|
}
|
||||||
|
|
||||||
bool DeviceManager::fetchingData() const
|
bool DeviceManager::fetchingData() const
|
||||||
{
|
{
|
||||||
return m_fetchingData;
|
return m_fetchingData;
|
||||||
@ -207,6 +226,22 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
|
|||||||
}
|
}
|
||||||
// qDebug() << "Event received" << deviceId.toString() << eventTypeId.toString();
|
// qDebug() << "Event received" << deviceId.toString() << eventTypeId.toString();
|
||||||
dev->eventTriggered(eventTypeId.toString(), event.value("params").toMap());
|
dev->eventTriggered(eventTypeId.toString(), event.value("params").toMap());
|
||||||
|
} else if (notification == "Integrations.IOConnectionAdded") {
|
||||||
|
QVariantMap connectionMap = data.value("params").toMap().value("ioConnection").toMap();
|
||||||
|
QUuid id = connectionMap.value("id").toUuid();
|
||||||
|
QUuid inputThingId = connectionMap.value("inputThingId").toUuid();
|
||||||
|
QUuid inputStateTypeId = connectionMap.value("inputStateTypeId").toUuid();
|
||||||
|
QUuid outputThingId = connectionMap.value("outputThingId").toUuid();
|
||||||
|
QUuid outputStateTypeId = connectionMap.value("outputStateTypeId").toUuid();
|
||||||
|
IOConnection *ioConnection = new IOConnection(id, inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||||
|
m_ioConnections->addIOConnection(ioConnection);
|
||||||
|
} else if (notification == "Integrations.IOConnectionRemoved") {
|
||||||
|
QUuid connectionId = data.value("params").toMap().value("ioConnectionId").toUuid();
|
||||||
|
if (!m_ioConnections->getIOConnection(connectionId)) {
|
||||||
|
qWarning() << "Received an IO connection removed event for an IO connection we don't know.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ioConnections->removeIOConnection(connectionId);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "DeviceManager unhandled device notification received" << notification;
|
qWarning() << "DeviceManager unhandled device notification received" << notification;
|
||||||
}
|
}
|
||||||
@ -223,8 +258,6 @@ void DeviceManager::getVendorsResponse(const QVariantMap ¶ms)
|
|||||||
// qDebug() << "Added Vendor:" << vendor->name();
|
// qDebug() << "Added Vendor:" << vendor->name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_jsonClient->sendCommand("Devices.GetSupportedDevices", this, "getSupportedDevicesResponse");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::getSupportedDevicesResponse(const QVariantMap ¶ms)
|
void DeviceManager::getSupportedDevicesResponse(const QVariantMap ¶ms)
|
||||||
@ -321,6 +354,10 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms)
|
|||||||
}
|
}
|
||||||
m_fetchingData = false;
|
m_fetchingData = false;
|
||||||
emit fetchingDataChanged();
|
emit fetchingDataChanged();
|
||||||
|
|
||||||
|
m_jsonClient->sendCommand("Integrations.GetIOConnections", this, "getIOConnectionsResponse");
|
||||||
|
|
||||||
|
m_jsonClient->sendCommand("Devices.GetPlugins", this, "getPluginsResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceManager::addDeviceResponse(const QVariantMap ¶ms)
|
void DeviceManager::addDeviceResponse(const QVariantMap ¶ms)
|
||||||
@ -675,9 +712,52 @@ int DeviceManager::executeBrowserItemAction(const QUuid &deviceId, const QString
|
|||||||
return m_jsonClient->sendCommand("Actions.ExecuteBrowserItemAction", data, this, "executeBrowserItemActionResponse");
|
return m_jsonClient->sendCommand("Actions.ExecuteBrowserItemAction", data, this, "executeBrowserItemActionResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DeviceManager::connectIO(const QUuid &inputThingId, const QUuid &inputStateTypeId, const QUuid &outputThingId, const QUuid &outputStateTypeId)
|
||||||
|
{
|
||||||
|
QVariantMap data;
|
||||||
|
data.insert("inputThingId", inputThingId);
|
||||||
|
data.insert("inputStateTypeId", inputStateTypeId);
|
||||||
|
data.insert("outputThingId", outputThingId);
|
||||||
|
data.insert("outputStateTypeId", outputStateTypeId);
|
||||||
|
return m_jsonClient->sendCommand("Integrations.ConnectIO", data, this, "connectIOResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeviceManager::disconnectIO(const QUuid &ioConnectionId)
|
||||||
|
{
|
||||||
|
QVariantMap data;
|
||||||
|
data.insert("ioConnectionId", ioConnectionId);
|
||||||
|
return m_jsonClient->sendCommand("Integrations.DisconnectIO", data, this, "disconnectIOResponse");
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceManager::executeBrowserItemActionResponse(const QVariantMap ¶ms)
|
void DeviceManager::executeBrowserItemActionResponse(const QVariantMap ¶ms)
|
||||||
{
|
{
|
||||||
qDebug() << "Execute Browser Item Action finished" << params;
|
qDebug() << "Execute Browser Item Action finished" << params;
|
||||||
emit executeBrowserItemActionReply(params);
|
emit executeBrowserItemActionReply(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceManager::getIOConnectionsResponse(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qDebug() << "Get IO connections response" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||||
|
|
||||||
|
foreach (const QVariant &connectionVariant, params.value("params").toMap().value("ioConnections").toList()) {
|
||||||
|
QVariantMap connectionMap = connectionVariant.toMap();
|
||||||
|
QUuid id = connectionMap.value("id").toUuid();
|
||||||
|
QUuid inputThingId = connectionMap.value("inputThingId").toUuid();
|
||||||
|
QUuid inputStateTypeId = connectionMap.value("inputStateTypeId").toUuid();
|
||||||
|
QUuid outputThingId = connectionMap.value("outputThingId").toUuid();
|
||||||
|
QUuid outputStateTypeId = connectionMap.value("outputStateTypeId").toUuid();
|
||||||
|
IOConnection *ioConnection = new IOConnection(id, inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||||
|
m_ioConnections->addIOConnection(ioConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceManager::connectIOResponse(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qDebug() << "ConnectIO response" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceManager::disconnectIOResponse(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qDebug() << "DisconnectIO response" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,17 +43,20 @@
|
|||||||
|
|
||||||
class BrowserItem;
|
class BrowserItem;
|
||||||
class BrowserItems;
|
class BrowserItems;
|
||||||
class EventHandler;
|
|
||||||
class ThingGroup;
|
class ThingGroup;
|
||||||
class Interface;
|
class Interface;
|
||||||
|
class IOConnections;
|
||||||
|
class EventHandler;
|
||||||
|
class IntegrationsHandler;
|
||||||
|
|
||||||
class DeviceManager : public JsonHandler
|
class DeviceManager : public JsonHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(Vendors *vendors READ vendors CONSTANT)
|
Q_PROPERTY(Vendors* vendors READ vendors CONSTANT)
|
||||||
Q_PROPERTY(Plugins *plugins READ plugins CONSTANT)
|
Q_PROPERTY(Plugins* plugins READ plugins CONSTANT)
|
||||||
Q_PROPERTY(Devices *devices READ devices CONSTANT)
|
Q_PROPERTY(Devices* devices READ devices CONSTANT)
|
||||||
Q_PROPERTY(DeviceClasses *deviceClasses READ deviceClasses CONSTANT)
|
Q_PROPERTY(DeviceClasses* deviceClasses READ deviceClasses CONSTANT)
|
||||||
|
Q_PROPERTY(IOConnections* ioConnections READ ioConnections CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged)
|
Q_PROPERTY(bool fetchingData READ fetchingData NOTIFY fetchingDataChanged)
|
||||||
|
|
||||||
@ -72,10 +75,11 @@ public:
|
|||||||
|
|
||||||
QString nameSpace() const override;
|
QString nameSpace() const override;
|
||||||
|
|
||||||
Vendors *vendors() const;
|
Vendors* vendors() const;
|
||||||
Plugins *plugins() const;
|
Plugins* plugins() const;
|
||||||
Devices *devices() const;
|
Devices* devices() const;
|
||||||
DeviceClasses *deviceClasses() const;
|
DeviceClasses* deviceClasses() const;
|
||||||
|
IOConnections* ioConnections() const;
|
||||||
|
|
||||||
bool fetchingData() const;
|
bool fetchingData() const;
|
||||||
|
|
||||||
@ -99,6 +103,9 @@ public:
|
|||||||
Q_INVOKABLE int executeBrowserItem(const QUuid &deviceId, const QString &itemId);
|
Q_INVOKABLE int executeBrowserItem(const QUuid &deviceId, const QString &itemId);
|
||||||
Q_INVOKABLE int executeBrowserItemAction(const QUuid &deviceId, const QString &itemId, const QUuid &actionTypeId, const QVariantList ¶ms = QVariantList());
|
Q_INVOKABLE int executeBrowserItemAction(const QUuid &deviceId, const QString &itemId, const QUuid &actionTypeId, const QVariantList ¶ms = QVariantList());
|
||||||
|
|
||||||
|
Q_INVOKABLE int connectIO(const QUuid &inputThingId, const QUuid &inputStateTypeId, const QUuid &outputThingId, const QUuid &outputStateTypeId);
|
||||||
|
Q_INVOKABLE int disconnectIO(const QUuid &ioConnectionId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_INVOKABLE void notificationReceived(const QVariantMap &data);
|
Q_INVOKABLE void notificationReceived(const QVariantMap &data);
|
||||||
Q_INVOKABLE void getVendorsResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void getVendorsResponse(const QVariantMap ¶ms);
|
||||||
@ -118,6 +125,9 @@ private:
|
|||||||
Q_INVOKABLE void browserItemResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void browserItemResponse(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void executeBrowserItemResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void executeBrowserItemResponse(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void executeBrowserItemActionResponse(const QVariantMap ¶ms);
|
Q_INVOKABLE void executeBrowserItemActionResponse(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE void getIOConnectionsResponse(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE void connectIOResponse(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE void disconnectIOResponse(const QVariantMap ¶ms);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void savePluginConfig(const QUuid &pluginId);
|
void savePluginConfig(const QUuid &pluginId);
|
||||||
@ -145,6 +155,7 @@ private:
|
|||||||
Plugins *m_plugins;
|
Plugins *m_plugins;
|
||||||
Devices *m_devices;
|
Devices *m_devices;
|
||||||
DeviceClasses *m_deviceClasses;
|
DeviceClasses *m_deviceClasses;
|
||||||
|
IOConnections *m_ioConnections;
|
||||||
|
|
||||||
bool m_fetchingData = false;
|
bool m_fetchingData = false;
|
||||||
|
|
||||||
@ -158,6 +169,8 @@ private:
|
|||||||
|
|
||||||
// Deprecated stuff for nymea < 0.17 (JSONRPC < 4.0)
|
// Deprecated stuff for nymea < 0.17 (JSONRPC < 4.0)
|
||||||
EventHandler *m_eventHandler = nullptr;
|
EventHandler *m_eventHandler = nullptr;
|
||||||
|
// Register notifications for new stuff that's only available in the Integrations namespace for now
|
||||||
|
IntegrationsHandler *m_integrationsHandler = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,4 +194,22 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IntegrationsHandler: public JsonHandler {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
IntegrationsHandler(QObject *parent = nullptr): JsonHandler(parent) {}
|
||||||
|
QString nameSpace() const override {
|
||||||
|
return "Integrations";
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void onNotificationReceived(const QVariantMap &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_INVOKABLE void notificationReceived(const QVariantMap &data) {
|
||||||
|
emit onNotificationReceived(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // DEVICEMANAGER_H
|
#endif // DEVICEMANAGER_H
|
||||||
|
|||||||
@ -203,6 +203,66 @@ void DevicesProxy::setNameFilter(const QString &nameFilter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DevicesProxy::showDigitalInputs() const
|
||||||
|
{
|
||||||
|
return m_showDigitalInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicesProxy::setShowDigitalInputs(bool showDigitalInputs)
|
||||||
|
{
|
||||||
|
if (m_showDigitalInputs != showDigitalInputs) {
|
||||||
|
m_showDigitalInputs = showDigitalInputs;
|
||||||
|
emit showDigitalInputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DevicesProxy::showDigitalOutputs() const
|
||||||
|
{
|
||||||
|
return m_showDigitalOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicesProxy::setShowDigitalOutputs(bool showDigitalOutputs)
|
||||||
|
{
|
||||||
|
if (m_showDigitalOutputs != showDigitalOutputs) {
|
||||||
|
m_showDigitalOutputs = showDigitalOutputs;
|
||||||
|
emit showDigitalOutputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DevicesProxy::showAnalogInputs() const
|
||||||
|
{
|
||||||
|
return m_showAnalogInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicesProxy::setShowAnalogInputs(bool showAnalogInputs)
|
||||||
|
{
|
||||||
|
if (m_showAnalogInputs != showAnalogInputs) {
|
||||||
|
m_showAnalogInputs = showAnalogInputs;
|
||||||
|
emit showAnalogInputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DevicesProxy::showAnalogOutputs() const
|
||||||
|
{
|
||||||
|
return m_showDigitalOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicesProxy::setShowAnalogOutputs(bool showAnalogOutputs)
|
||||||
|
{
|
||||||
|
if (m_showAnalogOutputs != showAnalogOutputs) {
|
||||||
|
m_showAnalogOutputs = showAnalogOutputs;
|
||||||
|
emit showAnalogOutputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DevicesProxy::filterBatteryCritical() const
|
bool DevicesProxy::filterBatteryCritical() const
|
||||||
{
|
{
|
||||||
return m_filterBatteryCritical;
|
return m_filterBatteryCritical;
|
||||||
@ -339,6 +399,21 @@ bool DevicesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_showDigitalInputs || m_showDigitalOutputs || m_showAnalogInputs || m_showAnalogOutputs) {
|
||||||
|
if (m_showDigitalInputs && deviceClass->stateTypes()->ioStateTypes(Types::IOTypeDigitalInput).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_showDigitalOutputs && deviceClass->stateTypes()->ioStateTypes(Types::IOTypeDigitalOutput).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_showAnalogInputs && deviceClass->stateTypes()->ioStateTypes(Types::IOTypeAnalogInput).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_showAnalogOutputs && deviceClass->stateTypes()->ioStateTypes(Types::IOTypeAnalogOutput).isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_filterBatteryCritical) {
|
if (m_filterBatteryCritical) {
|
||||||
if (!deviceClass->interfaces().contains("battery") || device->stateValue(deviceClass->stateTypes()->findByName("batteryCritical")->id()).toBool() == false) {
|
if (!deviceClass->interfaces().contains("battery") || device->stateValue(deviceClass->stateTypes()->findByName("batteryCritical")->id()).toBool() == false) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -53,6 +53,12 @@ class DevicesProxy : public QSortFilterProxyModel
|
|||||||
Q_PROPERTY(QStringList hiddenInterfaces READ hiddenInterfaces WRITE setHiddenInterfaces NOTIFY hiddenInterfacesChanged)
|
Q_PROPERTY(QStringList hiddenInterfaces READ hiddenInterfaces WRITE setHiddenInterfaces NOTIFY hiddenInterfacesChanged)
|
||||||
Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter NOTIFY nameFilterChanged)
|
Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter NOTIFY nameFilterChanged)
|
||||||
|
|
||||||
|
// Setting one of those to true will hide those set to false. If all of those are false no IO filtering will be done
|
||||||
|
Q_PROPERTY(bool showDigitalInputs READ showDigitalInputs WRITE setShowDigitalInputs NOTIFY showDigitalInputsChanged)
|
||||||
|
Q_PROPERTY(bool showDigitalOutputs READ showDigitalOutputs WRITE setShowDigitalOutputs NOTIFY showDigitalOutputsChanged)
|
||||||
|
Q_PROPERTY(bool showAnalogInputs READ showAnalogInputs WRITE setShowAnalogInputs NOTIFY showAnalogInputsChanged)
|
||||||
|
Q_PROPERTY(bool showAnalogOutputs READ showAnalogOutputs WRITE setShowAnalogOutputs NOTIFY showAnalogOutputsChanged)
|
||||||
|
|
||||||
// Setting this to true will imply filtering for "battery" interface
|
// Setting this to true will imply filtering for "battery" interface
|
||||||
Q_PROPERTY(bool filterBatteryCritical READ filterBatteryCritical WRITE setFilterBatteryCritical NOTIFY filterBatteryCriticalChanged)
|
Q_PROPERTY(bool filterBatteryCritical READ filterBatteryCritical WRITE setFilterBatteryCritical NOTIFY filterBatteryCriticalChanged)
|
||||||
|
|
||||||
@ -91,6 +97,18 @@ public:
|
|||||||
QString nameFilter() const;
|
QString nameFilter() const;
|
||||||
void setNameFilter(const QString &nameFilter);
|
void setNameFilter(const QString &nameFilter);
|
||||||
|
|
||||||
|
bool showDigitalInputs() const;
|
||||||
|
void setShowDigitalInputs(bool showDigitalInputs);
|
||||||
|
|
||||||
|
bool showDigitalOutputs() const;
|
||||||
|
void setShowDigitalOutputs(bool showDigitalOutputs);
|
||||||
|
|
||||||
|
bool showAnalogInputs() const;
|
||||||
|
void setShowAnalogInputs(bool showAnalogInputs);
|
||||||
|
|
||||||
|
bool showAnalogOutputs() const;
|
||||||
|
void setShowAnalogOutputs(bool showAnalogOutputs);
|
||||||
|
|
||||||
bool filterBatteryCritical() const;
|
bool filterBatteryCritical() const;
|
||||||
void setFilterBatteryCritical(bool filterBatteryCritical);
|
void setFilterBatteryCritical(bool filterBatteryCritical);
|
||||||
|
|
||||||
@ -113,6 +131,10 @@ signals:
|
|||||||
void shownInterfacesChanged();
|
void shownInterfacesChanged();
|
||||||
void hiddenInterfacesChanged();
|
void hiddenInterfacesChanged();
|
||||||
void nameFilterChanged();
|
void nameFilterChanged();
|
||||||
|
void showDigitalInputsChanged();
|
||||||
|
void showDigitalOutputsChanged();
|
||||||
|
void showAnalogInputsChanged();
|
||||||
|
void showAnalogOutputsChanged();
|
||||||
void filterBatteryCriticalChanged();
|
void filterBatteryCriticalChanged();
|
||||||
void filterDisconnectedChanged();
|
void filterDisconnectedChanged();
|
||||||
void groupByInterfaceChanged();
|
void groupByInterfaceChanged();
|
||||||
@ -131,6 +153,11 @@ private:
|
|||||||
QStringList m_hiddenInterfaces;
|
QStringList m_hiddenInterfaces;
|
||||||
QString m_nameFilter;
|
QString m_nameFilter;
|
||||||
|
|
||||||
|
bool m_showDigitalInputs = false;
|
||||||
|
bool m_showDigitalOutputs = false;
|
||||||
|
bool m_showAnalogInputs = false;
|
||||||
|
bool m_showAnalogOutputs = false;
|
||||||
|
|
||||||
bool m_filterBatteryCritical = false;
|
bool m_filterBatteryCritical = false;
|
||||||
bool m_filterDisconnected = false;
|
bool m_filterDisconnected = false;
|
||||||
|
|
||||||
|
|||||||
@ -189,6 +189,11 @@ StateType *JsonTypes::unpackStateType(const QVariantMap &stateTypeMap, QObject *
|
|||||||
QPair<Types::Unit, QString> unit = stringToUnit(stateTypeMap.value("unit").toString());
|
QPair<Types::Unit, QString> unit = stringToUnit(stateTypeMap.value("unit").toString());
|
||||||
stateType->setUnit(unit.first);
|
stateType->setUnit(unit.first);
|
||||||
stateType->setUnitString(unit.second);
|
stateType->setUnitString(unit.second);
|
||||||
|
|
||||||
|
QMetaEnum metaEnum = QMetaEnum::fromType<Types::IOType>();
|
||||||
|
Types::IOType ioType = static_cast<Types::IOType>(metaEnum.keyToValue(stateTypeMap.value("ioType").toByteArray()));
|
||||||
|
stateType->setIOType(ioType);
|
||||||
|
|
||||||
return stateType;
|
return stateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,10 @@
|
|||||||
#include "types/tokeninfo.h"
|
#include "types/tokeninfo.h"
|
||||||
#include "types/userinfo.h"
|
#include "types/userinfo.h"
|
||||||
#include "thinggroup.h"
|
#include "thinggroup.h"
|
||||||
|
#include "types/statetypesproxy.h"
|
||||||
|
#include "types/ioconnection.h"
|
||||||
|
#include "types/ioconnections.h"
|
||||||
|
#include "types/ioconnectionwatcher.h"
|
||||||
|
|
||||||
#include <QtQml/qqml.h>
|
#include <QtQml/qqml.h>
|
||||||
|
|
||||||
@ -157,6 +161,7 @@ void registerQmlTypes() {
|
|||||||
qmlRegisterUncreatableType<StateTypes>(uri, 1, 0, "StateTypes", "Can't create this in QML. Get it from the DeviceClass.");
|
qmlRegisterUncreatableType<StateTypes>(uri, 1, 0, "StateTypes", "Can't create this in QML. Get it from the DeviceClass.");
|
||||||
qmlRegisterUncreatableType<ActionType>(uri, 1, 0, "ActionType", "Can't create this in QML. Get it from the ActionTypes.");
|
qmlRegisterUncreatableType<ActionType>(uri, 1, 0, "ActionType", "Can't create this in QML. Get it from the ActionTypes.");
|
||||||
qmlRegisterUncreatableType<ActionTypes>(uri, 1, 0, "ActionTypes", "Can't create this in QML. Get it from the DeviceClass.");
|
qmlRegisterUncreatableType<ActionTypes>(uri, 1, 0, "ActionTypes", "Can't create this in QML. Get it from the DeviceClass.");
|
||||||
|
qmlRegisterType<StateTypesProxy>(uri, 1, 0, "StateTypesProxy");
|
||||||
|
|
||||||
qmlRegisterUncreatableType<State>(uri, 1, 0, "State", "Can't create this in QML. Get it from the States.");
|
qmlRegisterUncreatableType<State>(uri, 1, 0, "State", "Can't create this in QML. Get it from the States.");
|
||||||
qmlRegisterUncreatableType<States>(uri, 1, 0, "States", "Can't create this in QML. Get it from the Device.");
|
qmlRegisterUncreatableType<States>(uri, 1, 0, "States", "Can't create this in QML. Get it from the Device.");
|
||||||
@ -293,6 +298,11 @@ void registerQmlTypes() {
|
|||||||
qmlRegisterUncreatableType<UserInfo>(uri, 1, 0, "UserInfo", "Get it from UserManager");
|
qmlRegisterUncreatableType<UserInfo>(uri, 1, 0, "UserInfo", "Get it from UserManager");
|
||||||
qmlRegisterUncreatableType<TokenInfo>(uri, 1, 0, "TokenInfo", "Get it from TokenInfos");
|
qmlRegisterUncreatableType<TokenInfo>(uri, 1, 0, "TokenInfo", "Get it from TokenInfos");
|
||||||
qmlRegisterUncreatableType<TokenInfos>(uri, 1, 0, "TokenInfos", "Get it from UserManager");
|
qmlRegisterUncreatableType<TokenInfos>(uri, 1, 0, "TokenInfos", "Get it from UserManager");
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType<IOConnections>(uri, 1, 0, "IOConnections", "Get it from DeviceManager");
|
||||||
|
qmlRegisterUncreatableType<IOConnection>(uri, 1, 0, "IOConnection", "Get it from IOConnections");
|
||||||
|
qmlRegisterType<IOInputConnectionWatcher>(uri, 1, 0, "IOInputConnectionWatcher");
|
||||||
|
qmlRegisterType<IOOutputConnectionWatcher>(uri, 1, 0, "IOOutputConnectionWatcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LIBNYMEAAPPCORE_H
|
#endif // LIBNYMEAAPPCORE_H
|
||||||
|
|||||||
@ -48,6 +48,7 @@ SOURCES += \
|
|||||||
types/paramtypes.cpp \
|
types/paramtypes.cpp \
|
||||||
types/statetype.cpp \
|
types/statetype.cpp \
|
||||||
types/statetypes.cpp \
|
types/statetypes.cpp \
|
||||||
|
types/statetypesproxy.cpp \
|
||||||
types/eventtype.cpp \
|
types/eventtype.cpp \
|
||||||
types/eventtypes.cpp \
|
types/eventtypes.cpp \
|
||||||
types/actiontype.cpp \
|
types/actiontype.cpp \
|
||||||
@ -86,6 +87,9 @@ SOURCES += \
|
|||||||
types/tokeninfo.cpp \
|
types/tokeninfo.cpp \
|
||||||
types/tokeninfos.cpp \
|
types/tokeninfos.cpp \
|
||||||
types/userinfo.cpp \
|
types/userinfo.cpp \
|
||||||
|
types/ioconnection.cpp \
|
||||||
|
types/ioconnections.cpp \
|
||||||
|
types/ioconnectionwatcher.cpp \
|
||||||
connection/nymeahost.cpp \
|
connection/nymeahost.cpp \
|
||||||
connection/nymeahosts.cpp \
|
connection/nymeahosts.cpp \
|
||||||
connection/nymeaconnection.cpp \
|
connection/nymeaconnection.cpp \
|
||||||
@ -176,6 +180,7 @@ HEADERS += \
|
|||||||
types/paramtypes.h \
|
types/paramtypes.h \
|
||||||
types/statetype.h \
|
types/statetype.h \
|
||||||
types/statetypes.h \
|
types/statetypes.h \
|
||||||
|
types/statetypesproxy.h \
|
||||||
types/eventtype.h \
|
types/eventtype.h \
|
||||||
types/eventtypes.h \
|
types/eventtypes.h \
|
||||||
types/actiontype.h \
|
types/actiontype.h \
|
||||||
@ -214,6 +219,9 @@ HEADERS += \
|
|||||||
types/tokeninfo.h \
|
types/tokeninfo.h \
|
||||||
types/tokeninfos.h \
|
types/tokeninfos.h \
|
||||||
types/userinfo.h \
|
types/userinfo.h \
|
||||||
|
types/ioconnection.h \
|
||||||
|
types/ioconnections.h \
|
||||||
|
types/ioconnectionwatcher.h \
|
||||||
connection/nymeahost.h \
|
connection/nymeahost.h \
|
||||||
connection/nymeahosts.h \
|
connection/nymeahosts.h \
|
||||||
connection/nymeaconnection.h \
|
connection/nymeaconnection.h \
|
||||||
|
|||||||
67
libnymea-app/types/ioconnection.cpp
Normal file
67
libnymea-app/types/ioconnection.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "ioconnection.h"
|
||||||
|
|
||||||
|
IOConnection::IOConnection(const QUuid &id, const QUuid &inputThingId, const QUuid &inputStateTypeId, const QUuid &outputThingId, const QUuid &outputStateTypeId, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_id(id),
|
||||||
|
m_inputThingId(inputThingId),
|
||||||
|
m_inputStateTypeId(inputStateTypeId),
|
||||||
|
m_outputThingId(outputThingId),
|
||||||
|
m_outputStateTypeId(outputStateTypeId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOConnection::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOConnection::inputThingId() const
|
||||||
|
{
|
||||||
|
return m_inputThingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOConnection::inputStateTypeId() const
|
||||||
|
{
|
||||||
|
return m_inputStateTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOConnection::outputThingId() const
|
||||||
|
{
|
||||||
|
return m_outputThingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOConnection::outputStateTypeId() const
|
||||||
|
{
|
||||||
|
return m_outputStateTypeId;
|
||||||
|
}
|
||||||
63
libnymea-app/types/ioconnection.h
Normal file
63
libnymea-app/types/ioconnection.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef IOCONNECTION_H
|
||||||
|
#define IOCONNECTION_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
class IOConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QUuid id READ id CONSTANT)
|
||||||
|
Q_PROPERTY(QUuid inputThingId READ inputThingId CONSTANT)
|
||||||
|
Q_PROPERTY(QUuid inputStateTypeId READ inputStateTypeId CONSTANT)
|
||||||
|
Q_PROPERTY(QUuid outputThingId READ outputThingId CONSTANT)
|
||||||
|
Q_PROPERTY(QUuid outputStateTypeId READ outputStateTypeId CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IOConnection(const QUuid &id, const QUuid &inputThingId, const QUuid &inputStateTypeId, const QUuid &outputThingId, const QUuid &outputStateTypeId, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QUuid id() const;
|
||||||
|
QUuid inputThingId() const;
|
||||||
|
QUuid inputStateTypeId() const;
|
||||||
|
QUuid outputThingId() const;
|
||||||
|
QUuid outputStateTypeId() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUuid m_id;
|
||||||
|
QUuid m_inputThingId;
|
||||||
|
QUuid m_inputStateTypeId;
|
||||||
|
QUuid m_outputThingId;
|
||||||
|
QUuid m_outputStateTypeId;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IOCONNECTION_H
|
||||||
129
libnymea-app/types/ioconnections.cpp
Normal file
129
libnymea-app/types/ioconnections.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "ioconnections.h"
|
||||||
|
|
||||||
|
IOConnections::IOConnections(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int IOConnections::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return m_list.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant IOConnections::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case RoleInputThingId:
|
||||||
|
return m_list.at(index.row())->inputThingId();
|
||||||
|
case RoleInputStateTypeId:
|
||||||
|
return m_list.at(index.row())->inputStateTypeId();
|
||||||
|
case RoleOutputThingId:
|
||||||
|
return m_list.at(index.row())->outputThingId();
|
||||||
|
case RoleOutputStateTypeId:
|
||||||
|
return m_list.at(index.row())->outputStateTypeId();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> IOConnections::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles.insert(RoleInputThingId, "inputThingId");
|
||||||
|
roles.insert(RoleInputStateTypeId, "inputStateTypeId");
|
||||||
|
roles.insert(RoleOutputThingId, "outputThingId");
|
||||||
|
roles.insert(RoleOutputStateTypeId, "outputStateTypeId");
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOConnections::addIOConnection(IOConnection *ioConnection)
|
||||||
|
{
|
||||||
|
ioConnection->setParent(this);
|
||||||
|
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
|
||||||
|
m_list.append(ioConnection);
|
||||||
|
endInsertRows();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOConnections::removeIOConnection(const QUuid &ioConnectionId)
|
||||||
|
{
|
||||||
|
int idx = -1;
|
||||||
|
for (int i = 0; i < m_list.count(); i++) {
|
||||||
|
if (m_list.at(i)->id() == ioConnectionId) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
beginRemoveRows(QModelIndex(), idx, idx);
|
||||||
|
m_list.takeAt(idx)->deleteLater();
|
||||||
|
endRemoveRows();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOConnections::clearModel()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
qDeleteAll(m_list);
|
||||||
|
m_list.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnection *IOConnections::getIOConnection(const QUuid &ioConnectionId) const
|
||||||
|
{
|
||||||
|
foreach (IOConnection* ioConnection, m_list) {
|
||||||
|
if (ioConnection->id() == ioConnectionId) {
|
||||||
|
return ioConnection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnection *IOConnections::findIOConnectionByInput(const QUuid &inputThingId, const QUuid &inputStateTypeId) const
|
||||||
|
{
|
||||||
|
foreach (IOConnection* ioConnection, m_list) {
|
||||||
|
if (ioConnection->inputThingId() == inputThingId && ioConnection->inputStateTypeId() == inputStateTypeId) {
|
||||||
|
return ioConnection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnection *IOConnections::findIOConnectionByOutput(const QUuid &outputThingId, const QUuid &outputStateTypeId) const
|
||||||
|
{
|
||||||
|
foreach (IOConnection* ioConnection, m_list) {
|
||||||
|
if (ioConnection->outputThingId() == outputThingId && ioConnection->outputStateTypeId() == outputStateTypeId) {
|
||||||
|
return ioConnection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
73
libnymea-app/types/ioconnections.h
Normal file
73
libnymea-app/types/ioconnections.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef IOCONNECTIONS_H
|
||||||
|
#define IOCONNECTIONS_H
|
||||||
|
|
||||||
|
#include "ioconnection.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class IOConnections : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
public:
|
||||||
|
enum Roles {
|
||||||
|
RoleInputThingId,
|
||||||
|
RoleInputStateTypeId,
|
||||||
|
RoleOutputThingId,
|
||||||
|
RoleOutputStateTypeId
|
||||||
|
};
|
||||||
|
Q_ENUM(Roles)
|
||||||
|
|
||||||
|
explicit IOConnections(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QHash<int, QByteArray> roleNames() const;
|
||||||
|
|
||||||
|
void addIOConnection(IOConnection *ioConnection);
|
||||||
|
void removeIOConnection(const QUuid &ioConnectionId);
|
||||||
|
void clearModel();
|
||||||
|
|
||||||
|
Q_INVOKABLE IOConnection* getIOConnection(const QUuid &ioConnectionId) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE IOConnection* findIOConnectionByInput(const QUuid &inputThingId, const QUuid &inputStateTypeId) const;
|
||||||
|
Q_INVOKABLE IOConnection* findIOConnectionByOutput(const QUuid &outputThingId, const QUuid &outputStateTypeId) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<IOConnection*> m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IOCONNECTIONS_H
|
||||||
157
libnymea-app/types/ioconnectionwatcher.cpp
Normal file
157
libnymea-app/types/ioconnectionwatcher.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "ioconnectionwatcher.h"
|
||||||
|
#include "ioconnections.h"
|
||||||
|
#include "ioconnection.h"
|
||||||
|
|
||||||
|
IOInputConnectionWatcher::IOInputConnectionWatcher(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnections *IOInputConnectionWatcher::ioConnections() const
|
||||||
|
{
|
||||||
|
return m_ioConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOInputConnectionWatcher::setIOConnections(IOConnections *ioConnections)
|
||||||
|
{
|
||||||
|
if (m_ioConnections != ioConnections) {
|
||||||
|
|
||||||
|
if (m_ioConnections) {
|
||||||
|
disconnect(ioConnections, &IOConnections::countChanged, this, &IOInputConnectionWatcher::ioConnectionChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ioConnections = ioConnections;
|
||||||
|
emit ioConnectionsChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
|
||||||
|
connect(ioConnections, &IOConnections::countChanged, this, &IOInputConnectionWatcher::ioConnectionChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOInputConnectionWatcher::inputThingId() const
|
||||||
|
{
|
||||||
|
return m_inputThingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOInputConnectionWatcher::setInputThingId(const QUuid &inputThingId)
|
||||||
|
{
|
||||||
|
if (m_inputThingId != inputThingId) {
|
||||||
|
m_inputThingId = inputThingId;
|
||||||
|
emit inputThingIdChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOInputConnectionWatcher::inputStateTypeId() const
|
||||||
|
{
|
||||||
|
return m_inputStateTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOInputConnectionWatcher::setInputStateTypeId(const QUuid &inputStateTypeId)
|
||||||
|
{
|
||||||
|
if (m_inputStateTypeId != inputStateTypeId) {
|
||||||
|
m_inputStateTypeId = inputStateTypeId;
|
||||||
|
emit inputStateTypeIdChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnection* IOInputConnectionWatcher::ioConnection() const
|
||||||
|
{
|
||||||
|
if (!m_ioConnections) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_ioConnections->findIOConnectionByInput(m_inputThingId, m_inputStateTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOOutputConnectionWatcher::IOOutputConnectionWatcher(QObject *parent): QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnections *IOOutputConnectionWatcher::ioConnections() const
|
||||||
|
{
|
||||||
|
return m_ioConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOOutputConnectionWatcher::setIOConnections(IOConnections *ioConnections)
|
||||||
|
{
|
||||||
|
if (m_ioConnections != ioConnections) {
|
||||||
|
|
||||||
|
if (m_ioConnections) {
|
||||||
|
disconnect(ioConnections, &IOConnections::countChanged, this, &IOOutputConnectionWatcher::ioConnectionChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ioConnections = ioConnections;
|
||||||
|
emit ioConnectionsChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
|
||||||
|
connect(ioConnections, &IOConnections::countChanged, this, &IOOutputConnectionWatcher::ioConnectionChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOOutputConnectionWatcher::outputThingId() const
|
||||||
|
{
|
||||||
|
return m_outputThingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOOutputConnectionWatcher::setOutputThingId(const QUuid &outputThingId)
|
||||||
|
{
|
||||||
|
if (m_outputThingId != outputThingId) {
|
||||||
|
m_outputThingId = outputThingId;
|
||||||
|
emit outputThingIdChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid IOOutputConnectionWatcher::outputStateTypeId() const
|
||||||
|
{
|
||||||
|
return m_outputStateTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOOutputConnectionWatcher::setOutputStateTypeId(const QUuid &outputStateTypeId)
|
||||||
|
{
|
||||||
|
if (m_outputStateTypeId != outputStateTypeId) {
|
||||||
|
m_outputStateTypeId = outputStateTypeId;
|
||||||
|
emit outputStateTypeIdChanged();
|
||||||
|
emit ioConnectionChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOConnection *IOOutputConnectionWatcher::ioConnection() const
|
||||||
|
{
|
||||||
|
if (!m_ioConnections) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_ioConnections->findIOConnectionByOutput(m_outputThingId, m_outputStateTypeId);
|
||||||
|
}
|
||||||
107
libnymea-app/types/ioconnectionwatcher.h
Normal file
107
libnymea-app/types/ioconnectionwatcher.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef IOCONNECTIONWATCHER_H
|
||||||
|
#define IOCONNECTIONWATCHER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
class IOConnection;
|
||||||
|
class IOConnections;
|
||||||
|
|
||||||
|
class IOInputConnectionWatcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(IOConnections* ioConnections READ ioConnections WRITE setIOConnections NOTIFY ioConnectionsChanged)
|
||||||
|
Q_PROPERTY(QUuid inputThingId READ inputThingId WRITE setInputThingId NOTIFY inputThingIdChanged)
|
||||||
|
Q_PROPERTY(QUuid inputStateTypeId READ inputStateTypeId WRITE setInputStateTypeId NOTIFY inputStateTypeIdChanged)
|
||||||
|
Q_PROPERTY(IOConnection* ioConnection READ ioConnection NOTIFY ioConnectionChanged)
|
||||||
|
public:
|
||||||
|
explicit IOInputConnectionWatcher(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
IOConnections* ioConnections() const;
|
||||||
|
void setIOConnections(IOConnections *ioConnections);
|
||||||
|
|
||||||
|
QUuid inputThingId() const;
|
||||||
|
void setInputThingId(const QUuid &inputThingId);
|
||||||
|
|
||||||
|
QUuid inputStateTypeId() const;
|
||||||
|
void setInputStateTypeId(const QUuid &inputStateTypeId);
|
||||||
|
|
||||||
|
IOConnection* ioConnection() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void ioConnectionsChanged();
|
||||||
|
void inputThingIdChanged();
|
||||||
|
void inputStateTypeIdChanged();
|
||||||
|
void ioConnectionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOConnections *m_ioConnections = nullptr;
|
||||||
|
QUuid m_inputThingId;
|
||||||
|
QUuid m_inputStateTypeId;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class IOOutputConnectionWatcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(IOConnections* ioConnections READ ioConnections WRITE setIOConnections NOTIFY ioConnectionsChanged)
|
||||||
|
Q_PROPERTY(QUuid outputThingId READ outputThingId WRITE setOutputThingId NOTIFY outputThingIdChanged)
|
||||||
|
Q_PROPERTY(QUuid outputStateTypeId READ outputStateTypeId WRITE setOutputStateTypeId NOTIFY outputStateTypeIdChanged)
|
||||||
|
Q_PROPERTY(IOConnection* ioConnection READ ioConnection NOTIFY ioConnectionChanged)
|
||||||
|
public:
|
||||||
|
explicit IOOutputConnectionWatcher(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
IOConnections* ioConnections() const;
|
||||||
|
void setIOConnections(IOConnections *ioConnections);
|
||||||
|
|
||||||
|
QUuid outputThingId() const;
|
||||||
|
void setOutputThingId(const QUuid &outputThingId);
|
||||||
|
|
||||||
|
QUuid outputStateTypeId() const;
|
||||||
|
void setOutputStateTypeId(const QUuid &outputStateTypeId);
|
||||||
|
|
||||||
|
IOConnection* ioConnection() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void ioConnectionsChanged();
|
||||||
|
void outputThingIdChanged();
|
||||||
|
void outputStateTypeIdChanged();
|
||||||
|
void ioConnectionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOConnections *m_ioConnections = nullptr;
|
||||||
|
QUuid m_outputThingId;
|
||||||
|
QUuid m_outputStateTypeId;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IOCONNECTIONWATCHER_H
|
||||||
@ -149,3 +149,13 @@ void StateType::setMaxValue(const QVariant &maxValue)
|
|||||||
{
|
{
|
||||||
m_maxValue = maxValue;
|
m_maxValue = maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Types::IOType StateType::ioType() const
|
||||||
|
{
|
||||||
|
return m_ioType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateType::setIOType(Types::IOType ioType)
|
||||||
|
{
|
||||||
|
m_ioType = ioType;
|
||||||
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ class StateType : public QObject
|
|||||||
Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT)
|
Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT)
|
||||||
Q_PROPERTY(QVariantList allowedValues READ allowedValues CONSTANT)
|
Q_PROPERTY(QVariantList allowedValues READ allowedValues CONSTANT)
|
||||||
Q_PROPERTY(Types::Unit unit READ unit CONSTANT)
|
Q_PROPERTY(Types::Unit unit READ unit CONSTANT)
|
||||||
|
Q_PROPERTY(Types::IOType ioType READ ioType CONSTANT)
|
||||||
Q_PROPERTY(QString unitString READ unitString CONSTANT)
|
Q_PROPERTY(QString unitString READ unitString CONSTANT)
|
||||||
Q_PROPERTY(QVariant minValue READ minValue CONSTANT)
|
Q_PROPERTY(QVariant minValue READ minValue CONSTANT)
|
||||||
Q_PROPERTY(QVariant maxValue READ maxValue CONSTANT)
|
Q_PROPERTY(QVariant maxValue READ maxValue CONSTANT)
|
||||||
@ -80,6 +81,9 @@ public:
|
|||||||
Types::Unit unit() const;
|
Types::Unit unit() const;
|
||||||
void setUnit(const Types::Unit &unit);
|
void setUnit(const Types::Unit &unit);
|
||||||
|
|
||||||
|
Types::IOType ioType() const;
|
||||||
|
void setIOType(Types::IOType ioType);
|
||||||
|
|
||||||
QString unitString() const;
|
QString unitString() const;
|
||||||
void setUnitString(const QString &unitString);
|
void setUnitString(const QString &unitString);
|
||||||
|
|
||||||
@ -97,7 +101,8 @@ private:
|
|||||||
int m_index;
|
int m_index;
|
||||||
QVariant m_defaultValue;
|
QVariant m_defaultValue;
|
||||||
QVariantList m_allowedValues;
|
QVariantList m_allowedValues;
|
||||||
Types::Unit m_unit;
|
Types::Unit m_unit = Types::UnitNone;
|
||||||
|
Types::IOType m_ioType = Types::IOTypeNone;
|
||||||
QString m_unitString;
|
QString m_unitString;
|
||||||
QVariant m_minValue;
|
QVariant m_minValue;
|
||||||
QVariant m_maxValue;
|
QVariant m_maxValue;
|
||||||
|
|||||||
@ -87,6 +87,8 @@ QVariant StateTypes::data(const QModelIndex &index, int role) const
|
|||||||
return stateType->unitString();
|
return stateType->unitString();
|
||||||
case RoleUnit:
|
case RoleUnit:
|
||||||
return stateType->unit();
|
return stateType->unit();
|
||||||
|
case RoleIOType:
|
||||||
|
return stateType->ioType();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -110,6 +112,17 @@ StateType *StateTypes::findByName(const QString &name) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<StateType *> StateTypes::ioStateTypes(Types::IOType ioType) const
|
||||||
|
{
|
||||||
|
QList<StateType*> ret;
|
||||||
|
foreach (StateType* stateType, m_stateTypes) {
|
||||||
|
if (stateType->ioType() == ioType) {
|
||||||
|
ret.append(stateType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void StateTypes::clearModel()
|
void StateTypes::clearModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
@ -129,6 +142,7 @@ QHash<int, QByteArray> StateTypes::roleNames() const
|
|||||||
roles[RoleDefaultValue] = "defaultValue";
|
roles[RoleDefaultValue] = "defaultValue";
|
||||||
roles[RoleUnitString] = "unitString";
|
roles[RoleUnitString] = "unitString";
|
||||||
roles[RoleUnit] = "unit";
|
roles[RoleUnit] = "unit";
|
||||||
|
roles[RoleIOType] = "ioType";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -49,10 +49,11 @@ public:
|
|||||||
RoleType,
|
RoleType,
|
||||||
RoleDefaultValue,
|
RoleDefaultValue,
|
||||||
RoleUnit,
|
RoleUnit,
|
||||||
RoleUnitString
|
RoleUnitString,
|
||||||
|
RoleIOType,
|
||||||
};
|
};
|
||||||
|
|
||||||
StateTypes(QObject *parent = 0);
|
StateTypes(QObject *parent = nullptr);
|
||||||
|
|
||||||
QList<StateType *> stateTypes();
|
QList<StateType *> stateTypes();
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE StateType *findByName(const QString &name) const;
|
Q_INVOKABLE StateType *findByName(const QString &name) const;
|
||||||
|
|
||||||
|
QList<StateType*> ioStateTypes(Types::IOType ioType) const;
|
||||||
|
|
||||||
void clearModel();
|
void clearModel();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
140
libnymea-app/types/statetypesproxy.cpp
Normal file
140
libnymea-app/types/statetypesproxy.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "statetypesproxy.h"
|
||||||
|
|
||||||
|
StateTypesProxy::StateTypesProxy(QObject *parent) : QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StateTypes *StateTypesProxy::stateTypes() const
|
||||||
|
{
|
||||||
|
return m_stateTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateTypesProxy::setStateTypes(StateTypes *stateTypes)
|
||||||
|
{
|
||||||
|
if (m_stateTypes != stateTypes) {
|
||||||
|
m_stateTypes = stateTypes;
|
||||||
|
setSourceModel(stateTypes);
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateTypesProxy::digitalInputs() const
|
||||||
|
{
|
||||||
|
return m_digitalInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateTypesProxy::setDigitalInputs(bool digitalInputs)
|
||||||
|
{
|
||||||
|
if (m_digitalInputs != digitalInputs) {
|
||||||
|
m_digitalInputs = digitalInputs;
|
||||||
|
emit digitalInputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateTypesProxy::digitalOutputs() const
|
||||||
|
{
|
||||||
|
return m_digitalOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateTypesProxy::setDigitalOutputs(bool digitalOutputs)
|
||||||
|
{
|
||||||
|
if (m_digitalOutputs != digitalOutputs) {
|
||||||
|
m_digitalOutputs = digitalOutputs;
|
||||||
|
emit digitalOutputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateTypesProxy::analogInputs() const
|
||||||
|
{
|
||||||
|
return m_analogInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateTypesProxy::setAnalogInputs(bool analogInputs)
|
||||||
|
{
|
||||||
|
if (m_analogInputs != analogInputs) {
|
||||||
|
m_analogInputs = analogInputs;
|
||||||
|
emit analogInputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateTypesProxy::analogOutputs() const
|
||||||
|
{
|
||||||
|
return m_analogOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateTypesProxy::setAnalogOutputs(bool analogOutputs)
|
||||||
|
{
|
||||||
|
if (m_analogOutputs != analogOutputs) {
|
||||||
|
m_analogOutputs = analogOutputs;
|
||||||
|
emit analogOutputsChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateType *StateTypesProxy::get(int index) const
|
||||||
|
{
|
||||||
|
return m_stateTypes->get(mapToSource(this->index(index, 0)).row());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateTypesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(source_parent)
|
||||||
|
|
||||||
|
if (!m_digitalInputs && !m_digitalOutputs && !m_analogInputs && !m_analogOutputs) {
|
||||||
|
// filtering disabled
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateType* stateType = m_stateTypes->get(source_row);
|
||||||
|
switch (stateType->ioType()) {
|
||||||
|
case Types::IOTypeNone:
|
||||||
|
return false;
|
||||||
|
case Types::IOTypeDigitalInput:
|
||||||
|
return m_digitalInputs;
|
||||||
|
case Types::IOTypeDigitalOutput:
|
||||||
|
return m_digitalOutputs;
|
||||||
|
case Types::IOTypeAnalogInput:
|
||||||
|
return m_analogInputs;
|
||||||
|
case Types::IOTypeAnalogOutput:
|
||||||
|
return m_analogOutputs;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
89
libnymea-app/types/statetypesproxy.h
Normal file
89
libnymea-app/types/statetypesproxy.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef STATETYPESPROXY_H
|
||||||
|
#define STATETYPESPROXY_H
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
#include "statetypes.h"
|
||||||
|
|
||||||
|
class StateTypesProxy : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(StateTypes* stateTypes READ stateTypes WRITE setStateTypes NOTIFY stateTypesChanged)
|
||||||
|
Q_PROPERTY(bool digitalInputs READ digitalInputs WRITE setDigitalInputs NOTIFY digitalInputsChanged)
|
||||||
|
Q_PROPERTY(bool digitalOutputs READ digitalOutputs WRITE setDigitalOutputs NOTIFY digitalOutputsChanged)
|
||||||
|
Q_PROPERTY(bool analogInputs READ analogInputs WRITE setAnalogInputs NOTIFY analogInputsChanged)
|
||||||
|
Q_PROPERTY(bool analogOutputs READ analogOutputs WRITE setAnalogOutputs NOTIFY analogOutputsChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StateTypesProxy(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
StateTypes* stateTypes() const;
|
||||||
|
void setStateTypes(StateTypes *stateTypes);
|
||||||
|
|
||||||
|
bool digitalInputs() const;
|
||||||
|
void setDigitalInputs(bool digitalInputs);
|
||||||
|
|
||||||
|
bool digitalOutputs() const;
|
||||||
|
void setDigitalOutputs(bool digitalOutputs);
|
||||||
|
|
||||||
|
bool analogInputs() const;
|
||||||
|
void setAnalogInputs(bool analogInputs);
|
||||||
|
|
||||||
|
bool analogOutputs() const;
|
||||||
|
void setAnalogOutputs(bool analogOutputs);
|
||||||
|
|
||||||
|
Q_INVOKABLE StateType* get(int index) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
void stateTypesChanged();
|
||||||
|
void digitalInputsChanged();
|
||||||
|
void digitalOutputsChanged();
|
||||||
|
void analogInputsChanged();
|
||||||
|
void analogOutputsChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateTypes *m_stateTypes = nullptr;
|
||||||
|
|
||||||
|
bool m_digitalInputs = false;
|
||||||
|
bool m_digitalOutputs = false;
|
||||||
|
bool m_analogInputs = false;
|
||||||
|
bool m_analogOutputs = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATETYPESPROXY_H
|
||||||
@ -120,6 +120,15 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(Unit)
|
Q_ENUM(Unit)
|
||||||
|
|
||||||
|
enum IOType {
|
||||||
|
IOTypeNone,
|
||||||
|
IOTypeDigitalInput,
|
||||||
|
IOTypeDigitalOutput,
|
||||||
|
IOTypeAnalogInput,
|
||||||
|
IOTypeAnalogOutput
|
||||||
|
};
|
||||||
|
Q_ENUM(IOType)
|
||||||
|
|
||||||
enum UnitSystem {
|
enum UnitSystem {
|
||||||
UnitSystemMetric,
|
UnitSystemMetric,
|
||||||
UnitSystemImperial
|
UnitSystemImperial
|
||||||
|
|||||||
@ -218,5 +218,6 @@
|
|||||||
<file>ui/images/smartlock.svg</file>
|
<file>ui/images/smartlock.svg</file>
|
||||||
<file>ui/images/key.svg</file>
|
<file>ui/images/key.svg</file>
|
||||||
<file>ui/images/browser/MediaBrowserIconRadioParadise.svg</file>
|
<file>ui/images/browser/MediaBrowserIconRadioParadise.svg</file>
|
||||||
|
<file>ui/images/io-connections.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -77,7 +77,9 @@ ItemDelegate {
|
|||||||
case "uint":
|
case "uint":
|
||||||
case "int":
|
case "int":
|
||||||
case "double":
|
case "double":
|
||||||
if (root.paramType.minValue && root.paramType.maxValue) {
|
if (root.paramType.allowedValues.length > 0) {
|
||||||
|
return comboBoxComponent;
|
||||||
|
} else if (root.paramType.minValue !== undefined && root.paramType.maxValue !== undefined) {
|
||||||
return sliderComponent;
|
return sliderComponent;
|
||||||
} else {
|
} else {
|
||||||
return spinnerComponent;
|
return spinnerComponent;
|
||||||
@ -238,11 +240,18 @@ ItemDelegate {
|
|||||||
Component {
|
Component {
|
||||||
id: comboBoxComponent
|
id: comboBoxComponent
|
||||||
ComboBox {
|
ComboBox {
|
||||||
|
id: control
|
||||||
|
Layout.fillWidth: true
|
||||||
model: root.paramType.allowedValues
|
model: root.paramType.allowedValues
|
||||||
currentIndex: root.paramType.allowedValues.indexOf(root.param.value)
|
displayText: currentText + ( root.paramType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.paramType.unit) : "")
|
||||||
|
currentIndex: root.paramType.allowedValues.indexOf(root.param.value !== undefined ? root.param.value : root.paramType.defaultValue)
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
width: control.width
|
||||||
|
text: Types.toUiValue(modelData, root.paramType.unit) + ( root.paramType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.paramType.unit) : "")
|
||||||
|
highlighted: control.highlightedIndex === index
|
||||||
|
}
|
||||||
onActivated: {
|
onActivated: {
|
||||||
root.param.value = root.paramType.allowedValues[index]
|
root.param.value = root.paramType.allowedValues[index]
|
||||||
print("setting value to", root.param.value)
|
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (root.value === undefined) {
|
if (root.value === undefined) {
|
||||||
|
|||||||
20
nymea-app/ui/images/io-connections.svg
Normal file
20
nymea-app/ui/images/io-connections.svg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg id="svg4874" width="96" height="96" version="1.1" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<metadata id="metadata4879">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g id="layer1" transform="translate(67.857 -78.505)">
|
||||||
|
<rect id="rect4782-638" transform="rotate(90)" x="78.505" y="-28.143" width="96" height="96" style="color:#000000;fill:none"/>
|
||||||
|
<path id="rect4747-4-8" d="m8.1428 140.51 1 4h-45v-4z" style="color:#000000;fill:#808080"/>
|
||||||
|
<path id="path4175" d="m-47.857 108.5-1 4h45v-4z" style="color:#000000;fill:#808080"/>
|
||||||
|
<path id="path5839" d="m-5.8725 130.5 0.0076 24c3.65-1.6687 7.3659-3.5359 11.149-5.5987 3.7477-2.0678 7.3628-4.2005 10.843-6.4002-3.4801-2.1558-7.0952-4.2681-10.843-6.3358-3.7853-2.0639-7.5033-3.9519-11.155-5.6652z" style="color:#000000;fill:#808080"/>
|
||||||
|
<path id="path5856" d="m-33.874 122.52-0.0076-24c-3.65 1.6687-7.3659 3.5359-11.149 5.5987-3.7477 2.0678-7.3628 4.2005-10.843 6.4003 3.48 2.1558 7.0951 4.2681 10.843 6.3358 3.7853 2.0639 7.5033 3.9519 11.155 5.6651z" style="color:#000000;fill:#808080"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -35,7 +35,7 @@ import Nymea 1.0
|
|||||||
import "../components"
|
import "../components"
|
||||||
import "../delegates"
|
import "../delegates"
|
||||||
|
|
||||||
Page {
|
SettingsPageBase {
|
||||||
id: root
|
id: root
|
||||||
property Device device: null
|
property Device device: null
|
||||||
readonly property DeviceClass deviceClass: device ? device.deviceClass : null
|
readonly property DeviceClass deviceClass: device ? device.deviceClass : null
|
||||||
@ -110,120 +110,174 @@ Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Flickable {
|
|
||||||
anchors.fill: parent
|
|
||||||
contentHeight: contentColumn.implicitHeight
|
|
||||||
|
|
||||||
ColumnLayout {
|
Label {
|
||||||
id: contentColumn
|
Layout.fillWidth: true
|
||||||
width: parent.width
|
Layout.margins: app.margins
|
||||||
|
text: qsTr("Information")
|
||||||
Label {
|
color: app.accentColor
|
||||||
Layout.fillWidth: true
|
}
|
||||||
Layout.margins: app.margins
|
RowLayout {
|
||||||
text: qsTr("Information")
|
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||||
color: app.accentColor
|
Label {
|
||||||
}
|
text: qsTr("Vendor:")
|
||||||
RowLayout {
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
|
||||||
Label {
|
|
||||||
text: qsTr("Vendor:")
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
text: engine.deviceManager.vendors.getVendor(root.deviceClass.vendorId).displayName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
|
||||||
Label {
|
|
||||||
text: qsTr("Type")
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
text: root.deviceClass.displayName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: app.margins
|
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
Layout.topMargin: app.margins
|
|
||||||
text: qsTr("Parameters")
|
|
||||||
color: app.accentColor
|
|
||||||
visible: root.deviceClass.paramTypes.count > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: root.device.params
|
|
||||||
delegate: ParamDelegate {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
paramType: root.deviceClass.paramTypes.getParamType(model.id)
|
|
||||||
param: root.device.params.get(index)
|
|
||||||
writable: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: app.margins
|
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
Layout.topMargin: app.margins
|
|
||||||
text: qsTr("Settings")
|
|
||||||
color: app.accentColor
|
|
||||||
visible: root.deviceClass.settingsTypes.count > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: settingsRepeater
|
|
||||||
model: root.device.settings
|
|
||||||
delegate: ParamDelegate {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
paramType: root.deviceClass.settingsTypes.getParamType(model.id)
|
|
||||||
value: root.device.settings.get(index).value
|
|
||||||
writable: true
|
|
||||||
property bool dirty: root.device.settings.get(index).value !== value
|
|
||||||
onDirtyChanged: settingsRepeater.checkDirty()
|
|
||||||
}
|
|
||||||
function checkDirty() {
|
|
||||||
for (var i = 0; i < settingsRepeater.count; i++) {
|
|
||||||
if (settingsRepeater.itemAt(i).dirty) {
|
|
||||||
dirty = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dirty = false;
|
|
||||||
}
|
|
||||||
property bool dirty: false
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: app.margins
|
|
||||||
Layout.rightMargin: app.margins
|
|
||||||
text: qsTr("Apply")
|
|
||||||
enabled: settingsRepeater.dirty
|
|
||||||
visible: settingsRepeater.count > 0
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
var params = []
|
|
||||||
for (var i = 0; i < settingsRepeater.count; i++) {
|
|
||||||
if (!settingsRepeater.itemAt(i).dirty) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var setting = {}
|
|
||||||
setting["paramTypeId"] = settingsRepeater.itemAt(i).param.paramTypeId
|
|
||||||
setting["value"] = settingsRepeater.itemAt(i).param.value
|
|
||||||
params.push(setting)
|
|
||||||
}
|
|
||||||
|
|
||||||
engine.deviceManager.setDeviceSettings(root.device.id, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ThinDivider {}
|
|
||||||
}
|
}
|
||||||
|
Label {
|
||||||
|
text: engine.deviceManager.vendors.getVendor(root.deviceClass.vendorId).displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||||
|
Label {
|
||||||
|
text: qsTr("Type")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.deviceClass.displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins
|
||||||
|
Layout.rightMargin: app.margins
|
||||||
|
Layout.topMargin: app.margins
|
||||||
|
text: qsTr("Parameters")
|
||||||
|
color: app.accentColor
|
||||||
|
visible: root.deviceClass.paramTypes.count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.device.params
|
||||||
|
delegate: ParamDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
paramType: root.deviceClass.paramTypes.getParamType(model.id)
|
||||||
|
param: root.device.params.get(index)
|
||||||
|
writable: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins
|
||||||
|
Layout.rightMargin: app.margins
|
||||||
|
Layout.topMargin: app.margins
|
||||||
|
text: qsTr("Input/Output Connections")
|
||||||
|
color: app.accentColor
|
||||||
|
visible: ioModel.count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
StateTypesProxy {
|
||||||
|
id: ioModel
|
||||||
|
stateTypes: root.deviceClass.stateTypes
|
||||||
|
digitalInputs: true
|
||||||
|
digitalOutputs: true
|
||||||
|
analogInputs: true
|
||||||
|
analogOutputs: true
|
||||||
|
}
|
||||||
|
Repeater {
|
||||||
|
model: ioModel
|
||||||
|
delegate: NymeaListItemDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
iconName: "../images/io-connections.svg"
|
||||||
|
text: model.displayName
|
||||||
|
subText: {
|
||||||
|
if (ioStateType.ioType == Types.IOTypeDigitalInput || ioStateType.ioType == Types.IOTypeAnalogInput) {
|
||||||
|
if (inputConnectionWatcher.ioConnection) {
|
||||||
|
return "%1: %2".arg(inputConnectionWatcher.outputThing.name).arg(inputConnectionWatcher.outputStateType.displayName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (outputConnectionWatcher.ioConnection) {
|
||||||
|
return "%1: %2".arg(outputConnectionWatcher.inputThing.name).arg(outputConnectionWatcher.inputStateType.displayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return qsTr("Not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
property StateType ioStateType: ioModel.get(index)
|
||||||
|
|
||||||
|
IOInputConnectionWatcher {
|
||||||
|
id: inputConnectionWatcher
|
||||||
|
ioConnections: engine.deviceManager.ioConnections
|
||||||
|
inputThingId: root.device.id
|
||||||
|
inputStateTypeId: ioStateType.id
|
||||||
|
property Device outputThing: ioConnection ? engine.deviceManager.devices.getDevice(ioConnection.outputThingId) : null
|
||||||
|
property StateType outputStateType: ioConnection ? outputThing.deviceClass.stateTypes.getStateType(ioConnection.outputStateTypeId) : null
|
||||||
|
}
|
||||||
|
IOOutputConnectionWatcher {
|
||||||
|
id: outputConnectionWatcher
|
||||||
|
ioConnections: engine.deviceManager.ioConnections
|
||||||
|
outputThingId: root.device.id
|
||||||
|
outputStateTypeId: ioStateType.id
|
||||||
|
property Device inputThing: ioConnection ? engine.deviceManager.devices.getDevice(ioConnection.inputThingId) : null
|
||||||
|
property StateType inputStateType: ioConnection ? inputThing.deviceClass.stateTypes.getStateType(ioConnection.inputStateTypeId) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var popup = ioConnectionsDialogComponent.createObject(app, {ioStateType: ioStateType, inputWatcher: inputConnectionWatcher, outputWatcher: outputConnectionWatcher})
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins
|
||||||
|
Layout.rightMargin: app.margins
|
||||||
|
Layout.topMargin: app.margins
|
||||||
|
text: qsTr("Settings")
|
||||||
|
color: app.accentColor
|
||||||
|
visible: root.deviceClass.settingsTypes.count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: settingsRepeater
|
||||||
|
model: root.device.settings
|
||||||
|
delegate: ParamDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
paramType: root.deviceClass.settingsTypes.getParamType(model.id)
|
||||||
|
value: root.device.settings.get(index).value
|
||||||
|
writable: true
|
||||||
|
property bool dirty: root.device.settings.get(index).value !== value
|
||||||
|
onDirtyChanged: settingsRepeater.checkDirty()
|
||||||
|
}
|
||||||
|
function checkDirty() {
|
||||||
|
for (var i = 0; i < settingsRepeater.count; i++) {
|
||||||
|
if (settingsRepeater.itemAt(i).dirty) {
|
||||||
|
dirty = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
property bool dirty: false
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins
|
||||||
|
Layout.rightMargin: app.margins
|
||||||
|
text: qsTr("Apply")
|
||||||
|
enabled: settingsRepeater.dirty
|
||||||
|
visible: settingsRepeater.count > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var params = []
|
||||||
|
for (var i = 0; i < settingsRepeater.count; i++) {
|
||||||
|
if (!settingsRepeater.itemAt(i).dirty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var setting = {}
|
||||||
|
setting["paramTypeId"] = settingsRepeater.itemAt(i).param.paramTypeId
|
||||||
|
setting["value"] = settingsRepeater.itemAt(i).param.value
|
||||||
|
params.push(setting)
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.deviceManager.setDeviceSettings(root.device.id, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
@ -264,4 +318,130 @@ Page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: ioConnectionsDialogComponent
|
||||||
|
MeaDialog {
|
||||||
|
id: ioConnectionDialog
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel | Dialog.Reset
|
||||||
|
|
||||||
|
title: qsTr("Connect Inputs/Outputs")
|
||||||
|
|
||||||
|
property StateType ioStateType: null
|
||||||
|
property IOInputConnectionWatcher inputWatcher: null
|
||||||
|
property IOOutputConnectionWatcher outputWatcher: null
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Connect \"%1\" to:").arg(ioConnectionDialog.ioStateType.displayName)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Label { text: "\n" } // Fake in some spacing
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
columns: (ioConnectionDialog.width / 400) * 2
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Thing")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: ioThingComboBox
|
||||||
|
model: DevicesProxy {
|
||||||
|
id: connectableIODevices
|
||||||
|
engine: _engine
|
||||||
|
showDigitalInputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalOutput
|
||||||
|
showDigitalOutputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput
|
||||||
|
showAnalogInputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogOutput
|
||||||
|
showAnalogOutputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput
|
||||||
|
}
|
||||||
|
textRole: "name"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var i = 0; i < connectableIODevices.count; i++) {
|
||||||
|
if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) {
|
||||||
|
if (connectableIODevices.get(i).id === ioConnectionDialog.inputWatcher.ioConnection.outputThingId) {
|
||||||
|
ioThingComboBox.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (connectableIODevices.get(i).id === ioConnectionDialog.outputWatcher.ioConnection.inputThingId) {
|
||||||
|
ioThingComboBox.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) ? qsTr("Output") : qsTr("Input")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: ioStateComboBox
|
||||||
|
model: StateTypesProxy {
|
||||||
|
id: connectableStateTypes
|
||||||
|
stateTypes: connectableIODevices.get(ioThingComboBox.currentIndex).deviceClass.stateTypes
|
||||||
|
digitalInputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalOutput
|
||||||
|
digitalOutputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput
|
||||||
|
analogInputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogOutput
|
||||||
|
analogOutputs: ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput
|
||||||
|
}
|
||||||
|
textRole: "displayName"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onCountChanged: {
|
||||||
|
// print("loading for:", ioConnectionDialog.inputWatcher.ioConnection.outputStateTypeId)
|
||||||
|
for (var i = 0; i < connectableStateTypes.count; i++) {
|
||||||
|
print("checking:", connectableStateTypes.get(i).id)
|
||||||
|
if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) {
|
||||||
|
if (connectableStateTypes.get(i).id === ioConnectionDialog.inputWatcher.ioConnection.outputStateTypeId) {
|
||||||
|
ioStateComboBox.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (connectableStateTypes.get(i).id === ioConnectionDialog.outputWatcher.ioConnection.inputStateTypeId) {
|
||||||
|
ioStateComboBox.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
var inputThingId;
|
||||||
|
var inputStateTypeId;
|
||||||
|
var outputThingId;
|
||||||
|
var outputStateTypeId;
|
||||||
|
if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput
|
||||||
|
|| ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) {
|
||||||
|
inputThingId = root.device.id;
|
||||||
|
inputStateTypeId = ioConnectionDialog.ioStateType.id;
|
||||||
|
outputThingId = connectableIODevices.get(ioThingComboBox.currentIndex).id;
|
||||||
|
outputStateTypeId = connectableStateTypes.get(ioStateComboBox.currentIndex).id;
|
||||||
|
} else {
|
||||||
|
inputThingId = connectableIODevices.get(ioThingComboBox.currentIndex).id;
|
||||||
|
inputStateTypeId = connectableStateTypes.get(ioStateComboBox.currentIndex).id;
|
||||||
|
outputThingId = root.device.id;
|
||||||
|
outputStateTypeId = ioConnectionDialog.ioStateType.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("connecting", inputThingId, inputStateTypeId, outputThingId, outputStateTypeId)
|
||||||
|
engine.deviceManager.connectIO(inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||||
|
}
|
||||||
|
onReset: {
|
||||||
|
if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput
|
||||||
|
|| ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) {
|
||||||
|
engine.deviceManager.disconnectIO(ioConnectionDialog.inputWatcher.ioConnection.id);
|
||||||
|
} else {
|
||||||
|
engine.deviceManager.disconnectIO(ioConnectionDialog.outputWatcher.ioConnection.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
ioConnectionDialog.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user