diff --git a/CHANGES.md b/CHANGES.md index a50fc7fae..2f8e24550 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +# HAP-Java 2.0.10 +* Add optional Mute characteristic to Doorbell service + # HAP-Java 2.0.9 * Fix Set Duration and Remaining Duration characteristics to advertise format `uint32` instead of `int` [#202](https://github.com/hap-java/HAP-Java/issues/202) * Stop logging the SRP shared secret, derived key and M5 message data during pairing at DEBUG level diff --git a/src/main/java/io/github/hapjava/services/impl/DoorbellService.java b/src/main/java/io/github/hapjava/services/impl/DoorbellService.java index fd8fc7004..06ee325d4 100644 --- a/src/main/java/io/github/hapjava/services/impl/DoorbellService.java +++ b/src/main/java/io/github/hapjava/services/impl/DoorbellService.java @@ -2,8 +2,10 @@ import io.github.hapjava.accessories.DoorbellAccessory; import io.github.hapjava.accessories.optionalcharacteristic.AccessoryWithBrightness; +import io.github.hapjava.accessories.optionalcharacteristic.AccessoryWithMute; import io.github.hapjava.accessories.optionalcharacteristic.AccessoryWithName; import io.github.hapjava.accessories.optionalcharacteristic.AccessoryWithVolume; +import io.github.hapjava.characteristics.impl.audio.MuteCharacteristic; import io.github.hapjava.characteristics.impl.audio.VolumeCharacteristic; import io.github.hapjava.characteristics.impl.common.NameCharacteristic; import io.github.hapjava.characteristics.impl.common.ProgrammableSwitchEventCharacteristic; @@ -42,6 +44,14 @@ public DoorbellService(DoorbellAccessory accessory) { ((AccessoryWithVolume) accessory)::subscribeVolume, ((AccessoryWithVolume) accessory)::unsubscribeVolume)); } + if (accessory instanceof AccessoryWithMute) { + addOptionalCharacteristic( + new MuteCharacteristic( + ((AccessoryWithMute) accessory)::isMuted, + ((AccessoryWithMute) accessory)::setMute, + ((AccessoryWithMute) accessory)::subscribeMuteState, + ((AccessoryWithMute) accessory)::unsubscribeMuteState)); + } } public void addOptionalCharacteristic(NameCharacteristic name) { @@ -55,4 +65,8 @@ public void addOptionalCharacteristic(BrightnessCharacteristic brightness) { public void addOptionalCharacteristic(VolumeCharacteristic volume) { addCharacteristic(volume); } + + public void addOptionalCharacteristic(MuteCharacteristic mute) { + addCharacteristic(mute); + } } diff --git a/src/test/java/io/github/hapjava/services/impl/DoorbellServiceTest.java b/src/test/java/io/github/hapjava/services/impl/DoorbellServiceTest.java new file mode 100644 index 000000000..feb67b94c --- /dev/null +++ b/src/test/java/io/github/hapjava/services/impl/DoorbellServiceTest.java @@ -0,0 +1,51 @@ +package io.github.hapjava.services.impl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; + +import io.github.hapjava.accessories.DoorbellAccessory; +import io.github.hapjava.accessories.optionalcharacteristic.AccessoryWithMute; +import io.github.hapjava.characteristics.Characteristic; +import io.github.hapjava.characteristics.impl.audio.MuteCharacteristic; +import io.github.hapjava.characteristics.impl.common.ProgrammableSwitchEventCharacteristic; +import java.util.concurrent.CompletableFuture; +import javax.json.JsonObject; +import javax.json.JsonValue; +import org.junit.Test; + +public class DoorbellServiceTest { + + @Test + public void doorbellWithoutOptionalsOnlyHasSwitchEvent() { + DoorbellService service = new DoorbellService(mock(DoorbellAccessory.class)); + + assertThat(service.getType()).isEqualTo("00000121-0000-1000-8000-0026BB765291"); + assertThat(service.getCharacteristics()) + .hasExactlyElementsOfTypes(ProgrammableSwitchEventCharacteristic.class); + } + + @Test + public void doorbellWithMuteHasMuteCharacteristic() throws Exception { + DoorbellAccessory accessory = + mock(DoorbellAccessory.class, withSettings().extraInterfaces(AccessoryWithMute.class)); + when(((AccessoryWithMute) accessory).isMuted()) + .thenReturn(CompletableFuture.completedFuture(true)); + + DoorbellService service = new DoorbellService(accessory); + + assertThat(service.getCharacteristics()) + .hasExactlyElementsOfTypes( + ProgrammableSwitchEventCharacteristic.class, MuteCharacteristic.class); + + Characteristic mute = service.getCharacteristics().get(1); + JsonObject json = mute.toJson(2).join(); + assertThat(json.getString("type")).isEqualTo("11A"); + assertThat(json.getBoolean("value")).isTrue(); + + mute.setValue(JsonValue.FALSE); + verify((AccessoryWithMute) accessory).setMute(false); + } +}