mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[dirigera] Bugfix startup synchronization (#20184)
* remove unknown status Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
This commit is contained in:
+98
-38
@@ -21,6 +21,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
@@ -44,6 +46,7 @@ import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.BridgeHandler;
|
||||
@@ -66,17 +69,20 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
private static final ThingStatusInfo UNKNOWN_INITIALZING = new ThingStatusInfo(ThingStatus.UNKNOWN,
|
||||
ThingStatusDetail.NONE, null);
|
||||
private static final ThingStatusInfo UNKNOWN_NOT_READY = new ThingStatusInfo(ThingStatus.UNKNOWN,
|
||||
ThingStatusDetail.NOT_YET_READY, null);
|
||||
private final Logger logger = LoggerFactory.getLogger(BaseHandler.class);
|
||||
private List<PowerListener> powerListeners = new ArrayList<>();
|
||||
private @Nullable ScheduledFuture<?> initializationFuture;
|
||||
private @Nullable Gateway gateway;
|
||||
|
||||
// to be overwritten by child class in order to route the updates to the right instance
|
||||
protected @Nullable BaseHandler child;
|
||||
|
||||
protected BaseHandler child;
|
||||
// maps to route properties to channels and vice versa
|
||||
protected Map<String, String> property2ChannelMap;
|
||||
protected Map<String, String> channel2PropertyMap;
|
||||
|
||||
// cache to handle each refresh command properly
|
||||
protected Map<String, State> channelStateMap;
|
||||
|
||||
@@ -111,6 +117,7 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
property2ChannelMap = mapping;
|
||||
channel2PropertyMap = reverse(mapping);
|
||||
channelStateMap = initializeCache(mapping);
|
||||
this.child = this;
|
||||
}
|
||||
|
||||
protected void setChildHandler(BaseHandler child) {
|
||||
@@ -125,11 +132,11 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
// first get bridge as Gateway
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge != null) {
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
BridgeHandler handler = bridge.getHandler();
|
||||
if (handler != null) {
|
||||
if (handler instanceof Gateway gw) {
|
||||
gateway = gw;
|
||||
checkBridge();
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"@text/dirigera.device.status.wrong-bridge-type");
|
||||
@@ -145,22 +152,66 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
"@text/dirigera.device.status.missing-bridge");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checkHandler()) {
|
||||
// if handler doesn't match model status will be set to offline and it will stay until correction
|
||||
if (config.id.isBlank()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"@text/dirigera.device.status.id-mandatory");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.id.isBlank()) {
|
||||
updateProperties();
|
||||
BaseHandler proxy = child;
|
||||
if (proxy != null) {
|
||||
gateway().registerDevice(proxy, config.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProperties() {
|
||||
public synchronized void checkBridge() {
|
||||
// disposed flag set - go away
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* UNKNOWN => device initialization in progress, do nothing and wait for it to finish with resulting
|
||||
* ONLINE(OFFLINE response
|
||||
* CONFIGURATION_ERROR => something went wrong during initialize, don't continue
|
||||
*/
|
||||
ThingStatusInfo handlerStatusInfo = getThing().getStatusInfo();
|
||||
if (UNKNOWN_INITIALZING.equals(handlerStatusInfo)
|
||||
|| ThingStatusDetail.CONFIGURATION_ERROR.equals(handlerStatusInfo.getStatusDetail())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bridge ONLINE, thing anything else than ONLINE => initialize device and wait for it to finish with resulting
|
||||
// ONLINE(OFFLINE response, if
|
||||
if (ThingStatus.ONLINE.equals(gateway().getThing().getStatus())
|
||||
&& !ThingStatus.ONLINE.equals(handlerStatusInfo.getStatus())) {
|
||||
updateStatus(UNKNOWN_INITIALZING.getStatus(), UNKNOWN_INITIALZING.getStatusDetail(), null);
|
||||
initializationFuture = scheduler.schedule(child::initializeDevice, 0, TimeUnit.SECONDS);
|
||||
} else {
|
||||
updateStatus(UNKNOWN_NOT_READY.getStatus(), UNKNOWN_NOT_READY.getStatusDetail(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Handler sanity
|
||||
* Initial channel update
|
||||
* Thing properties
|
||||
* Register device at gateway
|
||||
*/
|
||||
public void initializeDevice() {
|
||||
if (!checkHandler()) {
|
||||
// if handler doesn't match model status will be set to offline and it will stay until correction
|
||||
return;
|
||||
} else {
|
||||
updateProperties();
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
gateway().registerDevice(child, config.id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
super.bridgeStatusChanged(bridgeStatusInfo);
|
||||
checkBridge();
|
||||
}
|
||||
|
||||
protected void updateProperties() {
|
||||
// fill canSend and canReceive capabilities
|
||||
Map<String, Object> modelProperties = gateway().model().getPropertiesFor(config.id);
|
||||
Object canReceiveCapabilities = modelProperties.get(Model.PROPERTY_CAN_RECEIVE);
|
||||
@@ -318,17 +369,6 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
if (customDebug) {
|
||||
logger.info("DIRIGERA BASE_HANDLER {} handleUpdate JSON {}", thing.getUID(), update);
|
||||
}
|
||||
// check online offline for each device
|
||||
if (update.has(Model.REACHABLE)) {
|
||||
if (update.getBoolean(Model.REACHABLE)) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
online = true;
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/dirigera.device.status.not-reachable");
|
||||
online = false;
|
||||
}
|
||||
}
|
||||
if (update.has(PROPERTY_DEVICE_TYPE) && deviceType.isBlank()) {
|
||||
deviceType = update.getString(PROPERTY_DEVICE_TYPE);
|
||||
}
|
||||
@@ -405,13 +445,25 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
updateList.add(link.toString());
|
||||
});
|
||||
Collections.sort(updateList);
|
||||
Collections.sort(hardLinks);
|
||||
if (!hardLinks.equals(updateList)) {
|
||||
hardLinks = updateList;
|
||||
List<String> localHardLinks = getLinks();
|
||||
Collections.sort(localHardLinks);
|
||||
if (!localHardLinks.equals(updateList)) {
|
||||
setLinks(updateList);
|
||||
// just update internal link list and let the gateway update do all updates regarding soft links
|
||||
gateway().updateLinks();
|
||||
}
|
||||
}
|
||||
// check online offline for each device
|
||||
if (update.has(Model.REACHABLE)) {
|
||||
if (update.getBoolean(Model.REACHABLE)) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
online = true;
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/dirigera.device.status.not-reachable");
|
||||
online = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void createChannelIfNecessary(String channelId, String channelTypeUID, String itemType) {
|
||||
@@ -450,19 +502,24 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
@Override
|
||||
public void dispose() {
|
||||
disposed = true;
|
||||
ScheduledFuture<?> localFuture = initializationFuture;
|
||||
if (localFuture != null) {
|
||||
localFuture.cancel(true);
|
||||
initializationFuture = null;
|
||||
}
|
||||
online = false;
|
||||
BaseHandler proxy = child;
|
||||
if (proxy != null) {
|
||||
gateway().unregisterDevice(proxy, config.id);
|
||||
Gateway localGateway = gateway;
|
||||
if (localGateway != null) {
|
||||
localGateway.unregisterDevice(child, config.id);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRemoval() {
|
||||
BaseHandler proxy = child;
|
||||
if (proxy != null) {
|
||||
gateway().deleteDevice(proxy, config.id);
|
||||
Gateway localGateway = gateway;
|
||||
if (localGateway != null) {
|
||||
localGateway.deleteDevice(child, config.id);
|
||||
}
|
||||
super.handleRemoval();
|
||||
}
|
||||
@@ -487,7 +544,6 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.GONE,
|
||||
"@text/dirigera.device.status.id-not-found" + " [\"" + config.id + "\"]");
|
||||
} else {
|
||||
// String message = "Handler " + thing.getThingTypeUID() + " doesn't match with model " + modelTTUID;
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"@text/dirigera.device.status.ttuid-mismatch" + " [\"" + thing.getThingTypeUID() + "\",\""
|
||||
+ modelTTUID + "\"]");
|
||||
@@ -530,10 +586,14 @@ public class BaseHandler extends BaseThingHandler implements DebugHandler {
|
||||
*
|
||||
* @return links attached to this device
|
||||
*/
|
||||
public List<String> getLinks() {
|
||||
public synchronized List<String> getLinks() {
|
||||
return new ArrayList<String>(hardLinks);
|
||||
}
|
||||
|
||||
private synchronized void setLinks(List<String> newLinks) {
|
||||
hardLinks = new ArrayList<>(newLinks);
|
||||
}
|
||||
|
||||
private void linkUpdate(String linkedDeviceId, boolean add) {
|
||||
/**
|
||||
* link has to be set to target device like light or outlet, not to the device which triggers an action like
|
||||
|
||||
+7
-21
@@ -14,7 +14,6 @@ package org.openhab.binding.dirigera.internal.handler;
|
||||
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -94,7 +93,6 @@ public class DirigeraHandler extends BaseBridgeHandler implements Gateway, Debug
|
||||
|
||||
// Can be overwritten by Unit test for mocking API
|
||||
protected Map<String, State> channelStateMap = new HashMap<>();
|
||||
protected Class<?> apiProvider = DirigeraAPIImpl.class;
|
||||
|
||||
private final Map<String, BaseHandler> deviceTree = new HashMap<>();
|
||||
private final DirigeraDiscoveryService discoveryService;
|
||||
@@ -146,6 +144,8 @@ public class DirigeraHandler extends BaseBridgeHandler implements Gateway, Debug
|
||||
locationOptions.add(new CommandOption(location.toFullString(), "Home location"));
|
||||
}
|
||||
commandProvider.setCommandOptions(new ChannelUID(thing.getUID(), CHANNEL_LOCATION), locationOptions);
|
||||
|
||||
api = Optional.of(new DirigeraAPIImpl(httpClient, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,25 +249,7 @@ public class DirigeraHandler extends BaseBridgeHandler implements Gateway, Debug
|
||||
|
||||
// Step 2 - if token is fine start initializing, else set status pairing retry
|
||||
if (!token.isBlank()) {
|
||||
// now create api and model
|
||||
try {
|
||||
DirigeraAPI apiProviderInstance = (DirigeraAPI) apiProvider
|
||||
.getConstructor(HttpClient.class, Gateway.class).newInstance(httpClient, this);
|
||||
if (apiProviderInstance != null) {
|
||||
api = Optional.of(apiProviderInstance);
|
||||
} else {
|
||||
throw (new InstantiationException(apiProvider.descriptorString()));
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
// this will not happen - DirirgeraAPIIMpl tested with mocks in unit tests
|
||||
logger.error("Error {}", apiProvider.descriptorString());
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
|
||||
"@text/dirigera.gateway.status.api-error" + " [\"" + apiProvider.descriptorString() + "\"]");
|
||||
return;
|
||||
}
|
||||
Model houseModel = new DirigeraModel(this);
|
||||
model = Optional.of(houseModel);
|
||||
model = Optional.of(new DirigeraModel(this));
|
||||
modelUpdate(); // initialize model
|
||||
websocket.initialize();
|
||||
// checks API access and starts websocket
|
||||
@@ -284,6 +266,10 @@ public class DirigeraHandler extends BaseBridgeHandler implements Gateway, Debug
|
||||
}
|
||||
}
|
||||
|
||||
void setAPIHandler(DirigeraAPI api) {
|
||||
this.api = Optional.of(api);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
-9
@@ -57,15 +57,6 @@ public class AirPurifierHandler extends BaseHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -49,15 +49,6 @@ public class BlindHandler extends BaseHandler {
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_BLIND_CONTROLLER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
String channel = channelUID.getIdWithoutGroup();
|
||||
|
||||
+2
-8
@@ -86,10 +86,7 @@ public class BaseShortcutController extends BaseHandler {
|
||||
@Override
|
||||
public void dispose() {
|
||||
sceneMapping.forEach((key, value) -> {
|
||||
BaseHandler proxy = child;
|
||||
if (proxy != null) {
|
||||
gateway().unregisterDevice(proxy, value);
|
||||
}
|
||||
gateway().unregisterDevice(child, value);
|
||||
});
|
||||
super.dispose();
|
||||
}
|
||||
@@ -98,10 +95,7 @@ public class BaseShortcutController extends BaseHandler {
|
||||
public void handleRemoval() {
|
||||
sceneMapping.forEach((key, value) -> {
|
||||
// cleanup storage and hub
|
||||
BaseHandler proxy = child;
|
||||
if (proxy != null) {
|
||||
gateway().deleteDevice(proxy, value);
|
||||
}
|
||||
gateway().deleteDevice(child, value);
|
||||
gateway().api().deleteScene(value);
|
||||
storage.remove(key);
|
||||
});
|
||||
|
||||
-9
@@ -39,15 +39,6 @@ public class BlindsControllerHandler extends BaseHandler {
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_BLINDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
+8
-9
@@ -38,28 +38,27 @@ public class DoubleShortcutControllerHandler extends BaseShortcutController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
public void initializeDevice() {
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
|
||||
super.updateProperties();
|
||||
// now register at gateway all device and scene ids
|
||||
String relationId = gateway().model().getRelationId(config.id);
|
||||
relations = gateway().model().getRelations(relationId);
|
||||
Entry<String, String> firstEntry = relations.firstEntry();
|
||||
String firstDeviceId = firstEntry.getKey();
|
||||
super.initializeScenes(firstDeviceId, CHANNEL_BUTTON_1);
|
||||
gateway().registerDevice(this, firstDeviceId);
|
||||
values = gateway().api().readDevice(firstDeviceId);
|
||||
handleUpdate(values);
|
||||
|
||||
// double shortcut controller has 2 devices
|
||||
Entry<String, String> secondEntry = relations.higherEntry(firstEntry.getKey());
|
||||
String secondDeviceId = secondEntry.getKey();
|
||||
super.initializeScenes(secondDeviceId, CHANNEL_BUTTON_2);
|
||||
gateway().registerDevice(this, secondDeviceId);
|
||||
|
||||
JSONObject values = gateway().api().readDevice(firstDeviceId);
|
||||
handleUpdate(values);
|
||||
gateway().registerDevice(this, firstDeviceId);
|
||||
values = gateway().api().readDevice(secondDeviceId);
|
||||
handleUpdate(values);
|
||||
gateway().registerDevice(this, secondDeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-9
@@ -43,15 +43,6 @@ public class LightControllerHandler extends BaseHandler {
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_LIGHT, DEVICE_TYPE_OUTLET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
+2
-5
@@ -17,7 +17,6 @@ import static org.openhab.binding.dirigera.internal.Constants.CHANNEL_BUTTON_1;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.json.JSONObject;
|
||||
import org.openhab.core.storage.Storage;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
@@ -35,12 +34,10 @@ public class ShortcutControllerHandler extends BaseShortcutController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
public void initializeDevice() {
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
super.initializeScenes(config.id, CHANNEL_BUTTON_1);
|
||||
}
|
||||
super.initializeDevice();
|
||||
}
|
||||
}
|
||||
|
||||
-10
@@ -18,7 +18,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.json.JSONObject;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
@@ -36,13 +35,4 @@ public class SoundControllerHandler extends BaseHandler {
|
||||
// links of types which can be established towards this device
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_SPEAKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -52,15 +52,6 @@ public class ColorLightHandler extends TemperatureLightHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
-9
@@ -40,15 +40,6 @@ public class DimmableLightHandler extends BaseLight {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-10
@@ -15,7 +15,6 @@ package org.openhab.binding.dirigera.internal.handler.light;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.json.JSONObject;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
@@ -30,13 +29,4 @@ public class SwitchLightHandler extends BaseLight {
|
||||
super(thing, mapping);
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -56,8 +56,7 @@ public class TemperatureLightHandler extends DimmableLightHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
public void initializeDevice() {
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
JSONObject attributes = values.getJSONObject(Model.ATTRIBUTES);
|
||||
@@ -74,6 +73,18 @@ public class TemperatureLightHandler extends DimmableLightHandler {
|
||||
properties.put("colorTemperatureMax", String.valueOf(colorTemperatureMax));
|
||||
}
|
||||
}
|
||||
|
||||
// KAJPLATS is delivering color temperature in Mired https://en.wikipedia.org/wiki/Mired
|
||||
if (colorTemperatureMin - colorTemperatureMax < 0) {
|
||||
properties.put("colorTemperatureMin", String.valueOf(colorTemperatureMin) + "M");
|
||||
properties.put("colorTemperatureMax", String.valueOf(colorTemperatureMax) + "M");
|
||||
colorTemperatureMin = 1000000 / colorTemperatureMin;
|
||||
colorTemperatureMax = 1000000 / colorTemperatureMax;
|
||||
} else {
|
||||
properties.put("colorTemperatureMin", String.valueOf(colorTemperatureMin) + "K");
|
||||
properties.put("colorTemperatureMax", String.valueOf(colorTemperatureMax) + "K");
|
||||
}
|
||||
|
||||
StateDescriptionFragment fragment = StateDescriptionFragmentBuilder.create()
|
||||
.withMinimum(BigDecimal.valueOf(colorTemperatureMax))
|
||||
.withMaximum(BigDecimal.valueOf(colorTemperatureMin)).withStep(BigDecimal.valueOf(100))
|
||||
@@ -81,8 +92,8 @@ public class TemperatureLightHandler extends DimmableLightHandler {
|
||||
stateProvider.setStateDescription(new ChannelUID(thing.getUID(), CHANNEL_LIGHT_TEMPERATURE_ABS), fragment);
|
||||
updateProperties(properties);
|
||||
range = colorTemperatureMin - colorTemperatureMax;
|
||||
handleUpdate(values);
|
||||
}
|
||||
super.initializeDevice();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-6
@@ -37,12 +37,6 @@ public class PowerPlugHandler extends SimplePlugHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
// update of values is handled in super class
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-11
@@ -18,7 +18,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.json.JSONObject;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
@@ -35,14 +34,4 @@ public class SimplePlugHandler extends BaseHandler {
|
||||
// links of types which can be established towards this device
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_LIGHT_CONTROLLER, DEVICE_TYPE_MOTION_SENSOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
// handling of first update, also for PowerPlug and SmartPlug child classes!
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-6
@@ -44,12 +44,6 @@ public class SmartPlugHandler extends PowerPlugHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
// update of values is handled in super class
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -34,15 +34,6 @@ public class RepeaterHandler extends BaseHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
+3
-2
@@ -50,8 +50,8 @@ public class SceneHandler extends BaseHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
public void initializeDevice() {
|
||||
super.initializeDevice();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readScene(config.id);
|
||||
handleUpdate(values);
|
||||
@@ -62,6 +62,7 @@ public class SceneHandler extends BaseHandler {
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
gateway().registerDevice(this, config.id);
|
||||
|
||||
// check if different undo duration is configured
|
||||
if (values.has("undoAllowedDuration")) {
|
||||
|
||||
-9
@@ -45,15 +45,6 @@ public class AirQualityHandler extends BaseHandler {
|
||||
hardLinks = Arrays.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -42,15 +42,6 @@ public class ContactSensorHandler extends BaseHandler {
|
||||
hardLinks = Arrays.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -39,15 +39,6 @@ public class LightSensorHandler extends BaseHandler {
|
||||
super.setChildHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
+7
-11
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.dirigera.internal.handler.sensor;
|
||||
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.CHANNEL_ILLUMINANCE;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -42,21 +42,17 @@ public class MotionLightSensorHandler extends MotionSensorHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
public void initializeDevice() {
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
// assure deviceType is set from main device
|
||||
if (values.has(PROPERTY_DEVICE_TYPE)) {
|
||||
deviceType = values.getString(PROPERTY_DEVICE_TYPE);
|
||||
}
|
||||
|
||||
updateProperties();
|
||||
// get all relations and register
|
||||
String relationId = gateway().model().getRelationId(config.id);
|
||||
relations = gateway().model().getRelations(relationId);
|
||||
// register for updates of twin devices
|
||||
relations.forEach((key, value) -> {
|
||||
// assure deviceType is set from main device
|
||||
if (config.id.equals(key)) {
|
||||
deviceType = value;
|
||||
}
|
||||
gateway().registerDevice(this, key);
|
||||
JSONObject relationValues = gateway().api().readDevice(key);
|
||||
handleUpdate(relationValues);
|
||||
|
||||
-9
@@ -59,15 +59,6 @@ public class MotionSensorHandler extends BaseHandler {
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_LIGHT, DEVICE_TYPE_OUTLET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -42,15 +42,6 @@ public class WaterSensorHandler extends BaseHandler {
|
||||
hardLinks = Arrays.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
super.handleCommand(channelUID, command);
|
||||
|
||||
-9
@@ -50,15 +50,6 @@ public class SpeakerHandler extends BaseHandler {
|
||||
linkCandidateTypes = List.of(DEVICE_TYPE_SOUND_CONTROLLER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (super.checkHandler()) {
|
||||
JSONObject values = gateway().api().readDevice(config.id);
|
||||
handleUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
String channel = channelUID.getIdWithoutGroup();
|
||||
|
||||
+1
@@ -379,6 +379,7 @@ dirigera.device.status.missing-bridge = No Bridge configured
|
||||
dirigera.device.status.not-reachable = Device not reachable
|
||||
dirigera.device.status.api-error = API {0} cannot be created
|
||||
dirigera.device.status.id-not-found = Device id {0} not found
|
||||
dirigera.device.status.id-mandatory = Device id is mandatory configuration
|
||||
dirigera.device.status.ttuid-mismatch = Handler {0} doesn't match with model {1}
|
||||
dirigera.gateway.status.pairing-button = Press Button on DIRIGERA Gateway
|
||||
dirigera.gateway.status.pairing-retry = Pairing failed. Stop and start bridge to initialize new pairing.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="dirigera"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="light-sensor">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="gateway"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Light Sensor</label>
|
||||
<description>Sensor measuring illuminance in your room</description>
|
||||
|
||||
<channels>
|
||||
<channel id="illuminance" typeId="illuminance"/>
|
||||
</channels>
|
||||
|
||||
<config-description-ref uri="thing-type:dirigera:base-device"/>
|
||||
</thing-type>
|
||||
</thing:thing-descriptions>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 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.binding.dirigera.internal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.sensor.MotionSensorHandler;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.internal.ThingImpl;
|
||||
|
||||
/**
|
||||
* {@link TestBridgeStatus} Tests different bridge modes for device initialization
|
||||
*
|
||||
* @author Bernd Weymann - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class TestBridgeStatus {
|
||||
private static final ThingStatusInfo INITIALIZING = new ThingStatusInfo(ThingStatus.INITIALIZING,
|
||||
ThingStatusDetail.NONE, null);
|
||||
private static final ThingStatusInfo UNKNOWN_NONE = new ThingStatusInfo(ThingStatus.UNKNOWN, ThingStatusDetail.NONE,
|
||||
null);
|
||||
private static final ThingStatusInfo UNKNOWN_NOT_READY = new ThingStatusInfo(ThingStatus.UNKNOWN,
|
||||
ThingStatusDetail.NOT_YET_READY, null);
|
||||
private static final ThingStatusInfo ONLINE = new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null);
|
||||
private static final ThingStatusInfo OFFLINE_CONFIG_ERROR = new ThingStatusInfo(ThingStatus.OFFLINE,
|
||||
ThingStatusDetail.CONFIGURATION_ERROR, null);
|
||||
|
||||
private static Stream<Arguments> testBridgeStatusChanges() {
|
||||
return Stream.of(//
|
||||
Arguments.of(UNKNOWN_NONE, INITIALIZING, UNKNOWN_NOT_READY), // Bridge not ready yet
|
||||
Arguments.of(ONLINE, OFFLINE_CONFIG_ERROR, OFFLINE_CONFIG_ERROR), // Stay at config error, no init shall
|
||||
// happen
|
||||
Arguments.of(ONLINE, INITIALIZING, ONLINE) // Go from init straight to ONLINE
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testBridgeStatusChanges(ThingStatusInfo bridgeStatusInfo, ThingStatusInfo handlerStatusInfo,
|
||||
ThingStatusInfo expectedStatusInfo) {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge();
|
||||
hubBridge.setStatusInfo(bridgeStatusInfo);
|
||||
|
||||
ThingImpl thing = new ThingImpl(THING_TYPE_MOTION_SENSOR, "test-device");
|
||||
thing.setBridgeUID(hubBridge.getBridgeUID());
|
||||
MotionSensorHandler handler = new MotionSensorHandler(thing, MOTION_SENSOR_MAP);
|
||||
CallbackMock thingCallback = new CallbackMock();
|
||||
thingCallback.setBridge(hubBridge);
|
||||
handler.setCallback(thingCallback);
|
||||
|
||||
// set the right id
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("id", "ee61c57f-8efa-44f4-ba8a-d108ae054138_1");
|
||||
handler.handleConfigurationUpdate(config);
|
||||
|
||||
hubBridge.setStatusInfo(bridgeStatusInfo);
|
||||
thingCallback.statusUpdated(thing, handlerStatusInfo);
|
||||
handler.initialize();
|
||||
thingCallback.waitForStatus(expectedStatusInfo.getStatus());
|
||||
assertEquals(expectedStatusInfo.getStatus(), thingCallback.getStatus().getStatus(), "Status Check");
|
||||
assertEquals(expectedStatusInfo.getStatusDetail(), thingCallback.getStatus().getStatusDetail(),
|
||||
"Status Detail Check");
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -28,7 +28,6 @@ import org.openhab.binding.dirigera.internal.Constants;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DicoveryServiceMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraHandlerManipulator;
|
||||
import org.openhab.binding.dirigera.internal.mock.HandlerFactoryMock;
|
||||
import org.openhab.core.storage.Storage;
|
||||
import org.openhab.core.test.storage.VolatileStorageService;
|
||||
@@ -58,7 +57,7 @@ public class DirigeraBridgeProvider {
|
||||
public static Bridge prepareSimuBridge(String homeFile, boolean discovery, List<String> knownDevicesd) {
|
||||
String ipAddress = "1.2.3.4";
|
||||
HttpClient httpMock = mock(HttpClient.class);
|
||||
DirigeraAPISimu.fileName = homeFile;
|
||||
|
||||
/**
|
||||
* Prepare persistence
|
||||
*/
|
||||
@@ -82,6 +81,8 @@ public class DirigeraBridgeProvider {
|
||||
*/
|
||||
DirigeraHandlerManipulator hubHandler = new DirigeraHandlerManipulator(hubBridge, httpMock, mockStorage,
|
||||
new DicoveryServiceMock());
|
||||
DirigeraAPISimu apiSimu = new DirigeraAPISimu(httpMock, hubHandler, homeFile);
|
||||
hubHandler.setAPIHandler(apiSimu);
|
||||
hubBridge.setHandler(hubHandler);
|
||||
CallbackMock bridgeCallback = new CallbackMock();
|
||||
hubHandler.setCallback(bridgeCallback);
|
||||
|
||||
+7
-4
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.dirigera.internal.mock;
|
||||
package org.openhab.binding.dirigera.internal.handler;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.dirigera.internal.DirigeraCommandProvider;
|
||||
import org.openhab.binding.dirigera.internal.discovery.DirigeraDiscoveryService;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraHandler;
|
||||
import org.openhab.binding.dirigera.internal.interfaces.DirigeraAPI;
|
||||
import org.openhab.core.i18n.LocationProvider;
|
||||
import org.openhab.core.storage.Storage;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@@ -38,8 +38,6 @@ public class DirigeraHandlerManipulator extends DirigeraHandler {
|
||||
DirigeraDiscoveryService discoveryService) {
|
||||
super(bridge, insecureClient, bindingStorage, discoveryService, mock(LocationProvider.class),
|
||||
mock(DirigeraCommandProvider.class), mock(BundleContext.class));
|
||||
// Changes the class of the provider. During initialize this class will be used for instantiation
|
||||
super.apiProvider = DirigeraAPISimu.class;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,4 +47,9 @@ public class DirigeraHandlerManipulator extends DirigeraHandler {
|
||||
public @Nullable ThingHandlerCallback getCallback() {
|
||||
return super.getCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAPIHandler(DirigeraAPI api) {
|
||||
super.setAPIHandler(api);
|
||||
}
|
||||
}
|
||||
+23
-30
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.dirigera.internal.handler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.CHANNEL_LOCATION;
|
||||
|
||||
import java.util.List;
|
||||
@@ -22,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraHandlerManipulator;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@@ -40,34 +38,27 @@ import org.openhab.core.types.UnDefType;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class TestGateway {
|
||||
private static String deviceId = "594197c3-23c9-4dc7-a6ca-1fe6a8455d29_1";
|
||||
private String deviceId = "594197c3-23c9-4dc7-a6ca-1fe6a8455d29_1";
|
||||
|
||||
private static DirigeraHandler handler = mock(DirigeraHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
private static String mockFile = "src/test/resources/gateway/home-with-coordinates.json";
|
||||
|
||||
@Test
|
||||
void testBridgeCreation() {
|
||||
DirigeraHandlerManipulator getBridgeHandler(String mockFile) {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge(mockFile, false, List.of());
|
||||
ThingHandler bridgeHandler = hubBridge.getHandler();
|
||||
assertTrue(bridgeHandler instanceof DirigeraHandlerManipulator);
|
||||
handler = (DirigeraHandlerManipulator) bridgeHandler;
|
||||
thing = handler.getThing();
|
||||
DirigeraHandler handler = (DirigeraHandlerManipulator) bridgeHandler;
|
||||
ThingHandlerCallback proxyCallback = ((DirigeraHandlerManipulator) handler).getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
CallbackMock callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
return (DirigeraHandlerManipulator) handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWithCoordinates() {
|
||||
mockFile = "src/test/resources/gateway/home-with-coordinates.json";
|
||||
testBridgeCreation();
|
||||
DirigeraHandlerManipulator handler = getBridgeHandler("src/test/resources/gateway/home-with-coordinates.json");
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
|
||||
State locationPoint = callback.getState("dirigera:gateway:9876:location");
|
||||
@@ -78,10 +69,12 @@ class TestGateway {
|
||||
|
||||
@Test
|
||||
void testWithoutCoordinates() {
|
||||
mockFile = "src/test/resources/gateway/home-without-coordinates.json";
|
||||
testBridgeCreation();
|
||||
Bridge hubBridge = DirigeraBridgeProvider
|
||||
.prepareSimuBridge("src/test/resources/gateway/home-without-coordinates.json", false, List.of());
|
||||
|
||||
DirigeraHandlerManipulator handler = (DirigeraHandlerManipulator) hubBridge.getHandler();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
|
||||
State locationPoint = callback.getState("dirigera:gateway:9876:location");
|
||||
@@ -91,27 +84,27 @@ class TestGateway {
|
||||
|
||||
@Test
|
||||
void testCommands() {
|
||||
testWithCoordinates();
|
||||
DirigeraHandlerManipulator handler = getBridgeHandler("src/test/resources/gateway/home-with-coordinates.json");
|
||||
assertNotNull(handler);
|
||||
Thing thing = handler.getThing();
|
||||
assertNotNull(thing);
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
DirigeraAPISimu api = (DirigeraAPISimu) handler.api();
|
||||
|
||||
// remove location from gateway with empty string
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_LOCATION), StringType.EMPTY);
|
||||
String patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
String patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"coordinates\":{}}}", patch, "Empty Coordinates");
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
api.clear();
|
||||
|
||||
// set new location with valid coordinates
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_LOCATION), StringType.valueOf("9.123,1.987"));
|
||||
patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"coordinates\":{\"latitude\":9.123,\"longitude\":1.987}}}", patch,
|
||||
"Valid Coordinates");
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
|
||||
// nothing send if value is invalid
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_LOCATION), StringType.valueOf("wrong coding"));
|
||||
patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
assertNull(patch, "Wrong coordinates");
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
api.clear();
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -51,6 +51,7 @@ class TestWrongHandler {
|
||||
handler.handleConfigurationUpdate(config);
|
||||
|
||||
handler.initialize();
|
||||
callback.waitForStatus(ThingStatus.OFFLINE);
|
||||
ThingStatusInfo status = callback.getStatus();
|
||||
assertEquals(ThingStatus.OFFLINE, status.getStatus(), "OFFLINE");
|
||||
assertEquals(ThingStatusDetail.CONFIGURATION_ERROR, status.getStatusDetail(), "Config Error");
|
||||
@@ -78,6 +79,7 @@ class TestWrongHandler {
|
||||
handler.handleConfigurationUpdate(config);
|
||||
|
||||
handler.initialize();
|
||||
callback.waitForStatus(ThingStatus.OFFLINE);
|
||||
ThingStatusInfo status = callback.getStatus();
|
||||
assertEquals(ThingStatus.OFFLINE, status.getStatus(), "OFFLINE");
|
||||
assertEquals(ThingStatusDetail.GONE, status.getStatusDetail(), "Device disappeared");
|
||||
|
||||
+25
-28
@@ -13,13 +13,13 @@
|
||||
package org.openhab.binding.dirigera.internal.handler.airpurifier;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
@@ -33,7 +33,6 @@ import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
@@ -47,31 +46,30 @@ class TestAirPurifier {
|
||||
private static String deviceId = "a8319695-0729-428c-9465-aadc0b738995";
|
||||
private static ThingTypeUID thingTypeUID = THING_TYPE_AIR_PURIFIER;
|
||||
|
||||
private static AirPurifierHandler handler = mock(AirPurifierHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof AirPurifierHandler);
|
||||
handler = (AirPurifierHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
return (BaseHandler) factoryHandler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler handler = getHandler();
|
||||
assertNotNull(handler);
|
||||
assertTrue(handler instanceof AirPurifierHandler);
|
||||
assertTrue(handler instanceof BaseHandler);
|
||||
assertNotNull(handler.getThing());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
assertNotNull(handler);
|
||||
Thing thing = handler.getThing();
|
||||
assertNotNull(thing);
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
checkAirPurifierStates(callback);
|
||||
|
||||
@@ -92,29 +90,28 @@ class TestAirPurifier {
|
||||
|
||||
@Test
|
||||
void testCommands() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
assertNotNull(handler);
|
||||
Thing thing = handler.getThing();
|
||||
assertNotNull(thing);
|
||||
DirigeraAPISimu api = (DirigeraAPISimu) handler.gateway().api();
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_PURIFIER_FAN_MODE), new DecimalType(4));
|
||||
String patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
String patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"fanMode\":\"on\"}}", patch, "Fan Mode on");
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_PURIFIER_FAN_SPEED), new PercentType(23));
|
||||
patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"motorState\":12}}", patch, "Fan Speed");
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_PURIFIER_FAN_SPEED), new PercentType(100));
|
||||
patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"motorState\":50}}", patch, "Fan Speed");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDump() {
|
||||
testHandlerCreation();
|
||||
assertEquals("unit-test", handler.getToken());
|
||||
}
|
||||
|
||||
void checkAirPurifierStates(CallbackMock callback) {
|
||||
State otaStatus = callback.getState("dirigera:air-purifier:test-device:ota-status");
|
||||
assertNotNull(otaStatus);
|
||||
|
||||
+17
-17
@@ -13,13 +13,13 @@
|
||||
package org.openhab.binding.dirigera.internal.handler.blind;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
@@ -43,34 +43,29 @@ import org.openhab.core.types.State;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class TestBlindHandler {
|
||||
String deviceId = "eadfad54-9d23-4475-92b6-0ee3d6f8b481_1";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_BLIND;
|
||||
private static String deviceId = "eadfad54-9d23-4475-92b6-0ee3d6f8b481_1";
|
||||
private static ThingTypeUID thingTypeUID = THING_TYPE_BLIND;
|
||||
|
||||
private static BlindHandler handler = mock(BlindHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof BlindHandler);
|
||||
handler = (BlindHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (BlindHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
assertNotNull(handler);
|
||||
Thing thing = handler.getThing();
|
||||
assertNotNull(thing);
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
checkBlindStates(callback);
|
||||
|
||||
@@ -86,10 +81,15 @@ class TestBlindHandler {
|
||||
|
||||
@Test
|
||||
void testCommands() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
assertNotNull(handler);
|
||||
Thing thing = handler.getThing();
|
||||
assertNotNull(thing);
|
||||
DirigeraAPISimu api = (DirigeraAPISimu) handler.gateway().api();
|
||||
|
||||
// DirigeraAPISimu api = (DirigeraAPISimu) ((DirigeraHandler) hubBridge.getHandler()).api();
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), "blind-level"), new PercentType(20));
|
||||
String patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
String patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"blindsTargetLevel\":20}}", patch, "Target Blind Level");
|
||||
}
|
||||
|
||||
+19
-22
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.dirigera.internal.handler.controller;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -25,6 +24,7 @@ import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.FileReader;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
@@ -34,13 +34,12 @@ import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* {@link TestDoubleShortcutController} Tests device handler creation, initializing and refresh of channels
|
||||
@@ -49,36 +48,29 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class TestDoubleShortcutController {
|
||||
private final Logger logger = LoggerFactory.getLogger(TestDoubleShortcutController.class);
|
||||
|
||||
String deviceId = "854bdf30-86b8-48f5-b070-16ff5ab12be4_1";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_DOUBLE_SHORTCUT_CONTROLLER;
|
||||
|
||||
private static DoubleShortcutControllerHandler handler = mock(DoubleShortcutControllerHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof DoubleShortcutControllerHandler);
|
||||
handler = (DoubleShortcutControllerHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (BaseHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
checkStates(callback);
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
|
||||
callback.clear();
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_OTA_STATUS), RefreshType.REFRESH);
|
||||
@@ -111,7 +103,10 @@ class TestDoubleShortcutController {
|
||||
|
||||
@Test
|
||||
void testTriggers() {
|
||||
testInitialization();
|
||||
DoubleShortcutControllerHandler handler = (DoubleShortcutControllerHandler) getHandler();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
|
||||
String updateSequence = FileReader
|
||||
.readFileInString("src/test/resources/websocket/scene-pressed/scene-trigger-sequence.json");
|
||||
JSONArray sequence = new JSONArray(updateSequence);
|
||||
@@ -131,13 +126,15 @@ class TestDoubleShortcutController {
|
||||
|
||||
@Test
|
||||
void testRemoval() {
|
||||
logger.warn("####### REMOVAL START ############");
|
||||
DirigeraAPISimu.scenesAdded.clear();
|
||||
DirigeraAPISimu.scenesDeleted.clear();
|
||||
testTriggers();
|
||||
logger.warn("####### TRIGGER CALLED ############");
|
||||
BaseHandler handler = getHandler();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(callback);
|
||||
|
||||
handler.dispose();
|
||||
handler.handleRemoval();
|
||||
callback.waitForStatus(ThingStatus.REMOVED);
|
||||
Collections.sort(DirigeraAPISimu.scenesAdded);
|
||||
Collections.sort(DirigeraAPISimu.scenesDeleted);
|
||||
assertEquals(6, DirigeraAPISimu.scenesAdded.size(), "Scenes added size");
|
||||
|
||||
+8
-13
@@ -13,13 +13,13 @@
|
||||
package org.openhab.binding.dirigera.internal.handler.controller;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
@@ -44,29 +44,24 @@ class TestShortcutController {
|
||||
String deviceId = "92dbcea1-3d7e-4d6a-a009-bdf3a1ae6691_1";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_SINGLE_SHORTCUT_CONTROLLER;
|
||||
|
||||
private static ShortcutControllerHandler handler = mock(ShortcutControllerHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof ShortcutControllerHandler);
|
||||
handler = (ShortcutControllerHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (ShortcutControllerHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
assertNotNull(callback);
|
||||
|
||||
+16
-21
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.dirigera.internal.handler.lights;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.List;
|
||||
@@ -21,6 +20,7 @@ import java.util.List;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.light.SwitchLightHandler;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
@@ -46,29 +46,24 @@ class TestSwitchLight {
|
||||
String deviceId = "eb9a4367-9e23-4d37-9566-401a7ae7caf0_2";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_SWITCH_LIGHT;
|
||||
|
||||
private static SwitchLightHandler handler = mock(SwitchLightHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof SwitchLightHandler);
|
||||
handler = (SwitchLightHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (SwitchLightHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
assertNotNull(callback);
|
||||
@@ -82,22 +77,22 @@ class TestSwitchLight {
|
||||
|
||||
@Test
|
||||
void testCommands() {
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
testHandlerCreation();
|
||||
// DirigeraAPISimu api = (DirigeraAPISimu) ((DirigeraHandler) hubBridge.getHandler()).api();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
DirigeraAPISimu api = (DirigeraAPISimu) handler.gateway().api();
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_POWER_STATE), OnOffType.ON);
|
||||
DirigeraAPISimu.waitForPatch();
|
||||
String patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
|
||||
String patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"isOn\":true}}", patch, "Power on");
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
api.clear();
|
||||
|
||||
// simulate feedback
|
||||
handler.handleUpdate(new JSONObject("{\"attributes\": {\"isOn\": true}}"));
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_POWER_STATE), OnOffType.OFF);
|
||||
DirigeraAPISimu.waitForPatch();
|
||||
patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"isOn\":false}}", patch, "Power off");
|
||||
}
|
||||
|
||||
+1
-2
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.dirigera.internal.handlerplug;
|
||||
package org.openhab.binding.dirigera.internal.handler.plug;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -22,7 +22,6 @@ import java.util.Map;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.plug.PowerPlugHandler;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.HandlerFactoryMock;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
+21
-36
@@ -10,32 +10,28 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.dirigera.internal.handlerplug;
|
||||
package org.openhab.binding.dirigera.internal.handler.plug;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.plug.SimplePlugHandler;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.HandlerFactoryMock;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.internal.ThingImpl;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
@@ -49,34 +45,27 @@ class TestSimplePlug {
|
||||
String deviceId = "6379a590-dc0a-47b5-b35b-7b46dfefd282_1";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_SIMPLE_PLUG;
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
HandlerFactoryMock hfm = new HandlerFactoryMock(mock(StorageService.class));
|
||||
assertTrue(hfm.supportsThingType(thingTypeUID));
|
||||
ThingImpl thing = new ThingImpl(thingTypeUID, "test-device");
|
||||
ThingHandler th = hfm.createHandler(thing);
|
||||
assertNotNull(th);
|
||||
assertTrue(th instanceof SimplePlugHandler);
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof SimplePlugHandler);
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (SimplePlugHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingImpl thing = new ThingImpl(thingTypeUID, "test-device");
|
||||
thing.setBridgeUID(hubBridge.getBridgeUID());
|
||||
SimplePlugHandler handler = new SimplePlugHandler(thing, SMART_PLUG_MAP);
|
||||
CallbackMock callback = new CallbackMock();
|
||||
callback.setBridge(hubBridge);
|
||||
handler.setCallback(callback);
|
||||
|
||||
// set the right id
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("id", deviceId);
|
||||
handler.handleConfigurationUpdate(config);
|
||||
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
assertNotNull(callback);
|
||||
checkPowerPlugStates(callback);
|
||||
|
||||
callback.clear();
|
||||
@@ -105,10 +94,6 @@ class TestSimplePlug {
|
||||
assertTrue(((QuantityType<?>) otaProgess).getUnit().equals(Units.PERCENT));
|
||||
assertEquals(0, ((QuantityType<?>) otaProgess).intValue(), "OTA Progress");
|
||||
|
||||
State disableLightState = callback.getState("dirigera:simple-plug:test-device:disable-light");
|
||||
assertNull(disableLightState);
|
||||
State childlockState = callback.getState("dirigera:simple-plug:test-device:child-lock");
|
||||
assertNull(childlockState);
|
||||
State onOffState = callback.getState("dirigera:simple-plug:test-device:power");
|
||||
assertNotNull(onOffState);
|
||||
assertTrue(onOffState instanceof OnOffType);
|
||||
+16
-20
@@ -10,18 +10,17 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.dirigera.internal.handlerplug;
|
||||
package org.openhab.binding.dirigera.internal.handler.plug;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.handler.BaseHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.plug.SmartPlugHandler;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
@@ -48,29 +47,24 @@ class TestSmartPlug {
|
||||
String deviceId = "ec549fa8-4e35-4f27-90e9-bb67e68311f2_1";
|
||||
ThingTypeUID thingTypeUID = THING_TYPE_SMART_PLUG;
|
||||
|
||||
private static SmartPlugHandler handler = mock(SmartPlugHandler.class);
|
||||
private static CallbackMock callback = mock(CallbackMock.class);
|
||||
private static Thing thing = mock(Thing.class);
|
||||
|
||||
@Test
|
||||
void testHandlerCreation() {
|
||||
BaseHandler getHandler() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/devices/home-all-devices.json",
|
||||
false, List.of());
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(thingTypeUID, hubBridge, deviceId);
|
||||
assertTrue(factoryHandler instanceof SmartPlugHandler);
|
||||
handler = (SmartPlugHandler) factoryHandler;
|
||||
thing = handler.getThing();
|
||||
assertTrue(factoryHandler instanceof BaseHandler);
|
||||
BaseHandler handler = (SmartPlugHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
callback = (CallbackMock) proxyCallback;
|
||||
handler.initialize();
|
||||
callback.waitForOnline();
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialization() {
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
assertNotNull(callback);
|
||||
@@ -94,17 +88,19 @@ class TestSmartPlug {
|
||||
|
||||
@Test
|
||||
void testCommands() {
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
testHandlerCreation();
|
||||
BaseHandler handler = getHandler();
|
||||
Thing thing = handler.getThing();
|
||||
CallbackMock callback = (CallbackMock) handler.getCallback();
|
||||
DirigeraAPISimu api = (DirigeraAPISimu) handler.gateway().api();
|
||||
assertNotNull(handler);
|
||||
assertNotNull(thing);
|
||||
assertNotNull(callback);
|
||||
|
||||
handler.handleCommand(new ChannelUID(thing.getUID(), CHANNEL_ENERGY_RESET_DATE), new DateTimeType());
|
||||
DirigeraAPISimu.waitForPatch();
|
||||
String patch = DirigeraAPISimu.patchMap.get(deviceId);
|
||||
|
||||
String patch = api.getPatch(deviceId);
|
||||
assertNotNull(patch);
|
||||
assertEquals("{\"attributes\":{\"energyConsumedAtLastReset\":0}}", patch, "Reset Power");
|
||||
DirigeraAPISimu.patchMap.clear();
|
||||
}
|
||||
|
||||
void checkSmartPlugStates(CallbackMock callback) {
|
||||
+56
-33
@@ -49,22 +49,76 @@ import org.openhab.core.types.TimeSeries;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class CallbackMock implements ThingHandlerCallback {
|
||||
private final int STATUS_DURATION_TIMEOUT_SEC = 10;
|
||||
private ThingStatusInfo statusInfo = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED).build();
|
||||
private @Nullable Bridge bridge;
|
||||
private ThingStatusInfo status = ThingStatusInfoBuilder.create(ThingStatus.OFFLINE).build();
|
||||
public Map<String, State> stateMap = new HashMap<>();
|
||||
public Map<String, String> triggerMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void statusUpdated(Thing thing, ThingStatusInfo thingStatusInfo) {
|
||||
synchronized (this) {
|
||||
thing.setStatusInfo(thingStatusInfo);
|
||||
statusInfo = thingStatusInfo;
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForStatus(ThingStatus expectedStatus) {
|
||||
synchronized (this) {
|
||||
Instant start = Instant.now();
|
||||
Instant check = Instant.now();
|
||||
while (!expectedStatus.equals(statusInfo.getStatus())
|
||||
&& Duration.between(start, check).getSeconds() < STATUS_DURATION_TIMEOUT_SEC) {
|
||||
try {
|
||||
this.wait(100);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
check = Instant.now();
|
||||
}
|
||||
}
|
||||
// if method is exited without reaching ONLINE e.g. through timeout fail
|
||||
if (!expectedStatus.equals(statusInfo.getStatus())) {
|
||||
fail("Wait for status " + expectedStatus + " reached just " + statusInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForOnline() {
|
||||
waitForStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
public ThingStatusInfo getStatus() {
|
||||
return statusInfo;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
stateMap.clear();
|
||||
}
|
||||
|
||||
public @Nullable State getState(String channel) {
|
||||
synchronized (stateMap) {
|
||||
Instant start = Instant.now();
|
||||
Instant check = Instant.now();
|
||||
while (stateMap.get(channel) == null
|
||||
&& Duration.between(start, check).getSeconds() < STATUS_DURATION_TIMEOUT_SEC) {
|
||||
try {
|
||||
stateMap.wait(100);
|
||||
} catch (InterruptedException e) {
|
||||
fail("Interruppted waiting for ONLINE");
|
||||
}
|
||||
check = Instant.now();
|
||||
}
|
||||
}
|
||||
return stateMap.get(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateUpdated(ChannelUID channelUID, State state) {
|
||||
stateMap.put(channelUID.getAsString(), state);
|
||||
synchronized (stateMap) {
|
||||
stateMap.put(channelUID.getAsString(), state);
|
||||
stateMap.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,37 +129,6 @@ public class CallbackMock implements ThingHandlerCallback {
|
||||
public void sendTimeSeries(ChannelUID channelUID, TimeSeries timeSeries) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statusUpdated(Thing thing, ThingStatusInfo thingStatus) {
|
||||
synchronized (this) {
|
||||
status = thingStatus;
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public ThingStatusInfo getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void waitForOnline() {
|
||||
synchronized (this) {
|
||||
Instant start = Instant.now();
|
||||
Instant check = Instant.now();
|
||||
while (!ThingStatus.ONLINE.equals(status.getStatus()) && Duration.between(start, check).getSeconds() < 10) {
|
||||
try {
|
||||
this.wait(1000);
|
||||
} catch (InterruptedException e) {
|
||||
fail("Interruppted waiting for ONLINE");
|
||||
}
|
||||
check = Instant.now();
|
||||
}
|
||||
}
|
||||
// if method is exited without reaching ONLINE e.g. through timeout fail
|
||||
if (!ThingStatus.ONLINE.equals(status.getStatus())) {
|
||||
fail("waitForOnline just reached status " + status);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thingUpdated(Thing thing) {
|
||||
}
|
||||
|
||||
+23
-15
@@ -14,6 +14,8 @@ package org.openhab.binding.dirigera.internal.mock;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -43,24 +45,30 @@ public class DicoveryServiceMock extends DirigeraDiscoveryService {
|
||||
|
||||
@Override
|
||||
public void deviceRemoved(final DiscoveryResult discoveryResult) {
|
||||
// logger.warn("Discovery thingRemoved {}", discoveryResult);
|
||||
String id = discoveryResult.getThingUID().getId();
|
||||
DiscoveryResult remover = discoveries.remove(id);
|
||||
// assertNotNull(remover);
|
||||
if (remover != null) {
|
||||
deletes.put(id, remover);
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForDetection() {
|
||||
synchronized (this) {
|
||||
if (discoveries.isEmpty()) {
|
||||
try {
|
||||
wait(5000);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
DiscoveryResult remover = discoveries.remove(id);
|
||||
if (remover != null) {
|
||||
deletes.put(id, remover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForDetection(int size) {
|
||||
synchronized (this) {
|
||||
Instant start = Instant.now();
|
||||
Instant check = Instant.now();
|
||||
while (discoveries.size() != size && Duration.between(start, check).getSeconds() < 5) {
|
||||
try {
|
||||
wait(100);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
check = Instant.now();
|
||||
}
|
||||
}
|
||||
if (discoveries.size() != size) {
|
||||
fail("Discovery size expected " + size + " but was " + discoveries.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-6
@@ -19,6 +19,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -26,6 +27,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@@ -44,16 +46,20 @@ import org.openhab.core.types.UnDefType;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class DirigeraAPISimu implements DirigeraAPI {
|
||||
private static JSONObject model = new JSONObject();
|
||||
private JSONObject model = new JSONObject();
|
||||
|
||||
public static String fileName = "src/test/resources/home/home.json";
|
||||
public static Map<String, String> patchMap = new HashMap<>();
|
||||
private String fileName = "src/test/resources/home/home.json";
|
||||
private Map<String, String> patchMap = new HashMap<>();
|
||||
public static List<String> scenesAdded = new ArrayList<>();
|
||||
public static List<String> scenesDeleted = new ArrayList<>();
|
||||
|
||||
public DirigeraAPISimu(HttpClient client, Gateway gateway) {
|
||||
}
|
||||
|
||||
public DirigeraAPISimu(HttpClient client, Gateway gateway, String homeFile) {
|
||||
fileName = homeFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject readHome() {
|
||||
String modelString = FileReader.readFileInString(fileName);
|
||||
@@ -136,15 +142,25 @@ public class DirigeraAPISimu implements DirigeraAPI {
|
||||
scenesDeleted.add(uuid);
|
||||
}
|
||||
|
||||
public static void waitForPatch() {
|
||||
public @Nullable String getPatch(String id) {
|
||||
Instant endTime = Instant.now().plusSeconds(10);
|
||||
synchronized (patchMap) {
|
||||
if (patchMap.isEmpty()) {
|
||||
String patch = patchMap.get(id);
|
||||
while (patch == null && Instant.now().isBefore(endTime)) {
|
||||
try {
|
||||
patchMap.wait(5000);
|
||||
patchMap.wait(100);
|
||||
patch = patchMap.get(id);
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
patchMap.clear();
|
||||
scenesAdded.clear();
|
||||
scenesDeleted.clear();
|
||||
}
|
||||
}
|
||||
|
||||
+40
-14
@@ -13,22 +13,28 @@
|
||||
package org.openhab.binding.dirigera.internal.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.openhab.binding.dirigera.internal.Constants.*;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.dirigera.internal.FileReader;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraBridgeProvider;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraHandler;
|
||||
import org.openhab.binding.dirigera.internal.handler.DirigeraHandlerManipulator;
|
||||
import org.openhab.binding.dirigera.internal.handler.sensor.WaterSensorHandler;
|
||||
import org.openhab.binding.dirigera.internal.interfaces.Gateway;
|
||||
import org.openhab.binding.dirigera.internal.mock.CallbackMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DicoveryServiceMock;
|
||||
import org.openhab.binding.dirigera.internal.mock.DirigeraAPISimu;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
@@ -147,30 +153,42 @@ class TestModel {
|
||||
|
||||
@Test
|
||||
void testDiscoveryAfterHandlerRemoval() {
|
||||
DirigeraHandler.detectionTimeSeonds = 0;
|
||||
Bridge hubBridge = DirigeraBridgeProvider.prepareSimuBridge("src/test/resources/home/home-one-device.json",
|
||||
true, List.of());
|
||||
Gateway gateway = (Gateway) hubBridge.getHandler();
|
||||
assertNotNull(gateway);
|
||||
|
||||
DicoveryServiceMock discovery = (DicoveryServiceMock) gateway.discovery();
|
||||
discovery.waitForDetection(1);
|
||||
assertEquals(1, discovery.discoveries.size(), "Initial discoveries");
|
||||
|
||||
String deviceId = "9af826ad-a8ad-40bf-8aed-125300bccd20_1";
|
||||
ThingHandler factoryHandler = DirigeraBridgeProvider.createHandler(THING_TYPE_WATER_SENSOR, hubBridge,
|
||||
"9af826ad-a8ad-40bf-8aed-125300bccd20_1");
|
||||
deviceId);
|
||||
assertTrue(factoryHandler instanceof WaterSensorHandler);
|
||||
WaterSensorHandler handler = (WaterSensorHandler) factoryHandler;
|
||||
ThingHandlerCallback proxyCallback = handler.getCallback();
|
||||
assertNotNull(proxyCallback);
|
||||
assertTrue(proxyCallback instanceof CallbackMock);
|
||||
CallbackMock callback = (CallbackMock) proxyCallback;
|
||||
callback.waitForOnline();
|
||||
|
||||
DirigeraHandler.detectionTimeSeonds = 0;
|
||||
discovery.discoveries.clear();
|
||||
assertEquals(0, discovery.discoveries.size(), "Cleanup after handler creation");
|
||||
// wait until device is registered
|
||||
Instant start = Instant.now();
|
||||
Instant check = Instant.now();
|
||||
while (!gateway.isKnownDevice(deviceId) && Duration.between(start, check).getSeconds() < 10) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
check = Instant.now();
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
handler.dispose();
|
||||
handler.handleRemoval();
|
||||
discovery.waitForDetection();
|
||||
callback.waitForStatus(ThingStatus.REMOVED);
|
||||
discovery.waitForDetection(1);
|
||||
assertEquals(1, discovery.discoveries.size(), "After removal new discovery result shall be present ");
|
||||
}
|
||||
|
||||
@@ -192,7 +210,7 @@ class TestModel {
|
||||
void testDeviceAdded() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider
|
||||
.prepareSimuBridge("src/test/resources/websocket/device-added/home-before.json", true, List.of());
|
||||
Gateway gateway = (Gateway) hubBridge.getHandler();
|
||||
DirigeraHandlerManipulator gateway = (DirigeraHandlerManipulator) hubBridge.getHandler();
|
||||
assertNotNull(gateway);
|
||||
|
||||
DicoveryServiceMock discovery = (DicoveryServiceMock) gateway.discovery();
|
||||
@@ -201,7 +219,9 @@ class TestModel {
|
||||
// Prepare update message
|
||||
String update = FileReader.readFileInString("src/test/resources/websocket/device-added/device-added.json");
|
||||
// prepare mock
|
||||
DirigeraAPISimu.fileName = "src/test/resources/websocket/device-added/home-after.json";
|
||||
DirigeraAPISimu apiSimu = new DirigeraAPISimu(mock(HttpClient.class), gateway,
|
||||
"src/test/resources/websocket/device-added/home-after.json");
|
||||
gateway.setAPIHandler(apiSimu);
|
||||
try {
|
||||
gateway.websocketUpdate(update);
|
||||
// give the gateway some time to handle the message
|
||||
@@ -216,7 +236,7 @@ class TestModel {
|
||||
void testDeviceRemoved() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider
|
||||
.prepareSimuBridge("src/test/resources/websocket/device-removed/home-before.json", true, List.of());
|
||||
Gateway gateway = (Gateway) hubBridge.getHandler();
|
||||
DirigeraHandlerManipulator gateway = (DirigeraHandlerManipulator) hubBridge.getHandler();
|
||||
assertNotNull(gateway);
|
||||
|
||||
DicoveryServiceMock discovery = (DicoveryServiceMock) gateway.discovery();
|
||||
@@ -225,7 +245,9 @@ class TestModel {
|
||||
// Prepare update message
|
||||
String update = FileReader.readFileInString("src/test/resources/websocket/device-removed/device-removed.json");
|
||||
// prepare mock
|
||||
DirigeraAPISimu.fileName = "src/test/resources/websocket/device-removed/home-after.json";
|
||||
DirigeraAPISimu apiSimu = new DirigeraAPISimu(mock(HttpClient.class), gateway,
|
||||
"src/test/resources/websocket/device-removed/home-after.json");
|
||||
gateway.setAPIHandler(apiSimu);
|
||||
try {
|
||||
gateway.websocketUpdate(update);
|
||||
// give the gateway some time to handle the message
|
||||
@@ -241,7 +263,7 @@ class TestModel {
|
||||
void testSceneCreated() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider
|
||||
.prepareSimuBridge("src/test/resources/websocket/scene-created/home-before.json", true, List.of());
|
||||
Gateway gateway = (Gateway) hubBridge.getHandler();
|
||||
DirigeraHandlerManipulator gateway = (DirigeraHandlerManipulator) hubBridge.getHandler();
|
||||
assertNotNull(gateway);
|
||||
|
||||
DicoveryServiceMock discovery = (DicoveryServiceMock) gateway.discovery();
|
||||
@@ -250,7 +272,9 @@ class TestModel {
|
||||
// Prepare update message
|
||||
String update = FileReader.readFileInString("src/test/resources/websocket/scene-created/scene-created.json");
|
||||
// prepare mock
|
||||
DirigeraAPISimu.fileName = "src/test/resources/websocket/scene-created/home-after.json";
|
||||
DirigeraAPISimu apiSimu = new DirigeraAPISimu(mock(HttpClient.class), gateway,
|
||||
"src/test/resources/websocket/scene-created/home-after.json");
|
||||
gateway.setAPIHandler(apiSimu);
|
||||
try {
|
||||
gateway.websocketUpdate(update);
|
||||
// give the gateway some time to handle the message
|
||||
@@ -265,7 +289,7 @@ class TestModel {
|
||||
void testSceneDeleted() {
|
||||
Bridge hubBridge = DirigeraBridgeProvider
|
||||
.prepareSimuBridge("src/test/resources/websocket/scene-deleted/home-before.json", true, List.of());
|
||||
Gateway gateway = (Gateway) hubBridge.getHandler();
|
||||
DirigeraHandlerManipulator gateway = (DirigeraHandlerManipulator) hubBridge.getHandler();
|
||||
assertNotNull(gateway);
|
||||
|
||||
DicoveryServiceMock discovery = (DicoveryServiceMock) gateway.discovery();
|
||||
@@ -274,7 +298,9 @@ class TestModel {
|
||||
// Prepare update message
|
||||
String update = FileReader.readFileInString("src/test/resources/websocket/scene-deleted/scene-deleted.json");
|
||||
// prepare mock
|
||||
DirigeraAPISimu.fileName = "src/test/resources/websocket/scene-deleted/home-after.json";
|
||||
DirigeraAPISimu apiSimu = new DirigeraAPISimu(mock(HttpClient.class), gateway,
|
||||
"src/test/resources/websocket/scene-deleted/home-after.json");
|
||||
gateway.setAPIHandler(apiSimu);
|
||||
try {
|
||||
gateway.websocketUpdate(update);
|
||||
// give the gateway some time to handle the message
|
||||
|
||||
Reference in New Issue
Block a user