use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.
the class KNXProtocol method createAsset.
protected void createAsset(StateDP datapoint, boolean isStatusGA, MetaItem agentLink, Map<String, Asset> createdAssets) throws KNXException {
String name = datapoint.getName().substring(0, datapoint.getName().length() - 3);
String assetName = name.replaceAll(" -.*-", "");
Asset asset;
if (createdAssets.containsKey(assetName)) {
asset = createdAssets.get(assetName);
} else {
asset = new Asset(assetName, AssetType.THING);
}
String attrName = assetName.replaceAll(" ", "");
AttributeType type = TypeMapper.toAttributeType(datapoint);
AssetAttribute attr = asset.getAttribute(attrName).orElse(new AssetAttribute(attrName, type).setMeta(new MetaItem(AssetMeta.LABEL, Values.create(name)), new MetaItem(KNXProtocol.META_KNX_DPT, Values.create(datapoint.getDPT())), agentLink));
if (isStatusGA) {
attr.addMeta(new MetaItem(KNXProtocol.META_KNX_STATUS_GA, Values.create(datapoint.getMainAddress().toString())));
} else {
attr.addMeta(new MetaItem(KNXProtocol.META_KNX_ACTION_GA, Values.create(datapoint.getMainAddress().toString())));
}
if (!asset.hasAttribute(attrName)) {
asset.addAttributes(attr);
}
createdAssets.put(assetName, asset);
}
use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.
the class MacroProtocol method processLinkedAttributeWrite.
@Override
protected void processLinkedAttributeWrite(AttributeEvent event, AssetAttribute protocolConfiguration) {
AssetAttribute attribute = getLinkedAttribute(event.getAttributeRef());
if (attribute.isExecutable()) {
// This is a macro execution related write operation
AttributeExecuteStatus status = event.getValue().flatMap(Values::getString).flatMap(AttributeExecuteStatus::fromString).orElse(null);
AttributeRef attributeRef = event.getAttributeRef();
// Check if it's a cancellation request
if (status == AttributeExecuteStatus.REQUEST_CANCEL) {
LOG.fine("Request received to cancel macro execution: " + event);
executions.computeIfPresent(attributeRef, (attributeRef1, macroExecutionTask) -> {
macroExecutionTask.cancel();
return macroExecutionTask;
});
return;
}
// If protocol configuration is disabled then nothing to do here
if (!protocolConfiguration.isEnabled()) {
LOG.fine("Protocol configuration is disabled so cannot be executed: " + protocolConfiguration.getReferenceOrThrow());
return;
}
List<MacroAction> actions = getMacroActions(protocolConfiguration.getReferenceOrThrow());
if (actions.isEmpty()) {
LOG.fine("No actions to execute");
return;
}
executeMacro(attributeRef, actions, status == AttributeExecuteStatus.REQUEST_REPEATING);
return;
}
// Assume this is a write to a macro action value (default to index 0)
int actionIndex = getMacroActionIndex(attribute).orElse(0);
// Extract macro actions from protocol configuration rather than modify the in memory ones
List<MacroAction> actions = MacroConfiguration.getMacroActions(protocolConfiguration);
if (actions.isEmpty()) {
LOG.fine("No actions are available for the linked macro, maybe it is disabled?: " + protocolConfiguration.getReferenceOrThrow());
} else {
actionIndex = Math.min(actions.size(), Math.max(0, actionIndex));
LOG.fine("Updating macro action [" + actionIndex + "] value to: " + event.getValue().map(Value::toJson).orElse(""));
MacroAction action = actions.get(actionIndex);
action.setAttributeState(new AttributeState(action.getAttributeState().getAttributeRef(), event.getValue().orElse(null)));
MetaItem[] actionMeta = actions.stream().map(MacroAction::toMetaItem).toArray(MetaItem[]::new);
updateLinkedProtocolConfiguration(protocolConfiguration, protocolConfig -> MetaItem.replaceMetaByName(protocolConfig.getMeta(), META_MACRO_ACTION, Arrays.asList(actionMeta)));
}
}
use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.
the class LocalAgentConnector method getDiscoveredLinkedAttributes.
@Override
public Asset[] getDiscoveredLinkedAttributes(AttributeRef protocolConfigurationRef, FileInfo fileInfo) throws IllegalArgumentException, UnsupportedOperationException, IllegalStateException {
Optional<Pair<Protocol, AssetAttribute>> protocolAndConfigOptional = getProtocolAndConfig(protocolConfigurationRef);
if (!protocolAndConfigOptional.isPresent()) {
throw new IllegalArgumentException("Protocol not found for: " + protocolConfigurationRef);
}
Pair<Protocol, AssetAttribute> protocolAndConfig = protocolAndConfigOptional.get();
// Check protocol is of correct type
if (!(protocolAndConfigOptional.get().key instanceof ProtocolLinkedAttributeImport)) {
LOG.info("Protocol not of type '" + ProtocolLinkedAttributeImport.class.getSimpleName() + "'");
throw new UnsupportedOperationException("Protocol doesn't support linked attribute import:" + protocolAndConfigOptional.get().key.getProtocolDisplayName());
}
ProtocolLinkedAttributeImport discoveryProtocol = (ProtocolLinkedAttributeImport) protocolAndConfig.key;
return discoveryProtocol.discoverLinkedAssetAttributes(protocolAndConfig.value, fileInfo);
}
use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.
the class RulesService method processAssetChange.
protected void processAssetChange(ServerAsset asset, PersistenceEvent persistenceEvent) {
withLock(getClass().getSimpleName() + "::processAssetChange", () -> {
// We must load the asset from database (only when required), as the
// persistence event might not contain a completely loaded asset
BiFunction<Asset, AssetAttribute, AssetState> buildAssetState = (loadedAsset, attribute) -> new AssetState(loadedAsset, attribute.deepCopy(), Source.INTERNAL);
switch(persistenceEvent.getCause()) {
case INSERT:
// New asset has been created so get attributes that have RULE_STATE meta
List<AssetAttribute> ruleStateAttributes = asset.getAttributesStream().filter(AssetAttribute::isRuleState).collect(Collectors.toList());
// Build an update with a fully loaded asset
ruleStateAttributes.forEach(attribute -> {
ServerAsset loadedAsset = assetStorageService.find(asset.getId(), true);
// If the asset is now gone it was deleted immediately after being inserted, nothing more to do
if (loadedAsset == null)
return;
AssetState assetState = buildAssetState.apply(loadedAsset, attribute);
LOG.fine("Asset was persisted (" + persistenceEvent.getCause() + "), inserting fact: " + assetState);
updateAssetState(assetState, true, true);
});
break;
case UPDATE:
int attributesIndex = Arrays.asList(persistenceEvent.getPropertyNames()).indexOf("attributes");
if (attributesIndex < 0) {
return;
}
// Fully load the asset
final Asset loadedAsset = assetStorageService.find(asset.getId(), true);
// If the asset is now gone it was deleted immediately after being updated, nothing more to do
if (loadedAsset == null)
return;
// Attributes have possibly changed so need to compare old and new attributes
// to determine which facts to retract and which to insert
List<AssetAttribute> oldRuleStateAttributes = attributesFromJson((ObjectValue) persistenceEvent.getPreviousState()[attributesIndex], asset.getId()).filter(AssetAttribute::isRuleState).collect(Collectors.toList());
List<AssetAttribute> newRuleStateAttributes = attributesFromJson((ObjectValue) persistenceEvent.getCurrentState()[attributesIndex], asset.getId()).filter(AssetAttribute::isRuleState).collect(Collectors.toList());
// Retract facts for attributes that are obsolete
getAddedOrModifiedAttributes(newRuleStateAttributes, oldRuleStateAttributes, key -> key.equals(VALUE_TIMESTAMP_FIELD_NAME)).forEach(obsoleteFactAttribute -> {
AssetState update = buildAssetState.apply(loadedAsset, obsoleteFactAttribute);
LOG.fine("Asset was persisted (" + persistenceEvent.getCause() + "), retracting: " + update);
retractAssetState(update);
});
// Insert facts for attributes that are new
getAddedOrModifiedAttributes(oldRuleStateAttributes, newRuleStateAttributes, key -> key.equals(VALUE_TIMESTAMP_FIELD_NAME)).forEach(newFactAttribute -> {
AssetState assetState = buildAssetState.apply(loadedAsset, newFactAttribute);
LOG.fine("Asset was persisted (" + persistenceEvent.getCause() + "), updating: " + assetState);
updateAssetState(assetState, true, true);
});
break;
case DELETE:
// Retract any facts that were associated with this asset
asset.getAttributesStream().filter(AssetAttribute::isRuleState).forEach(attribute -> {
// We can't load the asset again (it was deleted), so don't use buildAssetState() and
// hope that the path of the event asset has been loaded before deletion, although it is
// "unlikely" anybody will access it during retraction...
AssetState assetState = new AssetState(asset, attribute, Source.INTERNAL);
LOG.fine("Asset was persisted (" + persistenceEvent.getCause() + "), retracting fact: " + assetState);
retractAssetState(assetState);
});
break;
}
});
}
use of org.openremote.model.asset.AssetAttribute in project openremote by openremote.
the class AbstractManagerSetup method createDemoApartment.
// ################################ Demo apartment with complex scenes ###################################
protected ServerAsset createDemoApartment(ServerAsset parent, String name) {
ServerAsset apartment = new ServerAsset(name, RESIDENCE, parent);
apartment.setLocation(parent.getLocation());
apartment.setAttributes(new AssetAttribute("alarmEnabled", AttributeType.BOOLEAN).setMeta(new Meta(new MetaItem(LABEL, Values.create("Alarm enabled")), new MetaItem(DESCRIPTION, Values.create("Send notifications when presence is detected")), new MetaItem(ACCESS_RESTRICTED_READ, Values.create(true)), new MetaItem(ACCESS_RESTRICTED_WRITE, Values.create(true)), new MetaItem(RULE_STATE, Values.create(true)), new MetaItem(SHOW_ON_DASHBOARD, Values.create(true)))), new AssetAttribute("presenceDetected", AttributeType.BOOLEAN).setMeta(new Meta(new MetaItem(LABEL, Values.create("Presence detected")), new MetaItem(DESCRIPTION, Values.create("Presence detected in any room")), new MetaItem(ACCESS_RESTRICTED_READ, Values.create(true)), new MetaItem(READ_ONLY, Values.create(true)), new MetaItem(RULE_STATE, Values.create(true)), new MetaItem(STORE_DATA_POINTS, Values.create(true)), new MetaItem(SHOW_ON_DASHBOARD, Values.create(true)))), new AssetAttribute("vacationUntil", TIMESTAMP_MILLIS).setMeta(new Meta(new MetaItem(LABEL, Values.create("Vacation until")), new MetaItem(DESCRIPTION, Values.create("Vacation mode enabled until")), new MetaItem(ACCESS_RESTRICTED_READ, Values.create(true)), new MetaItem(ACCESS_RESTRICTED_WRITE, Values.create(true)), new MetaItem(RULE_STATE, Values.create(true)))), new AssetAttribute("lastExecutedScene", AttributeType.STRING).setMeta(new MetaItem(LABEL, Values.create("Last executed scene")), new MetaItem(ACCESS_RESTRICTED_READ, Values.create(true)), new MetaItem(READ_ONLY, Values.create(true)), new MetaItem(RULE_STATE, Values.create(true)), new MetaItem(SHOW_ON_DASHBOARD, Values.create(true))));
return apartment;
}
Aggregations