7 package com.google.appinventor.components.runtime;
20 import android.os.Handler;
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,
34 iconName =
"images/legoMindstormsNxt.png")
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;
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;
57 super(container,
"NxtLightSensor");
58 handler =
new Handler();
59 previousState = State.UNKNOWN;
60 sensorReader =
new Runnable() {
63 SensorValue<Integer> sensorValue = getLightValue(
"");
64 if (sensorValue.valid) {
66 if (sensorValue.value < bottomOfRange) {
67 currentState = State.BELOW_RANGE;
68 }
else if (sensorValue.value > topOfRange) {
69 currentState = State.ABOVE_RANGE;
71 currentState = State.WITHIN_RANGE;
74 if (currentState != previousState) {
75 if (currentState == State.BELOW_RANGE && belowRangeEventEnabled) {
78 if (currentState == State.WITHIN_RANGE && withinRangeEventEnabled) {
81 if (currentState == State.ABOVE_RANGE && aboveRangeEventEnabled) {
86 previousState = currentState;
89 if (isHandlerNeeded()) {
90 handler.post(sensorReader);
107 generateLight ? SENSOR_TYPE_LIGHT_ACTIVE : SENSOR_TYPE_LIGHT_INACTIVE,
108 SENSOR_MODE_PCTFULLSCALEMODE);
116 defaultValue = DEFAULT_SENSOR_PORT)
125 @
SimpleProperty(description =
"Whether the light sensor should generate light.",
128 return generateLight;
135 defaultValue =
"False")
138 this.generateLight = generateLight;
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.")
147 String functionName =
"GetLightLevel";
152 SensorValue<Integer> sensorValue = getLightValue(functionName);
153 if (sensorValue.valid) {
154 return sensorValue.value;
161 private SensorValue<Integer> getLightValue(String functionName) {
163 if (returnPackage !=
null) {
167 return new SensorValue<Integer>(
true, normalizedValue);
172 return new SensorValue<Integer>(
false,
null);
179 @SimpleProperty(description =
"The bottom of the range used for the BelowRange, WithinRange," +
180 " and AboveRange events.",
181 category = PropertyCategory.BEHAVIOR)
183 return bottomOfRange;
191 defaultValue =
"" + DEFAULT_BOTTOM_OF_RANGE)
194 this.bottomOfRange = bottomOfRange;
195 previousState = State.UNKNOWN;
202 @
SimpleProperty(description =
"The top of the range used for the BelowRange, WithinRange, and" +
203 " AboveRange events.",
214 defaultValue =
"" + DEFAULT_TOP_OF_RANGE)
217 this.topOfRange = topOfRange;
218 previousState = State.UNKNOWN;
225 @
SimpleProperty(description =
"Whether the BelowRange event should fire when the light level" +
226 " goes below the BottomOfRange.",
229 return belowRangeEventEnabled;
239 boolean handlerWasNeeded = isHandlerNeeded();
241 belowRangeEventEnabled = enabled;
243 boolean handlerIsNeeded = isHandlerNeeded();
244 if (handlerWasNeeded && !handlerIsNeeded) {
245 handler.removeCallbacks(sensorReader);
247 if (!handlerWasNeeded && handlerIsNeeded) {
248 previousState = State.UNKNOWN;
249 handler.post(sensorReader);
253 @
SimpleEvent(description =
"Light level has gone below the range.")
262 @
SimpleProperty(description =
"Whether the WithinRange event should fire when the light level" +
263 " goes between the BottomOfRange and the TopOfRange.",
266 return withinRangeEventEnabled;
276 boolean handlerWasNeeded = isHandlerNeeded();
278 withinRangeEventEnabled = enabled;
280 boolean handlerIsNeeded = isHandlerNeeded();
281 if (handlerWasNeeded && !handlerIsNeeded) {
282 handler.removeCallbacks(sensorReader);
284 if (!handlerWasNeeded && handlerIsNeeded) {
285 previousState = State.UNKNOWN;
286 handler.post(sensorReader);
290 @
SimpleEvent(description =
"Light level has gone within the range.")
299 @
SimpleProperty(description =
"Whether the AboveRange event should fire when the light level" +
300 " goes above the TopOfRange.",
303 return aboveRangeEventEnabled;
313 boolean handlerWasNeeded = isHandlerNeeded();
315 aboveRangeEventEnabled = enabled;
317 boolean handlerIsNeeded = isHandlerNeeded();
318 if (handlerWasNeeded && !handlerIsNeeded) {
319 handler.removeCallbacks(sensorReader);
321 if (!handlerWasNeeded && handlerIsNeeded) {
322 previousState = State.UNKNOWN;
323 handler.post(sensorReader);
327 @
SimpleEvent(description =
"Light level has gone above the range.")
332 private boolean isHandlerNeeded() {
333 return belowRangeEventEnabled || withinRangeEventEnabled || aboveRangeEventEnabled;
340 handler.removeCallbacks(sensorReader);