some more work

This commit is contained in:
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 { typedef struct {
PyObject_HEAD PyObject_HEAD
ThingDiscoveryInfo* info; ThingDiscoveryInfo* info;
// PyObject* pyThingClassId = nullptr; PyObject* pyThingClassId = nullptr;
// PyObject *pyParams = nullptr; PyObject *pyParams = nullptr;
} PyThingDiscoveryInfo; } PyThingDiscoveryInfo;
static PyObject* PyThingDiscoveryInfo_new(PyTypeObject *type, PyObject */*args*/, PyObject */*kwds*/) 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) void PyThingDiscoveryInfo_setInfo(PyThingDiscoveryInfo *self, ThingDiscoveryInfo *info)
{ {
self->info = info; self->info = info;
// self->pyThingClassId = PyUnicode_FromString(info->thingClassId().toString().toUtf8().data()); self->pyThingClassId = PyUnicode_FromString(info->thingClassId().toString().toUtf8().data());
// self->pyParams = PyParams_FromParamList(info->params()); self->pyParams = PyParams_FromParamList(info->params());
} }
static void PyThingDiscoveryInfo_dealloc(PyThingDiscoveryInfo * self) static void PyThingDiscoveryInfo_dealloc(PyThingDiscoveryInfo * self)
{ {
qWarning() << "---- PyThingDiscoveryInfo"; qWarning() << "---- PyThingDiscoveryInfo";
// Py_DECREF(self->pyThingClassId); Py_DECREF(self->pyThingClassId);
// Py_DECREF(self->pyParams); Py_DECREF(self->pyParams);
Py_TYPE(self)->tp_free(self); 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)); QMetaObject::invokeMethod(self->info, "addThingDescriptor", Qt::QueuedConnection, Q_ARG(ThingDescriptor, descriptor));
} }
Py_DECREF(pyDescriptor);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
//static PyMemberDef PyThingDiscoveryInfo_members[] = { static PyMemberDef PyThingDiscoveryInfo_members[] = {
// {"thingClassId", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyThingClassId), READONLY, "The ThingClassId this discovery is for."}, {"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"}, {"params", T_OBJECT_EX, offsetof(PyThingDiscoveryInfo, pyParams), READONLY, "The params for this discovery"},
// {nullptr, 0, 0, 0, nullptr} /* Sentinel */ {nullptr, 0, 0, 0, nullptr} /* Sentinel */
//}; };
static PyMethodDef PyThingDiscoveryInfo_methods[] = { static PyMethodDef PyThingDiscoveryInfo_methods[] = {
{ "addDescriptor", (PyCFunction)PyThingDiscoveryInfo_addDescriptor, METH_VARARGS, "Add a new descriptor to the discovery" }, { "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_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
PyThingDiscoveryInfo_methods, /* tp_methods */ PyThingDiscoveryInfo_methods, /* tp_methods */
0, //PyThingDiscoveryInfo_members, /* tp_members */ PyThingDiscoveryInfo_members, /* tp_members */
0, /* tp_getset */ 0, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */

View File

@ -316,6 +316,10 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
return false; return false;
} }
// PyThreadState *m_thread = Py_NewInterpreter();
// PyInterpreterState *m_interpreter = PyInterpreterState_New();
// PyEval_RestoreThread(s_mainThread);
PyGILState_STATE s = PyGILState_Ensure(); PyGILState_STATE s = PyGILState_Ensure();
// Finally, import the plugin // Finally, import the plugin
@ -329,6 +333,7 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
qCWarning(dcThingManager()) << "Error importing python plugin from:" << fi.absoluteFilePath(); qCWarning(dcThingManager()) << "Error importing python plugin from:" << fi.absoluteFilePath();
PyErr_Print(); PyErr_Print();
PyErr_Clear(); PyErr_Clear();
// PyEval_SaveThread();
PyGILState_Release(s); PyGILState_Release(s);
return false; return false;
} }
@ -352,6 +357,7 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
// Register config access methods // Register config access methods
PyModule_AddFunctions(m_module, plugin_methods); PyModule_AddFunctions(m_module, plugin_methods);
// PyEval_SaveThread();
PyGILState_Release(s); PyGILState_Release(s);
// Set up connections to be forwareded into the plugin // 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) bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObject *param1, PyObject *param2, PyObject *param3)
{ {
PyGILState_STATE s = PyGILState_Ensure(); PyGILState_STATE s = PyGILState_Ensure();
// PyEval_RestoreThread(s_mainThread);
qCDebug(dcThingManager()) << "Calling python plugin function" << function << "on plugin" << pluginName(); qCDebug(dcThingManager()) << "Calling python plugin function" << function << "on plugin" << pluginName();
PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8()); PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8());
@ -668,6 +675,7 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
Py_XDECREF(pFunc); Py_XDECREF(pFunc);
qCWarning(dcThingManager()) << "Python plugin" << pluginName() << "does not implement" << function; qCWarning(dcThingManager()) << "Python plugin" << pluginName() << "does not implement" << function;
PyGILState_Release(s); PyGILState_Release(s);
// PyEval_SaveThread();
return false; return false;
} }
@ -680,12 +688,14 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
qCWarning(dcThingManager()) << "Error calling python method:" << function << "on plugin" << pluginName(); qCWarning(dcThingManager()) << "Error calling python method:" << function << "on plugin" << pluginName();
PyErr_Print(); PyErr_Print();
PyErr_Clear(); PyErr_Clear();
// PyEval_SaveThread();
PyGILState_Release(s); PyGILState_Release(s);
return false; return false;
} }
if (QByteArray(result->ob_type->tp_name) != "coroutine") { if (QByteArray(result->ob_type->tp_name) != "coroutine") {
Py_DECREF(result); Py_DECREF(result);
// PyEval_SaveThread();
PyGILState_Release(s); PyGILState_Release(s);
return true; return true;
} }
@ -710,19 +720,26 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
dumpError(); dumpError();
PyObject *run_until_complete = PyObject_GetAttrString(loop, "run_until_complete"); PyObject *run_until_complete = PyObject_GetAttrString(loop, "run_until_complete");
QtConcurrent::run([=](){ QtConcurrent::run([run_until_complete, task, loop, result](){
PyGILState_STATE s = PyGILState_Ensure(); PyGILState_STATE g = PyGILState_Ensure();
// auto s = PyThreadState_New(PyInterpreterState_Main());
// PyThreadState *previousThreadState = PyThreadState_Swap(s);
PyObject_CallFunctionObjArgs(run_until_complete, task, nullptr); 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(create_task);
Py_DECREF(task);
Py_DECREF(add_done_callback); Py_DECREF(add_done_callback);
Py_DECREF(result);
PyGILState_Release(s); PyGILState_Release(s);
// PyEval_SaveThread();
return true; return true;
} }

View File

@ -85,6 +85,15 @@
"defaultValue": 0 "defaultValue": 0
} }
], ],
"settingsTypes": [
{
"id": "d2312d00-22f5-4e2c-a6cc-8e4cade2d58b",
"name": "setting1",
"displayName": "Setting 1",
"type": "QString",
"defaultValue": "hello"
}
],
"stateTypes": [ "stateTypes": [
{ {
"id": "99d0af17-9e8c-42bb-bece-a5d114f051d3", "id": "99d0af17-9e8c-42bb-bece-a5d114f051d3",

View File

@ -41,25 +41,17 @@ def startMonitoringAutoThings():
async def discoverThings(info): async def discoverThings(info):
logger.log("Discovery started for") #, info.thingClassId, "with result count:") #, info.params[0].value) logger.log("Discovery started for", info.thingClassId, "with result count:", info.params[0].value)
logger.log("a")
await asyncio.sleep(1) # Some delay for giving a feeling of a discovery await asyncio.sleep(1) # Some delay for giving a feeling of a discovery
# Add 2 new discovery results # Add 2 new discovery results
logger.log("b") for i in range(0, info.params[0].value):
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing 1")) info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing %i" % i))
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, "Python mock thing 2"))
logger.log("c")
# Also add existing ones again so reconfiguration is possible # Also add existing ones again so reconfiguration is possible
for thing in myThings(): for thing in myThings():
logger.log("d")
if thing.thingClassId == pyMockDiscoveryPairingThingClassId: if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
logger.log("e")
info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, thing.name, thingId=thing.id)) info.addDescriptor(nymea.ThingDescriptor(pyMockDiscoveryPairingThingClassId, thing.name, thingId=thing.id))
logger.log("f")
logger.log("g")
info.finish(nymea.ThingErrorNoError) info.finish(nymea.ThingErrorNoError)
logger.log("h")
async def startPairing(info): async def startPairing(info):
@ -89,6 +81,9 @@ def postSetupThing(thing):
if thing.thingClassId == pyMockAutoThingClassId: if thing.thingClassId == pyMockAutoThingClassId:
logger.log("State 1 value:", thing.stateValue(pyMockAutoState1StateTypeId)) logger.log("State 1 value:", thing.stateValue(pyMockAutoState1StateTypeId))
if thing.thingClassId == pyMockDiscoveryPairingThingClassId:
logger.log("Setting 1 value:", thing.settingsValue(pyMockDiscoveryPairingSettingsSetting1ParamTypeId))
def autoThings(): def autoThings():
autoThings = [] autoThings = []