fixed storage actions

master
Boernsman 2021-02-04 14:02:11 +01:00
parent 73958b2e59
commit 1596780916
7 changed files with 82 additions and 72 deletions

View File

@ -284,24 +284,7 @@ void IntegrationPluginSunSpec::executeAction(ThingActionInfo *info)
Thing *thing = info->thing();
Action action = info->action();
if (thing->thingClassId() == sunspecSinglePhaseInverterThingClassId ||
thing->thingClassId() == sunspecSplitPhaseInverterThingClassId ||
thing->thingClassId() == sunspecThreePhaseInverterThingClassId) {
SunSpecInverter *sunSpecInverter = m_sunSpecInverters.value(thing);
if (!sunSpecInverter) {
qWarning(dcSunSpec()) << "Could not find SunSpec inverter for thing" << thing->name();
info->finish(Thing::ThingErrorHardwareNotAvailable);
return;
}
info->finish(Thing::ThingErrorActionTypeNotFound);
} else if (thing->thingClassId() == sunspecSinglePhaseMeterThingClassId ||
thing->thingClassId() == sunspecSplitPhaseMeterThingClassId ||
thing->thingClassId() == sunspecThreePhaseMeterThingClassId) {
info->finish(Thing::ThingErrorActionTypeNotFound);
} else if (thing->thingClassId() == sunspecStorageThingClassId) {
if (thing->thingClassId() == sunspecStorageThingClassId) {
SunSpecStorage *sunSpecStorage = m_sunSpecStorages.value(thing);
if (!sunSpecStorage) {
qWarning(dcSunSpec()) << "Could not find sunspec instance for thing";
@ -481,7 +464,7 @@ void IntegrationPluginSunSpec::onPluginConfigurationChanged(const ParamTypeId &p
m_refreshTimer->startTimer(refreshTime);
}
} else if (paramTypeId == sunSpecPluginNumberOfRetriesParamTypeId) {
qCDebug(dcSunSpec()) << "Updating number of retires" << value.toUInt();
qCDebug(dcSunSpec()) << "Updating number of retries" << value.toUInt();
Q_FOREACH(SunSpec *connection, m_sunSpecConnections) {
connection->setNumberOfRetries(value.toUInt());
}
@ -592,7 +575,7 @@ void IntegrationPluginSunSpec::onFoundSunSpecModel(SunSpec::ModelId modelId, int
emit autoThingsAppeared({descriptor});
} break;
default:
qCDebug(dcSunSpec()) << "Block Id not handled";
qCDebug(dcSunSpec()) << "Model Id not handled";
}
}
@ -823,7 +806,7 @@ void IntegrationPluginSunSpec::onMeterDataReceived(const SunSpecMeter::MeterData
qCDebug(dcSunSpec()) << " - Voltage LL" << meterData.voltageLL << "[V]";
qCDebug(dcSunSpec()) << " - Phase voltage AB" << meterData.phaseVoltageAB << "[V]";
qCDebug(dcSunSpec()) << " - Phase voltage BC" << meterData.phaseVoltageBC << "[V]";
qCDebug(dcSunSpec()) << " - Phase voltage CA" << meterData.phaseVoltageCA<< "[V]";
qCDebug(dcSunSpec()) << " - Phase voltage CA" << meterData.phaseVoltageCA << "[V]";
qCDebug(dcSunSpec()) << " - Frequency" << meterData.frequency << "[Hz]";
qCDebug(dcSunSpec()) << " - Total real power" << meterData.totalRealPower << "[W]";
qCDebug(dcSunSpec()) << " - Total real energy exported" << meterData.totalRealEnergyExported<< "[kWH]";

View File

@ -354,13 +354,20 @@ QByteArray SunSpec::convertModbusRegisters(const QVector<quint16> &modbusData, i
return bytes;
}
float SunSpec::convertValueWithSSF(quint32 rawValue, quint16 sunssf)
float SunSpec::convertToFloatWithSSF(quint32 rawValue, quint16 sunssf)
{
float value;
value = rawValue * pow(10, static_cast<qint16>(sunssf));
return value;
}
quint32 SunSpec::convertFromFloatWithSSF(float value, quint16 sunssf)
{
quint32 rawValue;
rawValue = value / pow(10, static_cast<qint16>(sunssf));
return rawValue;
}
float SunSpec::convertFloatValues(quint16 rawValue0, quint16 rawValue1)
{
suns_modbus_v32_t value;

View File

@ -190,7 +190,9 @@ public:
void readModelHeader(uint modbusAddress);
void readModelDataBlock(uint modbusAddress, uint modelLength); //modbusAddress = model start address, model length is without header
float convertValueWithSSF(quint32 rawValue, quint16 sunssf);
float convertToFloatWithSSF(quint32 rawValue, quint16 sunssf);
quint32 convertFromFloatWithSSF(float value, quint16 sunssf);
float convertFloatValues(quint16 rawValue0, quint16 rawValue1);
QByteArray convertModbusRegister(const uint16_t &modbusData);
QBitArray convertModbusRegisterBits(const uint16_t &modbusData);

View File

@ -120,23 +120,23 @@ void SunSpecInverter::onModelDataBlockReceived(SunSpec::ModelId modelId, uint le
case SunSpec::ModelIdInverterSinglePhase:
case SunSpec::ModelIdInverterSplitPhase:
case SunSpec::ModelIdInverterThreePhase: {
inverterData.acCurrent= m_connection->convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
inverterData.acPower = m_connection->convertValueWithSSF(data[Model10X::Model10XACPower], data[Model10X::Model10XWattScaleFactor]);
inverterData.lineFrequency = m_connection->convertValueWithSSF(data[Model10X::Model10XLineFrequency], data[Model10X::Model10XHerzScaleFactor]);
inverterData.acCurrent= m_connection->convertToFloatWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
inverterData.acPower = m_connection->convertToFloatWithSSF(data[Model10X::Model10XACPower], data[Model10X::Model10XWattScaleFactor]);
inverterData.lineFrequency = m_connection->convertToFloatWithSSF(data[Model10X::Model10XLineFrequency], data[Model10X::Model10XHerzScaleFactor]);
quint16 ampereScaleFactor = data[Model10X::Model10XAmpereScaleFactor];
inverterData.phaseACurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseACurrent], ampereScaleFactor);
inverterData.phaseBCurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseBCurrent], ampereScaleFactor);
inverterData.phaseCCurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseCCurrent], ampereScaleFactor);
inverterData.phaseACurrent = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseACurrent], ampereScaleFactor);
inverterData.phaseBCurrent = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseBCurrent], ampereScaleFactor);
inverterData.phaseCCurrent = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseCCurrent], ampereScaleFactor);
quint16 voltageScaleFactor = data[Model10X::Model10XVoltageScaleFactor];
inverterData.phaseVoltageAN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageAN], voltageScaleFactor);
inverterData.phaseVoltageBN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageBN], voltageScaleFactor);
inverterData.phaseVoltageCN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageCN], voltageScaleFactor);
inverterData.phaseVoltageAN = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseVoltageAN], voltageScaleFactor);
inverterData.phaseVoltageBN = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseVoltageBN], voltageScaleFactor);
inverterData.phaseVoltageCN = m_connection->convertToFloatWithSSF(data[Model10X::Model10XPhaseVoltageCN], voltageScaleFactor);
quint32 acEnergy = ((static_cast<quint32>(data.value(Model10X::Model10XAcEnergy))<<16)|static_cast<quint32>(data.value(Model10X::Model10XAcEnergy+1)));
inverterData.acEnergy = m_connection->convertValueWithSSF(acEnergy, data[Model10X::Model10XWattHoursScaleFactor]);
inverterData.acEnergy = m_connection->convertToFloatWithSSF(acEnergy, data[Model10X::Model10XWattHoursScaleFactor]);
inverterData.cabinetTemperature = m_connection->convertValueWithSSF(data[Model10X::Model10XCabinetTemperature], data[Model10X::Model10XTemperatureScaleFactor]);
inverterData.cabinetTemperature = m_connection->convertToFloatWithSSF(data[Model10X::Model10XCabinetTemperature], data[Model10X::Model10XTemperatureScaleFactor]);
inverterData.event1 = bitfieldToSunSpecEvent1(data[Model10X::Model10XEvent1], data[Model10X::Model10XEvent1+1]);
inverterData.operatingState = SunSpec::SunSpecOperatingState(data[Model10X::Model10XOperatingState]);
emit inverterDataReceived(inverterData);

View File

@ -98,24 +98,24 @@ void SunSpecMeter::onModelDataBlockReceived(SunSpec::ModelId modelId, uint lengt
MeterData meterData;
quint16 currentScaleFactor = data[Model20XCurrentScaleFactor];
meterData.totalAcCurrent = m_connection->convertValueWithSSF(data[Model20XTotalAcCurrent], currentScaleFactor);
meterData.phaseACurrent = m_connection->convertValueWithSSF(data[Model20XPhaseACurrent], currentScaleFactor);
meterData.phaseBCurrent = m_connection->convertValueWithSSF(data[Model20XPhaseBCurrent], currentScaleFactor);
meterData.phaseCCurrent = m_connection->convertValueWithSSF(data[Model20XPhaseCCurrent], currentScaleFactor);
meterData.totalAcCurrent = m_connection->convertToFloatWithSSF(data[Model20XTotalAcCurrent], currentScaleFactor);
meterData.phaseACurrent = m_connection->convertToFloatWithSSF(data[Model20XPhaseACurrent], currentScaleFactor);
meterData.phaseBCurrent = m_connection->convertToFloatWithSSF(data[Model20XPhaseBCurrent], currentScaleFactor);
meterData.phaseCCurrent = m_connection->convertToFloatWithSSF(data[Model20XPhaseCCurrent], currentScaleFactor);
quint16 voltageScaleFactor = data[Model20XVoltageScaleFactor];
meterData.voltageLN = m_connection->convertValueWithSSF(data[Model20XVoltageLN], voltageScaleFactor);
meterData.phaseVoltageAN = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageAN], voltageScaleFactor);
meterData.phaseVoltageBN = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageBN], voltageScaleFactor);
meterData.phaseVoltageCN = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageCN], voltageScaleFactor);
meterData.voltageLL = m_connection->convertValueWithSSF(data[Model20XVoltageLL], voltageScaleFactor);
meterData.phaseVoltageAB = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageAB], voltageScaleFactor);
meterData.phaseVoltageBC = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageBC], voltageScaleFactor);
meterData.phaseVoltageCA = m_connection->convertValueWithSSF(data[Model20XPhaseVoltageCA], voltageScaleFactor);
meterData.frequency = m_connection->convertValueWithSSF(data[Model20XFrequency], data[Model20XFrequencyScaleFactor]);
meterData.totalRealPower = m_connection->convertValueWithSSF(data[Model20XTotalRealPower], data[Model20XRealPowerScaleFactor]);
meterData.voltageLN = m_connection->convertToFloatWithSSF(data[Model20XVoltageLN], voltageScaleFactor);
meterData.phaseVoltageAN = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageAN], voltageScaleFactor);
meterData.phaseVoltageBN = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageBN], voltageScaleFactor);
meterData.phaseVoltageCN = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageCN], voltageScaleFactor);
meterData.voltageLL = m_connection->convertToFloatWithSSF(data[Model20XVoltageLL], voltageScaleFactor);
meterData.phaseVoltageAB = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageAB], voltageScaleFactor);
meterData.phaseVoltageBC = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageBC], voltageScaleFactor);
meterData.phaseVoltageCA = m_connection->convertToFloatWithSSF(data[Model20XPhaseVoltageCA], voltageScaleFactor);
meterData.frequency = m_connection->convertToFloatWithSSF(data[Model20XFrequency], data[Model20XFrequencyScaleFactor]);
meterData.totalRealPower = m_connection->convertToFloatWithSSF(data[Model20XTotalRealPower], data[Model20XRealPowerScaleFactor]);
quint16 energyScaleFactor = data[Model20XRealEnergyScaleFactor];
meterData.totalRealEnergyExported = m_connection->convertValueWithSSF(data[Model20XTotalRealEnergyExported], energyScaleFactor);
meterData.totalRealEnergyImported = m_connection->convertValueWithSSF(data[Model20XTotalRealEnergyImported], energyScaleFactor);;
meterData.totalRealEnergyExported = m_connection->convertToFloatWithSSF(data[Model20XTotalRealEnergyExported], energyScaleFactor);
meterData.totalRealEnergyImported = m_connection->convertToFloatWithSSF(data[Model20XTotalRealEnergyImported], energyScaleFactor);;
meterData.meterEventFlags = (static_cast<quint32>(data[Model20XMeterEventFlags]) << 16) | data[Model20XMeterEventFlags+1];
emit meterDataReceived(meterData);

View File

@ -100,22 +100,32 @@ QUuid SunSpecStorage::setStorageControlMode(bool chargingEnabled, bool dischargi
return m_connection->writeHoldingRegister(modbusRegister, value);
}
QUuid SunSpecStorage::setChargingRate(int rate)
QUuid SunSpecStorage::setChargingRate(float rate)
{
//Register Name InWRte
/* Defines the maximum charge rate (charge limit). Default is 100% */
if (!m_scaleFactorsSet) {
qCWarning(dcSunSpec()) << "SunSpecStorage: Set charging rate, scale factors are not set";
return "";
}
if (rate < 0.00 || rate > 100.00) {
qCWarning(dcSunSpec()) << "SunSpecStorage: Set charging rate, rate out of boundaries [0, 100]";
return "";
}
uint modbusRegister = m_modelModbusStartRegister + Model124::Model124WChaGra;
int16_t value = rate * 100;
quint16 value = m_connection->convertFromFloatWithSSF(rate, m_WChaDisChaGra_SF);
return m_connection->writeHoldingRegister(modbusRegister, value);
}
QUuid SunSpecStorage::setDischargingRate(int charging)
QUuid SunSpecStorage::setDischargingRate(float rate)
{
//Register Name OutWRte
/* Defines the maximum discharge rate (discharge limit). Default is 100% */
if (!m_scaleFactorsSet) {
qCWarning(dcSunSpec()) << "SunSpecStorage: Set discharging rate, scale factors are not set";
}
if (rate < 0.00 || rate > 100.00) {
qCWarning(dcSunSpec()) << "SunSpecStorage: Set doscharging rate, rate out of boundaries [0, 100]";
return "";
}
uint modbusRegister = m_modelModbusStartRegister + Model124::Model124WDisChaGra;
quint16 value = charging * 100;
quint16 value = m_connection->convertFromFloatWithSSF(rate, m_WChaDisChaGra_SF);
return m_connection->writeHoldingRegister(modbusRegister, value);
}
@ -134,21 +144,21 @@ void SunSpecStorage::onModelDataBlockReceived(SunSpec::ModelId modelId, uint len
switch (modelId) {
case SunSpec::ModelIdStorage: {
StorageData mandatory;
mandatory.WChaMax = m_connection->convertValueWithSSF(data[Model124WChaMax], data[Model124WChaMax_SF]);
mandatory.WChaGra = m_connection->convertValueWithSSF(data[Model124WChaGra], data[Model124WChaDisChaGra_SF]);
mandatory.WDisChaGra = m_connection->convertValueWithSSF(data[Model124WDisChaGra], data[Model124WChaDisChaGra_SF]);
mandatory.WChaMax = m_connection->convertToFloatWithSSF(data[Model124WChaMax], data[Model124WChaMax_SF]);
mandatory.WChaGra = m_connection->convertToFloatWithSSF(data[Model124WChaGra], data[Model124WChaDisChaGra_SF]);
mandatory.WDisChaGra = m_connection->convertToFloatWithSSF(data[Model124WDisChaGra], data[Model124WChaDisChaGra_SF]);
mandatory.StorCtl_Mod_ChargingEnabled = data[Model124StorCtl_Mod]&0x01;
mandatory.StorCtl_Mod_DischargingEnabled = data[Model124StorCtl_Mod]&0x02;
StorageDataOptional optional;
optional.VAChaMax = m_connection->convertValueWithSSF(data[Model124VAChaMax], data[Model124VAChaMax_SF]);
optional.MinRsvPct = m_connection->convertValueWithSSF(data[Model124MinRsvPct], data[Model124MinRsvPct_SF]);
optional.ChaState = m_connection->convertValueWithSSF(data[Model124ChaState], data[Model124ChaState_SF]);
optional.StorAval = m_connection->convertValueWithSSF(data[Model124StorAval], data[Model124StorAval_SF]);
optional.InBatV = m_connection->convertValueWithSSF(data[Model124InBatV], data[Model124InBatV_SF]);
optional.VAChaMax = m_connection->convertToFloatWithSSF(data[Model124VAChaMax], data[Model124VAChaMax_SF]);
optional.MinRsvPct = m_connection->convertToFloatWithSSF(data[Model124MinRsvPct], data[Model124MinRsvPct_SF]);
optional.ChaState = m_connection->convertToFloatWithSSF(data[Model124ChaState], data[Model124ChaState_SF]);
optional.StorAval = m_connection->convertToFloatWithSSF(data[Model124StorAval], data[Model124StorAval_SF]);
optional.InBatV = m_connection->convertToFloatWithSSF(data[Model124InBatV], data[Model124InBatV_SF]);
optional.ChaSt = ChargingStatus(data[Model124ChaSt]);
optional.OutWRte = m_connection->convertValueWithSSF(data[Model124OutWRte], data[Model124InOutWRte_SF]);
optional.InWRte = m_connection->convertValueWithSSF(data[Model124InWRte], data[Model124InOutWRte_SF]);
optional.OutWRte = m_connection->convertToFloatWithSSF(data[Model124OutWRte], data[Model124InOutWRte_SF]);
optional.InWRte = m_connection->convertToFloatWithSSF(data[Model124InWRte], data[Model124InOutWRte_SF]);
optional.InOutWRte_WinTms = data[Model124InOutWRte_WinTms];
optional.InOutWRte_RvrtTms = data[Model124InOutWRte_RvrtTms];
optional.InOutWRte_RmpTms = data[Model124InOutWRte_RmpTms];

View File

@ -46,8 +46,8 @@ public:
void getStorageModelDataBlock();
QUuid setGridCharging(bool enabled);
QUuid setDischargingRate(int rate);
QUuid setChargingRate(int rate);
QUuid setDischargingRate(float rate);
QUuid setChargingRate(float rate);
QUuid setStorageControlMode(bool chargingEnabled, bool dischargingEnabled);
enum StorageControl {
@ -79,7 +79,7 @@ public:
Model124WChaGra = 1,
Model124WDisChaGra = 2,
Model124StorCtl_Mod = 3,
Model124WChaMax_SF = 16,
Model124WChaMax_SF = 16,
Model124WChaDisChaGra_SF = 17,
};
@ -135,6 +135,14 @@ private:
uint m_modelModbusStartRegister = 40000;
bool m_initFinishedSuccess = false;
// Scale factors needed to perform write requests
bool m_scaleFactorsSet = false;
quint16 m_WChaMax_SF = 0;
quint16 m_WChaDisChaGra_SF = 0;
quint16 m_VAChaMax_SF = 0;
quint16 m_MinRsvPct_SF = 0;
quint16 m_InOutWRte_SF = 0;
private slots:
void onModelDataBlockReceived(SunSpec::ModelId modelId, uint length, const QVector<quint16> &data);