]> git.basschouten.com Git - openhab-addons.git/blob
2ac81a0e8ab7a3e9e46247bf4d8fab5962f455ee
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.netatmo.internal.api.data;
14
15 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
16 import static org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.*;
17
18 import java.net.URI;
19 import java.util.EnumSet;
20 import java.util.List;
21 import java.util.Optional;
22 import java.util.Set;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
27 import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.MeasureClass;
28 import org.openhab.binding.netatmo.internal.handler.capability.AirCareCapability;
29 import org.openhab.binding.netatmo.internal.handler.capability.AlarmEventCapability;
30 import org.openhab.binding.netatmo.internal.handler.capability.CameraCapability;
31 import org.openhab.binding.netatmo.internal.handler.capability.Capability;
32 import org.openhab.binding.netatmo.internal.handler.capability.ChannelHelperCapability;
33 import org.openhab.binding.netatmo.internal.handler.capability.DeviceCapability;
34 import org.openhab.binding.netatmo.internal.handler.capability.DoorbellCapability;
35 import org.openhab.binding.netatmo.internal.handler.capability.HomeCapability;
36 import org.openhab.binding.netatmo.internal.handler.capability.MeasureCapability;
37 import org.openhab.binding.netatmo.internal.handler.capability.PersonCapability;
38 import org.openhab.binding.netatmo.internal.handler.capability.PresenceCapability;
39 import org.openhab.binding.netatmo.internal.handler.capability.RoomCapability;
40 import org.openhab.binding.netatmo.internal.handler.capability.WeatherCapability;
41 import org.openhab.binding.netatmo.internal.handler.channelhelper.AirQualityChannelHelper;
42 import org.openhab.binding.netatmo.internal.handler.channelhelper.ApiBridgeChannelHelper;
43 import org.openhab.binding.netatmo.internal.handler.channelhelper.CameraChannelHelper;
44 import org.openhab.binding.netatmo.internal.handler.channelhelper.DoorTagChannelHelper;
45 import org.openhab.binding.netatmo.internal.handler.channelhelper.EnergyChannelHelper;
46 import org.openhab.binding.netatmo.internal.handler.channelhelper.EventCameraChannelHelper;
47 import org.openhab.binding.netatmo.internal.handler.channelhelper.EventPersonChannelHelper;
48 import org.openhab.binding.netatmo.internal.handler.channelhelper.PersonChannelHelper;
49 import org.openhab.binding.netatmo.internal.handler.channelhelper.PresenceChannelHelper;
50 import org.openhab.binding.netatmo.internal.handler.channelhelper.PressureChannelHelper;
51 import org.openhab.binding.netatmo.internal.handler.channelhelper.RainChannelHelper;
52 import org.openhab.binding.netatmo.internal.handler.channelhelper.RoomChannelHelper;
53 import org.openhab.binding.netatmo.internal.handler.channelhelper.SecurityChannelHelper;
54 import org.openhab.binding.netatmo.internal.handler.channelhelper.SetpointChannelHelper;
55 import org.openhab.binding.netatmo.internal.handler.channelhelper.SirenChannelHelper;
56 import org.openhab.binding.netatmo.internal.handler.channelhelper.Therm1ChannelHelper;
57 import org.openhab.binding.netatmo.internal.handler.channelhelper.WindChannelHelper;
58 import org.openhab.core.thing.ThingTypeUID;
59
60 /**
61  * This enum describes all Netatmo modules and devices along with their capabilities.
62  *
63  * @author GaĆ«l L'hopital - Initial contribution
64  */
65 @NonNullByDefault
66 public enum ModuleType {
67     UNKNOWN(FeatureArea.NONE, "", 1, "virtual", null, Set.of()),
68
69     ACCOUNT(FeatureArea.NONE, "", 1, "api_bridge", null, Set.of(),
70             new ChannelGroup(ApiBridgeChannelHelper.class, GROUP_MONITORING)),
71
72     HOME(FeatureArea.NONE, "NAHome", 1, "home", ACCOUNT,
73             Set.of(DeviceCapability.class, HomeCapability.class, ChannelHelperCapability.class),
74             new ChannelGroup(SecurityChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_SECURITY),
75             new ChannelGroup(EnergyChannelHelper.class, GROUP_ENERGY)),
76
77     PERSON(FeatureArea.SECURITY, "NAPerson", 1, "virtual", HOME,
78             Set.of(PersonCapability.class, ChannelHelperCapability.class),
79             new ChannelGroup(PersonChannelHelper.class, GROUP_PERSON),
80             new ChannelGroup(EventPersonChannelHelper.class, GROUP_PERSON_LAST_EVENT)),
81
82     WELCOME(FeatureArea.SECURITY, "NACamera", 1, "camera", HOME,
83             Set.of(CameraCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
84             new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE)),
85
86     TAG(FeatureArea.SECURITY, "NACamDoorTag", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class),
87             ChannelGroup.SIGNAL, ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP,
88             new ChannelGroup(DoorTagChannelHelper.class, GROUP_TAG)),
89
90     SIREN(FeatureArea.SECURITY, "NIS", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
91             ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(SirenChannelHelper.class, GROUP_SIREN)),
92
93     PRESENCE(FeatureArea.SECURITY, "NOC", 1, "camera", HOME,
94             Set.of(PresenceCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
95             new ChannelGroup(PresenceChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE,
96                     GROUP_PRESENCE),
97             new ChannelGroup(EventCameraChannelHelper.class, GROUP_SUB_EVENT)),
98
99     DOORBELL(FeatureArea.SECURITY, "NDB", 1, "camera", HOME,
100             Set.of(DoorbellCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
101             new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_DOORBELL_STATUS,
102                     GROUP_DOORBELL_LIVE),
103             new ChannelGroup(EventCameraChannelHelper.class, GROUP_DOORBELL_LAST_EVENT, GROUP_DOORBELL_SUB_EVENT)),
104
105     WEATHER_STATION(FeatureArea.WEATHER, "NAMain", 1, "configurable", ACCOUNT,
106             Set.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class,
107                     ChannelHelperCapability.class),
108             ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE,
109             ChannelGroup.AIR_QUALITY, ChannelGroup.LOCATION, ChannelGroup.NOISE, ChannelGroup.TEMP_INSIDE_EXT,
110             new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_TYPE_PRESSURE_EXTENDED)),
111
112     OUTDOOR(FeatureArea.WEATHER, "NAModule1", 1, "device", WEATHER_STATION,
113             Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY,
114             ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.TEMP_OUTSIDE_EXT),
115
116     WIND(FeatureArea.WEATHER, "NAModule2", 1, "device", WEATHER_STATION, Set.of(ChannelHelperCapability.class),
117             ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.BATTERY,
118             new ChannelGroup(WindChannelHelper.class, GROUP_WIND)),
119
120     RAIN(FeatureArea.WEATHER, "NAModule3", 1, "device", WEATHER_STATION,
121             Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
122             ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
123             new ChannelGroup(RainChannelHelper.class, MeasureClass.RAIN_QUANTITY, GROUP_RAIN)),
124
125     INDOOR(FeatureArea.WEATHER, "NAModule4", 1, "device", WEATHER_STATION,
126             Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
127             ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.HUMIDITY,
128             ChannelGroup.TEMP_INSIDE_EXT, ChannelGroup.AIR_QUALITY),
129
130     HOME_COACH(FeatureArea.AIR_CARE, "NHC", 1, "configurable", ACCOUNT,
131             Set.of(DeviceCapability.class, AirCareCapability.class, MeasureCapability.class,
132                     ChannelHelperCapability.class),
133             ChannelGroup.LOCATION, ChannelGroup.SIGNAL, ChannelGroup.NOISE, ChannelGroup.HUMIDITY,
134             ChannelGroup.TEMP_INSIDE, ChannelGroup.MEASURE, ChannelGroup.TSTAMP_EXT,
135             new ChannelGroup(AirQualityChannelHelper.class, GROUP_TYPE_AIR_QUALITY_EXTENDED),
136             new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_PRESSURE)),
137
138     PLUG(FeatureArea.ENERGY, "NAPlug", 1, "device", HOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL),
139
140     VALVE(FeatureArea.ENERGY, "NRV", 1, "device", PLUG, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
141             ChannelGroup.BATTERY_EXT),
142
143     THERMOSTAT(FeatureArea.ENERGY, "NATherm1", 1, "device", PLUG, Set.of(ChannelHelperCapability.class),
144             ChannelGroup.SIGNAL, ChannelGroup.BATTERY_EXT,
145             new ChannelGroup(Therm1ChannelHelper.class, GROUP_TYPE_TH_PROPERTIES)),
146
147     ROOM(FeatureArea.ENERGY, "NARoom", 1, "virtual", HOME, Set.of(RoomCapability.class, ChannelHelperCapability.class),
148             new ChannelGroup(RoomChannelHelper.class, GROUP_TYPE_ROOM_PROPERTIES, GROUP_TYPE_ROOM_TEMPERATURE),
149             new ChannelGroup(SetpointChannelHelper.class, GROUP_SETPOINT)),
150
151     SMOKE_DETECTOR(FeatureArea.SECURITY, "NSD", 1, "device", HOME,
152             Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
153             ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT),
154
155     CO_DETECTOR(FeatureArea.SECURITY, "NCO", 1, "device", HOME,
156             Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
157             ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT);
158
159     public static final EnumSet<ModuleType> AS_SET = EnumSet.allOf(ModuleType.class);
160
161     private final Optional<ModuleType> bridgeType;
162     public final Set<ChannelGroup> channelGroups;
163     public final Set<Class<? extends Capability>> capabilities;
164     public final ThingTypeUID thingTypeUID;
165     public final FeatureArea feature;
166     public final String apiName;
167     public final String thingTypeVersion;
168     public final URI configDescription;
169
170     ModuleType(FeatureArea feature, String apiName, int thingTypeVersion, String config, @Nullable ModuleType bridge,
171             Set<Class<? extends Capability>> capabilities, ChannelGroup... channelGroups) {
172         this.bridgeType = Optional.ofNullable(bridge);
173         this.feature = feature;
174         this.capabilities = capabilities;
175         this.apiName = apiName;
176         this.channelGroups = Set.of(channelGroups);
177         this.thingTypeUID = new ThingTypeUID(BINDING_ID, name().toLowerCase().replace("_", "-"));
178         this.thingTypeVersion = Integer.toString(thingTypeVersion);
179         this.configDescription = URI.create(BINDING_ID + ":" + config);
180     }
181
182     public boolean isLogical() {
183         return !channelGroups.contains(ChannelGroup.SIGNAL);
184     }
185
186     public boolean isABridge() { // I am a bridge if any module references me as being so
187         return AS_SET.stream().anyMatch(mt -> this.equals(mt.getBridge()));
188     }
189
190     public List<String> getExtensions() {
191         return channelGroups.stream().map(cg -> cg.extensions).flatMap(Set::stream).toList();
192     }
193
194     public List<String> getGroupTypes() {
195         return channelGroups.stream().map(cg -> cg.groupTypes).flatMap(Set::stream).toList();
196     }
197
198     public int[] getSignalLevels() {
199         if (!isLogical()) {
200             return (channelGroups.contains(ChannelGroup.BATTERY) || channelGroups.contains(ChannelGroup.BATTERY_EXT))
201                     ? RADIO_SIGNAL_LEVELS
202                     : WIFI_SIGNAL_LEVELS;
203         }
204         throw new IllegalArgumentException(
205                 "getSignalLevels should not be called for module type: '%s', please file a bug report."
206                         .formatted(name()));
207     }
208
209     public ModuleType getBridge() {
210         return bridgeType.orElse(UNKNOWN);
211     }
212
213     public int getDepth() {
214         ModuleType parent = getBridge();
215         return parent == UNKNOWN ? 1 : parent.getDepth() + 1;
216     }
217
218     public static ModuleType from(ThingTypeUID thingTypeUID) {
219         return AS_SET.stream().filter(mt -> mt.thingTypeUID.equals(thingTypeUID)).findFirst()
220                 .orElseThrow(() -> new IllegalArgumentException(
221                         "No known ModuleType matched '%s'".formatted(thingTypeUID.toString())));
222     }
223 }