Skip to content

Commit

Permalink
[amplipi] Add support for incremental volume control (openhab#12297)
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Jones <[email protected]>
  • Loading branch information
sumnerboy12 authored Feb 17, 2022
1 parent f18ee99 commit 2b80c0e
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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;
Expand Down Expand Up @@ -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;
Expand All @@ -68,6 +71,10 @@ private int getId(Thing thing) {
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();
Expand Down Expand Up @@ -104,6 +111,17 @@ public void handleCommand(ChannelUID channelUID, Command command) {
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:
Expand Down Expand Up @@ -136,13 +154,18 @@ public void handleCommand(ChannelUID channelUID, Command command) {
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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
*/
@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -88,6 +91,10 @@ private int getId(Thing thing) {
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) {
Expand All @@ -104,6 +111,17 @@ public void handleCommand(ChannelUID channelUID, Command command) {
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:
Expand Down Expand Up @@ -135,13 +153,18 @@ public void handleCommand(ChannelUID channelUID, Command command) {
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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
<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>

Expand All @@ -83,6 +89,12 @@
<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>

Expand Down

0 comments on commit 2b80c0e

Please sign in to comment.