Merge PR #1067: Make dashboard wizard usable on small screens

pull/1069/head
jenkins 2023-10-11 23:59:05 +02:00
commit d285e05691
24 changed files with 775 additions and 118 deletions

View File

@ -160,9 +160,10 @@ void InterfacesModel::syncInterfaces()
}
}
qWarning() << "syncing for interfaces:" << m_shownInterfaces;
QStringList interfacesInSource;
foreach (ThingClass *dc, thingClasses) {
// qDebug() << "thing" <<dc->name() << "has interfaces" << dc->interfaces();
// qWarning() << "thing" <<dc->name() << "has interfaces" << dc->interfaces();
bool isInShownIfaces = false;
foreach (const QString &interface, dc->interfaces()) {
@ -173,6 +174,7 @@ void InterfacesModel::syncInterfaces()
if (!interfacesInSource.contains(interface)) {
interfacesInSource.append(interface);
}
// qWarning() << "yes" << interface;
isInShownIfaces = true;
}
if (m_showUncategorized && !isInShownIfaces && !interfacesInSource.contains("uncategorized")) {

View File

@ -180,3 +180,23 @@ QUuid DashboardStateItem::stateTypeId() const
{
return m_stateTypeId;
}
DashboardSensorItem::DashboardSensorItem(const QUuid &thingId, const QStringList &interfaces, QObject *parent):
DashboardItem("sensor", parent),
m_thingId(thingId),
m_interfaces(interfaces)
{
if (interfaces.count() > 1) {
setColumnSpan(2);
}
}
QUuid DashboardSensorItem::thingId() const
{
return m_thingId;
}
QStringList DashboardSensorItem::interfaces() const
{
return m_interfaces;
}

View File

@ -124,4 +124,18 @@ private:
QUuid m_stateTypeId;
};
class DashboardSensorItem: public DashboardItem
{
Q_OBJECT
Q_PROPERTY(QUuid thingId READ thingId CONSTANT)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
public:
explicit DashboardSensorItem(const QUuid &thingId, const QStringList &interfaces, QObject *parent = nullptr);
QUuid thingId() const;
QStringList interfaces() const;
private:
QUuid m_thingId;
QStringList m_interfaces;
};
#endif // DASHBOARDITEM_H

View File

@ -91,6 +91,12 @@ void DashboardModel::addStateItem(const QUuid &thingId, const QUuid &stateTypeId
addItem(item, index);
}
void DashboardModel::addSensorItem(const QUuid &thingId, const QStringList &interfaces, int index)
{
DashboardSensorItem *item = new DashboardSensorItem(thingId, interfaces, this);
addItem(item, index);
}
void DashboardModel::removeItem(int index)
{
qWarning() << "removing" << index;
@ -145,6 +151,8 @@ void DashboardModel::loadFromJson(const QByteArray &json)
item = new DashboardWebViewItem(itemMap.value("url").toUrl(), itemMap.value("interactive", false).toBool(), this);
} else if (type == "state") {
item = new DashboardStateItem(itemMap.value("thingId").toUuid(), itemMap.value("stateTypeId").toUuid(), this);
} else if (type == "sensor") {
item = new DashboardSensorItem(itemMap.value("thingId").toUuid(), itemMap.value("interfaces").toStringList(), this);
} else {
qWarning() << "Dashboard item type" << type << "is not implemented. Skipping...";
continue;
@ -188,6 +196,10 @@ QByteArray DashboardModel::toJson() const
if (webViewItem->interactive()) {
map.insert("interactive", true);
}
} else if (item->type() == "sensor") {
DashboardSensorItem *sensorItem = dynamic_cast<DashboardSensorItem*>(item);
map.insert("thingId", sensorItem->thingId());
map.insert("interfaces", sensorItem->interfaces());
} else if (item->type() == "state") {
DashboardStateItem *stateItem = dynamic_cast<DashboardStateItem*>(item);
map.insert("thingId", stateItem->thingId());

View File

@ -31,6 +31,7 @@ public:
Q_INVOKABLE void addSceneItem(const QUuid &ruleId, int index = -1);
Q_INVOKABLE void addWebViewItem(const QUrl &url, int columnSpan, int rowSpan, bool interactive, int index = -1);
Q_INVOKABLE void addStateItem(const QUuid &thingId, const QUuid &stateTypeId, int index = -1);
Q_INVOKABLE void addSensorItem(const QUuid &thingId, const QStringList &interfaces, int index = -1);
Q_INVOKABLE void removeItem(int index);
Q_INVOKABLE void move(int from, int to);

View File

@ -183,6 +183,7 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<DashboardSceneItem>("Nymea", 1, 0, "DashboardSceneItem", "");
qmlRegisterUncreatableType<DashboardWebViewItem>("Nymea", 1, 0, "DashboardWebViewItem", "");
qmlRegisterUncreatableType<DashboardStateItem>("Nymea", 1, 0, "DashboardStateItem", "");
qmlRegisterUncreatableType<DashboardSensorItem>("Nymea", 1, 0, "DashboardSensorItem", "");
qmlRegisterSingletonType<PrivacyPolicyHelper>("NymeaApp.Utils", 1, 0, "PrivacyPolicyHelper", PrivacyPolicyHelper::qmlProvider);
qmlRegisterType<QHashQml>("NymeaApp.Utils", 1, 0, "QHash");

View File

@ -315,5 +315,6 @@
<file>ui/devicepages/ActionLogPage.qml</file>
<file>ui/devicepages/EventLogPage.qml</file>
<file>ui/mainviews/dashboard/DashboardStateDelegate.qml</file>
<file>ui/mainviews/dashboard/DashboardSensorDelegate.qml</file>
</qresource>
</RCC>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation>Tato akce není zaznamenána.</translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished">Žádná data</translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1227,6 +1235,18 @@
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished">Stav</translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2110,6 +2130,14 @@
<source>This event is not being logged.</source>
<translation>Tato událost není zaznamenána.</translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished">Žádná data</translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3985,6 +4013,14 @@ Prosím zkuste to znovu.</translation>
<source>Set up another...</source>
<translation>Nastavit další...</translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6582,6 +6618,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation>Celková vráceno: %1 kWh</translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6793,10 +6833,6 @@ Toto prosím používejte pouze v případě, že jste si jisti tím co děláte
<source>Details</source>
<translation>Detaily</translation>
</message>
<message>
<source>Logs</source>
<translation>Protokoly</translation>
</message>
<message>
<source>Mark as favorite</source>
<translation>Označit jako oblíbené</translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation>Diese Aktion wird nicht protokolliert.</translation>
</message>
<message>
<source>No data</source>
<translation>Keine Daten</translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation>Diese Aktion wurde noch nicht ausgeführt.</translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1226,6 +1234,18 @@
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>Sensor</source>
<translation>Sensor</translation>
</message>
<message>
<source>State</source>
<translation>Zustand</translation>
</message>
<message>
<source>Select depiction</source>
<translation>Darstellung auswählen</translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2109,6 +2129,14 @@
<source>This event is not being logged.</source>
<translation>Dieses Ereignis wird nicht protokolliert.</translation>
</message>
<message>
<source>No data</source>
<translation>Keine Daten</translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation>Dieses Ereignis ist noch nicht aufgetreten.</translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3967,6 +3995,14 @@ Bitte versuche es erneut.</translation>
<source>Set up another...</source>
<translation>Ein weiteres einrichten...</translation>
</message>
<message>
<source>Are you sure?</source>
<translation>Bist Du sicher?</translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation>Möchtest Du dich von %1 abmelden und die Verbindung entfernen?</translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6563,6 +6599,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation>Gesamte Netzeinspeisung: %1 kWh</translation>
</message>
<message>
<source>The battery is empty</source>
<translation>Die Batterie ist leer</translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6773,10 +6813,6 @@ Bitte benutze diese Funktion nur wenn Du sicher bist, dass es das ist was Du mö
<source>Details</source>
<translation>Details</translation>
</message>
<message>
<source>Logs</source>
<translation>Protokoll</translation>
</message>
<message>
<source>Mark as favorite</source>
<translation>Als Favorit</translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1226,6 +1234,18 @@
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2103,6 +2123,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3960,6 +3988,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6550,6 +6586,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6757,10 +6797,6 @@ Please only use this if you are sure you want this and consider reporting the is
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark as favorite</source>
<translation type="unfinished"></translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1226,6 +1234,18 @@
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2103,6 +2123,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3960,6 +3988,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6550,6 +6586,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6757,10 +6797,6 @@ Please only use this if you are sure you want this and consider reporting the is
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark as favorite</source>
<translation type="unfinished"></translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1226,6 +1234,18 @@
<source>OK</source>
<translation type="unfinished">Ok</translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2103,6 +2123,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3960,6 +3988,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6550,6 +6586,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6757,10 +6797,6 @@ Please only use this if you are sure you want this and consider reporting the is
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark as favorite</source>
<translation type="unfinished"></translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1225,6 +1233,18 @@
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2105,6 +2125,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3946,6 +3974,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6537,6 +6573,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6743,10 +6783,6 @@ Please only use this if you are sure you want this and consider reporting the is
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark as favorite</source>
<translation type="unfinished"> </translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation>Van deze actie wordt geen log bijgehouden.</translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished">Geen gegevens</translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1226,6 +1234,18 @@
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished">Status</translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2111,6 +2131,14 @@
<source>This event is not being logged.</source>
<translation>Van deze gebeurtenis wordt geen log bijgehouden.</translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished">Geen gegevens</translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3971,6 +3999,14 @@ Probeer het nog een keer.</translation>
<source>Set up another...</source>
<translation>Stel een andere in...</translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6568,6 +6604,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation>Totaal teruggegeven aan het net: %1 kWh</translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6779,10 +6819,6 @@ Als je fouten in de niet-officiële software vindt, geef deze dan door aan de on
<source>Details</source>
<translation>Details</translation>
</message>
<message>
<source>Logs</source>
<translation>Logs</translation>
</message>
<message>
<source>Mark as favorite</source>
<translation>Maak favoriet</translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1225,6 +1233,18 @@
<source>OK</source>
<translation>Tamam</translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished">Durum</translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2105,6 +2125,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3945,6 +3973,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation>Başka bir tane ayarla...</translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6536,6 +6572,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6744,10 +6784,6 @@ Lütfen bunu istediğinizden eminseniz kullanın ve yayınlanmamış kanalları
<source>Details</source>
<translation>Detaylar</translation>
</message>
<message>
<source>Logs</source>
<translation>Kayıtlar</translation>
</message>
<message>
<source>Mark as favorite</source>
<translation>Favori olarak işaretle</translation>

View File

@ -175,6 +175,14 @@
<source>This action is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This action has not been executed yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedConnectionInterfacesPage</name>
@ -1225,6 +1233,18 @@
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sensor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>State</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select depiction</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardFolderDelegate</name>
@ -2102,6 +2122,14 @@
<source>This event is not being logged.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This event has not been triggered yet.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FavoritesView</name>
@ -3942,6 +3970,14 @@ Please try again.</source>
<source>Set up another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to log out from %1 and remove it from your connections?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainPage</name>
@ -6532,6 +6568,10 @@ A consumer, not consuming anything</extracomment>
<source>Total return: %1 kWh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The battery is empty</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StateChart</name>
@ -6738,10 +6778,6 @@ Please only use this if you are sure you want this and consider reporting the is
<source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark as favorite</source>
<translation type="unfinished"></translation>

View File

@ -12,33 +12,6 @@ Item {
property Thing thing: null
property string interfaceName: ""
property var interfaceStateMap: {
"temperaturesensor": "temperature",
"humiditysensor": "humidity",
"pressuresensor": "pressure",
"moisturesensor": "moisture",
"lightsensor": "lightIntensity",
"conductivitysensor": "conductivity",
"noisesensor": "noise",
"cosensor": "co",
"co2sensor": "co2",
"gassensor": "gasLevel",
"presencesensor": "isPresent",
"daylightsensor": "daylight",
"closablesensor": "closed",
"watersensor": "waterDetected",
"firesensor": "fireDetected",
"waterlevelsensor": "waterLevel",
"phsensor": "ph",
"o2sensor": "o2saturation",
"o3sensor": "o3",
"orpsensor": "orp",
"vocsensor": "voc",
"cosensor": "co",
"pm10sensor": "pm10",
"pm25sensor": "pm25",
"no2sensor": "no2"
}
CircleBackground {
id: background
@ -46,8 +19,8 @@ Item {
width: Math.min(parent.width, parent.height) - Style.margins
height: width
readonly property StateType sensorStateType: root.thing ? root.thing.thingClass.stateTypes.findByName(interfaceStateMap[root.interfaceName]) : null
readonly property State sensorState: root.thing ? root.thing.stateByName(interfaceStateMap[interfaceName]) : null
readonly property StateType sensorStateType: root.thing ? root.thing.thingClass.stateTypes.findByName(NymeaUtils.sensorInterfaceStateMap[root.interfaceName]) : null
readonly property State sensorState: root.thing ? root.thing.stateByName(NymeaUtils.sensorInterfaceStateMap[interfaceName]) : null
onColor: {
if (root.interfaceName == "closablesensor") {
@ -78,8 +51,8 @@ Item {
anchors.centerIn: parent
width: background.contentItem.width
height: background.contentItem.height
property StateType stateType: root.thing.thingClass.stateTypes.findByName(interfaceStateMap[root.interfaceName])
property State state: root.thing.stateByName(interfaceStateMap[root.interfaceName])
property StateType stateType: root.thing.thingClass.stateTypes.findByName(NymeaUtils.sensorInterfaceStateMap[root.interfaceName])
property State state: root.thing.stateByName(NymeaUtils.sensorInterfaceStateMap[root.interfaceName])
property string interfaceName: root.interfaceName
property var minValue: {
if (["temperaturesensor"].indexOf(root.interfaceName) >= 0) {

View File

@ -62,18 +62,18 @@ Item {
sortOrder: Qt.DescendingOrder
Component.onCompleted: {
print("****** completed")
// print("****** completed")
ready = true
update()
}
property bool ready: false
onSourceChanged: {
print("***** source changed")
// print("***** source changed")
update()
}
function update() {
print("*********+ source", source, "start", startTime, "end", endTime, ready)
// print("*********+ source", source, "start", startTime, "end", endTime, ready)
if (ready && source != "") {
fetchLogs()
}
@ -83,10 +83,10 @@ Item {
property double maxValue
onEntriesAddedIdx: {
print("**** entries added", index, count, "entries in series:", valueSeries.count, "in model", logsModel.count)
// print("**** entries added", index, count, "entries in series:", valueSeries.count, "in model", logsModel.count)
for (var i = 0; i < count; i++) {
var entry = logsModel.get(i)
print("entry", entry.timestamp, entry.source, JSON.stringify(entry.values))
// print("entry", entry.timestamp, entry.source, JSON.stringify(entry.values))
zeroSeries.ensureValue(entry.timestamp)
if (root.stateType.type.toLowerCase() == "bool") {

View File

@ -42,6 +42,11 @@ BigThingTile {
id: dataGrid
columns: Math.floor(contentItem.width / 120)
Connections {
target: itemDelegate
onThingChanged: stateModel.update()
}
ListModel {
id: interfacesModel
ListElement { interfaceName: "temperaturesensor"; stateName: "temperature" }
@ -74,8 +79,13 @@ BigThingTile {
}
Repeater {
model: ListModel {
id: stateModel
dynamicRoles: true
Component.onCompleted: {
update()
}
function update() {
for (var i = 0; i < interfacesModel.count; i++) {
if (itemDelegate.thing.thingClass.interfaces.indexOf(interfacesModel.get(i).interfaceName) >= 0) {
append(interfacesModel.get(i))

View File

@ -64,7 +64,8 @@ MainViewBase {
"graph": "DashboardGraphDelegate.qml",
"scene": "DashboardSceneDelegate.qml",
"webview": "DashboardWebViewDelegate.qml",
"state": "DashboardStateDelegate.qml"
"state": "DashboardStateDelegate.qml",
"sensor": "DashboardSensorDelegate.qml"
}
onEditModeChanged: {

View File

@ -37,6 +37,7 @@ import Nymea 1.0
import NymeaApp.Utils 1.0
import "../../components"
import "../../delegates"
import "../../customviews"
NymeaDialog {
id: root
@ -56,55 +57,75 @@ NymeaDialog {
implicitHeight: currentItem.implicitHeight
clip: true
initialItem: ColumnLayout {
id: contentColumn
implicitHeight: childrenRect.height
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Thing")
iconName: "things"
onClicked: {
internalPageStack.push(addThingSelectionComponent)
initialItem: Flickable {
id: flickable
width: internalPageStack.width
implicitHeight: contentColumn.implicitHeight
contentHeight: contentColumn.implicitHeight
contentWidth: width
ScrollBar.vertical: ScrollBar {}
ColumnLayout {
id: contentColumn
width: flickable.width
implicitHeight: childrenRect.height
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Thing")
iconName: "things"
onClicked: {
internalPageStack.push(addThingSelectionComponent)
}
}
}
NymeaItemDelegate {
Layout.fillWidth: true
iconName: "folder"
text: qsTr("Folder")
onClicked: {
internalPageStack.push(addFolderComponent)
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Sensor")
iconName: "sensors"
onClicked: {
internalPageStack.push(addSensorComponent)
}
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("State")
iconName: "state"
onClicked: {
internalPageStack.push(addStateSelectThingComponent)
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("State")
iconName: "state"
onClicked: {
internalPageStack.push(addStateSelectThingComponent)
}
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Chart")
iconName: "chart"
onClicked: {
internalPageStack.push(addGraphSelectThingComponent)
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Chart")
iconName: "chart"
onClicked: {
internalPageStack.push(addGraphSelectThingComponent)
}
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Scene")
iconName: "slideshow"
onClicked: {
internalPageStack.push(addSceneComponent)
NymeaItemDelegate {
Layout.fillWidth: true
iconName: "folder"
text: qsTr("Folder")
onClicked: {
internalPageStack.push(addFolderComponent)
}
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Web view")
iconName: "stock_website"
onClicked: {
internalPageStack.push(addWebViewComponent)
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Scene")
iconName: "slideshow"
onClicked: {
internalPageStack.push(addSceneComponent)
}
}
NymeaItemDelegate {
Layout.fillWidth: true
text: qsTr("Web view")
iconName: "stock_website"
onClicked: {
internalPageStack.push(addWebViewComponent)
}
}
}
}
@ -154,6 +175,168 @@ NymeaDialog {
}
}
Component {
id: addSensorComponent
ColumnLayout {
RowLayout {
Layout.leftMargin: Style.margins
Layout.rightMargin: Style.margins
ColorIcon {
name: "/ui/images/find.svg"
}
TextField {
id: filterTextField
Layout.fillWidth: true
}
}
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: Style.delegateHeight * 6
clip: true
model: ThingsProxy {
id: thingsProxy
engine: _engine
nameFilter: filterTextField.displayText
shownInterfaces: {
var ret = []
for (var key in NymeaUtils.sensorInterfaceStateMap) {
ret.push(key)
}
return ret
}
}
ScrollBar.vertical: ScrollBar {}
delegate: NymeaItemDelegate {
width: parent.width
text: model.name
iconName: app.interfacesToIcon(thingsProxy.get(index).thingClass.interfaces)
progressive: false
onClicked: {
var thing = thingsProxy.get(index)
var availableInterfaces = []
print("checking ifaces", thingsProxy.shownInterfaces, "----", thing.thingClass.interfaces)
for (var i = 0; i < thing.thingClass.interfaces.length; i++) {
var iface = thing.thingClass.interfaces[i]
print("checking", iface)
if (thingsProxy.shownInterfaces.indexOf(iface) >= 0) {
availableInterfaces.push(iface);
}
}
print("matching:", availableInterfaces)
if (availableInterfaces.length == 1) {
root.dashboardModel.addSensorItem(model.id, availableInterfaces[0], root.index)
root.close();
} else {
print("opening with interfaces:", availableInterfaces)
internalPageStack.push(addSensorSelectInterfaceComponent, {thing: thing, interfaces: availableInterfaces})
}
}
}
}
}
}
Component {
id: addSensorSelectInterfaceComponent
ColumnLayout {
id: addSensorSelectInterface
property Thing thing: null
property var interfaces: ([])
Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("Select depiction")
}
SensorListDelegate {
Layout.fillWidth: true
thing: addSensorSelectInterface.thing
onClicked: {
root.dashboardModel.addSensorItem(addSensorSelectInterface.thing.id, addSensorSelectInterface.interfaces, root.index)
root.close();
}
}
GridLayout {
Layout.fillWidth: true
Layout.fillHeight: true
columns: 2
Repeater {
model: addSensorSelectInterface.interfaces
delegate: SensorView {
thing: addSensorSelectInterface.thing
interfaceName: modelData
Layout.fillWidth: true
Layout.preferredHeight: width
MouseArea {
anchors.fill: parent
onClicked: {
root.dashboardModel.addSensorItem(addSensorSelectInterface.thing.id, [modelData], root.index)
root.close();
}
}
}
}
}
// ListView {
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.preferredHeight: Style.delegateHeight * 6
// clip: true
// model: InterfacesModel {
// engine: _engine
// things: ThingsProxy {
// engine: _engine
// shownThingIds: [addSensorSelectInterface.thing.id]
// }
//// shownInterfaces: app.supportedInterfaces
// shownInterfaces: addSensorSelectInterface.interfaces
// }
// ScrollBar.vertical: ScrollBar {}
// delegate: NymeaItemDelegate {
// readonly property StateType stateType: addSensorSelectInterface.thing.thingClass.stateTypes.findByName(NymeaUtils.sensorInterfaceStateMap[model.name])
// width: parent.width
// text: stateType.displayName
// iconName: app.interfaceToIcon(model.name)
// progressive: false
// onClicked: {
//// var thing = thingsProxy.get(index)
//// var availableInterfaces = []
//// for (var i = 0; i < thing.thingClass.interfaces.count; i++) {
//// var iface = thing.thingClass.interfaces[i]
//// if (thingsProxy.shownInterfaces.indexOf(iface) >= 0) {
//// availableInterfaces.push(iface);
//// }
//// }
//// if (availableInterfaces.length == 1) {
//// root.dashboardModel.addSensorItem(model.id, availableInterfaces[0], root.index)
//// } else {
//// internalPageStack.push(addSensorSelectInterfaceComponent, thing, availableInterfaces)
//// }
//// root.close();
// }
// }
// }
}
}
Component {
id: addFolderComponent
ColumnLayout {

View File

@ -0,0 +1,81 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2023, 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
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
import QtCharts 2.2
import Nymea 1.0
import NymeaApp.Utils 1.0
import "../../components"
import "../../delegates"
import "../../customviews"
DashboardDelegateBase {
id: root
property DashboardSensorItem item: null
readonly property Thing thing: engine.thingManager.fetchingData ? null : engine.thingManager.things.getThing(root.item.thingId)
readonly property var interfaces: root.item.interfaces
contentItem: Loader {
height: root.height
width: root.width
sourceComponent: root.item.interfaces.length === 1 ? singleSensorViewComponent : multiSensorViewComponent
}
Component {
id: singleSensorViewComponent
ColumnLayout {
id: delegateRoot
SensorView {
Layout.fillWidth: true
Layout.fillHeight: true
thing: root.thing
interfaceName: root.item.interfaces[0]
// onPressAndHold: root.longPressed();
}
Label {
text: root.thing.name
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
}
}
}
Component {
id: multiSensorViewComponent
SensorListDelegate {
id: delegateRoot
thing: root.thing
}
}
}

View File

@ -180,4 +180,33 @@ Item {
var h= c && ((v==r) ? (g-b)/c : ((v==g) ? 2+(b-r)/c : 4+(r-g)/c));
return [60*(h<0?h+6:h), v&&c/v, v];
}
readonly property var sensorInterfaceStateMap: {
"temperaturesensor": "temperature",
"humiditysensor": "humidity",
"pressuresensor": "pressure",
"moisturesensor": "moisture",
"lightsensor": "lightIntensity",
"conductivitysensor": "conductivity",
"noisesensor": "noise",
"cosensor": "co",
"co2sensor": "co2",
"gassensor": "gasLevel",
"presencesensor": "isPresent",
"daylightsensor": "daylight",
"closablesensor": "closed",
"watersensor": "waterDetected",
"firesensor": "fireDetected",
"waterlevelsensor": "waterLevel",
"phsensor": "ph",
"o2sensor": "o2saturation",
"o3sensor": "o3",
"orpsensor": "orp",
"vocsensor": "voc",
"cosensor": "co",
"pm10sensor": "pm10",
"pm25sensor": "pm25",
"no2sensor": "no2"
}
}

View File

@ -0,0 +1,5 @@
import QtQuick 2.0
Item {
}