added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.hdpowerview;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.openhab.binding.hdpowerview.internal.api.ActuatorClass.*;
|
||||
import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets;
|
||||
import org.openhab.binding.hdpowerview.internal.HubMaintenanceException;
|
||||
import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem;
|
||||
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Shade;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Shades;
|
||||
import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/**
|
||||
* Unit tests for HD PowerView binding
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HDPowerViewJUnitTests {
|
||||
|
||||
private static final Pattern VALID_IP_V4_ADDRESS = Pattern
|
||||
.compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b");
|
||||
|
||||
/*
|
||||
* load a test JSON string from a file
|
||||
*/
|
||||
private String loadJson(String fileName) {
|
||||
try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName));
|
||||
BufferedReader reader = new BufferedReader(file)) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line).append("\n");
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (IOException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a series of ONLINE tests on the communication with a hub
|
||||
*
|
||||
* @param hubIPAddress must be a valid hub IP address to run the
|
||||
* tests on; or an INVALID IP address to
|
||||
* suppress the tests
|
||||
* @param allowShadeMovementCommands set to true if you accept that the tests
|
||||
* shall physically move the shades
|
||||
*/
|
||||
@Test
|
||||
public void testOnlineCommunication() {
|
||||
/*
|
||||
* NOTE: in order to actually run these tests you must have a hub physically
|
||||
* available, and its IP address must be correctly configured in the
|
||||
* "hubIPAddress" string constant e.g. "192.168.1.123"
|
||||
*/
|
||||
String hubIPAddress = "192.168.1.xxx";
|
||||
|
||||
/*
|
||||
* NOTE: set allowShadeMovementCommands = true if you accept physically moving
|
||||
* the shades during these tests
|
||||
*/
|
||||
boolean allowShadeMovementCommands = false;
|
||||
|
||||
if (VALID_IP_V4_ADDRESS.matcher(hubIPAddress).matches()) {
|
||||
// initialize stuff
|
||||
Client client = ClientBuilder.newClient();
|
||||
assertNotNull(client);
|
||||
// client.register(new Logger());
|
||||
HDPowerViewWebTargets webTargets = new HDPowerViewWebTargets(client, hubIPAddress);
|
||||
assertNotNull(webTargets);
|
||||
|
||||
// ==== exercise some code ====
|
||||
ShadePosition test;
|
||||
State pos;
|
||||
|
||||
// shade fully up
|
||||
test = ShadePosition.create(ZERO_IS_CLOSED, 0);
|
||||
assertNotNull(test);
|
||||
pos = test.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(0, ((PercentType) pos).intValue());
|
||||
pos = test.getState(PRIMARY_ACTUATOR, VANE_COORDS);
|
||||
assertTrue(UnDefType.UNDEF.equals(pos));
|
||||
|
||||
// shade fully down (method 1)
|
||||
test = ShadePosition.create(ZERO_IS_CLOSED, 100);
|
||||
assertNotNull(test);
|
||||
pos = test.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(100, ((PercentType) pos).intValue());
|
||||
pos = test.getState(PRIMARY_ACTUATOR, VANE_COORDS);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(0, ((PercentType) pos).intValue());
|
||||
|
||||
// shade fully down (method 2)
|
||||
test = ShadePosition.create(VANE_COORDS, 0);
|
||||
assertNotNull(test);
|
||||
pos = test.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(100, ((PercentType) pos).intValue());
|
||||
pos = test.getState(PRIMARY_ACTUATOR, VANE_COORDS);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(0, ((PercentType) pos).intValue());
|
||||
|
||||
// shade fully down (method 2) and vane fully open
|
||||
test = ShadePosition.create(VANE_COORDS, 100);
|
||||
assertNotNull(test);
|
||||
pos = test.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(100, ((PercentType) pos).intValue());
|
||||
pos = test.getState(PRIMARY_ACTUATOR, VANE_COORDS);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(100, ((PercentType) pos).intValue());
|
||||
|
||||
int shadeId = 0;
|
||||
@Nullable
|
||||
ShadePosition shadePos = null;
|
||||
@Nullable
|
||||
Shades shadesX = null;
|
||||
|
||||
// ==== get all shades ====
|
||||
try {
|
||||
shadesX = webTargets.getShades();
|
||||
assertNotNull(shadesX);
|
||||
@Nullable
|
||||
List<ShadeData> shadesData = shadesX.shadeData;
|
||||
assertNotNull(shadesData);
|
||||
assertTrue(shadesData.size() > 0);
|
||||
@Nullable
|
||||
ShadeData shadeData;
|
||||
shadeData = shadesData.get(0);
|
||||
assertNotNull(shadeData);
|
||||
assertTrue(shadeData.getName().length() > 0);
|
||||
shadePos = shadeData.positions;
|
||||
assertNotNull(shadePos);
|
||||
@Nullable
|
||||
ShadeData shadeZero = shadesData.get(0);
|
||||
assertNotNull(shadeZero);
|
||||
shadeId = shadeZero.id;
|
||||
assertNotEquals(0, shadeId);
|
||||
|
||||
for (ShadeData shadexData : shadesData) {
|
||||
String shadeName = shadexData.getName();
|
||||
assertNotNull(shadeName);
|
||||
}
|
||||
} catch (JsonParseException | ProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// ==== get all scenes ====
|
||||
int sceneId = 0;
|
||||
try {
|
||||
Scenes scenes = webTargets.getScenes();
|
||||
assertNotNull(scenes);
|
||||
@Nullable
|
||||
List<Scene> scenesData = scenes.sceneData;
|
||||
assertNotNull(scenesData);
|
||||
assertTrue(scenesData.size() > 0);
|
||||
@Nullable
|
||||
Scene sceneZero = scenesData.get(0);
|
||||
assertNotNull(sceneZero);
|
||||
sceneId = sceneZero.id;
|
||||
assertTrue(sceneId > 0);
|
||||
|
||||
for (Scene scene : scenesData) {
|
||||
String sceneName = scene.getName();
|
||||
assertNotNull(sceneName);
|
||||
}
|
||||
} catch (JsonParseException | ProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// ==== refresh a specific shade ====
|
||||
@Nullable
|
||||
Shade shade = null;
|
||||
try {
|
||||
assertNotEquals(0, shadeId);
|
||||
shade = webTargets.refreshShade(shadeId);
|
||||
assertNotNull(shade);
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// ==== move a specific shade ====
|
||||
try {
|
||||
assertNotEquals(0, shadeId);
|
||||
assertNotNull(shade);
|
||||
@Nullable
|
||||
ShadeData shadeData = shade.shade;
|
||||
assertNotNull(shadeData);
|
||||
ShadePosition positions = shadeData.positions;
|
||||
assertNotNull(positions);
|
||||
CoordinateSystem coordSys = positions.getCoordinateSystem(PRIMARY_ACTUATOR);
|
||||
assertNotNull(coordSys);
|
||||
|
||||
pos = positions.getState(PRIMARY_ACTUATOR, coordSys);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
|
||||
pos = positions.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
|
||||
int position = ((PercentType) pos).intValue();
|
||||
position = position + ((position <= 10) ? 5 : -5);
|
||||
|
||||
ShadePosition newPos = ShadePosition.create(ZERO_IS_CLOSED, position);
|
||||
assertNotNull(newPos);
|
||||
|
||||
if (allowShadeMovementCommands) {
|
||||
webTargets.moveShade(shadeId, newPos);
|
||||
}
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// ==== activate a specific scene ====
|
||||
if (allowShadeMovementCommands) {
|
||||
try {
|
||||
assertNotNull(sceneId);
|
||||
webTargets.activateScene(sceneId);
|
||||
} catch (ProcessingException | HubMaintenanceException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a series of OFFLINE tests on the JSON parsing machinery
|
||||
*/
|
||||
@Test
|
||||
public void testOfflineJsonParsing() {
|
||||
final Gson gson = new Gson();
|
||||
|
||||
@Nullable
|
||||
Shades shades;
|
||||
// test generic JSON shades response
|
||||
try {
|
||||
@Nullable
|
||||
String json = loadJson("shades");
|
||||
assertNotNull(json);
|
||||
assertNotEquals("", json);
|
||||
shades = gson.fromJson(json, Shades.class);
|
||||
assertNotNull(shades);
|
||||
} catch (JsonParseException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// test generic JSON scenes response
|
||||
try {
|
||||
@Nullable
|
||||
String json = loadJson("scenes");
|
||||
assertNotNull(json);
|
||||
assertNotEquals("", json);
|
||||
@Nullable
|
||||
Scenes scenes = gson.fromJson(json, Scenes.class);
|
||||
assertNotNull(scenes);
|
||||
} catch (JsonParseException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
// test the JSON parsing for a duette top down bottom up shade
|
||||
try {
|
||||
@Nullable
|
||||
ShadeData shadeData = null;
|
||||
String json = loadJson("duette");
|
||||
assertNotNull(json);
|
||||
assertNotEquals("", json);
|
||||
|
||||
shades = gson.fromJson(json, Shades.class);
|
||||
assertNotNull(shades);
|
||||
@Nullable
|
||||
List<ShadeData> shadesData = shades.shadeData;
|
||||
assertNotNull(shadesData);
|
||||
|
||||
assertEquals(1, shadesData.size());
|
||||
shadeData = shadesData.get(0);
|
||||
assertNotNull(shadeData);
|
||||
|
||||
assertEquals("Gardin 1", shadeData.getName());
|
||||
assertEquals(63778, shadeData.id);
|
||||
|
||||
ShadePosition shadePos = shadeData.positions;
|
||||
assertNotNull(shadePos);
|
||||
assertEquals(ZERO_IS_CLOSED, shadePos.getCoordinateSystem(PRIMARY_ACTUATOR));
|
||||
|
||||
State pos = shadePos.getState(PRIMARY_ACTUATOR, ZERO_IS_CLOSED);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(59, ((PercentType) pos).intValue());
|
||||
|
||||
pos = shadePos.getState(SECONDARY_ACTUATOR, ZERO_IS_OPEN);
|
||||
assertEquals(PercentType.class, pos.getClass());
|
||||
assertEquals(65, ((PercentType) pos).intValue());
|
||||
|
||||
pos = shadePos.getState(PRIMARY_ACTUATOR, VANE_COORDS);
|
||||
assertEquals(UnDefType.class, pos.getClass());
|
||||
} catch (JsonParseException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"shadeIds": [
|
||||
63778
|
||||
],
|
||||
"shadeData": [
|
||||
{
|
||||
"id": 63778,
|
||||
"type": 8,
|
||||
"batteryStatus": 0,
|
||||
"batteryStrength": 0,
|
||||
"roomId": 891,
|
||||
"firmware": {
|
||||
"revision": 1,
|
||||
"subRevision": 8,
|
||||
"build": 1944
|
||||
},
|
||||
"motor": {
|
||||
"revision": 0,
|
||||
"subRevision": 0,
|
||||
"build": 267
|
||||
},
|
||||
"name": "R2FyZGluIDE=",
|
||||
"groupId": 18108,
|
||||
"positions": {
|
||||
"posKind2": 2,
|
||||
"position2": 23194,
|
||||
"posKind1": 1,
|
||||
"position1": 26566
|
||||
},
|
||||
"signalStrength": 4,
|
||||
"aid": 2,
|
||||
"capabilities": 7,
|
||||
"batteryKind": "unassigned"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"sceneIds": [
|
||||
18097,
|
||||
22663,
|
||||
35821,
|
||||
6551
|
||||
],
|
||||
"sceneData": [
|
||||
{
|
||||
"roomId": 59611,
|
||||
"name": "RG9vciBPcGVu",
|
||||
"colorId": 6,
|
||||
"iconId": 160,
|
||||
"networkNumber": 19,
|
||||
"id": 18097,
|
||||
"order": 3,
|
||||
"hkAssist": false
|
||||
},
|
||||
{
|
||||
"roomId": 59611,
|
||||
"name": "SGVhcnQ=",
|
||||
"colorId": 15,
|
||||
"iconId": 49,
|
||||
"networkNumber": 3,
|
||||
"id": 22663,
|
||||
"order": 0,
|
||||
"hkAssist": false
|
||||
},
|
||||
{
|
||||
"roomId": 59611,
|
||||
"name": "Q2xvc2U=",
|
||||
"colorId": 5,
|
||||
"iconId": 31,
|
||||
"networkNumber": 8,
|
||||
"id": 35821,
|
||||
"order": 2,
|
||||
"hkAssist": false
|
||||
},
|
||||
{
|
||||
"roomId": 59611,
|
||||
"name": "T3Blbg==",
|
||||
"colorId": 10,
|
||||
"iconId": 95,
|
||||
"networkNumber": 20,
|
||||
"id": 6551,
|
||||
"order": 1,
|
||||
"hkAssist": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"shadeIds": [
|
||||
25206,
|
||||
55854,
|
||||
50150
|
||||
],
|
||||
"shadeData": [
|
||||
{
|
||||
"id": 25206,
|
||||
"type": 44,
|
||||
"batteryStatus": 3,
|
||||
"batteryStrength": 179,
|
||||
"roomId": 59611,
|
||||
"firmware": {
|
||||
"revision": 1,
|
||||
"subRevision": 8,
|
||||
"build": 1944
|
||||
},
|
||||
"name": "U2hhZGUgMg==",
|
||||
"motor": {
|
||||
"revision": 51,
|
||||
"subRevision": 51,
|
||||
"build": 11825
|
||||
},
|
||||
"groupId": 64003,
|
||||
"aid": 2,
|
||||
"signalStrength": 4,
|
||||
"capabilities": 0,
|
||||
"batteryKind": "unassigned",
|
||||
"positions": {
|
||||
"posKind1": 3,
|
||||
"position1": 32579
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 55854,
|
||||
"type": 44,
|
||||
"batteryStatus": 3,
|
||||
"batteryStrength": 187,
|
||||
"roomId": 59611,
|
||||
"firmware": {
|
||||
"revision": 1,
|
||||
"subRevision": 8,
|
||||
"build": 1944
|
||||
},
|
||||
"motor": {
|
||||
"revision": 51,
|
||||
"subRevision": 51,
|
||||
"build": 11825
|
||||
},
|
||||
"name": "U2hhZGUgMw==",
|
||||
"groupId": 64003,
|
||||
"aid": 3,
|
||||
"signalStrength": 4,
|
||||
"capabilities": 0,
|
||||
"positions": {
|
||||
"posKind1": 1,
|
||||
"position1": 65534
|
||||
},
|
||||
"batteryKind": "unassigned"
|
||||
},
|
||||
{
|
||||
"id": 50150,
|
||||
"type": 44,
|
||||
"batteryStatus": 3,
|
||||
"batteryStrength": 181,
|
||||
"roomId": 59611,
|
||||
"name": "U2hhZGUgMQ==",
|
||||
"firmware": {
|
||||
"revision": 1,
|
||||
"subRevision": 8,
|
||||
"build": 1944
|
||||
},
|
||||
"motor": {
|
||||
"revision": 51,
|
||||
"subRevision": 51,
|
||||
"build": 11825
|
||||
},
|
||||
"groupId": 64003,
|
||||
"aid": 4,
|
||||
"signalStrength": 4,
|
||||
"capabilities": 0,
|
||||
"batteryKind": "unassigned",
|
||||
"positions": {
|
||||
"posKind1": 1,
|
||||
"position1": 1040
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user