/* SpheroLightProfile.java Copyright (c) 2014 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.sphero.profile; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.text.TextUtils; import org.deviceconnect.android.deviceplugin.sphero.SpheroManager; import org.deviceconnect.android.deviceplugin.sphero.data.DeviceInfo; import org.deviceconnect.android.message.MessageUtils; import org.deviceconnect.android.profile.LightProfile; import org.deviceconnect.android.profile.api.DConnectApi; import org.deviceconnect.android.profile.api.DeleteApi; import org.deviceconnect.android.profile.api.GetApi; import org.deviceconnect.android.profile.api.PostApi; import org.deviceconnect.android.profile.api.PutApi; import org.deviceconnect.message.DConnectMessage; import java.util.HashMap; import java.util.Map; /** * Lightプロファイル. * * @author NTT DOCOMO, INC. */ public class SpheroLightProfile extends LightProfile { /** * 本体の色設定用ライトのID. */ private static final String COLOR_LED_LIGHT_ID = "1"; /** * バックライトのID. */ private static final String BACK_LED_LIGHT_ID = "2"; /** * 本体の色設定用ライトの名前. */ private static final String COLOR_LED_LIGHT_NAME = "Sphero LED"; /** * バックライトの名前. */ private static final String BACK_LED_LIGHT_NAME = "Sphero CalibrationLED"; /** * brightnessの最大値. */ public static final int MAX_BRIGHTNESS = 255; private Map<String, FlashingExecutor> mFlashingMap = new HashMap<String, FlashingExecutor>(); public SpheroLightProfile() { addApi(mGetLightApi); addApi(mPostLightApi); addApi(mPutLightApi); addApi(mDeleteLightApi); } private final DConnectApi mGetLightApi = new GetApi() { @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); if (serviceId == null) { MessageUtils.setEmptyServiceIdError(response); return true; } DeviceInfo info = SpheroManager.INSTANCE.getDevice(serviceId); if (info == null) { MessageUtils.setNotFoundServiceError(response); return true; } Bundle[] lights = new Bundle[2]; synchronized (info) { lights[0] = new Bundle(); setLightId(lights[0], COLOR_LED_LIGHT_ID); setName(lights[0], COLOR_LED_LIGHT_NAME); setOn(lights[0], (Color.BLACK != info.getColor())); setConfig(lights[0], ""); lights[1] = new Bundle(); setLightId(lights[1], BACK_LED_LIGHT_ID); setName(lights[1], BACK_LED_LIGHT_NAME); setOn(lights[1], info.getBackBrightness() > 0); setConfig(lights[1], ""); } setLights(response, lights); setResult(response, DConnectMessage.RESULT_OK); return true; } }; private final DConnectApi mPostLightApi = new PostApi() { @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); String lightId = getLightId(request); Integer color = getColor(request); Double brightness = getBrightness(request); long[] flashing = getFlashing(request); return changeLight(response, serviceId, lightId, color, brightness, flashing); } }; private final DConnectApi mPutLightApi = new PutApi() { @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); String lightId = getLightId(request); Integer color = getColor(request); Double brightness = getBrightness(request); long[] flashing = getFlashing(request); String name = getName(request); if (TextUtils.isEmpty(name)) { MessageUtils.setInvalidRequestParameterError(response); return true; } return changeLight(response, serviceId, lightId, color, brightness, flashing); } }; private final DConnectApi mDeleteLightApi = new DeleteApi() { @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); String lightId = getLightId(request); if (serviceId == null) { MessageUtils.setEmptyServiceIdError(response); return true; } DeviceInfo info = SpheroManager.INSTANCE.getDevice(serviceId); if (info == null) { MessageUtils.setNotFoundServiceError(response); return true; } synchronized (info) { if (COLOR_LED_LIGHT_ID.equals(lightId) || lightId == null) { info.setColor(0, 0, 0); setResult(response, DConnectMessage.RESULT_OK); } else if (BACK_LED_LIGHT_ID.equals(lightId)) { info.setBackBrightness(0.0f); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "lightId is invalid."); } } return true; } }; /** * Change the color of the light. * * @param response response * @param serviceId service id * @param lightId light id * @param color color * @param brightness brightness(0.0〜1.0) * @param flashing flashing * @return true */ private boolean changeLight(final Intent response, final String serviceId, final String lightId, final Integer color, final Double brightness, final long[] flashing) { if (serviceId == null) { MessageUtils.setEmptyServiceIdError(response); return true; } DeviceInfo info = SpheroManager.INSTANCE.getDevice(serviceId); if (info == null) { MessageUtils.setNotFoundServiceError(response); return true; } if (lightId == null || COLOR_LED_LIGHT_ID.equals(lightId)) { changeFrontLight(serviceId, COLOR_LED_LIGHT_ID, info, color, brightness, flashing); setResult(response, DConnectMessage.RESULT_OK); } else if (BACK_LED_LIGHT_ID.equals(lightId)) { changeBackLight(serviceId, BACK_LED_LIGHT_ID, info, brightness, flashing); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "lightId is invalid."); } return true; } /** * フロントのライトを変更します. * @param serviceId サービスID * @param lightId ライトID * @param info Shperoデバイス情報 * @param color 変更後の色 * @param brightness ブライトネス * @param flashing フラッシングのパターン */ private void changeFrontLight(final String serviceId, final String lightId, final DeviceInfo info, final Integer color, final Double brightness, final long[] flashing) { int[] colors = convertColor(color, brightness); if (flashing != null) { flashing(serviceId, lightId, info, colors, 0, flashing); } else { info.setColor(colors[0], colors[1], colors[2]); } } /** * バックのライトを変更します. * @param serviceId サービスID * @param lightId ライトID * @param info Spheroデバイス情報 * @param brightness ブライトネス * @param flashing フラッシングのパターン */ private void changeBackLight(final String serviceId, final String lightId, final DeviceInfo info, final Double brightness, final long[] flashing) { int brightnessRaw = MAX_BRIGHTNESS; if (brightness != null) { brightnessRaw = (int) (MAX_BRIGHTNESS * brightness); } if (flashing != null) { flashing(serviceId, lightId, info, null, brightnessRaw, flashing); } else { info.setBackBrightness(convertBrightness(brightnessRaw)); } } /** * ライトをフラッシングさせます. * @param serviceId サービスID * @param lightId ライトID * @param info Spheroデバイス情報 * @param colors 色 * @param brightnessRaw ブライトネス * @param flashing フラッシングのパターン */ private void flashing(final String serviceId, final String lightId, final DeviceInfo info, final int[] colors, final int brightnessRaw, long[] flashing) { FlashingExecutor exe = mFlashingMap.get(serviceId + lightId); if (exe == null) { exe = new FlashingExecutor(); mFlashingMap.put(serviceId + lightId, exe); } exe.setLightControllable(new FlashingExecutor.LightControllable() { @Override public void changeLight(final boolean isOn, final FlashingExecutor.CompleteListener listener) { if (lightId == null || COLOR_LED_LIGHT_ID.equals(lightId)) { if (isOn) { info.setColor(colors[0], colors[1], colors[2]); } else { info.setColor(0, 0, 0); } } else if (BACK_LED_LIGHT_ID.equals(lightId)) { if (isOn) { info.setBackBrightness(convertBrightness(brightnessRaw)); } else { info.setBackBrightness(0.0f); } } listener.onComplete(); } }); exe.start(flashing); } /** * ブライトネスの値をパーセンテージに変換します. * @param brightnessRaw ブライトネス * @return ブライトネス値のパーセンテージ */ private float convertBrightness(final int brightnessRaw) { return brightnessRaw / (float) MAX_BRIGHTNESS; } /** * Convert Integer to int[]. * * @param color color * @return int[] * @paarm brightness brightness */ private int[] convertColor(final Integer color, final Double brightness) { double b = 1.0; if (brightness != null) { b = brightness; } int[] colors = new int[3]; if (color != null) { colors[0] = (int) (Color.red(color) * b); colors[1] = (int) (Color.green(color) * b); colors[2] = (int) (Color.blue(color) * b); } else { colors[0] = (int) (0xFF * b); colors[1] = (int) (0xFF * b); colors[2] = (int) (0xFF * b); } return colors; } }