Search in sources :

Example 1 with MessageFilter

use of org.openremote.agent.protocol.filter.MessageFilter in project openremote by openremote.

the class AbstractProtocol method updateLinkedAttribute.

/**
 * Update the value of a linked attribute. Call this to publish new sensor values. This will apply any
 * {@link MessageFilter}s that have been set for the {@link Attribute} against the {@link AttributeState#value}
 * before sending on the sensor queue.
 */
@SuppressWarnings("unchecked")
protected final void updateLinkedAttribute(final AttributeState finalState, long timestamp) {
    withLock(getProtocolName() + "::updateLinkedAttribute", () -> {
        AttributeState state = finalState;
        AssetAttribute attribute = linkedAttributes.get(state.getAttributeRef());
        if (attribute == null) {
            LOG.severe("Update linked attribute called for un-linked attribute: " + state);
            return;
        }
        if (state.getValue().isPresent()) {
            List<MessageFilter> filters;
            Value value = state.getValue().get();
            filters = linkedAttributeFilters.get(state.getAttributeRef());
            if (filters != null) {
                LOG.fine("Applying message filters to sensor value...");
                for (MessageFilter filter : filters) {
                    if (filter.getMessageType() != value.getType().getModelType()) {
                        LOG.fine("Message filter type '" + filter.getMessageType().getName() + "' is not compatible with actual message type '" + value.getType().getModelType().getName() + "': " + filter.getClass().getName());
                        value = null;
                    } else {
                        try {
                            LOG.finest("Applying message filter: " + filter.getClass().getName());
                            value = filter.process(value);
                        } catch (Exception e) {
                            LOG.log(Level.SEVERE, "Message filter threw and exception during processing of message: " + filter.getClass().getName(), e);
                            value = null;
                        }
                    }
                    if (value == null) {
                        break;
                    }
                }
            }
            // Do basic value conversion
            Optional<ValueType> attributeValueType = attribute.getType().map(AttributeType::getValueType);
            if (value != null && attributeValueType.isPresent()) {
                if (attributeValueType.get() != value.getType()) {
                    LOG.fine("Converting value: " + value.getType() + " -> " + attributeValueType.get());
                    Optional<Value> convertedValue = Values.convert(value, attributeValueType.get());
                    if (!convertedValue.isPresent()) {
                        LOG.warning("Failed to convert value: " + value.getType() + " -> " + attributeValueType.get());
                    } else {
                        value = convertedValue.get();
                    }
                }
            }
            state = new AttributeState(state.getAttributeRef(), value);
        }
        AttributeEvent attributeEvent = new AttributeEvent(state, timestamp);
        LOG.fine("Sending on sensor queue: " + attributeEvent);
        producerTemplate.sendBodyAndHeader(SENSOR_QUEUE, attributeEvent, Protocol.SENSOR_QUEUE_SOURCE_PROTOCOL, getProtocolName());
        if (locationLinkedAttributes.contains(state.getAttributeRef())) {
            // Check value type is compatible
            Point location = state.getValue().map(value -> {
                if (value.getType() != ValueType.ARRAY) {
                    LOG.warning("Location linked attribute type is not an array");
                    return null;
                }
                Optional<List<NumberValue>> coordinates = Values.getArrayElements((ArrayValue) value, NumberValue.class, false, false);
                if (!coordinates.isPresent() || coordinates.get().size() != 2 || Math.abs(coordinates.get().get(0).getNumber()) > 180 || Math.abs(coordinates.get().get(1).getNumber()) > 90) {
                    LOG.warning("Location linked attribute value must contain longitude then latitude in a 2 value number array");
                    return null;
                }
                try {
                    return new GeometryFactory().createPoint(new Coordinate(coordinates.get().get(0).getNumber(), coordinates.get().get(1).getNumber()));
                } catch (Exception e) {
                    return null;
                }
            }).orElse(null);
            updateAssetLocation(state.getAttributeRef().getEntityId(), location);
        }
    });
}
Also used : java.util(java.util) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) ConnectionStatus(org.openremote.model.asset.agent.ConnectionStatus) ValidationFailure(org.openremote.model.ValidationFailure) MessageFilter(org.openremote.agent.protocol.filter.MessageFilter) Point(com.vividsolutions.jts.geom.Point) Level(java.util.logging.Level) AgentLink(org.openremote.model.asset.agent.AgentLink) GlobalLock.withLockReturning(org.openremote.container.concurrent.GlobalLock.withLockReturning) Container(org.openremote.container.Container) ProducerTemplate(org.apache.camel.ProducerTemplate) Coordinate(com.vividsolutions.jts.geom.Coordinate) MessageBrokerService(org.openremote.container.message.MessageBrokerService) Logger(java.util.logging.Logger) MessageBrokerSetupService(org.openremote.container.message.MessageBrokerSetupService) AssetMeta(org.openremote.model.asset.AssetMeta) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) org.openremote.model.value(org.openremote.model.value) RouteBuilder(org.apache.camel.builder.RouteBuilder) TimerService(org.openremote.container.timer.TimerService) MessageBrokerContext(org.openremote.container.message.MessageBrokerContext) org.openremote.model.attribute(org.openremote.model.attribute) ProtocolDescriptor(org.openremote.model.asset.agent.ProtocolDescriptor) GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) ValueHolder(org.openremote.model.ValueHolder) AssetAttribute(org.openremote.model.asset.AssetAttribute) GlobalLock(org.openremote.container.concurrent.GlobalLock) GlobalLock.withLock(org.openremote.container.concurrent.GlobalLock.withLock) GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) Point(com.vividsolutions.jts.geom.Point) Coordinate(com.vividsolutions.jts.geom.Coordinate) AssetAttribute(org.openremote.model.asset.AssetAttribute) MessageFilter(org.openremote.agent.protocol.filter.MessageFilter)

Example 2 with MessageFilter

use of org.openremote.agent.protocol.filter.MessageFilter in project openremote by openremote.

the class Protocol method getLinkedAttributeMessageFilters.

/**
 * Extract the {@link MessageFilter}s from the specified {@link Attribute}
 */
static Optional<List<MessageFilter>> getLinkedAttributeMessageFilters(Attribute attribute) {
    if (attribute == null) {
        return Optional.empty();
    }
    Optional<ArrayValue> arrayValueOptional = attribute.getMetaItem(META_PROTOCOL_FILTERS).flatMap(AbstractValueHolder::getValueAsArray);
    if (!arrayValueOptional.isPresent()) {
        return Optional.empty();
    }
    try {
        ArrayValue arrayValue = arrayValueOptional.get();
        List<MessageFilter> messageFilters = new ArrayList<>(arrayValue.length());
        for (int i = 0; i < arrayValue.length(); i++) {
            ObjectValue objValue = arrayValue.getObject(i).orElseThrow(() -> new IllegalArgumentException("Attribute protocol filters meta item is invalid"));
            MessageFilter filter = deserialiseMessageFilter(objValue);
            messageFilters.add(filter);
        }
        return messageFilters.isEmpty() ? Optional.empty() : Optional.of(messageFilters);
    } catch (IllegalArgumentException e) {
        LOG.log(Level.WARNING, e.getMessage(), e);
    }
    return Optional.empty();
}
Also used : ObjectValue(org.openremote.model.value.ObjectValue) AbstractValueHolder(org.openremote.model.AbstractValueHolder) ArrayList(java.util.ArrayList) MessageFilter(org.openremote.agent.protocol.filter.MessageFilter) ArrayValue(org.openremote.model.value.ArrayValue)

Aggregations

MessageFilter (org.openremote.agent.protocol.filter.MessageFilter)2 Coordinate (com.vividsolutions.jts.geom.Coordinate)1 GeometryFactory (com.vividsolutions.jts.geom.GeometryFactory)1 Point (com.vividsolutions.jts.geom.Point)1 java.util (java.util)1 ArrayList (java.util.ArrayList)1 TimeUnit (java.util.concurrent.TimeUnit)1 Consumer (java.util.function.Consumer)1 Level (java.util.logging.Level)1 Logger (java.util.logging.Logger)1 ProducerTemplate (org.apache.camel.ProducerTemplate)1 RouteBuilder (org.apache.camel.builder.RouteBuilder)1 Container (org.openremote.container.Container)1 GlobalLock (org.openremote.container.concurrent.GlobalLock)1 GlobalLock.withLock (org.openremote.container.concurrent.GlobalLock.withLock)1 GlobalLock.withLockReturning (org.openremote.container.concurrent.GlobalLock.withLockReturning)1 MessageBrokerContext (org.openremote.container.message.MessageBrokerContext)1 MessageBrokerService (org.openremote.container.message.MessageBrokerService)1 MessageBrokerSetupService (org.openremote.container.message.MessageBrokerSetupService)1 TimerService (org.openremote.container.timer.TimerService)1