235 lines
12 KiB
C++
235 lines
12 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright 2013 - 2025, nymea GmbH
|
|
* Contact: contact@nymea.io
|
|
*
|
|
* This file is part of nymea.
|
|
* This project including source code and documentation is protected by
|
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
|
* reproduction, publication, editing and translation, are reserved. The use of
|
|
* this project is subject to the terms of a license agreement to be concluded
|
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
|
* under https://nymea.io/license
|
|
*
|
|
* GNU General Public License Usage
|
|
* Alternatively, this project may be redistributed and/or modified under the
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* For any further details and any questions please contact us under
|
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
|
* https://nymea.io/license/faq
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "energyjsonhandler.h"
|
|
#include "energymanagerimpl.h"
|
|
|
|
Q_DECLARE_LOGGING_CATEGORY(dcEnergyExperience)
|
|
|
|
EnergyJsonHandler::EnergyJsonHandler(EnergyManager *energyManager, QObject *parent):
|
|
JsonHandler(parent),
|
|
m_energyManager(energyManager)
|
|
{
|
|
registerEnum<EnergyManager::EnergyError>();
|
|
registerEnum<EnergyLogs::SampleRate>();
|
|
|
|
registerObject<PowerBalanceLogEntry, PowerBalanceLogEntries>();
|
|
registerObject<ThingPowerLogEntry, ThingPowerLogEntries>();
|
|
|
|
QVariantMap params, returns;
|
|
QString description;
|
|
|
|
params.clear(); returns.clear();
|
|
description = "Get the root meter ID. If there is no root meter set, the params will be empty.";
|
|
returns.insert("o:rootMeterThingId", enumValueName(Uuid));
|
|
registerMethod("GetRootMeter", description, params, returns, Types::PermissionScopeNone);
|
|
|
|
params.clear(); returns.clear();
|
|
description = "Set the root meter.";
|
|
params.insert("rootMeterThingId", enumValueName(Uuid));
|
|
returns.insert("energyError", enumRef<EnergyManager::EnergyError>());
|
|
registerMethod("SetRootMeter", description, params, returns, Types::PermissionScopeAdmin);
|
|
|
|
params.clear(); returns.clear();
|
|
description = "Get the current power balance. That is, production, consumption and acquisition.";
|
|
returns.insert("currentPowerConsumption", enumValueName(Double));
|
|
returns.insert("currentPowerProduction", enumValueName(Double));
|
|
returns.insert("currentPowerAcquisition", enumValueName(Double));
|
|
returns.insert("currentPowerStorage", enumValueName(Double));
|
|
returns.insert("totalConsumption", enumValueName(Double));
|
|
returns.insert("totalProduction", enumValueName(Double));
|
|
returns.insert("totalAcquisition", enumValueName(Double));
|
|
returns.insert("totalReturn", enumValueName(Double));
|
|
registerMethod("GetPowerBalance", description, params, returns, Types::PermissionScopeNone);
|
|
|
|
params.clear(); returns.clear();
|
|
description = "Get logs for the power balance. If from is not give, the log will start at the beginning of "
|
|
"recording. If to is not given, the logs will and at the last sample for this sample rate before now.";
|
|
params.insert("sampleRate", enumRef<EnergyLogs::SampleRate>());
|
|
params.insert("o:from", enumValueName(Uint));
|
|
params.insert("o:to", enumValueName(Uint));
|
|
returns.insert("powerBalanceLogEntries", objectRef<PowerBalanceLogEntries>());
|
|
registerMethod("GetPowerBalanceLogs", description, params, returns, Types::PermissionScopeNone);
|
|
|
|
params.clear(); returns.clear();
|
|
description = "Get logs for one or more things power values. If thingIds is not given, logs for all energy related "
|
|
"things will be returned. If from is not given, the log will start at the beginning of recording. If "
|
|
"to is not given, the logs will and at the last sample for this sample rate before now. If the parameter "
|
|
"\"includeCurrent\" is set to true, the result will contain the newest log entries available, regardless "
|
|
"of the sample rate (that is, 1 minute). This may be useful to calculate the difference to the newest "
|
|
"entry of the fetched sample rate and the current values to display the live value until the current sample "
|
|
"is completed.";
|
|
params.insert("sampleRate", enumRef<EnergyLogs::SampleRate>());
|
|
params.insert("o:thingIds", QVariantList() << enumValueName(Uuid));
|
|
params.insert("o:from", enumValueName(Uint));
|
|
params.insert("o:to", enumValueName(Uint));
|
|
params.insert("o:includeCurrent", enumValueName(Bool));
|
|
returns.insert("o:currentEntries", objectRef<ThingPowerLogEntries>());
|
|
returns.insert("thingPowerLogEntries", objectRef<ThingPowerLogEntries>());
|
|
registerMethod("GetThingPowerLogs", description, params, returns, Types::PermissionScopeNone);
|
|
|
|
params.clear();
|
|
description = "Emitted whenever the root meter id changes. If the root meter has been unset, the params will be empty.";
|
|
params.insert("o:rootMeterThingId", enumValueName(Uuid));
|
|
registerNotification("RootMeterChanged", description, params);
|
|
|
|
params.clear();
|
|
description = "Emitted whenever the energy balance changes. That is, when the current consumption, production or "
|
|
"acquisition changes. Typically they will all change at the same time.";
|
|
params.insert("currentPowerConsumption", enumValueName(Double));
|
|
params.insert("currentPowerProduction", enumValueName(Double));
|
|
params.insert("currentPowerAcquisition", enumValueName(Double));
|
|
params.insert("currentPowerStorage", enumValueName(Double));
|
|
params.insert("totalConsumption", enumValueName(Double));
|
|
params.insert("totalProduction", enumValueName(Double));
|
|
params.insert("totalAcquisition", enumValueName(Double));
|
|
params.insert("totalReturn", enumValueName(Double));
|
|
registerNotification("PowerBalanceChanged", description, params);
|
|
|
|
params.clear();
|
|
description = "Emitted whenever an entry is added to the power balance log.";
|
|
params.insert("sampleRate", enumRef<EnergyLogs::SampleRate>());
|
|
params.insert("powerBalanceLogEntry", objectRef<PowerBalanceLogEntry>());
|
|
registerNotification("PowerBalanceLogEntryAdded", description, params);
|
|
|
|
params.clear();
|
|
description = "Emitted whenever an entry is added to the thing power log.";
|
|
params.insert("sampleRate", enumRef<EnergyLogs::SampleRate>());
|
|
params.insert("thingPowerLogEntry", objectRef<ThingPowerLogEntry>());
|
|
registerNotification("ThingPowerLogEntryAdded", description, params);
|
|
|
|
connect(m_energyManager, &EnergyManager::rootMeterChanged, this, [=](){
|
|
QVariantMap params;
|
|
if (m_energyManager->rootMeter()) {
|
|
params.insert("rootMeterThingId", m_energyManager->rootMeter()->id());
|
|
}
|
|
emit RootMeterChanged(params);
|
|
});
|
|
|
|
connect(m_energyManager, &EnergyManager::powerBalanceChanged, this, [=](){
|
|
QVariantMap params;
|
|
params.insert("currentPowerConsumption", m_energyManager->currentPowerConsumption());
|
|
params.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
|
|
params.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
|
|
params.insert("currentPowerStorage", m_energyManager->currentPowerStorage());
|
|
params.insert("totalConsumption", m_energyManager->totalConsumption());
|
|
params.insert("totalProduction", m_energyManager->totalProduction());
|
|
params.insert("totalAcquisition", m_energyManager->totalAcquisition());
|
|
params.insert("totalReturn", m_energyManager->totalReturn());
|
|
emit PowerBalanceChanged(params);
|
|
});
|
|
|
|
connect(m_energyManager->logs(), &EnergyLogs::powerBalanceEntryAdded, this, [=](EnergyLogs::SampleRate sampleRate, const PowerBalanceLogEntry &entry){
|
|
QVariantMap params;
|
|
params.insert("sampleRate", enumValueName(sampleRate));
|
|
params.insert("powerBalanceLogEntry", pack(entry));
|
|
emit PowerBalanceLogEntryAdded(params);
|
|
});
|
|
|
|
connect(m_energyManager->logs(), &EnergyLogs::thingPowerEntryAdded, this, [=](EnergyLogs::SampleRate sampleRate, const ThingPowerLogEntry &entry){
|
|
QVariantMap params;
|
|
params.insert("sampleRate", enumValueName(sampleRate));
|
|
params.insert("thingPowerLogEntry", pack(entry));
|
|
emit ThingPowerLogEntryAdded(params);
|
|
});
|
|
}
|
|
|
|
QString EnergyJsonHandler::name() const
|
|
{
|
|
return "Energy";
|
|
}
|
|
|
|
JsonReply *EnergyJsonHandler::GetRootMeter(const QVariantMap ¶ms)
|
|
{
|
|
Q_UNUSED(params)
|
|
QVariantMap ret;
|
|
if (m_energyManager->rootMeter()) {
|
|
ret.insert("rootMeterThingId", m_energyManager->rootMeter()->id());
|
|
}
|
|
return createReply(ret);
|
|
}
|
|
|
|
JsonReply *EnergyJsonHandler::SetRootMeter(const QVariantMap ¶ms)
|
|
{
|
|
QVariantMap returns;
|
|
|
|
if (!params.contains("rootMeterThingId")) {
|
|
returns.insert("energyError", enumValueName(EnergyManager::EnergyErrorMissingParameter));
|
|
return createReply(returns);
|
|
}
|
|
EnergyManager::EnergyError status = m_energyManager->setRootMeter(params.value("rootMeterThingId").toUuid());
|
|
returns.insert("energyError", enumValueName(status));
|
|
return createReply(returns);
|
|
}
|
|
|
|
JsonReply *EnergyJsonHandler::GetPowerBalance(const QVariantMap ¶ms)
|
|
{
|
|
Q_UNUSED(params)
|
|
QVariantMap ret;
|
|
ret.insert("currentPowerConsumption", m_energyManager->currentPowerConsumption());
|
|
ret.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
|
|
ret.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
|
|
ret.insert("currentPowerStorage", m_energyManager->currentPowerStorage());
|
|
ret.insert("totalConsumption", m_energyManager->totalConsumption());
|
|
ret.insert("totalProduction", m_energyManager->totalProduction());
|
|
ret.insert("totalAcquisition", m_energyManager->totalAcquisition());
|
|
ret.insert("totalReturn", m_energyManager->totalReturn());
|
|
return createReply(ret);
|
|
}
|
|
|
|
JsonReply *EnergyJsonHandler::GetPowerBalanceLogs(const QVariantMap ¶ms)
|
|
{
|
|
EnergyLogs::SampleRate sampleRate = enumNameToValue<EnergyLogs::SampleRate>(params.value("sampleRate").toString());
|
|
QDateTime from = params.contains("from") ? QDateTime::fromMSecsSinceEpoch(params.value("from").toLongLong() * 1000) : QDateTime();
|
|
QDateTime to = params.contains("to") ? QDateTime::fromMSecsSinceEpoch(params.value("to").toLongLong() * 1000) : QDateTime();
|
|
QVariantMap returns;
|
|
returns.insert("powerBalanceLogEntries", pack(m_energyManager->logs()->powerBalanceLogs(sampleRate, from, to)));
|
|
return createReply(returns);
|
|
}
|
|
|
|
JsonReply *EnergyJsonHandler::GetThingPowerLogs(const QVariantMap ¶ms)
|
|
{
|
|
EnergyLogs::SampleRate sampleRate = enumNameToValue<EnergyLogs::SampleRate>(params.value("sampleRate").toString());
|
|
QList<ThingId> thingIds;
|
|
foreach (const QVariant &thingId, params.value("thingIds").toList()) {
|
|
thingIds.append(thingId.toUuid());
|
|
}
|
|
QDateTime from = params.contains("from") ? QDateTime::fromMSecsSinceEpoch(params.value("from").toLongLong() * 1000) : QDateTime();
|
|
QDateTime to = params.contains("to") ? QDateTime::fromMSecsSinceEpoch(params.value("to").toLongLong() * 1000) : QDateTime();
|
|
QVariantMap returns;
|
|
returns.insert("thingPowerLogEntries", pack(m_energyManager->logs()->thingPowerLogs(sampleRate, thingIds, from, to)));
|
|
|
|
if (params.contains("includeCurrent") && params.value("includeCurrent").toBool()) {
|
|
returns.insert("currentEntries", pack(m_energyManager->logs()->thingPowerLogs(EnergyLogs::SampleRate1Min, thingIds, QDateTime::currentDateTime().addSecs(-60))));
|
|
}
|
|
|
|
return createReply(returns);
|
|
}
|