[amplipi] Add support for incremental volume control (#12297)

Signed-off-by: Ben Jones <ben.jones12@gmail.com>
This commit is contained in:
Ben Jones 2022-02-17 21:30:30 +13:00 committed by GitHub
parent f18ee99b08
commit 2b80c0ea97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 16 deletions

View 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";
}

View 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));
}
}

View 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

View 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));
}
}

View File

@ -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>
@ -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>