com.idlegandalf.ledd.helper.LedDHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.idlegandalf.ledd.helper.LedDHelper.java

Source

/*
 * LEDD Project
 * Copyright (C) 2015 LEDD Team
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.idlegandalf.ledd.helper;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;

import com.idlegandalf.ledd.ColorApplication;
import com.idlegandalf.ledd.callbacks.AddControllerCallback;
import com.idlegandalf.ledd.callbacks.AddStripeCallback;
import com.idlegandalf.ledd.callbacks.DiscoverCallback;
import com.idlegandalf.ledd.callbacks.ReceiveColorCallback;
import com.idlegandalf.ledd.callbacks.StripesCallback;
import com.idlegandalf.ledd.components.AnswerTask;
import com.idlegandalf.ledd.components.Controller;
import com.idlegandalf.ledd.components.HSV;
import com.idlegandalf.ledd.components.LedDDaemon;
import com.idlegandalf.ledd.components.LedDRequest;
import com.idlegandalf.ledd.components.LedStripe;
import com.idlegandalf.ledd.services.ColorService;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;

public class LedDHelper {
    final String ACTION_SETCOLOR = "set_color";
    final String ACTION_GETCOLOR = "get_color";
    final String ACTION_ADDCONTROLLER = "add_controller";
    final String ACTION_GETALLSTRIPES = "get_stripes";
    final String ACTION_ADDSTRIPE = "add_stripe";
    final String ACTION_TESTCHANNEL = "test_channel";
    final String ACTION_DISCOVER = "discover";
    private Context context;
    private boolean mBound = false;
    private LedDDaemon ledDDaemon;
    private Worker<LedDRequest> requestWorker;
    private LinkedBlockingQueue<LedDRequest> dRequests;
    ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            Log.d(ColorApplication.TAG, "ColorService bound!");
            requestWorker = new Worker<>(dRequests, (ColorService.ColorBinder) service, ledDDaemon);
            mBound = true;
            new Thread(requestWorker).start();
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            requestWorker.stop();
            mBound = false;
        }
    };

    public LedDHelper(LedDDaemon ledDDaemon, Context appl) {
        this.context = appl;
        this.dRequests = new LinkedBlockingQueue<>();
        this.ledDDaemon = ledDDaemon;

        Intent intent = new Intent(appl, ColorService.class);
        appl.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * Add controller to ledd daemon
     *
     * @param c controller object
     */
    public void addController(final Controller c, final AddControllerCallback callback) {
        Map<String, Object> params = new HashMap<>();

        params.put("channels", c.getChannels());
        params.put("i2c_dev", c.getI2c_device());
        params.put("address", c.getAddress());

        JSONRPC2Request request = new JSONRPC2Request(ACTION_ADDCONTROLLER, params, UUID.randomUUID().toString());

        addRequestToQueue(request, new AnswerTask() {
            @Override
            public void onConnectionFailed(String message) {
                callback.onConnectionFailed(message);
            }

            @Override
            public void onResponse(JSONRPC2Response response) {
                if (response.indicatesSuccess()) {
                    try {
                        JSONObject json = new JSONObject(response.getResult().toString());
                        c.setId(json.getInt("cid"));
                        callback.onControllerAdded(c);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                    JSONRPC2Error error = response.getError();
                    callback.onAddFailed(error.getCode(), error.getMessage());
                }
            }
        });
    }

    /**
     * Get stripes known to daemon
     */
    public void getStripes(final StripesCallback callback) {
        addRequestToQueue(new JSONRPC2Request(ACTION_GETALLSTRIPES, UUID.randomUUID().toString()),
                new AnswerTask() {
                    @Override
                    public void onConnectionFailed(String message) {
                        callback.onConnectionFailed(message);
                    }

                    @Override
                    public void onResponse(JSONRPC2Response response) {
                        try {
                            if (response.indicatesSuccess()) {
                                ledDDaemon.getControllers().clear();
                                List<LedStripe> list = new ArrayList<>();
                                JSONObject json = new JSONObject(response.getResult().toString());
                                JSONArray jcontrollers = json.getJSONArray("controller");

                                for (int i = 0; i < jcontrollers.length(); i++) {
                                    JSONObject row = jcontrollers.getJSONObject(i);
                                    Controller nController = new Controller();
                                    nController.setAddress(row.getString("address"));
                                    nController.setChannels(row.getInt("channel"));
                                    nController.setI2c_device(row.getInt("i2c_device"));
                                    nController.setId(row.getInt("id"));

                                    JSONArray jstripes = row.getJSONArray("stripes");

                                    for (int o = 0; o < jstripes.length(); o++) {
                                        JSONObject srow = jstripes.getJSONObject(o);
                                        LedStripe nStripe = new LedStripe();
                                        nStripe.setId(srow.getInt("id"));
                                        nStripe.setRGB(srow.getBoolean("rgb"));
                                        nStripe.setChannelRed(srow.getJSONArray("channel").getInt(0));
                                        nStripe.setChannelGreen(srow.getJSONArray("channel").getInt(1));
                                        nStripe.setChannelBlue(srow.getJSONArray("channel").getInt(2));
                                        nStripe.setName(srow.getString("name"));
                                        nStripe.setController(nController);
                                        nStripe.setLedDDaemon(ledDDaemon);
                                        list.add(nStripe);
                                    }

                                    ledDDaemon.getControllers().add(nController);
                                }

                                callback.onSuccess(list);
                            } else {
                                @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                                JSONRPC2Error error = response.getError();
                                callback.onGetFailed(error.getCode(), error.getMessage());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
    }

    /**
     * Set color using the stripeid
     *
     * @param ledStripe Stripe
     */
    public void setColor(LedStripe ledStripe) {
        Map<String, Object> hsv = new HashMap<>();

        hsv.put("h", ledStripe.getColor().getHue());
        hsv.put("s", ledStripe.getColor().getSaturation());
        hsv.put("v", ledStripe.getColor().getValue());

        Map<String, Object> params = new HashMap<>();
        params.put("sid", ledStripe.getId());
        params.put("hsv", hsv);

        JSONRPC2Request request = new JSONRPC2Request(ACTION_SETCOLOR, params, UUID.randomUUID().toString());

        addRequestToQueue(request, null);
    }

    /**
     * Get color using the stripeid
     *
     * @param ledStripe Stripe
     */
    public void getColor(final LedStripe ledStripe, final ReceiveColorCallback callback) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("sid", ledStripe.getId());

        addRequestToQueue(new JSONRPC2Request(ACTION_GETCOLOR, params, UUID.randomUUID().toString()),
                new AnswerTask() {
                    @Override
                    public void onConnectionFailed(String message) {
                        callback.onConnectionFailed(message);
                    }

                    @Override
                    public void onResponse(JSONRPC2Response response) {
                        if (response.indicatesSuccess()) {
                            try {
                                JSONObject json = new JSONObject(response.getResult().toString());
                                JSONArray hsv = json.getJSONArray("color");
                                if (hsv.length() == 3) {
                                    ledStripe.setColor(
                                            new HSV(hsv.getDouble(0), hsv.getDouble(1), hsv.getDouble(2)));
                                    callback.onColorReceived(ledStripe);
                                } else {
                                    callback.onReceiveFailed(-1, "HSV was empty");
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                                callback.onReceiveFailed(-1, "Unhandeled JSON Exception");
                            }
                        } else {
                            @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                            JSONRPC2Error error = response.getError();
                            callback.onReceiveFailed(error.getCode(), error.getMessage());
                        }
                    }
                });
    }

    /**
     * Test a channel on the controller
     *
     * @param c       controller
     * @param channel channel number
     * @param value   value (1= on, 0 = off)
     */
    public void testChannel(Controller c, int channel, int value) {
        HashMap<String, Object> params = new HashMap<>();

        params.put("cid", c.getId());
        params.put("channel", channel);
        params.put("value", value);

        addRequestToQueue(new JSONRPC2Request(ACTION_TESTCHANNEL, params, UUID.randomUUID().toString()),
                new AnswerTask() {
                    @Override
                    public void onConnectionFailed(String message) {

                    }

                    @Override
                    public void onResponse(JSONRPC2Response response) {

                    }
                });
    }

    /**
     * Get information about an ledd daemon
     */
    public void discover(final DiscoverCallback callback) {
        addRequestToQueue(new JSONRPC2Request(ACTION_DISCOVER, UUID.randomUUID().toString()), new AnswerTask() {
            @Override
            public void onConnectionFailed(String message) {
                callback.onConnectionFailed(message);
            }

            @Override
            public void onResponse(JSONRPC2Response response) {
                try {
                    if (response.indicatesSuccess()) {
                        JSONObject json = new JSONObject(response.getResult().toString());
                        callback.onDiscoverSuccessfully(json.getString("version"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Get information about an ledd daemon
     */
    public void addStripe(final LedStripe ledStripe, final AddStripeCallback callback) {
        HashMap<String, Object> params = new HashMap<>();
        HashMap<String, Object> mapping = new HashMap<>();

        params.put("name", ledStripe.getName());
        params.put("rgb", ledStripe.isRGB());

        mapping.put("r", ledStripe.getChannelRed());
        mapping.put("g", ledStripe.getChannelGreen());
        mapping.put("b", ledStripe.getChannelBlue());
        params.put("map", mapping);
        params.put("cid", ledStripe.getController().getId());

        addRequestToQueue(new JSONRPC2Request(ACTION_ADDSTRIPE, params, UUID.randomUUID().toString()),
                new AnswerTask() {
                    @Override
                    public void onConnectionFailed(String message) {
                        callback.onConnectionFailed(message);
                    }

                    @Override
                    public void onResponse(JSONRPC2Response response) {
                        try {
                            if (response.indicatesSuccess()) {
                                JSONObject json = new JSONObject(response.getResult().toString());
                                ledStripe.setId(json.getInt("sid"));
                                callback.onAddSuccessfully(ledStripe);
                            } else {
                                @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                                JSONRPC2Error error = response.getError();
                                callback.onAddFailed(error.getCode(), error.getMessage());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
    }

    private void addRequestToQueue(JSONRPC2Request request, AnswerTask task) {
        if (request != null)
            dRequests.add(new LedDRequest(request, task));
    }

    public void teardown() {
        if (mBound) {
            context.unbindService(mConnection);
            mBound = false;
        }
        requestWorker.stop();
    }

    private static class Worker<T> implements Runnable {
        private final LinkedBlockingQueue<T> workQueue;
        private final ColorService.ColorBinder binder;
        private final LedDDaemon ledDDaemon;

        public Worker(LinkedBlockingQueue<T> workQueue, ColorService.ColorBinder colorBinder, LedDDaemon dDaemon) {
            this.workQueue = workQueue;
            this.binder = colorBinder;
            this.ledDDaemon = dDaemon;
        }

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    final T item = workQueue.take();

                    if (item instanceof LedDRequest) {
                        binder.queueSend(ledDDaemon, ((LedDRequest) item).getRequest(),
                                ((LedDRequest) item).getTask());
                    }
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        public void stop() {
            Thread.currentThread().interrupt();
        }
    }
}