Add EV Dash experience
This commit is contained in:
parent
d486a5f61e
commit
336e21aabc
29
experiences/evdash/evdash.pro
Normal file
29
experiences/evdash/evdash.pro
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
TEMPLATE = lib
|
||||||
|
CONFIG += staticlib
|
||||||
|
TARGET = nymea-app-evdash
|
||||||
|
|
||||||
|
QT -= gui
|
||||||
|
QT += network websockets quick
|
||||||
|
|
||||||
|
include(../../shared.pri)
|
||||||
|
|
||||||
|
LIBS += -L$${top_builddir}/libnymea-app/ -lnymea-app
|
||||||
|
INCLUDEPATH += $${top_srcdir}/libnymea-app/
|
||||||
|
|
||||||
|
android: {
|
||||||
|
LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH}
|
||||||
|
PRE_TARGETDEPS += $$top_builddir/libnymea-app/$${ANDROID_TARGET_ARCH}/libnymea-app_$${ANDROID_TARGET_ARCH}.a
|
||||||
|
}
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
evdashmanager.h \
|
||||||
|
evdashusers.h \
|
||||||
|
libnymea-app-evdash.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
evdashmanager.cpp \
|
||||||
|
evdashusers.cpp
|
||||||
|
|
||||||
|
android: {
|
||||||
|
DESTDIR = $${ANDROID_TARGET_ARCH}
|
||||||
|
}
|
||||||
167
experiences/evdash/evdashmanager.cpp
Normal file
167
experiences/evdash/evdashmanager.cpp
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
||||||
|
*
|
||||||
|
* This file is part of nymea-app.
|
||||||
|
*
|
||||||
|
* nymea-app is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "evdashmanager.h"
|
||||||
|
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
#include <logging.h>
|
||||||
|
|
||||||
|
NYMEA_LOGGING_CATEGORY(dcEvDashExperience, "EvDashExperience")
|
||||||
|
|
||||||
|
EvDashManager::EvDashManager(QObject *parent)
|
||||||
|
:QObject{parent},
|
||||||
|
m_users{new EvDashUsers(this)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EvDashManager::~EvDashManager()
|
||||||
|
{
|
||||||
|
if (m_engine) {
|
||||||
|
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EvDashUsers *EvDashManager::users() const
|
||||||
|
{
|
||||||
|
return m_users;
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine *EvDashManager::engine() const
|
||||||
|
{
|
||||||
|
return m_engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::setEngine(Engine *engine)
|
||||||
|
{
|
||||||
|
if (m_engine == engine)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_engine)
|
||||||
|
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
|
||||||
|
|
||||||
|
m_engine = engine;
|
||||||
|
emit engineChanged();
|
||||||
|
|
||||||
|
if (m_engine) {
|
||||||
|
connect(engine, &Engine::destroyed, this, [engine, this]{ if (m_engine == engine) m_engine = nullptr; });
|
||||||
|
|
||||||
|
m_engine->jsonRpcClient()->registerNotificationHandler(this, "EvDash", "notificationReceived");
|
||||||
|
m_engine->jsonRpcClient()->sendCommand("EvDash.GetEnabled", QVariantMap(), this, "getEnabledResponse");
|
||||||
|
m_engine->jsonRpcClient()->sendCommand("EvDash.GetUsers", QVariantMap(), this, "getUsersResponse");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EvDashManager::enabled() const
|
||||||
|
{
|
||||||
|
return m_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EvDashManager::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("enabled", enabled);
|
||||||
|
return m_engine->jsonRpcClient()->sendCommand("EvDash.SetEnabled", params, this, "setEnabledResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
int EvDashManager::addUser(const QString &username, const QString &password)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("username", username);
|
||||||
|
params.insert("password", password);
|
||||||
|
return m_engine->jsonRpcClient()->sendCommand("EvDash.AddUser", params, this, "addUserResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
int EvDashManager::removeUser(const QString &username)
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("username", username);
|
||||||
|
return m_engine->jsonRpcClient()->sendCommand("EvDash.RemoveUser", params, this, "removeUserResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::notificationReceived(const QVariantMap &data)
|
||||||
|
{
|
||||||
|
QString notification = data.value("notification").toString();
|
||||||
|
QVariantMap params = data.value("params").toMap();
|
||||||
|
|
||||||
|
if (notification == "EvDash.EnabledChanged") {
|
||||||
|
bool enabled = params.value("enabled").toBool();
|
||||||
|
if (m_enabled != enabled) {
|
||||||
|
m_enabled = enabled;
|
||||||
|
emit enabledChanged();
|
||||||
|
}
|
||||||
|
} else if (notification == "EvDash.UserAdded") {
|
||||||
|
m_users->addUser(params.value("username").toString());
|
||||||
|
} else if (notification == "EvDash.UserRemoved") {
|
||||||
|
m_users->removeUser(params.value("username").toString());
|
||||||
|
} else {
|
||||||
|
qCDebug(dcEvDashExperience()) << "Unhandled notification received" << data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::getEnabledResponse(int commandId, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
Q_UNUSED(commandId)
|
||||||
|
qCDebug(dcEvDashExperience()) << "Response for GetEnabled request" << commandId << params;
|
||||||
|
|
||||||
|
bool enabled = params.value("enabled").toBool();
|
||||||
|
if (m_enabled != enabled) {
|
||||||
|
m_enabled = enabled;
|
||||||
|
emit enabledChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::setEnabledResponse(int commandId, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qCDebug(dcEvDashExperience()) << "Response for SetEnabled request" << commandId << params;
|
||||||
|
QMetaEnum metaEnum = QMetaEnum::fromType<EvDashError>();
|
||||||
|
EvDashError error = static_cast<EvDashError>(metaEnum.keyToValue(params.value("evDashError").toByteArray().data()));
|
||||||
|
emit setEnabledReply(commandId, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::getUsersResponse(int commandId, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
Q_UNUSED(commandId)
|
||||||
|
qCDebug(dcEvDashExperience()) << "Response for GetEnabled request" << commandId << params;
|
||||||
|
m_users->setUsers(params.value("usernames").toStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::addUserResponse(int commandId, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qCDebug(dcEvDashExperience()) << "Response for AddUser request" << commandId << params;
|
||||||
|
QMetaEnum metaEnum = QMetaEnum::fromType<EvDashError>();
|
||||||
|
EvDashError error = static_cast<EvDashError>(metaEnum.keyToValue(params.value("evDashError").toByteArray().data()));
|
||||||
|
emit addUserReply(commandId, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashManager::removeUserResponse(int commandId, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
qCDebug(dcEvDashExperience()) << "Response for RemoveUser request" << commandId << params;
|
||||||
|
QMetaEnum metaEnum = QMetaEnum::fromType<EvDashError>();
|
||||||
|
EvDashError error = static_cast<EvDashError>(metaEnum.keyToValue(params.value("evDashError").toByteArray().data()));
|
||||||
|
emit removeUserReply(commandId, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
89
experiences/evdash/evdashmanager.h
Normal file
89
experiences/evdash/evdashmanager.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
||||||
|
*
|
||||||
|
* This file is part of nymea-app.
|
||||||
|
*
|
||||||
|
* nymea-app is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef EVDASHMANAGER_H
|
||||||
|
#define EVDASHMANAGER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <engine.h>
|
||||||
|
|
||||||
|
#include "evdashusers.h"
|
||||||
|
|
||||||
|
class EvDashManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged)
|
||||||
|
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL)
|
||||||
|
Q_PROPERTY(EvDashUsers *users READ users CONSTANT FINAL)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum EvDashError {
|
||||||
|
EvDashErrorNoError = 0,
|
||||||
|
EvDashErrorBackendError,
|
||||||
|
EvDashErrorDuplicateUser,
|
||||||
|
EvDashErrorUserNotFound,
|
||||||
|
EvDashErrorBadPassword
|
||||||
|
};
|
||||||
|
Q_ENUM(EvDashError)
|
||||||
|
|
||||||
|
explicit EvDashManager(QObject *parent = nullptr);
|
||||||
|
~EvDashManager();
|
||||||
|
|
||||||
|
EvDashUsers *users() const;
|
||||||
|
|
||||||
|
Engine* engine() const;
|
||||||
|
void setEngine(Engine *engine);
|
||||||
|
|
||||||
|
bool enabled() const;
|
||||||
|
int setEnabled(bool enabled);
|
||||||
|
|
||||||
|
Q_INVOKABLE int addUser(const QString &username, const QString &password);
|
||||||
|
Q_INVOKABLE int removeUser(const QString &username);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void engineChanged();
|
||||||
|
void enabledChanged();
|
||||||
|
|
||||||
|
void setEnabledReply(int commandId, EvDashManager::EvDashError error);
|
||||||
|
void addUserReply(int commandId, EvDashManager::EvDashError error);
|
||||||
|
void removeUserReply(int commandId, EvDashManager::EvDashError error);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void notificationReceived(const QVariantMap &data);
|
||||||
|
|
||||||
|
void getEnabledResponse(int commandId, const QVariantMap ¶ms);
|
||||||
|
void setEnabledResponse(int commandId, const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
void getUsersResponse(int commandId, const QVariantMap ¶ms);
|
||||||
|
void addUserResponse(int commandId, const QVariantMap ¶ms);
|
||||||
|
void removeUserResponse(int commandId, const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Engine *m_engine = nullptr;
|
||||||
|
bool m_enabled = false;
|
||||||
|
EvDashUsers *m_users = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EVDASHMANAGER_H
|
||||||
108
experiences/evdash/evdashusers.cpp
Normal file
108
experiences/evdash/evdashusers.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
||||||
|
*
|
||||||
|
* This file is part of nymea-app.
|
||||||
|
*
|
||||||
|
* nymea-app is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "evdashusers.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline bool localeLess(const QString &lhs, const QString &rhs)
|
||||||
|
{
|
||||||
|
return QString::localeAwareCompare(lhs, rhs) < 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EvDashUsers::EvDashUsers(QObject *parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EvDashUsers::EvDashUsers(const QStringList &data, QObject *parent)
|
||||||
|
: QAbstractListModel(parent), m_data(data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int EvDashUsers::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return m_data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant EvDashUsers::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid() || index.row() >= m_data.size())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole || role == NameRole)
|
||||||
|
return m_data.at(index.row());
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> EvDashUsers::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles[NameRole] = "name";
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashUsers::setUsers(const QStringList &users)
|
||||||
|
{
|
||||||
|
QStringList sortedUsers = users;
|
||||||
|
sortedUsers.removeDuplicates();
|
||||||
|
std::sort(sortedUsers.begin(), sortedUsers.end(), localeLess);
|
||||||
|
|
||||||
|
if (sortedUsers == m_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
m_data = sortedUsers;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashUsers::addUser(const QString &user)
|
||||||
|
{
|
||||||
|
if (user.isEmpty() || m_data.contains(user))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto insertIt = std::lower_bound(m_data.begin(), m_data.end(), user, localeLess);
|
||||||
|
const int insertIndex = std::distance(m_data.begin(), insertIt);
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), insertIndex, insertIndex);
|
||||||
|
m_data.insert(insertIndex, user);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvDashUsers::removeUser(const QString &user)
|
||||||
|
{
|
||||||
|
int index = m_data.indexOf(user);
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
m_data.removeAt(index);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
55
experiences/evdash/evdashusers.h
Normal file
55
experiences/evdash/evdashusers.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
||||||
|
*
|
||||||
|
* This file is part of nymea-app.
|
||||||
|
*
|
||||||
|
* nymea-app is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef EVDASHUSERS_H
|
||||||
|
#define EVDASHUSERS_H
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class EvDashUsers : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Roles { DisplayRole = Qt::UserRole + 1, NameRole };
|
||||||
|
|
||||||
|
explicit EvDashUsers(QObject *parent = nullptr);
|
||||||
|
explicit EvDashUsers(const QStringList &data, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
void setUsers(const QStringList &users);
|
||||||
|
void addUser(const QString &username);
|
||||||
|
void removeUser(const QString &username);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList m_data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // EVDASHUSERS_H
|
||||||
46
experiences/evdash/libnymea-app-evdash.h
Normal file
46
experiences/evdash/libnymea-app-evdash.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
||||||
|
*
|
||||||
|
* This file is part of nymea-app.
|
||||||
|
*
|
||||||
|
* nymea-app is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef LIBNYMEA_APP_EVDASH_H
|
||||||
|
#define LIBNYMEA_APP_EVDASH_H
|
||||||
|
|
||||||
|
#include "evdashmanager.h"
|
||||||
|
#include "evdashusers.h"
|
||||||
|
|
||||||
|
#include <qqml.h>
|
||||||
|
|
||||||
|
namespace Nymea {
|
||||||
|
|
||||||
|
namespace EvDash {
|
||||||
|
|
||||||
|
void registerQmlTypes() {
|
||||||
|
qmlRegisterType<EvDashManager>("Nymea.EvDash", 1, 0, "EvDashManager");
|
||||||
|
qmlRegisterUncreatableType<EvDashUsers>("Nymea.EvDash", 1, 0, "EvDashUsers", "Get if from the EvDash Manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LIBNYMEA_APP_EVDASH_H
|
||||||
@ -1,3 +1,3 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += airconditioning
|
SUBDIRS += airconditioning evdash
|
||||||
|
|||||||
@ -668,7 +668,10 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms)
|
|||||||
QString name = params.value("name").toString();
|
QString name = params.value("name").toString();
|
||||||
m_experiences.clear();
|
m_experiences.clear();
|
||||||
foreach (const QVariant &experience, params.value("experiences").toList()) {
|
foreach (const QVariant &experience, params.value("experiences").toList()) {
|
||||||
m_experiences.insert(experience.toMap().value("name").toString(), experience.toMap().value("version").toString());
|
QString experienceName = experience.toMap().value("name").toString();
|
||||||
|
QString experienceVersion = experience.toMap().value("version").toString();
|
||||||
|
m_experiences.insert(experienceName, experienceVersion);
|
||||||
|
qCInfo(dcJsonRpc()) << "Experience available:" << experienceName << experienceVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString protoVersionString = params.value("protocol version").toString();
|
QString protoVersionString = params.value("protocol version").toString();
|
||||||
|
|||||||
@ -163,7 +163,7 @@ int UserManager::setUserScopes(const QString &username, int scopes, const QList<
|
|||||||
if (m_engine->jsonRpcClient()->ensureServerVersion("8.4")) {
|
if (m_engine->jsonRpcClient()->ensureServerVersion("8.4")) {
|
||||||
QVariantList thingIds;
|
QVariantList thingIds;
|
||||||
foreach (const QUuid &thingId, allowedThingIds)
|
foreach (const QUuid &thingId, allowedThingIds)
|
||||||
thingIds.append(thingId);
|
thingIds.append(thingId.toString());
|
||||||
|
|
||||||
params.insert("allowedThingIds", thingIds);
|
params.insert("allowedThingIds", thingIds);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include "libnymea-app-core.h"
|
#include "libnymea-app-core.h"
|
||||||
#include "libnymea-app-airconditioning.h"
|
#include "libnymea-app-airconditioning.h"
|
||||||
|
#include "libnymea-app-evdash.h"
|
||||||
|
|
||||||
#include "stylecontroller.h"
|
#include "stylecontroller.h"
|
||||||
#include "pushnotifications.h"
|
#include "pushnotifications.h"
|
||||||
@ -145,6 +146,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Nymea::Core::registerQmlTypes();
|
Nymea::Core::registerQmlTypes();
|
||||||
Nymea::AirConditioning::registerQmlTypes();
|
Nymea::AirConditioning::registerQmlTypes();
|
||||||
|
Nymea::EvDash::registerQmlTypes();
|
||||||
|
|
||||||
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
||||||
|
|
||||||
|
|||||||
@ -13,25 +13,29 @@ qtHaveModule(webview) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
INCLUDEPATH += $$top_srcdir/libnymea-app \
|
INCLUDEPATH += $$top_srcdir/libnymea-app \
|
||||||
$$top_srcdir/experiences/airconditioning
|
$$top_srcdir/experiences/airconditioning \
|
||||||
|
$$top_srcdir/experiences/evdash
|
||||||
|
|
||||||
|
linux:!android:LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app \
|
||||||
|
-L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \
|
||||||
|
-L$$top_builddir/experiences/evdash -lnymea-app-evdash
|
||||||
|
|
||||||
linux:!android: LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning
|
|
||||||
|
|
||||||
win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug -lnymea-app \
|
win32:Debug:LIBS += -L$$top_builddir/libnymea-app/debug -lnymea-app \
|
||||||
-L$$top_builddir/experiences/airconditioning/debug -lnymea-app-airconditioning
|
-L$$top_builddir/experiences/airconditioning/debug -lnymea-app-airconditioning \
|
||||||
win32:Release:LIBS += -L$$top_builddir/libnymea-app/release -lnymea-app \
|
-L$$top_builddir/experiences/evdash/debug -lnymea-app-evdash
|
||||||
-L$$top_builddir/experiences/airconditioning/release -lnymea-app-airconditioning
|
|
||||||
|
win32:Release:LIBS += -L$$top_builddir/libnymea-app/release -lnymea-app \
|
||||||
|
-L$$top_builddir/experiences/airconditioning/release -lnymea-app-airconditioning \
|
||||||
|
-L$$top_builddir/experiences/evdash/release -lnymea-app-evdash
|
||||||
|
|
||||||
win32:Debug:PRE_TARGETDEPS += $$top_builddir/libnymea-app/debug/nymea-app.lib \
|
|
||||||
$$top_builddir/experiences/airconditioning/debug/nymea-app-airconditioning.lib
|
|
||||||
win32:Release:PRE_TARGETDEPS += $$top_builddir/libnymea-app/release/nymea-app.lib \
|
|
||||||
$$top_builddir/experiences/airconditioning/release/nymea-app-airconditioning.lib
|
|
||||||
win32:CXX_FLAGS += /w
|
win32:CXX_FLAGS += /w
|
||||||
|
|
||||||
linux:!android:!nozeroconf:LIBS += -lavahi-client -lavahi-common
|
linux:!android:!nozeroconf:LIBS += -lavahi-client -lavahi-common
|
||||||
|
|
||||||
linux:!android:PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \
|
linux:!android:PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \
|
||||||
$$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a
|
$$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a \
|
||||||
|
$$top_builddir/experiences/evdash/libnymea-app-evdash.a
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
configuredhostsmodel.h \
|
configuredhostsmodel.h \
|
||||||
@ -94,7 +98,7 @@ android {
|
|||||||
include(../3rdParty/android/android_openssl/openssl.pri)
|
include(../3rdParty/android/android_openssl/openssl.pri)
|
||||||
|
|
||||||
ANDROID_MIN_SDK_VERSION = 21
|
ANDROID_MIN_SDK_VERSION = 21
|
||||||
ANDROID_TARGET_SDK_VERSION = 35
|
ANDROID_TARGET_SDK_VERSION = 36
|
||||||
|
|
||||||
HEADERS += platformintegration/android/platformhelperandroid.h \
|
HEADERS += platformintegration/android/platformhelperandroid.h \
|
||||||
platformintegration/android/platformpermissionsandroid.h \
|
platformintegration/android/platformpermissionsandroid.h \
|
||||||
@ -104,9 +108,11 @@ android {
|
|||||||
|
|
||||||
CORE_LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH}
|
CORE_LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH}
|
||||||
AIRCONDITIONING_LIBS += -L$${top_builddir}/experiences/airconditioning/$${ANDROID_TARGET_ARCH}
|
AIRCONDITIONING_LIBS += -L$${top_builddir}/experiences/airconditioning/$${ANDROID_TARGET_ARCH}
|
||||||
|
EVDASH_LIBS += -L$${top_builddir}/experiences/evdash/$${ANDROID_TARGET_ARCH}
|
||||||
|
|
||||||
LIBS += $${CORE_LIBS} -lnymea-app_$${ANDROID_TARGET_ARCH} \
|
LIBS += $${CORE_LIBS} -lnymea-app_$${ANDROID_TARGET_ARCH} \
|
||||||
$${AIRCONDITIONING_LIBS} -lnymea-app-airconditioning_$${ANDROID_TARGET_ARCH}
|
$${AIRCONDITIONING_LIBS} -lnymea-app-airconditioning_$${ANDROID_TARGET_ARCH} \
|
||||||
|
$${EVDASH_LIBS} -lnymea-app-evdash_$${ANDROID_TARGET_ARCH}
|
||||||
|
|
||||||
versioninfo.files = ../version.txt
|
versioninfo.files = ../version.txt
|
||||||
versioninfo.path = /
|
versioninfo.path = /
|
||||||
|
|||||||
@ -325,5 +325,6 @@
|
|||||||
<file>ui/shaders/coloricon.frag.qsb</file>
|
<file>ui/shaders/coloricon.frag.qsb</file>
|
||||||
<file>ui/shaders/brightnesscircle.frag.qsb</file>
|
<file>ui/shaders/brightnesscircle.frag.qsb</file>
|
||||||
<file>ui/shaders/colorizedimage.frag.qsb</file>
|
<file>ui/shaders/colorizedimage.frag.qsb</file>
|
||||||
|
<file>ui/system/EvDashSettingsPage.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -143,6 +143,17 @@ Page {
|
|||||||
onClicked:pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml"))
|
onClicked:pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SettingsTile {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
iconSource: "qrc:/icons/dashboard.svg"
|
||||||
|
text: qsTr("EV Dash")
|
||||||
|
subText: qsTr("Dashboard settings")
|
||||||
|
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) &&
|
||||||
|
(engine.jsonRpcClient.experiences.hasOwnProperty("EvDash"))
|
||||||
|
onClicked:pageStack.push(Qt.resolvedUrl("system/EvDashSettingsPage.qml"))
|
||||||
|
}
|
||||||
|
|
||||||
SettingsTile {
|
SettingsTile {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
iconSource: "qrc:/icons/sdk.svg"
|
iconSource: "qrc:/icons/sdk.svg"
|
||||||
|
|||||||
203
nymea-app/ui/system/EvDashSettingsPage.qml
Normal file
203
nymea-app/ui/system/EvDashSettingsPage.qml
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2025, 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.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
import Nymea 1.0
|
||||||
|
import Nymea.EvDash 1.0
|
||||||
|
|
||||||
|
import "../components"
|
||||||
|
|
||||||
|
SettingsPageBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
header: NymeaHeader {
|
||||||
|
text: qsTr("EV Dash")
|
||||||
|
onBackPressed: pageStack.pop()
|
||||||
|
|
||||||
|
HeaderButton {
|
||||||
|
imageSource: Qt.resolvedUrl("qrc:/icons/add.svg")
|
||||||
|
onClicked: {
|
||||||
|
var popup = addUserPopup.createObject(app);
|
||||||
|
popup.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EvDashManager {
|
||||||
|
id: evDashManager
|
||||||
|
engine: _engine
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: errorDialog
|
||||||
|
ErrorDialog {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: removeUserPopup
|
||||||
|
NymeaDialog {
|
||||||
|
id: removeUserDialog
|
||||||
|
|
||||||
|
property string username
|
||||||
|
|
||||||
|
headerIcon: "qrc:/icons/dialog-warning-symbolic.svg"
|
||||||
|
title: qsTr("Remove user")
|
||||||
|
text: qsTr("Are you sure you want to remove \"%1\"?").arg(username)
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
evDashManager.removeUser(username);
|
||||||
|
popup.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: evDashManager
|
||||||
|
onAddUserReply: {
|
||||||
|
if (error === EvDashManager.EvDashErrorNoError)
|
||||||
|
return
|
||||||
|
|
||||||
|
var text;
|
||||||
|
switch (error) {
|
||||||
|
case EvDashManager.EvDashErrorDuplicateUser:
|
||||||
|
text = qsTr("The given username is already in use. Please choose a different username.");
|
||||||
|
break;
|
||||||
|
case EvDashManager.EvDashErrorBadPassword:
|
||||||
|
text = qsTr("The given password is not valid.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text = qsTr("Un unexpected error happened when creating the user. We're sorry for this. (Error code: %1)").arg(error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var popup = errorDialog.createObject(app, {text: text});
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveUserReply: {
|
||||||
|
if (error === EvDashManager.EvDashErrorNoError)
|
||||||
|
return
|
||||||
|
|
||||||
|
var text;
|
||||||
|
switch (error) {
|
||||||
|
case EvDashManager.EvDashErrorDuplicateUser:
|
||||||
|
text = qsTr("The given username is already in use. Please choose a different username.");
|
||||||
|
break;
|
||||||
|
case EvDashManager.EvDashErrorBadPassword:
|
||||||
|
text = qsTr("The given password is not valid.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text = qsTr("Un unexpected error happened when creating the user. We're sorry for this. (Error code: %1)").arg(error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var popup = errorDialog.createObject(app, {text: text});
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: addUserPopup
|
||||||
|
|
||||||
|
NymeaDialog {
|
||||||
|
id: addUserDialog
|
||||||
|
|
||||||
|
title: qsTr("Create new user")
|
||||||
|
standardButtons: Dialog.NoButton
|
||||||
|
|
||||||
|
Label { text: qsTr("Username") }
|
||||||
|
|
||||||
|
NymeaTextField {
|
||||||
|
id: usernameTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label { text: qsTr("Password") }
|
||||||
|
|
||||||
|
PasswordTextField {
|
||||||
|
id: passwordTextField
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
minPasswordLength: 4
|
||||||
|
requireSpecialChar: false
|
||||||
|
requireNumber: false
|
||||||
|
requireUpperCaseLetter: false
|
||||||
|
requireLowerCaseLetter: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Add user")
|
||||||
|
onClicked: {
|
||||||
|
evDashManager.addUser(usernameTextField.text, passwordTextField.password)
|
||||||
|
addUserDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
onClicked: {
|
||||||
|
addUserDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SwitchDelegate {
|
||||||
|
text: qsTr("Dashboard enabled")
|
||||||
|
checked: evDashManager.enabled
|
||||||
|
onCheckedChanged: evDashManager.enabled = checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPageSectionHeader {
|
||||||
|
text: qsTr("Manage users")
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: usersList
|
||||||
|
model: evDashManager.users
|
||||||
|
|
||||||
|
delegate: NymeaItemDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: model.name
|
||||||
|
onClicked: {
|
||||||
|
var popup = removeUserPopup.createObject(app, {username: model.name});
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user