QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
CompInfoParam.cc
Go to the documentation of this file.
1#include "CompInfoParam.h"
2#include "FirmwarePlugin.h"
3#include "JsonParsing.h"
5#include "ParameterMetaData.h"
7#include "Vehicle.h"
8
9#include <QtCore/QJsonArray>
10#include <QtCore/QJsonDocument>
11#include <QtCore/QRegularExpression>
12
13QGC_LOGGING_CATEGORY(CompInfoParamLog, "ComponentInformation.CompInfoParam")
14
15CompInfoParam::CompInfoParam(uint8_t compId_, Vehicle *vehicle_, QObject *parent)
16 : CompInfo(COMP_METADATA_TYPE_PARAMETER, compId_, vehicle_, parent)
17{
18}
19
20void CompInfoParam::setJson(const QString &metadataJsonFileName)
21{
22 if (metadataJsonFileName.isEmpty()) {
23 return;
24 }
25
26 QString errorString;
27 QJsonDocument jsonDoc;
28
29 if (!JsonParsing::isJsonFile(metadataJsonFileName, jsonDoc, errorString)) {
30 qCWarning(CompInfoParamLog) << "Metadata json file open failed: compid:" << compId << errorString;
31 return;
32 }
33
34 QString schemaError;
35 if (!JsonSchemaValidator::validate(jsonDoc, QStringLiteral(":/json/component_metadata/parameter.schema.json"), schemaError)) {
36 qCWarning(CompInfoParamLog) << "Metadata json schema validation failed: compid:" << compId << schemaError;
37 }
38
39 const QJsonObject jsonObj = jsonDoc.object();
40 const QList<JsonParsing::KeyValidateInfo> keyInfoList = {
41 {JsonParsing::jsonVersionKey, QJsonValue::Double, true},
42 {kJsonParametersKey, QJsonValue::Array, true},
43 };
44 if (!JsonParsing::validateKeys(jsonObj, keyInfoList, errorString)) {
45 qCWarning(CompInfoParamLog) << "Metadata json validation failed: compid:" << compId << errorString;
46 return;
47 }
48
49 if (jsonObj[JsonParsing::jsonVersionKey].toInt() != 1) {
50 qCWarning(CompInfoParamLog) << "Metadata json unsupported version" << jsonObj[JsonParsing::jsonVersionKey].toInt();
51 return;
52 }
53
54 _noJsonMetadata = false;
55
56 const QJsonArray parameters = jsonObj[kJsonParametersKey].toArray();
57 const QString escapedTag = QRegularExpression::escape(kIndexedNameTag);
58
59 for (const QJsonValue &parameterValue : parameters) {
60 if (!parameterValue.isObject()) {
61 qCWarning(CompInfoParamLog) << "Metadata json read failed: compid:" << compId << "parameters array contains non-object";
62 return;
63 }
64
65 FactMetaData *newMetaData = FactMetaData::createFromJsonObject(parameterValue.toObject(), ParameterMetaData::kEmptyDefines, this);
66
67 if (newMetaData->name().contains(kIndexedNameTag)) {
68 QString regexPattern = QRegularExpression::escape(newMetaData->name());
69 regexPattern.replace(escapedTag, QStringLiteral("(\\d+)"));
70 _indexedNameMetaDataList.append({QRegularExpression(QStringLiteral("^%1$").arg(regexPattern)), newMetaData});
71 } else {
72 _nameToMetaDataMap[newMetaData->name()] = newMetaData;
73 }
74 }
75}
76
78{
79 if (FactMetaData *cached = _nameToMetaDataMap.value(name)) {
80 return cached;
81 }
82
83 FactMetaData *factMetaData = _resolveMetaData(name, valueType);
84 _nameToMetaDataMap[name] = factMetaData;
85 return factMetaData;
86}
87
88FactMetaData *CompInfoParam::_resolveMetaData(const QString &name, FactMetaData::ValueType_t valueType)
89{
90 if (_noJsonMetadata) {
91 // No vehicle-provided metadata — use firmware-bundled metadata
92 if (ParameterMetaData *fwMeta = _getParameterMetaData()) {
93 return fwMeta->getMetaDataForFact(name, valueType);
94 }
95 } else {
96 // Vehicle provided JSON metadata — check exact match then indexed patterns
97 if (FactMetaData *found = _lookupJsonMetaData(name)) {
98 return found;
99 }
100 }
101
102 // Generic fallback
103 auto *factMetaData = new FactMetaData(valueType, this);
104 const int sep = name.indexOf('_');
105 if (sep > 0) {
106 factMetaData->setGroup(name.left(sep));
107 }
108 if (compId != MAV_COMP_ID_AUTOPILOT1) {
109 factMetaData->setCategory(tr("Component %1").arg(compId));
110 }
111 return factMetaData;
112}
113
114FactMetaData *CompInfoParam::_lookupJsonMetaData(const QString &name)
115{
116 // Try indexed name patterns (e.g. "CAL_GYRO{n}_ID" matches "CAL_GYRO0_ID")
117 for (const auto &[regex, templateMeta] : _indexedNameMetaDataList) {
118 const QRegularExpressionMatch match = regex.match(name);
119 if (match.hasMatch()) {
120 auto *factMetaData = new FactMetaData(*templateMeta, this);
121 factMetaData->setName(name);
122
123 const QString index = match.captured(1);
124 QString desc = factMetaData->shortDescription();
125 desc.replace(kIndexedNameTag, index);
126 factMetaData->setShortDescription(desc);
127
128 desc = factMetaData->longDescription();
129 desc.replace(kIndexedNameTag, index);
130 factMetaData->setLongDescription(desc);
131 return factMetaData;
132 }
133 }
134
135 return nullptr;
136}
137
138ParameterMetaData *CompInfoParam::_getParameterMetaData()
139{
140 if (!_parameterMetaData && compId == MAV_COMP_ID_AUTOPILOT1) {
141 _parameterMetaData = vehicle->firmwarePlugin()->loadParameterMetaData(vehicle);
142 if (_parameterMetaData) {
143 _parameterMetaData->setParent(this);
144 }
145 }
146
147 return _parameterMetaData;
148}
QString errorString
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void setJson(const QString &metadataJsonFileName) override
FactMetaData * factMetaDataForName(const QString &name, FactMetaData::ValueType_t valueType)
Base class for all CompInfo types.
Definition CompInfo.h:15
Vehicle *const vehicle
Definition CompInfo.h:37
const uint8_t compId
Definition CompInfo.h:38
Holds the meta data associated with a Fact.
static FactMetaData * createFromJsonObject(const QJsonObject &json, const QMap< QString, QString > &defineMap, QObject *metaDataParent)
QString name() const
ParameterMetaData * loadParameterMetaData(const Vehicle *vehicle)
static const FactMetaData::DefineMap_t kEmptyDefines
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
Definition Vehicle.h:448
bool validateKeys(const QJsonObject &jsonObject, const QList< KeyValidateInfo > &keyInfo, QString &errorString)
Validates that all required keys are present and that listed keys have the expected type.
bool isJsonFile(const QByteArray &bytes, QJsonDocument &jsonDoc, QString &errorString)
Determines whether an in-memory byte buffer contains parseable JSON content.
constexpr const char * jsonVersionKey
Definition JsonParsing.h:12
bool validate(const QJsonDocument &doc, const QString &schemaResourcePath, QString &errorString)