2 * Copyright (c) 2010-2023 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.livisismarthome.internal.client.api.entity.device;
15 import static org.openhab.binding.livisismarthome.internal.LivisiBindingConstants.*;
17 import java.util.Collections;
18 import java.util.List;
20 import java.util.Objects;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.openhab.binding.livisismarthome.internal.client.api.entity.capability.CapabilityDTO;
24 import org.openhab.binding.livisismarthome.internal.client.api.entity.location.LocationDTO;
25 import org.openhab.binding.livisismarthome.internal.client.api.entity.message.MessageDTO;
27 import com.google.gson.annotations.SerializedName;
30 * Defines the structure of a {@link DeviceDTO}.
32 * @author Oliver Kuhl - Initial contribution
34 public class DeviceDTO {
36 private static final String PROTOCOL_ID_COSIP = "Cosip";
37 private static final String PROTOCOL_ID_VIRTUAL = "Virtual";
38 private static final String PROTOCOL_ID_WMBUS = "wMBus";
41 * Unique id for the device, always available in model.
46 * Identifier of the manufacturer, always available in model
48 private String manufacturer;
51 * Version number of the device for the domain model.
53 * If the functionality of the device changes, the version must
54 * be increased to indicate that there are new or changed attributes
55 * of the device. Always available in model.
57 private String version;
60 * Defines the product, which is used as an identifier for selecting the
61 * right add-in to support the functionality of the device.
62 * Remark: one add-in can support multiple devices, e.g.
63 * core.RWE, which supports all RWE hardware devices (also referred to as core devices).
64 * Always available in model.
66 private String product;
69 * Device number or id like SGTIN given by the manufacturer. Optional.
71 @SerializedName("serialnumber")
72 private String serialNumber;
75 * Specifies the type of the device, which is defined by the manufacturer. The triple of device type, manufacturer
76 * and the version must be unique.
77 * Always available in model.
81 private DeviceConfigDTO config;
83 private List<String> capabilities;
85 private Map<String, CapabilityDTO> capabilityMap;
87 private DeviceStateDTO deviceState;
90 * The tag container can contain any number of properties for grouping of the devices in the client, e.g. category
91 * of device like “security related”. The tags can be freely chosen by the client and will not be considered by the
92 * system for any business logic.
97 * private List<Property> tagList;
101 * The location contains the link to the location of the device. Optional.
103 @SerializedName("location")
104 private String locationLink;
106 private transient LocationDTO location;
108 private List<MessageDTO> messageList;
110 private boolean lowBattery;
113 * Stores, if the {@link DeviceDTO} is battery powered.
115 private boolean batteryPowered = false;
120 public String getId() {
125 * @param id the id to set
127 public void setId(String id) {
132 * @return the manufacturer
134 public String getManufacturer() {
139 * @param manufacturer the manufacturer to set
141 public void setManufacturer(String manufacturer) {
142 this.manufacturer = manufacturer;
146 * @return the version
148 public String getVersion() {
153 * @param version the version to set
155 public void setVersion(String version) {
156 this.version = version;
160 * @return the product
162 public String getProduct() {
167 * @param product the product to set
169 public void setProduct(String product) {
170 this.product = product;
174 * @return the serialnumber
176 public String getSerialNumber() {
181 * @param serialNumber the serialnumber to set
183 public void setSerialNumber(String serialNumber) {
184 this.serialNumber = serialNumber;
188 * Returns true, if the {@link DeviceDTO} has a serial number.
190 * @return true if the device has serial number, otherwise false
192 public boolean hasSerialNumber() {
193 return serialNumber != null && !serialNumber.isEmpty();
199 public String getType() {
204 * @param type the type to set
206 public void setType(String type) {
213 public DeviceConfigDTO getConfig() {
218 * @param config the config to set
220 public void setConfig(DeviceConfigDTO config) {
221 this.config = config;
225 * Returns the {@link DeviceStateDTO}. Only available, if device has a state. Better check with
226 * {@link DeviceDTO#hasDeviceState()} first!
228 * @return the entityState or null
230 public DeviceStateDTO getDeviceState() {
235 * @param deviceState the deviceState to set
237 public void setDeviceState(DeviceStateDTO deviceState) {
238 this.deviceState = deviceState;
242 * Returns, if the {@link DeviceDTO} has a state. Not all {@link DeviceDTO}s have a state.
244 * @return true if the device has a device state, otherwise false
246 public boolean hasDeviceState() {
247 return deviceState != null;
251 * @return the capabilityList
253 public List<String> getCapabilities() {
254 return Objects.requireNonNullElse(capabilities, Collections.emptyList());
258 * @param capabilityList the capabilityList to set
260 public void setCapabilities(List<String> capabilityList) {
261 this.capabilities = capabilityList;
265 * @param capabilityMap the capabilityMap to set
267 public void setCapabilityMap(Map<String, CapabilityDTO> capabilityMap) {
268 this.capabilityMap = capabilityMap;
272 * @return the capabilityMap
274 public Map<String, CapabilityDTO> getCapabilityMap() {
275 if (capabilityMap != null) {
276 return capabilityMap;
278 return Collections.emptyMap();
282 * Returns the {@link CapabilityDTO} with the given id.
284 * @param id capability id
287 public CapabilityDTO getCapabilityWithId(String id) {
288 return this.capabilityMap.get(id);
292 * @return the locationLink
294 public String getLocationLink() {
299 * @param locationLink the locationList to set
301 public void setLocation(String locationLink) {
302 this.locationLink = locationLink;
306 * Returns the id of the {@link LocationDTO}
308 * @return location id
310 public String getLocationId() {
311 if (locationLink != null) {
312 return locationLink.replace("/location/", "");
318 * Returns the {@link LocationDTO} of the {@link DeviceDTO}. Better check with {@link DeviceDTO#hasLocation()}
320 * all devices have one.
322 * @return the location
324 public LocationDTO getLocation() {
329 * @param location the location to set
331 public void setLocation(LocationDTO location) {
332 this.location = location;
336 * Returns, if the {@link DeviceDTO} has a {@link LocationDTO}. Not all devices have a {@link LocationDTO}...
338 * @return boolean true, if a {@link LocationDTO} is set, else false
340 public boolean hasLocation() {
341 return location != null;
344 public @NonNull String getLocationName() {
345 LocationDTO location = getLocation();
346 if (location != null && location.getName() != null) {
347 return location.getName();
353 * @return the messageList
355 public List<MessageDTO> getMessageList() {
356 if (messageList != null) {
359 return Collections.emptyList();
363 * @param messageList the messageList to set
365 public void setMessageList(List<MessageDTO> messageList) {
366 this.messageList = messageList;
367 applyMessageList(messageList);
370 private void applyMessageList(List<MessageDTO> messageList) {
371 if (messageList != null && !messageList.isEmpty()) {
372 boolean isUnreachableMessageFound = false;
373 boolean isLowBatteryMessageFound = false;
374 for (final MessageDTO message : messageList) {
375 switch (message.getType()) {
376 case MessageDTO.TYPE_DEVICE_UNREACHABLE:
377 isUnreachableMessageFound = true;
379 case MessageDTO.TYPE_DEVICE_LOW_BATTERY:
380 isLowBatteryMessageFound = true;
384 if (isUnreachableMessageFound) {
385 setReachable(false); // overwrite only when there is a corresponding message (to keep the state of the
386 // API in other cases)
388 if (isLowBatteryMessageFound) {
389 setLowBattery(true); // overwrite only when there is a corresponding message (to keep the state of the
390 // API in other cases)
396 * Sets if the {@link DeviceDTO} is reachable;
398 * @param isReachable reachable (boolean)
400 private void setReachable(boolean isReachable) {
401 if (getDeviceState().hasIsReachableState()) {
402 getDeviceState().setReachable(isReachable);
407 * Returns if the {@link DeviceDTO} is reachable.
409 * @return reachable (boolean)
411 public Boolean isReachable() {
412 if (hasDeviceState() && getDeviceState().hasIsReachableState()) {
413 return getDeviceState().isReachable();
419 * Sets the low battery state for the {@link DeviceDTO}.
421 * @param isBatteryLow true if the battery is low, otherwise false
423 public void setLowBattery(boolean isBatteryLow) {
424 this.lowBattery = isBatteryLow;
428 * Returns true if the {@link DeviceDTO} has a low battery warning. Only available on battery devices.
430 * @return true if the battery is low, otherwise false
432 public boolean hasLowBattery() {
437 * Returns true, if the {@link DeviceDTO} is battery powered.
439 * @return true if the device is battery powered, otherwise false
441 public boolean isBatteryPowered() {
442 return batteryPowered;
446 * Sets if the device is battery powered.
448 * @param isBatteryPowerd true if the device is battery powered, otherwise false
450 public void setIsBatteryPowered(boolean isBatteryPowerd) {
451 batteryPowered = isBatteryPowerd;
455 * Returns true, if the {@link DeviceDTO} has {@link MessageDTO}s.
457 * @return true if messages accoring the device are available, otherwise false
459 public boolean hasMessages() {
460 return (messageList != null && !messageList.isEmpty());
464 * Returns true if the device is a SmartHomeController (SHC).
466 * @return true if the device is a SmartHomeController (SHC) otherwise false
468 public boolean isController() {
469 return isClassicController() || DEVICE_SHCA.equals(type);
473 * Returns true if the device is a classic controller (SHC, before Gen 2.).
475 * @return true if it is a classic controller, otherwise false
477 public boolean isClassicController() {
478 return DEVICE_SHC.equals(type);
482 * Returns true, if the {@link DeviceDTO} is a virtual device (e.g. a VariableActuator).
484 * @return true if it is a virtual device, otherwise false
486 public boolean isVirtualDevice() {
487 return PROTOCOL_ID_VIRTUAL.equals(getConfig().getProtocolId());
491 * Returns true, if the {@link DeviceDTO} is a radio device.
493 * @return true if it is a radio device, otherwise false
495 public boolean isRadioDevice() {
496 return isCoSipDevice() || isWMBusDevice();
500 * Returns true, if the {@link DeviceDTO} is a CoSip device.
502 * @return true if it is a CoSip device, otherwise false
504 public boolean isCoSipDevice() {
505 return PROTOCOL_ID_COSIP.equals(getConfig().getProtocolId());
509 * Returns true, if the {@link DeviceDTO} is a W-Mbus device.
511 * @return true if it is a W-Mbus device, otherwise false
513 public boolean isWMBusDevice() {
514 return PROTOCOL_ID_WMBUS.equals(getConfig().getProtocolId());
518 public String toString() {
519 return "Device [" + "id=" + getId() + " manufacturer=" + getManufacturer() + " version=" + getVersion()
520 + " product=" + getProduct() + " serialnumber=" + getSerialNumber() + " type=" + getType() + " name="
521 + getConfig().getName() + "]";