From d71ce85f124e6b6307c99ad94d60c44b8ecfb135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 19 Aug 2025 13:00:08 +0200 Subject: [PATCH] Fix interface allowed values loading and debug cathegories for thing and thing manager --- libnymea-core/integrations/python/pything.h | 4 +- .../integrations/pythonintegrationplugin.cpp | 6 +- .../thingmanagerimplementation.cpp | 60 +++++++------- libnymea/integrations/pluginmetadata.cpp | 8 +- libnymea/integrations/thing.cpp | 14 ++-- libnymea/integrations/thingutils.cpp | 82 ++++++++++++++----- libnymea/interfaces/mediaplayer.json | 1 + libnymea/jsonrpc/jsonhandler.cpp | 6 +- 8 files changed, 112 insertions(+), 69 deletions(-) diff --git a/libnymea-core/integrations/python/pything.h b/libnymea-core/integrations/python/pything.h index 775a279a..5f1fe46e 100644 --- a/libnymea-core/integrations/python/pything.h +++ b/libnymea-core/integrations/python/pything.h @@ -192,7 +192,7 @@ static PyObject * PyThing_paramValue(PyThing* self, PyObject* args) char *paramTypeIdStr = nullptr; if (!PyArg_ParseTuple(args, "s", ¶mTypeIdStr)) { - 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", ¶mTypeIdStr)) { - qCWarning(dcThingManager) << "Error parsing parameters"; + qCWarning(dcThingManager()) << "Error parsing parameters"; return nullptr; } diff --git a/libnymea-core/integrations/pythonintegrationplugin.cpp b/libnymea-core/integrations/pythonintegrationplugin.cpp index 4ddd5acd..758c97de 100644 --- a/libnymea-core/integrations/pythonintegrationplugin.cpp +++ b/libnymea-core/integrations/pythonintegrationplugin.cpp @@ -40,7 +40,7 @@ PyObject *PythonIntegrationPlugin::pyConfigValue(PyObject *self, PyObject *args) char *paramTypeIdStr = nullptr; if (!PyArg_ParseTuple(args, "s", ¶mTypeIdStr)) { - 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", ¶mTypeIdStr, &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); diff --git a/libnymea-core/integrations/thingmanagerimplementation.cpp b/libnymea-core/integrations/thingmanagerimplementation.cpp index 8fdfee94..2f3ee433 100644 --- a/libnymea-core/integrations/thingmanagerimplementation.cpp +++ b/libnymea-core/integrations/thingmanagerimplementation.cpp @@ -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(p); if (!pluginIface) { - qCWarning(dcThingManager) << "Could not get plugin instance of" << absoluteFilePath; + qCWarning(dcThingManager()) << "Could not get plugin instance of" << absoluteFilePath; return nullptr; } diff --git a/libnymea/integrations/pluginmetadata.cpp b/libnymea/integrations/pluginmetadata.cpp index 95a4f5aa..7ea5ada8 100644 --- a/libnymea/integrations/pluginmetadata.cpp +++ b/libnymea/integrations/pluginmetadata.cpp @@ -31,8 +31,6 @@ #include "pluginmetadata.h" #include "thingutils.h" -#include "loggingcategories.h" - #include "types/interface.h" #include @@ -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 PluginMetadata::parseParamTypes(const QJsonArray &array) } // Check type +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QMetaType::Type t = static_cast(QMetaType::fromName(pt.value("type").toString().toUtf8()).id()); +#else QMetaType::Type t = static_cast(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; diff --git a/libnymea/integrations/thing.cpp b/libnymea/integrations/thing.cpp index ef7c06f0..b5bd98d9 100644 --- a/libnymea/integrations/thing.cpp +++ b/libnymea/integrations/thing.cpp @@ -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()); } diff --git a/libnymea/integrations/thingutils.cpp b/libnymea/integrations/thingutils.cpp index fc44c4cb..ba6f6592 100644 --- a/libnymea/integrations/thingutils.cpp +++ b/libnymea/integrations/thingutils.cpp @@ -60,7 +60,7 @@ Thing::ThingError ThingUtils::verifyParams(const QList 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 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 paramTypes, con Thing::ThingError ThingUtils::verifyParam(const ParamType ¶mType, const Param ¶m) { 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(paramType.type()))) { - qCWarning(dcThing) << "Wrong parameter type for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Expected:" << QVariant::typeToName(static_cast(paramType.type())); + qCWarning(dcThing()) << "Wrong parameter type for param" << param.paramTypeId().toString() << " Got:" << param.value() << " Expected:" << QVariant::typeToName(static_cast(paramType.type())); return Thing::ThingErrorInvalidParameter; } if (!param.value().convert(static_cast(paramType.type()))) { - qCWarning(dcThing) << "Could not convert value of param" << param.paramTypeId().toString() << " to:" << QVariant::typeToName(static_cast(paramType.type())) << " Got:" << param.value(); + qCWarning(dcThing()) << "Could not convert value of param" << param.paramTypeId().toString() << " to:" << QVariant::typeToName(static_cast(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 ¶mType, 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::fromName(paramMap.value("type").toString().toUtf8()).id())); +#else paramType.setType(static_cast(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(); 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(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::fromName(stateMap.value("type").toString().toUtf8()).id())); +#else stateType.setType(static_cast(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(); 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(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::fromName(actionParamVariant.toMap().value("type").toString().toUtf8()).id())); +#else paramType.setType(static_cast(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::fromName(eventParamVariant.toMap().value("type").toString().toUtf8()).id())); +#else paramType.setType(static_cast(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}; diff --git a/libnymea/interfaces/mediaplayer.json b/libnymea/interfaces/mediaplayer.json index 73930681..5dda2700 100644 --- a/libnymea/interfaces/mediaplayer.json +++ b/libnymea/interfaces/mediaplayer.json @@ -15,6 +15,7 @@ { "name": "inputSource", "type": "QString", + "allowedValues": "any", "writable": true, "optional": true }, diff --git a/libnymea/jsonrpc/jsonhandler.cpp b/libnymea/jsonrpc/jsonhandler.cpp index 60001b42..4b5c522e 100644 --- a/libnymea/jsonrpc/jsonhandler.cpp +++ b/libnymea/jsonrpc/jsonhandler.cpp @@ -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(QVariant::nameToType(elementType.toUtf8())); + QMetaType::Type variantType = static_cast(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));