some more work

pull/341/head
Michael Zanetti 2020-07-05 12:28:25 +02:00
parent 0cbd1ff5ec
commit f132c6b006
4 changed files with 50 additions and 30 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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",

View File

@ -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 = []