From 1020dd90a4f11f9904dffdb9b534d5a46033424c Mon Sep 17 00:00:00 2001 From: Boernsman Date: Wed, 3 Feb 2021 16:34:19 +0100 Subject: [PATCH] fixed sunspec inverter event state --- sunspec/integrationpluginsunspec.cpp | 105 ++++++++++++++-------- sunspec/integrationpluginsunspec.h | 1 - sunspec/sunspec.h | 19 ---- sunspec/sunspecinverter.cpp | 77 ++++++++++------ sunspec/sunspecinverter.h | 68 +++++++++++++- sunspec/sunspecmeter.cpp | 65 ++++++++++++-- sunspec/sunspecmeter.h | 125 ++++++++++++++++++++------ sunspec/sunspecstorage.cpp | 11 +-- sunspec/sunspecstringcombiner.cpp | 90 ------------------- sunspec/sunspecstringcombiner.h | 128 --------------------------- sunspec/sunspectracker.cpp | 42 --------- sunspec/sunspectracker.h | 77 ---------------- 12 files changed, 349 insertions(+), 459 deletions(-) delete mode 100644 sunspec/sunspecstringcombiner.cpp delete mode 100644 sunspec/sunspecstringcombiner.h delete mode 100644 sunspec/sunspectracker.cpp delete mode 100644 sunspec/sunspectracker.h diff --git a/sunspec/integrationpluginsunspec.cpp b/sunspec/integrationpluginsunspec.cpp index 4fbfa66..a4ebf2f 100644 --- a/sunspec/integrationpluginsunspec.cpp +++ b/sunspec/integrationpluginsunspec.cpp @@ -564,6 +564,8 @@ void IntegrationPluginSunSpec::onFoundSunSpecModel(SunSpec::ModelId modelId, int descriptor.setParams(params); emit autoThingsAppeared({descriptor}); } break; + case SunSpec::ModelIdWyeConnectThreePhaseMeter: + case SunSpec::ModelIdDeltaConnectThreePhaseMeter: case SunSpec::ModelIdWyeConnectThreePhaseMeterFloat: case SunSpec::ModelIdDeltaConnectThreePhaseMeterFloat: { ThingDescriptor descriptor(sunspecThreePhaseMeterThingClassId, model+" meter", "", thing->id()); @@ -617,6 +619,24 @@ void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::Inv if(!thing) { return; } + + qCDebug(dcSunSpec()) << "Inverter data received"; + qCDebug(dcSunSpec()) << " - Total AC Current" << inverterData.acCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase A Current" << inverterData.phaseACurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase B Current" << inverterData.phaseBCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase C Current" << inverterData.phaseCCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase voltage AB" << inverterData.phaseVoltageAB << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage BC" << inverterData.phaseVoltageBC << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage CA" << inverterData.phaseVoltageCA << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage AN" << inverterData.phaseVoltageAN << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage BN" << inverterData.phaseVoltageBN << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage CN" << inverterData.phaseVoltageCN << "[V]"; + qCDebug(dcSunSpec()) << " - AC Power" << inverterData.acPower << "[W]"; + qCDebug(dcSunSpec()) << " - Line frequency" << inverterData.lineFrequency << "[Hz]"; + qCDebug(dcSunSpec()) << " - AC energy" << inverterData.acEnergy << "[Wh]"; + qCDebug(dcSunSpec()) << " - Cabinet temperature" << inverterData.cabinetTemperature << "[°C]"; + qCDebug(dcSunSpec()) << " - Operating state" << inverterData.operatingState; + thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), true); thing->setStateValue(m_acPowerStateTypeIds.value(thing->thingClassId()), inverterData.acPower/1000.00); thing->setStateValue(m_acEnergyStateTypeIds.value(thing->thingClassId()), inverterData.acEnergy/1000.00); @@ -625,7 +645,7 @@ void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::Inv thing->setStateValue(sunspecThreePhaseInverterTotalCurrentStateTypeId, inverterData.acCurrent); thing->setStateValue(sunspecThreePhaseInverterCabinetTemperatureStateTypeId, inverterData.cabinetTemperature); - if (thing->thingClassId() == sunspecSplitPhaseMeterThingClassId) { + if (thing->thingClassId() == sunspecSplitPhaseInverterThingClassId) { thing->setStateValue(sunspecSplitPhaseInverterPhaseANVoltageStateTypeId, inverterData.phaseVoltageAN); thing->setStateValue(sunspecSplitPhaseInverterPhaseBNVoltageStateTypeId, inverterData.phaseVoltageBN); @@ -633,7 +653,7 @@ void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::Inv thing->setStateValue(sunspecSplitPhaseInverterPhaseACurrentStateTypeId, inverterData.phaseACurrent); thing->setStateValue(sunspecSplitPhaseInverterPhaseBCurrentStateTypeId, inverterData.phaseBCurrent); - } else if (thing->thingClassId() == sunspecThreePhaseMeterThingClassId) { + } else if (thing->thingClassId() == sunspecThreePhaseInverterThingClassId) { thing->setStateValue(sunspecThreePhaseInverterPhaseANVoltageStateTypeId, inverterData.phaseVoltageAN); thing->setStateValue(sunspecThreePhaseInverterPhaseBNVoltageStateTypeId, inverterData.phaseVoltageBN); @@ -671,55 +691,41 @@ void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::Inv break; } - switch(inverterData.event) { - case SunSpec::SunSpecEvent1::OVER_TEMP: + //FIXME: Event1 may have multiple states at once. Only one is stated in nymea + if (inverterData.event1.overTemperature) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Over temperature"); - break; - case SunSpec::SunSpecEvent1::UNDER_TEMP: + } else if (inverterData.event1.underTemperature) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Under temperature"); - break; - case SunSpec::SunSpecEvent1::GroundFault: + } else if (inverterData.event1.groundFault) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Ground fault"); - break; - case SunSpec::SunSpecEvent1::MEMORY_LOSS: + } else if (inverterData.event1.memoryLoss) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Memory loss"); - break; - case SunSpec::SunSpecEvent1::AC_OVER_VOLT: + } else if (inverterData.event1.acOverVolt) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "AC voltage above limit"); - break; - case SunSpec::SunSpecEvent1::CABINET_OPEN: + } else if (inverterData.event1.cabinetOpen) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Cabinet open"); - break; - case SunSpec::SunSpecEvent1::AC_DISCONNECT: + } else if (inverterData.event1.acDisconnect) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "AC disconnect open"); - break; - case SunSpec::SunSpecEvent1::AC_UNDER_VOLT: + } else if (inverterData.event1.acUnderVolt) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "AC voltage under limit"); - break; - case SunSpec::SunSpecEvent1::DC_DISCONNECT: + } else if (inverterData.event1.dcDicconnect) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "DC disconnect open"); - break; - case SunSpec::SunSpecEvent1::DcOverVolatage: + } else if (inverterData.event1.dcOverVoltage) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "DC over voltage"); - break; - case SunSpec::SunSpecEvent1::OVER_FREQUENCY: + } else if (inverterData.event1.overFrequency) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Frequency above limit"); - break; - case SunSpec::SunSpecEvent1::GRID_DISCONNECT: + } else if (inverterData.event1.gridDisconnect) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Grid disconnect"); - break; - case SunSpec::SunSpecEvent1::HW_TEST_FAILURE: + } else if (inverterData.event1.hwTestFailure) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Hardware test failure"); - break; - case SunSpec::SunSpecEvent1::MANUAL_SHUTDOWN: + } else if (inverterData.event1.manualShutdown) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Manual shutdown"); - break; - case SunSpec::SunSpecEvent1::UNDER_FREQUENCY: + } else if (inverterData.event1.underFrequency) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Frequency under limit"); - break; - case SunSpec::SunSpecEvent1::BLOWN_STRING_FUSE: + } else if (inverterData.event1.blownStringFuse) { thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "Blown string fuse on input"); - break; + } else { + thing->setStateValue(sunspecThreePhaseInverterErrorStateTypeId, "None"); } } @@ -774,5 +780,34 @@ void IntegrationPluginSunSpec::onMeterDataReceived(const SunSpecMeter::MeterData if (!thing) { return; } + thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), true); + + qCDebug(dcSunSpec()) << "Meter data received"; + qCDebug(dcSunSpec()) << " - Total AC Current" << meterData.totalAcCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase A current" << meterData.phaseACurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase B current" << meterData.phaseBCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Phase C current" << meterData.phaseCCurrent << "[A]"; + qCDebug(dcSunSpec()) << " - Voltage LN" << meterData.voltageLN << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage AN" << meterData.phaseVoltageAN << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage BN" << meterData.phaseVoltageBN << "[V]"; + qCDebug(dcSunSpec()) << " - Phase voltage CN" << meterData.phaseVoltageCN<< "[V]"; + 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()) << " - Frequency" << meterData.frequency << "[Hz]"; + qCDebug(dcSunSpec()) << " - Total real power" << meterData.totalRealPower << "[W]"; + qCDebug(dcSunSpec()) << " - Total real energy exported" << meterData.totalRealEnergyExported<< "[kWH]"; + qCDebug(dcSunSpec()) << " - Total real energy imported" << meterData.totalRealEnergyImported<< "[kWH]"; + + thing->setStateValue(sunspecThreePhaseMeterTotalCurrentStateTypeId, meterData.totalAcCurrent); + thing->setStateValue(sunspecThreePhaseMeterPhaseACurrentStateTypeId, meterData.phaseACurrent); + thing->setStateValue(sunspecThreePhaseMeterPhaseBCurrentStateTypeId, meterData.phaseBCurrent); + thing->setStateValue(sunspecThreePhaseMeterPhaseCCurrentStateTypeId, meterData.phaseCCurrent); + thing->setStateValue(sunspecThreePhaseMeterLnACVoltageStateTypeId, meterData.voltageLN); + thing->setStateValue(sunspecThreePhaseMeterTotalRealPowerEventTypeId, meterData.totalRealPower); + thing->setStateValue(sunspecThreePhaseMeterEnergyExportedStateTypeId, meterData.totalRealEnergyExported); + thing->setStateValue(sunspecThreePhaseMeterEnergyImportedStateTypeId, meterData.totalRealEnergyImported); + thing->setStateValue(m_frequencyStateTypeIds.value(thing->thingClassId()), meterData.frequency); } diff --git a/sunspec/integrationpluginsunspec.h b/sunspec/integrationpluginsunspec.h index 5a1f9aa..b860ddd 100644 --- a/sunspec/integrationpluginsunspec.h +++ b/sunspec/integrationpluginsunspec.h @@ -39,7 +39,6 @@ #include "sunspecinverter.h" #include "sunspecstorage.h" #include "sunspecmeter.h" -#include "sunspectracker.h" #include diff --git a/sunspec/sunspec.h b/sunspec/sunspec.h index 2c6a038..8021df4 100644 --- a/sunspec/sunspec.h +++ b/sunspec/sunspec.h @@ -67,25 +67,6 @@ public: }; Q_ENUM(SunSpecOperatingState) - enum SunSpecEvent1 { - GroundFault = 0, - DcOverVolatage, - AC_DISCONNECT, - DC_DISCONNECT, - GRID_DISCONNECT, - CABINET_OPEN, - MANUAL_SHUTDOWN, - OVER_TEMP, - OVER_FREQUENCY, - UNDER_FREQUENCY, - AC_OVER_VOLT, - AC_UNDER_VOLT, - BLOWN_STRING_FUSE, - UNDER_TEMP, - MEMORY_LOSS, - HW_TEST_FAILURE - }; - Q_ENUM(SunSpecEvent1) enum ModelId { ModelIdCommon = 1, diff --git a/sunspec/sunspecinverter.cpp b/sunspec/sunspecinverter.cpp index 7cc97f1..9811a98 100644 --- a/sunspec/sunspecinverter.cpp +++ b/sunspec/sunspecinverter.cpp @@ -73,46 +73,70 @@ void SunSpecInverter::getInverterModelDataBlock() m_connection->readModelDataBlock(m_modelModbusStartRegister, m_modelLength); } +SunSpecInverter::SunSpecEvent1 SunSpecInverter::bitfieldToSunSpecEvent1(quint16 register1, quint16 register2) +{ + SunSpecEvent1 event1; + Q_UNUSED(register2); + event1.groundFault = ((register1 & (0x01 << 0)) != 0); + event1.dcOverVoltage = ((register1 & (0x01 << 1)) != 0); + event1.acDisconnect = ((register1 & (0x01 << 2)) != 0); + event1.dcDicconnect = ((register1 & (0x01 << 3)) != 0); + event1.gridDisconnect = ((register1 & (0x01 << 4)) != 0); + event1.cabinetOpen = ((register1 & (0x01 << 5)) != 0); + event1.manualShutdown = ((register1 & (0x01 << 6)) != 0); + event1.overTemperature = ((register1 & (0x01 << 7)) != 0); + event1.overFrequency = ((register1 & (0x01 << 8)) != 0); + event1.underFrequency = ((register1 & (0x01 << 9)) != 0); + event1.acOverVolt = ((register1 & (0x01 << 10)) != 0); + event1.acUnderVolt = ((register1 & (0x01 << 11)) != 0); + event1.blownStringFuse = ((register1 & (0x01 << 12)) != 0); + event1.underTemperature = ((register1 & (0x01 << 13)) != 0); + event1.memoryLoss = ((register1 & (0x01 << 14)) != 0); + event1.hwTestFailure = ((register1 & (0x01 << 15)) != 0); + return event1; +} + void SunSpecInverter::getInverterModelHeader() { qCDebug(dcSunSpec()) << "SunSpecInverter: get inverter model header, modbus register" << m_modelModbusStartRegister; m_connection->readModelHeader(m_modelModbusStartRegister); } -void SunSpecInverter::onModelDataBlockReceived(SunSpec::ModelId mapId, uint mapLength, QVector data) +void SunSpecInverter::onModelDataBlockReceived(SunSpec::ModelId modelId, uint length, QVector data) { - Q_UNUSED(mapLength) - if (mapId != m_id) { + Q_UNUSED(length) + if (modelId != m_id) { return; } - if (mapLength < m_modelLength) { - qCDebug(dcSunSpec()) << "SunSpecInverter: on modbus map received, map length is too short" << mapLength; - //return; + if (length < m_modelLength) { + qCDebug(dcSunSpec()) << "SunSpecInverter: on model data block received, model length is too short" << length; + return; } InverterData inverterData; - switch (mapId) { + qCDebug(dcSunSpec()) << "SunSpecInverter: Received" << modelId; + switch (modelId) { 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.phaseACurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseACurrent], data[Model10X::Model10XAmpereScaleFactor]); - inverterData.phaseBCurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseBCurrent], data[Model10X::Model10XAmpereScaleFactor]); - inverterData.phaseCCurrent = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseCCurrent], data[Model10X::Model10XAmpereScaleFactor]); - - inverterData.phaseVoltageAN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageAN], data[Model10X::Model10XVoltageScaleFactor]); - inverterData.phaseVoltageBN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageBN], data[Model10X::Model10XVoltageScaleFactor]); - inverterData.phaseVoltageCN = m_connection->convertValueWithSSF(data[Model10X::Model10XPhaseVoltageCN], data[Model10X::Model10XVoltageScaleFactor]); + 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); + 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); quint32 acEnergy = ((static_cast(data.value(Model10X::Model10XAcEnergy))<<16)|static_cast(data.value(Model10X::Model10XAcEnergy+1))); inverterData.acEnergy = m_connection->convertValueWithSSF(acEnergy, data[Model10X::Model10XWattHoursScaleFactor]); inverterData.cabinetTemperature = m_connection->convertValueWithSSF(data[Model10X::Model10XCabinetTemperature], data[Model10X::Model10XTemperatureScaleFactor]); - inverterData.event = SunSpec::SunSpecEvent1(data[Model10X::Model10XEvent1]); + inverterData.event1 = bitfieldToSunSpecEvent1(data[Model10X::Model10XEvent1], data[Model10X::Model10XEvent1+1]); inverterData.operatingState = SunSpec::SunSpecOperatingState(data[Model10X::Model10XOperatingState]); emit inverterDataReceived(inverterData); @@ -123,21 +147,20 @@ void SunSpecInverter::onModelDataBlockReceived(SunSpec::ModelId mapId, uint mapL inverterData.acCurrent = m_connection->convertFloatValues(data[Model11X::Model11XAcCurrent], data[Model11X::Model11XAcCurrent+1]); - inverterData.phaseCCurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseCCurrent], data[Model11X::Model11XPhaseCCurrent+1]); + inverterData.phaseVoltageAN = m_connection->convertFloatValues(data[Model11X::Model11XPhaseVoltageAN], data[Model11X::Model11XPhaseVoltageAN+1]); + inverterData.phaseVoltageBN = m_connection->convertFloatValues(data[Model11X::Model11XPhaseVoltageBN], data[Model11X::Model11XPhaseVoltageBN+1]); inverterData.phaseVoltageCN = m_connection->convertFloatValues(data[Model11X::Model11XPhaseVoltageCN], data[Model11X::Model11XPhaseVoltageCN+1]); - inverterData.phaseBCurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseBCurrent], data[Model11X::Model11XPhaseBCurrent+1]); - inverterData.phaseVoltageBN = m_connection->convertFloatValues(data[Model11X::Model11XPhaseVoltageBN], data[Model11X::Model11XPhaseVoltageBN+1]); + inverterData.phaseACurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseACurrent], data[Model11X::Model11XPhaseACurrent+1]); + inverterData.phaseBCurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseBCurrent], data[Model11X::Model11XPhaseBCurrent+1]); + inverterData.phaseCCurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseCCurrent], data[Model11X::Model11XPhaseCCurrent+1]); - inverterData.phaseACurrent = m_connection->convertFloatValues(data[Model11X::Model11XPhaseACurrent], data[Model11X::Model11XPhaseACurrent+1]); - inverterData.phaseVoltageAN = m_connection->convertFloatValues(data[Model11X::Model11XPhaseVoltageAN], data[Model11X::Model11XPhaseVoltageAN+1]); + inverterData.acPower = m_connection->convertFloatValues(data[Model11X::Model11XACPower], data[Model11X::Model11XACPower+1]); + inverterData.lineFrequency = m_connection->convertFloatValues(data[Model11X::Model11XLineFrequency], data[Model11X::Model11XLineFrequency+1]); - inverterData.acPower = m_connection->convertFloatValues(data[Model11X::Model11XACPower], data[Model11X::Model11XACPower+1]); - inverterData.lineFrequency = m_connection->convertFloatValues(data[Model11X::Model11XLineFrequency], data[Model11X::Model11XLineFrequency+1]); - - inverterData.acEnergy = m_connection->convertFloatValues(data[Model11X::Model11XAcEnergy], data[Model11X::Model11XAcEnergy+1]); - inverterData.cabinetTemperature =m_connection->convertFloatValues(data[Model11X::Model11XCabinetTemperature], data[Model11X::Model11XCabinetTemperature+1]); - inverterData.event = SunSpec::SunSpecEvent1(data[Model11X::Model11XEvent1]); + inverterData.acEnergy = m_connection->convertFloatValues(data[Model11X::Model11XAcEnergy], data[Model11X::Model11XAcEnergy+1]); + inverterData.cabinetTemperature = m_connection->convertFloatValues(data[Model11X::Model11XCabinetTemperature], data[Model11X::Model11XCabinetTemperature+1]); + inverterData.event1 = bitfieldToSunSpecEvent1(data[Model11X::Model11XEvent1], data[Model11X::Model11XEvent1+1]); inverterData.operatingState = SunSpec::SunSpecOperatingState(data[Model11X::Model11XOperatingState]); emit inverterDataReceived(inverterData); } break; diff --git a/sunspec/sunspecinverter.h b/sunspec/sunspecinverter.h index 918cc75..712983b 100644 --- a/sunspec/sunspecinverter.h +++ b/sunspec/sunspecinverter.h @@ -77,6 +77,71 @@ public: Model11XEvent1 = 48 }; + enum Model10XOptional { // Optional register + Model10XPhaseVoltageAB = 5, + Model10XPhaseVoltageBC = 6, + Model10XPhaseVoltageCA = 7, + Model10XACApparentPower = 16, + Model10XACApparentPowerSF = 17, + Model10XACReactivePower = 18, + Model10XACReactivePowerSF = 19, + Model10XACPowerFactor = 20, + Model10XACPowerFactorSF = 21, + Model10XDCCurrent = 25, + Model10XDCCurrentSF = 26, + Model10XDCVoltage = 27, + Model10XDCVoltageSF = 28, + Model10XDCPower = 29, + Model10XDCPowerSF = 30, + Model10XHeatSinkTemperature = 32, + Model10XTransformerTemperature = 33, + Model10XOtherTemperature = 34, + Model10XVendorOperatingState = 37, + Model10XVendorEventBitfield1 = 42, + Model10XVendorEventBitfield2 = 44, + Model10XVendorEventBitfield3 = 46, + Model10XVendorEventBitfield4 = 48 + }; + + enum Model11XOptional { // Optinal registers + Model11XPhaseVoltageAB = 8, + Model11XPhaseVoltageBC = 10, + Model11XPhaseVoltageCA = 12, + Model11XACApparentPower = 24, + Model11XACReactivePower = 26, + Model11XACPowerFactor = 28, + Model11XDCCurrent = 32, + Model11XDCVoltage = 34, + Model11XDCPower = 36, + Model11XHeatSinkTemperature = 40, + Model11XTransformerTemperature = 42, + Model11XOtherTemperature = 44, + Model11XVendorOperatingState = 47, + Model11XVendorEventBitfield1 = 52, + Model11XVendorEventBitfield2 = 54, + Model11XVendorEventBitfield3 = 56, + Model11XVendorEventBitfield4 = 58 + }; + + struct SunSpecEvent1 { + bool groundFault; + bool dcOverVoltage; + bool acDisconnect; + bool dcDicconnect; + bool gridDisconnect; + bool cabinetOpen; + bool manualShutdown; + bool overTemperature; + bool overFrequency; + bool underFrequency; + bool acOverVolt; + bool acUnderVolt; + bool blownStringFuse; + bool underTemperature; + bool memoryLoss; + bool hwTestFailure; + }; + struct InverterData { float acCurrent; //in ampere float phaseACurrent; @@ -92,7 +157,7 @@ public: float lineFrequency; float acEnergy; float cabinetTemperature; // in degree Celsius - SunSpec::SunSpecEvent1 event; + SunSpecEvent1 event1; SunSpec::SunSpecOperatingState operatingState; }; @@ -108,6 +173,7 @@ private: uint m_modelModbusStartRegister = 40000; bool m_initFinishedSuccess = false; + SunSpecEvent1 bitfieldToSunSpecEvent1(quint16 register1, quint16 register2); void getInverterModelHeader(); private slots: diff --git a/sunspec/sunspecmeter.cpp b/sunspec/sunspecmeter.cpp index 9e7c488..093c81b 100644 --- a/sunspec/sunspecmeter.cpp +++ b/sunspec/sunspecmeter.cpp @@ -83,20 +83,67 @@ void SunSpecMeter::onModelDataBlockReceived(SunSpec::ModelId modelId, uint lengt if (modelId != m_id) { return; } - Q_UNUSED(length) - Q_UNUSED(data) + + if (length < m_modelLength) { + qCDebug(dcSunSpec()) << "SunSpecMeter: on model data block received, model length is too short" << length; + return; + } + + qCDebug(dcSunSpec()) << "SunSpecMeter: Received" << modelId; switch (modelId) { - case SunSpec::ModelIdSinglePhaseMeter: - case SunSpec::ModelIdSinglePhaseMeterFloat: { - - } break; case SunSpec::ModelIdSplitSinglePhaseMeter: - case SunSpec::ModelIdSplitSinglePhaseMeterFloat: { + case SunSpec::ModelIdDeltaConnectThreePhaseMeter: + case SunSpec::ModelIdWyeConnectThreePhaseMeter: { + + 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); + 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]); + quint16 energyScaleFactor = data[Model20XRealEnergyScaleFactor]; + meterData.totalRealEnergyExported = m_connection->convertValueWithSSF(data[Model20XTotalRealEnergyExported], energyScaleFactor); + meterData.totalRealEnergyImported = m_connection->convertValueWithSSF(data[Model20XTotalRealEnergyImported], energyScaleFactor);; + meterData.meterEventFlags = (static_cast(data[Model20XMeterEventFlags]) << 16) | data[Model20XMeterEventFlags+1]; + emit meterDataReceived(meterData); } break; - case SunSpec::ModelIdWyeConnectThreePhaseMeterFloat: - case SunSpec::ModelIdDeltaConnectThreePhaseMeterFloat: { + case SunSpec::ModelIdSinglePhaseMeterFloat: + case SunSpec::ModelIdSplitSinglePhaseMeterFloat: + case SunSpec::ModelIdDeltaConnectThreePhaseMeterFloat: + case SunSpec::ModelIdWyeConnectThreePhaseMeterFloat: { + + MeterData meterData; + meterData.totalAcCurrent = m_connection->convertFloatValues(data[Model21XTotalAcCurrent], data[Model21XTotalAcCurrent+1]); + meterData.phaseACurrent = m_connection->convertFloatValues(data[Model21XPhaseACurrent], data[Model21XPhaseACurrent+1]); + meterData.phaseBCurrent = m_connection->convertFloatValues(data[Model21XPhaseBCurrent], data[Model21XPhaseBCurrent+1]); + meterData.phaseCCurrent = m_connection->convertFloatValues(data[Model21XPhaseCCurrent], data[Model21XPhaseCCurrent+1]); + meterData.voltageLN = m_connection->convertFloatValues(data[Model21XVoltageLN], data[Model21XVoltageLN+1]); + meterData.phaseVoltageAN = m_connection->convertFloatValues(data[Model21XPhaseVoltageAN], data[Model21XPhaseVoltageAN+1]); + meterData.phaseVoltageBN = m_connection->convertFloatValues(data[Model21XPhaseVoltageBN], data[Model21XPhaseVoltageBN+1]); + meterData.phaseVoltageCN = m_connection->convertFloatValues(data[Model21XPhaseVoltageCN], data[Model21XPhaseVoltageCN+1]); + meterData.voltageLL = m_connection->convertFloatValues(data[Model21XVoltageLL], data[Model21XVoltageLL+1]); + meterData.phaseVoltageAB = m_connection->convertFloatValues(data[Model21XPhaseVoltageAB], data[Model21XPhaseVoltageAB+1]); + meterData.phaseVoltageBC = m_connection->convertFloatValues(data[Model21XPhaseVoltageBC], data[Model21XPhaseVoltageBC+1]); + meterData.phaseVoltageCA = m_connection->convertFloatValues(data[Model21XPhaseVoltageCA], data[Model21XPhaseVoltageCA+1]); + meterData.frequency = m_connection->convertFloatValues(data[Model21XFrequency], data[Model21XFrequency+1]); + meterData.totalRealPower = m_connection->convertFloatValues(data[Model21XTotalRealPower], data[Model21XTotalRealPower+1]); + meterData.totalRealEnergyExported = m_connection->convertFloatValues(data[Model21XTotalRealEnergyExported], data[Model21XTotalRealEnergyExported+1]); + meterData.totalRealEnergyImported = m_connection->convertFloatValues(data[Model21XTotalRealEnergyImported], data[Model21XTotalRealEnergyImported+1]); + meterData.meterEventFlags = ((static_cast(data[Model21XMeterEventFlags]) << 16) | data[Model21XMeterEventFlags+1]); + emit meterDataReceived(meterData); } break; default: diff --git a/sunspec/sunspecmeter.h b/sunspec/sunspecmeter.h index 1c0f2df..cc664d3 100644 --- a/sunspec/sunspecmeter.h +++ b/sunspec/sunspecmeter.h @@ -38,34 +38,109 @@ class SunSpecMeter : public QObject { Q_OBJECT public: - //Model 203 = Three phase meter - enum MandatoryRegistersModel20X { - TotalAcCurrent = 2, - PhaseACurrent = 3, - PhaseBCurrent = 4, - PhaseCCurrent = 5, - CurrentScaleFactor = 6, - VoltageLN = 7, - PhaseVoltageAN = 8, - PhaseVoltageBN = 9, - PhaseVoltageCN = 10, - VoltageLL = 11, - PhaseVoltageAB = 12, - PhaseVoltageBC = 13, - PhaseVoltageCA = 14, - VoltageScaleFactor = 15, - Frequency = 16, - TotalRealPower = 18, - RealPowerScaleFactor = 22, - TotalRealEnergyExported = 38, - TotalRealEnergyImported = 46, - RealEnergyScaleFactor = 54, - MeterEventFlags = 105 + + enum MeterEventFlags { + MeterEventPowerFailure = 2, + MeterEventUnderVoltage, + MeterEventLowPF, + MeterEventOverCurrent, + MeterEventOverVoltage, + MeterEventMissing_Sensor, + MeterEventReserved1, + MeterEventReserved2, + MeterEventReserved3, + MeterEventReserved4, + MeterEventReserved5, + MeterEventReserved6, + MeterEventReserved7, + MeterEventReserved8, + MeterEventOEM01, + MeterEventOEM02, + MeterEventOEM03, + MeterEventOEM04, + MeterEventOEM05, + MeterEventOEM06, + MeterEventOEM07, + MeterEventOEM08, + MeterEventOEM09, + MeterEventOEM10, + MeterEventOEM11, + MeterEventOEM12, + MeterEventOEM13, + MeterEventOEM14, + MeterEventOEM15 + }; + + //Model 201 = Single phase meter SF + //Model 202 = Split phase meter SF + //Model 203 = Three phase meter SF + //Note: For example single phase inverters, Phase B current is optional then. + enum Model20X { + Model20XTotalAcCurrent = 0, + Model20XPhaseACurrent = 1, + Model20XPhaseBCurrent = 2, + Model20XPhaseCCurrent = 3, + Model20XCurrentScaleFactor = 4, + Model20XVoltageLN = 5, + Model20XPhaseVoltageAN = 6, + Model20XPhaseVoltageBN = 7, + Model20XPhaseVoltageCN = 8, + Model20XVoltageLL = 9, + Model20XPhaseVoltageAB = 10, + Model20XPhaseVoltageBC = 11, + Model20XPhaseVoltageCA = 12, + Model20XVoltageScaleFactor = 13, + Model20XFrequency = 14, + Model20XFrequencyScaleFactor = 15, + Model20XTotalRealPower = 16, + Model20XRealPowerScaleFactor = 20, + Model20XTotalRealEnergyExported = 36, + Model20XTotalRealEnergyImported = 44, + Model20XRealEnergyScaleFactor = 52, + Model20XMeterEventFlags = 103 + }; + + //Model 211 = Single phase meter float + //Model 212 = Split phase meter float + //Model 213 = Three phase meter float + enum Model21X { + Model21XTotalAcCurrent = 0, + Model21XPhaseACurrent = 2, + Model21XPhaseBCurrent = 4, + Model21XPhaseCCurrent = 6, + Model21XVoltageLN = 8, + Model21XPhaseVoltageAN = 10, + Model21XPhaseVoltageBN = 12, + Model21XPhaseVoltageCN = 14, + Model21XVoltageLL = 16, + Model21XPhaseVoltageAB = 18, + Model21XPhaseVoltageBC = 20, + Model21XPhaseVoltageCA = 22, + Model21XFrequency = 24, + Model21XTotalRealPower = 26, + Model21XTotalRealEnergyExported = 58, + Model21XTotalRealEnergyImported = 66, + Model21XMeterEventFlags = 122 }; struct MeterData { - SunSpec::SunSpecEvent1 event; - SunSpec::SunSpecOperatingState operatingState; + double totalAcCurrent; // [A] + double phaseACurrent; // [A] + double phaseBCurrent; // [A] + double phaseCCurrent; // [A] + double voltageLN; // [V] + double phaseVoltageAN; // [V] + double phaseVoltageBN; // [V] + double phaseVoltageCN; // [V] + double voltageLL; // [V] + double phaseVoltageAB; // [V] + double phaseVoltageBC; // [V] + double phaseVoltageCA; // [V] + double frequency; // [Hz] + double totalRealPower; // [W] + double totalRealEnergyExported; // [kWh] + double totalRealEnergyImported; // [kWh] + quint32 meterEventFlags; // MeterEventFlags }; SunSpecMeter(SunSpec *sunspec, SunSpec::ModelId modelId, int modbusAddress); diff --git a/sunspec/sunspecstorage.cpp b/sunspec/sunspecstorage.cpp index 5648ca5..b40a098 100644 --- a/sunspec/sunspecstorage.cpp +++ b/sunspec/sunspecstorage.cpp @@ -121,15 +121,19 @@ QUuid SunSpecStorage::setDischargingRate(int charging) void SunSpecStorage::onModelDataBlockReceived(SunSpec::ModelId modelId, uint length, const QVector &data) { - Q_UNUSED(length) if (modelId != m_id) { return; } + if (length < m_modelLength) { + qCDebug(dcSunSpec()) << "SunSpecMeter: on model data block received, model length is too short" << length; + //return; + } + + qCDebug(dcSunSpec()) << "SunSpecStorage: Received" << modelId; switch (modelId) { case SunSpec::ModelIdStorage: { StorageData mandatory; - qCDebug(dcSunSpec()) << "SunSpecStorage: Storage model received:"; qCDebug(dcSunSpec()) << " - Setpoint maximum charge" << data[Model124SetpointMaximumCharge]; qCDebug(dcSunSpec()) << " - Setpoint maximum charging rate" << data[Model124SetpointMaximumChargingRate]; qCDebug(dcSunSpec()) << " - Setpoint maximum discharge rate" << data[Model124SetpointMaximumDischargeRate]; @@ -150,9 +154,6 @@ void SunSpecStorage::onModelDataBlockReceived(SunSpec::ModelId modelId, uint len optional.storageAvailable = m_connection->convertValueWithSSF(data[Model124StorageAvailableAH], data[Model124ScaleFactorMaximumChargingVA]); optional.gridChargingEnabled = (data[Model124ChargeGridSet] == 1); optional.currentlyAvailableEnergy = m_connection->convertValueWithSSF(data[Model124CurrentlyAvailableEnergyPercent], data[Model124ScaleFactorAvailableEnergyPercent]); - //qCDebug(dcSunSpec()) << " - Currently available energy" << data[Model124CurrentlyAvailableEnergy]; - //mandatory.chargingState = ChargingStatus(data[Model124ChargeStatus]); - //qCDebug(dcSunSpec()) << " - Charging state" << mandatory.chargingState; emit storageDataReceived(mandatory, optional); diff --git a/sunspec/sunspecstringcombiner.cpp b/sunspec/sunspecstringcombiner.cpp deleted file mode 100644 index 9445085..0000000 --- a/sunspec/sunspecstringcombiner.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, 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 Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this project. If not, see . -* -* 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 "sunspecstringcombiner.h" -#include "extern-plugininfo.h" - -SunSpecStringCombiner::SunSpecStringCombiner(const QHostAddress &hostAddress, uint port, QObject *parent) : SunSpec(hostAddress, port, parent) -{ - connect(m_modbusTcpClient, &QModbusClient::stateChanged, this, [this] (QModbusDevice::State state) { - if (state == QModbusDevice::ConnectedState) { - qCDebug(dcSunSpec()) << "String combiner connected successfully"; - QList mapIds; - mapIds.append(BlockIdStringCombiner); - mapIds.append(BlockIdStringCombinerCurrent); - mapIds.append(BlockIdStringCombinerAdvanced); - mapIds.append(BlockIdStringCombinerCurrentAdvanced); - findModbusMap(mapIds); - } - }); - connect(this, &SunSpec::foundModbusMap, this, [this] (BlockId mapId, uint modbusRegisterAddress) { - qCDebug(dcSunSpec()) << "Read map header for mapId" << mapId << "and modbus register" << modbusRegisterAddress; - readMapHeader(modbusRegisterAddress); - }); - - connect(this, &SunSpec::mapHeaderReceived, this, [this] (uint modbusAddress, BlockId mapId, uint mapLength) { - m_id = mapId; - m_mapLength = mapLength; - m_mapModbusStartRegister = modbusAddress; - readMap(modbusAddress, mapLength); - }); - - connect(this, &SunSpec::mapReceived, this, &SunSpecStringCombiner::onModbusMapReceived); -} - -void SunSpecStringCombiner::getStringCombinerMap() -{ - -} - -void SunSpecStringCombiner::readStringCombinerMapHeader() -{ - readMap(m_mapModbusStartRegister, m_mapLength); -} - -void SunSpecStringCombiner::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength, QVector data) -{ - Q_UNUSED(data); - - switch (mapId) { - case BlockIdStringCombiner: { - int rbCount = (mapLength-14)/8; - qCDebug(dcSunSpec()) << "Map" << mapId << "Repeating Block Count" << rbCount; - } break; - case BlockIdStringCombinerCurrent: - case BlockIdStringCombinerAdvanced: - case BlockIdStringCombinerCurrentAdvanced: { - //StringCombinerData stringCombinerData; - //stringCombinerData.acCurrent= convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]); - } break; - default: - break; - } -} diff --git a/sunspec/sunspecstringcombiner.h b/sunspec/sunspecstringcombiner.h deleted file mode 100644 index 7e7afe5..0000000 --- a/sunspec/sunspecstringcombiner.h +++ /dev/null @@ -1,128 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, 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 Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this project. If not, see . -* -* 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 -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SUNSPECSTRINGCOMBINER_H -#define SUNSPECSTRINGCOMBINER_H - -#include -#include "sunspec.h" - -class SunSpecStringCombiner : public SunSpec -{ - Q_OBJECT -public: - - //Map401 length: 14 + (RB Count * 8) - //Map403 length: 16 + (RB Count * 8) - enum Map401 { - Map401CurrentScaleFactor = 0, - Map401AmpHourScaleFactor = 1, - Map401VoltageScaleFactor = 2, - Map401MaximumDCCurrentRating = 3, - Map401NumberOfInputs = 4, - Map401Events = 5, - Map401VendorDefniedEvents = 7, - Map401TotalMeasuredCurrent = 9, - Map401TotalMeteredAmpHours = 10, - Map401OutputVoltage = 12, - Map401InternalOperatingTemperature = 13 - }; - - enum Map402 { - Map402CurrentScaleFactor, - Map402AmpHourScaleFactor, - Map402VoltageScaleFactor, - Map402PowerScaleFactor, - Map402EnergyScaleFactor, - Map402MaximumDCCurrentRating, - Map402NumberOfInputs, - Map402BitmaskValueEvents, - Map402BitmaskvalueVendorDefniedEvents, - Map402TotalMeasuredCurrent, - Map402TotalMeteredAmpHours, - Map402OutputVoltage - }; - - enum Map401RB { //Repeating block - ID = 0, - Event = 1, - VendorEvent = 3, - Amps = 5, - AmpHours = 6 - }; - - enum StringCombinerEvent { - LowVoltage = 0, - LowPower, - LowEfficiency, - Current, - Voltage, - Power, - Pr, - Disconnected, - FuseFault, - CombinerFuseFault, - CombinerCabinetOpen, - Temp, - Groundfault, - ReversedPolarity, - Incompatible, - CommunicationError, - InternalError, - Theft, - ArcDetected - }; - Q_ENUM(StringCombinerEvent) - - struct StringCombinerData { - SunSpecEvent1 event; - SunSpecOperatingState operatingState; - }; - - SunSpecStringCombiner(const QHostAddress &hostAddress, uint port = 502, QObject *parent = 0); - - void getStringCombinerMap(); - -private: - BlockId m_id = BlockIdStringCombiner; - uint m_mapLength = 0; - uint m_mapModbusStartRegister = 40000; - - void readStringCombinerMapHeader(); - -private slots: - void onModbusMapReceived(BlockId mapId, uint mapLength, QVector data); - -signals: - void initFinished(); - void stringCombinerDataReceived(const StringCombinerData &data); -}; - -#endif // SUNSPECSTRINGCOMBINER_H diff --git a/sunspec/sunspectracker.cpp b/sunspec/sunspectracker.cpp deleted file mode 100644 index 8d99fbf..0000000 --- a/sunspec/sunspectracker.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, 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 Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this project. If not, see . -* -* 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 "sunspectracker.h" -#include "extern-plugininfo.h" - -SunSpecTracker::SunSpecTracker(const QHostAddress &hostAddress, uint port, QObject *parent) : SunSpec(hostAddress, port, parent) -{ - -} - -void SunSpecTracker::readTrackerBlockHeader() -{ - readMap(m_mapModbusStartRegister, m_mapLength); -} diff --git a/sunspec/sunspectracker.h b/sunspec/sunspectracker.h deleted file mode 100644 index 88b81a8..0000000 --- a/sunspec/sunspectracker.h +++ /dev/null @@ -1,77 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, 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 Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU Lesser General Public License as published by the Free -* Software Foundation; 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this project. If not, see . -* -* 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 -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SUNSPECTRACKER_H -#define SUNSPECTRACKER_H - -#include -#include "sunspec.h" - -class SunSpecTracker : public SunSpec -{ - Q_OBJECT -public: - - enum TrackerType { - Unknown = 0, - Fixed = 1, - Horizontal = 2, - Tilted = 3, - Azimuth = 4, - Dual = 5, - Other = 99 - }; - Q_ENUM(TrackerType) - - struct TrackerData { - SunSpecEvent1 event; - SunSpecOperatingState operatingState; - }; - - SunSpecTracker(const QHostAddress &hostAddress, uint port = 502, QObject *parent = 0); - - void getTrackerMap(); - -private: - ModelId m_id = ModelIdTrackerController; - uint m_mapLength = 0; - uint m_mapModbusStartRegister = 40000; - - void readTrackerBlockHeader(); - -private slots: - //void onModbusMapReceived(BlockId mapId, uint mapLength, QVector data); - -signals: - void initFinished(); - void trackerDataReceived(const TrackerData &data); -}; - -#endif // SUNSPECTRACKER_H