]> git.basschouten.com Git - openhab-addons.git/blob
924d6b847509bb184499d997ed63befb98bcbf10
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.shelly.internal.discovery;
14
15 import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
16 import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*;
17 import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
18
19 import java.util.LinkedHashMap;
20 import java.util.Map;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.core.thing.ThingTypeUID;
24 import org.openhab.core.thing.ThingUID;
25
26 /**
27  * The {@link ShellyThingCreator} maps the device id into the thing type id
28  *
29  * @author Markus Michels - Initial contribution
30  */
31 @NonNullByDefault
32 public class ShellyThingCreator {
33     private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>();
34     static {
35         // mapping by device type id
36         THING_TYPE_MAPPING.put(SHELLYDT_1PM, THING_TYPE_SHELLY1PM_STR);
37         THING_TYPE_MAPPING.put(SHELLYDT_1L, THING_TYPE_SHELLY1L_STR);
38         THING_TYPE_MAPPING.put(SHELLYDT_1, THING_TYPE_SHELLY1_STR);
39         THING_TYPE_MAPPING.put(SHELLYDT_3EM, THING_TYPE_SHELLY3EM_STR);
40         THING_TYPE_MAPPING.put(SHELLYDT_EM, THING_TYPE_SHELLYEM_STR);
41         THING_TYPE_MAPPING.put(SHELLYDT_SHPLG_S, THING_TYPE_SHELLYPLUGS_STR);
42         THING_TYPE_MAPPING.put(SHELLYDT_SHPLG_U1, THING_TYPE_SHELLYPLUGU1_STR);
43         THING_TYPE_MAPPING.put(SHELLYDT_GAS, THING_TYPE_SHELLYGAS_STR);
44         THING_TYPE_MAPPING.put(SHELLYDT_DW, THING_TYPE_SHELLYDOORWIN_STR);
45         THING_TYPE_MAPPING.put(SHELLYDT_DW2, THING_TYPE_SHELLYDOORWIN2_STR);
46         THING_TYPE_MAPPING.put(SHELLYDT_DUO, THING_TYPE_SHELLYDUO_STR);
47         THING_TYPE_MAPPING.put(SHELLYDT_DUORGBW, THING_TYPE_SHELLYDUORGBW_STR);
48         THING_TYPE_MAPPING.put(SHELLYDT_BULB, THING_TYPE_SHELLYBULB_STR);
49         THING_TYPE_MAPPING.put(SHELLYDT_VINTAGE, THING_TYPE_SHELLYVINTAGE_STR);
50         THING_TYPE_MAPPING.put(SHELLYDT_DIMMER, THING_TYPE_SHELLYDIMMER_STR);
51         THING_TYPE_MAPPING.put(SHELLYDT_DIMMER2, THING_TYPE_SHELLYDIMMER2_STR);
52         THING_TYPE_MAPPING.put(SHELLYDT_IX3, THING_TYPE_SHELLYIX3_STR);
53         THING_TYPE_MAPPING.put(SHELLYDT_BUTTON1, THING_TYPE_SHELLYBUTTON1_STR);
54         THING_TYPE_MAPPING.put(SHELLYDT_BUTTON2, THING_TYPE_SHELLYBUTTON2_STR);
55         THING_TYPE_MAPPING.put(SHELLYDT_UNI, THING_TYPE_SHELLYUNI_STR);
56         THING_TYPE_MAPPING.put(SHELLYDT_HT, THING_TYPE_SHELLYHT_STR);
57         THING_TYPE_MAPPING.put(SHELLYDT_TRV, THING_TYPE_SHELLYTRV_STR);
58         THING_TYPE_MAPPING.put(SHELLYDT_MOTION, THING_TYPE_SHELLYMOTION_STR);
59
60         // mapping by thing type
61         THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1_STR, THING_TYPE_SHELLY1_STR);
62         THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1PM_STR, THING_TYPE_SHELLY1PM_STR);
63         THING_TYPE_MAPPING.put(THING_TYPE_SHELLY1L_STR, THING_TYPE_SHELLY1L_STR);
64         THING_TYPE_MAPPING.put(THING_TYPE_SHELLY4PRO_STR, THING_TYPE_SHELLY4PRO_STR);
65         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDIMMER2_STR, THING_TYPE_SHELLYDIMMER2_STR);
66         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDIMMER_STR, THING_TYPE_SHELLYDIMMER_STR);
67         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYIX3_STR, THING_TYPE_SHELLYIX3_STR);
68         THING_TYPE_MAPPING.put(THING_TYPE_SHELLY3EM_STR, THING_TYPE_SHELLY3EM_STR);
69         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYEM_STR, THING_TYPE_SHELLYEM_STR);
70         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDUORGBW_STR, THING_TYPE_SHELLYDUORGBW_STR);
71         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDUO_STR, THING_TYPE_SHELLYDUO_STR);
72         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYVINTAGE_STR, THING_TYPE_SHELLYVINTAGE_STR);
73         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYBULB_STR, THING_TYPE_SHELLYBULB_STR);
74         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDUO_STR, THING_TYPE_SHELLYDUO_STR);
75         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYHT_STR, THING_TYPE_SHELLYHT_STR);
76         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYSMOKE_STR, THING_TYPE_SHELLYSMOKE_STR);
77         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYGAS_STR, THING_TYPE_SHELLYGAS_STR);
78         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYFLOOD_STR, THING_TYPE_SHELLYFLOOD_STR);
79         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYTRV_STR, THING_TYPE_SHELLYTRV_STR);
80         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDOORWIN_STR, THING_TYPE_SHELLYDOORWIN_STR);
81         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYDOORWIN2_STR, THING_TYPE_SHELLYDOORWIN2_STR);
82         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYSENSE_STR, THING_TYPE_SHELLYSENSE_STR);
83         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYEYE_STR, THING_TYPE_SHELLYEYE_STR);
84         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYBUTTON1_STR, THING_TYPE_SHELLYBUTTON1_STR);
85         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYBUTTON2_STR, THING_TYPE_SHELLYBUTTON2_STR);
86         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYUNI_STR, THING_TYPE_SHELLYUNI_STR);
87         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYMOTION2_STR, THING_TYPE_SHELLYMOTION_STR);
88
89         THING_TYPE_MAPPING.put(THING_TYPE_SHELLYPROTECTED_STR, THING_TYPE_SHELLYPROTECTED_STR);
90     }
91
92     public static ThingUID getThingUID(String serviceName, String deviceType, String mode, boolean unknown) {
93         String devid = substringAfterLast(serviceName, "-");
94         if (devid.isEmpty()) {
95             throw new IllegalArgumentException("serviceName has improper format: " + serviceName);
96         }
97         return new ThingUID(!unknown ? getThingTypeUID(serviceName, deviceType, mode)
98                 : getThingTypeUID(THING_TYPE_SHELLYPROTECTED_STR + "-" + devid, deviceType, mode), devid);
99     }
100
101     public static ThingTypeUID getThingTypeUID(String serviceName, String deviceType, String mode) {
102         return new ThingTypeUID(BINDING_ID, getThingType(serviceName, deviceType, mode));
103     }
104
105     public static ThingTypeUID getUnknownTTUID() {
106         return new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYPROTECTED_STR);
107     }
108
109     public static String getThingType(String hostname, String deviceType, String mode) {
110         if (THING_TYPE_SHELLYPROTECTED_STR.equals(hostname)) {
111             return THING_TYPE_SHELLYPROTECTED_STR;
112         }
113         String name = hostname.toLowerCase();
114         String type = substringBefore(name, "-").toLowerCase();
115         String devid = substringAfterLast(name, "-");
116         if (devid.isEmpty() || type.isEmpty()) {
117             throw new IllegalArgumentException("Invalid device name format: " + hostname);
118         }
119
120         // First check for special handling
121         if (name.startsWith(THING_TYPE_SHELLY25_PREFIX)) { // Shelly v2.5
122             return mode.equals(SHELLY_MODE_RELAY) ? THING_TYPE_SHELLY25_RELAY_STR : THING_TYPE_SHELLY25_ROLLER_STR;
123         }
124         if (name.startsWith(THING_TYPE_SHELLY2_PREFIX)) { // Shelly v2
125             return mode.equals(SHELLY_MODE_RELAY) ? THING_TYPE_SHELLY2_RELAY_STR : THING_TYPE_SHELLY2_ROLLER_STR;
126         }
127         if (name.startsWith(THING_TYPE_SHELLYPLUG_STR)) {
128             // shellyplug-s needs to be mapped to shellyplugs to follow the schema
129             // for the thing types: <thing type>-<mode>
130             if (name.startsWith(THING_TYPE_SHELLYPLUGS_STR) || name.contains("-s")) {
131                 return THING_TYPE_SHELLYPLUGS_STR;
132             }
133             if (name.startsWith(THING_TYPE_SHELLYPLUGU1_STR)) {
134                 return THING_TYPE_SHELLYPLUGU1_STR;
135             }
136             return THING_TYPE_SHELLYPLUG_STR;
137         }
138         if (name.startsWith(THING_TYPE_SHELLYRGBW2_PREFIX)) {
139             return mode.equals(SHELLY_MODE_COLOR) ? THING_TYPE_SHELLYRGBW2_COLOR_STR : THING_TYPE_SHELLYRGBW2_WHITE_STR;
140         }
141         if (name.startsWith(THING_TYPE_SHELLYMOTION_STR)) {
142             // depending on firmware release the Motion advertises under shellymotion-xxx or shellymotionsensor-xxxx
143             return THING_TYPE_SHELLYMOTION_STR;
144         }
145
146         // Check general mapping
147         if (!deviceType.isEmpty()) {
148             String res = THING_TYPE_MAPPING.get(deviceType); // by device type
149             if (res != null) {
150                 return res;
151             }
152
153             String dt = mode.equals(SHELLY_MODE_RELAY) || mode.equals(SHELLY_MODE_ROLLER) ? deviceType + "-" + mode
154                     : deviceType;
155             res = THING_TYPE_MAPPING.get(dt); // <DT>-relay / <DT>-roller
156             if (res != null) {
157                 return res;
158             }
159         }
160
161         String res = THING_TYPE_MAPPING.get(type);
162         if (res != null) {
163             return res;
164         }
165         return THING_TYPE_SHELLYUNKNOWN_STR;
166     }
167 }