AI2 Component  (Version nb184)
NxtLightSensor.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2011 Google, All Rights reserved
3 // Copyright 2011-2012 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.runtime;
8 
19 
20 import android.os.Handler;
21 
29 @DesignerComponent(version = YaVersion.NXT_LIGHTSENSOR_COMPONENT_VERSION,
30  description = "A component that provides a high-level interface to a light sensor on a " +
31  "LEGO MINDSTORMS NXT robot.",
32  category = ComponentCategory.LEGOMINDSTORMS,
33  nonVisible = true,
34  iconName = "images/legoMindstormsNxt.png")
35 @SimpleObject
36 public class NxtLightSensor extends LegoMindstormsNxtSensor implements Deleteable {
37 
38  private enum State { UNKNOWN, BELOW_RANGE, WITHIN_RANGE, ABOVE_RANGE }
39  private static final String DEFAULT_SENSOR_PORT = "3";
40  private static final int DEFAULT_BOTTOM_OF_RANGE = 256;
41  private static final int DEFAULT_TOP_OF_RANGE = 767;
42 
43  private Handler handler;
44  private final Runnable sensorReader;
45  private State previousState;
46  private int bottomOfRange;
47  private int topOfRange;
48  private boolean belowRangeEventEnabled;
49  private boolean withinRangeEventEnabled;
50  private boolean aboveRangeEventEnabled;
51  private boolean generateLight;
52 
56  public NxtLightSensor(ComponentContainer container) {
57  super(container, "NxtLightSensor");
58  handler = new Handler();
59  previousState = State.UNKNOWN;
60  sensorReader = new Runnable() {
61  public void run() {
62  if (bluetooth != null && bluetooth.IsConnected()) {
63  SensorValue<Integer> sensorValue = getLightValue("");
64  if (sensorValue.valid) {
65  State currentState;
66  if (sensorValue.value < bottomOfRange) {
67  currentState = State.BELOW_RANGE;
68  } else if (sensorValue.value > topOfRange) {
69  currentState = State.ABOVE_RANGE;
70  } else {
71  currentState = State.WITHIN_RANGE;
72  }
73 
74  if (currentState != previousState) {
75  if (currentState == State.BELOW_RANGE && belowRangeEventEnabled) {
76  BelowRange();
77  }
78  if (currentState == State.WITHIN_RANGE && withinRangeEventEnabled) {
79  WithinRange();
80  }
81  if (currentState == State.ABOVE_RANGE && aboveRangeEventEnabled) {
82  AboveRange();
83  }
84  }
85 
86  previousState = currentState;
87  }
88  }
89  if (isHandlerNeeded()) {
90  handler.post(sensorReader);
91  }
92  }
93  };
94 
95  SensorPort(DEFAULT_SENSOR_PORT);
96  BottomOfRange(DEFAULT_BOTTOM_OF_RANGE);
97  TopOfRange(DEFAULT_TOP_OF_RANGE);
100  AboveRangeEventEnabled(false);
101  GenerateLight(false);
102  }
103 
104  @Override
105  protected void initializeSensor(String functionName) {
106  setInputMode(functionName, port,
107  generateLight ? SENSOR_TYPE_LIGHT_ACTIVE : SENSOR_TYPE_LIGHT_INACTIVE,
108  SENSOR_MODE_PCTFULLSCALEMODE);
109  }
110 
116  defaultValue = DEFAULT_SENSOR_PORT)
117  @SimpleProperty(userVisible = false)
118  public void SensorPort(String sensorPortLetter) {
119  setSensorPort(sensorPortLetter);
120  }
121 
125  @SimpleProperty(description = "Whether the light sensor should generate light.",
126  category = PropertyCategory.BEHAVIOR)
127  public boolean GenerateLight() {
128  return generateLight;
129  }
130 
135  defaultValue = "False")
137  public void GenerateLight(boolean generateLight) {
138  this.generateLight = generateLight;
139  if (bluetooth != null && bluetooth.IsConnected()) {
140  initializeSensor("GenerateLight");
141  }
142  }
143 
144  @SimpleFunction(description = "Returns the current light level as a value between 0 and 1023, " +
145  "or -1 if the light level can not be read.")
146  public int GetLightLevel() {
147  String functionName = "GetLightLevel";
148  if (!checkBluetooth(functionName)) {
149  return -1;
150  }
151 
152  SensorValue<Integer> sensorValue = getLightValue(functionName);
153  if (sensorValue.valid) {
154  return sensorValue.value;
155  }
156 
157  // invalid response
158  return -1;
159  }
160 
161  private SensorValue<Integer> getLightValue(String functionName) {
162  byte[] returnPackage = getInputValues(functionName, port);
163  if (returnPackage != null) {
164  boolean valid = getBooleanValueFromBytes(returnPackage, 4);
165  if (valid) {
166  int normalizedValue = getUWORDValueFromBytes(returnPackage, 10);
167  return new SensorValue<Integer>(true, normalizedValue);
168  }
169  }
170 
171  // invalid response
172  return new SensorValue<Integer>(false, null);
173  }
174 
179  @SimpleProperty(description = "The bottom of the range used for the BelowRange, WithinRange," +
180  " and AboveRange events.",
181  category = PropertyCategory.BEHAVIOR)
182  public int BottomOfRange() {
183  return bottomOfRange;
184  }
185 
191  defaultValue = "" + DEFAULT_BOTTOM_OF_RANGE)
193  public void BottomOfRange(int bottomOfRange) {
194  this.bottomOfRange = bottomOfRange;
195  previousState = State.UNKNOWN;
196  }
197 
202  @SimpleProperty(description = "The top of the range used for the BelowRange, WithinRange, and" +
203  " AboveRange events.",
204  category = PropertyCategory.BEHAVIOR)
205  public int TopOfRange() {
206  return topOfRange;
207  }
208 
214  defaultValue = "" + DEFAULT_TOP_OF_RANGE)
216  public void TopOfRange(int topOfRange) {
217  this.topOfRange = topOfRange;
218  previousState = State.UNKNOWN;
219  }
220 
225  @SimpleProperty(description = "Whether the BelowRange event should fire when the light level" +
226  " goes below the BottomOfRange.",
227  category = PropertyCategory.BEHAVIOR)
228  public boolean BelowRangeEventEnabled() {
229  return belowRangeEventEnabled;
230  }
231 
236  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
238  public void BelowRangeEventEnabled(boolean enabled) {
239  boolean handlerWasNeeded = isHandlerNeeded();
240 
241  belowRangeEventEnabled = enabled;
242 
243  boolean handlerIsNeeded = isHandlerNeeded();
244  if (handlerWasNeeded && !handlerIsNeeded) {
245  handler.removeCallbacks(sensorReader);
246  }
247  if (!handlerWasNeeded && handlerIsNeeded) {
248  previousState = State.UNKNOWN;
249  handler.post(sensorReader);
250  }
251  }
252 
253  @SimpleEvent(description = "Light level has gone below the range.")
254  public void BelowRange() {
255  EventDispatcher.dispatchEvent(this, "BelowRange");
256  }
257 
262  @SimpleProperty(description = "Whether the WithinRange event should fire when the light level" +
263  " goes between the BottomOfRange and the TopOfRange.",
264  category = PropertyCategory.BEHAVIOR)
265  public boolean WithinRangeEventEnabled() {
266  return withinRangeEventEnabled;
267  }
268 
273  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
275  public void WithinRangeEventEnabled(boolean enabled) {
276  boolean handlerWasNeeded = isHandlerNeeded();
277 
278  withinRangeEventEnabled = enabled;
279 
280  boolean handlerIsNeeded = isHandlerNeeded();
281  if (handlerWasNeeded && !handlerIsNeeded) {
282  handler.removeCallbacks(sensorReader);
283  }
284  if (!handlerWasNeeded && handlerIsNeeded) {
285  previousState = State.UNKNOWN;
286  handler.post(sensorReader);
287  }
288  }
289 
290  @SimpleEvent(description = "Light level has gone within the range.")
291  public void WithinRange() {
292  EventDispatcher.dispatchEvent(this, "WithinRange");
293  }
294 
299  @SimpleProperty(description = "Whether the AboveRange event should fire when the light level" +
300  " goes above the TopOfRange.",
301  category = PropertyCategory.BEHAVIOR)
302  public boolean AboveRangeEventEnabled() {
303  return aboveRangeEventEnabled;
304  }
305 
310  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, defaultValue = "False")
312  public void AboveRangeEventEnabled(boolean enabled) {
313  boolean handlerWasNeeded = isHandlerNeeded();
314 
315  aboveRangeEventEnabled = enabled;
316 
317  boolean handlerIsNeeded = isHandlerNeeded();
318  if (handlerWasNeeded && !handlerIsNeeded) {
319  handler.removeCallbacks(sensorReader);
320  }
321  if (!handlerWasNeeded && handlerIsNeeded) {
322  previousState = State.UNKNOWN;
323  handler.post(sensorReader);
324  }
325  }
326 
327  @SimpleEvent(description = "Light level has gone above the range.")
328  public void AboveRange() {
329  EventDispatcher.dispatchEvent(this, "AboveRange");
330  }
331 
332  private boolean isHandlerNeeded() {
333  return belowRangeEventEnabled || withinRangeEventEnabled || aboveRangeEventEnabled;
334  }
335 
336  // Deleteable implementation
337 
338  @Override
339  public void onDelete() {
340  handler.removeCallbacks(sensorReader);
341  super.onDelete();
342  }
343 }
com.google.appinventor.components.runtime.EventDispatcher
Definition: EventDispatcher.java:22
com.google.appinventor.components.annotations.SimpleFunction
Definition: SimpleFunction.java:23
com.google.appinventor.components.runtime.NxtLightSensor.BelowRangeEventEnabled
void BelowRangeEventEnabled(boolean enabled)
Definition: NxtLightSensor.java:238
com.google.appinventor.components.common.YaVersion
Definition: YaVersion.java:14
com.google.appinventor.components.runtime.NxtLightSensor.BelowRange
void BelowRange()
Definition: NxtLightSensor.java:254
com.google.appinventor.components.annotations.DesignerProperty
Definition: DesignerProperty.java:25
com.google.appinventor.components.runtime.NxtLightSensor.onDelete
void onDelete()
Definition: NxtLightSensor.java:339
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.bluetooth
BluetoothClient bluetooth
Definition: LegoMindstormsNxtBase.java:77
com.google.appinventor.components
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_NON_NEGATIVE_INTEGER
static final String PROPERTY_TYPE_NON_NEGATIVE_INTEGER
Definition: PropertyTypeConstants.java:206
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.setSensorPort
final void setSensorPort(String sensorPortLetter)
Definition: LegoMindstormsNxtSensor.java:78
com.google.appinventor.components.runtime.BluetoothConnectionBase.IsConnected
final boolean IsConnected()
Definition: BluetoothConnectionBase.java:204
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN
static final String PROPERTY_TYPE_BOOLEAN
Definition: PropertyTypeConstants.java:35
com.google.appinventor.components.runtime.NxtLightSensor.GenerateLight
void GenerateLight(boolean generateLight)
Definition: NxtLightSensor.java:137
com.google.appinventor.components.annotations.DesignerComponent
Definition: DesignerComponent.java:22
com.google.appinventor.components.annotations.SimpleEvent
Definition: SimpleEvent.java:20
com.google.appinventor.components.runtime.NxtLightSensor.BelowRangeEventEnabled
boolean BelowRangeEventEnabled()
Definition: NxtLightSensor.java:228
com.google.appinventor.components.annotations.PropertyCategory.BEHAVIOR
BEHAVIOR
Definition: PropertyCategory.java:15
com.google.appinventor.components.runtime.NxtLightSensor.GetLightLevel
int GetLightLevel()
Definition: NxtLightSensor.java:146
com.google.appinventor.components.runtime.NxtLightSensor.TopOfRange
void TopOfRange(int topOfRange)
Definition: NxtLightSensor.java:216
com.google.appinventor.components.runtime.NxtLightSensor.BottomOfRange
void BottomOfRange(int bottomOfRange)
Definition: NxtLightSensor.java:193
com.google.appinventor.components.runtime.NxtLightSensor.WithinRangeEventEnabled
void WithinRangeEventEnabled(boolean enabled)
Definition: NxtLightSensor.java:275
com.google.appinventor.components.runtime.NxtLightSensor.NxtLightSensor
NxtLightSensor(ComponentContainer container)
Definition: NxtLightSensor.java:56
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.SensorPort
String SensorPort()
Definition: LegoMindstormsNxtSensor.java:70
com.google.appinventor.components.runtime.NxtLightSensor.WithinRangeEventEnabled
boolean WithinRangeEventEnabled()
Definition: NxtLightSensor.java:265
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getInputValues
final byte[] getInputValues(String functionName, int port)
Definition: LegoMindstormsNxtBase.java:168
com.google.appinventor.components.runtime.NxtLightSensor.AboveRangeEventEnabled
void AboveRangeEventEnabled(boolean enabled)
Definition: NxtLightSensor.java:312
com.google.appinventor.components.runtime.EventDispatcher.dispatchEvent
static boolean dispatchEvent(Component component, String eventName, Object...args)
Definition: EventDispatcher.java:188
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor
Definition: LegoMindstormsNxtSensor.java:21
com.google.appinventor.components.runtime.NxtLightSensor
Definition: NxtLightSensor.java:36
com.google.appinventor.components.runtime.NxtLightSensor.AboveRangeEventEnabled
boolean AboveRangeEventEnabled()
Definition: NxtLightSensor.java:302
com.google.appinventor.components.annotations.SimpleProperty
Definition: SimpleProperty.java:23
com.google.appinventor.components.annotations.PropertyCategory
Definition: PropertyCategory.java:13
com.google.appinventor.components.runtime.ComponentContainer
Definition: ComponentContainer.java:16
com.google.appinventor.components.runtime.NxtLightSensor.initializeSensor
void initializeSensor(String functionName)
Definition: NxtLightSensor.java:105
com.google.appinventor.components.runtime.Deleteable
Definition: Deleteable.java:15
com.google.appinventor.components.common
Definition: ComponentCategory.java:7
com.google.appinventor.components.runtime.NxtLightSensor.GenerateLight
boolean GenerateLight()
Definition: NxtLightSensor.java:127
com.google.appinventor.components.common.ComponentCategory
Definition: ComponentCategory.java:48
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.checkBluetooth
final boolean checkBluetooth(String functionName)
Definition: LegoMindstormsNxtBase.java:250
com.google.appinventor.components.runtime.NxtLightSensor.TopOfRange
int TopOfRange()
Definition: NxtLightSensor.java:205
com.google.appinventor.components.annotations.SimpleObject
Definition: SimpleObject.java:23
com.google.appinventor.components.runtime.LegoMindstormsNxtSensor.port
int port
Definition: LegoMindstormsNxtSensor.java:56
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getBooleanValueFromBytes
final boolean getBooleanValueFromBytes(byte[] bytes, int offset)
Definition: LegoMindstormsNxtBase.java:399
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.getUWORDValueFromBytes
final int getUWORDValueFromBytes(byte[] bytes, int offset)
Definition: LegoMindstormsNxtBase.java:416
com.google
com
com.google.appinventor.components.runtime.NxtLightSensor.WithinRange
void WithinRange()
Definition: NxtLightSensor.java:291
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_LEGO_NXT_SENSOR_PORT
static final String PROPERTY_TYPE_LEGO_NXT_SENSOR_PORT
Definition: PropertyTypeConstants.java:101
com.google.appinventor.components.runtime.NxtLightSensor.AboveRange
void AboveRange()
Definition: NxtLightSensor.java:328
com.google.appinventor.components.runtime.LegoMindstormsNxtBase.setInputMode
final void setInputMode(String functionName, int port, int sensorType, int sensorMode)
Definition: LegoMindstormsNxtBase.java:158
com.google.appinventor.components.common.PropertyTypeConstants
Definition: PropertyTypeConstants.java:14
com.google.appinventor.components.annotations
com.google.appinventor
com.google.appinventor.components.runtime.NxtLightSensor.BottomOfRange
int BottomOfRange()
Definition: NxtLightSensor.java:182