etm-powersync-plugins-modbus/sunspec/sunspecstoragelogic.cpp
Patrick Schurig 4ec7aa50e8 sunspec: reconcile storage states from the registers actions write
onStorageBlockUpdated() fed chargingRate from wChaGra() and dischargingRate
from wDisChaGra(). Those are the gradients, in percent of WChaMax per
second, and read only on several inverters. The matching actions write
InWRte and OutWRte, in percent of WChaMax. The user wrote one quantity and
read back another.

Feed the two rate states from inWRte() and outWRte(), and keep the
gradients under names that cannot be mistaken for setpoints:
chargeGradient and dischargeGradient, read only.

enableDischarging was never reconciled either, while enableCharging was.
It stayed frozen on the last written value and drifted silently as soon as
the inverter changed StorCtl_Mod on its own. Reconcile both flags.

The mapping moves into SunSpecStorageLogic so it can be exercised on a
register dump without a running nymea.
2026-07-31 10:22:44 +02:00

60 lines
2.1 KiB
C++

// 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.
*
* nymea is 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 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
* nymea. If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "sunspecstoragelogic.h"
#include <QtMath>
namespace SunSpecStorageLogic {
StorageStates readStates(SunSpecStorageModel *storage)
{
StorageStates states;
if (!storage)
return states;
/* InWRte / OutWRte are what the chargingRate / dischargingRate actions
* write. Reading the gradients here instead would mean the user writes one
* quantity and reads back another. */
states.chargingRate = storage->inWRte();
states.dischargingRate = storage->outWRte();
/* The gradients stay available, under names that cannot be mistaken for the
* setpoints above. */
states.chargeGradient = storage->wChaGra();
states.dischargeGradient = storage->wDisChaGra();
const SunSpecStorageModel::Storctl_modFlags controlMode = storage->storCtlMod();
states.enableCharging = controlMode.testFlag(SunSpecStorageModel::Storctl_modCharge);
states.enableDischarging = controlMode.testFlag(SunSpecStorageModel::Storctl_modDiScharge);
states.gridCharging = (storage->chaGriSet() == SunSpecStorageModel::ChagrisetGrid);
states.batteryLevel = qRound(storage->chaState());
states.batteryCritical = storage->chaState() < 5;
return states;
}
}