diff --git a/everest/everst.png b/everest/everest.png similarity index 100% rename from everest/everst.png rename to everest/everest.png diff --git a/everest/everest.pro b/everest/everest.pro index 36759647..91c7f1c5 100644 --- a/everest/everest.pro +++ b/everest/everest.pro @@ -1,17 +1,18 @@ include(../plugins.pri) -QT += network +QT += network websockets PKGCONFIG += nymea-mqtt SOURCES += \ - everest.cpp \ - everestclient.cpp \ - everestdiscovery.cpp \ - integrationplugineverest.cpp + mqtt/everestmqtt.cpp \ + mqtt/everestmqttclient.cpp \ + mqtt/everestmqttdiscovery.cpp \ + integrationplugineverest.cpp \ + jsonrpc/everestjsonrpcclient.cpp HEADERS += \ - everest.h \ - everestclient.h \ - everestdiscovery.h \ - integrationplugineverest.h - + mqtt/everestmqtt.h \ + mqtt/everestmqttclient.h \ + mqtt/everestmqttdiscovery.h \ + integrationplugineverest.h \ + jsonrpc/everestjsonrpcclient.h diff --git a/everest/integrationplugineverest.cpp b/everest/integrationplugineverest.cpp index ea91fe1b..8b0ec9d5 100644 --- a/everest/integrationplugineverest.cpp +++ b/everest/integrationplugineverest.cpp @@ -30,7 +30,7 @@ #include "integrationplugineverest.h" #include "plugininfo.h" -#include "everestdiscovery.h" +#include "mqtt/everestmqttdiscovery.h" #include @@ -47,29 +47,29 @@ void IntegrationPluginEverest::init() void IntegrationPluginEverest::startMonitoringAutoThings() { // Check on localhost if there is any EVerest instance running and if we have to set up a thing for this EV charger - // Since this integration plugin is most luikly running on an EV charger running EVerest, the local instance should + // 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 - EverestDiscovery *discovery = new EverestDiscovery(nullptr, this); - connect(discovery, &EverestDiscovery::finished, discovery, &EverestDiscovery::deleteLater); - connect(discovery, &EverestDiscovery::finished, this, [this, discovery](){ + EverestMqttDiscovery *discovery = new EverestMqttDiscovery(nullptr, this); + connect(discovery, &EverestMqttDiscovery::finished, discovery, &EverestMqttDiscovery::deleteLater); + connect(discovery, &EverestMqttDiscovery::finished, this, [this, discovery](){ ThingDescriptors descriptors; - foreach (const EverestDiscovery::Result &result, discovery->results()) { + foreach (const EverestMqttDiscovery::Result &result, discovery->results()) { // Create one EV charger foreach available connector on that host foreach(const QString &connectorName, result.connectors) { QString title = QString("EVerest"); QString description = connectorName; - ThingDescriptor descriptor(everestThingClassId, title, description); + ThingDescriptor descriptor(everestMqttThingClassId, title, description); qCInfo(dcEverest()) << "Discovered -->" << title << description; ParamList params; - params.append(Param(everestThingConnectorParamTypeId, connectorName)); - params.append(Param(everestThingAddressParamTypeId, result.address.toString())); + params.append(Param(everestMqttThingConnectorParamTypeId, connectorName)); + params.append(Param(everestMqttThingAddressParamTypeId, result.networkDeviceInfo.address().toString())); descriptor.setParams(params); // Let's check if we aleardy have a thing with those params @@ -117,11 +117,11 @@ void IntegrationPluginEverest::discoverThings(ThingDiscoveryInfo *info) return; } - EverestDiscovery *discovery = new EverestDiscovery(hardwareManager()->networkDeviceDiscovery(), this); - connect(discovery, &EverestDiscovery::finished, discovery, &EverestDiscovery::deleteLater); - connect(discovery, &EverestDiscovery::finished, info, [this, info, discovery](){ + EverestMqttDiscovery *discovery = new EverestMqttDiscovery(hardwareManager()->networkDeviceDiscovery(), this); + connect(discovery, &EverestMqttDiscovery::finished, discovery, &EverestMqttDiscovery::deleteLater); + connect(discovery, &EverestMqttDiscovery::finished, info, [this, info, discovery](){ - foreach (const EverestDiscovery::Result &result, discovery->results()) { + foreach (const EverestMqttDiscovery::Result &result, discovery->results()) { // Create one EV charger foreach available connector on that host foreach(const QString &connectorName, result.connectors) { @@ -146,17 +146,17 @@ void IntegrationPluginEverest::discoverThings(ThingDiscoveryInfo *info) break; } - ThingDescriptor descriptor(everestThingClassId, title, description); + 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(everestThingConnectorParamTypeId, connectorName)); - params.append(Param(everestThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress())); - params.append(Param(everestThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName())); - params.append(Param(everestThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress())); + 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 @@ -197,14 +197,14 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - QHostAddress address(thing->paramValue(everestThingAddressParamTypeId).toString()); - MacAddress macAddress(thing->paramValue(everestThingMacAddressParamTypeId).toString()); - QString hostName(thing->paramValue(everestThingHostNameParamTypeId).toString()); - QString connector(thing->paramValue(everestThingConnectorParamTypeId).toString()); + QHostAddress address(thing->paramValue(everestMqttThingAddressParamTypeId).toString()); + MacAddress macAddress(thing->paramValue(everestMqttThingMacAddressParamTypeId).toString()); + QString hostName(thing->paramValue(everestMqttThingHostNameParamTypeId).toString()); + QString connector(thing->paramValue(everestMqttThingConnectorParamTypeId).toString()); - EverestClient *everstClient = nullptr; + EverestMqttClient *everstClient = nullptr; - foreach (EverestClient *ec, m_everstClients) { + foreach (EverestMqttClient *ec, m_everstClients) { if (ec->monitor()->macAddress() == macAddress && ec->monitor()->hostName() == hostName && ec->monitor()->address() == address) { @@ -222,7 +222,7 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) return; } - everstClient = new EverestClient(this); + everstClient = new EverestMqttClient(this); everstClient->setMonitor(monitor); m_everstClients.append(everstClient); qCDebug(dcEverest()) << "Created new" << everstClient; @@ -240,17 +240,17 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) qCDebug(dcEverest()) << "Executing action for thing" << info->thing() << info->action().actionTypeId().toString() << info->action().params(); - if (info->thing()->thingClassId() == everestThingClassId) { + if (info->thing()->thingClassId() == everestMqttThingClassId) { Thing *thing = info->thing(); - EverestClient *everstClient = m_thingClients.value(thing); + EverestMqttClient *everstClient = m_thingClients.value(thing); if (!everstClient) { qCWarning(dcEverest()) << "Failed to execute action. Unable to find everst client for" << thing; info->finish(Thing::ThingErrorHardwareFailure); return; } - Everest *everest = everstClient->getEverest(thing); + EverestMqtt *everest = everstClient->getEverest(thing); if (!everest) { qCWarning(dcEverest()) << "Failed to execute action. Unable to find everst for" << thing << "on" << everstClient; @@ -258,32 +258,32 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) return; } - if (!thing->stateValue(everestConnectedStateTypeId).toBool()) { + if (!thing->stateValue(everestMqttConnectedStateTypeId).toBool()) { info->finish(Thing::ThingErrorHardwareNotAvailable); return; } // All checks where good, let's execute the action - if (info->action().actionTypeId() == everestPowerActionTypeId) { - bool power = info->action().paramValue(everestPowerActionPowerParamTypeId).toBool(); + if (info->action().actionTypeId() == everestMqttPowerActionTypeId) { + bool power = info->action().paramValue(everestMqttPowerActionPowerParamTypeId).toBool(); qCDebug(dcEverest()) << (power ? "Resume charging on" : "Pause charging on") << thing; everest->enableCharging(power); - thing->setStateValue(everestPowerStateTypeId, power); + thing->setStateValue(everestMqttPowerStateTypeId, power); info->finish(Thing::ThingErrorNoError); - } else if (info->action().actionTypeId() == everestMaxChargingCurrentActionTypeId) { + } else if (info->action().actionTypeId() == everestMqttMaxChargingCurrentActionTypeId) { // Note: once we support phase switching, we cannot use the - uint phaseCount = thing->stateValue(everestDesiredPhaseCountStateTypeId).toUInt(); - double current = info->action().paramValue(everestMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble(); + uint phaseCount = thing->stateValue(everestMqttDesiredPhaseCountStateTypeId).toUInt(); + double current = info->action().paramValue(everestMqttMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble(); qCDebug(dcEverest()).nospace() << "Setting max charging current to " << current << "A (Phases: " << phaseCount << ") " << thing; everest->setMaxChargingCurrentAndPhaseCount(phaseCount, current); - thing->setStateValue(everestMaxChargingCurrentStateTypeId, current); + thing->setStateValue(everestMqttMaxChargingCurrentStateTypeId, current); info->finish(Thing::ThingErrorNoError); - } else if (info->action().actionTypeId() == everestDesiredPhaseCountActionTypeId) { - uint phaseCount = info->action().paramValue(everestDesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt(); - double current = thing->stateValue(everestMaxChargingCurrentStateTypeId).toDouble(); + } else if (info->action().actionTypeId() == everestMqttDesiredPhaseCountActionTypeId) { + uint phaseCount = info->action().paramValue(everestMqttDesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt(); + double current = thing->stateValue(everestMqttMaxChargingCurrentStateTypeId).toDouble(); qCDebug(dcEverest()).nospace() << "Setting desired phase count to " << phaseCount << " (" << current << "A) " << thing; everest->setMaxChargingCurrentAndPhaseCount(phaseCount, current); - thing->setStateValue(everestDesiredPhaseCountStateTypeId, phaseCount); + thing->setStateValue(everestMqttDesiredPhaseCountStateTypeId, phaseCount); info->finish(Thing::ThingErrorNoError); } @@ -296,8 +296,8 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) void IntegrationPluginEverest::thingRemoved(Thing *thing) { qCDebug(dcEverest()) << "Remove thing" << thing; - if (thing->thingClassId() == everestThingClassId) { - EverestClient *everestClient = m_thingClients.take(thing); + if (thing->thingClassId() == everestMqttThingClassId) { + EverestMqttClient *everestClient = m_thingClients.take(thing); everestClient->removeThing(thing); if (everestClient->things().isEmpty()) { qCDebug(dcEverest()) << "Deleting" << everestClient << "since there is no thing left"; @@ -311,8 +311,6 @@ void IntegrationPluginEverest::thingRemoved(Thing *thing) everestClient->deleteLater(); } - - } } diff --git a/everest/integrationplugineverest.h b/everest/integrationplugineverest.h index fd8fcb72..b57a91e1 100644 --- a/everest/integrationplugineverest.h +++ b/everest/integrationplugineverest.h @@ -34,7 +34,7 @@ #include "integrations/integrationplugin.h" #include "extern-plugininfo.h" -#include "everestclient.h" +#include "mqtt/everestmqttclient.h" #include @@ -58,8 +58,8 @@ public: void executeAction(ThingActionInfo *info) override; private: - QList m_everstClients; - QHash m_thingClients; + QList m_everstClients; + QHash m_thingClients; }; diff --git a/everest/integrationplugineverest.json b/everest/integrationplugineverest.json index 727c3538..2fb7a6af 100644 --- a/everest/integrationplugineverest.json +++ b/everest/integrationplugineverest.json @@ -9,7 +9,7 @@ "id": "07ba8a98-799f-4a6e-a8d9-b45cd38dbcc5", "thingClasses": [ { - "name": "everest", + "name": "everestMqtt", "displayName": "Everest", "id": "965cbe0d-088c-42a2-965d-ceafbb8b01e9", "setupMethod": "JustAdd", diff --git a/everest/jsonrpc/everestjsonrpcclient.cpp b/everest/jsonrpc/everestjsonrpcclient.cpp new file mode 100644 index 00000000..e16e5e71 --- /dev/null +++ b/everest/jsonrpc/everestjsonrpcclient.cpp @@ -0,0 +1,84 @@ +#include "everestjsonrpcclient.h" +#include "extern-plugininfo.h" + +EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent) + : QObject{parent} +{ + m_webSocket = new QWebSocket("nymea-client", QWebSocketProtocol::Version13, this); + + connect(m_webSocket, &QWebSocket::disconnected, this, &EverestJsonRpcClient::onDisconnected); + connect(m_webSocket, &QWebSocket::textMessageReceived, this, &EverestJsonRpcClient::onTextMessageReceived); + connect(m_webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); + connect(m_webSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState))); +} + +EverestJsonRpcClient::~EverestJsonRpcClient() +{ + disconnectServer(); +} + +void EverestJsonRpcClient::sendData(const QByteArray &data) +{ + m_webSocket->sendTextMessage(QString::fromUtf8(data)); +} + +void EverestJsonRpcClient::connectServer(const QUrl &serverUrl) +{ + if (m_connected) { + m_connected = false; + emit connectedChanged(m_connected); + m_webSocket->close(); + } + + m_serverUrl = serverUrl; + + qCDebug(dcEverest()) << "Connecting to" << m_serverUrl.toString(); + m_webSocket->open(m_serverUrl); +} + +void EverestJsonRpcClient::disconnectServer() +{ + qCDebug(dcEverest()) << "Disconnecting from" << m_serverUrl.toString(); + m_webSocket->close(); +} + +void EverestJsonRpcClient::onDisconnected() +{ + qCDebug(dcEverest()) << "Disconnected from" << m_webSocket->requestUrl().toString() << m_webSocket->closeReason(); + + if (m_connected) { + m_connected = false; + emit connectedChanged(m_connected); + } +} + +void EverestJsonRpcClient::onError(QAbstractSocket::SocketError error) +{ + qCDebug(dcEverest()) << "Socket error occurred" << error << m_webSocket->errorString(); +} + +void EverestJsonRpcClient::onStateChanged(QAbstractSocket::SocketState state) +{ + qCDebug(dcEverest()) << "Socket state changed" << state; + + switch (state) { + case QAbstractSocket::ConnectedState: + qCDebug(dcEverest()) << "Connected with" << m_webSocket->requestUrl().toString(); + if (!m_connected) { + m_connected = true; + emit connectedChanged(m_connected); + } + break; + default: + if (m_connected) { + m_connected = false; + emit connectedChanged(m_connected); + } + break; + } +} + +void EverestJsonRpcClient::onTextMessageReceived(const QString &message) +{ + emit dataReceived(message.toUtf8()); +} diff --git a/everest/jsonrpc/everestjsonrpcclient.h b/everest/jsonrpc/everestjsonrpcclient.h new file mode 100644 index 00000000..3e059c94 --- /dev/null +++ b/everest/jsonrpc/everestjsonrpcclient.h @@ -0,0 +1,36 @@ +#ifndef EVERESTJSONRPCCLIENT_H +#define EVERESTJSONRPCCLIENT_H + +#include +#include + +class EverestJsonRpcClient : public QObject +{ + Q_OBJECT +public: + explicit EverestJsonRpcClient(QObject *parent = nullptr); + ~EverestJsonRpcClient(); + + void sendData(const QByteArray &data); + +public slots: + void connectServer(const QUrl &serverUrl); + void disconnectServer(); + +signals: + void connectedChanged(bool connected); + void dataReceived(const QByteArray &data); + +private slots: + void onDisconnected(); + void onError(QAbstractSocket::SocketError error); + void onStateChanged(QAbstractSocket::SocketState state); + void onTextMessageReceived(const QString &message); + +private: + QWebSocket *m_webSocket = nullptr; + QUrl m_serverUrl; + bool m_connected = false; +}; + +#endif // EVERESTJSONRPCCLIENT_H diff --git a/everest/everest.cpp b/everest/mqtt/everestmqtt.cpp similarity index 75% rename from everest/everest.cpp rename to everest/mqtt/everestmqtt.cpp index c78d3974..dde89261 100644 --- a/everest/everest.cpp +++ b/everest/mqtt/everestmqtt.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2024, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -28,7 +28,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "everest.h" +#include "everestmqtt.h" #include "extern-plugininfo.h" #include @@ -38,12 +38,12 @@ NYMEA_LOGGING_CATEGORY(dcEverestTraffic, "EverestTraffic") -Everest::Everest(MqttClient *client, Thing *thing, QObject *parent) +EverestMqtt::EverestMqtt(MqttClient *client, Thing *thing, QObject *parent) : QObject{parent}, m_client{client}, m_thing{thing} { - m_connector = m_thing->paramValue(everestThingConnectorParamTypeId).toString(); + m_connector = m_thing->paramValue(everestMqttThingConnectorParamTypeId).toString(); m_topicPrefix = "everest_api/" + m_connector; m_subscribedTopics.append(buildTopic("hardware_capabilities")); @@ -52,18 +52,18 @@ Everest::Everest(MqttClient *client, Thing *thing, QObject *parent) m_subscribedTopics.append(buildTopic("session_info")); m_subscribedTopics.append(buildTopic("telemetry")); - connect(m_client, &MqttClient::connected, this, &Everest::onConnected); - connect(m_client, &MqttClient::disconnected, this, &Everest::onDisconnected); - connect(m_client, &MqttClient::publishReceived, this, &Everest::onPublishReceived); - connect(m_client, &MqttClient::subscribed, this, &Everest::onSubscribed); + connect(m_client, &MqttClient::connected, this, &EverestMqtt::onConnected); + connect(m_client, &MqttClient::disconnected, this, &EverestMqtt::onDisconnected); + connect(m_client, &MqttClient::publishReceived, this, &EverestMqtt::onPublishReceived); + connect(m_client, &MqttClient::subscribed, this, &EverestMqtt::onSubscribed); m_aliveTimer.setInterval(2000); m_aliveTimer.setSingleShot(true); connect(&m_aliveTimer, &QTimer::timeout, this, [this](){ qCDebug(dcEverest()) << "No MQTT traffic since" << m_aliveTimer.interval() << "ms. Mark device as not connected" << m_thing; - m_thing->setStateValue(everestCurrentPowerStateTypeId, 0); - m_thing->setStateValue(everestConnectedStateTypeId, false); + m_thing->setStateValue(everestMqttCurrentPowerStateTypeId, 0); + m_thing->setStateValue(everestMqttConnectedStateTypeId, false); }); if (m_client->isConnected()) { @@ -72,22 +72,22 @@ Everest::Everest(MqttClient *client, Thing *thing, QObject *parent) } } -Everest::~Everest() +EverestMqtt::~EverestMqtt() { deinitialize(); } -Thing *Everest::thing() const +Thing *EverestMqtt::thing() const { return m_thing; } -QString Everest::connector() const +QString EverestMqtt::connector() const { return m_connector; } -void Everest::initialize() +void EverestMqtt::initialize() { qCDebug(dcEverest()) << "Initializing" << m_thing->name(); if (!m_client->isConnected()) { @@ -103,7 +103,7 @@ void Everest::initialize() qCDebug(dcEverest()) << "Initialized" << m_thing->name() << "successfully"; } -void Everest::deinitialize() +void EverestMqtt::deinitialize() { qCDebug(dcEverest()) << "Deinitializing" << m_thing->name(); if (m_initialized && m_client->isConnected()) { @@ -115,7 +115,7 @@ void Everest::deinitialize() m_initialized = false; } -void Everest::enableCharging(bool enable) +void EverestMqtt::enableCharging(bool enable) { QString topic; if (enable) { @@ -127,7 +127,7 @@ void Everest::enableCharging(bool enable) m_client->publish(topic, QByteArray::fromHex("01")); } -void Everest::setMaxChargingCurrent(double current) +void EverestMqtt::setMaxChargingCurrent(double current) { QString topic = m_topicPrefix + "/cmd/set_limit_amps"; QByteArray payload = QByteArray::number(current); @@ -135,7 +135,7 @@ void Everest::setMaxChargingCurrent(double current) m_client->publish(topic, payload); } -void Everest::setMaxChargingCurrentAndPhaseCount(uint phasesCount, double current) +void EverestMqtt::setMaxChargingCurrentAndPhaseCount(uint phasesCount, double current) { QString topic = m_topicPrefix + "/cmd/set_limit_amps_phases"; QVariantMap data; @@ -145,20 +145,20 @@ void Everest::setMaxChargingCurrentAndPhaseCount(uint phasesCount, double curren m_client->publish(topic, QJsonDocument::fromVariant(data).toJson()); } -void Everest::onConnected() +void EverestMqtt::onConnected() { m_aliveTimer.start(); initialize(); } -void Everest::onDisconnected() +void EverestMqtt::onDisconnected() { - m_thing->setStateValue(everestConnectedStateTypeId, false); - m_thing->setStateValue(everestCurrentPowerStateTypeId, 0); + m_thing->setStateValue(everestMqttConnectedStateTypeId, false); + m_thing->setStateValue(everestMqttCurrentPowerStateTypeId, 0); m_initialized = false; } -void Everest::onSubscribed(const QString &topic, Mqtt::SubscribeReturnCode subscribeReturnCode) +void EverestMqtt::onSubscribed(const QString &topic, Mqtt::SubscribeReturnCode subscribeReturnCode) { if (subscribeReturnCode == Mqtt::SubscribeReturnCodeFailure) { qCWarning(dcEverest()) << "Failed to subscribe to" << topic << m_thing; @@ -167,7 +167,7 @@ void Everest::onSubscribed(const QString &topic, Mqtt::SubscribeReturnCode subsc } } -void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, bool retained) +void EverestMqtt::onPublishReceived(const QString &topic, const QByteArray &payload, bool retained) { Q_UNUSED(retained) @@ -177,7 +177,7 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, // We are for sure connected now m_aliveTimer.start(); - m_thing->setStateValue(everestConnectedStateTypeId, true); + m_thing->setStateValue(everestMqttConnectedStateTypeId, true); qCDebug(dcEverestTraffic()) << "Received publish on" << topic << qUtf8Printable(payload); @@ -213,18 +213,18 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, uint maxCurrent = dataMap.value("max_current_A_import").toUInt(); uint minCurrent = dataMap.value("min_current_A_import").toUInt(); - m_thing->setStateMaxValue(everestMaxChargingCurrentStateTypeId, maxCurrent); - m_thing->setStateMinValue(everestMaxChargingCurrentStateTypeId, minCurrent == 0 ? 6 : minCurrent); + m_thing->setStateMaxValue(everestMqttMaxChargingCurrentStateTypeId, maxCurrent); + m_thing->setStateMinValue(everestMqttMaxChargingCurrentStateTypeId, minCurrent == 0 ? 6 : minCurrent); bool phaseSwitchingAvailable = dataMap.value("supports_changing_phases_during_charging", false).toBool(); if (!phaseSwitchingAvailable) { // Only option left is set the desired phase count to 3, force that value - m_thing->setStatePossibleValues(everestDesiredPhaseCountStateTypeId, { 3 }); - m_thing->setStateValue(everestDesiredPhaseCountStateTypeId, 3); - m_thing->setStateValue(everestPhaseCountStateTypeId, 3); + m_thing->setStatePossibleValues(everestMqttDesiredPhaseCountStateTypeId, { 3 }); + m_thing->setStateValue(everestMqttDesiredPhaseCountStateTypeId, 3); + m_thing->setStateValue(everestMqttPhaseCountStateTypeId, 3); } else { - m_thing->setStatePossibleValues(everestDesiredPhaseCountStateTypeId, { 1, 3 }); - m_thing->setStateValue(everestPhaseCountStateTypeId, m_thing->stateValue(everestDesiredPhaseCountStateTypeId)); + m_thing->setStatePossibleValues(everestMqttDesiredPhaseCountStateTypeId, { 1, 3 }); + m_thing->setStateValue(everestMqttPhaseCountStateTypeId, m_thing->stateValue(everestMqttDesiredPhaseCountStateTypeId)); } } else if (topic.endsWith("limits")) { @@ -240,7 +240,7 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, double maxCurrent = dataMap.value("max_current").toDouble(); if (maxCurrent >= 6) { // FIXME: make it a double again once supported from the interface - m_thing->setStateValue(everestMaxChargingCurrentStateTypeId, qRound(maxCurrent)); + m_thing->setStateValue(everestMqttMaxChargingCurrentStateTypeId, qRound(maxCurrent)); } } else if (topic.endsWith("powermeter")) { @@ -268,10 +268,10 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, */ QVariantMap dataMap = jsonDoc.toVariant().toMap(); QVariantMap energyImportedMap = dataMap.value("energy_Wh_import").toMap(); - m_thing->setStateValue(everestTotalEnergyConsumedStateTypeId, + m_thing->setStateValue(everestMqttTotalEnergyConsumedStateTypeId, energyImportedMap.value("total").toDouble() / 1000.0); QVariantMap powerMap = dataMap.value("power_W").toMap(); - m_thing->setStateValue(everestCurrentPowerStateTypeId, powerMap.value("total").toUInt()); + m_thing->setStateValue(everestMqttCurrentPowerStateTypeId, powerMap.value("total").toUInt()); } else if (topic.endsWith("session_info")) { /* @@ -288,23 +288,23 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, */ QVariantMap dataMap = jsonDoc.toVariant().toMap(); - m_thing->setStateValue(everestSessionEnergyStateTypeId, + m_thing->setStateValue(everestMqttSessionEnergyStateTypeId, dataMap.value("charged_energy_wh").toDouble() / 1000.0); // Interpret state QString stateString = dataMap.value("state").toString(); - m_thing->setStateValue(everestStateStateTypeId, stateString); + m_thing->setStateValue(everestMqttStateStateTypeId, stateString); State state = convertStringToState(stateString); if (state == StateUnknown) return; // No need to proceed here - m_thing->setStateValue(everestChargingStateTypeId, state == StateCharging); - m_thing->setStateValue(everestPluggedInStateTypeId, state != StateUnplugged); + m_thing->setStateValue(everestMqttChargingStateTypeId, state == StateCharging); + m_thing->setStateValue(everestMqttPluggedInStateTypeId, state != StateUnplugged); // TODO: check if we can set the power state in other EVSE states - if (state == StateCharging && !m_thing->stateValue(everestPowerStateTypeId).toBool()) { - m_thing->setStateValue(everestPowerStateTypeId, true); + if (state == StateCharging && !m_thing->stateValue(everestMqttPowerStateTypeId).toBool()) { + m_thing->setStateValue(everestMqttPowerStateTypeId, true); } } else if (topic.endsWith("telemetry")) { @@ -319,14 +319,14 @@ void Everest::onPublishReceived(const QString &topic, const QByteArray &payload, */ QVariantMap dataMap = jsonDoc.toVariant().toMap(); - m_thing->setStateValue(everestTemperatureStateTypeId, dataMap.value("temperature").toDouble()); - m_thing->setStateValue(everestFanSpeedStateTypeId, dataMap.value("fan_rpm").toDouble()); + m_thing->setStateValue(everestMqttTemperatureStateTypeId, dataMap.value("temperature").toDouble()); + m_thing->setStateValue(everestMqttFanSpeedStateTypeId, dataMap.value("fan_rpm").toDouble()); } } -QString Everest::buildTopic(const QString &topic) +QString EverestMqtt::buildTopic(const QString &topic) { - Q_ASSERT_X(!m_connector.isEmpty(), "Everest::buildTopic", "The connector must be known before building a topic"); + Q_ASSERT_X(!m_connector.isEmpty(), "EverestMqtt::buildTopic", "The connector must be known before building a topic"); QString baseTopic = QString(m_topicPrefix + "/var"); if (!topic.startsWith("/")) @@ -335,7 +335,7 @@ QString Everest::buildTopic(const QString &topic) return baseTopic + topic; } -Everest::State Everest::convertStringToState(const QString &stateString) +EverestMqtt::State EverestMqtt::convertStringToState(const QString &stateString) { State state = StateUnknown; diff --git a/everest/everest.h b/everest/mqtt/everestmqtt.h similarity index 92% rename from everest/everest.h rename to everest/mqtt/everestmqtt.h index 7d9393d9..d7eb1397 100644 --- a/everest/everest.h +++ b/everest/mqtt/everestmqtt.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2024, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -28,8 +28,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef EVEREST_H -#define EVEREST_H +#ifndef EVERESTMQTT_H +#define EVERESTMQTT_H #include #include @@ -38,7 +38,7 @@ #include -class Everest : public QObject +class EverestMqtt : public QObject { Q_OBJECT public: @@ -58,8 +58,8 @@ public: }; Q_ENUM(State) - explicit Everest(MqttClient *client, Thing *thing, QObject *parent = nullptr); - ~Everest(); + explicit EverestMqtt(MqttClient *client, Thing *thing, QObject *parent = nullptr); + ~EverestMqtt(); Thing *thing() const; @@ -98,4 +98,4 @@ private: State convertStringToState(const QString &stateString); }; -#endif // EVEREST_H +#endif // EVERESTMQTT_H diff --git a/everest/everestclient.cpp b/everest/mqtt/everestmqttclient.cpp similarity index 86% rename from everest/everestclient.cpp rename to everest/mqtt/everestmqttclient.cpp index 83232ac5..abece7ad 100644 --- a/everest/everestclient.cpp +++ b/everest/mqtt/everestmqttclient.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2024, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -28,10 +28,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "everestclient.h" +#include "everestmqttclient.h" #include "extern-plugininfo.h" -EverestClient::EverestClient(QObject *parent) +EverestMqttClient::EverestMqttClient(QObject *parent) : QObject{parent} { m_client = new MqttClient("nymea-" + QUuid::createUuid().toString().left(8), 300, QString(), QByteArray(), Mqtt::QoS0, false, this); @@ -71,24 +71,24 @@ EverestClient::EverestClient(QObject *parent) }); } -EverestClient::~EverestClient() +EverestMqttClient::~EverestMqttClient() { - foreach (Everest *everest, m_everests) { + foreach (EverestMqtt *everest, m_everests) { removeThing(everest->thing()); } } -MqttClient *EverestClient::client() const +MqttClient *EverestMqttClient::client() const { return m_client; } -Things EverestClient::things() const +Things EverestMqttClient::things() const { return m_everests.keys(); } -void EverestClient::addThing(Thing *thing) +void EverestMqttClient::addThing(Thing *thing) { if (m_everests.contains(thing)) { qCWarning(dcEverest()) << "The" << thing << "has already been added to the everest client. " @@ -97,11 +97,11 @@ void EverestClient::addThing(Thing *thing) return; } - Everest *everest = new Everest(m_client, thing, this); + EverestMqtt *everest = new EverestMqtt(m_client, thing, this); m_everests.insert(thing, everest); } -void EverestClient::removeThing(Thing *thing) +void EverestMqttClient::removeThing(Thing *thing) { if (!m_everests.contains(thing)) { qCWarning(dcEverest()) << "The" << thing << "has already been removed from the everest client. " @@ -109,12 +109,12 @@ void EverestClient::removeThing(Thing *thing) return; } - Everest *everest = m_everests.take(thing); + EverestMqtt *everest = m_everests.take(thing); everest->deinitialize(); everest->deleteLater(); } -Everest *EverestClient::getEverest(Thing *thing) const +EverestMqtt *EverestMqttClient::getEverest(Thing *thing) const { if (!m_everests.contains(thing)) return nullptr; @@ -122,18 +122,18 @@ Everest *EverestClient::getEverest(Thing *thing) const return m_everests.value(thing); } -NetworkDeviceMonitor *EverestClient::monitor() const +NetworkDeviceMonitor *EverestMqttClient::monitor() const { return m_monitor; } -void EverestClient::setMonitor(NetworkDeviceMonitor *monitor) +void EverestMqttClient::setMonitor(NetworkDeviceMonitor *monitor) { m_monitor = monitor; - connect(m_monitor, &NetworkDeviceMonitor::reachableChanged, this, &EverestClient::onMonitorReachableChanged); + connect(m_monitor, &NetworkDeviceMonitor::reachableChanged, this, &EverestMqttClient::onMonitorReachableChanged); } -void EverestClient::start() +void EverestMqttClient::start() { qCDebug(dcEverest()) << "Starting" << this; m_running = true; @@ -155,7 +155,7 @@ void EverestClient::start() } } -void EverestClient::stop() +void EverestMqttClient::stop() { qCDebug(dcEverest()) << "Stopping" << this; m_running = false; @@ -163,7 +163,7 @@ void EverestClient::stop() m_client->disconnectFromHost(); } -void EverestClient::onMonitorReachableChanged(bool reachable) +void EverestMqttClient::onMonitorReachableChanged(bool reachable) { qCDebug(dcEverest()) << "Network monitor for" << m_monitor->macAddress().toString() << (reachable ? " is now reachable" : "is not reachable any more"); @@ -185,10 +185,10 @@ void EverestClient::onMonitorReachableChanged(bool reachable) } } -QDebug operator<<(QDebug debug, EverestClient *everestClient) +QDebug operator<<(QDebug debug, EverestMqttClient *everestClient) { QDebugStateSaver saver(debug); - debug.nospace() << "EverestClient("; + debug.nospace() << "EverestMqttClient("; switch(everestClient->monitor()->monitorMode()) { case NetworkDeviceInfo::MonitorModeMac: debug.nospace() << everestClient->monitor()->networkDeviceInfo().macAddressInfos().constFirst() << ", "; diff --git a/everest/everestclient.h b/everest/mqtt/everestmqttclient.h similarity index 86% rename from everest/everestclient.h rename to everest/mqtt/everestmqttclient.h index 5fe19881..ae448ce0 100644 --- a/everest/everestclient.h +++ b/everest/mqtt/everestmqttclient.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2024, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -42,14 +42,14 @@ #include -#include "everest.h" +#include "everestmqtt.h" -class EverestClient : public QObject +class EverestMqttClient : public QObject { Q_OBJECT public: - explicit EverestClient(QObject *parent = nullptr); - ~EverestClient(); + explicit EverestMqttClient(QObject *parent = nullptr); + ~EverestMqttClient(); MqttClient *client() const; @@ -57,7 +57,7 @@ public: void addThing(Thing *thing); void removeThing(Thing *thing); - Everest *getEverest(Thing *thing) const; + EverestMqtt *getEverest(Thing *thing) const; NetworkDeviceMonitor *monitor() const; void setMonitor(NetworkDeviceMonitor *monitor); @@ -76,10 +76,10 @@ private: bool m_running = false; - QHash m_everests; + QHash m_everests; NetworkDeviceMonitor *m_monitor = nullptr; }; -QDebug operator<<(QDebug debug, EverestClient *everestClient); +QDebug operator<<(QDebug debug, EverestMqttClient *everestClient); #endif // EVERESTCLIENT_H diff --git a/everest/everestdiscovery.cpp b/everest/mqtt/everestmqttdiscovery.cpp similarity index 93% rename from everest/everestdiscovery.cpp rename to everest/mqtt/everestmqttdiscovery.cpp index bfe8005c..c556730f 100644 --- a/everest/everestdiscovery.cpp +++ b/everest/mqtt/everestmqttdiscovery.cpp @@ -28,29 +28,28 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "everestdiscovery.h" +#include "everestmqttdiscovery.h" #include "extern-plugininfo.h" -#include "everest.h" #include #include -EverestDiscovery::EverestDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) +EverestMqttDiscovery::EverestMqttDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) : QObject{parent}, m_networkDeviceDiscovery{networkDeviceDiscovery} { } -void EverestDiscovery::start() +void EverestMqttDiscovery::start() { qCInfo(dcEverest()) << "Discovery: Start discovering Everest MQTT brokers in the network..."; m_startDateTime = QDateTime::currentDateTime(); NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover(); - connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &EverestDiscovery::checkHostAddress); + connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &EverestMqttDiscovery::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"; @@ -68,7 +67,7 @@ void EverestDiscovery::start() checkHostAddress(QHostAddress::LocalHost); } -void EverestDiscovery::startLocalhost() +void EverestMqttDiscovery::startLocalhost() { qCInfo(dcEverest()) << "Discovery: Start discovering EVerest on localhost ..."; m_startDateTime = QDateTime::currentDateTime(); @@ -79,12 +78,12 @@ void EverestDiscovery::startLocalhost() checkHostAddress(QHostAddress::LocalHost); } -QList EverestDiscovery::results() const +QList EverestMqttDiscovery::results() const { return m_results; } -void EverestDiscovery::checkHostAddress(const QHostAddress &address) +void EverestMqttDiscovery::checkHostAddress(const QHostAddress &address) { MqttClient *client = new MqttClient("nymea-" + QUuid::createUuid().toString().left(8), 300, QString(), QByteArray(), Mqtt::QoS0, false, this); @@ -162,7 +161,7 @@ void EverestDiscovery::checkHostAddress(const QHostAddress &address) } -void EverestDiscovery::cleanupClient(MqttClient *client) +void EverestMqttDiscovery::cleanupClient(MqttClient *client) { if (!m_clients.contains(client)) return; @@ -177,7 +176,7 @@ void EverestDiscovery::cleanupClient(MqttClient *client) } } -void EverestDiscovery::finishDiscovery() +void EverestMqttDiscovery::finishDiscovery() { qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch(); diff --git a/everest/everestdiscovery.h b/everest/mqtt/everestmqttdiscovery.h similarity index 89% rename from everest/everestdiscovery.h rename to everest/mqtt/everestmqttdiscovery.h index ccfdd363..b44c0204 100644 --- a/everest/everestdiscovery.h +++ b/everest/mqtt/everestmqttdiscovery.h @@ -37,7 +37,7 @@ #include #include -class EverestDiscovery : public QObject +class EverestMqttDiscovery : public QObject { Q_OBJECT public: @@ -47,12 +47,12 @@ public: NetworkDeviceInfo networkDeviceInfo; } Result; - explicit EverestDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr); + explicit EverestMqttDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr); void start(); void startLocalhost(); - QList results() const; + QList results() const; signals: void finished(); @@ -60,7 +60,7 @@ signals: private: NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr; QDateTime m_startDateTime; - QList m_results; + QList m_results; QList m_clients; NetworkDeviceInfos m_networkDeviceInfos;