]> git.basschouten.com Git - openhab-addons.git/commitdiff
[amplipi] Add support for incremental volume control (#12297)
authorBen Jones <sumnerboy12@users.noreply.github.com>
Thu, 17 Feb 2022 08:30:30 +0000 (21:30 +1300)
committerGitHub <noreply@github.com>
Thu, 17 Feb 2022 08:30:30 +0000 (09:30 +0100)
Signed-off-by: Ben Jones <ben.jones12@gmail.com>
bundles/org.openhab.binding.amplipi/src/main/java/org/openhab/binding/amplipi/internal/AmpliPiBindingConstants.java
bundles/org.openhab.binding.amplipi/src/main/java/org/openhab/binding/amplipi/internal/AmpliPiGroupHandler.java
bundles/org.openhab.binding.amplipi/src/main/java/org/openhab/binding/amplipi/internal/AmpliPiUtils.java
bundles/org.openhab.binding.amplipi/src/main/java/org/openhab/binding/amplipi/internal/AmpliPiZoneHandler.java
bundles/org.openhab.binding.amplipi/src/main/resources/OH-INF/thing/thing-types.xml

index 91d15ff6842cb50090aef9e4d4f3ad143fd2adf2..5b0b48ead9e8e0d93da1276954e27c991c48dccc 100644 (file)
@@ -41,4 +41,5 @@ public class AmpliPiBindingConstants {
     // list of configuration parameters
     public static final String CFG_PARAM_HOSTNAME = "hostname";
     public static final String CFG_PARAM_ID = "id";
+    public static final String CFG_PARAM_VOLUME_DELTA = "volumeDelta";
 }
index 800958e2ba59f684a6a09270fbcb7f8802f51461..9fa545d297058e9fda15e38163b081081d55bb5e 100644 (file)
@@ -27,6 +27,7 @@ import org.openhab.binding.amplipi.internal.model.Group;
 import org.openhab.binding.amplipi.internal.model.GroupUpdate;
 import org.openhab.binding.amplipi.internal.model.Status;
 import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.IncreaseDecreaseType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.PercentType;
 import org.openhab.core.thing.Bridge;
@@ -58,6 +59,8 @@ public class AmpliPiGroupHandler extends BaseThingHandler implements AmpliPiStat
 
     private @Nullable AmpliPiHandler bridgeHandler;
 
+    private @Nullable Group groupState;
+
     public AmpliPiGroupHandler(Thing thing, HttpClient httpClient) {
         super(thing);
         this.httpClient = httpClient;
@@ -68,6 +71,10 @@ public class AmpliPiGroupHandler extends BaseThingHandler implements AmpliPiStat
         return Integer.valueOf(thing.getConfiguration().get(AmpliPiBindingConstants.CFG_PARAM_ID).toString());
     }
 
+    private int getVolumeDelta(Thing thing) {
+        return Integer.valueOf(thing.getConfiguration().get(AmpliPiBindingConstants.CFG_PARAM_VOLUME_DELTA).toString());
+    }
+
     @Override
     public void initialize() {
         Bridge bridge = getBridge();
@@ -104,6 +111,17 @@ public class AmpliPiGroupHandler extends BaseThingHandler implements AmpliPiStat
             case AmpliPiBindingConstants.CHANNEL_VOLUME:
                 if (command instanceof PercentType) {
                     update.setVolDelta(AmpliPiUtils.percentTypeToVolume((PercentType) command));
+                } else if (command instanceof IncreaseDecreaseType) {
+                    if (groupState != null) {
+                        if (IncreaseDecreaseType.INCREASE.equals(command)) {
+                            groupState.setVolDelta(Math.min(groupState.getVolDelta() + getVolumeDelta(thing),
+                                    AmpliPiUtils.MAX_VOLUME_DB));
+                        } else {
+                            groupState.setVolDelta(Math.max(groupState.getVolDelta() - getVolumeDelta(thing),
+                                    AmpliPiUtils.MIN_VOLUME_DB));
+                        }
+                        update.setVolDelta(groupState.getVolDelta());
+                    }
                 }
                 break;
             case AmpliPiBindingConstants.CHANNEL_SOURCE:
@@ -136,13 +154,18 @@ public class AmpliPiGroupHandler extends BaseThingHandler implements AmpliPiStat
     public void receive(Status status) {
         int id = getId(thing);
         Optional<Group> group = status.getGroups().stream().filter(z -> z.getId().equals(id)).findFirst();
-        if (group.isPresent()) {
-            Boolean mute = group.get().getMute();
-            Integer volume = group.get().getVolDelta();
-            Integer source = group.get().getSourceId();
-            updateState(AmpliPiBindingConstants.CHANNEL_MUTE, mute ? OnOffType.ON : OnOffType.OFF);
-            updateState(AmpliPiBindingConstants.CHANNEL_VOLUME, AmpliPiUtils.volumeToPercentType(volume));
-            updateState(AmpliPiBindingConstants.CHANNEL_SOURCE, new DecimalType(source));
-        }
+        group.ifPresent(this::updateGroupState);
+    }
+
+    private void updateGroupState(Group state) {
+        this.groupState = state;
+
+        Boolean mute = groupState.getMute();
+        Integer volDelta = groupState.getVolDelta();
+        Integer sourceId = groupState.getSourceId();
+
+        updateState(AmpliPiBindingConstants.CHANNEL_MUTE, mute ? OnOffType.ON : OnOffType.OFF);
+        updateState(AmpliPiBindingConstants.CHANNEL_VOLUME, AmpliPiUtils.volumeToPercentType(volDelta));
+        updateState(AmpliPiBindingConstants.CHANNEL_SOURCE, new DecimalType(sourceId));
     }
 }
index 007f635a439d8acf81c22060a0f89f724d82dd4b..8bfbdd3c03511a34070ec38cc00b67d23e274a50 100644 (file)
@@ -23,6 +23,11 @@ import org.openhab.core.library.types.PercentType;
  */
 @NonNullByDefault
 public class AmpliPiUtils {
+    /**
+     * The supported volume range in decibels for the AmpliPi
+     */
+    public static final int MIN_VOLUME_DB = -79;
+    public static final int MAX_VOLUME_DB = 0;
 
     /**
      * Converts a volume from AmpliPi to an openHAB PercentType
index c5e48c3fc52a13df46aa7e8d83c8a875c9dc3f05..852be84d6de653eeaa563584edf1b222037178f7 100644 (file)
@@ -27,6 +27,7 @@ import org.openhab.binding.amplipi.internal.model.Status;
 import org.openhab.binding.amplipi.internal.model.Zone;
 import org.openhab.binding.amplipi.internal.model.ZoneUpdate;
 import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.IncreaseDecreaseType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.PercentType;
 import org.openhab.core.thing.Bridge;
@@ -58,6 +59,8 @@ public class AmpliPiZoneHandler extends BaseThingHandler implements AmpliPiStatu
 
     private @Nullable AmpliPiHandler bridgeHandler;
 
+    private @Nullable Zone zoneState;
+
     public AmpliPiZoneHandler(Thing thing, HttpClient httpClient) {
         super(thing);
         this.httpClient = httpClient;
@@ -88,6 +91,10 @@ public class AmpliPiZoneHandler extends BaseThingHandler implements AmpliPiStatu
         return Integer.valueOf(thing.getConfiguration().get(AmpliPiBindingConstants.CFG_PARAM_ID).toString());
     }
 
+    private int getVolumeDelta(Thing thing) {
+        return Integer.valueOf(thing.getConfiguration().get(AmpliPiBindingConstants.CFG_PARAM_VOLUME_DELTA).toString());
+    }
+
     @Override
     public void handleCommand(ChannelUID channelUID, Command command) {
         if (command == RefreshType.REFRESH) {
@@ -104,6 +111,17 @@ public class AmpliPiZoneHandler extends BaseThingHandler implements AmpliPiStatu
             case AmpliPiBindingConstants.CHANNEL_VOLUME:
                 if (command instanceof PercentType) {
                     update.setVol(AmpliPiUtils.percentTypeToVolume((PercentType) command));
+                } else if (command instanceof IncreaseDecreaseType) {
+                    if (zoneState != null) {
+                        if (IncreaseDecreaseType.INCREASE.equals(command)) {
+                            zoneState.setVol(
+                                    Math.min(zoneState.getVol() + getVolumeDelta(thing), AmpliPiUtils.MAX_VOLUME_DB));
+                        } else {
+                            zoneState.setVol(
+                                    Math.max(zoneState.getVol() - getVolumeDelta(thing), AmpliPiUtils.MIN_VOLUME_DB));
+                        }
+                        update.setVol(zoneState.getVol());
+                    }
                 }
                 break;
             case AmpliPiBindingConstants.CHANNEL_SOURCE:
@@ -135,13 +153,18 @@ public class AmpliPiZoneHandler extends BaseThingHandler implements AmpliPiStatu
     public void receive(Status status) {
         int id = getId(thing);
         Optional<Zone> zone = status.getZones().stream().filter(z -> z.getId().equals(id)).findFirst();
-        if (zone.isPresent()) {
-            Boolean mute = zone.get().getMute();
-            Integer volume = zone.get().getVol();
-            Integer source = zone.get().getSourceId();
-            updateState(AmpliPiBindingConstants.CHANNEL_MUTE, mute ? OnOffType.ON : OnOffType.OFF);
-            updateState(AmpliPiBindingConstants.CHANNEL_VOLUME, AmpliPiUtils.volumeToPercentType(volume));
-            updateState(AmpliPiBindingConstants.CHANNEL_SOURCE, new DecimalType(source));
-        }
+        zone.ifPresent(this::updateZoneState);
+    }
+
+    private void updateZoneState(Zone state) {
+        this.zoneState = state;
+
+        Boolean mute = zoneState.getMute();
+        Integer vol = zoneState.getVol();
+        Integer sourceId = zoneState.getSourceId();
+
+        updateState(AmpliPiBindingConstants.CHANNEL_MUTE, mute ? OnOffType.ON : OnOffType.OFF);
+        updateState(AmpliPiBindingConstants.CHANNEL_VOLUME, AmpliPiUtils.volumeToPercentType(vol));
+        updateState(AmpliPiBindingConstants.CHANNEL_SOURCE, new DecimalType(sourceId));
     }
 }
index d73b0310915907836c6b9e7d9a21368063c1d4d6..df5f8400c959e5d2d632230659674b62f47683aa 100644 (file)
                                <label>Zone ID</label>
                                <description>The ID of the zone</description>
                        </parameter>
+                       <parameter name="volumeDelta" type="integer" min="1" max="10">
+                               <label>Volume Delta</label>
+                               <description>How much to change the zone volume for each INCREASE/DECREASE command (in dB)</description>
+                               <default>1</default>
+                               <advanced>true</advanced>
+                       </parameter>
                </config-description>
        </thing-type>
 
                                <label>Group ID</label>
                                <description>The ID of the group</description>
                        </parameter>
+                       <parameter name="volumeDelta" type="integer" min="1" max="10">
+                               <label>Volume Delta</label>
+                               <description>How much to change the group volume for each INCREASE/DECREASE command (in dB)</description>
+                               <default>1</default>
+                               <advanced>true</advanced>
+                       </parameter>
                </config-description>
        </thing-type>