/** * Copyright (c) 2016 Kai Kreuzer and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.automation.module.media.internal; import java.io.File; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; import org.eclipse.smarthome.automation.Visibility; import org.eclipse.smarthome.automation.module.media.handler.PlayActionHandler; import org.eclipse.smarthome.automation.type.ActionType; import org.eclipse.smarthome.automation.type.Input; import org.eclipse.smarthome.automation.type.ModuleType; import org.eclipse.smarthome.automation.type.ModuleTypeProvider; import org.eclipse.smarthome.automation.type.Output; import org.eclipse.smarthome.config.core.ConfigConstants; import org.eclipse.smarthome.config.core.ConfigDescriptionParameter; import org.eclipse.smarthome.config.core.ConfigDescriptionParameter.Type; import org.eclipse.smarthome.config.core.ConfigDescriptionParameterBuilder; import org.eclipse.smarthome.config.core.ParameterOption; import org.eclipse.smarthome.core.audio.AudioManager; import org.eclipse.smarthome.core.audio.AudioSink; import org.eclipse.smarthome.core.common.registry.ProviderChangeListener; /** * This class dynamically provides the Play action type. * This is necessary since there is no other way to provide dynamic config param options for module types. * * @author Kai Kreuzer - Initial contribution and API * */ public class MediaActionTypeProvider implements ModuleTypeProvider { private AudioManager audioManager; @SuppressWarnings("unchecked") @Override public ModuleType getModuleType(String UID, Locale locale) { if ("media.PlayAction".equals(UID)) { return getPlayActionType(locale); } else { return null; } } @Override public Collection<ModuleType> getModuleTypes(Locale locale) { return Collections.singleton(getPlayActionType(locale)); } private ModuleType getPlayActionType(Locale locale) { return new ActionType("media.PlayAction", getConfigDesc(locale), "play a sound", "Plays a sound file.", null, Visibility.VISIBLE, new ArrayList<Input>(), new ArrayList<Output>()); } private List<ConfigDescriptionParameter> getConfigDesc(Locale locale) { ConfigDescriptionParameter param1 = ConfigDescriptionParameterBuilder .create(PlayActionHandler.PARAM_SOUND, Type.TEXT).withRequired(true).withLabel("Sound") .withDescription("the sound to play").withOptions(getSoundOptions()).withLimitToOptions(true).build(); ConfigDescriptionParameter param2 = ConfigDescriptionParameterBuilder .create(PlayActionHandler.PARAM_SINK, Type.TEXT).withRequired(false).withLabel("Sink") .withDescription("the audio sink id").withOptions(getSinkOptions(locale)).withLimitToOptions(true) .build(); List<ConfigDescriptionParameter> params = new ArrayList<>(2); params.add(param1); params.add(param2); return params; } /** * This method creates one option for every file that is found in the sounds directory. * As a label, the file extension is removed and the string is capitalized. * * @return a list of parameter options representing the sound files */ private List<ParameterOption> getSoundOptions() { List<ParameterOption> options = new ArrayList<>(); File soundsDir = Paths.get(ConfigConstants.getConfigFolder(), AudioManager.SOUND_DIR).toFile(); if (soundsDir.isDirectory()) { for (String fileName : soundsDir.list()) { if (fileName.contains(".") && !fileName.startsWith(".")) { String soundName = StringUtils.capitalize(fileName.substring(0, fileName.lastIndexOf("."))); options.add(new ParameterOption(fileName, soundName)); } } } return options; } /** * This method creates one option for every sink that is found in the system. * * @return a list of parameter options representing the audio sinks */ private List<ParameterOption> getSinkOptions(Locale locale) { List<ParameterOption> options = new ArrayList<>(); for (String sinkId : audioManager.getSinkIds()) { AudioSink sink = audioManager.getSink(sinkId); options.add(new ParameterOption(sinkId, sink.getLabel(null))); } return options; } @Override public void addProviderChangeListener(ProviderChangeListener<ModuleType> listener) { // does nothing because this provider does not change } @Override public Collection<ModuleType> getAll() { return getModuleTypes(null); } @Override public void removeProviderChangeListener(ProviderChangeListener<ModuleType> listener) { // does nothing because this provider does not change } protected void setAudioManager(AudioManager audioManager) { this.audioManager = audioManager; } protected void unsetAudioManager(AudioManager audioManager) { this.audioManager = null; } }