Implement discovery and reply error handling
parent
5acce61d6a
commit
52e481bfaa
|
|
@ -5,6 +5,7 @@ PKGCONFIG += nymea-mqtt
|
|||
|
||||
SOURCES += \
|
||||
jsonrpc/everestjsonrpcclient.cpp \
|
||||
jsonrpc/everestjsonrpcdiscovery.cpp \
|
||||
jsonrpc/everestjsonrpcinterface.cpp \
|
||||
jsonrpc/everestjsonrpcreply.cpp \
|
||||
mqtt/everestmqtt.cpp \
|
||||
|
|
@ -14,6 +15,7 @@ SOURCES += \
|
|||
|
||||
HEADERS += \
|
||||
jsonrpc/everestjsonrpcclient.h \
|
||||
jsonrpc/everestjsonrpcdiscovery.h \
|
||||
jsonrpc/everestjsonrpcinterface.h \
|
||||
jsonrpc/everestjsonrpcreply.h \
|
||||
mqtt/everestmqtt.h \
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "integrationplugineverest.h"
|
||||
#include "plugininfo.h"
|
||||
#include "mqtt/everestmqttdiscovery.h"
|
||||
#include "jsonrpc/everestjsonrpcdiscovery.h"
|
||||
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
|
|
@ -41,8 +42,8 @@ IntegrationPluginEverest::IntegrationPluginEverest()
|
|||
|
||||
void IntegrationPluginEverest::init()
|
||||
{
|
||||
EverestJsonRpcClient *client = new EverestJsonRpcClient(this);
|
||||
client->setSeverUrl(QUrl("ws://10.10.10.165:8080"));
|
||||
// EverestJsonRpcClient *client = new EverestJsonRpcClient(this);
|
||||
// client->connectToServer(QUrl("ws://10.10.10.165:8080"));
|
||||
}
|
||||
|
||||
void IntegrationPluginEverest::startMonitoringAutoThings()
|
||||
|
|
@ -51,13 +52,13 @@ void IntegrationPluginEverest::startMonitoringAutoThings()
|
|||
// Since this integration plugin is most liekly running on an EV charger running EVerest, the local instance should
|
||||
// be set up automatically. Additional instances in the network can still be added by running a normal network discovery
|
||||
|
||||
EverestMqttDiscovery *discovery = new EverestMqttDiscovery(nullptr, this);
|
||||
connect(discovery, &EverestMqttDiscovery::finished, discovery, &EverestMqttDiscovery::deleteLater);
|
||||
connect(discovery, &EverestMqttDiscovery::finished, this, [this, discovery](){
|
||||
EverestMqttDiscovery *mqttDiscovery = new EverestMqttDiscovery(nullptr, this);
|
||||
connect(mqttDiscovery, &EverestMqttDiscovery::finished, mqttDiscovery, &EverestMqttDiscovery::deleteLater);
|
||||
connect(mqttDiscovery, &EverestMqttDiscovery::finished, this, [this, mqttDiscovery](){
|
||||
|
||||
ThingDescriptors descriptors;
|
||||
|
||||
foreach (const EverestMqttDiscovery::Result &result, discovery->results()) {
|
||||
foreach (const EverestMqttDiscovery::Result &result, mqttDiscovery->results()) {
|
||||
|
||||
// Create one EV charger foreach available connector on that host
|
||||
foreach(const QString &connectorName, result.connectors) {
|
||||
|
|
@ -106,7 +107,7 @@ void IntegrationPluginEverest::startMonitoringAutoThings()
|
|||
}
|
||||
});
|
||||
|
||||
discovery->startLocalhost();
|
||||
mqttDiscovery->startLocalhost();
|
||||
}
|
||||
|
||||
void IntegrationPluginEverest::discoverThings(ThingDiscoveryInfo *info)
|
||||
|
|
@ -118,80 +119,163 @@ void IntegrationPluginEverest::discoverThings(ThingDiscoveryInfo *info)
|
|||
return;
|
||||
}
|
||||
|
||||
EverestMqttDiscovery *discovery = new EverestMqttDiscovery(hardwareManager()->networkDeviceDiscovery(), this);
|
||||
connect(discovery, &EverestMqttDiscovery::finished, discovery, &EverestMqttDiscovery::deleteLater);
|
||||
connect(discovery, &EverestMqttDiscovery::finished, info, [this, info, discovery](){
|
||||
|
||||
foreach (const EverestMqttDiscovery::Result &result, discovery->results()) {
|
||||
if (info->thingClassId() == everestMqttThingClassId) {
|
||||
EverestMqttDiscovery *mqttDiscovery = new EverestMqttDiscovery(hardwareManager()->networkDeviceDiscovery(), this);
|
||||
connect(mqttDiscovery, &EverestMqttDiscovery::finished, mqttDiscovery, &EverestMqttDiscovery::deleteLater);
|
||||
connect(mqttDiscovery, &EverestMqttDiscovery::finished, info, [this, info, mqttDiscovery](){
|
||||
|
||||
// Create one EV charger foreach available connector on that host
|
||||
foreach(const QString &connectorName, result.connectors) {
|
||||
foreach (const EverestMqttDiscovery::Result &result, mqttDiscovery->results()) {
|
||||
|
||||
QString title = QString("Everest (%1)").arg(connectorName);
|
||||
QString description;
|
||||
MacAddressInfo macInfo;
|
||||
// Create one EV charger foreach available connector on that host
|
||||
foreach(const QString &connectorName, result.connectors) {
|
||||
|
||||
switch (result.networkDeviceInfo.monitorMode()) {
|
||||
case NetworkDeviceInfo::MonitorModeMac:
|
||||
macInfo = result.networkDeviceInfo.macAddressInfos().constFirst();
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
if (!macInfo.vendorName().isEmpty())
|
||||
description += " - " + result.networkDeviceInfo.macAddressInfos().constFirst().vendorName();
|
||||
QString title = QString("Everest (%1)").arg(connectorName);
|
||||
QString description;
|
||||
MacAddressInfo macInfo;
|
||||
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeHostName:
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeIp:
|
||||
description = "Interface: " + result.networkDeviceInfo.networkInterface().name();
|
||||
break;
|
||||
}
|
||||
switch (result.networkDeviceInfo.monitorMode()) {
|
||||
case NetworkDeviceInfo::MonitorModeMac:
|
||||
macInfo = result.networkDeviceInfo.macAddressInfos().constFirst();
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
if (!macInfo.vendorName().isEmpty())
|
||||
description += " - " + result.networkDeviceInfo.macAddressInfos().constFirst().vendorName();
|
||||
|
||||
ThingDescriptor descriptor(everestMqttThingClassId, title, description);
|
||||
qCInfo(dcEverest()) << "Discovered -->" << title << description;
|
||||
|
||||
// Note: the network device info already provides the correct set of parameters in order to be used by the monitor
|
||||
// depending on the possibilities within this network. It is not recommended to fill in all information available.
|
||||
// Only the information available depending on the monitor mode are relevant for the monitor.
|
||||
ParamList params;
|
||||
params.append(Param(everestMqttThingConnectorParamTypeId, connectorName));
|
||||
params.append(Param(everestMqttThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress()));
|
||||
params.append(Param(everestMqttThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName()));
|
||||
params.append(Param(everestMqttThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress()));
|
||||
descriptor.setParams(params);
|
||||
|
||||
// Let's check if we aleardy have a thing with those params
|
||||
bool thingExists = true;
|
||||
Thing *existingThing = nullptr;
|
||||
foreach (Thing *thing, myThings()) {
|
||||
if (thing->thingClassId() != info->thingClassId())
|
||||
continue;
|
||||
|
||||
foreach(const Param ¶m, params) {
|
||||
if (param.value() != thing->paramValue(param.paramTypeId())) {
|
||||
thingExists = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeHostName:
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeIp:
|
||||
description = "Interface: " + result.networkDeviceInfo.networkInterface().name();
|
||||
break;
|
||||
}
|
||||
|
||||
// The params are equal, we already know this thing
|
||||
if (thingExists)
|
||||
existingThing = thing;
|
||||
ThingDescriptor descriptor(everestMqttThingClassId, title, description);
|
||||
qCInfo(dcEverest()) << "Discovered -->" << title << description;
|
||||
|
||||
// Note: the network device info already provides the correct set of parameters in order to be used by the monitor
|
||||
// depending on the possibilities within this network. It is not recommended to fill in all information available.
|
||||
// Only the information available depending on the monitor mode are relevant for the monitor.
|
||||
ParamList params;
|
||||
params.append(Param(everestMqttThingConnectorParamTypeId, connectorName));
|
||||
params.append(Param(everestMqttThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress()));
|
||||
params.append(Param(everestMqttThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName()));
|
||||
params.append(Param(everestMqttThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress()));
|
||||
descriptor.setParams(params);
|
||||
|
||||
// Let's check if we aleardy have a thing with those params
|
||||
bool thingExists = true;
|
||||
Thing *existingThing = nullptr;
|
||||
foreach (Thing *thing, myThings()) {
|
||||
if (thing->thingClassId() != info->thingClassId())
|
||||
continue;
|
||||
|
||||
foreach(const Param ¶m, params) {
|
||||
if (param.value() != thing->paramValue(param.paramTypeId())) {
|
||||
thingExists = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The params are equal, we already know this thing
|
||||
if (thingExists)
|
||||
existingThing = thing;
|
||||
}
|
||||
|
||||
// Set the thing ID id we already have this device (for reconfiguration)
|
||||
if (existingThing)
|
||||
descriptor.setThingId(existingThing->id());
|
||||
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
|
||||
// Set the thing ID id we already have this device (for reconfiguration)
|
||||
if (existingThing)
|
||||
descriptor.setThingId(existingThing->id());
|
||||
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
// All discovery results processed, we are done
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
// All discovery results processed, we are done
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
|
||||
discovery->start();
|
||||
mqttDiscovery->start();
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->thingClassId() == everestJsonRpcThingClassId) {
|
||||
quint16 port = info->params().paramValue(everestJsonRpcDiscoveryPortParamTypeId).toUInt();
|
||||
EverestJsonRpcDiscovery *jsonRpcDiscovery = new EverestJsonRpcDiscovery(hardwareManager()->networkDeviceDiscovery(), port, this);
|
||||
connect(jsonRpcDiscovery, &EverestJsonRpcDiscovery::finished, jsonRpcDiscovery, &EverestJsonRpcDiscovery::deleteLater);
|
||||
connect(jsonRpcDiscovery, &EverestJsonRpcDiscovery::finished, info, [this, info, jsonRpcDiscovery, port](){
|
||||
|
||||
foreach (const EverestJsonRpcDiscovery::Result &result, jsonRpcDiscovery->results()) {
|
||||
|
||||
// Create one EV charger foreach available connector on that host
|
||||
// foreach(const QString &connectorName, result.connectors) {
|
||||
|
||||
QString title = QString("Everest");
|
||||
QString description;
|
||||
MacAddressInfo macInfo;
|
||||
|
||||
switch (result.networkDeviceInfo.monitorMode()) {
|
||||
case NetworkDeviceInfo::MonitorModeMac:
|
||||
macInfo = result.networkDeviceInfo.macAddressInfos().constFirst();
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
if (!macInfo.vendorName().isEmpty())
|
||||
description += " - " + result.networkDeviceInfo.macAddressInfos().constFirst().vendorName();
|
||||
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeHostName:
|
||||
description = result.networkDeviceInfo.address().toString();
|
||||
break;
|
||||
case NetworkDeviceInfo::MonitorModeIp:
|
||||
description = "Interface: " + result.networkDeviceInfo.networkInterface().name();
|
||||
break;
|
||||
}
|
||||
|
||||
ThingDescriptor descriptor(everestJsonRpcThingClassId, title, description);
|
||||
qCInfo(dcEverest()) << "Discovered -->" << title << description;
|
||||
|
||||
// Note: the network device info already provides the correct set of parameters in order to be used by the monitor
|
||||
// depending on the possibilities within this network. It is not recommended to fill in all information available.
|
||||
// Only the information available depending on the monitor mode are relevant for the monitor.
|
||||
ParamList params;
|
||||
params.append(Param(everestJsonRpcThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress()));
|
||||
params.append(Param(everestJsonRpcThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName()));
|
||||
params.append(Param(everestJsonRpcThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress()));
|
||||
params.append(Param(everestJsonRpcThingPortParamTypeId, port));
|
||||
descriptor.setParams(params);
|
||||
|
||||
// Let's check if we aleardy have a thing with those params
|
||||
bool thingExists = true;
|
||||
Thing *existingThing = nullptr;
|
||||
foreach (Thing *thing, myThings()) {
|
||||
if (thing->thingClassId() != info->thingClassId())
|
||||
continue;
|
||||
|
||||
foreach(const Param ¶m, params) {
|
||||
if (param.value() != thing->paramValue(param.paramTypeId())) {
|
||||
thingExists = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The params are equal, we already know this thing
|
||||
if (thingExists)
|
||||
existingThing = thing;
|
||||
}
|
||||
|
||||
// Set the thing ID id we already have this device (for reconfiguration)
|
||||
if (existingThing)
|
||||
descriptor.setThingId(existingThing->id());
|
||||
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
// }
|
||||
|
||||
// All discovery results processed, we are done
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
|
||||
jsonRpcDiscovery->start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginEverest::setupThing(ThingSetupInfo *info)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
"thingClasses": [
|
||||
{
|
||||
"name": "everestMqtt",
|
||||
"displayName": "Everest",
|
||||
"displayName": "Everest (MQTT)",
|
||||
"id": "965cbe0d-088c-42a2-965d-ceafbb8b01e9",
|
||||
"setupMethod": "JustAdd",
|
||||
"createMethods": ["discovery", "user"],
|
||||
|
|
@ -171,6 +171,187 @@
|
|||
],
|
||||
"eventTypes": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "everestJsonRpc",
|
||||
"displayName": "Everest (JSON RPC)",
|
||||
"id": "7f0387b9-670a-4e63-b100-ead9f6b8e46c",
|
||||
"setupMethod": "JustAdd",
|
||||
"createMethods": ["discovery", "user"],
|
||||
"interfaces": [ "evcharger", "smartmeterconsumer", "networkdevice", "connectable" ],
|
||||
"discoveryParamTypes": [
|
||||
{
|
||||
"id": "ce21618e-1a2a-4dbc-8843-98eb443ca6c3",
|
||||
"name": "port",
|
||||
"displayName": "Port",
|
||||
"type": "uint",
|
||||
"defaultValue": 8080
|
||||
}
|
||||
],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "c54926e2-7b88-4400-b1ca-d01a370919e7",
|
||||
"name": "hostName",
|
||||
"displayName": "Host name",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "b0b52731-56be-4b9e-931a-512b1f9dfe28",
|
||||
"name": "address",
|
||||
"displayName": "IP address",
|
||||
"type": "QString",
|
||||
"inputType": "IPv4Address",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "839ece70-472c-4c99-97ae-476be75ba996",
|
||||
"name": "macAddress",
|
||||
"displayName": "MAC address",
|
||||
"type": "QString",
|
||||
"defaultValue": "00:00:00:00:00:00",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "e0b6b5d8-78db-4e47-83d2-f8a82cd94648",
|
||||
"name": "connector",
|
||||
"displayName": "Connector name",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "3c16a1fa-39a8-4ed0-ab00-14b71882726d",
|
||||
"name": "port",
|
||||
"displayName": "Port",
|
||||
"type": "uint",
|
||||
"defaultValue": 8080
|
||||
}
|
||||
],
|
||||
"settingsTypes": [],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "2cbe44b1-5b34-43d6-89d8-bece220270d3",
|
||||
"name": "power",
|
||||
"displayName": "Charging enabled",
|
||||
"displayNameAction": "Enable or disable charging",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "b4d4e47a-d229-409b-b6d4-d5c13783f445",
|
||||
"name": "maxChargingCurrent",
|
||||
"displayName": "Maximum charging current",
|
||||
"displayNameAction": "Set maximum charging current",
|
||||
"type": "uint",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 6,
|
||||
"minValue": 6,
|
||||
"maxValue": 32,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "85184e0e-e17e-4f1d-8708-9e8b2f95df74",
|
||||
"name": "pluggedIn",
|
||||
"displayName": "Plugged in",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "8a39135e-7149-4ccb-9e0a-1fb499107965",
|
||||
"name": "charging",
|
||||
"displayName": "Charging",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "d95c8330-b219-4c70-837d-a7ab52c1f02a",
|
||||
"name": "phaseCount",
|
||||
"displayName": "Active phases",
|
||||
"type": "uint",
|
||||
"minValue": 1,
|
||||
"maxValue": 3,
|
||||
"defaultValue": 1
|
||||
},
|
||||
{
|
||||
"id": "7dbdd0f3-79f3-404f-8aad-6319eb4a8385",
|
||||
"name": "desiredPhaseCount",
|
||||
"displayName": "Desired phase count",
|
||||
"displayNameAction": "Set desired phase count",
|
||||
"type": "uint",
|
||||
"minValue": 1,
|
||||
"maxValue": 3,
|
||||
"possibleValues": [1, 3],
|
||||
"writable": true,
|
||||
"defaultValue": 3
|
||||
},
|
||||
{
|
||||
"id": "1cd82dab-82d8-4dbb-852e-4567284d20e9",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"cached": false,
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "4c0a0f46-1f31-4d19-93c5-140dceb364ef",
|
||||
"name": "totalEnergyConsumed",
|
||||
"displayName": "Total energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0,
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "ad0ab5f1-8803-426a-9110-29c9d788eedc",
|
||||
"name": "sessionEnergy",
|
||||
"displayName": "Session energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0,
|
||||
"suggestLogging": true
|
||||
},
|
||||
{
|
||||
"id": "c20d0f42-afe4-47da-9c84-97fba99053b5",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "126a5d55-ee47-4859-8ef2-bc8e79d1372a",
|
||||
"name": "state",
|
||||
"displayName": "State",
|
||||
"type": "QString",
|
||||
"defaultValue": "",
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "9df97785-91cd-482f-99f1-c910275bb630",
|
||||
"name": "temperature",
|
||||
"displayName": "Temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0.0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "f460d54d-8935-4f79-b79a-405de8f2b3ec",
|
||||
"name": "fanSpeed",
|
||||
"displayName": "Fan speed",
|
||||
"type": "double",
|
||||
"unit": "Rpm",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
||||
],
|
||||
"eventTypes": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -35,21 +35,89 @@
|
|||
#include <QJsonParseError>
|
||||
|
||||
EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent)
|
||||
: QObject{parent}
|
||||
: QObject{parent},
|
||||
m_interface{new EverestJsonRpcInterface(this)}
|
||||
{
|
||||
m_interface = new EverestJsonRpcInterface(this);
|
||||
connect(m_interface, &EverestJsonRpcInterface::dataReceived, this, &EverestJsonRpcClient::processDataPacket);
|
||||
connect(m_interface, &EverestJsonRpcInterface::connectedChanged, this, [this](bool connected){
|
||||
|
||||
qCDebug(dcEverest()) << "Interface is" << (connected ? "now connected" : "not connected any more");
|
||||
|
||||
if (connected) {
|
||||
EverestJsonRpcReply *reply = hello();
|
||||
|
||||
// The interface is connected, fetch initial data and mark the client as available if successfull,
|
||||
// otherwise emit connection error signal and close the connection
|
||||
|
||||
EverestJsonRpcReply *reply = apiHello();
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||
qCDebug(dcEverest()) << "Reply finished" << m_interface->serverUrl().toString() << reply->method();
|
||||
if (reply->error()) {
|
||||
qCWarning(dcEverest()) << "JsonRpc reply finished with error" << reply->method() << reply->error();
|
||||
disconnectFromServer();
|
||||
emit connectionErrorOccurred();
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify data format and API version
|
||||
QVariantMap result = reply->response().value("result").toMap();
|
||||
if (!result.contains("api_version") || !result.contains("everest_version") || !result.contains("charger_info")) {
|
||||
qCWarning(dcEverest()) << "Missing expected properties in JsonRpc response" << reply->method();
|
||||
disconnectFromServer();
|
||||
emit connectionErrorOccurred();
|
||||
return;
|
||||
}
|
||||
|
||||
//D | Everest: <-- {"id":0,"jsonrpc":"2.0","result":{"api_version":"0.0.1","authentication_required":false,"charger_info":{"firmware_version":"unknown","model":"unknown","serial":"unknown","vendor":"unknown"},"everest_version":""}
|
||||
m_apiVersion = result.value("api_version").toString();
|
||||
|
||||
EverestJsonRpcReply *reply = chargePointGetEVSEInfos();
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||
qCDebug(dcEverest()) << "Reply finished" << m_interface->serverUrl().toString() << reply->method()
|
||||
<< qUtf8Printable(QJsonDocument::fromVariant(reply->response()).toJson(QJsonDocument::Indented));
|
||||
|
||||
if (reply->error()) {
|
||||
qCWarning(dcEverest()) << "JsonRpc reply finished with error" << reply->method() << reply->error();
|
||||
disconnectFromServer();
|
||||
emit connectionErrorOccurred();
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap result = reply->response().value("result").toMap();
|
||||
QString errorString = result.value("error").toString();
|
||||
if (errorString != "NoError") {
|
||||
qCWarning(dcEverest()) << "Error requesting" << reply->method() << errorString;
|
||||
disconnectFromServer();
|
||||
emit connectionErrorOccurred();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: init infos
|
||||
|
||||
// Init data, we are done and connected.
|
||||
|
||||
if (!m_available) {
|
||||
m_available = true;
|
||||
emit availableChanged(m_available);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Client not available any more
|
||||
// Client disconnected. Clean up any pending replies
|
||||
qCDebug(dcEverest()) << "Lost connection to the server. Finish any pending replies ...";
|
||||
foreach (EverestJsonRpcReply *reply, m_replies) {
|
||||
reply->finishReply(EverestJsonRpcReply::ErrorConnectionError);
|
||||
}
|
||||
|
||||
if (m_available) {
|
||||
m_available = false;
|
||||
emit availableChanged(m_available);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_interface, &EverestJsonRpcInterface::dataReceived, this, &EverestJsonRpcClient::processDataPacket);
|
||||
}
|
||||
|
||||
QUrl EverestJsonRpcClient::serverUrl()
|
||||
|
|
@ -57,26 +125,79 @@ QUrl EverestJsonRpcClient::serverUrl()
|
|||
return m_interface->serverUrl();
|
||||
}
|
||||
|
||||
void EverestJsonRpcClient::setSeverUrl(const QUrl &serverUrl)
|
||||
bool EverestJsonRpcClient::available() const
|
||||
{
|
||||
return m_available;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::apiHello()
|
||||
{
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "API.Hello", QVariantMap(), this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::chargePointGetEVSEInfos()
|
||||
{
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "ChargePoint.GetEVSEInfos", QVariantMap(), this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::evseGetInfo()
|
||||
{
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "EVSE.GetInfo", QVariantMap(), this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::evseGetStatus(int evseIndex)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("evse_index", evseIndex);
|
||||
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "EVSE.GetStatus", params, this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::evseGetHardwareCapabilities(int evseIndex)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("evse_index", evseIndex);
|
||||
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "EVSE.GetStatus", params, this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void EverestJsonRpcClient::connectToServer(const QUrl &serverUrl)
|
||||
{
|
||||
m_interface->connectServer(serverUrl);
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::hello()
|
||||
void EverestJsonRpcClient::disconnectFromServer()
|
||||
{
|
||||
EverestJsonRpcReply *reply = new EverestJsonRpcReply(m_commandId, "API.Hello", QVariantMap(), this);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method();
|
||||
sendRequest(reply->requestMap());
|
||||
m_replies.insert(m_commandId, reply);
|
||||
m_commandId++;
|
||||
return reply;
|
||||
m_interface->disconnectServer();
|
||||
}
|
||||
|
||||
void EverestJsonRpcClient::sendRequest(const QVariantMap &request)
|
||||
void EverestJsonRpcClient::sendRequest(EverestJsonRpcReply *reply)
|
||||
{
|
||||
QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + '\n';
|
||||
QVariantMap requestMap = reply->requestMap();
|
||||
QByteArray data = QJsonDocument::fromVariant(requestMap).toJson(QJsonDocument::Compact) + '\n';
|
||||
|
||||
qCDebug(dcEverest()) << "-->" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
||||
m_interface->sendData(data);
|
||||
|
||||
m_replies.insert(m_commandId, reply);
|
||||
m_commandId++;
|
||||
|
||||
reply->startWaiting();
|
||||
}
|
||||
|
||||
void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
||||
|
|
@ -91,19 +212,26 @@ void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
|||
}
|
||||
|
||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||
if (!dataMap.contains("id") || dataMap.value("jsonrpc").toString() != "2.0") {
|
||||
qCWarning(dcEverest()) << "Received valid JSON data but does not seem to be a JSON RPC 2.0 format" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
||||
return;
|
||||
}
|
||||
|
||||
int commandId = dataMap.value("id").toInt();
|
||||
EverestJsonRpcReply *reply = m_replies.take(commandId);
|
||||
if (reply) {
|
||||
qCDebug(dcEverest()) << QString("Got response for %1: %2").arg(reply->method(), QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented)));
|
||||
|
||||
// if (dataMap.value("status").toString() == "error") {
|
||||
// qCWarning(dcEverest()) << "Api error happend" << dataMap.value("error").toString();
|
||||
// // FIMXME: handle json layer errors
|
||||
// }
|
||||
|
||||
reply->setResponse(dataMap);
|
||||
emit reply->finished();
|
||||
|
||||
// Verify if we received a json rpc error
|
||||
if (dataMap.contains("error")) {
|
||||
reply->finishReply(EverestJsonRpcReply::ErrorJsonRpcError);
|
||||
} else {
|
||||
reply->finishReply();
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
// Data without reply, check if this is a notification
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,24 +47,35 @@ public:
|
|||
|
||||
bool available() const;
|
||||
|
||||
EverestJsonRpcReply *hello();
|
||||
QString apiVersion() const;
|
||||
|
||||
// API calls
|
||||
EverestJsonRpcReply *apiHello();
|
||||
EverestJsonRpcReply *chargePointGetEVSEInfos();
|
||||
|
||||
EverestJsonRpcReply *evseGetInfo();
|
||||
EverestJsonRpcReply *evseGetStatus(int evseIndex);
|
||||
EverestJsonRpcReply *evseGetHardwareCapabilities(int evseIndex);
|
||||
|
||||
public slots:
|
||||
void connectToServer(const QUrl &serverUrl);
|
||||
void disconnectFromServer();
|
||||
|
||||
signals:
|
||||
void connectionErrorOccurred();
|
||||
void availableChanged(bool available);
|
||||
|
||||
private slots:
|
||||
void sendRequest(EverestJsonRpcReply *reply);
|
||||
void processDataPacket(const QByteArray &data);
|
||||
|
||||
private:
|
||||
bool m_available = false;
|
||||
|
||||
int m_commandId = 0;
|
||||
EverestJsonRpcInterface *m_interface = nullptr;
|
||||
|
||||
|
||||
QHash<int, EverestJsonRpcReply *> m_replies;
|
||||
|
||||
void sendRequest(const QVariantMap &request);
|
||||
|
||||
private slots:
|
||||
void processDataPacket(const QByteArray &data);
|
||||
QString m_apiVersion;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "everestjsonrpcdiscovery.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
EverestJsonRpcDiscovery::EverestJsonRpcDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, QObject *parent)
|
||||
: QObject{parent},
|
||||
m_networkDeviceDiscovery{networkDeviceDiscovery},
|
||||
m_port{port}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EverestJsonRpcDiscovery::start()
|
||||
{
|
||||
qCInfo(dcEverest()) << "Discovery: Start discovering Everest JsonRpc instances in the network...";
|
||||
m_startDateTime = QDateTime::currentDateTime();
|
||||
|
||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &EverestJsonRpcDiscovery::checkHostAddress);
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [discoveryReply, this](){
|
||||
qCDebug(dcEverest()) << "Discovery: Network device discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
||||
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
||||
|
||||
// Give the last connections added right before the network discovery finished a chance to check the device...
|
||||
QTimer::singleShot(3000, this, [this](){
|
||||
qCDebug(dcEverest()) << "Discovery: Grace period timer triggered.";
|
||||
finishDiscovery();
|
||||
});
|
||||
});
|
||||
|
||||
NetworkDeviceInfo localHostInfo;
|
||||
checkHostAddress(QHostAddress::LocalHost);
|
||||
}
|
||||
|
||||
void EverestJsonRpcDiscovery::startLocalhost()
|
||||
{
|
||||
qCInfo(dcEverest()) << "Discovery: Start discovering EVerest on localhost ...";
|
||||
m_startDateTime = QDateTime::currentDateTime();
|
||||
m_localhostDiscovery = true;
|
||||
|
||||
// For development, check local host
|
||||
NetworkDeviceInfo localHostInfo;
|
||||
checkHostAddress(QHostAddress::LocalHost);
|
||||
}
|
||||
|
||||
QList<EverestJsonRpcDiscovery::Result> EverestJsonRpcDiscovery::results() const
|
||||
{
|
||||
return m_results;
|
||||
}
|
||||
|
||||
void EverestJsonRpcDiscovery::checkHostAddress(const QHostAddress &address)
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme("ws");
|
||||
url.setHost(address.toString());
|
||||
url.setPort(m_port);
|
||||
|
||||
EverestJsonRpcClient *client = new EverestJsonRpcClient(this);
|
||||
connect(client, &EverestJsonRpcClient::availableChanged, this, [this, client, address](bool available){
|
||||
if (available) {
|
||||
qCDebug(dcEverest()) << "Discovery: Found JsonRpc interface on" << client->serverUrl().toString();
|
||||
|
||||
Result result;
|
||||
result.address = address;
|
||||
m_results.append(result);
|
||||
|
||||
cleanupClient(client);
|
||||
}
|
||||
});
|
||||
|
||||
connect(client, &EverestJsonRpcClient::connectionErrorOccurred, this, [this, client](){
|
||||
qCDebug(dcEverest()) << "Discovery: The connection to" << client->serverUrl().toString() << "failed. Skipping host";
|
||||
cleanupClient(client);
|
||||
});
|
||||
|
||||
client->connectToServer(url);
|
||||
}
|
||||
|
||||
void EverestJsonRpcDiscovery::cleanupClient(EverestJsonRpcClient *client)
|
||||
{
|
||||
if (!m_clients.contains(client))
|
||||
return;
|
||||
|
||||
m_clients.removeAll(client);
|
||||
|
||||
client->disconnectFromServer();
|
||||
client->deleteLater();
|
||||
|
||||
if (m_localhostDiscovery)
|
||||
finishDiscovery();
|
||||
|
||||
}
|
||||
|
||||
void EverestJsonRpcDiscovery::finishDiscovery()
|
||||
{
|
||||
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();
|
||||
|
||||
// Cleanup any leftovers
|
||||
foreach (EverestJsonRpcClient *client, m_clients)
|
||||
cleanupClient(client);
|
||||
|
||||
// Update results with final network device infos
|
||||
for (int i = 0; i < m_results.count(); i++)
|
||||
m_results[i].networkDeviceInfo = m_networkDeviceInfos.get(m_results.at(i).address);
|
||||
|
||||
qCInfo(dcEverest()) << "Discovery: Finished the discovery process. Found"
|
||||
<< m_results.count() << "Everest JsonRpc instances in"
|
||||
<< QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef EVERESTJSONRPCDISCOVERY_H
|
||||
#define EVERESTJSONRPCDISCOVERY_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
#include "jsonrpc/everestjsonrpcclient.h"
|
||||
|
||||
class EverestJsonRpcDiscovery : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef struct Result {
|
||||
QHostAddress address;
|
||||
NetworkDeviceInfo networkDeviceInfo;
|
||||
} Result;
|
||||
|
||||
explicit EverestJsonRpcDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port = 8080, QObject *parent = nullptr);
|
||||
|
||||
void start();
|
||||
void startLocalhost();
|
||||
|
||||
QList<EverestJsonRpcDiscovery::Result> results() const;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
|
||||
quint16 m_port = 8080;
|
||||
|
||||
QDateTime m_startDateTime;
|
||||
NetworkDeviceInfos m_networkDeviceInfos;
|
||||
QList<EverestJsonRpcClient *> m_clients;
|
||||
QList<EverestJsonRpcDiscovery::Result> m_results;
|
||||
|
||||
bool m_localhostDiscovery = false;
|
||||
|
||||
void checkHostAddress(const QHostAddress &address);
|
||||
void cleanupClient(EverestJsonRpcClient *client);
|
||||
void finishDiscovery();
|
||||
|
||||
};
|
||||
|
||||
#endif // EVERESTJSONRPCDISCOVERY_H
|
||||
|
|
@ -36,7 +36,17 @@ EverestJsonRpcReply::EverestJsonRpcReply(int commandId, QString method, QVariant
|
|||
m_method{method},
|
||||
m_params{params}
|
||||
{
|
||||
m_timer.setInterval(2000);
|
||||
m_timer.setSingleShot(true);
|
||||
connect(&m_timer, &QTimer::timeout, this, [this](){
|
||||
m_error = ErrorTimeout;
|
||||
emit finished();
|
||||
});
|
||||
}
|
||||
|
||||
EverestJsonRpcReply::Error EverestJsonRpcReply::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int EverestJsonRpcReply::commandId() const
|
||||
|
|
@ -44,7 +54,6 @@ int EverestJsonRpcReply::commandId() const
|
|||
return m_commandId;
|
||||
}
|
||||
|
||||
|
||||
QString EverestJsonRpcReply::method() const
|
||||
{
|
||||
return m_method;
|
||||
|
|
@ -77,3 +86,15 @@ void EverestJsonRpcReply::setResponse(const QVariantMap &response)
|
|||
{
|
||||
m_response = response;
|
||||
}
|
||||
|
||||
void EverestJsonRpcReply::startWaiting()
|
||||
{
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void EverestJsonRpcReply::finishReply(Error error)
|
||||
{
|
||||
m_timer.stop();
|
||||
m_error = error;
|
||||
emit finished();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,32 +31,53 @@
|
|||
#ifndef EVERESTJSONRPCREPLY_H
|
||||
#define EVERESTJSONRPCREPLY_H
|
||||
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class EverestJsonRpcReply : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EverestJsonRpcReply(int commandId, QString method, QVariantMap params = QVariantMap(), QObject *parent = nullptr);
|
||||
|
||||
friend class EverestJsonRpcClient;
|
||||
|
||||
public:
|
||||
enum Error {
|
||||
ErrorNoError = 0,
|
||||
ErrorTimeout,
|
||||
ErrorConnectionError,
|
||||
ErrorJsonRpcError
|
||||
};
|
||||
Q_ENUM(Error)
|
||||
|
||||
Error error() const;
|
||||
|
||||
// Request
|
||||
int commandId() const;
|
||||
QString method() const;
|
||||
QVariantMap params() const;
|
||||
QVariantMap requestMap();
|
||||
|
||||
// Response
|
||||
QVariantMap response() const;
|
||||
void setResponse(const QVariantMap &response);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
explicit EverestJsonRpcReply(int commandId, QString method, QVariantMap params = QVariantMap(), QObject *parent = nullptr);
|
||||
|
||||
int m_commandId;
|
||||
QString m_method;
|
||||
QVariantMap m_params;
|
||||
QVariantMap m_response;
|
||||
|
||||
QTimer m_timer;
|
||||
Error m_error = ErrorNoError;
|
||||
|
||||
void setResponse(const QVariantMap &response);
|
||||
void startWaiting();
|
||||
void finishReply(Error error = ErrorNoError);
|
||||
};
|
||||
|
||||
#endif // EVERESTJSONRPCREPLY_H
|
||||
|
|
|
|||
|
|
@ -111,32 +111,31 @@ void EverestMqttDiscovery::checkHostAddress(const QHostAddress &address)
|
|||
// We found a mqtt server, let's check if we find everest_api module on it...
|
||||
qCDebug(dcEverest()) << "Discovery: Successfully connected to host" << address.toString();
|
||||
|
||||
connect(client, &MqttClient::publishReceived, client, [this, client, address]
|
||||
(const QString &topic, const QByteArray &payload, bool retained) {
|
||||
connect(client, &MqttClient::publishReceived, client, [this, client, address] (const QString &topic, const QByteArray &payload, bool retained) {
|
||||
|
||||
qCDebug(dcEverest()) << "Discovery: Received publish on" << topic
|
||||
<< "retained:" << retained << qUtf8Printable(payload);
|
||||
qCDebug(dcEverest()) << "Discovery: Received publish on" << topic
|
||||
<< "retained:" << retained << qUtf8Printable(payload);
|
||||
|
||||
if (topic == m_everestApiModuleTopicConnectors) {
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &jsonError);
|
||||
if (jsonError.error) {
|
||||
qCDebug(dcEverest()) << "Discovery: Received payload on topic" << topic
|
||||
<< "with JSON error:" << jsonError.errorString();
|
||||
cleanupClient(client);
|
||||
return;
|
||||
}
|
||||
if (topic == m_everestApiModuleTopicConnectors) {
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &jsonError);
|
||||
if (jsonError.error) {
|
||||
qCDebug(dcEverest()) << "Discovery: Received payload on topic" << topic
|
||||
<< "with JSON error:" << jsonError.errorString();
|
||||
cleanupClient(client);
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList connectors = jsonDoc.toVariant().toStringList();
|
||||
qCInfo(dcEverest()) << "Discovery: Found Everest on" << address.toString() << connectors;
|
||||
Result result;
|
||||
result.address = address;
|
||||
result.connectors = connectors;
|
||||
m_results.append(result);
|
||||
QStringList connectors = jsonDoc.toVariant().toStringList();
|
||||
qCInfo(dcEverest()) << "Discovery: Found Everest on" << address.toString() << connectors;
|
||||
Result result;
|
||||
result.address = address;
|
||||
result.connectors = connectors;
|
||||
m_results.append(result);
|
||||
|
||||
cleanupClient(client);
|
||||
}
|
||||
});
|
||||
cleanupClient(client);
|
||||
}
|
||||
});
|
||||
|
||||
connect(client, &MqttClient::subscribeResult, client, [this, client]
|
||||
(quint16 packetId, const Mqtt::SubscribeReturnCodes &subscribeReturnCodes) {
|
||||
|
|
@ -189,7 +188,7 @@ void EverestMqttDiscovery::finishDiscovery()
|
|||
m_results[i].networkDeviceInfo = m_networkDeviceInfos.get(m_results.at(i).address);
|
||||
|
||||
qCInfo(dcEverest()) << "Discovery: Finished the discovery process. Found"
|
||||
<< m_results.count() << "Everest instances in"
|
||||
<< m_results.count() << "Everest mqtt instances in"
|
||||
<< QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||
|
||||
emit finished();
|
||||
|
|
|
|||
Loading…
Reference in New Issue