Fix interface allowed values loading and debug cathegories for thing and thing manager

This commit is contained in:
Simon Stürz 2025-08-19 13:00:08 +02:00
parent 685d28f88b
commit d71ce85f12
8 changed files with 112 additions and 69 deletions

View File

@ -192,7 +192,7 @@ static PyObject * PyThing_paramValue(PyThing* self, PyObject* args)
char *paramTypeIdStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &paramTypeIdStr)) {
qCWarning(dcThingManager) << "Error parsing parameters";
qCWarning(dcThingManager()) << "Error parsing parameters";
return nullptr;
}
@ -226,7 +226,7 @@ static PyObject * PyThing_setting(PyThing* self, PyObject* args)
char *paramTypeIdStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &paramTypeIdStr)) {
qCWarning(dcThingManager) << "Error parsing parameters";
qCWarning(dcThingManager()) << "Error parsing parameters";
return nullptr;
}

View File

@ -40,7 +40,7 @@ PyObject *PythonIntegrationPlugin::pyConfigValue(PyObject *self, PyObject *args)
char *paramTypeIdStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &paramTypeIdStr)) {
qCWarning(dcThingManager) << "Error parsing parameters";
qCWarning(dcThingManager()) << "Error parsing parameters";
return nullptr;
}
@ -64,7 +64,7 @@ PyObject *PythonIntegrationPlugin::pySetConfigValue(PyObject *self, PyObject *ar
PyObject *valueObj = nullptr;
if (!PyArg_ParseTuple(args, "sO", &paramTypeIdStr, &valueObj)) {
qCWarning(dcThingManager) << "Error parsing parameters";
qCWarning(dcThingManager()) << "Error parsing parameters";
return nullptr;
}
@ -172,7 +172,7 @@ PyObject *PythonIntegrationPlugin::pyAutoThingDisappeared(PyObject *self, PyObje
char *thingIdStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &thingIdStr)) {
qCWarning(dcThingManager) << "Error parsing parameters";
qCWarning(dcThingManager()) << "Error parsing parameters";
return nullptr;
}
ThingId thingId(thingIdStr);

View File

@ -291,20 +291,20 @@ ThingDiscoveryInfo* ThingManagerImplementation::discoverThings(const ThingClassI
{
ThingClass thingClass = findThingClass(thingClassId);
if (!thingClass.isValid()) {
qCWarning(dcThingManager) << "Thing discovery failed. Invalid thing class id:" << thingClassId.toString();
qCWarning(dcThingManager()) << "Thing discovery failed. Invalid thing class id:" << thingClassId.toString();
ThingDiscoveryInfo *discoveryInfo = new ThingDiscoveryInfo(thingClassId, params, this);
discoveryInfo->finish(Thing::ThingErrorThingClassNotFound);
return discoveryInfo;
}
if (!thingClass.createMethods().testFlag(ThingClass::CreateMethodDiscovery)) {
qCWarning(dcThingManager) << "Thing discovery failed." << thingClass << "cannot be discovered.";
qCWarning(dcThingManager()) << "Thing discovery failed." << thingClass << "cannot be discovered.";
ThingDiscoveryInfo *discoveryInfo = new ThingDiscoveryInfo(thingClassId, params, this);
discoveryInfo->finish(Thing::ThingErrorCreationMethodNotSupported);
return discoveryInfo;
}
IntegrationPlugin *plugin = m_integrationPlugins.value(thingClass.pluginId());
if (!plugin) {
qCWarning(dcThingManager) << "Thing discovery failed. Plugin not found for" << thingClass;
qCWarning(dcThingManager()) << "Thing discovery failed. Plugin not found for" << thingClass;
ThingDiscoveryInfo *discoveryInfo = new ThingDiscoveryInfo(thingClassId, params, this);
discoveryInfo->finish(Thing::ThingErrorPluginNotFound, tr("The plugin for this thing is not loaded."));
return discoveryInfo;
@ -335,7 +335,7 @@ ThingDiscoveryInfo* ThingManagerImplementation::discoverThings(const ThingClassI
}
});
qCDebug(dcThingManager) << "Thing discovery for" << thingClass << "started...";
qCDebug(dcThingManager()) << "Thing discovery for" << thingClass << "started...";
plugin->discoverThings(discoveryInfo);
return discoveryInfo;
}
@ -646,7 +646,7 @@ ThingPairingInfo* ThingManagerImplementation::pairThing(const ThingClassId &thin
ThingClass thingClass = m_supportedThings.value(thingClassId);
if (!thingClass.isValid()) {
qCWarning(dcThingManager) << "Cannot find a ThingClass with ID" << thingClassId.toString();
qCWarning(dcThingManager()) << "Cannot find a ThingClass with ID" << thingClassId.toString();
ThingPairingInfo *info = new ThingPairingInfo(transactionId, thingClassId, ThingId(), name, ParamList(), ThingId(), this, false);
info->finish(Thing::ThingErrorThingClassNotFound);
return info;
@ -668,7 +668,7 @@ ThingPairingInfo* ThingManagerImplementation::pairThing(const ThingDescriptorId
PairingTransactionId pairingTransactionId = PairingTransactionId::createPairingTransactionId();
ThingDescriptor descriptor = m_discoveredThings.value(thingDescriptorId);
if (!descriptor.isValid()) {
qCWarning(dcThingManager) << "Cannot find a ThingDescriptor with ID" << thingDescriptorId.toString();
qCWarning(dcThingManager()) << "Cannot find a ThingDescriptor with ID" << thingDescriptorId.toString();
ThingPairingInfo *info = new ThingPairingInfo(pairingTransactionId, ThingClassId(), ThingId(), name, ParamList(), ThingId(), this, false);
info->finish(Thing::ThingErrorThingDescriptorNotFound);
return info;
@ -676,7 +676,7 @@ ThingPairingInfo* ThingManagerImplementation::pairThing(const ThingDescriptorId
ThingClass thingClass = m_supportedThings.value(descriptor.thingClassId());
if (!thingClass.isValid()) {
qCWarning(dcThingManager) << "Cannot find a ThingClass with ID" << descriptor.thingClassId().toString();
qCWarning(dcThingManager()) << "Cannot find a ThingClass with ID" << descriptor.thingClassId().toString();
ThingPairingInfo *info = new ThingPairingInfo(pairingTransactionId, descriptor.thingClassId(), ThingId(), name, ParamList(), ThingId(), this, false);
info->finish(Thing::ThingErrorThingClassNotFound);
return info;
@ -702,7 +702,7 @@ ThingPairingInfo *ThingManagerImplementation::pairThing(const ThingId &thingId,
Thing *thing = findConfiguredThing(thingId);
if (!thing) {
qCWarning(dcThingManager) << "Cannot find a thing with ID" << thingId.toString();
qCWarning(dcThingManager()) << "Cannot find a thing with ID" << thingId.toString();
ThingPairingInfo *info = new ThingPairingInfo(pairingTransactionId, ThingClassId(), thingId, name, ParamList(), ThingId(), this, true);
info->finish(Thing::ThingErrorThingDescriptorNotFound);
return info;
@ -731,7 +731,7 @@ ThingPairingInfo *ThingManagerImplementation::confirmPairing(const PairingTransa
ThingClass thingClass = m_supportedThings.value(thingClassId);
IntegrationPlugin *plugin = m_integrationPlugins.value(thingClass.pluginId());
if (!plugin) {
qCWarning(dcThingManager) << "Can't find a plugin for this" << thingClass;
qCWarning(dcThingManager()) << "Can't find a plugin for this" << thingClass;
ThingPairingInfo *info = new ThingPairingInfo(pairingTransactionId, thingClassId, context.thingId, context.thingName, context.params, context.parentId, this, false);
info->finish(Thing::ThingErrorPluginNotFound);
return info;
@ -759,7 +759,7 @@ ThingPairingInfo *ThingManagerImplementation::confirmPairing(const PairingTransa
// Internal pairing succeeded, set up the thing.
if (!addNewThing && !m_configuredThings.contains(internalInfo->thingId())) {
qCWarning(dcThingManager) << "The thing to be reconfigured has disappeared!";
qCWarning(dcThingManager()) << "The thing to be reconfigured has disappeared!";
externalInfo->finish(Thing::ThingErrorThingNotFound);
return;
}
@ -888,14 +888,14 @@ ThingSetupInfo* ThingManagerImplementation::addConfiguredThingInternal(const Thi
ThingSetupInfo *info = setupThing(thing, true);
connect(info, &ThingSetupInfo::finished, this, [this, info](){
if (info->status() != Thing::ThingErrorNoError) {
qCWarning(dcThingManager) << "Thing setup failed for" << info->thing() << "Not adding thing to system.";
qCWarning(dcThingManager()) << "Thing setup failed for" << info->thing() << "Not adding thing to system.";
info->thing()->deleteLater();
return;
}
info->thing()->setSetupStatus(Thing::ThingSetupStatusComplete, Thing::ThingErrorNoError);
qCDebug(dcThingManager) << "Thing setup complete for" << info->thing();
qCDebug(dcThingManager()) << "Thing setup complete for" << info->thing();
registerThing(info->thing());
storeConfiguredThings();
emit thingAdded(info->thing());
@ -913,7 +913,7 @@ Thing::ThingError ThingManagerImplementation::removeConfiguredThing(const ThingI
}
if (!thing->parentId().isNull() && thing->autoCreated()) {
qCWarning(dcThingManager) << "Thing is an autocreated child of" << thing->parentId().toString() << ". Remove the parent instead.";
qCWarning(dcThingManager()) << "Thing is an autocreated child of" << thing->parentId().toString() << ". Remove the parent instead.";
return Thing::ThingErrorThingIsChild;
}
@ -1481,7 +1481,7 @@ void ThingManagerImplementation::loadPlugins()
foreach (const QString &path, searchDirs) {
QDir dir(path);
qCDebug(dcThingManager) << "Loading plugins from:" << dir.absolutePath();
qCDebug(dcThingManager()) << "Loading plugins from:" << dir.absolutePath();
foreach (const QString &entry, dir.entryList({"*.so", "*.js", "*.py"}, QDir::Files)) {
IntegrationPlugin *plugin = nullptr;
@ -1564,9 +1564,9 @@ void ThingManagerImplementation::loadPlugin(IntegrationPlugin *pluginIface)
pluginIface->setParent(this);
pluginIface->initPlugin(this, m_hardwareManager, apiKeyStorage);
qCDebug(dcThingManager) << "**** Loaded plugin" << pluginIface->pluginName();
qCDebug(dcThingManager()) << "**** Loaded plugin" << pluginIface->pluginName();
foreach (const Vendor &vendor, pluginIface->supportedVendors()) {
qCDebug(dcThingManager) << "* Loaded vendor:" << vendor.name() << vendor.id().toString();
qCDebug(dcThingManager()) << "* Loaded vendor:" << vendor.name() << vendor.id().toString();
if (m_supportedVendors.contains(vendor.id()))
continue;
@ -1575,12 +1575,12 @@ void ThingManagerImplementation::loadPlugin(IntegrationPlugin *pluginIface)
foreach (const ThingClass &thingClass, pluginIface->supportedThings()) {
if (!m_supportedVendors.contains(thingClass.vendorId())) {
qCWarning(dcThingManager) << "Vendor not found. Ignoring thing. VendorId:" << thingClass.vendorId().toString() << "ThingClass:" << thingClass.name() << thingClass.id().toString();
qCWarning(dcThingManager()) << "Vendor not found. Ignoring thing. VendorId:" << thingClass.vendorId().toString() << "ThingClass:" << thingClass.name() << thingClass.id().toString();
continue;
}
m_vendorThingMap[thingClass.vendorId()].append(thingClass.id());
m_supportedThings.insert(thingClass.id(), thingClass);
qCDebug(dcThingManager) << "* Loaded thing class:" << thingClass.name();
qCDebug(dcThingManager()) << "* Loaded thing class:" << thingClass.name();
}
NymeaSettings settings(NymeaSettings::SettingsRolePlugins);
@ -1609,7 +1609,7 @@ void ThingManagerImplementation::loadPlugin(IntegrationPlugin *pluginIface)
if (params.count() > 0) {
Thing::ThingError status = pluginIface->setConfiguration(params);
if (status != Thing::ThingErrorNoError) {
qCWarning(dcThingManager) << "Error setting params to plugin" << pluginIface->pluginId().toString() << pluginIface->pluginDisplayName() << ". Broken configuration?";
qCWarning(dcThingManager()) << "Error setting params to plugin" << pluginIface->pluginId().toString() << pluginIface->pluginDisplayName() << ". Broken configuration?";
}
}
@ -1633,7 +1633,7 @@ void ThingManagerImplementation::loadConfiguredThings()
settings.beginGroup("DeviceConfig");
needsMigration = true;
}
qCDebug(dcThingManager) << "Loading things from" << settings.fileName();
qCDebug(dcThingManager()) << "Loading things from" << settings.fileName();
foreach (const QString &idString, settings.childGroups()) {
settings.beginGroup(idString);
QString thingName = settings.value("thingName").toString();
@ -1912,7 +1912,7 @@ void ThingManagerImplementation::onAutoThingsAppeared(const ThingDescriptors &th
connect(info, &ThingSetupInfo::finished, thing, [this, info](){
if (info->status() != Thing::ThingErrorNoError) {
qCWarning(dcThingManager) << "Setting up" << info->thing() << "failed:" << info->status() << "Not adding auto thing to system.";
qCWarning(dcThingManager()) << "Setting up" << info->thing() << "failed:" << info->status() << "Not adding auto thing to system.";
info->thing()->deleteLater();
return;
}
@ -1932,19 +1932,19 @@ void ThingManagerImplementation::onAutoThingDisappeared(const ThingId &thingId)
Thing *thing = m_configuredThings.value(thingId);
if (!thing) {
qCWarning(dcThingManager) << "Received an autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but this thing is unknown:" << thingId.toString();
qCWarning(dcThingManager()) << "Received an autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but this thing is unknown:" << thingId.toString();
return;
}
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
if (thingClass.pluginId() != plugin->pluginId()) {
qCWarning(dcThingManager) << "Received a autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but emitting plugin does not own the thing";
qCWarning(dcThingManager()) << "Received a autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but emitting plugin does not own the thing";
return;
}
if (!thing->autoCreated()) {
qCWarning(dcThingManager) << "Received an autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but thing creationMethod is not CreateMothodAuto";
qCWarning(dcThingManager()) << "Received an autoThingDisappeared signal from plugin" << plugin->pluginDisplayName() << plugin->pluginId().toString() << "but thing creationMethod is not CreateMothodAuto";
return;
}
@ -2192,20 +2192,20 @@ void ThingManagerImplementation::pairThingInternal(ThingPairingInfo *info)
{
ThingClass thingClass = m_supportedThings.value(info->thingClassId());
if (thingClass.id().isNull()) {
qCWarning(dcThingManager) << "Cannot find a thing class with id" << info->thingClassId();
qCWarning(dcThingManager()) << "Cannot find a thing class with id" << info->thingClassId();
info->finish(Thing::ThingErrorThingClassNotFound);
return;
}
if (thingClass.setupMethod() == ThingClass::SetupMethodJustAdd) {
qCWarning(dcThingManager) << "Cannot setup this thing this way. No need to pair this thing.";
qCWarning(dcThingManager()) << "Cannot setup this thing this way. No need to pair this thing.";
info->finish(Thing::ThingErrorSetupMethodNotSupported);
return;
}
IntegrationPlugin *plugin = m_integrationPlugins.value(thingClass.pluginId());
if (!plugin) {
qCWarning(dcThingManager) << "Cannot pair thing class" << thingClass << "because no plugin for it is loaded.";
qCWarning(dcThingManager()) << "Cannot pair thing class" << thingClass << "because no plugin for it is loaded.";
info->finish(Thing::ThingErrorPluginNotFound);
return;
}
@ -2239,7 +2239,7 @@ ThingSetupInfo* ThingManagerImplementation::setupThing(Thing *thing, bool initia
ThingSetupInfo *info = new ThingSetupInfo(thing, this, initialSetup, false, 30000);
if (!plugin) {
qCWarning(dcThingManager) << "Can't find a plugin for this thing" << thing;
qCWarning(dcThingManager()) << "Can't find a plugin for this thing" << thing;
info->finish(Thing::ThingErrorPluginNotFound, tr("The plugin for this thing is not loaded."));
return info;
}
@ -2560,7 +2560,7 @@ IntegrationPlugin *ThingManagerImplementation::createCppIntegrationPlugin(const
qCDebug(dcThingManager()) << "Loading plugin from:" << absoluteFilePath;
if (!loader.load()) {
qCWarning(dcThingManager) << "Could not load plugin data of" << absoluteFilePath << "\n" << loader.errorString();
qCWarning(dcThingManager()) << "Could not load plugin data of" << absoluteFilePath << "\n" << loader.errorString();
return nullptr;
}
@ -2581,7 +2581,7 @@ IntegrationPlugin *ThingManagerImplementation::createCppIntegrationPlugin(const
}
IntegrationPlugin *pluginIface = qobject_cast<IntegrationPlugin *>(p);
if (!pluginIface) {
qCWarning(dcThingManager) << "Could not get plugin instance of" << absoluteFilePath;
qCWarning(dcThingManager()) << "Could not get plugin instance of" << absoluteFilePath;
return nullptr;
}

View File

@ -31,8 +31,6 @@
#include "pluginmetadata.h"
#include "thingutils.h"
#include "loggingcategories.h"
#include "types/interface.h"
#include <QJsonObject>
@ -758,6 +756,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
}
}
if (!ifaceParamType.allowedValues().isEmpty() && ifaceParamType.allowedValues() != paramType.allowedValues()) {
qCritical() << ifaceParamType.allowedValues();
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but param \"" +
paramType.name() + "\" has not matching allowed values.");
hasError = true;
@ -807,6 +806,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
}
}
if (!ifaceStateType.possibleValues().isEmpty() && ifaceStateType.possibleValues() != stateType.possibleValues()) {
qCritical() << ifaceStateType.possibleValues();
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching allowed values.");
hasError = true;
}
@ -1077,7 +1077,11 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
}
// Check type
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
QMetaType::Type t = static_cast<QMetaType::Type>(QMetaType::fromName(pt.value("type").toString().toUtf8()).id());
#else
QMetaType::Type t = static_cast<QMetaType::Type>(QVariant::nameToType(pt.value("type").toString().toLatin1().data()));
#endif
if (t == QMetaType::UnknownType) {
m_validationErrors.append("Param type \"" + paramName + "\" has unknown invalid type \"" + pt.value("type").toString() + "\"");
hasErrors = true;

View File

@ -419,7 +419,7 @@ void Thing::setStateValue(const StateTypeId &stateTypeId, const QVariant &value)
}
}
Q_ASSERT_X(false, m_name.toUtf8(), QString("Failed setting state %1 to %2").arg(stateType.name()).arg(value.toString()).toUtf8());
qCWarning(dcThing).nospace() << this << ": Failed setting state " << stateType.name() << " to " << value;
qCWarning(dcThing()).nospace() << this << ": Failed setting state " << stateType.name() << " to " << value;
}
/*! Sets the value for the \l{State} matching the given \a stateName in this thing to value. */
@ -467,7 +467,7 @@ void Thing::setStateMinValue(const StateTypeId &stateTypeId, const QVariant &min
}
}
Q_ASSERT_X(false, m_name.toUtf8(), QString("Failed setting minimum state value %1 to %2").arg(stateType.name()).arg(minValue.toString()).toUtf8());
qCWarning(dcThing).nospace() << this << ": Failed setting minimum state value " << stateType.name() << " to " << minValue;
qCWarning(dcThing()).nospace() << this << ": Failed setting minimum state value " << stateType.name() << " to " << minValue;
}
/*! Sets the minimum value for the \l{State} matching the given \a stateName in this thing to value. */
@ -513,7 +513,7 @@ void Thing::setStateMaxValue(const StateTypeId &stateTypeId, const QVariant &max
}
}
Q_ASSERT_X(false, m_name.toUtf8(), QString("Failed setting maximum state value %1 to %2").arg(stateType.name()).arg(maxValue.toString()).toUtf8());
qCWarning(dcThing).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << maxValue;
qCWarning(dcThing()).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << maxValue;
}
/*! Sets the maximum value for the \l{State} matching the given \a stateName in this thing to value. */
@ -564,7 +564,7 @@ void Thing::setStateMinMaxValues(const StateTypeId &stateTypeId, const QVariant
}
}
Q_ASSERT_X(false, m_name.toUtf8(), QString("Failed setting maximum state value %1 to %2").arg(stateType.name()).arg(maxValue.toString()).toUtf8());
qCWarning(dcThing).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << maxValue;
qCWarning(dcThing()).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << maxValue;
}
@ -591,10 +591,10 @@ void Thing::setStatePossibleValues(const StateTypeId &stateTypeId, const QVarian
if (!values.contains(m_states.value(i).value())) {
if (values.contains(stateType.defaultValue())) {
qCInfo(dcThing).nospace() << this << ": Adjusting state value for " << stateType.name() << " from " << m_states.at(i).value() << " to default value of " << stateType.defaultValue();
qCInfo(dcThing()).nospace() << this << ": Adjusting state value for " << stateType.name() << " from " << m_states.at(i).value() << " to default value of " << stateType.defaultValue();
m_states[i].setValue(stateType.defaultValue());
} else if (!values.isEmpty()) {
qCInfo(dcThing).nospace() << this << ": Adjusting state value for " << stateType.name() << " from " << m_states.at(i).value() << " to new value of " << values.first();
qCInfo(dcThing()).nospace() << this << ": Adjusting state value for " << stateType.name() << " from " << m_states.at(i).value() << " to new value of " << values.first();
m_states[i].setValue(values.first());
}
}
@ -602,7 +602,7 @@ void Thing::setStatePossibleValues(const StateTypeId &stateTypeId, const QVarian
return;
}
}
qCWarning(dcThing).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << values;
qCWarning(dcThing()).nospace() << this << ": Failed setting maximum state value " << stateType.name() << " to " << values;
Q_ASSERT_X(false, m_name.toUtf8(), QString("Failed setting possible state values for %1 to %2").arg(stateType.name()).arg(QString(QJsonDocument::fromVariant(values).toJson())).toUtf8());
}

View File

@ -60,7 +60,7 @@ Thing::ThingError ThingUtils::verifyParams(const QList<ParamType> paramTypes, co
}
if (!found) {
qCWarning(dcThing) << "Missing parameter:" << paramType.name() << params;
qCWarning(dcThing()) << "Missing parameter:" << paramType.name() << params;
return Thing::ThingErrorMissingParameter;
}
}
@ -76,7 +76,7 @@ Thing::ThingError ThingUtils::verifyParam(const QList<ParamType> paramTypes, con
}
}
qCWarning(dcThing) << "Invalid parameter" << param.paramTypeId().toString() << "in parameter list";
qCWarning(dcThing()) << "Invalid parameter" << param.paramTypeId().toString() << "in parameter list";
return Thing::ThingErrorInvalidParameter;
}
@ -84,58 +84,58 @@ Thing::ThingError ThingUtils::verifyParam(const QList<ParamType> paramTypes, con
Thing::ThingError ThingUtils::verifyParam(const ParamType &paramType, const Param &param)
{
if (paramType.id() != param.paramTypeId()) {
qCWarning(dcThing) << "Parameter id" << param.paramTypeId().toString() << "does not match with ParamType id" << paramType.id().toString();
qCWarning(dcThing()) << "Parameter id" << param.paramTypeId().toString() << "does not match with ParamType id" << paramType.id().toString();
return Thing::ThingErrorInvalidParameter;
}
if (!param.value().canConvert(static_cast<int>(paramType.type()))) {
qCWarning(dcThing) << "Wrong parameter type for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Expected:" << QVariant::typeToName(static_cast<int>(paramType.type()));
qCWarning(dcThing()) << "Wrong parameter type for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Expected:" << QVariant::typeToName(static_cast<int>(paramType.type()));
return Thing::ThingErrorInvalidParameter;
}
if (!param.value().convert(static_cast<int>(paramType.type()))) {
qCWarning(dcThing) << "Could not convert value of param" << param.paramTypeId().toString() << " to:" << QVariant::typeToName(static_cast<int>(paramType.type())) << " Got:" << param.value();
qCWarning(dcThing()) << "Could not convert value of param" << param.paramTypeId().toString() << " to:" << QVariant::typeToName(static_cast<int>(paramType.type())) << " Got:" << param.value();
return Thing::ThingErrorInvalidParameter;
}
if (paramType.type() == QMetaType::Int) {
if (paramType.maxValue().isValid() && param.value().toInt() > paramType.maxValue().toInt()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
return Thing::ThingErrorInvalidParameter;
}
if (paramType.minValue().isValid() && param.value().toInt() < paramType.minValue().toInt()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
return Thing::ThingErrorInvalidParameter;
}
} else if (paramType.type() == QMetaType::UInt) {
if (paramType.maxValue().isValid() && param.value().toUInt() > paramType.maxValue().toUInt()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
return Thing::ThingErrorInvalidParameter;
}
if (paramType.minValue().isValid() && param.value().toUInt() < paramType.minValue().toUInt()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
return Thing::ThingErrorInvalidParameter;
}
} else if (paramType.type() == QMetaType::Double) {
if (paramType.maxValue().isValid() && param.value().toDouble() > paramType.maxValue().toDouble()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
return Thing::ThingErrorInvalidParameter;
}
if (paramType.minValue().isValid() && param.value().toDouble() < paramType.minValue().toDouble()) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
return Thing::ThingErrorInvalidParameter;
}
} else {
if (paramType.maxValue().isValid() && ThingUtils::variantGreaterThan(param.value(), paramType.maxValue())) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Max:" << paramType.maxValue();
return Thing::ThingErrorInvalidParameter;
}
if (paramType.minValue().isValid() && ThingUtils::variantLessThan(param.value(), paramType.minValue())) {
qCWarning(dcThing) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
qCWarning(dcThing()) << "Value out of range for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Min:" << paramType.minValue();
return Thing::ThingErrorInvalidParameter;
}
}
@ -146,7 +146,7 @@ Thing::ThingError ThingUtils::verifyParam(const ParamType &paramType, const Para
allowedValues.append(value.toString());
}
qCWarning(dcThing) << "Value not in allowed values for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Allowed:" << allowedValues.join(",");
qCWarning(dcThing()) << "Value not in allowed values for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Allowed:" << allowedValues.join(",");
return Thing::ThingErrorInvalidParameter;
}
@ -174,7 +174,7 @@ Interface ThingUtils::loadInterface(const QString &name)
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(f.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcThingManager) << "Cannot load interface definition for interface" << name << ":" << error.errorString();
qCWarning(dcThingManager()) << "Cannot load interface definition for interface" << name << ":" << error.errorString();
return iface;
}
QVariantMap content = jsonDoc.toVariant().toMap();
@ -199,11 +199,21 @@ Interface ThingUtils::loadInterface(const QString &name)
InterfaceParamType paramType;
paramType.setName(paramMap.value("name").toString());
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
paramType.setType(static_cast<QMetaType::Type>(QMetaType::fromName(paramMap.value("type").toString().toUtf8()).id()));
#else
paramType.setType(static_cast<QMetaType::Type>(QVariant::nameToType(paramMap.value("type").toByteArray())));
#endif
paramType.setMinValue(paramMap.value("minValue"));
paramType.setMaxValue(paramMap.value("maxValue"));
paramType.setDefaultValue(paramMap.value("defaultValue"));
paramType.setAllowedValues(paramMap.value("allowedValues").toList());
if (paramMap.value("allowedValues").toString() == "any") {
// Note: Since Qt6 toList converts any to a char list ['a', 'n', 'y']
paramType.setAllowedValues(QVariantList());
} else {
paramType.setAllowedValues(paramMap.value("allowedValues").toList());
}
paramType.setReadOnly(paramMap.value("readOnly").toBool());
//paramType.setOptional(paramMap.value("optional", false).toBool());
@ -211,7 +221,7 @@ Interface ThingUtils::loadInterface(const QString &name)
QMetaEnum unitEnum = QMetaEnum::fromType<Types::Unit>();
int enumValue = unitEnum.keyToValue("Unit" + paramMap.value("unit").toByteArray());
if (enumValue == -1) {
qCWarning(dcThingManager) << "Invalid unit" << paramMap.value("unit").toString() << "in interface" << name;
qCWarning(dcThingManager()) << "Invalid unit" << paramMap.value("unit").toString() << "in interface" << name;
} else {
paramType.setUnit(static_cast<Types::Unit>(enumValue));
}
@ -226,8 +236,18 @@ Interface ThingUtils::loadInterface(const QString &name)
QVariantMap stateMap = stateVariant.toMap();
InterfaceStateType stateType;
stateType.setName(stateMap.value("name").toString());
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
stateType.setType(static_cast<QMetaType::Type>(QMetaType::fromName(stateMap.value("type").toString().toUtf8()).id()));
#else
stateType.setType(static_cast<QMetaType::Type>(QVariant::nameToType(stateMap.value("type").toByteArray())));
stateType.setPossibleValues(stateMap.value("allowedValues").toList());
#endif
if (stateMap.value("allowedValues").toString() == "any") {
// Note: Since Qt6 toList converts any to a char list ['a', 'n', 'y']
stateType.setPossibleValues(QVariantList());
} else {
stateType.setPossibleValues(stateMap.value("allowedValues").toList());
}
stateType.setMinValue(stateMap.value("minValue"));
stateType.setMaxValue(stateMap.value("maxValue"));
stateType.setOptional(stateMap.value("optional", false).toBool());
@ -235,7 +255,7 @@ Interface ThingUtils::loadInterface(const QString &name)
QMetaEnum unitEnum = QMetaEnum::fromType<Types::Unit>();
int enumValue = unitEnum.keyToValue("Unit" + stateMap.value("unit").toByteArray());
if (enumValue == -1) {
qCWarning(dcThingManager) << "Invalid unit" << stateMap.value("unit").toString() << "in interface" << name;
qCWarning(dcThingManager()) << "Invalid unit" << stateMap.value("unit").toString() << "in interface" << name;
} else {
stateType.setUnit(static_cast<Types::Unit>(enumValue));
}
@ -276,8 +296,17 @@ Interface ThingUtils::loadInterface(const QString &name)
foreach (const QVariant &actionParamVariant, actionVariant.toMap().value("params").toList()) {
ParamType paramType;
paramType.setName(actionParamVariant.toMap().value("name").toString());
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
paramType.setType(static_cast<QMetaType::Type>(QMetaType::fromName(actionParamVariant.toMap().value("type").toString().toUtf8()).id()));
#else
paramType.setType(static_cast<QMetaType::Type>(QVariant::nameToType(actionParamVariant.toMap().value("type").toByteArray())));
paramType.setAllowedValues(actionParamVariant.toMap().value("allowedValues").toList());
#endif
if (actionParamVariant.toMap().value("allowedValues").toString() == "any") {
// Note: Since Qt6 toList converts any to a char list ['a', 'n', 'y']
paramType.setAllowedValues(QVariantList());
} else {
paramType.setAllowedValues(actionParamVariant.toMap().value("allowedValues").toList());
}
paramType.setMinValue(actionParamVariant.toMap().value("min"));
paramType.setDefaultValue(actionParamVariant.toMap().value("defaultValue"));
paramTypes.append(paramType);
@ -298,8 +327,17 @@ Interface ThingUtils::loadInterface(const QString &name)
foreach (const QVariant &eventParamVariant, eventVariant.toMap().value("params").toList()) {
ParamType paramType;
paramType.setName(eventParamVariant.toMap().value("name").toString());
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
paramType.setType(static_cast<QMetaType::Type>(QMetaType::fromName(eventParamVariant.toMap().value("type").toString().toUtf8()).id()));
#else
paramType.setType(static_cast<QMetaType::Type>(QVariant::nameToType(eventParamVariant.toMap().value("type").toByteArray())));
paramType.setAllowedValues(eventParamVariant.toMap().value("allowedValues").toList());
#endif
if (eventParamVariant.toMap().value("allowedValues").toString() == "any") {
// Note: Since Qt6 toList converts any to a char list ['a', 'n', 'y']
paramType.setAllowedValues(QVariantList());
} else {
paramType.setAllowedValues(eventParamVariant.toMap().value("allowedValues").toList());
}
paramType.setMinValue(eventParamVariant.toMap().value("minValue"));
paramType.setMaxValue(eventParamVariant.toMap().value("maxValue"));
paramType.setDefaultValue(eventParamVariant.toMap().value("defaultValue"));
@ -351,7 +389,7 @@ QStringList ThingUtils::generateInterfaceParentList(const QString &interface)
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(f.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcThingManager) << "Cannot load interface definition for interface" << interface << ":" << error.errorString();
qCWarning(dcThingManager()) << "Cannot load interface definition for interface" << interface << ":" << error.errorString();
return QStringList();
}
QStringList ret = {interface};

View File

@ -15,6 +15,7 @@
{
"name": "inputSource",
"type": "QString",
"allowedValues": "any",
"writable": true,
"optional": true
},

View File

@ -216,12 +216,12 @@ void JsonHandler::registerObject(const QMetaObject &metaObject)
if (elementType == "ThingId" || elementType == "EventTypeId" || elementType == "StateTypeId" || elementType == "ActionTypeId") {
elementType = "QUuid";
}
QMetaType::Type variantType = static_cast<QMetaType::Type>(QVariant::nameToType(elementType.toUtf8()));
QMetaType::Type variantType = static_cast<QMetaType::Type>(QMetaType::fromName(elementType.toUtf8()).id());
typeName = QVariantList() << enumValueName(variantTypeToBasicType(variantType));
} else {
QString typeNameRaw = QString(metaProperty.typeName());
QString propertyNameRaw = QString(metaProperty.name());
QString metaTypeNameRaw = QString(metaProperty.metaType().name());
// QString propertyNameRaw = QString(metaProperty.name());
// QString metaTypeNameRaw = QString(metaProperty.metaType().name());
if (typeNameRaw.contains("QFlag")) {
QString enumType = QString(typeNameRaw).split("::").last().remove('<').remove('>');
typeName = QString("$ref:%1").arg(m_flagsEnums.key(enumType));