All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.component.plc4x.Plc4XEndpoint Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.component.plc4x;

import java.util.Map;

import org.apache.camel.Category;
import org.apache.camel.Component;
import org.apache.camel.Consumer;
import org.apache.camel.PollingConsumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import org.apache.camel.util.StringHelper;
import org.apache.plc4x.java.DefaultPlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Read and write to PLC devices
 */
@UriEndpoint(scheme = "plc4x", firstVersion = "3.20.0", title = "PLC4X",
             syntax = "plc4x:driver", category = Category.IOT)
public class Plc4XEndpoint extends DefaultEndpoint implements EndpointServiceLocation {
    private static final Logger LOGGER = LoggerFactory.getLogger(Plc4XEndpoint.class);

    protected DefaultPlcDriverManager plcDriverManager;
    protected PlcConnection connection;

    @UriPath
    @Metadata(required = true, description = "PLC4X connection string for the connection to the target")
    private String driver;
    @UriParam(label = "consumer", prefix = "tag.", multiValue = true)
    @Metadata(description = "Tags as key/values from the Map to use in query")
    private Map tags;
    @UriParam
    @Metadata(label = "consumer",
              description = "Query to a trigger. On a rising edge of the trigger, the tags will be read once")
    private String trigger;
    @UriParam
    @Metadata(label = "consumer", description = "Interval on which the Trigger should be checked")
    private int period;
    @UriParam
    @Metadata(description = "Whether to reconnect when no connection is present upon doing a request")
    private boolean autoReconnect;

    private String uri;

    public Plc4XEndpoint(String endpointUri, Component component) {
        super(endpointUri, component);
        this.plcDriverManager = new DefaultPlcDriverManager();
        this.uri = endpointUri.replaceFirst("plc4x:/?/?", "");
    }

    @Override
    public String getServiceUrl() {
        return StringHelper.after(uri, ":", uri);
    }

    @Override
    public String getServiceProtocol() {
        return StringHelper.before(uri, ":", "plc4x");
    }

    public int getPeriod() {
        return period;
    }

    public void setPeriod(int period) {
        this.period = period;
    }

    public String getUri() {
        return uri;
    }

    public String getTrigger() {
        return trigger;
    }

    public void setTrigger(String trigger) {
        this.trigger = trigger;
        this.plcDriverManager = new DefaultPlcDriverManager();
    }

    public void setAutoReconnect(boolean autoReconnect) {
        this.autoReconnect = autoReconnect;
    }

    public boolean isAutoReconnect() {
        return autoReconnect;
    }

    /**
     * Set up the connection.
     *
     * @throws PlcConnectionException if no connection could be established and auto-reconnect is turned off
     */
    public void setupConnection() throws PlcConnectionException {
        try {
            connection = plcDriverManager.getConnection(this.uri);
            if (!isConnected()) {
                reconnectIfNeeded();
            }
        } catch (PlcConnectionException e) {
            if (isAutoReconnect()) {
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.warn("Could not connect during setup, retrying on next request", e);
                } else {
                    LOGGER.warn("Could not connect during setup, retrying on next request");
                }
            } else {
                LOGGER.warn("Could not connect during setup and auto reconnect is turned off");
                throw e;
            }
        }
    }

    /**
     * Reconnects if needed. If connection is lost and auto-reconnect is turned off, endpoint will be shutdown.
     * 

* * @throws PlcConnectionException If reconnect failed and auto-reconnect is turned on */ public void reconnectIfNeeded() throws PlcConnectionException { if (isConnected()) { LOGGER.trace("No reconnect needed, already connected"); } else if (autoReconnect && connection == null) { connection = plcDriverManager.getConnection(uri); LOGGER.debug("Successfully reconnected"); } else if (autoReconnect && !isConnected()) { connection.connect(); // If reconnection fails without Exception, reset connection if (!isConnected()) { LOGGER.debug("No connection established after connect, resetting connection"); connection = plcDriverManager.getConnection(uri); } LOGGER.debug("Successfully reconnected"); } else { LOGGER.warn("Connection lost and auto-reconnect is turned off, shutting down Plc4XEndpoint"); stop(); } } /** * @return true if connection supports writing, else false */ public boolean canWrite() { return connection.getMetadata().isWriteSupported(); } /** * @return true if connection is established and still connected */ public boolean isConnected() { return connection != null && connection.isConnected(); } @Override public Producer createProducer() { return new Plc4XProducer(this); } @Override public Consumer createConsumer(Processor processor) throws Exception { Plc4XConsumer consumer = new Plc4XConsumer(this, processor); configureConsumer(consumer); return consumer; } @Override public PollingConsumer createPollingConsumer() { return new Plc4XPollingConsumer(this); } /** * Build a {@link PlcReadRequest} using the tags specified in the endpoint. */ public PlcReadRequest buildPlcReadRequest() { PlcReadRequest.Builder builder = connection.readRequestBuilder(); if (tags != null) { for (Map.Entry tag : tags.entrySet()) { try { builder.addTagAddress(tag.getKey(), tag.getValue()); } catch (PlcIncompatibleDatatypeException e) { LOGGER.warn("For consumer, please use Map, currently using {}", tags.getClass().getSimpleName()); } } } return builder.build(); } /** * Build a {@link PlcWriteRequest}. *

* * @param tags tags to add to write request * @return {@link PlcWriteRequest} */ public PlcWriteRequest buildPlcWriteRequest(Map> tags) { PlcWriteRequest.Builder builder = connection.writeRequestBuilder(); for (Map.Entry> entry : tags.entrySet()) { //Tags are stored like this --> Map> for writing String name = entry.getKey(); String query = entry.getValue().keySet().iterator().next(); Object value = entry.getValue().get(query); builder.addTagAddress(name, query, value); } return builder.build(); } public DefaultPlcDriverManager getPlcDriverManager() { return plcDriverManager; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public Map getTags() { return tags; } public void setTags(Map tags) { this.tags = tags; } @Override public void doStop() throws Exception { //Shutting down the connection when leaving the Context if (isConnected()) { connection.close(); connection = null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy