mirror of https://github.com/nymea/nymea.git
Allow states, events and actions in interfaces to be optional
parent
2ca4b2f32f
commit
49bbd64434
|
|
@ -634,29 +634,29 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
ActionTypes actionTypes(thingClass.actionTypes());
|
||||
EventTypes eventTypes(thingClass.eventTypes());
|
||||
|
||||
foreach (const StateType &ifaceStateType, iface.stateTypes()) {
|
||||
foreach (const InterfaceStateType &ifaceStateType, iface.stateTypes()) {
|
||||
StateType stateType = stateTypes.findByName(ifaceStateType.name());
|
||||
if (stateType.id().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement state \"" + ifaceStateType.name() + "\"");
|
||||
hasError = true;
|
||||
continue;
|
||||
if (!ifaceStateType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement state \"" + ifaceStateType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ifaceStateType.type() != stateType.type()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching type: \"" + QVariant::typeToName(stateType.type()) + "\" != \"" + QVariant::typeToName(ifaceStateType.type()) + "\"");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
if (ifaceStateType.minValue().isValid() && !ifaceStateType.minValue().isNull()) {
|
||||
if (ifaceStateType.minValue().toString() == "any") {
|
||||
if (stateType.minValue().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has no minimum value defined.");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
} else if (ifaceStateType.minValue() != stateType.minValue()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching minimum value: \"" + ifaceStateType.minValue().toString() + "\" != \"" + stateType.minValue().toString() + "\"");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ifaceStateType.maxValue().isValid() && !ifaceStateType.maxValue().isNull()) {
|
||||
|
|
@ -664,32 +664,32 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
if (stateType.maxValue().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has no maximum value defined.");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
} else if (ifaceStateType.maxValue() != stateType.maxValue()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching maximum value: \"" + ifaceStateType.maxValue().toString() + "\" != \"" + stateType.minValue().toString() + "\"");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!ifaceStateType.possibleValues().isEmpty() && ifaceStateType.possibleValues() != stateType.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;
|
||||
continue;
|
||||
}
|
||||
if (ifaceStateType.unit() != Types::UnitNone && ifaceStateType.unit() != stateType.unit()) {
|
||||
QMetaEnum unitEnum = QMetaEnum::fromType<Types::Unit>();
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching unit: \"" + unitEnum.valueToKey(ifaceStateType.unit()) + "\" != \"" + unitEnum.valueToKey(stateType.unit()));
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const ActionType &ifaceActionType, iface.actionTypes()) {
|
||||
foreach (const InterfaceActionType &ifaceActionType, iface.actionTypes()) {
|
||||
ActionType actionType = actionTypes.findByName(ifaceActionType.name());
|
||||
if (actionType.id().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement action \"" + ifaceActionType.name() + "\"");
|
||||
hasError = true;
|
||||
if (!ifaceActionType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement action \"" + ifaceActionType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (const ParamType &ifaceActionParamType, ifaceActionType.paramTypes()) {
|
||||
ParamType paramType = actionType.paramTypes().findByName(ifaceActionParamType.name());
|
||||
|
|
@ -711,11 +711,15 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
}
|
||||
}
|
||||
|
||||
foreach (const EventType &ifaceEventType, iface.eventTypes()) {
|
||||
foreach (const InterfaceEventType &ifaceEventType, iface.eventTypes()) {
|
||||
EventType eventType = eventTypes.findByName(ifaceEventType.name());
|
||||
if (!eventType.isValid()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement event \"" + ifaceEventType.name() + "\"");
|
||||
hasError = true;
|
||||
if (!ifaceEventType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement event \"" + ifaceEventType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (const ParamType &ifaceEventParamType, ifaceEventType.paramTypes()) {
|
||||
ParamType paramType = eventType.paramTypes().findByName(ifaceEventParamType.name());
|
||||
|
|
|
|||
|
|
@ -189,16 +189,17 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
}
|
||||
}
|
||||
|
||||
StateTypes stateTypes;
|
||||
ActionTypes actionTypes;
|
||||
EventTypes eventTypes;
|
||||
InterfaceStateTypes stateTypes;
|
||||
InterfaceActionTypes actionTypes;
|
||||
InterfaceEventTypes eventTypes;
|
||||
foreach (const QVariant &stateVariant, content.value("states").toList()) {
|
||||
StateType stateType;
|
||||
InterfaceStateType stateType;
|
||||
stateType.setName(stateVariant.toMap().value("name").toString());
|
||||
stateType.setType(QVariant::nameToType(stateVariant.toMap().value("type").toByteArray()));
|
||||
stateType.setPossibleValues(stateVariant.toMap().value("allowedValues").toList());
|
||||
stateType.setMinValue(stateVariant.toMap().value("minValue"));
|
||||
stateType.setMaxValue(stateVariant.toMap().value("maxValue"));
|
||||
stateType.setOptional(stateVariant.toMap().value("optional", false).toBool());
|
||||
if (stateVariant.toMap().contains("unit")) {
|
||||
QMetaEnum unitEnum = QMetaEnum::fromType<Types::Unit>();
|
||||
int enumValue = unitEnum.keyToValue("Unit" + stateVariant.toMap().value("unit").toByteArray());
|
||||
|
|
@ -210,8 +211,9 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
}
|
||||
stateTypes.append(stateType);
|
||||
|
||||
EventType stateChangeEventType;
|
||||
InterfaceEventType stateChangeEventType;
|
||||
stateChangeEventType.setName(stateType.name());
|
||||
stateChangeEventType.setOptional(stateType.optional());
|
||||
ParamType stateChangeEventParamType;
|
||||
stateChangeEventParamType.setName(stateType.name());
|
||||
stateChangeEventParamType.setType(stateType.type());
|
||||
|
|
@ -222,16 +224,18 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
eventTypes.append(stateChangeEventType);
|
||||
|
||||
if (stateVariant.toMap().value("writable", false).toBool()) {
|
||||
ActionType stateChangeActionType;
|
||||
InterfaceActionType stateChangeActionType;
|
||||
stateChangeActionType.setName(stateType.name());
|
||||
stateChangeActionType.setOptional(stateType.optional());
|
||||
stateChangeActionType.setParamTypes(ParamTypes() << stateChangeEventParamType);
|
||||
actionTypes.append(stateChangeActionType);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const QVariant &actionVariant, content.value("actions").toList()) {
|
||||
ActionType actionType;
|
||||
InterfaceActionType actionType;
|
||||
actionType.setName(actionVariant.toMap().value("name").toString());
|
||||
actionType.setOptional(actionVariant.toMap().value("optional").toBool());
|
||||
ParamTypes paramTypes;
|
||||
foreach (const QVariant &actionParamVariant, actionVariant.toMap().value("params").toList()) {
|
||||
ParamType paramType;
|
||||
|
|
@ -246,8 +250,9 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
}
|
||||
|
||||
foreach (const QVariant &eventVariant, content.value("events").toList()) {
|
||||
EventType eventType;
|
||||
InterfaceEventType eventType;
|
||||
eventType.setName(eventVariant.toMap().value("name").toString());
|
||||
eventType.setOptional(eventVariant.toMap().value("optional").toBool());
|
||||
ParamTypes paramTypes;
|
||||
foreach (const QVariant &eventParamVariant, eventVariant.toMap().value("params").toList()) {
|
||||
ParamType paramType;
|
||||
|
|
@ -267,20 +272,20 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
|
||||
Interface ThingUtils::mergeInterfaces(const Interface &iface1, const Interface &iface2)
|
||||
{
|
||||
EventTypes eventTypes = iface1.eventTypes();
|
||||
foreach (const EventType &et, iface2.eventTypes()) {
|
||||
InterfaceEventTypes eventTypes = iface1.eventTypes();
|
||||
foreach (const InterfaceEventType &et, iface2.eventTypes()) {
|
||||
if (eventTypes.findByName(et.name()).name().isEmpty()) {
|
||||
eventTypes.append(et);
|
||||
}
|
||||
}
|
||||
StateTypes stateTypes = iface1.stateTypes();
|
||||
foreach (const StateType &st, iface2.stateTypes()) {
|
||||
InterfaceStateTypes stateTypes = iface1.stateTypes();
|
||||
foreach (const InterfaceStateType &st, iface2.stateTypes()) {
|
||||
if (stateTypes.findByName(st.name()).name().isEmpty()) {
|
||||
stateTypes.append(st);
|
||||
}
|
||||
}
|
||||
ActionTypes actionTypes = iface1.actionTypes();
|
||||
foreach (const ActionType &at, iface2.actionTypes()) {
|
||||
InterfaceActionTypes actionTypes = iface1.actionTypes();
|
||||
foreach (const InterfaceActionType &at, iface2.actionTypes()) {
|
||||
if (actionTypes.findByName(at.name()).name().isEmpty()) {
|
||||
actionTypes.append(at);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ HEADERS += \
|
|||
types/browseritem.h \
|
||||
types/browseritemaction.h \
|
||||
types/browseraction.h \
|
||||
types/interfaceactiontype.h \
|
||||
types/interfaceeventtype.h \
|
||||
types/interfacestatetype.h \
|
||||
types/mediabrowseritem.h \
|
||||
types/thingclass.h \
|
||||
typeutils.h \
|
||||
|
|
@ -149,6 +152,9 @@ SOURCES += \
|
|||
types/browseritem.cpp \
|
||||
types/browseritemaction.cpp \
|
||||
types/browseraction.cpp \
|
||||
types/interfaceactiontype.cpp \
|
||||
types/interfaceeventtype.cpp \
|
||||
types/interfacestatetype.cpp \
|
||||
types/mediabrowseritem.cpp \
|
||||
types/action.cpp \
|
||||
types/actiontype.cpp \
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "interface.h"
|
||||
|
||||
Interface::Interface(const QString &name, const ActionTypes &actionTypes, const EventTypes &eventTypes, const StateTypes &stateTypes):
|
||||
Interface::Interface(const QString &name, const InterfaceActionTypes &actionTypes, const InterfaceEventTypes &eventTypes, const InterfaceStateTypes &stateTypes):
|
||||
m_name(name),
|
||||
m_actionTypes(actionTypes),
|
||||
m_eventTypes(eventTypes),
|
||||
|
|
@ -44,17 +44,17 @@ QString Interface::name() const
|
|||
return m_name;
|
||||
}
|
||||
|
||||
ActionTypes Interface::actionTypes() const
|
||||
InterfaceActionTypes Interface::actionTypes() const
|
||||
{
|
||||
return m_actionTypes;
|
||||
}
|
||||
|
||||
EventTypes Interface::eventTypes() const
|
||||
InterfaceEventTypes Interface::eventTypes() const
|
||||
{
|
||||
return m_eventTypes;
|
||||
}
|
||||
|
||||
StateTypes Interface::stateTypes() const
|
||||
InterfaceStateTypes Interface::stateTypes() const
|
||||
{
|
||||
return m_stateTypes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,28 +31,29 @@
|
|||
#ifndef INTERFACE_H
|
||||
#define INTERFACE_H
|
||||
|
||||
#include "eventtype.h"
|
||||
#include "actiontype.h"
|
||||
#include "statetype.h"
|
||||
#include "interfaceeventtype.h"
|
||||
#include "interfaceactiontype.h"
|
||||
#include "interfacestatetype.h"
|
||||
|
||||
class Interface{
|
||||
public:
|
||||
Interface() = default;
|
||||
Interface(const QString &name, const ActionTypes &actionTypes, const EventTypes &eventTypes, const StateTypes &stateTypes);
|
||||
Interface(const QString &name, const InterfaceActionTypes &actionTypes, const InterfaceEventTypes &eventTypes, const InterfaceStateTypes &stateTypes);
|
||||
|
||||
QString name() const;
|
||||
|
||||
ActionTypes actionTypes() const;
|
||||
EventTypes eventTypes() const;
|
||||
StateTypes stateTypes() const;
|
||||
InterfaceActionTypes actionTypes() const;
|
||||
InterfaceEventTypes eventTypes() const;
|
||||
InterfaceStateTypes stateTypes() const;
|
||||
|
||||
bool isValid() const;
|
||||
private:
|
||||
QUuid m_id;
|
||||
QString m_name;
|
||||
ActionTypes m_actionTypes;
|
||||
EventTypes m_eventTypes;
|
||||
StateTypes m_stateTypes;
|
||||
InterfaceActionTypes m_actionTypes;
|
||||
InterfaceEventTypes m_eventTypes;
|
||||
InterfaceStateTypes m_stateTypes;
|
||||
bool m_optional = false;
|
||||
};
|
||||
|
||||
class LIBNYMEA_EXPORT Interfaces: public QList<Interface>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#include "interfaceactiontype.h"
|
||||
|
||||
InterfaceActionType::InterfaceActionType()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool InterfaceActionType::optional() const
|
||||
{
|
||||
return m_optional;
|
||||
}
|
||||
|
||||
void InterfaceActionType::setOptional(bool optional)
|
||||
{
|
||||
m_optional = optional;
|
||||
}
|
||||
|
||||
InterfaceActionTypes::InterfaceActionTypes(const QList<InterfaceActionType> &other):
|
||||
QList<InterfaceActionType>(other)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InterfaceActionType InterfaceActionTypes::findByName(const QString &name)
|
||||
{
|
||||
foreach (const InterfaceActionType &iat, *this) {
|
||||
if (iat.name() == name) {
|
||||
return iat;
|
||||
}
|
||||
}
|
||||
return InterfaceActionType();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef INTERFACEACTIONTYPE_H
|
||||
#define INTERFACEACTIONTYPE_H
|
||||
|
||||
#include "actiontype.h"
|
||||
|
||||
class InterfaceActionType: public ActionType
|
||||
{
|
||||
public:
|
||||
InterfaceActionType();
|
||||
|
||||
bool optional() const;
|
||||
void setOptional(bool optional);
|
||||
|
||||
private:
|
||||
bool m_optional = false;
|
||||
};
|
||||
|
||||
class InterfaceActionTypes: public QList<InterfaceActionType>
|
||||
{
|
||||
public:
|
||||
InterfaceActionTypes() = default;
|
||||
InterfaceActionTypes(const QList<InterfaceActionType> &other);
|
||||
InterfaceActionType findByName(const QString &name);
|
||||
};
|
||||
|
||||
#endif // INTERFACEACTIONTYPE_H
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#include "interfaceeventtype.h"
|
||||
|
||||
InterfaceEventType::InterfaceEventType()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool InterfaceEventType::optional() const
|
||||
{
|
||||
return m_optional;
|
||||
}
|
||||
|
||||
void InterfaceEventType::setOptional(bool optional)
|
||||
{
|
||||
m_optional = optional;
|
||||
}
|
||||
|
||||
InterfaceEventTypes::InterfaceEventTypes(const QList<InterfaceEventType> &other):
|
||||
QList<InterfaceEventType>(other)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InterfaceEventType InterfaceEventTypes::findByName(const QString &name)
|
||||
{
|
||||
foreach (const InterfaceEventType &iet, *this) {
|
||||
if (iet.name() == name) {
|
||||
return iet;
|
||||
}
|
||||
}
|
||||
return InterfaceEventType();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef INTERFACEEVENTTYPE_H
|
||||
#define INTERFACEEVENTTYPE_H
|
||||
|
||||
#include "eventtype.h"
|
||||
|
||||
class InterfaceEventType: public EventType
|
||||
{
|
||||
public:
|
||||
InterfaceEventType();
|
||||
|
||||
bool optional() const;
|
||||
void setOptional(bool optional);
|
||||
|
||||
private:
|
||||
bool m_optional = false;
|
||||
};
|
||||
|
||||
class InterfaceEventTypes: public QList<InterfaceEventType>
|
||||
{
|
||||
public:
|
||||
InterfaceEventTypes() = default;
|
||||
InterfaceEventTypes(const QList<InterfaceEventType> &other);
|
||||
InterfaceEventType findByName(const QString &name);
|
||||
};
|
||||
|
||||
#endif // INTERFACEEVENTTYPE_H
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#include "interfacestatetype.h"
|
||||
|
||||
InterfaceStateType::InterfaceStateType()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool InterfaceStateType::optional() const
|
||||
{
|
||||
return m_optional;
|
||||
}
|
||||
|
||||
void InterfaceStateType::setOptional(bool optional)
|
||||
{
|
||||
m_optional = optional;
|
||||
}
|
||||
|
||||
InterfaceStateTypes::InterfaceStateTypes(const QList<InterfaceStateType> &other):
|
||||
QList<InterfaceStateType>(other)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InterfaceStateType InterfaceStateTypes::findByName(const QString &name)
|
||||
{
|
||||
foreach (const InterfaceStateType &ist, *this) {
|
||||
if (ist.name() == name) {
|
||||
return ist;
|
||||
}
|
||||
}
|
||||
return InterfaceStateType();
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef INTERFACESTATETYPE_H
|
||||
#define INTERFACESTATETYPE_H
|
||||
|
||||
#include "statetype.h"
|
||||
|
||||
class InterfaceStateType: public StateType
|
||||
{
|
||||
public:
|
||||
InterfaceStateType();
|
||||
|
||||
bool optional() const;
|
||||
void setOptional(bool optional);
|
||||
|
||||
private:
|
||||
bool m_optional = false;
|
||||
};
|
||||
|
||||
class InterfaceStateTypes: public QList<InterfaceStateType>
|
||||
{
|
||||
public:
|
||||
InterfaceStateTypes() = default;
|
||||
InterfaceStateTypes(const QList<InterfaceStateType> &other);
|
||||
InterfaceStateType findByName(const QString &name);
|
||||
};
|
||||
|
||||
#endif // INTERFACESTATETYPE_H
|
||||
Loading…
Reference in New Issue