]> git.basschouten.com Git - openhab-addons.git/blob
dda84ada74e1563b790fea21d502e5106e9d6161
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.mqtt.homeassistant.internal.config.dto;
14
15 import java.util.List;
16 import java.util.Map;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.mqtt.homeassistant.internal.exception.ConfigurationException;
21 import org.openhab.core.thing.Thing;
22 import org.openhab.core.util.UIDUtils;
23
24 import com.google.gson.Gson;
25 import com.google.gson.JsonSyntaxException;
26 import com.google.gson.annotations.SerializedName;
27
28 /**
29  * Base class for home assistant configurations.
30  *
31  * @author Jochen Klein - Initial contribution
32  */
33 @NonNullByDefault
34 public abstract class AbstractChannelConfiguration {
35     public static final char PARENT_TOPIC_PLACEHOLDER = '~';
36
37     protected String name;
38
39     protected String icon = "";
40     protected int qos; // defaults to 0 according to HA specification
41     protected boolean retain; // defaults to false according to HA specification
42     @SerializedName("value_template")
43     protected @Nullable String valueTemplate;
44     @SerializedName("unique_id")
45     protected @Nullable String uniqueId;
46
47     @SerializedName("availability_mode")
48     protected AvailabilityMode availabilityMode = AvailabilityMode.LATEST;
49     @SerializedName("availability_topic")
50     protected @Nullable String availabilityTopic;
51     @SerializedName("payload_available")
52     protected String payloadAvailable = "online";
53     @SerializedName("payload_not_available")
54     protected String payloadNotAvailable = "offline";
55     @SerializedName("availability_template")
56     protected @Nullable String availabilityTemplate;
57
58     /**
59      * A list of MQTT topics subscribed to receive availability (online/offline) updates. Must not be used together with
60      * availability_topic
61      */
62     protected @Nullable List<Availability> availability;
63
64     @SerializedName(value = "~")
65     protected String parentTopic = "";
66
67     protected @Nullable Device device;
68
69     /**
70      * Parse the base properties of the configJSON into an {@link AbstractChannelConfiguration}
71      *
72      * @param configJSON channels configuration in JSON
73      * @param gson parser
74      * @return configuration object
75      */
76     public static AbstractChannelConfiguration fromString(final String configJSON, final Gson gson) {
77         return fromString(configJSON, gson, Config.class);
78     }
79
80     protected AbstractChannelConfiguration(String defaultName) {
81         this.name = defaultName;
82     }
83
84     public String getThingName() {
85         String result = null;
86
87         if (this.device != null) {
88             result = this.device.name;
89         }
90         if (result == null) {
91             result = name;
92         }
93         return result;
94     }
95
96     public String getThingId(String defaultId) {
97         String result = null;
98         if (this.device != null) {
99             result = this.device.getId();
100         }
101         if (result == null) {
102             result = uniqueId;
103         }
104         return UIDUtils.encode(result != null ? result : defaultId);
105     }
106
107     public Map<String, Object> appendToProperties(Map<String, Object> properties) {
108         final Device d = device;
109         if (d == null) {
110             return properties;
111         }
112         final String manufacturer = d.manufacturer;
113         if (manufacturer != null) {
114             properties.put(Thing.PROPERTY_VENDOR, manufacturer);
115         }
116         final String model = d.model;
117         if (model != null) {
118             properties.put(Thing.PROPERTY_MODEL_ID, model);
119         }
120         final String swVersion = d.swVersion;
121         if (swVersion != null) {
122             properties.put(Thing.PROPERTY_FIRMWARE_VERSION, swVersion);
123         }
124         return properties;
125     }
126
127     public String getName() {
128         return name;
129     }
130
131     public String getIcon() {
132         return icon;
133     }
134
135     public int getQos() {
136         return qos;
137     }
138
139     public boolean isRetain() {
140         return retain;
141     }
142
143     @Nullable
144     public String getValueTemplate() {
145         return valueTemplate;
146     }
147
148     @Nullable
149     public String getUniqueId() {
150         return uniqueId;
151     }
152
153     @Nullable
154     public String getAvailabilityTopic() {
155         return availabilityTopic;
156     }
157
158     public String getPayloadAvailable() {
159         return payloadAvailable;
160     }
161
162     public String getPayloadNotAvailable() {
163         return payloadNotAvailable;
164     }
165
166     @Nullable
167     public String getAvailabilityTemplate() {
168         return availabilityTemplate;
169     }
170
171     @Nullable
172     public Device getDevice() {
173         return device;
174     }
175
176     @Nullable
177     public List<Availability> getAvailability() {
178         return availability;
179     }
180
181     public String getParentTopic() {
182         return parentTopic;
183     }
184
185     public AvailabilityMode getAvailabilityMode() {
186         return availabilityMode;
187     }
188
189     /**
190      * This class is needed, to be able to parse only the common base attributes.
191      * Without this, {@link AbstractChannelConfiguration} cannot be instantiated, as it is abstract.
192      * This is needed during the discovery.
193      */
194     private static class Config extends AbstractChannelConfiguration {
195         public Config() {
196             super("private");
197         }
198     }
199
200     /**
201      * Parse the configJSON into a subclass of {@link AbstractChannelConfiguration}
202      *
203      * @param configJSON channels configuration in JSON
204      * @param gson parser
205      * @param clazz target configuration class
206      * @return configuration object
207      */
208     public static <C extends AbstractChannelConfiguration> C fromString(final String configJSON, final Gson gson,
209             final Class<C> clazz) {
210         try {
211             @Nullable
212             final C config = gson.fromJson(configJSON, clazz);
213             if (config == null) {
214                 throw new ConfigurationException("Channel configuration is empty");
215             }
216             return config;
217         } catch (JsonSyntaxException e) {
218             throw new ConfigurationException("Cannot parse channel configuration JSON", e);
219         }
220     }
221 }