py_opcua_subscriptionclient.cpp
Go to the documentation of this file.
1 
12 
14 {
15  PyObject * type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL;
16  // Fetch the exception info from the Python C API
17  PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
18  // Fallback error
19  std::string ret("Unfetchable Python error");
20 
21  // If the fetch got a type pointer, parse the type into the exception string
22  if (type_ptr != NULL)
23  {
24  handle<> h_type(type_ptr);
25  str type_pstr(h_type);
26  // Extract the string from the boost::python object
27  extract<std::string> e_type_pstr(type_pstr);
28 
29  // If a valid string extraction is available, use it
30  // otherwise use fallback
31  if (e_type_pstr.check())
32  { ret = e_type_pstr(); }
33 
34  else
35  { ret = "Unknown exception type"; }
36  }
37 
38  // Do the same for the exception value (the stringification of the exception)
39  if (value_ptr != NULL)
40  {
41  handle<> h_val(value_ptr);
42  str a(h_val);
43  extract<std::string> returned(a);
44 
45  if (returned.check())
46  { ret += ": " + returned(); }
47 
48  else
49  { ret += std::string(": Unparseable Python error: "); }
50  }
51 
52  // Parse lines from the traceback using the Python traceback module
53  if (traceback_ptr != NULL)
54  {
55  handle<> h_tb(traceback_ptr);
56  // Load the traceback module and the format_tb function
57  object tb(import("traceback"));
58  object fmt_tb(tb.attr("format_tb"));
59  // Call format_tb to get a list of traceback strings
60  object tb_list(fmt_tb(h_tb));
61  // Join the traceback strings into a single string
62  object tb_str(str("\n").join(tb_list));
63  // Extract the string, check the extraction, and fallback in necessary
64  extract<std::string> returned(tb_str);
65 
66  if (returned.check())
67  { ret += ": " + returned(); }
68 
69  else
70  { ret += std::string(": Unparseable Python traceback"); }
71  }
72 
73  return ret;
74 }
75 
77  : self(p)
78 {}
79 
80 void PySubscriptionHandler::DataChange(uint32_t handle, const Node & node, const Variant & val, AttributeId attribute)
81 {
82  PyGILState_STATE state = PyGILState_Ensure();
83 
84  try
85  {
86  call_method<void>(self, "data_change", handle, node, val , attribute);
87  }
88 
89  catch (const error_already_set & ex)
90  {
91  std::string perror_str = parse_python_exception();
92  std::cout << "Error in 'data_change' method handler: " << perror_str << std::endl;
93  }
94 
95  PyGILState_Release(state);
96 }
97 
98 void PySubscriptionHandler::Event(uint32_t handle, const OpcUa::Event & event)
99 {
100  PyGILState_STATE state = PyGILState_Ensure();
101 
102  try
103  {
104  call_method<void>(self, "event", handle, event);
105  }
106 
107  catch (const error_already_set & ex)
108  {
109  std::string perror_str = parse_python_exception();
110  std::cout << "Error in 'event' method handler: " << perror_str << std::endl;
111  }
112 
113  PyGILState_Release(state);
114 }
115 
117 {
118  PyGILState_STATE state = PyGILState_Ensure();
119 
120  try
121  {
122  call_method<void>(self, "status_change", status);
123  }
124 
125  catch (const error_already_set & ex)
126  {
127  std::string perror_str = parse_python_exception();
128  std::cout << "Error in 'status_change' method handler: " << perror_str << std::endl;
129  }
130 
131  PyGILState_Release(state);
132 }
133 
134 void PySubscriptionHandler::DefaultDataChange(const SubscriptionHandler & self_, uint32_t handle, const Node & node, const object & val, uint32_t attribute)
135 {
136  std::cout << "'data_change' virtual in this context" << std::endl;
137 }
138 
140 {
141  std::cout << "'event' virtual in this context" << std::endl;
142 }
143 
145 {
146  std::cout << "'status_change' virtual in this context" << std::endl;
147 }
148 
149 
static void DefaultDataChange(const SubscriptionHandler &self_, uint32_t handle, const Node &node, const object &val, uint32_t attribute)
void Event(uint32_t handle, const OpcUa::Event &event) override
static void DefaultEvent(const SubscriptionHandler &self_, uint32_t handle, const OpcUa::Event &event)
void DataChange(uint32_t handle, const Node &node, const Variant &val, AttributeId attribute) override
static void DefaultStatusChange(const SubscriptionHandler &self_, StatusCode status)
handle
Definition: client.py:58
void StatusChange(StatusCode status) override
A Node object represent an OPC-UA node. It is high level object intended for developper who want to e...
Definition: node.h:42
static std::string parse_python_exception()
Python bindings for freeopcua. GNU LGPL.


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Tue Jan 19 2021 03:12:07