Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "py_opcua_subscriptionclient.h"
00012
00013 static std::string parse_python_exception()
00014 {
00015 PyObject * type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL;
00016
00017 PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
00018
00019 std::string ret("Unfetchable Python error");
00020
00021
00022 if (type_ptr != NULL)
00023 {
00024 handle<> h_type(type_ptr);
00025 str type_pstr(h_type);
00026
00027 extract<std::string> e_type_pstr(type_pstr);
00028
00029
00030
00031 if (e_type_pstr.check())
00032 { ret = e_type_pstr(); }
00033
00034 else
00035 { ret = "Unknown exception type"; }
00036 }
00037
00038
00039 if (value_ptr != NULL)
00040 {
00041 handle<> h_val(value_ptr);
00042 str a(h_val);
00043 extract<std::string> returned(a);
00044
00045 if (returned.check())
00046 { ret += ": " + returned(); }
00047
00048 else
00049 { ret += std::string(": Unparseable Python error: "); }
00050 }
00051
00052
00053 if (traceback_ptr != NULL)
00054 {
00055 handle<> h_tb(traceback_ptr);
00056
00057 object tb(import("traceback"));
00058 object fmt_tb(tb.attr("format_tb"));
00059
00060 object tb_list(fmt_tb(h_tb));
00061
00062 object tb_str(str("\n").join(tb_list));
00063
00064 extract<std::string> returned(tb_str);
00065
00066 if (returned.check())
00067 { ret += ": " + returned(); }
00068
00069 else
00070 { ret += std::string(": Unparseable Python traceback"); }
00071 }
00072
00073 return ret;
00074 }
00075
00076 PySubscriptionHandler::PySubscriptionHandler(PyObject * p)
00077 : self(p)
00078 {}
00079
00080 void PySubscriptionHandler::DataChange(uint32_t handle, const Node & node, const Variant & val, AttributeId attribute)
00081 {
00082 PyGILState_STATE state = PyGILState_Ensure();
00083
00084 try
00085 {
00086 call_method<void>(self, "data_change", handle, node, val , attribute);
00087 }
00088
00089 catch (const error_already_set & ex)
00090 {
00091 std::string perror_str = parse_python_exception();
00092 std::cout << "Error in 'data_change' method handler: " << perror_str << std::endl;
00093 }
00094
00095 PyGILState_Release(state);
00096 }
00097
00098 void PySubscriptionHandler::Event(uint32_t handle, const OpcUa::Event & event)
00099 {
00100 PyGILState_STATE state = PyGILState_Ensure();
00101
00102 try
00103 {
00104 call_method<void>(self, "event", handle, event);
00105 }
00106 catch (const error_already_set & ex)
00107 {
00108 std::string perror_str = parse_python_exception();
00109 std::cout << "Error in 'event' method handler: " << perror_str << std::endl;
00110 }
00111
00112 PyGILState_Release(state);
00113 }
00114
00115 void PySubscriptionHandler::StatusChange(StatusCode status)
00116 {
00117 PyGILState_STATE state = PyGILState_Ensure();
00118
00119 try
00120 {
00121 call_method<void>(self, "status_change", status);
00122 }
00123
00124 catch (const error_already_set & ex)
00125 {
00126 std::string perror_str = parse_python_exception();
00127 std::cout << "Error in 'status_change' method handler: " << perror_str << std::endl;
00128 }
00129
00130 PyGILState_Release(state);
00131 }
00132
00133 void PySubscriptionHandler::DefaultDataChange(const SubscriptionHandler & self_, uint32_t handle, const Node & node, const object & val, uint32_t attribute)
00134 {
00135 std::cout << "'data_change' virtual in this context" << std::endl;
00136 }
00137
00138 void PySubscriptionHandler::DefaultEvent(const SubscriptionHandler & self_, uint32_t handle, const OpcUa::Event & event)
00139 {
00140 std::cout << "'event' virtual in this context" << std::endl;
00141 }
00142
00143 void PySubscriptionHandler::DefaultStatusChange(const SubscriptionHandler & self_, StatusCode status)
00144 {
00145 std::cout << "'status_change' virtual in this context" << std::endl;
00146 }
00147
00148