All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kjkoster.wedo.WeDo Maven / Gradle / Ivy

package org.kjkoster.wedo;

import static java.lang.Byte.parseByte;
import static java.lang.Integer.parseInt;
import static java.lang.System.out;
import static org.apache.commons.cli.Option.builder;

import java.io.IOException;
import java.util.Collection;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.kjkoster.wedo.bricks.Brick;
import org.kjkoster.wedo.bricks.Distance;
import org.kjkoster.wedo.bricks.Hub;
import org.kjkoster.wedo.bricks.Tilt;
import org.kjkoster.wedo.systems.wedo.WeDoBricks;
import org.kjkoster.wedo.transport.usb.Usb;

/**
 * The WeDo command line tool's main entry point.
 * 
 * @author Kees Jan Koster <[email protected]>
 */
public class WeDo {
    private static final String VERBOSE = "v";

    private static final String RESET = "reset";
    private static final String LIST = "list";

    private static final String TILT = "tilt";
    private static final String DISTANCE = "distance";
    private static final String SENSOR = "sensor";

    private static final String ALL = "all";
    private static final String ALL_A = "allA";
    private static final String ALL_B = "allB";

    private static final String LIGHT = "light";
    private static final String LIGHT_A = "lightA";
    private static final String LIGHT_B = "lightB";

    private static final String MOTOR = "motor";
    private static final String MOTOR_A = "motorA";
    private static final String MOTOR_B = "motorB";

    private static WeDoBricks weDoBricks = null;

    /**
     * The main application entry point.
     * 
     * @param args
     *            The command line arguments, as documented in
     *            usage().
     * @throws ParseException
     *             When the command line could not be parsed.
     */
    public static void main(final String[] args) throws ParseException {
        final Options options = setOptions();

        final CommandLine commandLine = parseCommandLine(options, args);

        final boolean verbose = commandLine.hasOption(VERBOSE);

        try (final Usb usb = new Usb(verbose)) {
            weDoBricks = new WeDoBricks(usb, verbose);

            if (commandLine.hasOption(RESET)) {
                weDoBricks.reset();
            } else if (commandLine.hasOption(LIST)) {
                list(verbose);
            } else if (commandLine.hasOption(SENSOR)) {
                final String value = commandLine.getOptionValue(SENSOR);
                sensor(value == null ? -1 : parseInt(value), true, true);
            } else if (commandLine.hasOption(DISTANCE)) {
                final String value = commandLine.getOptionValue(DISTANCE);
                sensor(value == null ? -1 : parseInt(value), true, false);
            } else if (commandLine.hasOption(TILT)) {
                final String value = commandLine.getOptionValue(TILT);
                sensor(value == null ? -1 : parseInt(value), false, true);
            } else if (commandLine.hasOption(MOTOR)) {
                weDoBricks.motor(parseByte(commandLine.getOptionValue(MOTOR)));
            } else if (commandLine.hasOption(MOTOR_A)) {
                weDoBricks
                        .motorA(parseByte(commandLine.getOptionValue(MOTOR_A)));
            } else if (commandLine.hasOption(MOTOR_B)) {
                weDoBricks
                        .motorB(parseByte(commandLine.getOptionValue(MOTOR_B)));
            } else if (commandLine.hasOption(LIGHT)) {
                weDoBricks.light(parseByte(commandLine.getOptionValue(LIGHT)));
            } else if (commandLine.hasOption(LIGHT_A)) {
                weDoBricks
                        .lightA(parseByte(commandLine.getOptionValue(LIGHT_A)));
            } else if (commandLine.hasOption(LIGHT_B)) {
                weDoBricks
                        .lightB(parseByte(commandLine.getOptionValue(LIGHT_B)));
            } else if (commandLine.hasOption(ALL)) {
                weDoBricks.all(parseByte(commandLine.getOptionValue(ALL)));
            } else if (commandLine.hasOption(ALL_A)) {
                weDoBricks.allA(parseByte(commandLine.getOptionValue(ALL_A)));
            } else if (commandLine.hasOption(ALL_B)) {
                weDoBricks.allB(parseByte(commandLine.getOptionValue(ALL_B)));
            } else {
                final HelpFormatter formatter = new HelpFormatter();
                formatter.printHelp("wedo", options);
                System.exit(1);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            // It seems that under Mac OS X a thread is still stuck in the
            // hidapi USB library, so we force the JVM to exit.
            System.exit(0);
        }
    }

    private static Options setOptions() {
        final Options options = new Options();

        options.addOption(VERBOSE, "verbose output");

        options.addOption(RESET, "reset all bricks");
        options.addOption(LIST, "list WeDo hubs");
        options.addOption(builder(SENSOR).optionalArg(true)
                .desc("read all sensors [] times (default repeat forever)")
                .build());
        options.addOption(builder(DISTANCE).optionalArg(true)
                .desc("read all distance sensors [] times (default repeat forever)")
                .build());
        options.addOption(builder(TILT).optionalArg(true)
                .desc("read all tilt sensors [] times (default repeat forever)")
                .build());
        options.addOption(MOTOR, true,
                "set all motors to speed (-127 to 127, 0 is off, negative for reverse)");
        options.addOption(MOTOR_A, true,
                "set all motor A's to speed (-127 to 127, 0 is off, negative for reverse)");
        options.addOption(MOTOR_B, true,
                "set all motor B's to speed (-127 to 127, 0 is off, negative for reverse)");
        options.addOption(LIGHT, true,
                "set all lights to intensity (0 to 127, 0 is off)");
        options.addOption(LIGHT_A, true,
                "set all brick A lights to intensity (0 to 127, 0 is off)");
        options.addOption(LIGHT_B, true,
                "set all brick B lights to intensity (0 to 127, 0 is off)");
        options.addOption(ALL, true, "set all bricks to value (-127 to 127)");
        options.addOption(ALL_A, true,
                "set all brick A's to speed (-127 to 127)");
        options.addOption(ALL_B, true,
                "set all brick B's to speed (-127 to 127)");

        return options;
    }

    private static CommandLine parseCommandLine(final Options options,
            final String[] arguments) throws ParseException {
        final CommandLineParser commandLineParser = new DefaultParser();
        return commandLineParser.parse(options, arguments);
    }

    /**
     * Print information on the WeDo hubs attached to this computer, and the
     * devices connected to them. The list is unordered.
     * 

* We have no reliable way of addressing specific bricks connected to a * specific hub. If you study the output of the verbose you will find that * WeDo hubs do not seem to have identifying information. Further, the order * in which the hubs are reported by the listDevices() method * is random (though tantalisingly stable at times). */ private static void list(final boolean verbose) throws IOException { out.printf("Scanning for LEGO WeDo hubs...\n\n"); final Collection hubs = weDoBricks.readAll(); if (hubs.size() == 0) { out.println("No LEGO WeDo hubs found."); } else { for (final Hub hub : hubs) { // we don't show the USB address, it changes a lot. out.println(hub.getProductName()); for (final Brick brick : hub.getBricks()) { listBrick(brick); } } } } private static void listBrick(final Brick brick) { String sensorData = ""; switch (brick.getType()) { case DISTANCE: sensorData = ": " + brick.getDistance().getCm() + " cm"; break; case TILT: sensorData = ": " + brick.getTilt().getDirection().toString() .toLowerCase().replace("_", " "); break; default: } out.println(" brick " + brick.getPort() + ": " + brick.getType().toString().toLowerCase().replace("_", " ") + sensorData); } private static void sensor(int repeat, final boolean showDistance, final boolean showTilt) throws InterruptedException { while (repeat == -1 || repeat > 0) { for (final Hub hub : weDoBricks.readAll()) { for (final Brick brick : hub.getBricks()) { switch (brick.getType()) { case DISTANCE: if (showDistance) { final Distance distance = brick.getDistance(); out.printf("distance %d cm (value %d)\n", distance.getCm(), distance.getValue()); } break; case TILT: if (showTilt) { final Tilt tilt = brick.getTilt(); out.printf("tilt %s (value %d)\n", tilt.getDirection().toString().toLowerCase() .replace("_", " "), tilt.getValue()); } break; case MOTOR: case LIGHT: case NOT_CONNECTED: case UNKNOWN: // known not to be sensors break; default: out.printf("unknown sensor type %s\n", brick.getType() .toString().toLowerCase().replace("_", " ")); break; } } } if (repeat == -1 || --repeat > 0) { Thread.sleep(1000L); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy