This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
powersync-app/libnymea-app/energy/thingpowerlogs.cpp
2021-11-24 19:59:09 +01:00

176 lines
5.4 KiB
C++

#include "thingpowerlogs.h"
ThingPowerLogEntry::ThingPowerLogEntry(QObject *parent):
EnergyLogEntry(parent)
{
}
ThingPowerLogEntry::ThingPowerLogEntry(const QDateTime &timestamp, const QUuid &thingId, double currentPower, double totalConsumption, double totalProduction, QObject *parent):
EnergyLogEntry(timestamp, parent),
m_thingId(thingId),
m_currentPower(currentPower),
m_totalConsumption(totalConsumption),
m_totalProduction(totalProduction)
{
}
QUuid ThingPowerLogEntry::thingId() const
{
return m_thingId;
}
double ThingPowerLogEntry::currentPower() const
{
return m_currentPower;
}
double ThingPowerLogEntry::totalConsumption() const
{
return m_totalConsumption;
}
double ThingPowerLogEntry::totalProduction() const
{
return m_totalProduction;
}
ThingPowerLogs::ThingPowerLogs(QObject *parent) : EnergyLogs(parent)
{
m_cacheTimer.setInterval(2000);
connect(&m_cacheTimer, &QTimer::timeout, this, [=](){
if (m_cachedEntries.count() > 0) {
addEntries(m_cachedEntries);
m_cachedEntries.clear();
}
});
}
QList<QUuid> ThingPowerLogs::thingIds() const
{
return m_thingIds;
}
void ThingPowerLogs::setThingIds(const QList<QUuid> &thingIds)
{
if (m_thingIds != thingIds) {
m_thingIds = thingIds;
emit thingIdsChanged();
}
}
double ThingPowerLogs::minValue() const
{
return m_minValue;
}
double ThingPowerLogs::maxValue() const
{
return m_maxValue;
}
EnergyLogEntry *ThingPowerLogs::find(const QUuid &thingId, const QDateTime &timestamp)
{
// TODO: Can we do a binary search even if they key we're looking for is not unique (but still sorted)?
// For now, 365 * consumers items is the max we'll have here which seems on the edge for doing a stupid linear search...
for (int i = rowCount() - 1; i >= 0; i--) {
ThingPowerLogEntry *entry = static_cast<ThingPowerLogEntry*>(get(i));
if (entry->thingId() != thingId) {
continue;
}
if (timestamp == entry->timestamp()) {
return entry;
}
if (timestamp < entry->timestamp()) {
return nullptr; // Giving up, entry is not here
}
}
return nullptr;
}
void ThingPowerLogs::addEntry(ThingPowerLogEntry *entry)
{
appendEntry(entry);
}
void ThingPowerLogs::addEntries(const QList<ThingPowerLogEntry *> &entries)
{
QList<EnergyLogEntry*> energyLogEntries;
foreach (ThingPowerLogEntry* entry, entries) {
energyLogEntries.append(entry);
}
appendEntries(energyLogEntries);
}
QString ThingPowerLogs::logsName() const
{
return "ThingPowerLogs";
}
QVariantMap ThingPowerLogs::fetchParams() const
{
QVariantList thingIdsStrings;
foreach (const QUuid &id, m_thingIds) {
thingIdsStrings.append(id.toString());
}
QVariantMap ret;
ret.insert("thingIds", thingIdsStrings);
return ret;
}
void ThingPowerLogs::logEntriesReceived(const QVariantMap &params)
{
// Grouping them so when the UI gets entriesAdded, the whole set for this timstamp will be available at once
QList<ThingPowerLogEntry*> groupForTimestamp;
foreach (const QVariant &variant, params.value("thingPowerLogEntries").toList()) {
QVariantMap map = variant.toMap();
QDateTime timestamp = QDateTime::fromSecsSinceEpoch(map.value("timestamp").toLongLong());
QUuid thingId = map.value("thingId").toUuid();
double currentPower = map.value("currentPower").toDouble();
double totalConsumption = map.value("totalConsumption").toDouble();
double totalProduction = map.value("totalProduction").toDouble();
ThingPowerLogEntry *entry = new ThingPowerLogEntry(timestamp, thingId, currentPower, totalConsumption, totalProduction, this);
if (groupForTimestamp.isEmpty()) {
groupForTimestamp.append(entry);
} else if (groupForTimestamp.first()->timestamp() == timestamp) {
groupForTimestamp.append(entry);
} else {
// Finalize previous group and start a new one
addEntries(groupForTimestamp);
groupForTimestamp.clear();
groupForTimestamp.append(entry);
}
}
if (!groupForTimestamp.isEmpty()) {
addEntries(groupForTimestamp);
}
}
void ThingPowerLogs::notificationReceived(const QVariantMap &data)
{
QString notification = data.value("notification").toString();
QVariantMap params = data.value("params").toMap();
if (notification == "Energy.ThingPowerLogEntryAdded") {
QVariantMap map = params.value("thingPowerLogEntry").toMap();
QDateTime timestamp = QDateTime::fromSecsSinceEpoch(map.value("timestamp").toLongLong());
QUuid thingId = map.value("thingId").toUuid();
double currentPower = map.value("currentPower").toDouble();
double totalConsumption = map.value("totalConsumption").toDouble();
double totalProduction = map.value("totalProduction").toDouble();
ThingPowerLogEntry *entry = new ThingPowerLogEntry(timestamp, thingId, currentPower, totalConsumption, totalProduction, this);
if (m_cachedEntries.isEmpty()) {
m_cachedEntries.append(entry);
} else if (entry->timestamp() == m_cachedEntries.first()->timestamp()) {
m_cachedEntries.append(entry);
} else {
addEntries(m_cachedEntries);
m_cachedEntries.clear();
m_cachedEntries.append(entry);
}
m_cacheTimer.start();
}
}