From 191d4804fb52bc45189c016721873fda06ad1a26 Mon Sep 17 00:00:00 2001 From: Matt Jones Date: Sat, 13 Sep 2025 17:17:48 -0500 Subject: [PATCH] feat: adding support for roller shutter --- pom.xml | 2 +- .../switch_bot/IDeviceCommands.java | 10 +++ .../switch_bot/data/DeviceCommand.java | 8 +- .../switch_bot/IDeviceCommandsTest.java | 77 +++++++++++++++++++ .../switch_bot/data/DeviceCommandTest.java | 74 ++++++++++++++++++ .../SwitchBotApiIntegrationTest.java | 18 +++++ 6 files changed, 187 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 396c7c9..c897acc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.bigboxer23 switchbotapi-java - 1.2.4 + 1.2.5 switchbotapi-java https://github.com/bigboxer23/switchbotapi-java diff --git a/src/main/java/com/bigboxer23/switch_bot/IDeviceCommands.java b/src/main/java/com/bigboxer23/switch_bot/IDeviceCommands.java index bbd3fba..f65fc0f 100644 --- a/src/main/java/com/bigboxer23/switch_bot/IDeviceCommands.java +++ b/src/main/java/com/bigboxer23/switch_bot/IDeviceCommands.java @@ -8,6 +8,8 @@ public interface IDeviceCommands { String TURN_ON = "turnOn"; + String SET_POSITION = "setPosition"; + DeviceCommand CURTAIN_CLOSE = new DeviceCommand(TURN_OFF, "default"); DeviceCommand CURTAIN_OPEN = new DeviceCommand(TURN_ON, "default"); @@ -15,4 +17,12 @@ public interface IDeviceCommands { DeviceCommand PLUG_MINI_OFF = new DeviceCommand(TURN_OFF, "default"); DeviceCommand PLUG_MINI_ON = new DeviceCommand(TURN_ON, "default"); + + DeviceCommand ROLLER_SHADE_CLOSE = new DeviceCommand(SET_POSITION, 100); + + DeviceCommand ROLLER_SHADE_OPEN = new DeviceCommand(SET_POSITION, 0); + + static DeviceCommand rollerShadePosition(int position) { + return new DeviceCommand(SET_POSITION, position); + } } diff --git a/src/main/java/com/bigboxer23/switch_bot/data/DeviceCommand.java b/src/main/java/com/bigboxer23/switch_bot/data/DeviceCommand.java index cb43efd..7f74caf 100644 --- a/src/main/java/com/bigboxer23/switch_bot/data/DeviceCommand.java +++ b/src/main/java/com/bigboxer23/switch_bot/data/DeviceCommand.java @@ -11,7 +11,13 @@ public DeviceCommand(String command, String parameter) { this.parameter = parameter; } + public DeviceCommand(String command, int parameter) { + this.command = command; + this.commandType = "command"; + this.parameter = parameter; + } + private String commandType; private String command; - private String parameter; + private Object parameter; } diff --git a/src/test/java/com/bigboxer23/switch_bot/IDeviceCommandsTest.java b/src/test/java/com/bigboxer23/switch_bot/IDeviceCommandsTest.java index 36cf768..21c3151 100644 --- a/src/test/java/com/bigboxer23/switch_bot/IDeviceCommandsTest.java +++ b/src/test/java/com/bigboxer23/switch_bot/IDeviceCommandsTest.java @@ -60,5 +60,82 @@ public void testCommandObjectsAreNotNull() { assertNotNull(IDeviceCommands.CURTAIN_OPEN); assertNotNull(IDeviceCommands.PLUG_MINI_OFF); assertNotNull(IDeviceCommands.PLUG_MINI_ON); + assertNotNull(IDeviceCommands.ROLLER_SHADE_CLOSE); + assertNotNull(IDeviceCommands.ROLLER_SHADE_OPEN); + } + + @Test + public void testRollerShadeCloseCommand() { + DeviceCommand rollerShadeClose = IDeviceCommands.ROLLER_SHADE_CLOSE; + assertNotNull(rollerShadeClose); + assertEquals("setPosition", rollerShadeClose.getCommand()); + assertEquals(100, rollerShadeClose.getParameter()); + } + + @Test + public void testRollerShadeOpenCommand() { + DeviceCommand rollerShadeOpen = IDeviceCommands.ROLLER_SHADE_OPEN; + assertNotNull(rollerShadeOpen); + assertEquals("setPosition", rollerShadeOpen.getCommand()); + assertEquals(0, rollerShadeOpen.getParameter()); + } + + @Test + public void testRollerShadePositionWithIntegerParameter() { + DeviceCommand command = IDeviceCommands.rollerShadePosition(50); + + assertNotNull(command); + assertEquals("setPosition", command.getCommand()); + assertEquals(50, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testRollerShadePositionWithZeroParameter() { + DeviceCommand command = IDeviceCommands.rollerShadePosition(0); + + assertNotNull(command); + assertEquals("setPosition", command.getCommand()); + assertEquals(0, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testRollerShadePositionWithMaximumParameter() { + DeviceCommand command = IDeviceCommands.rollerShadePosition(100); + + assertNotNull(command); + assertEquals("setPosition", command.getCommand()); + assertEquals(100, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testRollerShadePositionWithNegativeParameter() { + DeviceCommand command = IDeviceCommands.rollerShadePosition(-10); + + assertNotNull(command); + assertEquals("setPosition", command.getCommand()); + assertEquals(-10, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testRollerShadePositionCreatesNewInstances() { + DeviceCommand command1 = IDeviceCommands.rollerShadePosition(25); + DeviceCommand command2 = IDeviceCommands.rollerShadePosition(25); + DeviceCommand command3 = IDeviceCommands.rollerShadePosition(75); + + assertNotSame(command1, command2); + assertEquals(command1.getCommand(), command2.getCommand()); + assertEquals(command1.getParameter(), command2.getParameter()); + assertEquals(command1.getCommandType(), command2.getCommandType()); + + assertNotEquals(command1.getParameter(), command3.getParameter()); + } + + @Test + public void testSetPositionConstant() { + assertEquals("setPosition", IDeviceCommands.SET_POSITION); } } diff --git a/src/test/java/com/bigboxer23/switch_bot/data/DeviceCommandTest.java b/src/test/java/com/bigboxer23/switch_bot/data/DeviceCommandTest.java index 94de19e..4196745 100644 --- a/src/test/java/com/bigboxer23/switch_bot/data/DeviceCommandTest.java +++ b/src/test/java/com/bigboxer23/switch_bot/data/DeviceCommandTest.java @@ -166,4 +166,78 @@ public void testDeviceCommandRoundTripSerialization() throws IOException { assertEquals(originalCommand.getParameter(), deserializedCommand.getParameter()); assertEquals(originalCommand.getCommandType(), deserializedCommand.getCommandType()); } + + @Test + public void testDeviceCommandConstructorWithIntegerParameter() { + DeviceCommand command = new DeviceCommand("setPosition", 75); + + assertEquals("setPosition", command.getCommand()); + assertEquals(75, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testDeviceCommandConstructorWithZeroIntegerParameter() { + DeviceCommand command = new DeviceCommand("setPosition", 0); + + assertEquals("setPosition", command.getCommand()); + assertEquals(0, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testDeviceCommandConstructorWithNegativeIntegerParameter() { + DeviceCommand command = new DeviceCommand("setPosition", -10); + + assertEquals("setPosition", command.getCommand()); + assertEquals(-10, command.getParameter()); + assertEquals("command", command.getCommandType()); + } + + @Test + public void testDeviceCommandJsonSerializationWithIntegerParameter() throws IOException { + DeviceCommand command = new DeviceCommand("setPosition", 50); + + String json = adapter.toJson(command); + + assertNotNull(json); + assertTrue(json.contains("\"command\":\"setPosition\"")); + assertTrue(json.contains("\"parameter\":50")); + assertFalse(json.contains("\"parameter\":\"50\"")); + assertTrue(json.contains("\"commandType\":\"command\"")); + } + + @Test + public void testDeviceCommandJsonSerializationIntegerVsString() throws IOException { + DeviceCommand intCommand = new DeviceCommand("setPosition", 75); + DeviceCommand stringCommand = new DeviceCommand("setPosition", "75"); + + String intJson = adapter.toJson(intCommand); + String stringJson = adapter.toJson(stringCommand); + + assertTrue(intJson.contains("\"parameter\":75")); + assertTrue(stringJson.contains("\"parameter\":\"75\"")); + assertNotEquals(intJson, stringJson); + } + + @Test + public void testDeviceCommandEqualsWithIntegerParameter() { + DeviceCommand command1 = new DeviceCommand("setPosition", 100); + DeviceCommand command2 = new DeviceCommand("setPosition", 100); + DeviceCommand command3 = new DeviceCommand("setPosition", 50); + + assertEquals(command1, command2); + assertEquals(command1.hashCode(), command2.hashCode()); + assertNotEquals(command1, command3); + assertNotEquals(command1.hashCode(), command3.hashCode()); + } + + @Test + public void testDeviceCommandIntegerAndStringParametersNotEqual() { + DeviceCommand intCommand = new DeviceCommand("setPosition", 100); + DeviceCommand stringCommand = new DeviceCommand("setPosition", "100"); + + assertNotEquals(intCommand, stringCommand); + assertNotEquals(intCommand.hashCode(), stringCommand.hashCode()); + } } diff --git a/src/test/java/com/bigboxer23/switch_bot/integration/SwitchBotApiIntegrationTest.java b/src/test/java/com/bigboxer23/switch_bot/integration/SwitchBotApiIntegrationTest.java index 84e7570..3024cc1 100644 --- a/src/test/java/com/bigboxer23/switch_bot/integration/SwitchBotApiIntegrationTest.java +++ b/src/test/java/com/bigboxer23/switch_bot/integration/SwitchBotApiIntegrationTest.java @@ -6,6 +6,7 @@ import com.bigboxer23.switch_bot.IDeviceTypes; import com.bigboxer23.switch_bot.SwitchBotApi; import com.bigboxer23.switch_bot.data.Device; +import com.bigboxer23.switch_bot.data.IApiResponse; import com.bigboxer23.utils.command.Command; import com.bigboxer23.utils.properties.PropertyUtils; import java.io.IOException; @@ -26,6 +27,23 @@ public void testGetDevices() throws IOException { assertNotNull(devices.get(0).getDeviceId()); } + @Test + public void testRollerShadeClosed() throws IOException { + instance.getDeviceApi().getDevices().stream() + .filter(device -> device.getDeviceType().equals(IDeviceTypes.ROLLER_SHADE)) + .filter(Device::isMaster) + .findAny() + .ifPresent(device -> { + try { + IApiResponse response = instance.getDeviceApi() + .sendDeviceControlCommands(device.getDeviceId(), IDeviceCommands.ROLLER_SHADE_CLOSE); + System.out.println(response); + } catch (IOException theE) { + theE.printStackTrace(); + } + }); + } + @Test public void getDeviceNameFromId() throws IOException { Device device = instance.getDeviceApi().getDevices().get(0);