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

Minor update to production #352

Merged
merged 15 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,32 @@ Make without limit! Device Simulator Express, a Microsoft Garage project, allows
result when you plug in your actual microcontroller. Curious about the output of the device, the serial
monitor allows you to observe the device output.

## Devices we support:
## Table of Contents
- [Devices we support](#devices-we-support)
- [Prerequisites](#prerequisites)
- [Adafruit Circuit Playground Express (CPX) Simulator](#adafruit-circuit-playground-express-cpx-simulator)
- [Features](#features)
- [Useful Links](#useful-links)
- [Keyboard Shortcuts](#keyboard-shortcuts)
- [BBC micro:bit Simulator](#bbc-microbit-simulator)
- [Features](#features-1)
- [Useful Links](#useful-links-1)
- [Keyboard Shortcuts](#keyboard-shortcuts-1)
- [Adafruit CLUE Simulator](#adafruit-clue-simulator)
- [Features](#features-2)
- [Useful Links](#useful-links-2)
- [Keyboard Shortcuts](#keyboard-shortcuts-2)
- [How to use](#how-to-use)
- [Commands](#commands)
- [Contribute](#contribute)
- [Provide feedback](#provide-feedback)
- [Privacy and Telemetry Notice](#privacy-and-telemetry-notice)
- [Third Party Notice](#third-party-notice)
- [Troubleshooting Tips](#troubleshooting-tips)
- [License](#license)
- [Notes](#notes)

## Devices we support

- [**Adafruit Circuit Playground Express (CPX)**](#adafruit-circuit-playground-express-cpx-simulator)

Expand Down
56 changes: 37 additions & 19 deletions src/clue/adafruit_slideshow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from io import BytesIO
from base_circuitpython import base_cp_constants as CONSTANTS
import time
import collections
from random import shuffle
import common
import board
Expand Down Expand Up @@ -165,6 +164,7 @@ def __init__(

self._order = order
self._curr_img = ""
self._current_image_index = None

# load images into main queue
self.__load_images()
Expand Down Expand Up @@ -219,41 +219,57 @@ def update(self):

def __get_next_img(self):

# handle empty queue
if not len(self.pic_queue):
if self.loop:
self.__load_images()
if self.direction == PlayBackDirection.FORWARD:
if self._current_image_index == None:
self._current_image_index = 0
else:
return ""
self._current_image_index += 1

if self._current_image_index >= len(self.dir_imgs):

if self.loop:
self._current_image_index = 0
self.__load_images()
else:
self._current_image_index = len(self.dir_imgs) - 10
return ""

if self.direction == PlayBackDirection.FORWARD:
return self.pic_queue.popleft()
else:
return self.pic_queue.pop()
if self._current_image_index == None:
self._current_image_index = len(self.dir_imgs) - 1
else:
self._current_image_index -= 1

if self._current_image_index < 0:
if self.loop:
self._current_image_index = len(self.dir_imgs) - 1
self.__load_images()
else:
self._current_image_index = 0
return ""

img = self.dir_imgs[self._current_image_index]
return img

def __load_images(self):
dir_imgs = []
self.dir_imgs = []
for d in self.dirs:
try:
new_path = os.path.join(self.folder, d)

# only add bmp imgs
if os.path.splitext(new_path)[1] == CONSTANTS.BMP_IMG_ENDING:
dir_imgs.append(new_path)
if os.path.splitext(new_path)[-1] == CONSTANTS.BMP_IMG_ENDING:
self.dir_imgs.append(new_path)
except Image.UnidentifiedImageError as e:
continue

if not len(dir_imgs):
if not len(self.dir_imgs):
raise RuntimeError(CONSTANTS.NO_VALID_IMGS_ERR)

if self._order == PlayBackOrder.RANDOM:
shuffle(dir_imgs)
shuffle(self.dir_imgs)
else:
dir_imgs.sort()

# convert list to queue
# (must be list beforehand for potential randomization)
self.pic_queue = collections.deque(dir_imgs)
self.dir_imgs.sort()

def __advance_with_fade(self):
if board.DISPLAY.active_group != self:
Expand All @@ -265,6 +281,7 @@ def __advance_with_fade(self):
while not advance_sucessful:
new_path = self.__get_next_img()
if new_path == "":
self._img_start = time.monotonic()
return False

try:
Expand Down Expand Up @@ -323,6 +340,7 @@ def __advance_no_fade(self):
while not advance_sucessful:
new_path = self.__get_next_img()
if new_path == "":
self._img_start = time.monotonic()
return False

try:
Expand Down
24 changes: 23 additions & 1 deletion src/debug_user_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@
# Insert absolute path to Circuitpython libraries for CLUE into sys.path
sys.path.insert(0, os.path.join(abs_path_to_parent_dir, CONSTANTS.CIRCUITPYTHON))

# get board so we can get terminal handle
import board

# This import must happen after the sys.path is modified
from common import debugger_communication_client

# get handle to terminal for clue
curr_terminal = board.DISPLAY.terminal

## Execute User Code ##

# Get user's code path
Expand All @@ -56,12 +62,26 @@
utils.abs_path_to_user_file = abs_path_to_code_file
utils.debug_mode = True

# overriding print function so that it shows on clue terminal
def print_decorator(func):
global curr_terminal

def wrapped_func(*args, **kwargs):
curr_terminal.add_str_to_terminal("".join(str(e) for e in args))
return func(*args, **kwargs)

return wrapped_func


print = print_decorator(print)

# Execute the user's code file
with open(abs_path_to_code_file, encoding="utf8") as user_code_file:
curr_terminal.add_str_to_terminal(CONSTANTS.CODE_START_MSG_CLUE)
user_code = user_code_file.read()
try:
codeObj = compile(user_code, abs_path_to_code_file, CONSTANTS.EXEC_COMMAND)
exec(codeObj, {})
exec(codeObj, {"print": print})
sys.stdout.flush()
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
Expand All @@ -71,3 +91,5 @@
for frameIndex in range(2, len(stackTrace) - 1):
errorMessage += "\t" + str(stackTrace[frameIndex])
print(e, errorMessage, file=sys.stderr, flush=True)
curr_terminal.add_str_to_terminal(CONSTANTS.CODE_FINISHED_MSG_CLUE)
board.DISPLAY.show(None)
57 changes: 35 additions & 22 deletions src/latest_release_note.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/view/components/cpx/CpxImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export const updateSwitch = (switchState: boolean): void => {
if (switchElement && switchInner) {
svg.addClass(switchInner, "sim-slide-switch-inner");

if (switchState) {
if (!switchState) {
svg.addClass(switchInner, "on");
switchInner.setAttribute("transform", "translate(-5,0)");
} else {
Expand Down
1 change: 1 addition & 0 deletions src/view/components/toolbar/GenericSliderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const GenericSliderComponent: React.FC<IProps> = props => {
value={
props.axisValues[sliderProperties.axisLabel]
}
step={sliderProperties.step}
/>
<br />
</React.Fragment>
Expand Down
11 changes: 8 additions & 3 deletions src/view/components/toolbar/InputSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class InputSlider extends React.Component<ISliderProps, any, any> {

render() {
const isInputDisabled = this.context === VIEW_STATE.PAUSE;

const nbDecimals =
this.props.step.toString().split(".")[1]?.length || 0;
return (
<div className="input-slider">
<span>{this.props.axisLabel}</span>
Expand All @@ -31,8 +34,9 @@ class InputSlider extends React.Component<ISliderProps, any, any> {
onInput={this.handleOnChange}
defaultValue={this.props.minValue.toLocaleString()}
pattern={`^-?[0-9]{0,${
this.props.maxValue.toString().length
}}$`}
(this.props.maxValue / this.props.step).toString()
.length
}}[.]{0,${nbDecimals > 0 ? 1 : 0}}[0-9]{0,${nbDecimals}}$`}
onKeyUp={this.handleOnChange}
aria-label={`${this.props.type} sensor input ${this.props.axisLabel}`}
/>
Expand All @@ -56,6 +60,7 @@ class InputSlider extends React.Component<ISliderProps, any, any> {
aria-label={`${this.props.type} sensor`}
defaultValue={this.props.minValue.toLocaleString()}
disabled={isInputDisabled}
step={this.props.step}
/>
<span className="downLabelArea">
<span className="minLabel">{this.props.minLabel}</span>
Expand Down Expand Up @@ -100,7 +105,7 @@ class InputSlider extends React.Component<ISliderProps, any, any> {
};

private validateRange = (valueString: string) => {
let valueInt = parseInt(valueString, 10);
let valueInt = parseFloat(valueString);
if (valueInt < this.props.minValue) {
valueInt = this.props.minValue;
this.setState({ value: valueInt });
Expand Down
23 changes: 20 additions & 3 deletions src/view/components/toolbar/clue/ClueSensorProperties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,31 @@ import { ISensorProps, ISliderProps } from "../../../viewUtils";
const CLUE_SLIDER_R: ISliderProps = {
axisLabel: "R",
maxLabel: "Max",
maxValue: 255,
maxValue: 65535,
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.LIGHT_R,
step: 1,
};

const CLUE_SLIDER_G: ISliderProps = {
axisLabel: "G",
maxLabel: "Max",
maxValue: 255,
maxValue: 65535,
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.LIGHT_G,
step: 1,
};

const CLUE_SLIDER_B: ISliderProps = {
axisLabel: "B",
maxLabel: "Max",
maxValue: 255,
maxValue: 65535,
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.LIGHT_B,
step: 1,
};
const CLUE_SLIDER_C: ISliderProps = {
axisLabel: "C",
Expand All @@ -34,6 +37,7 @@ const CLUE_SLIDER_C: ISliderProps = {
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.LIGHT_C,
step: 1,
};

export const CLUE_LIGHT_PROPERTIES: ISensorProps = {
Expand All @@ -50,6 +54,7 @@ const CLUE_MAGNET_X: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.MAGNET_X,
step: 0.1,
};
const CLUE_MAGNET_Y: ISliderProps = {
axisLabel: "Y",
Expand All @@ -58,6 +63,7 @@ const CLUE_MAGNET_Y: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.MAGNET_Y,
step: 0.1,
};
const CLUE_MAGNET_Z: ISliderProps = {
axisLabel: "Z",
Expand All @@ -66,6 +72,7 @@ const CLUE_MAGNET_Z: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.MAGNET_Z,
step: 0.1,
};

export const CLUE_MAGNET_PROPERTIES: ISensorProps = {
Expand All @@ -80,6 +87,7 @@ const CLUE_GYRO_X: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.GYRO_X,
step: 0.1,
};
const CLUE_GYRO_Y: ISliderProps = {
axisLabel: "Y",
Expand All @@ -88,6 +96,7 @@ const CLUE_GYRO_Y: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.GYRO_Y,
step: 0.1,
};
const CLUE_GYRO_Z: ISliderProps = {
axisLabel: "Z",
Expand All @@ -96,6 +105,7 @@ const CLUE_GYRO_Z: ISliderProps = {
maxValue: 1000,
minValue: -1000,
type: SENSOR_LIST.GYRO_Z,
step: 0.1,
};

export const CLUE_GYRO_PROPERTIES: ISensorProps = {
Expand All @@ -114,6 +124,7 @@ export const CLUE_HUMIDITY_PROPERTIES: ISensorProps = {
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.HUMIDITY,
step: 0.1,
},
],
unitLabel: "%",
Expand All @@ -128,6 +139,7 @@ export const CLUE__PROXIMITY_PROPERTIES: ISensorProps = {
minLabel: "Min",
minValue: 0,
type: SENSOR_LIST.PROXIMITY,
step: 1,
},
],
unitLabel: "",
Expand All @@ -142,6 +154,7 @@ export const CLUE_PRESSURE_PROPERTIES: ISensorProps = {
minLabel: "Min",
minValue: 800,
type: SENSOR_LIST.PRESSURE,
step: 0.1,
},
],
unitLabel: "hPa",
Expand All @@ -153,6 +166,7 @@ const MOTION_SLIDER_PROPS_X: ISliderProps = {
minLabel: "Left",
minValue: -1023,
type: SENSOR_LIST.MOTION_X,
step: 0.1,
};

const MOTION_SLIDER_PROPS_Y: ISliderProps = {
Expand All @@ -162,6 +176,7 @@ const MOTION_SLIDER_PROPS_Y: ISliderProps = {
minLabel: "Back",
minValue: -1023,
type: SENSOR_LIST.MOTION_Y,
step: 0.1,
};

const MOTION_SLIDER_PROPS_Z: ISliderProps = {
Expand All @@ -171,6 +186,7 @@ const MOTION_SLIDER_PROPS_Z: ISliderProps = {
minLabel: "Up",
minValue: -1023,
type: SENSOR_LIST.MOTION_Z,
step: 0.1,
};

export const MOTION_SENSOR_PROPERTIES: ISensorProps = {
Expand All @@ -190,6 +206,7 @@ const TEMPERATURE_SLIDER_PROPS: ISliderProps = {
minLabel: "Cold",
minValue: -55,
type: SENSOR_LIST.TEMPERATURE,
step: 0.1,
};

export const TEMPERATURE_SENSOR_PROPERTIES: ISensorProps = {
Expand Down
Loading