-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Split RESTapi class into logical units (ConfigurationAccess, UserManagement, LightsAndGroups) * rules support * scenes support * schedule support * Refactor tests: Use jersey JAX-RS server to test without requiring the framework (non OSGi tests) Signed-off-by: David Graeff <[email protected]> schedules Signed-off-by: David Gräff <[email protected]>
- Loading branch information
David Graeff
committed
Apr 6, 2019
1 parent
6d5239c
commit 11ec316
Showing
86 changed files
with
8,089 additions
and
2,364 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
231 changes: 231 additions & 0 deletions
231
...enhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/ConfigStore.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
/** | ||
* Copyright (c) 2010-2019 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.io.hueemulation.internal; | ||
|
||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
import java.net.UnknownHostException; | ||
import java.util.Collections; | ||
import java.util.Dictionary; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.eclipse.smarthome.config.core.Configuration; | ||
import org.eclipse.smarthome.core.items.Item; | ||
import org.eclipse.smarthome.core.items.Metadata; | ||
import org.eclipse.smarthome.core.items.MetadataKey; | ||
import org.eclipse.smarthome.core.items.MetadataRegistry; | ||
import org.eclipse.smarthome.core.net.NetworkAddressService; | ||
import org.openhab.io.hueemulation.internal.dto.HueAuthorizedConfig; | ||
import org.openhab.io.hueemulation.internal.dto.HueDataStore; | ||
import org.openhab.io.hueemulation.internal.dto.HueGroupEntry; | ||
import org.openhab.io.hueemulation.internal.dto.HueLightEntry; | ||
import org.openhab.io.hueemulation.internal.dto.HueRuleEntry; | ||
import org.openhab.io.hueemulation.internal.dto.HueSensorEntry; | ||
import org.openhab.io.hueemulation.internal.dto.response.HueSuccessGeneric; | ||
import org.openhab.io.hueemulation.internal.dto.response.HueSuccessResponseStateChanged; | ||
import org.osgi.service.cm.ConfigurationAdmin; | ||
import org.osgi.service.component.annotations.Activate; | ||
import org.osgi.service.component.annotations.Component; | ||
import org.osgi.service.component.annotations.Reference; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
|
||
/** | ||
* This component sets up the hue data store and gets the service configuration. | ||
* It also determines the address for the upnp service. | ||
* <p> | ||
* This is a central component and required by all other components and may not | ||
* depend on anything in this bundle. | ||
* | ||
* @author David Graeff - Initial contribution | ||
*/ | ||
@Component | ||
@NonNullByDefault | ||
public class ConfigStore { | ||
public static final String METAKEY = "HUEEMU"; | ||
|
||
private final Logger logger = LoggerFactory.getLogger(ConfigStore.class); | ||
|
||
public HueDataStore ds = new HueDataStore(); | ||
|
||
/** | ||
* This is the main gson instance, to be obtained by all components that operate on the dto data fields | ||
*/ | ||
public final Gson gson = new GsonBuilder().registerTypeAdapter(HueLightEntry.class, new HueLightEntry.Serializer()) | ||
.registerTypeAdapter(HueSensorEntry.class, new HueSensorEntry.Serializer()) | ||
.registerTypeAdapter(HueRuleEntry.Condition.class, new HueRuleEntry.SerializerCondition()) | ||
.registerTypeAdapter(HueAuthorizedConfig.class, new HueAuthorizedConfig.Serializer()) | ||
.registerTypeAdapter(HueSuccessGeneric.class, new HueSuccessGeneric.Serializer()) | ||
.registerTypeAdapter(HueSuccessResponseStateChanged.class, new HueSuccessResponseStateChanged.Serializer()) | ||
.registerTypeAdapter(HueGroupEntry.class, new HueGroupEntry.Serializer(this)).create(); | ||
|
||
@Reference | ||
protected @NonNullByDefault({}) ConfigurationAdmin configAdmin; | ||
|
||
@Reference | ||
protected @NonNullByDefault({}) NetworkAddressService networkAddressService; | ||
|
||
@Reference | ||
protected @NonNullByDefault({}) MetadataRegistry metadataRegistry; | ||
|
||
//// objects, set within activate() | ||
protected @NonNullByDefault({}) InetAddress address; | ||
protected @NonNullByDefault({}) HueEmulationConfig config; | ||
|
||
public Set<String> switchFilter = Collections.emptySet(); | ||
public Set<String> colorFilter = Collections.emptySet(); | ||
public Set<String> whiteFilter = Collections.emptySet(); | ||
|
||
private int highestAssignedHueID = 1; | ||
|
||
ConfigStore() { | ||
} | ||
|
||
/** | ||
* For test dependency injection | ||
* | ||
* @param networkAddressService The network address service | ||
* @param configAdmin The configuration admin service | ||
* @param metadataRegistry The metadataRegistry service | ||
*/ | ||
public ConfigStore(NetworkAddressService networkAddressService, ConfigurationAdmin configAdmin, | ||
@Nullable MetadataRegistry metadataRegistry) { | ||
this.networkAddressService = networkAddressService; | ||
this.configAdmin = configAdmin; | ||
this.metadataRegistry = metadataRegistry; | ||
|
||
} | ||
|
||
@Activate | ||
public void activate(Map<String, Object> properties) { | ||
this.config = new Configuration(properties).as(HueEmulationConfig.class); | ||
|
||
if (config.discoveryHttpPort == 0) { | ||
config.discoveryHttpPort = Integer.getInteger("org.osgi.service.http.port", 8080); | ||
} | ||
|
||
String discoveryIp = config.discoveryIp; | ||
if (discoveryIp == null) { | ||
discoveryIp = networkAddressService.getPrimaryIpv4HostAddress(); | ||
} | ||
|
||
if (discoveryIp == null) { | ||
logger.warn("No primary IP address configured. Discovery disabled!"); | ||
return; | ||
} | ||
|
||
try { | ||
address = InetAddress.getByName(discoveryIp); | ||
} catch (UnknownHostException e) { | ||
logger.warn("No primary IP address configured. Discovery disabled!", e); | ||
address = InetAddress.getLoopbackAddress(); | ||
return; | ||
} | ||
|
||
// Get and apply configurations | ||
ds.config.linkbutton = config.pairingEnabled; | ||
ds.config.createNewUserOnEveryEndpoint = config.createNewUserOnEveryEndpoint; | ||
ds.config.networkopenduration = config.pairingTimeout; | ||
ds.config.mac = NetworkUtils.getMAC(address); | ||
ds.config.ipaddress = address.getHostAddress(); | ||
ds.config.devicename = config.devicename; | ||
if (config.uuid.isEmpty()) { | ||
config.uuid = UUID.randomUUID().toString(); | ||
org.osgi.service.cm.Configuration configuration; | ||
try { | ||
configuration = configAdmin.getConfiguration(HueEmulationService.CONFIG_PID); | ||
Dictionary<String, Object> dictionary = configuration.getProperties(); | ||
dictionary.put(HueEmulationConfig.CONFIG_UUID, config.uuid); | ||
configuration.update(dictionary); // This will restart the service (and call activate again) | ||
return; | ||
} catch (IOException e) { | ||
throw new IllegalArgumentException(e); | ||
} | ||
} | ||
|
||
ds.config.uuid = config.uuid; | ||
ds.config.bridgeid = config.uuid.replace("-", "").toUpperCase(); | ||
if (ds.config.bridgeid.length() > 12) { | ||
ds.config.bridgeid = ds.config.bridgeid.substring(0, 12); | ||
} | ||
|
||
determineHighestAssignedHueID(); | ||
} | ||
|
||
protected void determineHighestAssignedHueID() { | ||
for (Metadata metadata : metadataRegistry.getAll()) { | ||
if (!metadata.getUID().getNamespace().equals(METAKEY)) { | ||
continue; | ||
} | ||
try { | ||
int hueId = Integer.parseInt(metadata.getValue()); | ||
if (hueId > highestAssignedHueID) { | ||
highestAssignedHueID = hueId; | ||
} | ||
} catch (NumberFormatException e) { | ||
logger.warn("A non numeric hue ID '{}' was assigned. Ignoring!", metadata.getValue()); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Although hue IDs are strings, a lot of implementations out there assume them to be numbers. Therefore | ||
* we map each item to a number and store that in the meta data provider. | ||
* | ||
* @param item The item to map | ||
* @return A stringified integer number | ||
*/ | ||
public String mapItemUIDtoHueID(@Nullable Item item) { | ||
if (item == null) { | ||
throw new IllegalArgumentException(); | ||
} | ||
|
||
MetadataKey key = new MetadataKey(METAKEY, item.getUID()); | ||
Metadata metadata = metadataRegistry.get(key); | ||
int hueId = 0; | ||
if (metadata != null) { | ||
try { | ||
hueId = Integer.parseInt(metadata.getValue()); | ||
} catch (NumberFormatException e) { | ||
logger.warn("A non numeric hue ID '{}' was assigned. Ignore and reassign a different id now!", | ||
metadata.getValue()); | ||
} | ||
} | ||
if (hueId == 0) { | ||
++highestAssignedHueID; | ||
hueId = highestAssignedHueID; | ||
metadataRegistry.update(new Metadata(key, String.valueOf(hueId), null)); | ||
} | ||
|
||
return String.valueOf(hueId); | ||
} | ||
|
||
public InetAddress getAddress() { | ||
return address; | ||
} | ||
|
||
public HueEmulationConfig getConfig() { | ||
return config; | ||
} | ||
|
||
public int getHighestAssignedHueID() { | ||
return highestAssignedHueID; | ||
} | ||
} |
Oops, something went wrong.