Skip to content
Permalink
Browse files

Modifying entites (EntityInterface, updateAttrByIndex)

  • Loading branch information
Christian Riedl
Christian Riedl committed Nov 21, 2019
1 parent 08c9127 commit d6b8fa18f3b06e75509e445a25f0f853b46e334b
@@ -29,6 +29,10 @@ HEADERS += \
sources/entities/entity.h \
sources/integrations/integrationinterface.h \
sources/entities/entitiesinterface.h \
sources/entities/entityinterface.h \
sources/entities/lightinterface.h \
sources/entities/blindinterface.h \
sources/entities/mediaplayerinterface.h \
sources/entities/light.h \
sources/entities/blind.h \
sources/notifications.h \
@@ -1,23 +1,53 @@
#include <QtDebug>
#include "blind.h"

QString Blind::Type = "blind";
BlindInterface::~BlindInterface()
{
}

QMetaEnum Blind::s_metaEnum;
QString Blind::Type = "blind";

bool Blind::update(const QVariantMap &attributes)
{
bool chg = false;
if (attributes.contains("state") && m_state != attributes.value("state").toBool()) {
m_state = attributes.value("state").toBool();
chg = true;
emit stateChanged();
}
if (attributes.contains("position") && m_position != attributes.value("position").toInt()) {
m_position = attributes.value("position").toInt();
chg = true;
emit positionChanged();
for (QVariantMap::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
if (updateAttrByName (iter.key(), iter.value()))
chg = true;
}
return chg;
}
bool Blind::updateAttrByName (const QString& name, const QVariant& value)
{
int attrIndex = getAttrIndex(name);
return updateAttrByIndex (attrIndex, value);
}
bool Blind::updateAttrByIndex (int attrIndex, const QVariant& value)
{
bool chg = false;
switch (static_cast<BlindDef::Attributes>(attrIndex)) {
case BlindDef::Attributes::STATE:
if (m_state != value.toBool()) {
m_state = value.toBool();
chg = true;
emit stateChanged();
}
break;
case BlindDef::Attributes::POSITION:
if (m_position != value.toInt()) {
m_position = value.toInt();
chg = true;
emit positionChanged();
}
break;
}
return chg;
}

void* Blind::getSpecificInterface()
{
return qobject_cast<BlindInterface*>(this);
}

void Blind::close()
{
@@ -39,12 +69,29 @@ void Blind::setPosition(int value)
command("POSITION", value);
}

Blind::Blind(QObject *parent) :
Entity (Type, QVariantMap(), NULL, parent)
Blind::Blind(const QVariantMap& config, QObject* integrationObj, QObject *parent):
Entity (Type, config, integrationObj, parent)
{
if (!s_metaEnum.isValid()) {
int index = BlindDef::staticMetaObject.indexOfEnumerator("Attributes");
s_metaEnum = BlindDef::staticMetaObject.enumerator(index);
}
}

Blind::Blind(const QVariantMap& config, QObject* integrationObj, QObject *parent):
Entity (Type, config, integrationObj, parent)
QStringList Blind::allFeatures ()
{
QStringList list;
for (int i = 0; i < s_metaEnum.keyCount(); i++)
list.append(s_metaEnum.key(i));
return list;
}
QString Blind::getAttrName(int attrIndex)
{
return s_metaEnum.valueToKey(static_cast<int>(attrIndex));
}
int Blind::getAttrIndex(const QString& str)
{
return s_metaEnum.keyToValue(str.toUpper().toUtf8());
}


@@ -4,30 +4,42 @@
#include <QObject>
#include <QString>
#include <QVariant>
#include <QMetaEnum>
#include "entity.h"
#include "blindinterface.h"

class Blind : public Entity
class Blind : public Entity, BlindInterface
{
Q_OBJECT
Q_INTERFACES(BlindInterface)

public:

Q_PROPERTY (bool state READ state NOTIFY stateChanged)
Q_PROPERTY (int position READ position NOTIFY positionChanged)

Q_INVOKABLE bool update(const QVariantMap& attributes) override;
// update an entity's attributes
Q_INVOKABLE bool update (const QVariantMap& attributes) override;
Q_INVOKABLE bool updateAttrByName (const QString& name, const QVariant& value) override;
Q_INVOKABLE bool updateAttrByIndex (int attrIndex, const QVariant& value) override;

// attribute name and index
Q_INVOKABLE QString getAttrName (int attrIndex) override;
Q_INVOKABLE int getAttrIndex (const QString& attrName) override;

// blind commands
Q_INVOKABLE void close();
Q_INVOKABLE void open();
Q_INVOKABLE void stop();
Q_INVOKABLE void setPosition(int value);

explicit Blind(QObject *parent = nullptr);
// only for C++ integrations
virtual void* getSpecificInterface() override;

Blind(const QVariantMap& config, QObject* integrationObj, QObject *parent = nullptr);

bool state() const { return m_state; }
int position() const { return m_position; }
bool state() override { return m_state; }
int position() override { return m_position; }

signals:
void stateChanged();
@@ -38,17 +50,18 @@ class Blind : public Entity

static QStringList& AllFeatures()
{
static QStringList s
{
"OPEN", "CLOSE", "STOP", "POSITION"
};

static QStringList s;
if (s.count() == 0)
s.append(allFeatures());
return s;
}

private:
bool m_state;
int m_position;
static QStringList allFeatures ();
static QMetaEnum s_metaEnum;

bool m_state;
int m_position;
};

#endif // BLIND_H
@@ -0,0 +1,37 @@
#ifndef BLINDINTERFACE_H
#define BLINDINTERFACE_H

#include "entityinterface.h"

/// This class is a work arround to make the feature enum available in the interface and in the specifc entity class.
/// Qt cannot create metadata describing an enum contained in the interface
/// In the specific entity class it is only needed to generically convert the feature enum to a string and back
class BlindDef : QObject
{
Q_OBJECT
public:
enum class Attributes { STATE, POSITION };
Q_ENUM (Attributes)

explicit BlindDef(QObject *parent = nullptr) : QObject(parent)
{}
};

/// This interface allows integrations to access the specific attributes
/// You get this interface from the generic entity using getSpecificInterface
class BlindInterface
{
public:
virtual ~BlindInterface ();

virtual bool state() = 0;
virtual int position() = 0;
};

QT_BEGIN_NAMESPACE
#define BlindInterface_iid "YIO.BlindInterface"
Q_DECLARE_INTERFACE(BlindInterface, BlindInterface_iid)
QT_END_NAMESPACE


#endif // BLINDINTERFACE_H
@@ -10,10 +10,12 @@

#include <QJsonArray>
#include <QtDebug>
#include <QLoggingCategory>
#include <QTimer>

static Q_LOGGING_CATEGORY(LOGC, "ENTITIES");
EntitiesInterface::~EntitiesInterface()
{
}


Entities* Entities::s_instance = nullptr;

@@ -94,15 +96,15 @@ QList<QObject *> Entities::getByAreaType(const QString &area, const QString &typ

QList<QObject *> Entities::getByIntegration(const QString& integration)
{
qDebug(LOGC) << "CALLED";
qDebug() << "CALLED";

QList<QObject *> e;
foreach (QObject *value, m_entities)
{
if (value->property("integration") == integration) {
e.append(m_entities.value(value->property("entity_id").toString()));

qDebug(LOGC) << e;
qDebug() << e;
}
}
return e;
@@ -112,6 +114,10 @@ QObject *Entities::get(const QString& entity_id)
{
return m_entities.value(entity_id);
}
EntityInterface* Entities::getInterface (const QString& entity_id)
{
return qobject_cast<EntityInterface*>(m_entities.value(entity_id));
}

void Entities::add(const QString& type, const QVariantMap& config, QObject *integrationObj)
{
@@ -132,18 +138,17 @@ void Entities::add(const QString& type, const QVariantMap& config, QObject *inte
if (type == "remote") {
entity = new Remote(config, integrationObj, this);
}
if (entity == nullptr) {
qDebug(LOGC) << "Illegal entity type: " << type;
} else {
if (entity == nullptr)
qDebug() << "Illegal entity type : " << type;
else
m_entities.insert(entity->entity_id(), entity);
}
}

void Entities::update(const QString &entity_id, const QVariantMap& attributes)
{
Entity *e = static_cast<Entity*>(m_entities.value(entity_id));
if (e == nullptr)
qDebug(LOGC) << "Entity not found: " << entity_id;
qDebug() << "Entity not found : " << entity_id;
else
e->update(attributes);
}
@@ -155,42 +160,35 @@ QList<QObject *> Entities::mediaplayersPlaying()

void Entities::addMediaplayersPlaying(const QString &entity_id)
{
qDebug(LOGC) << "Add media player requested";
// check if there is a timer active to remove the media player
QTimer* timer = nullptr;
timer = m_mediaplayersTimers.value(entity_id);
if (timer != nullptr) {
QTimer* timer = m_mediaplayersTimers.value(entity_id);
if (timer) {
timer->stop();
}

QObject *o = nullptr;
o = m_entities.value(entity_id);
QObject *o = m_entities.value(entity_id);

if (!m_mediaplayersPlaying.contains(entity_id) && o != nullptr) {
if (!m_mediaplayersPlaying.contains(entity_id)) {
m_mediaplayersPlaying.insert(entity_id, o);
qDebug(LOGC) << "Media player added, emitting mediaplayersPlayingChanged";
emit mediaplayersPlayingChanged();;
emit mediaplayersPlayingChanged();
emit mediaplayerAdded();
}
}

void Entities::removeMediaplayersPlaying(const QString &entity_id)
{
if (m_mediaplayersPlaying.contains(entity_id)) {
qDebug(LOGC) << "Remove media player requested";

// use a timer to remove the entity with a delay
QTimer* timer = new QTimer();
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, this, [=](){
m_mediaplayersPlaying.remove(entity_id);
qDebug(LOGC) << "Timer done, emitting mediaplayersPlayingChanged";
emit mediaplayersPlayingChanged();
emit mediaplayersPlayingChanged();
});
qDebug(LOGC) << "Timer created, connected";
timer->start(120000);

qDebug(LOGC) << "Timer added to m_mediaplayersTimers";
m_mediaplayersTimers.insert(entity_id, timer);
}
}
@@ -53,6 +53,8 @@ class Entities : public QObject , EntitiesInterface
// update an entity
Q_INVOKABLE void update (const QString& entity_id, const QVariantMap& attributes);

EntityInterface* getInterface (const QString& entity_id);

QStringList supported_entities () { return m_supported_entities; }
QStringList supported_entities_translation () { return m_supported_entities_translation; }
QStringList loaded_entities () { return m_loaded_entities; }
@@ -2,12 +2,12 @@
#define ENTITIESINTERFACE_H

#include <QVariant>

#include "entityinterface.h"
/// This interface is implemented by the Entities object and used by integration DLLs to access the entities
class EntitiesInterface
{
public:
virtual ~EntitiesInterface() {}
virtual ~EntitiesInterface ();

virtual QList<QObject *> list () = 0;

@@ -25,6 +25,9 @@ class EntitiesInterface

// update an entity's attributes
virtual void update (const QString& entity_id, const QVariantMap& attributes) = 0;

// get entity interface by entity_id
virtual EntityInterface* getInterface(const QString& entity_id) = 0;
};

QT_BEGIN_NAMESPACE

0 comments on commit d6b8fa1

Please sign in to comment.
You can’t perform that action at this time.