use of org.openremote.model.asset.AssetTreeNode in project openremote by openremote.
the class ZWaveNetwork method discoverDevices.
public synchronized AssetTreeNode[] discoverDevices(ZWaveAgent agent) {
if (controller == null) {
return new AssetTreeNode[0];
}
// Filter nodes
List<ZWaveNode> nodes = controller.getNodes().stream().filter(node -> node.getState() == INITIALIZATION_FINISHED).filter(node -> {
// Do not add devices that have already been discovered
List<ZWCommandClass> cmdClasses = new ArrayList<>(node.getSupportedCommandClasses());
for (ZWEndPoint curEndpoint : node.getEndPoints()) {
cmdClasses.addAll(curEndpoint.getCmdClasses());
}
return cmdClasses.stream().map(ZWCommandClass::getChannels).flatMap(List<Channel>::stream).noneMatch(channel -> consumerLinkMap.values().stream().anyMatch(link -> link.getChannel() == channel));
}).collect(toList());
List<AssetTreeNode> assetNodes = nodes.stream().map(node -> {
// Root device
AssetTreeNode deviceNode = createDeviceNode(agent.getId(), node.getSupportedCommandClasses(), node.getGenericDeviceClassID().getDisplayName(node.getSpecificDeviceClassID()));
// Device Info
Asset<?> deviceInfoAsset = new ThingAsset("Info");
deviceInfoAsset.getAttributes().addAll(createNodeInfoAttributes(agent.getId(), node));
deviceNode.addChild(new AssetTreeNode(deviceInfoAsset));
for (ZWEndPoint curEndpoint : node.getEndPoints()) {
String subDeviceName = curEndpoint.getGenericDeviceClassID().getDisplayName(curEndpoint.getSpecificDeviceClassID()) + " - " + curEndpoint.getEndPointNumber();
AssetTreeNode subDeviceNode = createDeviceNode(agent.getId(), curEndpoint.getCmdClasses(), subDeviceName);
deviceNode.addChild(subDeviceNode);
}
// Parameters
List<ZWParameterItem> parameters = node.getParameters();
if (parameters.size() > 0) {
AssetTreeNode parameterListNode = new AssetTreeNode(new ThingAsset("Parameters"));
deviceNode.addChild(parameterListNode);
List<AssetTreeNode> parameterNodes = parameters.stream().filter(parameter -> parameter.getChannels().size() > 0).map(parameter -> {
int number = parameter.getNumber();
String parameterLabel = number + " : " + parameter.getDisplayName();
String description = parameter.getDescription();
Asset<?> parameterAsset = new ThingAsset(parameterLabel);
AssetTreeNode parameterNode = new AssetTreeNode(parameterAsset);
List<Attribute<?>> attributes = parameter.getChannels().stream().map(channel -> {
Attribute<?> attribute = TypeMapper.createAttribute(channel.getName(), channel.getChannelType());
addAttributeChannelMetaItems(agent.getId(), attribute, channel);
addValidRangeMeta(attribute, parameter);
return attribute;
}).collect(toList());
if (description != null && description.length() > 0) {
Attribute<String> descriptionAttribute = new Attribute<>("description", org.openremote.model.value.ValueType.TEXT, description);
descriptionAttribute.addMeta(new MetaItem<>(MetaItemType.LABEL, "Description"), new MetaItem<>(MetaItemType.READ_ONLY, true));
attributes.add(descriptionAttribute);
}
parameterAsset.getAttributes().addAll(attributes);
return parameterNode;
}).collect(toList());
parameterNodes.forEach(parameterListNode::addChild);
}
return deviceNode;
}).collect(toList());
// Z-Wave Controller
Asset<?> networkManagementAsset = new ThingAsset("Z-Wave Controller");
List<Attribute<?>> attributes = controller.getSystemCommandManager().getChannels().stream().filter(channel -> consumerLinkMap.values().stream().noneMatch(link -> link.getChannel() == channel)).map(channel -> {
Attribute<?> attribute = TypeMapper.createAttribute(channel.getName(), channel.getChannelType());
addAttributeChannelMetaItems(agent.getId(), attribute, channel);
return attribute;
}).collect(toList());
if (attributes.size() > 0) {
networkManagementAsset.getAttributes().addAll(attributes);
assetNodes.add(new AssetTreeNode(networkManagementAsset));
}
return assetNodes.toArray(new AssetTreeNode[0]);
}
use of org.openremote.model.asset.AssetTreeNode in project openremote by openremote.
the class AbstractVelbusProtocol method startAssetImport.
/* ProtocolAssetImport */
@Override
public Future<Void> startAssetImport(byte[] fileData, Consumer<AssetTreeNode[]> assetConsumer) {
return executorService.submit(() -> {
Document xmlDoc;
try {
String xmlStr = new String(fileData, StandardCharsets.UTF_8);
LOG.info("Parsing VELBUS project file");
xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xmlStr)));
} catch (Exception e) {
LOG.log(Level.WARNING, "Failed to convert VELBUS project file into XML", e);
return;
}
xmlDoc.getDocumentElement().normalize();
NodeList modules = xmlDoc.getElementsByTagName("Module");
LOG.info("Found " + modules.getLength() + " module(s)");
List<Asset<?>> devices = new ArrayList<>(modules.getLength());
for (int i = 0; i < modules.getLength(); i++) {
Element module = (Element) modules.item(i);
// TODO: Process memory map and add
Optional<VelbusDeviceType> deviceType = EnumUtil.enumFromString(VelbusDeviceType.class, module.getAttribute("type").replaceAll("-", ""));
if (!deviceType.isPresent()) {
LOG.info("Module device type '" + module.getAttribute("type") + "' is not supported so ignoring");
continue;
}
String[] addresses = module.getAttribute("address").split(",");
int baseAddress = Integer.parseInt(addresses[0], 16);
String build = module.getAttribute("build");
String serial = module.getAttribute("serial");
String name = module.getElementsByTagName("Caption").item(0).getTextContent();
name = isNullOrEmpty(name) ? deviceType.toString() : name;
// TODO: Use device specific asset types
Asset<?> device = new ThingAsset(name);
device.addAttributes(new Attribute<>("build", ValueType.TEXT, build).addMeta(new MetaItem<>(MetaItemType.LABEL, "Build"), new MetaItem<>(MetaItemType.READ_ONLY, true)), new Attribute<>("serialNumber", ValueType.TEXT, serial).addMeta(new MetaItem<>(MetaItemType.LABEL, "Serial No"), new MetaItem<>(MetaItemType.READ_ONLY, true)));
device.addAttributes(deviceType.flatMap(type -> Optional.ofNullable(type.getFeatureProcessors()).map(processors -> Arrays.stream(processors).flatMap(processor -> processor.getPropertyDescriptors(type).stream().map(descriptor -> {
VelbusAgentLink agentLink = new VelbusAgentLink(agent.getId(), baseAddress, descriptor.getLinkName());
Attribute<?> attribute = new Attribute<>(descriptor.getName(), descriptor.getAttributeValueDescriptor()).addMeta(new MetaItem<>(AGENT_LINK, agentLink), new MetaItem<>(MetaItemType.LABEL, descriptor.getDisplayName()));
if (descriptor.isReadOnly()) {
attribute.addMeta(new MetaItem<>(MetaItemType.READ_ONLY, true));
}
return attribute;
})).toArray(Attribute<?>[]::new))).orElse(new Attribute<?>[0]));
devices.add(device);
}
assetConsumer.accept(devices.stream().map(AssetTreeNode::new).toArray(AssetTreeNode[]::new));
}, null);
}
use of org.openremote.model.asset.AssetTreeNode in project openremote by openremote.
the class KNXProtocol method startAssetImport.
@Override
public Future<Void> startAssetImport(byte[] fileData, Consumer<AssetTreeNode[]> assetConsumer) {
return executorService.submit(() -> {
ZipInputStream zin = null;
try {
boolean fileFound = false;
zin = new ZipInputStream(new ByteArrayInputStream(fileData));
ZipEntry zipEntry = zin.getNextEntry();
while (zipEntry != null) {
if (zipEntry.getName().endsWith("/0.xml")) {
fileFound = true;
break;
}
zipEntry = zin.getNextEntry();
}
if (!fileFound) {
String msg = "Failed to find '0.xml' in project file";
LOG.info(msg);
throw new IllegalStateException(msg);
}
// Create a transform factory instance.
TransformerFactory tfactory = new net.sf.saxon.TransformerFactoryImpl();
// Create a transformer for the stylesheet.
InputStream inputStream = KNXProtocol.class.getResourceAsStream("/org/openremote/agent/protocol/knx/ets_calimero_group_name.xsl");
String xsd = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
// Get weird behaviour sometimes without this
xsd = xsd.trim().replaceFirst("^([\\W]+)<", "<");
LOG.warning(xsd);
Transformer transformer = tfactory.newTransformer(new StreamSource(new StringReader(xsd)));
// Set the URIResolver
transformer.setURIResolver(new ETSFileURIResolver(fileData));
// Transform the source XML
String xml = IOUtils.toString(zin, StandardCharsets.UTF_8);
// Get weird behaviour sometimes without this
xml = xml.trim().replaceFirst("^([\\W]+)<", "<");
LOG.warning(xml);
StringWriter writer = new StringWriter();
StringReader reader = new StringReader(xml);
transformer.transform(new StreamSource(reader), new StreamResult(writer));
xml = writer.toString();
// we use a map of state-based data points and read from the transformed xml
final DatapointMap<StateDP> datapoints = new DatapointMap<>();
try (final XmlReader r = XmlInputFactory.newInstance().createXMLStreamReader(new StringReader(xml))) {
datapoints.load(r);
} catch (final KNXMLException e) {
String msg = "Error loading parsed ETS file: " + e.getMessage();
LOG.warning(msg);
throw new IllegalStateException(msg, e);
}
Map<String, Asset<?>> createdAssets = new HashMap<>();
for (StateDP dp : datapoints.getDatapoints()) {
if (dp.getName().endsWith("#A")) {
createAsset(dp, false, createdAssets);
} else if (dp.getName().endsWith("#S")) {
createAsset(dp, true, createdAssets);
} else if (dp.getName().endsWith("#SA") || dp.getName().endsWith("#AS")) {
createAsset(dp, false, createdAssets);
createAsset(dp, true, createdAssets);
} else {
LOG.info("Only group addresses ending on #A, #S, #AS or #SA will be imported. Ignoring: " + dp.getName());
}
}
assetConsumer.accept(createdAssets.values().stream().map(AssetTreeNode::new).toArray(AssetTreeNode[]::new));
} catch (Exception e) {
LOG.log(Level.WARNING, "ETS import error", e);
} finally {
if (zin != null) {
try {
zin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}, null);
}
use of org.openremote.model.asset.AssetTreeNode in project openremote by openremote.
the class MockProtocol method startAssetDiscovery.
@Override
public Future<Void> startAssetDiscovery(Consumer<AssetTreeNode[]> assetConsumer) {
return container.getExecutorService().submit(() -> {
// Simulate discovery init delay
Thread.sleep(2000);
// Discover a few assets
assetConsumer.accept(new AssetTreeNode[] { new AssetTreeNode(new ThingAsset("MockAsset1").addAttributes(new Attribute<>("mock1", ValueType.TEXT, "dummy1"), new Attribute<>("mock2", ValueType.POSITIVE_INTEGER, 1234))), new AssetTreeNode(new ThingAsset("MockAsset2").addAttributes(new Attribute<>("mock1", ValueType.TEXT, "dummy2"), new Attribute<>("mock2", ValueType.POSITIVE_INTEGER, 1234))) });
// Simulate a delay
Thread.sleep(1000);
// Discover a few assets
assetConsumer.accept(new AssetTreeNode[] { new AssetTreeNode(new ThingAsset("MockAsset3").addAttributes(new Attribute<>("mock1", ValueType.TEXT, "dummy3"), new Attribute<>("mock2", ValueType.POSITIVE_INTEGER, 1234))), new AssetTreeNode(new ThingAsset("MockAsset3").addAttributes(new Attribute<>("mock1", ValueType.TEXT, "dummy3"), new Attribute<>("mock2", ValueType.POSITIVE_INTEGER, 1234))) });
return null;
});
}
use of org.openremote.model.asset.AssetTreeNode in project openremote by openremote.
the class AgentResourceImpl method persistAssets.
// TODO: Allow user to select which assets/attributes are actually added to the DB
protected void persistAssets(AssetTreeNode[] assets, Asset<?> parentAsset, String realm) {
try {
if (assets == null || assets.length == 0) {
LOG.info("No assets to import");
return;
}
for (AssetTreeNode assetNode : assets) {
Asset<?> asset = assetNode.asset;
if (asset == null) {
LOG.info("Skipping node as asset not set");
continue;
}
asset.setId(null);
asset.setRealm(realm);
asset.setParent(parentAsset);
assetNode.asset = assetStorageService.merge(asset);
if (assetNode.children != null) {
persistAssets(assetNode.children, assetNode.asset, realm);
}
}
} catch (IllegalArgumentException e) {
LOG.log(Level.WARNING, e.getMessage(), e);
throw new NotFoundException(e.getMessage());
} catch (UnsupportedOperationException e) {
LOG.log(Level.WARNING, e.getMessage(), e);
throw new NotSupportedException(e.getMessage());
} catch (IllegalStateException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
throw new InternalServerErrorException(e.getMessage());
}
}
Aggregations