// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2016 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.components.runtime; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.SimpleFunction; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.annotations.UsesPermissions; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.runtime.util.ErrorMessages; import com.google.appinventor.components.runtime.util.Ev3BinaryParser; import com.google.appinventor.components.runtime.util.Ev3Constants; /** * A component that provides a low-level interface to a LEGO MINDSTORMS EV3 * robot, with functions to send system or direct commands to EV3 robots. * * @author jerry73204@gmail.com (jerry73204) * @author spaded06543@gmail.com (Alvin Chang) */ @DesignerComponent(version = YaVersion.EV3_COMMANDS_COMPONENT_VERSION, description = "A component that provides a low-level interface to a LEGO MINDSTORMS EV3 " + "robot, with functions to send system or direct commands to EV3 robots.", category = ComponentCategory.LEGOMINDSTORMS, nonVisible = true, iconName = "images/legoMindstormsEv3.png") @SimpleObject @UsesPermissions(permissionNames = "android.permission.INTERNET," + "android.permission.WRITE_EXTERNAL_STORAGE," + "android.permission.READ_EXTERNAL_STORAGE") public class Ev3Commands extends LegoMindstormsEv3Base { /** * Creates a new Ev3Commands component. */ public Ev3Commands(ComponentContainer container) { super(container, "Ev3Commands"); } /** * Keep the EV3 brick from shutdown for a period of time. */ @SimpleFunction(description = "Keep the EV3 brick from shutdown for a period of time.") public void KeepAlive(int minutes) { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); if (minutes < 0 || minutes > 0xff) { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_ILLEGAL_ARGUMENT, functionName); return; } byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.KEEP_ALIVE, false, 0, 0, "c", (byte) minutes); sendCommand(functionName, command, false); } /** * Get the battery voltage. */ @SimpleFunction(description = "Get the battery voltage.") public double GetBatteryVoltage() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 4, 0, "cg", Ev3Constants.UIReadSubcode.GET_VBATT, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply.length == 5 && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] values = Ev3BinaryParser.unpack("xf", reply); return (Float) values[0]; } else { // error return -1.0; } } /** * Get the battery current. */ @SimpleFunction(description = "Get the battery current.") public double GetBatteryCurrent() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 4, 0, "cg", Ev3Constants.UIReadSubcode.GET_IBATT, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply.length == 5 && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] values = Ev3BinaryParser.unpack("xf", reply); return (Float) values[0]; } else { // error return -1.0; } } /** * Get the OS version on EV3. */ @SimpleFunction(description = "Get the OS version on EV3.") public String GetOSVersion() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 100, 0, "ccg", Ev3Constants.UIReadSubcode.GET_OS_VERS, (short) 100, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] value = Ev3BinaryParser.unpack("xS", reply); return String.valueOf(value[0]); } else { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_INVALID_REPLY); return null; } } /** * Get the OS build on EV3. */ @SimpleFunction(description = "Get the OS build on EV3.") public String GetOSBuild() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.UIReadSubcode.GET_OS_VERS, true, 100, 0, "ccg", Ev3Constants.UIReadSubcode.GET_OS_BUILD, (short) 100, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] value = Ev3BinaryParser.unpack("xS", reply); return String.valueOf(value[0]); } else { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_INVALID_REPLY); return null; } } /** * Get the firmware version on EV3. */ @SimpleFunction(description = "Get the firmware version on EV3.") public String GetFirmwareVersion() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 100, 0, "ccg", Ev3Constants.UIReadSubcode.GET_FW_VERS, (short) 100, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] value = Ev3BinaryParser.unpack("xS", reply); return String.valueOf(value[0]); } else { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_INVALID_REPLY); return null; } } /** * Get the firmware build on EV3. */ @SimpleFunction(description = "Get the firmware build on EV3.") public String GetFirmwareBuild() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 100, 0, "cg", (byte) 127, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] value = Ev3BinaryParser.unpack("xS", reply); return String.valueOf(value[0]); } else { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_INVALID_REPLY); return null; } } /** * Get the hardware version of EV3. */ @SimpleFunction(description = "Get the hardware version of EV3.") public String GetHardwareVersion() { String functionName = Thread.currentThread().getStackTrace()[1].getMethodName(); byte[] command = Ev3BinaryParser.encodeDirectCommand(Ev3Constants.Opcode.UI_READ, true, 100, 0, "ccg", Ev3Constants.UIReadSubcode.GET_HW_VERS, (short) 100, (byte) 0); byte[] reply = sendCommand(functionName, command, true); if (reply != null && reply[0] == Ev3Constants.DirectReplyType.DIRECT_REPLY) { Object[] value = Ev3BinaryParser.unpack("xS", reply); return String.valueOf(value[0]); } else { form.dispatchErrorOccurredEvent(this, functionName, ErrorMessages.ERROR_EV3_INVALID_REPLY); return null; } } }