powersync-energy-plugin-etm/energyplugin/schedulermanager.h

161 lines
5.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// SPDX-License-Identifier: GPL-3.0-or-later
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (C) 2013 - 2024, nymea GmbH
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
*
* This file is part of nymea-energy-plugin-nymea.
*
* nymea-energy-plugin-nymea.s free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* nymea-energy-plugin-nymea.s 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 nymea-energy-plugin-nymea. If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef SCHEDULERMANAGER_H
#define SCHEDULERMANAGER_H
#include <QObject>
#include <QTimer>
#include <QDateTime>
#include <QList>
#include "types/energytimeslot.h"
#include "types/flexibleload.h"
#include "types/schedulerconfig.h"
#include "types/manualslotconfig.h"
#include "schedulingstrategies/ischedulingstrategy.h"
// from libnymea-energy
#include <energymanager.h>
// from libnymea
#include <integrations/thingmanager.h>
class SpotMarketManager;
class LoadAdapterRegistry;
// SchedulerManager orchestrates the full energy scheduling pipeline.
//
// Every recomputeIntervalMin (default 15 min) it:
// 1. Builds a forecast timeline from available data providers (stub: returns 0s).
// 2. Discovers all FlexibleLoad instances from known managers.
// 3. Calls strategy->computeSchedule(forecast, loads, config).
// 4. Applies the CURRENT slot's decisions to the relevant managers.
// 5. Stores future slots for later execution at their start time.
//
// Manual overrides (from UI or JSON-RPC) are respected: overridden slots are
// never touched by the Scheduler until the override expires.
class SchedulerManager : public QObject
{
Q_OBJECT
public:
explicit SchedulerManager(
SpotMarketManager *spotMarketManager,
EnergyManager *energyManager,
ThingManager *thingManager,
LoadAdapterRegistry *adapterRegistry = nullptr,
QObject *parent = nullptr
);
// --- Strategy management ---
void setStrategy(ISchedulingStrategy *strategy);
ISchedulingStrategy *currentStrategy() const;
QList<ISchedulingStrategy *> availableStrategies() const;
void registerStrategy(ISchedulingStrategy *strategy);
// --- Timeline access ---
QList<EnergyTimeSlot> currentTimeline() const;
QDateTime lastComputedAt() const;
QDateTime nextRecomputeAt() const;
// planHealth: "ok" | "degraded" | "no_forecast"
QString planHealth() const;
// --- Configuration ---
SchedulerConfig config() const;
void setConfig(const SchedulerConfig &config);
// --- Flexible loads ---
QList<FlexibleLoad> flexibleLoads() const;
void updateLoad(const FlexibleLoad &load);
// --- Manual override ---
// Marks a slot as manually overridden. The Scheduler will not touch it.
void overrideSlot(const QDateTime &slotStart,
LoadSource source,
double powerW,
const QString &reason);
// --- Active overrides count ---
int activeOverridesCount() const;
// --- Force immediate recompute ---
void forceRecompute();
// --- Manual slot management (ManualStrategy) ---
QList<ManualSlotConfig> manualSlots() const;
void setManualSlot(const ManualSlotConfig &config);
void removeManualSlot(const QDateTime &start);
void clearManualSlots();
signals:
void timelineUpdated(const QList<EnergyTimeSlot> &timeline);
void slotExecuted(const EnergyTimeSlot &slot, bool success);
void strategyChanged(const QString &strategyId);
void loadRegistered(const FlexibleLoad &load);
void loadUpdated(const FlexibleLoad &load);
void configChanged(const SchedulerConfig &config);
void manualSlotsChanged();
private slots:
void onRecomputeTimer();
void onSlotExecutionTimer();
private:
// Build 2448h forecast (stub: all predictions = 0)
QList<EnergyTimeSlot> buildForecast() const;
// Collect all managed flexible loads from connected managers
QList<FlexibleLoad> collectLoads() const;
// Apply the current slot's decisions to the hardware managers
void applyCurrentSlot(const EnergyTimeSlot &slot);
// Schedule next slot execution timer
void scheduleNextSlotTimer();
// Helper: return the registered ManualStrategy, or nullptr if not found
class ManualStrategy *findManualStrategy() const;
SpotMarketManager *m_spotMarketManager = nullptr;
EnergyManager *m_energyManager = nullptr;
ThingManager *m_thingManager = nullptr;
LoadAdapterRegistry *m_adapterRegistry = nullptr;
class SchedulerSettings *m_settings = nullptr;
ISchedulingStrategy *m_activeStrategy = nullptr;
QList<ISchedulingStrategy *> m_strategies;
QList<EnergyTimeSlot> m_timeline;
QList<FlexibleLoad> m_loads;
SchedulerConfig m_config;
QDateTime m_lastComputedAt;
QDateTime m_nextRecomputeAt;
QTimer m_recomputeTimer; // fires every recomputeIntervalMin
QTimer m_slotTimer; // fires at the start of the next future slot
};
#endif // SCHEDULERMANAGER_H