mirror of https://github.com/nymea/nymea.git
some more work
parent
0cbd1ff5ec
commit
f132c6b006
|
|
@ -39,8 +39,8 @@
|
|||
typedef struct {
|
||||
PyObject_HEAD
|
||||
ThingDiscoveryInfo* info;
|
||||
// PyObject* pyThingClassId = nullptr;
|
||||
// PyObject *pyParams = nullptr;
|
||||
PyObject* pyThingClassId = nullptr;
|
||||
PyObject *pyParams = nullptr;
|
||||
} PyThingDiscoveryInfo;
|
||||
|
||||
static PyObject* PyThingDiscoveryInfo_new(PyTypeObject *type, PyObject */*args*/, PyObject */*kwds*/)
|
||||
|
|
@ -56,15 +56,15 @@ static PyObject* PyThingDiscoveryInfo_new(PyTypeObject *type, PyObject */*args*/
|
|||
void PyThingDiscoveryInfo_setInfo(PyThingDiscoveryInfo *self, ThingDiscoveryInfo *info)
|
||||
{
|
||||
self->info = info;
|
||||
// self->pyThingClassId = PyUnicode_FromString(info->thingClassId().toString().toUtf8().data());
|
||||
// self->pyParams = PyParams_FromParamList(info->params());
|
||||
self->pyThingClassId = PyUnicode_FromString(info->thingClassId().toString().toUtf8().data());
|
||||
self->pyParams = PyParams_FromParamList(info->params());
|
||||
}
|
||||
|
||||
static void PyThingDiscoveryInfo_dealloc(PyThingDiscoveryInfo * self)
|
||||
{
|
||||
qWarning() << "---- PyThingDiscoveryInfo";
|
||||
// Py_DECREF(self->pyThingClassId);
|
||||
// Py_DECREF(self->pyParams);
|
||||
Py_DECREF(self->pyThingClassId);
|
||||
Py_DECREF(self->pyParams);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
|
|
@ -127,15 +127,14 @@ static PyObject * PyThingDiscoveryInfo_addDescriptor(PyThingDiscoveryInfo* self,
|
|||
QMetaObject::invokeMethod(self->info, "addThingDescriptor", Qt::QueuedConnection, Q_ARG(ThingDescriptor, descriptor));
|
||||
}
|
||||
|
||||
Py_DECREF(pyDescriptor);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//static PyMemberDef PyThingDiscoveryInfo_members[] = {
|
||||
// {"thingClassId", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyThingClassId), READONLY, "The ThingClassId this discovery is for."},
|
||||
//// {"params", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyParams), READONLY, "The params for this discovery"},
|
||||
// {nullptr, 0, 0, 0, nullptr} /* Sentinel */
|
||||
//};
|
||||
static PyMemberDef PyThingDiscoveryInfo_members[] = {
|
||||
{"thingClassId", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyThingClassId), READONLY, "The ThingClassId this discovery is for."},
|
||||
{"params", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyParams), READONLY, "The params for this discovery"},
|
||||
{nullptr, 0, 0, 0, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyMethodDef PyThingDiscoveryInfo_methods[] = {
|
||||
{ "addDescriptor", (PyCFunction)PyThingDiscoveryInfo_addDescriptor, METH_VARARGS, "Add a new descriptor to the discovery" },
|
||||
|
|
@ -172,7 +171,7 @@ static PyTypeObject PyThingDiscoveryInfoType = {
|
|||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
PyThingDiscoveryInfo_methods, /* tp_methods */
|
||||
0, //PyThingDiscoveryInfo_members, /* tp_members */
|
||||
PyThingDiscoveryInfo_members, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
|
|
|
|||
|
|
@ -316,6 +316,10 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
|||
return false;
|
||||
}
|
||||
|
||||
// PyThreadState *m_thread = Py_NewInterpreter();
|
||||
// PyInterpreterState *m_interpreter = PyInterpreterState_New();
|
||||
|
||||
// PyEval_RestoreThread(s_mainThread);
|
||||
PyGILState_STATE s = PyGILState_Ensure();
|
||||
|
||||
// Finally, import the plugin
|
||||
|
|
@ -329,6 +333,7 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
|||
qCWarning(dcThingManager()) << "Error importing python plugin from:" << fi.absoluteFilePath();
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
// PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -352,6 +357,7 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
|||
// Register config access methods
|
||||
PyModule_AddFunctions(m_module, plugin_methods);
|
||||
|
||||
// PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
|
||||
// Set up connections to be forwareded into the plugin
|
||||
|
|
@ -660,6 +666,7 @@ void PythonIntegrationPlugin::exportBrowserItemActionTypes(const ActionTypes &ac
|
|||
bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObject *param1, PyObject *param2, PyObject *param3)
|
||||
{
|
||||
PyGILState_STATE s = PyGILState_Ensure();
|
||||
// PyEval_RestoreThread(s_mainThread);
|
||||
|
||||
qCDebug(dcThingManager()) << "Calling python plugin function" << function << "on plugin" << pluginName();
|
||||
PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8());
|
||||
|
|
@ -668,6 +675,7 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
|||
Py_XDECREF(pFunc);
|
||||
qCWarning(dcThingManager()) << "Python plugin" << pluginName() << "does not implement" << function;
|
||||
PyGILState_Release(s);
|
||||
// PyEval_SaveThread();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -680,12 +688,14 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
|||
qCWarning(dcThingManager()) << "Error calling python method:" << function << "on plugin" << pluginName();
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
// PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (QByteArray(result->ob_type->tp_name) != "coroutine") {
|
||||
Py_DECREF(result);
|
||||
// PyEval_SaveThread();
|
||||
PyGILState_Release(s);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -710,19 +720,26 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
|||
dumpError();
|
||||
|
||||
PyObject *run_until_complete = PyObject_GetAttrString(loop, "run_until_complete");
|
||||
QtConcurrent::run([=](){
|
||||
PyGILState_STATE s = PyGILState_Ensure();
|
||||
QtConcurrent::run([run_until_complete, task, loop, result](){
|
||||
PyGILState_STATE g = PyGILState_Ensure();
|
||||
// auto s = PyThreadState_New(PyInterpreterState_Main());
|
||||
// PyThreadState *previousThreadState = PyThreadState_Swap(s);
|
||||
PyObject_CallFunctionObjArgs(run_until_complete, task, nullptr);
|
||||
PyGILState_Release(s);
|
||||
Py_DECREF(loop);
|
||||
Py_DECREF(task);
|
||||
Py_DECREF(run_until_complete);
|
||||
Py_DECREF(result);
|
||||
// PyThreadState_Swap(previousThreadState);
|
||||
// PyThreadState_Clear(s);
|
||||
// PyThreadState_Delete(s);
|
||||
PyGILState_Release(g);
|
||||
});
|
||||
|
||||
Py_DECREF(loop);
|
||||
Py_DECREF(create_task);
|
||||
Py_DECREF(task);
|
||||
Py_DECREF(add_done_callback);
|
||||
Py_DECREF(result);
|
||||
|
||||
PyGILState_Release(s);
|
||||
// PyEval_SaveThread();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,15 @@
|
|||
"defaultValue": 0
|
||||
}
|
||||
],
|
||||
"settingsTypes": [
|
||||
{
|
||||
"id": "d2312d00-22f5-4e2c-a6cc-8e4cade2d58b",
|
||||
"name": "setting1",
|
||||
"displayName": "Setting 1",
|
||||
"type": "QString",
|
||||
"defaultValue": "hello"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "99d0af17-9e8c-42bb-bece-a5d114f051d3",
|
||||
|
|
|
|||
|
|
@ -41,25 +41,17 @@ def startMonitoringAutoThings():
|
|||
|
||||
|
||||
async def discoverThings(info):
|
||||
logger.log("Discovery started for") #, info.thingClassId, "with result count:") #, info.params[0].value)
|
||||
logger.log("a")
|
||||
logger.log("Discovery started for", info.thingClassId, "with result count:", info.params[0].value)
|
||||
await asyncio.sleep(1) # Some delay for giving a feeling of a discovery
|
||||
# Add 2 new discovery results
|
||||
logger.log("b")
|
||||
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing 1"))
|
||||
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing 2"))
|
||||
logger.log("c")
|
||||
for i in range(0, info.params[0].value):
|
||||
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing %i" % i))
|
||||
# Also add existing ones again so reconfiguration is possible
|
||||
for thing in myThings():
|
||||
logger.log("d")
|
||||
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
|
||||
logger.log("e")
|
||||
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, thing.name, thingId=thing.id))
|
||||
logger.log("f")
|
||||
|
||||
logger.log("g")
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
logger.log("h")
|
||||
|
||||
|
||||
async def startPairing(info):
|
||||
|
|
@ -89,6 +81,9 @@ def postSetupThing(thing):
|
|||
if thing.thingClassId == pyMockAutoThingClassId:
|
||||
logger.log("State 1 value:", thing.stateValue(pyMockAutoState1StateTypeId))
|
||||
|
||||
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
|
||||
logger.log("Setting 1 value:", thing.settingsValue(pyMockDiscoveryPairingSettingsSetting1ParamTypeId))
|
||||
|
||||
|
||||
def autoThings():
|
||||
autoThings = []
|
||||
|
|
|
|||
Loading…
Reference in New Issue