Skip to content

Commit

Permalink
Merge pull request FreeOpcUa#7 from oroulet/master
Browse files Browse the repository at this point in the history
expose high level subscription api to python
  • Loading branch information
arykovanov committed Jul 27, 2014
2 parents f7db98f + 1cbf791 commit cfdacc4
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 23 deletions.
25 changes: 18 additions & 7 deletions src/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,31 @@
from IPython import embed
import opcua

class SubClient(opcua.SubscriptionClient):
def data_change_event(node, val, attr):
print("New data change event", node, val, attr)


if __name__ == "__main__":
s = opcua.Client()
s.set_endpoint("opc.tcp://localhost:4841")
client = opcua.Client()
client.set_endpoint("opc.tcp://localhost:4841")
#s.set_endpoint("opc.tcp://192.168.56.101:48030")
s.connect()
client.connect()
try:
root = s.get_root_node()
root = client.get_root_node()
print("I got root: ", root)
print("Childs are: ", root.get_children())
print("Objects is: ", s.get_objects_node())
o = s.get_objects_node()
print("Objects is: ", client.get_objects_node())
o = client.get_objects_node()
print("Children of objects are: ", o.get_children())
myvar = root.get_child(["0:Objects", "0:testfolder", "0:myvar"])
print("yvar is: ", myvar)

#sclt = SubClient()
#sub = client.create_subscription(100, sclt)
#handle = sub.subscribe(myvar)


embed()
finally:
s.disconnect()
client.disconnect()
42 changes: 35 additions & 7 deletions src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <opc/ua/server/opcuaserver.h>
#include <opc/ua/protocol/types.h>
#include <opc/ua/server.h>
#include <opc/ua/subscription.h>
#include <opc/ua/protocol/string_utils.h>

#include <boost/python.hpp>
Expand Down Expand Up @@ -935,17 +936,32 @@ namespace OpcUa

};

class PySubscription
{
public:
PySubscription (const Subscription& other): Sub(other) { }
void Delete() { Sub.Delete(); }
uint32_t Subscribe(PyNode node) { return Sub.Subscribe(node, AttributeID::VALUE);}
uint32_t Subscribe2(PyNode node, AttributeID attr) { return Sub.Subscribe(node, attr);}

//PySubscription(Remote::Server server, SubscriptionParameters params): Server(server), Data(params) { return PyNode(Registry->GetServer(), OpcUa::ObjectID::RootFolder); }
private:
Subscription Sub;
};

class PyClient: public RemoteClient
{
public:
PyNode PyGetRootNode() { return PyNode(Server, OpcUa::ObjectID::RootFolder); }
PyNode PyGetObjectsNode() { return PyNode(Server, OpcUa::ObjectID::ObjectsFolder); }
PyNode PyGetNode(PyNodeID nodeid) { return PyNode(RemoteClient::GetNode(nodeid)); }
//PyNode PyGetNodeFromPath(const python::object& path) { return Client::Client::GetNodeFromPath(ToVector<std::string>(path)); }
PySubscription CreateSubscription(uint period, SubscriptionClient& callback)
{
return PySubscription(RemoteClient::CreateSubscription(period, callback));
}
};



class PyOPCUAServer: public OPCUAServer
{
public:
Expand All @@ -954,6 +970,10 @@ namespace OpcUa
//PyNode GetNode(NodeID nodeid) { return PyNode::FromNode(OPCUAServer::GetNode(nodeid)); }
PyNode PyGetNode(PyNodeID nodeid) { return PyNode(OPCUAServer::GetNode(nodeid)); }
PyNode PyGetNodeFromPath(const python::object& path) { return OPCUAServer::GetNodeFromPath(ToVector<std::string>(path)); }
PySubscription CreateSubscription(uint period, SubscriptionClient& callback)
{
return PySubscription(OPCUAServer::CreateSubscription(period, callback));
}
};
}

Expand Down Expand Up @@ -1208,6 +1228,16 @@ BOOST_PYTHON_MODULE(MODULE_NAME) // MODULE_NAME specifies via preprocessor in co
.def(vector_indexing_suite<std::vector<std::string> >())
;

class_<SubscriptionClient, boost::noncopyable>("SubscriptionClient")
.def("data_change_event", &SubscriptionClient::DataChangeEvent)
;

class_<PySubscription>("Subscription", init<const Subscription&>())
.def("subscribe", &PySubscription::Subscribe)
.def("subscribe", &PySubscription::Subscribe2)
.def("delete", &PySubscription::Delete)
//.def("unsubscribe", &PySubscription::UnSubscribe)
;

class_<PyClient, boost::noncopyable>("Client")
.def("connect", &PyClient::Connect)
Expand All @@ -1223,13 +1253,10 @@ BOOST_PYTHON_MODULE(MODULE_NAME) // MODULE_NAME specifies via preprocessor in co
.def("set_uri", &PyClient::SetURI)
.def("set_security_policy", &PyClient::SetSecurityPolicy)
.def("get_security_policy", &PyClient::GetSecurityPolicy)
.def("create_subscription", &PyClient::CreateSubscription)
;


//Node (OPCUAServer::*NodeFromPathString)(const std::vector<std::string>&) = &OPCUAServer::GetNodeFromPath;
//Node (OPCUAServer::*NodeFromPathQN)(const std::vector<QualifiedName>&) = &OPCUAServer::GetNodeFromPath;

class_<PyOPCUAServer, boost::noncopyable >("Server" )
class_<PyOPCUAServer, boost::noncopyable >("Server")
.def("start", &PyOPCUAServer::Start)
.def("stop", &PyOPCUAServer::Stop)
.def("get_root_node", &PyOPCUAServer::PyGetRootNode)
Expand All @@ -1242,6 +1269,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME) // MODULE_NAME specifies via preprocessor in co
.def("set_server_name", &PyOPCUAServer::SetServerName)
.def("set_endpoint", &PyOPCUAServer::SetEndpoint)
.def("load_cpp_addressspace", &PyOPCUAServer::SetLoadCppAddressSpace)
.def("create_subscription", &PyOPCUAServer::CreateSubscription)
;

}
Expand Down
31 changes: 22 additions & 9 deletions src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,35 @@
from IPython import embed
import opcua

class SubClient(opcua.SubscriptionClient):
def data_change_event(node, val, attr):
print("New data change event", node, val, attr)

if __name__ == "__main__":
s = opcua.Server()
s.set_endpoint("opc.tcp://localhost:4841")
s.load_cpp_addressspace(True)
server = opcua.Server()
server.set_endpoint("opc.tcp://localhost:4841")
server.load_cpp_addressspace(True)
#s.add_xml_address_space("standard_address_space.xml")
#s.add_xml_address_space("user_address_space.xml")
s.start()
server.start()
try:
root = s.get_root_node()
root = server.get_root_node()
print("I got root folder: ", root)
objects = s.get_objects_node()
objects = server.get_objects_node()
print("I got objects folder: ", objects)

#Now adding some object to our addresse space from server side
test = objects.add_folder("testfolder")
v = test.add_variable("myvar", [16, 56])
p = test.add_property("myprop", 9.9)
myvar = test.add_variable("myvar", [16, 56])
myprop = test.add_property("myprop", 9.9)

#Now subscribing to changes on server side
# callback does not work yet.. but soon
sclt = SubClient()
sub = server.create_subscription(100, sclt)
handle = sub.subscribe(myvar) #keep handle if you want to delete the particular subscription later

embed()
finally:
s.stop()
server.stop()

0 comments on commit cfdacc4

Please sign in to comment.