Add basic functionality of fetching sessions
This commit is contained in:
parent
b36323c2ed
commit
a9f51296b3
103
dashboard/app.js
103
dashboard/app.js
@ -16,6 +16,9 @@ class DashboardApp {
|
||||
incomingMessage: document.getElementById('incomingMessage'),
|
||||
chargerTableBody: document.getElementById('chargerTableBody'),
|
||||
chargerEmptyRow: document.getElementById('chargerEmptyRow'),
|
||||
fetchSessionsButton: document.getElementById('fetchSessionsButton'),
|
||||
chargerFilter: document.getElementById('chargerFilter'),
|
||||
chargingSessionsOutput: document.getElementById('chargingSessionsOutput'),
|
||||
panelButtons: Array.from(document.querySelectorAll('[data-panel-target]')),
|
||||
contentPanels: Array.from(document.querySelectorAll('[data-panel]'))
|
||||
};
|
||||
@ -30,6 +33,7 @@ class DashboardApp {
|
||||
this.tokenRefreshTimer = null;
|
||||
this.refreshInFlight = false;
|
||||
this.chargers = new Map();
|
||||
this.sessions = [];
|
||||
this.activePanel = null;
|
||||
this.chargerColumns = [
|
||||
{ key: 'id', label: 'ID', hidden: true },
|
||||
@ -51,6 +55,7 @@ class DashboardApp {
|
||||
this.initializePanelNavigation();
|
||||
this.restoreSession();
|
||||
this.toggleChargerEmptyState();
|
||||
this.updateChargerSelector();
|
||||
}
|
||||
|
||||
attachEventListeners() {
|
||||
@ -66,6 +71,12 @@ class DashboardApp {
|
||||
this.logout();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.elements.fetchSessionsButton) {
|
||||
this.elements.fetchSessionsButton.addEventListener('click', () => {
|
||||
this.fetchChargingSessions();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initializePanelNavigation() {
|
||||
@ -341,6 +352,7 @@ class DashboardApp {
|
||||
this.refreshInFlight = false;
|
||||
this.chargers.clear();
|
||||
this.resetChargerTable();
|
||||
this.renderChargingSessions([], 'No charging sessions fetched yet.');
|
||||
|
||||
try {
|
||||
window.localStorage.removeItem(this.sessionKey);
|
||||
@ -460,6 +472,20 @@ class DashboardApp {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === 'getchargingsessions') {
|
||||
if (data.success) {
|
||||
const payload = data && data.payload ? data.payload : {};
|
||||
const sessions = Array.isArray(payload.sessions) ? payload.sessions : [];
|
||||
this.renderChargingSessions(sessions, 'No charging sessions found.');
|
||||
} else if (data.error === 'unauthenticated') {
|
||||
this.onAuthenticationFailed('unauthenticated');
|
||||
} else {
|
||||
console.warn('GetChargingSessions request failed', data.error || 'unknownError');
|
||||
this.renderChargingSessions([], 'Failed to fetch charging sessions.');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -480,6 +506,11 @@ class DashboardApp {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(payload.sessions)) {
|
||||
this.renderChargingSessions(payload.sessions);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (payload.charger) {
|
||||
this.upsertCharger(payload.charger);
|
||||
return true;
|
||||
@ -501,6 +532,10 @@ class DashboardApp {
|
||||
case 'chargerremoved':
|
||||
this.removeCharger(payload);
|
||||
return true;
|
||||
case 'chargingsessionsupdated':
|
||||
if (payload && Array.isArray(payload.sessions))
|
||||
this.renderChargingSessions(payload.sessions);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -581,6 +616,19 @@ class DashboardApp {
|
||||
return this.sendAction('GetChargers', { });
|
||||
}
|
||||
|
||||
fetchChargingSessions() {
|
||||
const payload = {};
|
||||
const chargerId = this.elements.chargerFilter ? this.elements.chargerFilter.value : '';
|
||||
if (chargerId)
|
||||
payload.chargerId = chargerId;
|
||||
|
||||
const requestId = this.sendAction('GetChargingSessions', payload);
|
||||
if (!requestId)
|
||||
this.renderChargingSessions([], 'Unable to request charging sessions. Check the connection status.');
|
||||
|
||||
return requestId;
|
||||
}
|
||||
|
||||
processChargerList(chargers = []) {
|
||||
if (!Array.isArray(chargers)) {
|
||||
console.warn('Expected chargers array in payload.');
|
||||
@ -600,6 +648,8 @@ class DashboardApp {
|
||||
if (!seen.has(existingId))
|
||||
this.removeCharger(existingId);
|
||||
}
|
||||
|
||||
this.updateChargerSelector();
|
||||
}
|
||||
|
||||
upsertCharger(charger) {
|
||||
@ -613,6 +663,7 @@ class DashboardApp {
|
||||
merged.thingId = key;
|
||||
this.chargers.set(key, merged);
|
||||
this.syncChargerRow(merged, !hasExisting);
|
||||
this.updateChargerSelector();
|
||||
}
|
||||
|
||||
syncChargerRow(charger, forceCreate = false) {
|
||||
@ -687,6 +738,7 @@ class DashboardApp {
|
||||
row.parentElement.removeChild(row);
|
||||
|
||||
this.toggleChargerEmptyState();
|
||||
this.updateChargerSelector();
|
||||
}
|
||||
|
||||
resetChargerTable() {
|
||||
@ -700,6 +752,7 @@ class DashboardApp {
|
||||
});
|
||||
|
||||
this.toggleChargerEmptyState();
|
||||
this.updateChargerSelector();
|
||||
}
|
||||
|
||||
findChargerRow(chargerId) {
|
||||
@ -736,6 +789,37 @@ class DashboardApp {
|
||||
this.elements.chargerEmptyRow.classList.toggle('hidden', hasChargers);
|
||||
}
|
||||
|
||||
updateChargerSelector() {
|
||||
const select = this.elements.chargerFilter;
|
||||
if (!select)
|
||||
return;
|
||||
|
||||
const currentValue = select.value;
|
||||
while (select.options.length > 0)
|
||||
select.remove(0);
|
||||
|
||||
const defaultOption = document.createElement('option');
|
||||
defaultOption.value = '';
|
||||
defaultOption.textContent = 'All chargers';
|
||||
select.appendChild(defaultOption);
|
||||
|
||||
const chargers = Array.from(this.chargers.values())
|
||||
.sort((a, b) => (a.name || '').localeCompare(b.name || '', undefined, { sensitivity: 'base' }));
|
||||
|
||||
chargers.forEach(charger => {
|
||||
const option = document.createElement('option');
|
||||
option.value = this.getChargerKey(charger) || '';
|
||||
option.textContent = charger.name || option.value;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
const hasValue = currentValue && select.querySelector
|
||||
&& typeof CSS !== 'undefined' && CSS.escape
|
||||
&& select.querySelector(`option[value="${CSS.escape(currentValue)}"]`);
|
||||
|
||||
select.value = hasValue ? currentValue : '';
|
||||
}
|
||||
|
||||
formatNumber(value, unit) {
|
||||
if (!Number.isFinite(value))
|
||||
return '—';
|
||||
@ -784,6 +868,25 @@ class DashboardApp {
|
||||
}
|
||||
}
|
||||
|
||||
renderChargingSessions(sessions, fallbackMessage) {
|
||||
if (!this.elements.chargingSessionsOutput)
|
||||
return;
|
||||
|
||||
if (!Array.isArray(sessions) || !sessions.length) {
|
||||
this.sessions = [];
|
||||
this.elements.chargingSessionsOutput.textContent = fallbackMessage || 'No charging sessions found.';
|
||||
return;
|
||||
}
|
||||
|
||||
this.sessions = sessions;
|
||||
try {
|
||||
this.elements.chargingSessionsOutput.textContent = JSON.stringify(sessions, null, 2);
|
||||
} catch (error) {
|
||||
console.warn('Failed to render charging sessions', error);
|
||||
this.elements.chargingSessionsOutput.textContent = 'Unable to display charging sessions.';
|
||||
}
|
||||
}
|
||||
|
||||
updateConnectionStatus(text, state) {
|
||||
if (this.elements.connectionStatus)
|
||||
this.elements.connectionStatus.textContent = text;
|
||||
|
||||
@ -283,6 +283,13 @@
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0;
|
||||
font-size: 0.8rem;
|
||||
@ -475,6 +482,22 @@
|
||||
box-shadow: 0 0 0 3px rgba(162, 13, 23, 0.2);
|
||||
}
|
||||
|
||||
select {
|
||||
border-radius: 10px;
|
||||
border: 1px solid #d3dce6;
|
||||
padding: 0.65rem 1rem;
|
||||
font-size: 1rem;
|
||||
background: #f9fbfd;
|
||||
color: var(--text-color);
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--secondary-color);
|
||||
box-shadow: 0 0 0 3px rgba(162, 13, 23, 0.2);
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
@ -600,6 +623,10 @@
|
||||
<span>Chargers</span>
|
||||
<span class="side-nav-subtitle">Live table & telemetry</span>
|
||||
</button>
|
||||
<button type="button" class="side-nav-button" data-panel-target="chargingSessions" aria-pressed="false">
|
||||
<span>Charging sessions</span>
|
||||
<span class="side-nav-subtitle">History fetched via nymea</span>
|
||||
</button>
|
||||
<button type="button" class="side-nav-button" data-panel-target="help" aria-pressed="false">
|
||||
<span>Help</span>
|
||||
<span class="side-nav-subtitle">API contract & logs</span>
|
||||
@ -647,6 +674,26 @@
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="content-panel" data-panel="chargingSessions" aria-labelledby="chargingSessionsTitle" aria-hidden="true">
|
||||
<article class="card">
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<p class="eyebrow">History</p>
|
||||
<h2 id="chargingSessionsTitle">Charging sessions</h2>
|
||||
</div>
|
||||
<div class="action-row">
|
||||
<label class="sr-only" for="chargerFilter">Charger</label>
|
||||
<select id="chargerFilter" name="chargerFilter">
|
||||
<option value="">All chargers</option>
|
||||
</select>
|
||||
<button type="button" id="fetchSessionsButton" class="primary">Fetch sessions</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="helper-text">Select a charger to filter by its assigned car and fetch sessions from nymea.</p>
|
||||
<pre id="chargingSessionsOutput">No charging sessions fetched yet.</pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="content-panel" data-panel="help" aria-labelledby="helpTitle" aria-hidden="true">
|
||||
<article class="card">
|
||||
<div class="card-header">
|
||||
|
||||
@ -26,14 +26,13 @@
|
||||
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QDBusPendingReply>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusError>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcChargingSessions)
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
static const QString kDbusService = QStringLiteral("io.nymea.energy.chargingsessions");
|
||||
static const QString kDbusPath = QStringLiteral("/io/nymea/energy/chargingsessions");
|
||||
@ -43,8 +42,16 @@ ChargingSessionsDBusInterfaceClient::ChargingSessionsDBusInterfaceClient(QObject
|
||||
QObject(parent),
|
||||
m_connection(QDBusConnection::systemBus())
|
||||
{
|
||||
if (!m_connection.isConnected()) {
|
||||
qCWarning(dcChargingSessions()) << "DBus system bus not connected";
|
||||
m_serviceWatcher = new QDBusServiceWatcher(kDbusService,
|
||||
m_connection,
|
||||
QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration,
|
||||
this);
|
||||
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &ChargingSessionsDBusInterfaceClient::onServiceRegistered);
|
||||
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &ChargingSessionsDBusInterfaceClient::onServiceUnregistered);
|
||||
|
||||
QDBusConnectionInterface *bus = m_connection.interface();
|
||||
if (bus && bus->isServiceRegistered(kDbusService)) {
|
||||
onServiceRegistered(kDbusService);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +83,6 @@ void ChargingSessionsDBusInterfaceClient::onCallFinished(QDBusPendingCallWatcher
|
||||
watcher->deleteLater();
|
||||
|
||||
if (reply.isError()) {
|
||||
qCWarning(dcChargingSessions()) << "GetSessions DBus call failed:" << reply.error().message();
|
||||
emit errorOccurred(reply.error().message());
|
||||
return;
|
||||
}
|
||||
@ -107,13 +113,11 @@ bool ChargingSessionsDBusInterfaceClient::ensureInterface()
|
||||
m_interface = nullptr;
|
||||
|
||||
if (!m_connection.isConnected()) {
|
||||
qCWarning(dcChargingSessions()) << "DBus system bus not connected";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_interface = new QDBusInterface(kDbusService, kDbusPath, kDbusInterface, m_connection, this);
|
||||
if (!m_interface->isValid()) {
|
||||
qCWarning(dcChargingSessions()) << "Charging sessions DBus interface is not available:" << m_connection.lastError().message();
|
||||
delete m_interface;
|
||||
m_interface = nullptr;
|
||||
return false;
|
||||
@ -121,3 +125,18 @@ bool ChargingSessionsDBusInterfaceClient::ensureInterface()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChargingSessionsDBusInterfaceClient::onServiceRegistered(const QString &service)
|
||||
{
|
||||
Q_UNUSED(service)
|
||||
ensureInterface();
|
||||
}
|
||||
|
||||
void ChargingSessionsDBusInterfaceClient::onServiceUnregistered(const QString &service)
|
||||
{
|
||||
Q_UNUSED(service)
|
||||
if (m_interface) {
|
||||
m_interface->deleteLater();
|
||||
}
|
||||
m_interface = nullptr;
|
||||
}
|
||||
|
||||
@ -29,9 +29,11 @@
|
||||
#include <QList>
|
||||
#include <QVariantMap>
|
||||
#include <QStringList>
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
class QDBusInterface;
|
||||
class QDBusPendingCallWatcher;
|
||||
class QDBusServiceWatcher;
|
||||
|
||||
class ChargingSessionsDBusInterfaceClient : public QObject
|
||||
{
|
||||
@ -51,11 +53,14 @@ signals:
|
||||
|
||||
private slots:
|
||||
void onCallFinished(QDBusPendingCallWatcher *watcher);
|
||||
void onServiceRegistered(const QString &service);
|
||||
void onServiceUnregistered(const QString &service);
|
||||
|
||||
private:
|
||||
bool ensureInterface();
|
||||
|
||||
QDBusConnection m_connection;
|
||||
QDBusInterface *m_interface = nullptr;
|
||||
QDBusServiceWatcher *m_serviceWatcher = nullptr;
|
||||
QList<QVariantMap> m_sessions;
|
||||
};
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QUuid>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcEvDashExperience)
|
||||
@ -105,16 +106,11 @@ EvDashEngine::EvDashEngine(ThingManager *thingManager, EvDashWebServerResource *
|
||||
|
||||
// ChargingSessions client for fetching charging sessions
|
||||
m_chargingSessionsClient = new ChargingSessionsDBusInterfaceClient(this);
|
||||
connect(m_chargingSessionsClient, &ChargingSessionsDBusInterfaceClient::sessionsReceived, this, [](const QList<QVariantMap> &chargingSessions){
|
||||
qCDebug(dcEvDashExperience()) << "ChargingSessions :";
|
||||
foreach (const QVariant &ciVariant, chargingSessions) {
|
||||
qCDebug(dcEvDashExperience()) << "-->" << ciVariant.toMap();
|
||||
}
|
||||
});
|
||||
connect(m_chargingSessionsClient, &ChargingSessionsDBusInterfaceClient::sessionsReceived,
|
||||
this, &EvDashEngine::onSessionsReceived);
|
||||
|
||||
connect(m_chargingSessionsClient, &ChargingSessionsDBusInterfaceClient::errorOccurred, this, [](const QString &errorMessage){
|
||||
qCWarning(dcEvDashExperience()) << "Charging sessions DBus client error occurred:" << errorMessage;
|
||||
});
|
||||
connect(m_chargingSessionsClient, &ChargingSessionsDBusInterfaceClient::errorOccurred,
|
||||
this, &EvDashEngine::onSessionsError);
|
||||
|
||||
|
||||
// Energy manager client for associated cars and current mode
|
||||
@ -307,11 +303,13 @@ void EvDashEngine::processTextMessage(QWebSocket *socket, const QString &message
|
||||
}
|
||||
|
||||
QJsonObject response = handleApiRequest(socket, requestObject);
|
||||
sendReply(socket, response);
|
||||
if (!response.isEmpty()) {
|
||||
sendReply(socket, response);
|
||||
|
||||
if (isAuthenticateAction && !response.value(QStringLiteral("success")).toBool()) {
|
||||
socket->close(QWebSocketProtocol::CloseCodePolicyViolated, QStringLiteral("Authentication failed"));
|
||||
m_authenticatedClients.remove(socket);
|
||||
if (isAuthenticateAction && !response.value(QStringLiteral("success")).toBool()) {
|
||||
socket->close(QWebSocketProtocol::CloseCodePolicyViolated, QStringLiteral("Authentication failed"));
|
||||
m_authenticatedClients.remove(socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,6 +364,19 @@ QJsonObject EvDashEngine::handleApiRequest(QWebSocket *socket, const QJsonObject
|
||||
return createSuccessResponse(requestId, payload);
|
||||
}
|
||||
|
||||
if (action.compare(QStringLiteral("GetChargingSessions"), Qt::CaseInsensitive) == 0) {
|
||||
if (!m_chargingSessionsClient)
|
||||
return createErrorResponse(requestId, QStringLiteral("chargingSessionsUnavailable"));
|
||||
|
||||
const QJsonObject payload = request.value(QStringLiteral("payload")).toObject();
|
||||
const QString chargerId = payload.value(QStringLiteral("chargerId")).toString();
|
||||
const QStringList carThingIds = carThingIdsForCharger(chargerId);
|
||||
|
||||
m_pendingChargingSessionsRequests.insert(requestId, QPointer<QWebSocket>(socket));
|
||||
m_chargingSessionsClient->getSessions(carThingIds);
|
||||
return {};
|
||||
}
|
||||
|
||||
return createErrorResponse(requestId, QStringLiteral("unknownAction"));
|
||||
}
|
||||
|
||||
@ -384,6 +395,9 @@ void EvDashEngine::sendNotification(const QString ¬ification, QJsonObject pay
|
||||
// Send to all active clients
|
||||
|
||||
for (QWebSocket *client : qAsConst(m_clients)) {
|
||||
if (m_authenticatedClients.value(client).isEmpty())
|
||||
continue;
|
||||
|
||||
QJsonObject notificationObject;
|
||||
notificationObject.insert(QStringLiteral("requestId"), QUuid::createUuid().toString(QUuid::WithoutBraces));
|
||||
notificationObject.insert("event", notification);
|
||||
@ -465,3 +479,62 @@ QJsonObject EvDashEngine::packCharger(Thing *charger) const
|
||||
|
||||
return chargerObject;
|
||||
}
|
||||
|
||||
QStringList EvDashEngine::carThingIdsForCharger(const QString &chargerId) const
|
||||
{
|
||||
QStringList carThingIds;
|
||||
if (!m_energyManagerClient || chargerId.isEmpty())
|
||||
return carThingIds;
|
||||
|
||||
const QUuid chargerUuid = QUuid::fromString(chargerId);
|
||||
if (chargerUuid.isNull())
|
||||
return carThingIds;
|
||||
|
||||
for (const QVariant &ciVariant : m_energyManagerClient->chargingInfos()) {
|
||||
const QVariantMap chargingInfo = ciVariant.toMap();
|
||||
if (chargingInfo.value(QStringLiteral("evChargerId")).toUuid() != chargerUuid)
|
||||
continue;
|
||||
|
||||
const QString assignedCarId = chargingInfo.value(QStringLiteral("assignedCarId")).toString();
|
||||
if (!assignedCarId.isEmpty())
|
||||
carThingIds.append(assignedCarId);
|
||||
break;
|
||||
}
|
||||
|
||||
return carThingIds;
|
||||
}
|
||||
|
||||
void EvDashEngine::onSessionsReceived(const QList<QVariantMap> &sessions)
|
||||
{
|
||||
qCDebug(dcEvDashExperience()) << "ChargingSessions received:" << sessions.count();
|
||||
|
||||
QJsonArray sessionArray;
|
||||
for (const QVariantMap &session : sessions)
|
||||
sessionArray.append(QJsonObject::fromVariantMap(session));
|
||||
|
||||
QJsonObject payload;
|
||||
payload.insert(QStringLiteral("sessions"), sessionArray);
|
||||
|
||||
const QList<QString> pendingRequestIds = m_pendingChargingSessionsRequests.keys();
|
||||
for (const QString &requestId : pendingRequestIds) {
|
||||
QPointer<QWebSocket> socket = m_pendingChargingSessionsRequests.take(requestId);
|
||||
if (!socket)
|
||||
continue;
|
||||
sendReply(socket, createSuccessResponse(requestId, payload));
|
||||
}
|
||||
|
||||
sendNotification(QStringLiteral("chargingSessionsUpdated"), payload);
|
||||
}
|
||||
|
||||
void EvDashEngine::onSessionsError(const QString &errorMessage)
|
||||
{
|
||||
qCWarning(dcEvDashExperience()) << "Charging sessions DBus client error occurred:" << errorMessage;
|
||||
|
||||
const QList<QString> pendingRequestIds = m_pendingChargingSessionsRequests.keys();
|
||||
for (const QString &requestId : pendingRequestIds) {
|
||||
QPointer<QWebSocket> socket = m_pendingChargingSessionsRequests.take(requestId);
|
||||
if (!socket)
|
||||
continue;
|
||||
sendReply(socket, createErrorResponse(requestId, errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QJsonObject>
|
||||
#include <QPointer>
|
||||
#include <QStringList>
|
||||
|
||||
#include <integrations/thing.h>
|
||||
|
||||
@ -91,6 +93,10 @@ private:
|
||||
QList<Thing *> m_chargers;
|
||||
void monitorChargerThing(Thing *thing);
|
||||
|
||||
// Pending requests waiting for charging sessions data to return
|
||||
QHash<QString, QPointer<QWebSocket>> m_pendingChargingSessionsRequests;
|
||||
QStringList carThingIdsForCharger(const QString &chargerId) const;
|
||||
|
||||
// Websocket server
|
||||
bool startWebSocketServer(quint16 port = 0);
|
||||
void stopWebSocketServer();
|
||||
@ -105,6 +111,8 @@ private:
|
||||
QJsonObject createErrorResponse(const QString &requestId, const QString &errorMessage) const;
|
||||
|
||||
QJsonObject packCharger(Thing *charger) const;
|
||||
void onSessionsReceived(const QList<QVariantMap> &sessions);
|
||||
void onSessionsError(const QString &errorMessage);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user