use of org.openremote.model.asset.agent.Protocol in project openremote by openremote.
the class AgentService method startAgent.
protected void startAgent(Agent<?, ?, ?> agent) {
withLock(getClass().getSimpleName() + "::startAgent", () -> {
Protocol<?> protocol = null;
try {
protocol = agent.getProtocolInstance();
protocolInstanceMap.put(agent.getId(), protocol);
LOG.fine("Starting protocol instance: " + protocol);
protocol.start(container);
LOG.fine("Started protocol instance:" + protocol);
LOG.finer("Linking attributes to protocol instance: " + protocol);
// Get all assets that have attributes with agent link meta for this agent
List<Asset<?>> assets = assetStorageService.findAll(new AssetQuery().attributes(new AttributePredicate().meta(new NameValuePredicate(AGENT_LINK, new StringPredicate(agent.getId()), false, new NameValuePredicate.Path("id")))));
LOG.finer("Found '" + assets.size() + "' asset(s) with attributes linked to this protocol instance: " + protocol);
assets.forEach(asset -> getGroupedAgentLinkAttributes(asset.getAttributes().stream(), assetAttribute -> assetAttribute.getMetaValue(AGENT_LINK).map(agentLink -> agentLink.getId().equals(agent.getId())).orElse(false)).forEach((agnt, attributes) -> linkAttributes(agnt, asset.getId(), attributes)));
} catch (Exception e) {
if (protocol != null) {
try {
protocol.stop(container);
} catch (Exception ignored) {
}
}
protocolInstanceMap.remove(agent.getId());
LOG.log(Level.SEVERE, "Failed to start protocol instance for agent: " + agent, e);
sendAttributeEvent(new AttributeEvent(agent.getId(), Agent.STATUS.getName(), ConnectionStatus.ERROR));
}
});
}
use of org.openremote.model.asset.agent.Protocol in project openremote by openremote.
the class SimulatorService method getSimulatorState.
/**
* Get info about all attributes linked to this instance (for frontend usage)
*/
protected SimulatorState getSimulatorState(SimulatorProtocol protocolInstance) {
return withLockReturning(protocolInstance.getProtocolInstanceUri() + "::getSimulatorInfo", () -> {
LOG.info("Getting simulator info for protocol instance: " + protocolInstance);
// We need asset names instead of identifiers for user-friendly display
List<String> linkedAssetIds = protocolInstance.getLinkedAttributes().keySet().stream().map(AttributeRef::getId).distinct().collect(Collectors.toList());
List<String> assetNames = assetStorageService.findNames(linkedAssetIds.toArray(new String[0]));
if (assetNames.size() != linkedAssetIds.size()) {
LOG.warning("Retrieved asset names don't match requested asset IDs");
return null;
}
SimulatorAttributeInfo[] attributeInfos = protocolInstance.getLinkedAttributes().entrySet().stream().map(refAttributeEntry -> {
String assetName = assetNames.get(linkedAssetIds.indexOf(refAttributeEntry.getKey().getId()));
return new SimulatorAttributeInfo(assetName, refAttributeEntry.getKey().getId(), refAttributeEntry.getValue(), protocolInstance.getReplayMap().containsKey(refAttributeEntry.getKey()));
}).toArray(SimulatorAttributeInfo[]::new);
return new SimulatorState(protocolInstance.getAgent().getId(), attributeInfos);
});
}
use of org.openremote.model.asset.agent.Protocol in project openremote by openremote.
the class AbstractProtocol method start.
@Override
public void start(Container container) throws Exception {
timerService = container.getService(TimerService.class);
executorService = container.getExecutorService();
assetService = container.getService(ProtocolAssetService.class);
predictedAssetService = container.getService(ProtocolPredictedAssetService.class);
messageBrokerContext = container.getService(MessageBrokerService.class).getContext();
withLock(getProtocolName() + "::start", () -> {
try {
messageBrokerContext.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from(ACTUATOR_TOPIC).routeId("Actuator-" + getProtocolName() + getAgent().getId()).process(exchange -> {
Protocol<?> protocolInstance = exchange.getIn().getHeader(ACTUATOR_TOPIC_TARGET_PROTOCOL, Protocol.class);
if (protocolInstance != AbstractProtocol.this) {
return;
}
AttributeEvent event = exchange.getIn().getBody(AttributeEvent.class);
Attribute<?> linkedAttribute = getLinkedAttributes().get(event.getAttributeRef());
if (linkedAttribute == null) {
LOG.info("Attempt to write to attribute that is not actually linked to this protocol '" + AbstractProtocol.this + "': " + linkedAttribute);
return;
}
processLinkedAttributeWrite(event);
});
}
});
doStart(container);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
});
this.producerTemplate = container.getService(MessageBrokerService.class).getProducerTemplate();
}
use of org.openremote.model.asset.agent.Protocol in project openremote by openremote.
the class AbstractIOClientProtocol method getGenericStringEncodersAndDecoders.
/**
* Supplies a set of encoders/decoders that convert from/to {@link String} to/from {@link ByteBuf} based on the generic protocol {@link Attribute}s
*/
public static Supplier<ChannelHandler[]> getGenericStringEncodersAndDecoders(AbstractNettyIOClient<String, ?> client, IOAgent<?, ?, ?> agent) {
boolean hexMode = agent.getMessageConvertHex().orElse(false);
boolean binaryMode = agent.getMessageConvertBinary().orElse(false);
Charset charset = agent.getMessageCharset().map(Charset::forName).orElse(CharsetUtil.UTF_8);
int maxLength = agent.getMessageMaxLength().orElse(Integer.MAX_VALUE);
String[] delimiters = agent.getMessageDelimiters().orElse(new String[0]);
boolean stripDelimiter = agent.getMessageStripDelimiter().orElse(false);
return () -> {
List<ChannelHandler> encodersDecoders = new ArrayList<>();
if (hexMode || binaryMode) {
encodersDecoders.add(new AbstractNettyIOClient.MessageToByteEncoder<>(String.class, client, (msg, out) -> {
byte[] bytes = hexMode ? ProtocolUtil.bytesFromHexString(msg) : ProtocolUtil.bytesFromBinaryString(msg);
out.writeBytes(bytes);
}));
if (delimiters.length > 0) {
ByteBuf[] byteDelimiters = Arrays.stream(delimiters).map(delim -> Unpooled.wrappedBuffer(hexMode ? ProtocolUtil.bytesFromHexString(delim) : ProtocolUtil.bytesFromBinaryString(delim))).toArray(ByteBuf[]::new);
encodersDecoders.add(new DelimiterBasedFrameDecoder(maxLength, stripDelimiter, byteDelimiters));
} else {
encodersDecoders.add(new FixedLengthFrameDecoder(maxLength));
}
// Incoming messages will be bytes
encodersDecoders.add(new AbstractNettyIOClient.ByteToMessageDecoder<>(client, (byteBuf, messages) -> {
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
String msg = hexMode ? ProtocolUtil.bytesToHexString(bytes) : ProtocolUtil.bytesToBinaryString(bytes);
messages.add(msg);
}));
} else {
encodersDecoders.add(new StringEncoder(charset));
if (agent.getMessageMaxLength().isPresent()) {
encodersDecoders.add(new FixedLengthFrameDecoder(maxLength));
} else {
ByteBuf[] byteDelimiters;
if (delimiters.length > 0) {
byteDelimiters = Arrays.stream(delimiters).map(delim -> Unpooled.wrappedBuffer(delim.getBytes(charset))).toArray(ByteBuf[]::new);
} else {
byteDelimiters = Delimiters.lineDelimiter();
}
encodersDecoders.add(new DelimiterBasedFrameDecoder(maxLength, stripDelimiter, byteDelimiters));
}
encodersDecoders.add(new StringDecoder(charset));
encodersDecoders.add(new AbstractNettyIOClient.MessageToMessageDecoder<>(String.class, client));
}
return encodersDecoders.toArray(new ChannelHandler[0]);
};
}
Aggregations