Add method overloads for PercentType to Audio & Voice actions (#3352)

* Overload Audio & Voice actions to support float in addition to PercentType for volume
* Align params in Audio & Voice actions to increase code readability
* Fix mathematical interval notation in string

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
Florian Hotze
2023-02-14 09:10:01 +01:00
committed by GitHub
parent 474d24c62d
commit 56fa0c9851
2 changed files with 80 additions and 23 deletions
@@ -47,7 +47,7 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the default sink")
public static void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
try {
AudioActionService.audioManager.playFile(filename, volume);
} catch (AudioException e) {
@@ -55,9 +55,15 @@ public class Audio {
}
}
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the default sink")
public static void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
playSound(filename, floatVolumeToPercentType(volume));
}
@ActionDoc(text = "plays a sound from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
try {
AudioActionService.audioManager.playFile(filename, sink);
} catch (AudioException e) {
@@ -67,8 +73,8 @@ public class Audio {
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
try {
AudioActionService.audioManager.playFile(filename, sink, volume);
} catch (AudioException e) {
@@ -76,6 +82,13 @@ public class Audio {
}
}
@ActionDoc(text = "plays a sound with the given volume from the sounds folder to the given sink(s)")
public static void playSound(@ParamDoc(name = "sink", text = "the id of the sink") String sink,
@ParamDoc(name = "filename", text = "the filename with extension") String filename,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
playSound(sink, filename, floatVolumeToPercentType(volume));
}
@ActionDoc(text = "plays an audio stream from a url to the default sink")
public static synchronized void playStream(
@ParamDoc(name = "url", text = "the url of the audio stream") String url) {
@@ -96,18 +109,15 @@ public class Audio {
}
}
@ActionDoc(text = "gets the master volume", returns = "volume as a float in the range [0,1]")
@ActionDoc(text = "gets the master volume", returns = "volume as a float in the range [0;1]")
public static float getMasterVolume() throws IOException {
return AudioActionService.audioManager.getVolume(null).floatValue() / 100f;
}
@ActionDoc(text = "sets the master volume")
public static void setMasterVolume(
@ParamDoc(name = "volume", text = "volume in the range [0,1]") final float volume) throws IOException {
if (volume < 0 || volume > 1) {
throw new IllegalArgumentException("Volume value must be in the range [0,1]!");
}
setMasterVolume(new PercentType(new BigDecimal(volume * 100f)));
@ParamDoc(name = "volume", text = "volume in the range [0;1]") final float volume) throws IOException {
setMasterVolume(floatVolumeToPercentType(volume));
}
@ActionDoc(text = "sets the master volume")
@@ -118,7 +128,7 @@ public class Audio {
@ActionDoc(text = "increases the master volume")
public static void increaseMasterVolume(@ParamDoc(name = "percent") final float percent) throws IOException {
if (percent <= 0 || percent > 100) {
throw new IllegalArgumentException("Percent must be in the range (0,100]!");
throw new IllegalArgumentException("Percent must be in the range (0;100]!");
}
Float volume = getMasterVolume();
if (volume == 0) {
@@ -140,12 +150,12 @@ public class Audio {
@ActionDoc(text = "decreases the master volume")
public static void decreaseMasterVolume(@ParamDoc(name = "percent") final float percent) throws IOException {
if (percent <= 0 || percent > 100) {
throw new IllegalArgumentException("Percent must be in the range (0,100]!");
throw new IllegalArgumentException("Percent must be in the range (0;100]!");
}
float volume = getMasterVolume();
float newVolume = volume * (1f - percent / 100f);
if (newVolume > 0 && volume - newVolume < .01) {
// the getMasterVolume() may only returns integers, so we have to make sure that we
// the getMasterVolume() may only return integers, so we have to make sure that we
// decrease the volume level at least by 1%.
newVolume -= .01;
}
@@ -155,4 +165,15 @@ public class Audio {
setMasterVolume(newVolume);
}
/**
* Converts a float volume to a {@link PercentType} volume and checks if float volume is in the [0;1] range.
* @param volume
* @return
*/
private static PercentType floatVolumeToPercentType(float volume) {
if (volume < 0 || volume > 1) {
throw new IllegalArgumentException("Volume value must be in the range [0;1]!");
}
return new PercentType(new BigDecimal(volume * 100f));
}
}
@@ -12,6 +12,7 @@
*/
package org.openhab.core.model.script.actions;
import java.math.BigDecimal;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -66,10 +67,16 @@ public class Voice {
*/
@ActionDoc(text = "says a given text with the default voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
say(text, null, null, volume);
}
@ActionDoc(text = "says a given text with the default voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, null, null, floatVolumeToPercentType(volume));
}
/**
* Says the given text with a given voice.
*
@@ -97,11 +104,19 @@ public class Voice {
* @param volume The volume to be used
*/
@ActionDoc(text = "says a given text with a given voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "the volume to be used") PercentType volume) {
say(text, voice, null, volume);
}
@ActionDoc(text = "says a given text with a given voice and the given volume")
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, voice, null, floatVolumeToPercentType(volume));
}
/**
* Says the given text with a given voice through the given sink.
*
@@ -113,8 +128,9 @@ public class Voice {
* be used
*/
@ActionDoc(text = "says a given text with a given voice through the given sink")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink) {
public static void say(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink) {
say(text, voice, sink, null);
}
@@ -131,14 +147,21 @@ public class Voice {
*/
@ActionDoc(text = "says a given text with a given voice and the given volume through the given sink")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "the volume to be used") @Nullable PercentType volume) {
String output = text.toString();
if (!output.isBlank()) {
VoiceActionService.voiceManager.say(output, voice, sink, volume);
}
}
@ActionDoc(text = "says a given text with a given voice and the given volume through the given sink")
public static void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") @Nullable String voice,
@ParamDoc(name = "sink") @Nullable String sink,
@ParamDoc(name = "volume", text = "volume in the range [0;1]") float volume) {
say(text, voice, sink, floatVolumeToPercentType(volume));
}
/**
* Interprets the given text.
*
@@ -162,7 +185,7 @@ public class Voice {
*/
@ActionDoc(text = "interprets a given text by given human language interpreter(s)", returns = "human language response")
public static String interpret(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "interpreters") @Nullable String interpreters) {
@ParamDoc(name = "interpreters") @Nullable String interpreters) {
String response;
try {
response = VoiceActionService.voiceManager.interpret(text.toString(), interpreters);
@@ -186,7 +209,8 @@ public class Voice {
*/
@ActionDoc(text = "interprets a given text by given human language interpreter(s) and using the given sink", returns = "human language response")
public static String interpret(@ParamDoc(name = "text") Object text,
@ParamDoc(name = "interpreters") String interpreters, @ParamDoc(name = "sink") @Nullable String sink) {
@ParamDoc(name = "interpreters") String interpreters,
@ParamDoc(name = "sink") @Nullable String sink) {
String response;
try {
response = VoiceActionService.voiceManager.interpret(text.toString(), interpreters);
@@ -209,7 +233,7 @@ public class Voice {
*/
@ActionDoc(text = "starts dialog processing for a given audio source")
public static void startDialog(@ParamDoc(name = "source") @Nullable String source,
@ParamDoc(name = "sink") @Nullable String sink) {
@ParamDoc(name = "sink") @Nullable String sink) {
startDialog(null, null, null, null, null, source, sink, null, null, null);
}
@@ -449,4 +473,16 @@ public class Voice {
return VoiceActionService.voiceManager.getAllVoices().stream().filter(voice -> voice.getUID().equals(id))
.findAny().orElse(null);
}
/**
* Converts a float volume to a {@link PercentType} volume and checks if float volume is in the [0;1] range.
* @param volume
* @return
*/
private static PercentType floatVolumeToPercentType(float volume) {
if (volume < 0 || volume > 1) {
throw new IllegalArgumentException("Volume value must be in the range [0;1]!");
}
return new PercentType(new BigDecimal(volume * 100f));
}
}