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);
}
});
}
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();
}
Aggregations