259 lines
9.2 KiB
C++
259 lines
9.2 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright 2013 - 2021, nymea GmbH
|
|
* Contact: contact@nymea.io
|
|
*
|
|
* This fileDescriptor 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 <https://www.gnu.org/licenses/>.
|
|
*
|
|
* 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 "sunspeclocationmodel.h"
|
|
#include "sunspecconnection.h"
|
|
|
|
SunSpecLocationModel::SunSpecLocationModel(SunSpecConnection *connection, quint16 modbusStartRegister, quint16 modelLength, SunSpecDataPoint::ByteOrder byteOrder, QObject *parent) :
|
|
SunSpecModel(connection, modbusStartRegister, 305, modelLength, byteOrder, parent)
|
|
{
|
|
m_modelBlockType = SunSpecModel::ModelBlockTypeFixed;
|
|
|
|
initDataPoints();
|
|
}
|
|
|
|
SunSpecLocationModel::~SunSpecLocationModel()
|
|
{
|
|
|
|
}
|
|
|
|
QString SunSpecLocationModel::name() const
|
|
{
|
|
return "location";
|
|
}
|
|
|
|
QString SunSpecLocationModel::description() const
|
|
{
|
|
return "Include to support location measurements";
|
|
}
|
|
|
|
QString SunSpecLocationModel::label() const
|
|
{
|
|
return "GPS";
|
|
}
|
|
|
|
QString SunSpecLocationModel::tm() const
|
|
{
|
|
return m_tm;
|
|
}
|
|
QString SunSpecLocationModel::date() const
|
|
{
|
|
return m_date;
|
|
}
|
|
QString SunSpecLocationModel::location() const
|
|
{
|
|
return m_location;
|
|
}
|
|
float SunSpecLocationModel::lat() const
|
|
{
|
|
return m_lat;
|
|
}
|
|
float SunSpecLocationModel::longitude() const
|
|
{
|
|
return m_longitude;
|
|
}
|
|
qint32 SunSpecLocationModel::altitude() const
|
|
{
|
|
return m_altitude;
|
|
}
|
|
void SunSpecLocationModel::initDataPoints()
|
|
{
|
|
SunSpecDataPoint modelIdDataPoint;
|
|
modelIdDataPoint.setName("ID");
|
|
modelIdDataPoint.setLabel("Model ID");
|
|
modelIdDataPoint.setDescription("Model identifier");
|
|
modelIdDataPoint.setMandatory(true);
|
|
modelIdDataPoint.setSize(1);
|
|
modelIdDataPoint.setAddressOffset(0);
|
|
modelIdDataPoint.setSunSpecDataType("uint16");
|
|
modelIdDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(modelIdDataPoint.name(), modelIdDataPoint);
|
|
|
|
SunSpecDataPoint modelLengthDataPoint;
|
|
modelLengthDataPoint.setName("L");
|
|
modelLengthDataPoint.setLabel("Model Length");
|
|
modelLengthDataPoint.setDescription("Model length");
|
|
modelLengthDataPoint.setMandatory(true);
|
|
modelLengthDataPoint.setSize(1);
|
|
modelLengthDataPoint.setAddressOffset(1);
|
|
modelLengthDataPoint.setSunSpecDataType("uint16");
|
|
modelLengthDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(modelLengthDataPoint.name(), modelLengthDataPoint);
|
|
|
|
SunSpecDataPoint tmDataPoint;
|
|
tmDataPoint.setName("Tm");
|
|
tmDataPoint.setLabel("Tm");
|
|
tmDataPoint.setDescription("UTC 24 hour time stamp to millisecond hhmmss.sssZ format");
|
|
tmDataPoint.setUnits("hhmmss.sssZ");
|
|
tmDataPoint.setSize(6);
|
|
tmDataPoint.setAddressOffset(2);
|
|
tmDataPoint.setBlockOffset(0);
|
|
tmDataPoint.setSunSpecDataType("string");
|
|
tmDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(tmDataPoint.name(), tmDataPoint);
|
|
|
|
SunSpecDataPoint dateDataPoint;
|
|
dateDataPoint.setName("Date");
|
|
dateDataPoint.setLabel("Date");
|
|
dateDataPoint.setDescription("UTC Date string YYYYMMDD format");
|
|
dateDataPoint.setUnits("YYYYMMDD");
|
|
dateDataPoint.setSize(4);
|
|
dateDataPoint.setAddressOffset(8);
|
|
dateDataPoint.setBlockOffset(6);
|
|
dateDataPoint.setSunSpecDataType("string");
|
|
dateDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(dateDataPoint.name(), dateDataPoint);
|
|
|
|
SunSpecDataPoint locationDataPoint;
|
|
locationDataPoint.setName("Loc");
|
|
locationDataPoint.setLabel("Location");
|
|
locationDataPoint.setDescription("Location string (40 chars max)");
|
|
locationDataPoint.setUnits("text");
|
|
locationDataPoint.setSize(20);
|
|
locationDataPoint.setAddressOffset(12);
|
|
locationDataPoint.setBlockOffset(10);
|
|
locationDataPoint.setSunSpecDataType("string");
|
|
locationDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(locationDataPoint.name(), locationDataPoint);
|
|
|
|
SunSpecDataPoint latDataPoint;
|
|
latDataPoint.setName("Lat");
|
|
latDataPoint.setLabel("Lat");
|
|
latDataPoint.setDescription("Latitude with seven degrees of precision");
|
|
latDataPoint.setUnits("Degrees");
|
|
latDataPoint.setSize(2);
|
|
latDataPoint.setAddressOffset(32);
|
|
latDataPoint.setBlockOffset(30);
|
|
latDataPoint.setScaleFactorName("-7");
|
|
latDataPoint.setSunSpecDataType("int32");
|
|
latDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(latDataPoint.name(), latDataPoint);
|
|
|
|
SunSpecDataPoint longitudeDataPoint;
|
|
longitudeDataPoint.setName("Long");
|
|
longitudeDataPoint.setLabel("Long");
|
|
longitudeDataPoint.setDescription("Longitude with seven degrees of precision");
|
|
longitudeDataPoint.setUnits("Degrees");
|
|
longitudeDataPoint.setSize(2);
|
|
longitudeDataPoint.setAddressOffset(34);
|
|
longitudeDataPoint.setBlockOffset(32);
|
|
longitudeDataPoint.setScaleFactorName("-7");
|
|
longitudeDataPoint.setSunSpecDataType("int32");
|
|
longitudeDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(longitudeDataPoint.name(), longitudeDataPoint);
|
|
|
|
SunSpecDataPoint altitudeDataPoint;
|
|
altitudeDataPoint.setName("Alt");
|
|
altitudeDataPoint.setLabel("Altitude");
|
|
altitudeDataPoint.setDescription("Altitude measurement in meters");
|
|
altitudeDataPoint.setUnits("meters");
|
|
altitudeDataPoint.setSize(2);
|
|
altitudeDataPoint.setAddressOffset(36);
|
|
altitudeDataPoint.setBlockOffset(34);
|
|
altitudeDataPoint.setSunSpecDataType("int32");
|
|
altitudeDataPoint.setByteOrder(m_byteOrder);
|
|
m_dataPoints.insert(altitudeDataPoint.name(), altitudeDataPoint);
|
|
|
|
}
|
|
|
|
void SunSpecLocationModel::processBlockData()
|
|
{
|
|
// Update properties according to the data point type
|
|
if (m_dataPoints.value("Tm").isValid())
|
|
m_tm = m_dataPoints.value("Tm").toString();
|
|
|
|
if (m_dataPoints.value("Date").isValid())
|
|
m_date = m_dataPoints.value("Date").toString();
|
|
|
|
if (m_dataPoints.value("Loc").isValid())
|
|
m_location = m_dataPoints.value("Loc").toString();
|
|
|
|
if (m_dataPoints.value("Lat").isValid())
|
|
m_lat = m_dataPoints.value("Lat").toFloatWithSSF(-7);
|
|
|
|
if (m_dataPoints.value("Long").isValid())
|
|
m_longitude = m_dataPoints.value("Long").toFloatWithSSF(-7);
|
|
|
|
if (m_dataPoints.value("Alt").isValid())
|
|
m_altitude = m_dataPoints.value("Alt").toInt32();
|
|
|
|
|
|
qCDebug(dcSunSpecModelData()) << this;
|
|
}
|
|
|
|
QDebug operator<<(QDebug debug, SunSpecLocationModel *model)
|
|
{
|
|
debug.nospace().noquote() << "SunSpecLocationModel(Model: " << model->modelId() << ", Register: " << model->modbusStartRegister() << ", Length: " << model->modelLength() << ")\n";
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Tm") << "-->";
|
|
if (model->dataPoints().value("Tm").isValid()) {
|
|
debug.nospace().noquote() << model->tm() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Date") << "-->";
|
|
if (model->dataPoints().value("Date").isValid()) {
|
|
debug.nospace().noquote() << model->date() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Loc") << "-->";
|
|
if (model->dataPoints().value("Loc").isValid()) {
|
|
debug.nospace().noquote() << model->location() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Lat") << "-->";
|
|
if (model->dataPoints().value("Lat").isValid()) {
|
|
debug.nospace().noquote() << model->lat() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Long") << "-->";
|
|
if (model->dataPoints().value("Long").isValid()) {
|
|
debug.nospace().noquote() << model->longitude() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
debug.nospace().noquote() << " - " << model->dataPoints().value("Alt") << "-->";
|
|
if (model->dataPoints().value("Alt").isValid()) {
|
|
debug.nospace().noquote() << model->altitude() << "\n";
|
|
} else {
|
|
debug.nospace().noquote() << "NaN\n";
|
|
}
|
|
|
|
|
|
return debug.space().quote();
|
|
}
|