mirror of https://github.com/nymea/nymea.git
more work
parent
f132c6b006
commit
3296d4b417
|
|
@ -7,6 +7,7 @@
|
||||||
#include "pyutils.h"
|
#include "pyutils.h"
|
||||||
|
|
||||||
#include "types/param.h"
|
#include "types/param.h"
|
||||||
|
#include "types/paramtype.h"
|
||||||
|
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
|
|
@ -99,7 +100,7 @@ static PyParam* PyParam_fromParam(const Param ¶m)
|
||||||
|
|
||||||
static Param PyParam_ToParam(PyParam *pyParam)
|
static Param PyParam_ToParam(PyParam *pyParam)
|
||||||
{
|
{
|
||||||
ParamTypeId paramTypeId = ParamTypeId(PyUnicode_AsUTF8(pyParam->pyParamTypeId));
|
ParamTypeId paramTypeId = ParamTypeId(PyUnicode_AsUTF8AndSize(pyParam->pyParamTypeId, nullptr));
|
||||||
QVariant value = PyObjectToQVariant(pyParam->pyValue);
|
QVariant value = PyObjectToQVariant(pyParam->pyValue);
|
||||||
return Param(paramTypeId, value);
|
return Param(paramTypeId, value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
|
@ -26,7 +25,7 @@
|
||||||
* So we must never directly access anything of it in here.
|
* So we must never directly access anything of it in here.
|
||||||
*
|
*
|
||||||
* For writing to it, invoking methods with QueuedConnections will thread-decouple stuff.
|
* For writing to it, invoking methods with QueuedConnections will thread-decouple stuff.
|
||||||
* Make sure to lock the self->mutex while using the pointer to it for invoking stuff.
|
* Make sure to hold the GIL whenver accessing the pointer value for invoking stuff.
|
||||||
*
|
*
|
||||||
* For reading access, we keep copies of the thing properties here and sync them
|
* For reading access, we keep copies of the thing properties here and sync them
|
||||||
* over to the according py* members when they change.
|
* over to the according py* members when they change.
|
||||||
|
|
@ -37,7 +36,7 @@
|
||||||
typedef struct _thing {
|
typedef struct _thing {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
Thing *thing = nullptr; // the actual thing in nymea (not thread-safe!)
|
Thing *thing = nullptr; // the actual thing in nymea (not thread-safe!)
|
||||||
QMutex *mutex = nullptr; // The mutex for accessing the thing pointer
|
ThingClass *thingClass = nullptr; // A copy of the thing class. This is owned by the python thread
|
||||||
PyObject *pyId = nullptr;
|
PyObject *pyId = nullptr;
|
||||||
PyObject *pyThingClassId = nullptr;
|
PyObject *pyThingClassId = nullptr;
|
||||||
PyObject *pyName = nullptr;
|
PyObject *pyName = nullptr;
|
||||||
|
|
@ -55,7 +54,6 @@ static PyObject* PyThing_new(PyTypeObject *type, PyObject */*args*/, PyObject */
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
qWarning() << "*++++ PyThing" << self;
|
qWarning() << "*++++ PyThing" << self;
|
||||||
self->mutex = new QMutex();
|
|
||||||
|
|
||||||
return (PyObject*)self;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +62,9 @@ static void PyThing_setThing(PyThing *self, Thing *thing)
|
||||||
{
|
{
|
||||||
self->thing = thing;
|
self->thing = thing;
|
||||||
|
|
||||||
|
// Creating a copy because we cannot access the actual thing from the python thread
|
||||||
|
self->thingClass = new ThingClass(thing->thingClass());
|
||||||
|
|
||||||
self->pyId = PyUnicode_FromString(self->thing->id().toString().toUtf8().data());
|
self->pyId = PyUnicode_FromString(self->thing->id().toString().toUtf8().data());
|
||||||
self->pyThingClassId = PyUnicode_FromString(self->thing->thingClassId().toString().toUtf8().data());
|
self->pyThingClassId = PyUnicode_FromString(self->thing->thingClassId().toString().toUtf8().data());
|
||||||
self->pyName = PyUnicode_FromString(self->thing->name().toUtf8().data());
|
self->pyName = PyUnicode_FromString(self->thing->name().toUtf8().data());
|
||||||
|
|
@ -106,6 +107,24 @@ static void PyThing_setThing(PyThing *self, Thing *thing)
|
||||||
}
|
}
|
||||||
PyGILState_Release(s);
|
PyGILState_Release(s);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QObject::connect(thing, &Thing::stateValueChanged, [=](const StateTypeId &stateTypeId, const QVariant &value){
|
||||||
|
PyGILState_STATE s = PyGILState_Ensure();
|
||||||
|
for (int i = 0; i < PyList_Size(self->pyStates); i++) {
|
||||||
|
PyObject *pyState = PyList_GetItem(self->pyStates, i);
|
||||||
|
PyObject *pyStateTypeId = PyDict_GetItemString(pyState, "stateTypeId");
|
||||||
|
StateTypeId stid = StateTypeId(PyUnicode_AsUTF8AndSize(pyStateTypeId, nullptr));
|
||||||
|
if (stid == stateTypeId) {
|
||||||
|
qWarning() << "Updating state" << stateTypeId << value;
|
||||||
|
pyState = Py_BuildValue("{s:s, s:O}",
|
||||||
|
"stateTypeId", stateTypeId.toString().toUtf8().data(),
|
||||||
|
"value", QVariantToPyObject(value));
|
||||||
|
PyList_SetItem(self->pyStates, i, pyState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyGILState_Release(s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -119,8 +138,8 @@ static void PyThing_dealloc(PyThing * self) {
|
||||||
Py_XDECREF(self->pyStates);
|
Py_XDECREF(self->pyStates);
|
||||||
Py_XDECREF(self->pyNameChangedHandler);
|
Py_XDECREF(self->pyNameChangedHandler);
|
||||||
Py_XDECREF(self->pySettingChangedHandler);
|
Py_XDECREF(self->pySettingChangedHandler);
|
||||||
delete self->mutex;
|
delete self->thingClass;
|
||||||
Py_TYPE(self)->tp_free(self);
|
Py_TYPE(self)->tp_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *PyThing_getName(PyThing *self, void */*closure*/)
|
static PyObject *PyThing_getName(PyThing *self, void */*closure*/)
|
||||||
|
|
@ -143,7 +162,6 @@ static PyObject *PyThing_getThingClassId(PyThing *self, void */*closure*/)
|
||||||
|
|
||||||
static int PyThing_setName(PyThing *self, PyObject *value, void */*closure*/){
|
static int PyThing_setName(PyThing *self, PyObject *value, void */*closure*/){
|
||||||
QString name = QString(PyUnicode_AsUTF8(value));
|
QString name = QString(PyUnicode_AsUTF8(value));
|
||||||
QMutexLocker(self->mutex);
|
|
||||||
if (!self->thing) {
|
if (!self->thing) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +169,74 @@ static int PyThing_setName(PyThing *self, PyObject *value, void */*closure*/){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject * PyThing_paramValue(PyThing* self, PyObject* args)
|
||||||
|
{
|
||||||
|
char *paramTypeIdStr = nullptr;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", ¶mTypeIdStr)) {
|
||||||
|
qCWarning(dcThingManager) << "Error parsing parameters";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParamTypeId paramTypeId = ParamTypeId(paramTypeIdStr);
|
||||||
|
PyObject *iterator = PyObject_GetIter(self->pyParams);
|
||||||
|
while (iterator) {
|
||||||
|
PyObject *pyParam = PyIter_Next(iterator);
|
||||||
|
if (!pyParam) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Param param = PyParam_ToParam((PyParam*)pyParam);
|
||||||
|
Py_DECREF(pyParam);
|
||||||
|
|
||||||
|
if (param.paramTypeId() != paramTypeId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
|
||||||
|
return QVariantToPyObject(param.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
qCWarning(dcPythonIntegrations()) << "No param for paramTypeId:" << paramTypeId;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject * PyThing_setting(PyThing* self, PyObject* args)
|
||||||
|
{
|
||||||
|
char *paramTypeIdStr = nullptr;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", ¶mTypeIdStr)) {
|
||||||
|
qCWarning(dcThingManager) << "Error parsing parameters";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParamTypeId paramTypeId = ParamTypeId(paramTypeIdStr);
|
||||||
|
PyObject *iterator = PyObject_GetIter(self->pySettings);
|
||||||
|
while (iterator) {
|
||||||
|
PyObject *pyParam = PyIter_Next(iterator);
|
||||||
|
if (!pyParam) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Param param = PyParam_ToParam((PyParam*)pyParam);
|
||||||
|
Py_DECREF(pyParam);
|
||||||
|
|
||||||
|
if (param.paramTypeId() != paramTypeId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
|
||||||
|
return QVariantToPyObject(param.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(iterator);
|
||||||
|
qCWarning(dcPythonIntegrations()) << "No setting for paramTypeId:" << paramTypeId;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *PyThing_getSettings(PyThing *self, void */*closure*/)
|
static PyObject *PyThing_getSettings(PyThing *self, void */*closure*/)
|
||||||
{
|
{
|
||||||
Py_INCREF(self->pySettings);
|
Py_INCREF(self->pySettings);
|
||||||
|
|
@ -167,42 +253,25 @@ static PyObject * PyThing_stateValue(PyThing* self, PyObject* args)
|
||||||
char *stateTypeIdStr = nullptr;
|
char *stateTypeIdStr = nullptr;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &stateTypeIdStr)) {
|
if (!PyArg_ParseTuple(args, "s", &stateTypeIdStr)) {
|
||||||
qCWarning(dcThingManager) << "Error parsing parameters";
|
PyErr_SetString(PyExc_ValueError, "Error parsing arguments. Signature is 's'");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateTypeId stateTypeId = StateTypeId(stateTypeIdStr);
|
StateTypeId stateTypeId = StateTypeId(stateTypeIdStr);
|
||||||
PyObject *iterator = PyObject_GetIter(self->pyStates);
|
|
||||||
while (iterator) {
|
|
||||||
PyObject *pyState = PyIter_Next(iterator);
|
|
||||||
if (!pyState) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (int i = 0; i < PyList_Size(self->pyStates); i++) {
|
||||||
|
PyObject *pyState = PyList_GetItem(self->pyStates, i);
|
||||||
PyObject *pyStateTypeId = PyDict_GetItemString(pyState, "stateTypeId");
|
PyObject *pyStateTypeId = PyDict_GetItemString(pyState, "stateTypeId");
|
||||||
PyObject *tmp = PyUnicode_AsEncodedString(pyStateTypeId, "UTF-8", "strict");
|
StateTypeId stid = StateTypeId(PyUnicode_AsUTF8AndSize(pyStateTypeId, nullptr));
|
||||||
|
if (stid == stateTypeId) {
|
||||||
StateTypeId stid = StateTypeId(PyBytes_AS_STRING(tmp));
|
PyObject *value = PyDict_GetItemString(pyState, "value");
|
||||||
|
Py_INCREF(value);
|
||||||
Py_DECREF(pyStateTypeId);
|
return value;
|
||||||
Py_XDECREF(tmp);
|
|
||||||
|
|
||||||
if (stid != stateTypeId) {
|
|
||||||
Py_DECREF(pyState);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *pyStateValue = PyDict_GetItemString(pyState, "value");
|
|
||||||
|
|
||||||
Py_DECREF(pyState);
|
|
||||||
Py_DECREF(iterator);
|
|
||||||
|
|
||||||
return pyStateValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(iterator);
|
PyErr_SetString(PyExc_ValueError, QString("No state type %1 in thing class %2").arg(stateTypeId.toString()).arg(self->thingClass->name()).toUtf8());
|
||||||
qCWarning(dcPythonIntegrations()) << "No state for stateTypeId:" << stateTypeId;
|
return nullptr;
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
||||||
|
|
@ -211,14 +280,18 @@ static PyObject * PyThing_setStateValue(PyThing* self, PyObject* args)
|
||||||
PyObject *valueObj = nullptr;
|
PyObject *valueObj = nullptr;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sO", &stateTypeIdStr, &valueObj)) {
|
if (!PyArg_ParseTuple(args, "sO", &stateTypeIdStr, &valueObj)) {
|
||||||
qCWarning(dcThingManager) << "Error parsing parameters";
|
PyErr_SetString(PyExc_ValueError, "Error parsing arguments. Signature is 'sO'");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateTypeId stateTypeId = StateTypeId(stateTypeIdStr);
|
StateTypeId stateTypeId = StateTypeId(stateTypeIdStr);
|
||||||
|
StateType stateType = self->thingClass->stateTypes().findById(stateTypeId);
|
||||||
|
if (!stateType.isValid()) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, QString("No state type %1 in thing class %2").arg(stateTypeId.toString()).arg(self->thingClass->name()).toUtf8());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
QVariant value = PyObjectToQVariant(valueObj);
|
QVariant value = PyObjectToQVariant(valueObj);
|
||||||
|
|
||||||
QMutexLocker(self->mutex);
|
|
||||||
if (self->thing != nullptr) {
|
if (self->thing != nullptr) {
|
||||||
QMetaObject::invokeMethod(self->thing, "setStateValue", Qt::QueuedConnection, Q_ARG(StateTypeId, stateTypeId), Q_ARG(QVariant, value));
|
QMetaObject::invokeMethod(self->thing, "setStateValue", Qt::QueuedConnection, Q_ARG(StateTypeId, stateTypeId), Q_ARG(QVariant, value));
|
||||||
}
|
}
|
||||||
|
|
@ -232,14 +305,23 @@ static PyObject * PyThing_emitEvent(PyThing* self, PyObject* args)
|
||||||
PyObject *valueObj = nullptr;
|
PyObject *valueObj = nullptr;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s|O", &eventTypeIdStr, &valueObj)) {
|
if (!PyArg_ParseTuple(args, "s|O", &eventTypeIdStr, &valueObj)) {
|
||||||
qCWarning(dcThingManager) << "Error parsing parameters";
|
PyErr_SetString(PyExc_TypeError, "Supplied arguments for emitEvent must be a ParamList");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (qstrcmp(valueObj->ob_type->tp_name, "list") != 0) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Supplied arguments for emitEvent must be a ParamList");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventTypeId eventTypeId = EventTypeId(eventTypeIdStr);
|
EventTypeId eventTypeId = EventTypeId(eventTypeIdStr);
|
||||||
|
EventType eventType = self->thingClass->eventTypes().findById(eventTypeId);
|
||||||
|
if (!eventType.isValid()) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, QString("No event type %1 in thing class %2").arg(eventTypeId.toString()).arg(self->thingClass->name()).toUtf8());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
ParamList params = PyParams_ToParamList(valueObj);
|
ParamList params = PyParams_ToParamList(valueObj);
|
||||||
|
|
||||||
QMutexLocker(self->mutex);
|
|
||||||
if (self->thing != nullptr) {
|
if (self->thing != nullptr) {
|
||||||
QMetaObject::invokeMethod(self->thing, "emitEvent", Qt::QueuedConnection, Q_ARG(EventTypeId, eventTypeId), Q_ARG(ParamList, params));
|
QMetaObject::invokeMethod(self->thing, "emitEvent", Qt::QueuedConnection, Q_ARG(EventTypeId, eventTypeId), Q_ARG(ParamList, params));
|
||||||
}
|
}
|
||||||
|
|
@ -256,9 +338,11 @@ static PyGetSetDef PyThing_getset[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef PyThing_methods[] = {
|
static PyMethodDef PyThing_methods[] = {
|
||||||
{ "stateValue", (PyCFunction)PyThing_stateValue, METH_VARARGS, "Get a things state value by stateTypeId" },
|
{ "paramValue", (PyCFunction)PyThing_paramValue, METH_VARARGS, "Get a things param value by paramTypeId" },
|
||||||
{ "setStateValue", (PyCFunction)PyThing_setStateValue, METH_VARARGS, "Set a certain things state value by stateTypeIp" },
|
{ "setting", (PyCFunction)PyThing_setting, METH_VARARGS, "Get a things setting value by paramTypeId" },
|
||||||
{ "emitEvent", (PyCFunction)PyThing_emitEvent, METH_VARARGS, "Emits an event" },
|
{ "stateValue", (PyCFunction)PyThing_stateValue, METH_VARARGS, "Get a things state value by stateTypeId" },
|
||||||
|
{ "setStateValue", (PyCFunction)PyThing_setStateValue, METH_VARARGS, "Set a certain things state value by stateTypeIp" },
|
||||||
|
{ "emitEvent", (PyCFunction)PyThing_emitEvent, METH_VARARGS, "Emits an event" },
|
||||||
{nullptr, nullptr, 0, nullptr} // sentinel
|
{nullptr, nullptr, 0, nullptr} // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,18 +45,21 @@ PyObject *QVariantToPyObject(const QVariant &value)
|
||||||
|
|
||||||
QVariant PyObjectToQVariant(PyObject *pyObject)
|
QVariant PyObjectToQVariant(PyObject *pyObject)
|
||||||
{
|
{
|
||||||
// FIXME: is there any better way to do this?
|
qWarning() << "**************** type" << pyObject->ob_type->tp_name;
|
||||||
qWarning() << "Error:" << PyErr_CheckSignals();
|
|
||||||
PyObject* repr = PyObject_Repr(pyObject);
|
|
||||||
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
|
|
||||||
const char *bytes = PyBytes_AS_STRING(str);
|
|
||||||
|
|
||||||
QVariant value(bytes);
|
if (qstrcmp(pyObject->ob_type->tp_name, "int") == 0) {
|
||||||
|
return QVariant(PyLong_AsLongLong(pyObject));
|
||||||
|
}
|
||||||
|
|
||||||
Py_XDECREF(repr);
|
if (qstrcmp(pyObject->ob_type->tp_name, "str") == 0) {
|
||||||
Py_XDECREF(str);
|
return QVariant(PyUnicode_AsUTF8AndSize(pyObject, nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
if (qstrcmp(pyObject->ob_type->tp_name, "double") == 0) {
|
||||||
|
return QVariant(PyFloat_AsDouble(pyObject));
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, "pyutils.h", "Unhandled data type in conversion from Param to PyParam!");
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ void ParamTypes::put(const QVariant &variant)
|
||||||
append(variant.value<ParamType>());
|
append(variant.value<ParamType>());
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamType ParamTypes::findByName(const QString &name)
|
ParamType ParamTypes::findByName(const QString &name) const
|
||||||
{
|
{
|
||||||
foreach (const ParamType ¶mType, *this) {
|
foreach (const ParamType ¶mType, *this) {
|
||||||
if (paramType.name() == name) {
|
if (paramType.name() == name) {
|
||||||
|
|
@ -282,7 +282,7 @@ ParamType ParamTypes::findByName(const QString &name)
|
||||||
return ParamType();
|
return ParamType();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamType ParamTypes::findById(const ParamTypeId &id)
|
ParamType ParamTypes::findById(const ParamTypeId &id) const
|
||||||
{
|
{
|
||||||
foreach (const ParamType ¶mType, *this) {
|
foreach (const ParamType ¶mType, *this) {
|
||||||
if (paramType.id() == id) {
|
if (paramType.id() == id) {
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ public:
|
||||||
ParamTypes(const QList<ParamType> &other);
|
ParamTypes(const QList<ParamType> &other);
|
||||||
Q_INVOKABLE QVariant get(int index) const;
|
Q_INVOKABLE QVariant get(int index) const;
|
||||||
Q_INVOKABLE void put(const QVariant &variant);
|
Q_INVOKABLE void put(const QVariant &variant);
|
||||||
ParamType findByName(const QString &name);
|
ParamType findByName(const QString &name) const;
|
||||||
ParamType findById(const ParamTypeId &id);
|
ParamType findById(const ParamTypeId &id) const;
|
||||||
};
|
};
|
||||||
Q_DECLARE_METATYPE(QList<ParamType>)
|
Q_DECLARE_METATYPE(QList<ParamType>)
|
||||||
Q_DECLARE_METATYPE(ParamTypes)
|
Q_DECLARE_METATYPE(ParamTypes)
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
int m_index = 0;
|
int m_index = 0;
|
||||||
QVariant::Type m_type;
|
QVariant::Type m_type = QVariant::Invalid;
|
||||||
QVariant m_defaultValue;
|
QVariant m_defaultValue;
|
||||||
QVariant m_minValue;
|
QVariant m_minValue;
|
||||||
QVariant m_maxValue;
|
QVariant m_maxValue;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"name": "autoThingCount",
|
"name": "autoThingCount",
|
||||||
"displayName": "Number of auto things",
|
"displayName": "Number of auto things",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"defaultValue": "fds"
|
"defaultValue": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"vendors": [
|
"vendors": [
|
||||||
|
|
@ -94,6 +94,21 @@
|
||||||
"defaultValue": "hello"
|
"defaultValue": "hello"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"eventTypes": [
|
||||||
|
{
|
||||||
|
"id": "e6b98ef6-7922-48e6-b508-238d178b86ca",
|
||||||
|
"name": "event1",
|
||||||
|
"displayName": "Event 1",
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "7c265a6a-f0ae-4822-a14f-e6a090f5a310",
|
||||||
|
"name": "param1",
|
||||||
|
"displayName": "Event param 1",
|
||||||
|
"type": "QString"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"stateTypes": [
|
"stateTypes": [
|
||||||
{
|
{
|
||||||
"id": "99d0af17-9e8c-42bb-bece-a5d114f051d3",
|
"id": "99d0af17-9e8c-42bb-bece-a5d114f051d3",
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,19 @@ import asyncio
|
||||||
|
|
||||||
watchingAutoThings = False
|
watchingAutoThings = False
|
||||||
|
|
||||||
def init():
|
async def init():
|
||||||
logger.log("Python mock plugin init")
|
logger.log("Python mock plugin init")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
await asyncio.sleep(2);
|
||||||
|
logger.log("Updating stuff")
|
||||||
|
for thing in myThings():
|
||||||
|
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
|
||||||
|
logger.log("Emitting event 1 for", thing.name)
|
||||||
|
# thing.emitEvent(pyMockDiscoveryPairingEvent1EventTypeId, [nymea.Param(pyMockDiscoveryPairingEvent1EventParam1ParamTypeId, "Im an event")])
|
||||||
|
logger.log("Setting state 1 for", thing.name, "Old value is:", thing.stateValue(pyMockDiscoveryPairingState1StateTypeId))
|
||||||
|
thing.setStateValue(pyMockDiscoveryPairingState1StateTypeId, thing.stateValue(pyMockDiscoveryPairingState1StateTypeId) + 1)
|
||||||
|
|
||||||
|
|
||||||
def configValueChanged(paramTypeId, value):
|
def configValueChanged(paramTypeId, value):
|
||||||
logger.log("Plugin config value changed:", paramTypeId, value, watchingAutoThings)
|
logger.log("Plugin config value changed:", paramTypeId, value, watchingAutoThings)
|
||||||
|
|
@ -74,7 +84,7 @@ async def setupThing(info):
|
||||||
info.finish(nymea.ThingErrorNoError)
|
info.finish(nymea.ThingErrorNoError)
|
||||||
|
|
||||||
|
|
||||||
def postSetupThing(thing):
|
async def postSetupThing(thing):
|
||||||
logger.log("postSetupThing for", thing.name, thing.params[0].value)
|
logger.log("postSetupThing for", thing.name, thing.params[0].value)
|
||||||
thing.nameChangedHandler = lambda thing : logger.log("Thing name changed", thing.name)
|
thing.nameChangedHandler = lambda thing : logger.log("Thing name changed", thing.name)
|
||||||
|
|
||||||
|
|
@ -82,7 +92,9 @@ def postSetupThing(thing):
|
||||||
logger.log("State 1 value:", thing.stateValue(pyMockAutoState1StateTypeId))
|
logger.log("State 1 value:", thing.stateValue(pyMockAutoState1StateTypeId))
|
||||||
|
|
||||||
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
|
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
|
||||||
logger.log("Setting 1 value:", thing.settingsValue(pyMockDiscoveryPairingSettingsSetting1ParamTypeId))
|
logger.log("Param 1 value:", thing.paramValue(pyMockDiscoveryPairingThingParam1ParamTypeId))
|
||||||
|
logger.log("Setting 1 value:", thing.setting(pyMockDiscoveryPairingSettingsSetting1ParamTypeId))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def autoThings():
|
def autoThings():
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue