Add proper car filtering
This commit is contained in:
parent
cd1c30223f
commit
75465f9226
126
dashboard/app.js
126
dashboard/app.js
@ -18,7 +18,7 @@ class DashboardApp {
|
|||||||
chargerEmptyRow: document.getElementById('chargerEmptyRow'),
|
chargerEmptyRow: document.getElementById('chargerEmptyRow'),
|
||||||
fetchSessionsButton: document.getElementById('fetchSessionsButton'),
|
fetchSessionsButton: document.getElementById('fetchSessionsButton'),
|
||||||
downloadSessionsButton: document.getElementById('downloadSessionsButton'),
|
downloadSessionsButton: document.getElementById('downloadSessionsButton'),
|
||||||
chargerFilter: document.getElementById('chargerFilter'),
|
carFilter: document.getElementById('carFilter'),
|
||||||
chargingSessionsTableBody: document.getElementById('chargingSessionsTableBody'),
|
chargingSessionsTableBody: document.getElementById('chargingSessionsTableBody'),
|
||||||
chargingSessionsEmptyRow: document.getElementById('chargingSessionsEmptyRow'),
|
chargingSessionsEmptyRow: document.getElementById('chargingSessionsEmptyRow'),
|
||||||
chargingSessionsOutput: document.getElementById('chargingSessionsOutput'),
|
chargingSessionsOutput: document.getElementById('chargingSessionsOutput'),
|
||||||
@ -36,6 +36,7 @@ class DashboardApp {
|
|||||||
this.tokenRefreshTimer = null;
|
this.tokenRefreshTimer = null;
|
||||||
this.refreshInFlight = false;
|
this.refreshInFlight = false;
|
||||||
this.chargers = new Map();
|
this.chargers = new Map();
|
||||||
|
this.cars = new Map();
|
||||||
this.sessions = [];
|
this.sessions = [];
|
||||||
this.activePanel = null;
|
this.activePanel = null;
|
||||||
this.chargerColumns = [
|
this.chargerColumns = [
|
||||||
@ -58,7 +59,7 @@ class DashboardApp {
|
|||||||
this.initializePanelNavigation();
|
this.initializePanelNavigation();
|
||||||
this.restoreSession();
|
this.restoreSession();
|
||||||
this.toggleChargerEmptyState();
|
this.toggleChargerEmptyState();
|
||||||
this.updateChargerSelector();
|
this.updateCarSelector();
|
||||||
}
|
}
|
||||||
|
|
||||||
attachEventListeners() {
|
attachEventListeners() {
|
||||||
@ -360,7 +361,9 @@ class DashboardApp {
|
|||||||
this.tokenRefreshTimer = null;
|
this.tokenRefreshTimer = null;
|
||||||
this.refreshInFlight = false;
|
this.refreshInFlight = false;
|
||||||
this.chargers.clear();
|
this.chargers.clear();
|
||||||
|
this.cars.clear();
|
||||||
this.resetChargerTable();
|
this.resetChargerTable();
|
||||||
|
this.updateCarSelector();
|
||||||
this.renderChargingSessions([], 'No charging sessions fetched yet.');
|
this.renderChargingSessions([], 'No charging sessions fetched yet.');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -481,6 +484,19 @@ class DashboardApp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'getcars') {
|
||||||
|
if (data.success) {
|
||||||
|
const payload = data && data.payload ? data.payload : {};
|
||||||
|
const cars = Array.isArray(payload.cars) ? payload.cars : [];
|
||||||
|
this.processCarList(cars);
|
||||||
|
} else if (data.error === 'unauthenticated') {
|
||||||
|
this.onAuthenticationFailed('unauthenticated');
|
||||||
|
} else {
|
||||||
|
console.warn('GetCars request failed', data.error || 'unknownError');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'getchargingsessions') {
|
if (type === 'getchargingsessions') {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
const payload = data && data.payload ? data.payload : {};
|
const payload = data && data.payload ? data.payload : {};
|
||||||
@ -515,6 +531,11 @@ class DashboardApp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(payload.cars)) {
|
||||||
|
this.processCarList(payload.cars);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (Array.isArray(payload.sessions)) {
|
if (Array.isArray(payload.sessions)) {
|
||||||
this.renderChargingSessions(payload.sessions);
|
this.renderChargingSessions(payload.sessions);
|
||||||
return true;
|
return true;
|
||||||
@ -525,6 +546,11 @@ class DashboardApp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payload.car) {
|
||||||
|
this.upsertCar(payload.car);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,6 +567,13 @@ class DashboardApp {
|
|||||||
case 'chargerremoved':
|
case 'chargerremoved':
|
||||||
this.removeCharger(payload);
|
this.removeCharger(payload);
|
||||||
return true;
|
return true;
|
||||||
|
case 'caradded':
|
||||||
|
case 'carchanged':
|
||||||
|
this.upsertCar(payload);
|
||||||
|
return true;
|
||||||
|
case 'carremoved':
|
||||||
|
this.removeCar(payload);
|
||||||
|
return true;
|
||||||
case 'chargingsessionsupdated':
|
case 'chargingsessionsupdated':
|
||||||
if (payload && Array.isArray(payload.sessions))
|
if (payload && Array.isArray(payload.sessions))
|
||||||
this.renderChargingSessions(payload.sessions);
|
this.renderChargingSessions(payload.sessions);
|
||||||
@ -553,6 +586,7 @@ class DashboardApp {
|
|||||||
onAuthenticationSucceeded() {
|
onAuthenticationSucceeded() {
|
||||||
this.updateConnectionStatus('Connected', 'connected');
|
this.updateConnectionStatus('Connected', 'connected');
|
||||||
this.updateSessionUser();
|
this.updateSessionUser();
|
||||||
|
this.sendGetCars();
|
||||||
this.sendGetChargers();
|
this.sendGetChargers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,15 +655,19 @@ class DashboardApp {
|
|||||||
return this.sendAction('ping', { timestamp: new Date().toISOString() });
|
return this.sendAction('ping', { timestamp: new Date().toISOString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendGetCars() {
|
||||||
|
return this.sendAction('GetCars', { });
|
||||||
|
}
|
||||||
|
|
||||||
sendGetChargers() {
|
sendGetChargers() {
|
||||||
return this.sendAction('GetChargers', { });
|
return this.sendAction('GetChargers', { });
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchChargingSessions() {
|
fetchChargingSessions() {
|
||||||
const payload = {};
|
const payload = {};
|
||||||
const chargerId = this.elements.chargerFilter ? this.elements.chargerFilter.value : '';
|
const carId = this.elements.carFilter ? this.elements.carFilter.value : '';
|
||||||
if (chargerId)
|
if (carId)
|
||||||
payload.chargerId = chargerId;
|
payload.carId = carId;
|
||||||
|
|
||||||
const requestId = this.sendAction('GetChargingSessions', payload);
|
const requestId = this.sendAction('GetChargingSessions', payload);
|
||||||
if (!requestId)
|
if (!requestId)
|
||||||
@ -657,8 +695,6 @@ class DashboardApp {
|
|||||||
if (!seen.has(existingId))
|
if (!seen.has(existingId))
|
||||||
this.removeCharger(existingId);
|
this.removeCharger(existingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateChargerSelector();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upsertCharger(charger) {
|
upsertCharger(charger) {
|
||||||
@ -672,7 +708,6 @@ class DashboardApp {
|
|||||||
merged.thingId = key;
|
merged.thingId = key;
|
||||||
this.chargers.set(key, merged);
|
this.chargers.set(key, merged);
|
||||||
this.syncChargerRow(merged, !hasExisting);
|
this.syncChargerRow(merged, !hasExisting);
|
||||||
this.updateChargerSelector();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
syncChargerRow(charger, forceCreate = false) {
|
syncChargerRow(charger, forceCreate = false) {
|
||||||
@ -747,7 +782,6 @@ class DashboardApp {
|
|||||||
row.parentElement.removeChild(row);
|
row.parentElement.removeChild(row);
|
||||||
|
|
||||||
this.toggleChargerEmptyState();
|
this.toggleChargerEmptyState();
|
||||||
this.updateChargerSelector();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetChargerTable() {
|
resetChargerTable() {
|
||||||
@ -761,7 +795,6 @@ class DashboardApp {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.toggleChargerEmptyState();
|
this.toggleChargerEmptyState();
|
||||||
this.updateChargerSelector();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findChargerRow(chargerId) {
|
findChargerRow(chargerId) {
|
||||||
@ -798,8 +831,67 @@ class DashboardApp {
|
|||||||
this.elements.chargerEmptyRow.classList.toggle('hidden', hasChargers);
|
this.elements.chargerEmptyRow.classList.toggle('hidden', hasChargers);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChargerSelector() {
|
processCarList(cars = []) {
|
||||||
const select = this.elements.chargerFilter;
|
if (!Array.isArray(cars)) {
|
||||||
|
console.warn('Expected cars array in payload.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const seen = new Set();
|
||||||
|
cars.forEach(car => {
|
||||||
|
const key = this.getCarKey(car);
|
||||||
|
if (!key)
|
||||||
|
return;
|
||||||
|
seen.add(key);
|
||||||
|
this.upsertCar(car);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const existingId of Array.from(this.cars.keys())) {
|
||||||
|
if (!seen.has(existingId))
|
||||||
|
this.removeCar(existingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
upsertCar(car) {
|
||||||
|
const key = this.getCarKey(car);
|
||||||
|
if (!key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const hasExisting = this.cars.has(key);
|
||||||
|
const previous = hasExisting ? this.cars.get(key) : {};
|
||||||
|
const merged = { ...previous, ...car };
|
||||||
|
merged.thingId = key;
|
||||||
|
this.cars.set(key, merged);
|
||||||
|
this.updateCarSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCar(identifier) {
|
||||||
|
const key = this.getCarKey(identifier);
|
||||||
|
if (!key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.cars.delete(key);
|
||||||
|
this.updateCarSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCarKey(source) {
|
||||||
|
if (!source)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (typeof source === 'string')
|
||||||
|
return source;
|
||||||
|
|
||||||
|
if (source.thingId)
|
||||||
|
return source.thingId;
|
||||||
|
|
||||||
|
if (source.id)
|
||||||
|
return source.id;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCarSelector() {
|
||||||
|
const select = this.elements.carFilter;
|
||||||
if (!select)
|
if (!select)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -809,16 +901,16 @@ class DashboardApp {
|
|||||||
|
|
||||||
const defaultOption = document.createElement('option');
|
const defaultOption = document.createElement('option');
|
||||||
defaultOption.value = '';
|
defaultOption.value = '';
|
||||||
defaultOption.textContent = 'All chargers';
|
defaultOption.textContent = 'All cars';
|
||||||
select.appendChild(defaultOption);
|
select.appendChild(defaultOption);
|
||||||
|
|
||||||
const chargers = Array.from(this.chargers.values())
|
const cars = Array.from(this.cars.values())
|
||||||
.sort((a, b) => (a.name || '').localeCompare(b.name || '', undefined, { sensitivity: 'base' }));
|
.sort((a, b) => (a.name || '').localeCompare(b.name || '', undefined, { sensitivity: 'base' }));
|
||||||
|
|
||||||
chargers.forEach(charger => {
|
cars.forEach(car => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.value = this.getChargerKey(charger) || '';
|
option.value = this.getCarKey(car) || '';
|
||||||
option.textContent = charger.name || option.value;
|
option.textContent = car.name || option.value;
|
||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -687,15 +687,15 @@
|
|||||||
<h2 id="chargingSessionsTitle">Charging sessions</h2>
|
<h2 id="chargingSessionsTitle">Charging sessions</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<label class="sr-only" for="chargerFilter">Charger</label>
|
<label class="sr-only" for="carFilter">Car</label>
|
||||||
<select id="chargerFilter" name="chargerFilter">
|
<select id="carFilter" name="carFilter">
|
||||||
<option value="">All chargers</option>
|
<option value="">All cars</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" id="fetchSessionsButton" class="primary">Fetch sessions</button>
|
<button type="button" id="fetchSessionsButton" class="primary">Fetch sessions</button>
|
||||||
<button type="button" id="downloadSessionsButton">Download CSV</button>
|
<button type="button" id="downloadSessionsButton">Download CSV</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="helper-text">Select a charger to filter by its assigned car and fetch sessions from nymea.</p>
|
<p class="helper-text">Select a car to filter charging sessions fetched from nymea.</p>
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="data-table sessions-table">
|
<table class="data-table sessions-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
@ -56,12 +56,17 @@ EvDashEngine::EvDashEngine(ThingManager *thingManager, EvDashWebServerResource *
|
|||||||
m_thingManager{thingManager},
|
m_thingManager{thingManager},
|
||||||
m_webServerResource{webServerResource}
|
m_webServerResource{webServerResource}
|
||||||
{
|
{
|
||||||
Things evChargers = m_thingManager->configuredThings().filterByInterface("evcharger");
|
Things configuredThings = m_thingManager->configuredThings();
|
||||||
|
foreach (Thing *thing, configuredThings) {
|
||||||
|
if (isChargerThing(thing)) {
|
||||||
|
m_chargers.append(thing);
|
||||||
|
monitorChargerThing(thing);
|
||||||
|
}
|
||||||
|
|
||||||
// Init charger list
|
if (isCarThing(thing)) {
|
||||||
foreach (Thing *chargerThing, evChargers) {
|
m_cars.append(thing);
|
||||||
m_chargers.append(chargerThing);
|
monitorCarThing(thing);
|
||||||
monitorChargerThing(chargerThing);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_thingManager, &ThingManager::thingAdded, this, &EvDashEngine::onThingAdded);
|
connect(m_thingManager, &ThingManager::thingAdded, this, &EvDashEngine::onThingAdded);
|
||||||
@ -191,11 +196,17 @@ bool EvDashEngine::setEnabled(bool enabled)
|
|||||||
|
|
||||||
void EvDashEngine::onThingAdded(Thing *thing)
|
void EvDashEngine::onThingAdded(Thing *thing)
|
||||||
{
|
{
|
||||||
if (thing->thingClass().interfaces().contains("evcharger")) {
|
if (isChargerThing(thing)) {
|
||||||
m_chargers.append(thing);
|
m_chargers.append(thing);
|
||||||
monitorChargerThing(thing);
|
monitorChargerThing(thing);
|
||||||
sendNotification("ChargerAdded", packCharger(thing));
|
sendNotification("ChargerAdded", packCharger(thing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCarThing(thing)) {
|
||||||
|
m_cars.append(thing);
|
||||||
|
monitorCarThing(thing);
|
||||||
|
sendNotification("CarAdded", packCar(thing));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvDashEngine::onThingRemoved(const ThingId &thingId)
|
void EvDashEngine::onThingRemoved(const ThingId &thingId)
|
||||||
@ -205,13 +216,27 @@ void EvDashEngine::onThingRemoved(const ThingId &thingId)
|
|||||||
qCDebug(dcEvDashExperience()) << "Charger has been removed.";
|
qCDebug(dcEvDashExperience()) << "Charger has been removed.";
|
||||||
m_chargers.removeAll(thing);
|
m_chargers.removeAll(thing);
|
||||||
sendNotification("ChargerRemoved", packCharger(thing));
|
sendNotification("ChargerRemoved", packCharger(thing));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Thing *thing, m_cars) {
|
||||||
|
if (thing->id() == thingId) {
|
||||||
|
qCDebug(dcEvDashExperience()) << "Car has been removed.";
|
||||||
|
m_cars.removeAll(thing);
|
||||||
|
sendNotification("CarRemoved", packCar(thing));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvDashEngine::onThingChanged(Thing *thing)
|
void EvDashEngine::onThingChanged(Thing *thing)
|
||||||
{
|
{
|
||||||
sendNotification("ChargerChanged", packCharger(thing));
|
if (isChargerThing(thing))
|
||||||
|
sendNotification("ChargerChanged", packCharger(thing));
|
||||||
|
|
||||||
|
if (isCarThing(thing))
|
||||||
|
sendNotification("CarChanged", packCar(thing));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvDashEngine::monitorChargerThing(Thing *thing)
|
void EvDashEngine::monitorChargerThing(Thing *thing)
|
||||||
@ -227,6 +252,19 @@ void EvDashEngine::monitorChargerThing(Thing *thing)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EvDashEngine::monitorCarThing(Thing *thing)
|
||||||
|
{
|
||||||
|
connect(thing, &Thing::stateValueChanged, this, [this, thing](const StateTypeId &stateTypeId, const QVariant &value, const QVariant &minValue, const QVariant &maxValue, const QVariantList &possibleValues){
|
||||||
|
Q_UNUSED(stateTypeId)
|
||||||
|
Q_UNUSED(value)
|
||||||
|
Q_UNUSED(minValue)
|
||||||
|
Q_UNUSED(maxValue)
|
||||||
|
Q_UNUSED(possibleValues)
|
||||||
|
|
||||||
|
onThingChanged(thing);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool EvDashEngine::startWebSocketServer(quint16 port)
|
bool EvDashEngine::startWebSocketServer(quint16 port)
|
||||||
{
|
{
|
||||||
if (m_webSocketServer->isListening()) {
|
if (m_webSocketServer->isListening()) {
|
||||||
@ -356,21 +394,45 @@ QJsonObject EvDashEngine::handleApiRequest(QWebSocket *socket, const QJsonObject
|
|||||||
|
|
||||||
QJsonObject payload;
|
QJsonObject payload;
|
||||||
QJsonArray chargerList;
|
QJsonArray chargerList;
|
||||||
for (Thing *charger : m_thingManager->configuredThings().filterByInterface("evcharger")) {
|
foreach (Thing *thing, m_thingManager->configuredThings()) {
|
||||||
chargerList.append(packCharger(charger));
|
if (isChargerThing(thing))
|
||||||
|
chargerList.append(packCharger(thing));
|
||||||
}
|
}
|
||||||
|
|
||||||
payload.insert(QStringLiteral("chargers"), chargerList);
|
payload.insert(QStringLiteral("chargers"), chargerList);
|
||||||
return createSuccessResponse(requestId, payload);
|
return createSuccessResponse(requestId, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.compare(QStringLiteral("GetCars"), Qt::CaseInsensitive) == 0) {
|
||||||
|
QJsonObject payload;
|
||||||
|
QJsonArray carList;
|
||||||
|
foreach (Thing *thing, m_thingManager->configuredThings()) {
|
||||||
|
if (isCarThing(thing))
|
||||||
|
carList.append(packCar(thing));
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.insert(QStringLiteral("cars"), carList);
|
||||||
|
return createSuccessResponse(requestId, payload);
|
||||||
|
}
|
||||||
|
|
||||||
if (action.compare(QStringLiteral("GetChargingSessions"), Qt::CaseInsensitive) == 0) {
|
if (action.compare(QStringLiteral("GetChargingSessions"), Qt::CaseInsensitive) == 0) {
|
||||||
if (!m_chargingSessionsClient)
|
if (!m_chargingSessionsClient)
|
||||||
return createErrorResponse(requestId, QStringLiteral("chargingSessionsUnavailable"));
|
return createErrorResponse(requestId, QStringLiteral("chargingSessionsUnavailable"));
|
||||||
|
|
||||||
const QJsonObject payload = request.value(QStringLiteral("payload")).toObject();
|
const QJsonObject payload = request.value(QStringLiteral("payload")).toObject();
|
||||||
const QString chargerId = payload.value(QStringLiteral("chargerId")).toString();
|
QStringList carThingIds;
|
||||||
const QStringList carThingIds = carThingIdsForCharger(chargerId);
|
|
||||||
|
const QString carId = payload.value(QStringLiteral("carId")).toString();
|
||||||
|
if (!carId.isEmpty()) {
|
||||||
|
const QUuid carUuid = QUuid::fromString(carId);
|
||||||
|
if (carUuid.isNull())
|
||||||
|
return createErrorResponse(requestId, QStringLiteral("invalidCarId"));
|
||||||
|
carThingIds.append(carUuid.toString(QUuid::WithoutBraces));
|
||||||
|
} else {
|
||||||
|
const QString chargerId = payload.value(QStringLiteral("chargerId")).toString();
|
||||||
|
if (!chargerId.isEmpty())
|
||||||
|
carThingIds = carThingIdsForCharger(chargerId);
|
||||||
|
}
|
||||||
|
|
||||||
m_pendingChargingSessionsRequests.insert(requestId, QPointer<QWebSocket>(socket));
|
m_pendingChargingSessionsRequests.insert(requestId, QPointer<QWebSocket>(socket));
|
||||||
m_chargingSessionsClient->getSessions(carThingIds);
|
m_chargingSessionsClient->getSessions(carThingIds);
|
||||||
@ -480,6 +542,36 @@ QJsonObject EvDashEngine::packCharger(Thing *charger) const
|
|||||||
return chargerObject;
|
return chargerObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject EvDashEngine::packCar(Thing *car) const
|
||||||
|
{
|
||||||
|
QJsonObject carObject;
|
||||||
|
if (!car)
|
||||||
|
return carObject;
|
||||||
|
|
||||||
|
carObject.insert("id", car->id().toString(QUuid::WithoutBraces));
|
||||||
|
carObject.insert("name", car->name());
|
||||||
|
|
||||||
|
return carObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EvDashEngine::isChargerThing(Thing *thing) const
|
||||||
|
{
|
||||||
|
if (!thing)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QStringList interfaces = thing->thingClass().interfaces();
|
||||||
|
return interfaces.contains(QStringLiteral("evcharger"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EvDashEngine::isCarThing(Thing *thing) const
|
||||||
|
{
|
||||||
|
if (!thing)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QStringList interfaces = thing->thingClass().interfaces();
|
||||||
|
return interfaces.contains(QStringLiteral("electricvehicle"));
|
||||||
|
}
|
||||||
|
|
||||||
QStringList EvDashEngine::carThingIdsForCharger(const QString &chargerId) const
|
QStringList EvDashEngine::carThingIdsForCharger(const QString &chargerId) const
|
||||||
{
|
{
|
||||||
QStringList carThingIds;
|
QStringList carThingIds;
|
||||||
|
|||||||
@ -92,10 +92,14 @@ private:
|
|||||||
|
|
||||||
QList<Thing *> m_chargers;
|
QList<Thing *> m_chargers;
|
||||||
void monitorChargerThing(Thing *thing);
|
void monitorChargerThing(Thing *thing);
|
||||||
|
QList<Thing *> m_cars;
|
||||||
|
void monitorCarThing(Thing *thing);
|
||||||
|
|
||||||
// Pending requests waiting for charging sessions data to return
|
// Pending requests waiting for charging sessions data to return
|
||||||
QHash<QString, QPointer<QWebSocket>> m_pendingChargingSessionsRequests;
|
QHash<QString, QPointer<QWebSocket>> m_pendingChargingSessionsRequests;
|
||||||
QStringList carThingIdsForCharger(const QString &chargerId) const;
|
QStringList carThingIdsForCharger(const QString &chargerId) const;
|
||||||
|
bool isChargerThing(Thing *thing) const;
|
||||||
|
bool isCarThing(Thing *thing) const;
|
||||||
|
|
||||||
// Websocket server
|
// Websocket server
|
||||||
bool startWebSocketServer(quint16 port = 0);
|
bool startWebSocketServer(quint16 port = 0);
|
||||||
@ -111,6 +115,7 @@ private:
|
|||||||
QJsonObject createErrorResponse(const QString &requestId, const QString &errorMessage) const;
|
QJsonObject createErrorResponse(const QString &requestId, const QString &errorMessage) const;
|
||||||
|
|
||||||
QJsonObject packCharger(Thing *charger) const;
|
QJsonObject packCharger(Thing *charger) const;
|
||||||
|
QJsonObject packCar(Thing *car) const;
|
||||||
void onSessionsReceived(const QList<QVariantMap> &sessions);
|
void onSessionsReceived(const QList<QVariantMap> &sessions);
|
||||||
void onSessionsError(const QString &errorMessage);
|
void onSessionsError(const QString &errorMessage);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user