Skip to content
This repository has been archived by the owner on Dec 23, 2021. It is now read-only.

Commit

Permalink
CLUE LEDs (White and Red) (#298)
Browse files Browse the repository at this point in the history
* first commit

* updated broken test

* Fixed spelling error for red_led

* Add white leds to refs

* wip white leds

* Add colors for leds on and off

* Modify white led color according to state

* Functioning red and white leds

* Remove logs

* Fix merge conflicts

* Format py

* Rebase change for cluesimulator.tsx

* Reset file to dev version

* Restore cluesimulator.tsx with dev version

* Make changes for cluesimulator.tsx

* Updated led variables

Co-authored-by: xnkevinnguyen <xuannamkevin@gmail.com>
Co-authored-by: Andrea Mah <31675041+andreamah@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 9, 2020
1 parent 003b42b commit 87897bd
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 80 deletions.
3 changes: 3 additions & 0 deletions src/base_circuitpython/base_cp_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class CLUE_STATE:
GYRO_X = "gyro_x"
GYRO_Y = "gyro_y"
GYRO_Z = "gyro_z"
# LEDs
RED_LED = "red_led"
WHITE_LEDS = "white_leds"


CPX = "CPX"
Expand Down
42 changes: 23 additions & 19 deletions src/clue/adafruit_clue.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel
"""

from common.telemetry_events import TelemetryEvent
from common.telemetry import telemetry_py
from common import utils
from base_circuitpython import base_cp_constants as CONSTANTS
import neopixel
import time
import array
import math
Expand All @@ -67,11 +72,6 @@

abs_path = pathlib.Path(__file__).parent.absolute()
sys.path.insert(0, os.path.join(abs_path))
import neopixel
from base_circuitpython import base_cp_constants as CONSTANTS
from common import utils
from common.telemetry import telemetry_py
from common.telemetry_events import TelemetryEvent

# REVISED VERSION OF THE ADAFRUIT CLUE LIBRARY FOR DSX

Expand Down Expand Up @@ -227,6 +227,10 @@ def __init__(self):
self.__state[CONSTANTS.CLUE_STATE.GYRO_X] = 0
self.__state[CONSTANTS.CLUE_STATE.GYRO_Y] = 0
self.__state[CONSTANTS.CLUE_STATE.GYRO_Z] = 0
# LEDs
self.__state[CONSTANTS.CLUE_STATE.RED_LED] = False
self.__state[CONSTANTS.CLUE_STATE.WHITE_LEDS] = False

self.button_mapping = {
CONSTANTS.CLUE_STATE.BUTTON_A: "A",
CONSTANTS.CLUE_STATE.BUTTON_B: "B",
Expand Down Expand Up @@ -502,7 +506,7 @@ def touch_0(self):
@property
def touch_1(self):
"""Not Implemented!
Detect touch on capacitive touch pad 1.
.. image :: ../docs/_static/pad_1.jpg
:alt: Pad 1
Expand All @@ -520,7 +524,7 @@ def touch_1(self):
@property
def touch_2(self):
"""Not Implemented!
Detect touch on capacitive touch pad 2.
.. image :: ../docs/_static/pad_2.jpg
:alt: Pad 2
Expand All @@ -537,9 +541,7 @@ def touch_2(self):

@property
def white_leds(self):
"""Not Implemented!
The red led next to the USB plug labeled LED.
"""The red led next to the USB plug labeled LED.
.. image :: ../docs/_static/white_leds.jpg
:alt: White LEDs
This example turns on the white LEDs.
Expand All @@ -549,19 +551,16 @@ def white_leds(self):
clue.white_leds = True
"""
telemetry_py.send_telemetry(TelemetryEvent.CLUE_API_WHITE_LEDS)
utils.print_for_unimplemented_functions(Clue.white_leds.__name__)
return self.__state[CONSTANTS.CLUE_STATE.WHITE_LEDS]

@white_leds.setter
def white_leds(self, value):
"""Not Implemented!"""
telemetry_py.send_telemetry(TelemetryEvent.CLUE_API_WHITE_LEDS)
utils.print_for_unimplemented_functions(Clue.white_leds.__name__)
self.__set_leds(CONSTANTS.CLUE_STATE.WHITE_LEDS, value)

@property
def red_led(self):
"""Not Implemented!
The red led next to the USB plug labeled LED.
"""The red led next to the USB plug labeled LED.
.. image :: ../docs/_static/red_led.jpg
:alt: Red LED
This example turns on the red LED.
Expand All @@ -571,13 +570,12 @@ def red_led(self):
clue.red_led = True
"""
telemetry_py.send_telemetry(TelemetryEvent.CLUE_API_RED_LED)
utils.print_for_unimplemented_functions(Clue.red_led.__name__)
return self.__state[CONSTANTS.CLUE_STATE.RED_LED]

@red_led.setter
def red_led(self, value):
"""Not Implemented!"""
telemetry_py.send_telemetry(TelemetryEvent.CLUE_API_RED_LED)
utils.print_for_unimplemented_functions(Clue.red_led.__name__)
self.__set_leds(CONSTANTS.CLUE_STATE.RED_LED, value)

def play_tone(self, frequency, duration):
""" Not Implemented!
Expand Down Expand Up @@ -773,6 +771,12 @@ def __update_button(self, button, value):
)
self.__state[button] = value

def __set_leds(self, led, value):
value = bool(value)
self.__state[led] = value
sendable_json = {led: value}
utils.send_to_simulator(sendable_json, CONSTANTS.CLUE)


clue = Clue() # pylint: disable=invalid-name
"""Object that is automatically created on import.
Expand Down
16 changes: 16 additions & 0 deletions src/clue/test/test_adafruit_clue.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,19 @@ def test_sea_level_pressure(self, mock_sea_level_pressure):
def test_pixel(self, mock_color):
clue.pixel.fill(mock_color)
assert clue.pixel[0] == mock_color

@pytest.mark.parametrize(
"value, expected",
[(True, True), (False, False), (1, True), ("a", True), (0, False), ("", False)],
)
def test_red_led(self, value, expected):
clue.red_led = value
assert clue.red_led == expected

@pytest.mark.parametrize(
"value, expected",
[(True, True), (False, False), (1, True), ("a", True), (0, False), ("", False)],
)
def test_white_leds(self, value, expected):
clue.white_leds = value
assert clue.white_leds == expected
8 changes: 6 additions & 2 deletions src/view/components/clue/ClueImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ interface EventTriggers {
interface IProps {
eventTriggers: EventTriggers;
displayMessage: string;
neopixel: number[];
leds: {
neopixel: number[];
isRedLedOn: boolean;
isWhiteLedOn: boolean;
};
}

export enum BUTTONS_KEYS {
Expand Down Expand Up @@ -80,7 +84,7 @@ export class ClueImage extends React.Component<IProps, {}> {
<ClueSvg
ref={this.svgRef}
displayImage={this.props.displayMessage}
neopixel={this.props.neopixel}
leds={this.props.leds}
/>
);
}
Expand Down
78 changes: 54 additions & 24 deletions src/view/components/clue/ClueSimulator.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import * as React from "react";
import {
AB_BUTTONS_KEYS,
// DEVICE_LIST_KEY,
CONSTANTS,
DEFAULT_IMG_CLUE,
DEVICE_LIST_KEY,
VIEW_STATE,
WEBVIEW_MESSAGES,
} from "../../constants";
import { ViewStateContext } from "../../context";
import "../../styles/Simulator.css";
import PlayLogo from "../../svgs/play_svg";
import StopLogo from "../../svgs/stop_svg";
import { sendMessage } from "../../utils/MessageUtils";
import ActionBar from "../simulator/ActionBar";
import { BUTTONS_KEYS, ClueImage } from "./ClueImage";
import "../../styles/Simulator.css";
import { ViewStateContext } from "../../context";

export const DEFAULT_CLUE_STATE: IClueState = {
buttons: { button_a: false, button_b: false },
displayMessage: DEFAULT_IMG_CLUE,
neopixel: [0, 0, 0],
leds: {
neopixel: [0, 0, 0],
isRedLedOn: false,
isWhiteLedOn: false,
},
};

interface IState {
Expand All @@ -34,7 +38,11 @@ interface IState {
interface IClueState {
buttons: { button_a: boolean; button_b: boolean };
displayMessage: string;
neopixel: number[];
leds: {
neopixel: number[];
isRedLedOn: boolean;
isWhiteLedOn: boolean;
};
}
export class ClueSimulator extends React.Component<any, IState> {
private imageRef: React.RefObject<ClueImage> = React.createRef();
Expand Down Expand Up @@ -63,25 +71,7 @@ export class ClueSimulator extends React.Component<any, IState> {
});
break;
case "set-state":
console.log(
`message received ${JSON.stringify(message.state)}`
);
if (message.state.display_base64) {
this.setState({
clue: {
...this.state.clue,
displayMessage: message.state.display_base64,
},
});
} else if (message.state.pixels) {
this.setState({
clue: {
...this.state.clue,
neopixel: message.state.pixels,
},
});
}

this.handleStateChangeMessage(message);
break;
case "activate-play":
const newRunningFile = this.state.currently_selected_file;
Expand Down Expand Up @@ -142,7 +132,7 @@ export class ClueSimulator extends React.Component<any, IState> {
onKeyEvent: this.onKeyEvent,
}}
displayMessage={this.state.clue.displayMessage}
neopixel={this.state.clue.neopixel}
leds={this.state.clue.leds}
/>
</div>
<ActionBar
Expand Down Expand Up @@ -280,5 +270,45 @@ export class ClueSimulator extends React.Component<any, IState> {
this.refreshSimulatorClick();
}
}
protected handleStateChangeMessage(message: any) {
if (message.state.display_base64 != null) {
this.setState({
clue: {
...this.state.clue,
displayMessage: message.state.display_base64,
},
});
} else if (message.state.pixels != null) {
this.setState({
clue: {
...this.state.clue,
leds: {
...this.state.clue.leds,
neopixel: message.state.pixels,
},
},
});
} else if (message.state.white_leds != null) {
this.setState({
clue: {
...this.state.clue,
leds: {
...this.state.clue.leds,
isWhiteLedOn: message.state.white_leds,
},
},
});
} else if (message.state.red_led != null) {
this.setState({
clue: {
...this.state.clue,
leds: {
...this.state.clue.leds,
isRedLedOn: message.state.red_led,
},
},
});
}
}
}
ClueSimulator.contextType = ViewStateContext;
Loading

0 comments on commit 87897bd

Please sign in to comment.