2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mqtt.generic;
15 import java.lang.ref.WeakReference;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.core.transform.TransformationException;
20 import org.openhab.core.transform.TransformationService;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 * A transformation for a {@link ChannelState}. It is applied for each received value on an MQTT topic.
27 * @author David Graeff - Initial contribution
30 public class ChannelStateTransformation {
31 private final Logger logger = LoggerFactory.getLogger(ChannelStateTransformation.class);
32 private final TransformationServiceProvider provider;
33 private WeakReference<@Nullable TransformationService> transformationService = new WeakReference<>(null);
35 final String serviceName;
38 * Creates a new channel state transformer.
40 * @param pattern A transformation pattern, starting with the transformation service
41 * name,followed by a colon and the transformation itself. An Example:
42 * JSONPATH:$.device.status.temperature for a json {device: {status: {
43 * temperature: 23.2 }}}.
44 * @param provider The transformation service provider
46 public ChannelStateTransformation(String pattern, TransformationServiceProvider provider) {
47 this.provider = provider;
48 int index = pattern.indexOf(':');
50 throw new IllegalArgumentException(
51 "The transformation pattern must consist of the type and the pattern separated by a colon");
53 String type = pattern.substring(0, index).toUpperCase();
54 this.pattern = pattern.substring(index + 1);
55 this.serviceName = type;
59 * Creates a new channel state transformer.
61 * @param serviceName A transformation service name.
62 * @param pattern A transformation. An Example:
63 * $.device.status.temperature for a json {device: {status: {
64 * temperature: 23.2 }}} (for type <code>JSONPATH</code>).
65 * @param provider The transformation service provider
67 public ChannelStateTransformation(String serviceName, String pattern, TransformationServiceProvider provider) {
68 this.serviceName = serviceName;
69 this.pattern = pattern;
70 this.provider = provider;
74 * Will be called by the {@link ChannelState} for each incoming MQTT value.
76 * @param value The incoming value
77 * @return The transformed value
79 protected @Nullable String processValue(String value) {
80 TransformationService transformationService = this.transformationService.get();
81 if (transformationService == null) {
82 transformationService = provider.getTransformationService(serviceName);
83 if (transformationService == null) {
84 logger.warn("Transformation service {} for pattern {} not found!", serviceName, pattern);
87 this.transformationService = new WeakReference<>(transformationService);
89 String returnValue = null;
91 returnValue = transformationService.transform(pattern, value);
92 } catch (TransformationException e) {
93 logger.warn("Executing the {}-transformation failed: {}. Pattern: '{}'. Value: '{}'", serviceName,
94 e.getMessage(), pattern, value);