Manager Service API (MSA)
The Manager Service API (MSA) lets managers call each other. One manager offers a service, another manager calls its methods through a stub. MSA works across all manager programming languages, so a Python manager can call a service written in CTRL, C++, C# or TypeScript, and vice versa.
The protocol is vRPC (Variable Remote Procedure Call).
A request and a response each carry one WinCC OA variable, which Python represents as OaVariant.
This page is a quick start. Everything beyond it, such as metadata, deadlines, cancellation, error handling and the service options, is described in the Manager Service API chapter of the WinCC OA online help.
Package
MSA is not part of etm.wccoa.manager.
It is the separate import package etm.wccoa.msa, installed with the distribution package etm-wccoa-msa.
It builds on a running Manager.
Applications import the vrpc module:
from etm.wccoa.msa import vrpc
vrpc contains everything an application needs.
The API reference describes etm.wccoa.msa.vrpc
and the protocol-neutral types in etm.wccoa.msa.base.
Offering a Service
A service derives from vrpc.ServiceBase and registers its methods in __init__.
A vrpc.ServiceContainer announces the service and runs it until the container is closed.
from etm.wccoa.datatypes import OaValueLike, OaVariant
from etm.wccoa.manager import Manager
from etm.wccoa.msa import vrpc
class GreeterService(vrpc.ServiceBase):
def __init__(self) -> None:
super().__init__("Greeter")
self.register_function("SayHello", self.say_hello)
def say_hello(self, context: vrpc.ServerContext, request: OaVariant) -> OaValueLike:
if not request.value:
raise vrpc.RpcError(vrpc.Status(vrpc.StatusCode.INVALID_ARGUMENT, "Name cannot be empty"))
return f"Hello {request.value}"
with Manager() as manager, vrpc.ServiceContainer(manager) as container:
container.register_service(GreeterService())
container.start_all_services()
manager.wait()
The handlers of a service run on a thread of their own, one request after another.
A handler answers by returning a value, or by raising vrpc.RpcError to return an error status.
A handler that takes a third parameter receives a vrpc.Responder
and may send the answer later, from any thread.
Calling a Service
A vrpc.Stub calls the methods of a service by name.
from etm.wccoa.manager import Manager
from etm.wccoa.msa import vrpc
with Manager() as manager, vrpc.Stub.create_and_initialize(manager, "Greeter") as stub:
try:
greeting = stub.call_function("SayHello", "Python")
print(greeting.value)
except vrpc.RpcError as error:
print(error.status)
call_function() blocks until the response arrives.
call_function_async() returns a vrpc.AsyncUnaryCall at once.
It gives access to the response and trailing headers and allows the call to be canceled.
