Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

BaSyx / Introductory Examples / Java / Example 2a

Example 2a

This is a variant of the scenario showcased in Example 2.

Instead of accessing the oven model through HTTP/REST, BaSyxTCP is used. The registry is still accessed through HTTP/REST.

Example Code

Only small code changes are necessary to support this scenario. First, the local variant needs to be changed to provide the oven model via TCP. Then, the remote side needs to be extended to support both HTTP/REST and TCP.

Local

Instead of providing the oven through HTTP/REST, it is now provided via TCP. Thus, the oven servlet is replaced with a BaSyxTCP server. Additionally, the registry entry is updated to point to the TCP server.

/** 
 * Expected console output in this HandsOn:
 * - the heater id
 * - oven is activated and deactivated multiple times
 * - temperature values between 30 and 40
 */
public class Scenario2TCP {
	// Initializes a logger for the output
	private static final Logger logger = LoggerFactory.getLogger(Scenario2TCP.class);
 
	public static void main(String[] args) throws Exception {
		// First, a local model is created that is wrapped by a model provider (see first HandsOn)
		Map<String, Object> model = Scenario1.createMyOvenModel(new Oven());
		IModelProvider modelProvider = new VABLambdaProvider(model);
		// Up to this point, everything is known from the previous HandsOn
 
		// Create a directory that can store endpoints for VAB models
		// => The directory will be published using an HTTP-REST interface
		IVABDirectoryService directory = new InMemoryDirectory();
		IModelProvider directoryProvider = new DirectoryModelProvider(directory);
		HttpServlet directoryServlet = new VABHTTPInterface<IModelProvider>(directoryProvider);
		logger.info("Created a servlet for the directory");
 
		// Now, define a context to which multiple servlets can be added
		BaSyxContext context = new BaSyxContext("/handson", "", "localhost", 4001);
		// => Every servlet contained in this context is available at http://localhost:4001/handson/
		context.addServletMapping("/directory/*", directoryServlet);
		// The directory will be available at http://localhost:4001/handson/directory/
		AASHTTPServer server = new AASHTTPServer(context);
		server.start();
 
		// Creates a tcp server providing the oven model on port 7000
		BaSyxTCPServer<IModelProvider> tcpServer = new BaSyxTCPServer<>(modelProvider, 7000);
		tcpServer.start();
 
 
		// Register the VAB model at the directory (locally in this case)
		directory.addMapping("oven", "basyx://127.0.0.1:7000");
		logger.info("Oven model registered!");
 
		logger.info("Server started");
	}

Remote

Due the abstracting nature of the VAB, there's little change on the remote side. Instead of directly using the HTTPConnectorProvider, the ConnectorProviderMapper is used. It allows to provide different connectors, selected depending on the address passed to it. The ConnectorProviderMapper is initialized with http prefix for HTTP/REST and basyx prefix for TCP.

The application logic, i.e. the control of the oven based on its temperature, remains unchanged. This again showcases the capability of the VAB to enable abstraction from the specific communication mechanism used.

/** 
 * This is the connected site in the HandsOn. Although everything is executed locally in this HandsOn,
 * the connection to the model can also be established from distributed locations in the network using this code
 * (using the correct network addresses).
 * 
 */
 
public class Scenario2Connected {
	// Initializes a logger for the output
	private static final Logger logger = LoggerFactory.getLogger(Scenario2Connected.class);
 
	public static void main(String[] args) throws Exception {
		// At the connected site, no direct access to the model is possible
		// Every access is done through the network infrastructure
 
		// The Virtual Automation Bus hides network details to the connected site. Only the endpoint of the
		// directory has to be known:
		VABRegistryProxy directoryProxy = new VABRegistryProxy("http://localhost:4001/handson/directory/");
 
		// The connection manager is responsible for resolving every connection attempt
		// For this, it needs:
		// - The directory at which all models are registered
		// - A provider for different types of network protocols (in this example, both HTTP-REST and TCPBaSyx)
		ConnectorProviderMapper mapper = new ConnectorProviderMapper();
		mapper.addConnectorProvider("http", new HTTPConnectorFactory());
		mapper.addConnectorProvider("basyx", new BaSyxConnectorFactory());
 
		VABConnectionManager connectionManager = new VABConnectionManager(directoryProxy, mapper);
 
		// It is now one line of code to retrieve a model provider for any registered model in the network
		IModelProvider connectedOven = connectionManager.connectToVABElement("oven");
 
		// Now, implement a simple a simple bang-bang controller as it has been done in the first HandsOn
		for (int i = 0; i < 100; i++) {
			// Pause for 100ms
			Thread.sleep(100);
			// Retrieve the current temperature from the model provider
			double temperature = (double) connectedOven.getValue("/properties/temperature");
			logger.info("Current temperature: " + temperature);
 
			// Turn the oven on/off, depending on the defined temperature range
			if (temperature > 40) {
				connectedOven.invokeOperation("/operations/deactivateOven");
			} else if (temperature < 30) {
				connectedOven.invokeOperation("/operations/activateOven");
			}
		}
	}
}

Back to the top