Search in sources :

Example 21 with AttributeRef

use of org.openremote.model.attribute.AttributeRef in project openremote by openremote.

the class JsonRulesBuilder method buildRuleActionExecution.

protected static RuleActionExecution buildRuleActionExecution(JsonRule rule, RuleAction ruleAction, String actionsName, int index, boolean useUnmatched, RulesFacts facts, RuleState ruleState, Assets assetsFacade, Users usersFacade, Notifications notificationsFacade, PredictedDatapoints predictedDatapointsFacade) {
    if (ruleAction instanceof RuleActionNotification) {
        RuleActionNotification notificationAction = (RuleActionNotification) ruleAction;
        if (notificationAction.notification != null) {
            Notification notification = notificationAction.notification;
            if (notification.getMessage() != null) {
                String body = null;
                boolean isEmail = Objects.equals(notification.getMessage().getType(), EmailNotificationMessage.TYPE);
                boolean isPush = Objects.equals(notification.getMessage().getType(), PushNotificationMessage.TYPE);
                boolean isHtml = false;
                if (isEmail) {
                    EmailNotificationMessage email = (EmailNotificationMessage) notification.getMessage();
                    isHtml = !TextUtil.isNullOrEmpty(email.getHtml());
                    body = isHtml ? email.getHtml() : email.getText();
                } else if (isPush) {
                    PushNotificationMessage pushNotificationMessage = (PushNotificationMessage) notification.getMessage();
                    body = pushNotificationMessage.getBody();
                }
                if (!TextUtil.isNullOrEmpty(body)) {
                    if (body.contains(PLACEHOLDER_TRIGGER_ASSETS)) {
                        // Need to clone the notification
                        notification = ValueUtil.clone(notification);
                        String triggeredAssetInfo = buildTriggeredAssetInfo(useUnmatched, ruleState, isHtml);
                        body = body.replace(PLACEHOLDER_TRIGGER_ASSETS, triggeredAssetInfo);
                        if (isEmail) {
                            EmailNotificationMessage email = (EmailNotificationMessage) notification.getMessage();
                            if (isHtml) {
                                email.setHtml(body);
                            } else {
                                email.setText(body);
                            }
                        } else if (isPush) {
                            PushNotificationMessage pushNotificationMessage = (PushNotificationMessage) notification.getMessage();
                            pushNotificationMessage.setBody(body);
                        }
                    }
                }
            }
            // Transfer the rule action target into notification targets
            Notification.TargetType targetType = Notification.TargetType.ASSET;
            if (ruleAction.target != null) {
                if (ruleAction.target.users != null && ruleAction.target.conditionAssets == null && ruleAction.target.assets == null && ruleAction.target.matchedAssets == null) {
                    targetType = Notification.TargetType.USER;
                } else if (ruleAction.target.custom != null && ruleAction.target.conditionAssets == null && ruleAction.target.assets == null && ruleAction.target.matchedAssets == null) {
                    targetType = Notification.TargetType.CUSTOM;
                }
            }
            Collection<String> ids = getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts);
            if (ids == null) {
                notification.setTargets((List<Notification.Target>) null);
            } else {
                Notification.TargetType finalTargetType = targetType;
                notification.setTargets(ids.stream().map(id -> new Notification.Target(finalTargetType, id)).collect(Collectors.toList()));
            }
            log(Level.FINE, "Sending notification for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            Notification finalNotification = notification;
            return new RuleActionExecution(() -> notificationsFacade.send(finalNotification), 0);
        }
    }
    if (ruleAction instanceof RuleActionWriteAttribute) {
        if (targetIsNotAssets(ruleAction.target)) {
            return null;
        }
        RuleActionWriteAttribute attributeAction = (RuleActionWriteAttribute) ruleAction;
        if (TextUtil.isNullOrEmpty(attributeAction.attributeName)) {
            log(Level.WARNING, "Attribute name is missing for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        Collection<String> ids = getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts);
        if (ids == null || ids.isEmpty()) {
            log(Level.INFO, "No targets for write attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        log(Level.FINE, "Writing attribute '" + attributeAction.attributeName + "' for " + ids.size() + " asset(s) for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
        return new RuleActionExecution(() -> ids.forEach(id -> assetsFacade.dispatch(id, attributeAction.attributeName, attributeAction.value)), 0);
    }
    if (ruleAction instanceof RuleActionWait) {
        long millis = ((RuleActionWait) ruleAction).millis;
        if (millis > 0) {
            return new RuleActionExecution(null, millis);
        }
        log(Level.FINEST, "Invalid delay for wait rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
    }
    if (ruleAction instanceof RuleActionUpdateAttribute) {
        if (targetIsNotAssets(ruleAction.target)) {
            log(Level.FINEST, "Invalid target update attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        RuleActionUpdateAttribute attributeUpdateAction = (RuleActionUpdateAttribute) ruleAction;
        if (TextUtil.isNullOrEmpty(attributeUpdateAction.attributeName)) {
            log(Level.WARNING, "Attribute name is missing for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        List<String> matchingAssetIds;
        if (ruleAction.target == null || ruleAction.target.assets == null) {
            if (ruleAction.target != null && ruleAction.target.users != null) {
                throw new IllegalStateException("Cannot use action type '" + RuleActionUpdateAttribute.class.getSimpleName() + "' with user target");
            }
            matchingAssetIds = new ArrayList<>(getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts));
        } else {
            matchingAssetIds = facts.matchAssetState(ruleAction.target.assets).map(AssetState::getId).distinct().collect(Collectors.toList());
        }
        if (matchingAssetIds.isEmpty()) {
            log(Level.INFO, "No targets for update attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        // Look for the current value within the asset state facts (asset/attribute has to be in scope of this rule engine and have a rule state meta item)
        List<AssetState<?>> matchingAssetStates = matchingAssetIds.stream().map(assetId -> facts.getAssetStates().stream().filter(state -> state.getId().equals(assetId) && state.getName().equals(attributeUpdateAction.attributeName)).findFirst().orElseGet(() -> {
            log(Level.WARNING, "Failed to find attribute in rule states for attribute update: " + new AttributeRef(assetId, attributeUpdateAction.attributeName));
            return null;
        })).filter(Objects::nonNull).collect(Collectors.toList());
        if (matchingAssetStates.isEmpty()) {
            log(Level.WARNING, "No asset states matched to apply update attribute action to");
            return null;
        }
        return new RuleActionExecution(() -> matchingAssetStates.forEach(assetState -> {
            Object value = assetState.getValue().orElse(null);
            Class<?> valueType = assetState.getType().getType();
            boolean isArray = ValueUtil.isArray(valueType);
            if (!isArray && !ValueUtil.isObject(valueType)) {
                log(Level.WARNING, "Rule action target asset cannot determine value type or incompatible value type for attribute: " + assetState);
            } else {
                // Convert value to JSON Node to easily manipulate it
                value = isArray ? ValueUtil.convert(value, ArrayNode.class) : ValueUtil.convert(value, ObjectNode.class);
                switch(attributeUpdateAction.updateAction) {
                    case ADD:
                        if (isArray) {
                            value = value == null ? ValueUtil.JSON.createArrayNode() : value;
                            ((ArrayNode) value).add(ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                        } else {
                            value = value == null ? ValueUtil.JSON.createObjectNode() : value;
                            ((ObjectNode) value).set(attributeUpdateAction.key, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                        }
                        break;
                    case ADD_OR_REPLACE:
                    case REPLACE:
                        if (isArray) {
                            value = value == null ? ValueUtil.JSON.createArrayNode() : value;
                            ArrayNode arrayValue = (ArrayNode) value;
                            if (attributeUpdateAction.index != null && arrayValue.size() >= attributeUpdateAction.index) {
                                arrayValue.set(attributeUpdateAction.index, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            } else {
                                arrayValue.add(ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            }
                        } else {
                            value = value == null ? ValueUtil.JSON.createObjectNode() : value;
                            if (!TextUtil.isNullOrEmpty(attributeUpdateAction.key)) {
                                ((ObjectNode) value).set(attributeUpdateAction.key, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            } else {
                                log(Level.WARNING, "JSON Rule: Rule action missing required 'key': " + ValueUtil.asJSON(attributeUpdateAction));
                            }
                        }
                        break;
                    case DELETE:
                        if (value != null) {
                            if (isArray) {
                                ((ArrayNode) value).remove(attributeUpdateAction.index);
                            } else {
                                ((ObjectNode) value).remove(attributeUpdateAction.key);
                            }
                        }
                        break;
                    case CLEAR:
                        if (isArray) {
                            value = ValueUtil.JSON.createArrayNode();
                        } else {
                            value = ValueUtil.JSON.createObjectNode();
                        }
                        break;
                }
                log(Level.FINE, "Updating attribute for rule action: " + rule.name + " '" + actionsName + "' action index " + index + ": " + assetState);
                assetsFacade.dispatch(assetState.getId(), attributeUpdateAction.attributeName, value);
            }
        }), 0);
    }
    log(Level.FINE, "Unsupported rule action: " + rule.name + " '" + actionsName + "' action index " + index);
    return null;
}
Also used : AssetStorageService(org.openremote.manager.asset.AssetStorageService) java.util(java.util) AttributeRef(org.openremote.model.attribute.AttributeRef) CronExpression(org.quartz.CronExpression) LocationAttributePredicate.getLocationPredicates(org.openremote.model.query.filter.LocationAttributePredicate.getLocationPredicates) ValueUtil(org.openremote.model.util.ValueUtil) Supplier(java.util.function.Supplier) ValueUtil.distinctByKey(org.openremote.model.util.ValueUtil.distinctByKey) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Level(java.util.logging.Level) Notification(org.openremote.model.notification.Notification) UserQuery(org.openremote.model.query.UserQuery) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) EmailNotificationMessage(org.openremote.model.notification.EmailNotificationMessage) JsonNode(com.fasterxml.jackson.databind.JsonNode) TextUtil(org.openremote.model.util.TextUtil) PersistenceEvent(org.openremote.model.PersistenceEvent) LogicGroup(org.openremote.model.query.LogicGroup) org.openremote.model.rules(org.openremote.model.rules) Asset(org.openremote.model.asset.Asset) MetaItemType(org.openremote.model.value.MetaItemType) Predicate(java.util.function.Predicate) AssetQuery(org.openremote.model.query.AssetQuery) AttributePredicate(org.openremote.model.query.filter.AttributePredicate) Collectors(java.util.stream.Collectors) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) AtomicLong(java.util.concurrent.atomic.AtomicLong) PushNotificationMessage(org.openremote.model.notification.PushNotificationMessage) Stream(java.util.stream.Stream) org.openremote.model.rules.json(org.openremote.model.rules.json) TimerService(org.openremote.container.timer.TimerService) TimeUtil(org.openremote.model.util.TimeUtil) AssetQueryPredicate.groupIsEmpty(org.openremote.manager.rules.AssetQueryPredicate.groupIsEmpty) AttributeRef(org.openremote.model.attribute.AttributeRef) Notification(org.openremote.model.notification.Notification) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) EmailNotificationMessage(org.openremote.model.notification.EmailNotificationMessage) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) PushNotificationMessage(org.openremote.model.notification.PushNotificationMessage)

Example 22 with AttributeRef

use of org.openremote.model.attribute.AttributeRef in project openremote by openremote.

the class AgentResourceImpl method searchForLinkedAttributes.

@Override
public Asset[] searchForLinkedAttributes(RequestParams requestParams, String agentId, String protocolConfigurationName, String parentId, String realmId) {
    AttributeRef protocolConfigRef = new AttributeRef(agentId, protocolConfigurationName);
    Pair<Asset, String> parentAndRealmId = getParentAssetAndRealmId(parentId, realmId);
    // TODO: Allow user to select which assets/attributes are actually added to the DB
    Asset[] assets = withAgentConnector(agentId, agentConnector -> {
        LOG.finer("Asking connector '" + agentConnector.value.getClass().getSimpleName() + "' to do linked attribute discovery for protocol configuration: " + protocolConfigRef);
        return agentConnector.value.getDiscoveredLinkedAttributes(protocolConfigRef);
    });
    try {
        persistAssets(assets, parentAndRealmId.key, parentAndRealmId.value);
        return assets;
    } 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());
    }
}
Also used : AttributeRef(org.openremote.model.attribute.AttributeRef) ServerAsset(org.openremote.manager.asset.ServerAsset) Asset(org.openremote.model.asset.Asset)

Example 23 with AttributeRef

use of org.openremote.model.attribute.AttributeRef in project openremote by openremote.

the class AbstractTcpServerProtocol method doLinkProtocolConfiguration.

@Override
protected void doLinkProtocolConfiguration(AssetAttribute protocolConfiguration) {
    final AttributeRef protocolRef = protocolConfiguration.getReferenceOrThrow();
    if (!protocolConfiguration.isEnabled()) {
        updateStatus(protocolRef, ConnectionStatus.DISABLED);
        return;
    }
    int port = protocolConfiguration.getMetaItem(META_PROTOCOL_PORT).flatMap(AbstractValueHolder::getValueAsInteger).orElseThrow(() -> new IllegalArgumentException("Missing or invalid require meta item: " + META_PROTOCOL_PORT));
    Optional<StringValue> bindAddress = Values.getMetaItemValueOrThrow(protocolConfiguration, META_PROTOCOL_BIND_ADDRESS, StringValue.class, false, true);
    LOG.info("Creating TCP server instance");
    T tcpServer = createTcpServer(port, bindAddress.map(StringValue::getString).orElse(null), protocolConfiguration);
    tcpServerMap.put(protocolRef, tcpServer);
    startTcpServer(protocolRef, tcpServer);
    if (!tcpServer.isStarted()) {
        LOG.warning("Failed to start TCP server instance");
        updateStatus(protocolRef, ConnectionStatus.ERROR);
    } else {
        updateStatus(protocolRef, ConnectionStatus.CONNECTED);
    }
}
Also used : AttributeRef(org.openremote.model.attribute.AttributeRef) StringValue(org.openremote.model.value.StringValue)

Example 24 with AttributeRef

use of org.openremote.model.attribute.AttributeRef in project openremote by openremote.

the class AssetViewActivity method onAgentStatusEvent.

protected void onAgentStatusEvent(AgentStatusEvent event) {
    for (AttributeView attributeView : attributeViews) {
        AssetAttribute assetAttribute = attributeView.getAttribute();
        Optional<AttributeRef> assetAttributeRef = assetAttribute.getReference();
        if (asset.getWellKnownType() == AssetType.AGENT) {
            if (assetAttributeRef.map(ref -> ref.equals(event.getProtocolConfiguration())).orElse(false)) {
                attributeView.setStatus(event.getConnectionStatus());
            }
        } else {
            AgentLink.getAgentLink(assetAttribute).filter(agentLink -> agentLink.equals(event.getProtocolConfiguration())).ifPresent(agentLink -> {
                attributeView.setStatus(event.getConnectionStatus());
            });
        }
    }
}
Also used : SimulatorState(org.openremote.model.simulator.SimulatorState) DatapointInterval(org.openremote.model.datapoint.DatapointInterval) AssetMapper(org.openremote.app.client.assets.AssetMapper) Environment(org.openremote.app.client.Environment) ProtocolConfiguration(org.openremote.model.asset.agent.ProtocolConfiguration) AttributeRef(org.openremote.model.attribute.AttributeRef) AssetDatapointResource(org.openremote.model.datapoint.AssetDatapointResource) AttributeViewImpl(org.openremote.app.client.assets.attributes.AttributeViewImpl) ObjectValueMapper(org.openremote.app.client.interop.value.ObjectValueMapper) FormButton(org.openremote.app.client.widget.FormButton) NumberDatapoint(org.openremote.model.datapoint.NumberDatapoint) ArrayList(java.util.ArrayList) AgentLink(org.openremote.model.asset.agent.AgentLink) Inject(javax.inject.Inject) ReadAssetAttributesEvent(org.openremote.model.asset.ReadAssetAttributesEvent) TenantFilter(org.openremote.model.event.shared.TenantFilter) AttributeEvent(org.openremote.model.attribute.AttributeEvent) URL(com.google.gwt.http.client.URL) AbstractAttributeViewExtension(org.openremote.app.client.assets.attributes.AbstractAttributeViewExtension) AttributeView(org.openremote.app.client.assets.attributes.AttributeView) AgentStatusEventMapper(org.openremote.app.client.assets.AgentStatusEventMapper) Consumer(org.openremote.model.interop.Consumer) AgentResource(org.openremote.model.asset.agent.AgentResource) MapResource(org.openremote.model.map.MapResource) AgentStatusEvent(org.openremote.model.asset.agent.AgentStatusEvent) AssetType(org.openremote.model.asset.AssetType) DatapointBrowser(org.openremote.app.client.datapoint.DatapointBrowser) JsonEditor(org.openremote.app.client.app.dialog.JsonEditor) Constants(org.openremote.model.Constants) AssetResource(org.openremote.model.asset.AssetResource) Provider(com.google.inject.Provider) List(java.util.List) AssetBrowser(org.openremote.app.client.assets.browser.AssetBrowser) NumberDatapointArrayMapper(org.openremote.app.client.datapoint.NumberDatapointArrayMapper) Optional(java.util.Optional) Values(org.openremote.model.value.Values) TextUtil.isNullOrEmpty(org.openremote.model.util.TextUtil.isNullOrEmpty) AssetAttribute(org.openremote.model.asset.AssetAttribute) Datapoint(org.openremote.model.datapoint.Datapoint) Collections(java.util.Collections) Simulator(org.openremote.app.client.simulator.Simulator) AttributeExecuteStatus(org.openremote.model.attribute.AttributeExecuteStatus) AttributeView(org.openremote.app.client.assets.attributes.AttributeView) AttributeRef(org.openremote.model.attribute.AttributeRef) AssetAttribute(org.openremote.model.asset.AssetAttribute)

Example 25 with AttributeRef

use of org.openremote.model.attribute.AttributeRef in project openremote by openremote.

the class AssetViewActivity method createSimulator.

protected Simulator createSimulator(AssetAttribute attribute, AttributeViewImpl view) {
    AttributeRef protocolConfigurationRef = attribute.getReferenceOrThrow();
    return new Simulator(environment, this.view.getStyle(), view, attribute, protocolConfigurationRef, () -> {
        activeSimulators.add(protocolConfigurationRef);
        updateSimulatorSubscription();
    }, () -> {
        activeSimulators.remove(protocolConfigurationRef);
        updateSimulatorSubscription();
    });
}
Also used : AttributeRef(org.openremote.model.attribute.AttributeRef) Simulator(org.openremote.app.client.simulator.Simulator)

Aggregations

AttributeRef (org.openremote.model.attribute.AttributeRef)42 Logger (java.util.logging.Logger)9 AttributeEvent (org.openremote.model.attribute.AttributeEvent)8 AttributeState (org.openremote.model.attribute.AttributeState)8 Attribute (org.openremote.model.attribute.Attribute)7 List (java.util.List)6 Level (java.util.logging.Level)6 Container (org.openremote.model.Container)6 SyslogCategory (org.openremote.model.syslog.SyslogCategory)6 ArrayList (java.util.ArrayList)5 Map (java.util.Map)5 ScheduledFuture (java.util.concurrent.ScheduledFuture)5 Consumer (java.util.function.Consumer)5 Asset (org.openremote.model.asset.Asset)5 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)4 HashMap (java.util.HashMap)4 TimeUnit (java.util.concurrent.TimeUnit)4 AbstractProtocol (org.openremote.agent.protocol.AbstractProtocol)4 AssetStorageService (org.openremote.manager.asset.AssetStorageService)4 ConnectionStatus (org.openremote.model.asset.agent.ConnectionStatus)4