From 0b31c8722dde607baa13b0d068ca636b0b94251e Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 10:44:57 -0800 Subject: [PATCH 01/10] updated cpx telemtry --- src/adafruit_circuitplayground/constants.py | 28 ++++++++++++++------- src/adafruit_circuitplayground/express.py | 11 +++++++- src/adafruit_circuitplayground/pixel.py | 6 +++-- src/adafruit_circuitplayground/telemetry.py | 27 ++++++-------------- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/adafruit_circuitplayground/constants.py b/src/adafruit_circuitplayground/constants.py index 4e6100d97..b41608bd8 100644 --- a/src/adafruit_circuitplayground/constants.py +++ b/src/adafruit_circuitplayground/constants.py @@ -28,16 +28,26 @@ VALID_PIXEL_ASSIGN_ERROR = "The pixel color value should be a tuple with three values between 0 and 255 or a hexadecimal color between 0x000000 and 0xFFFFFF." TELEMETRY_EVENT_NAMES = { - "TAPPED": "API.TAPPED", - "PLAY_FILE": "API.PLAY.FILE", - "PLAY_TONE": "API.PLAY.TONE", - "START_TONE": "API.START.TONE", - "STOP_TONE": "API.STOP.TONE", - "DETECT_TAPS": "API.DETECT.TAPS", - "ADJUST_THRESHOLD": "API.ADJUST.THRESHOLD", - "RED_LED": "API.RED.LED", - "PIXELS": "API.PIXELS", + "CPX_API_ACCELERATION": "CPX.API.ACCELERATION", + "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", + "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", + "CPX_API_SWITCH": "CPX.API.SWITCH", + "CPX_API_TEMPERATURE": "CPX.API.TEMPERATURE", + "CPX_API_BRIGHTNESS": "CPX.API.BRIGHTNESS", + "CPX_API_LIGHT": "CPX.API.LIGHT", + "CPX_API_TOUCH": "CPX.API.TOUCH", + "CPX_API_SHAKE": "CPX.API.SHAKE", + "CPX_API_TAPPED": "CPX.API.TAPPED", + "CPX_API_PLAY_FILE": "CPX.API.PLAY.FILE", + "CPX_API_PLAY_TONE": "CPX.API.PLAY.TONE", + "CPX_API_START_TONE": "CPX.API.START.TONE", + "CPX_API_STOP_TONE": "CPX.API.STOP.TONE", + "CPX_API_DETECT_TAPS": "CPX.API.DETECT.TAPS", + "CPX_API_ADJUST_THRESHOLD": "CPX.API.ADJUST.THRESHOLD", + "CPX_API_RED_LED": "CPX.API.RED.LED", + "CPX_API_PIXELS": "CPX.API.PIXELS", } + ERROR_SENDING_EVENT = "Error trying to send event to the process : " TIME_DELAY = 0.03 diff --git a/src/adafruit_circuitplayground/express.py b/src/adafruit_circuitplayground/express.py index 9e20af4b2..e063f1434 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -52,25 +52,29 @@ def __init__(self): @property def acceleration(self): + telemetry_py.send_telemetry("CPX_API_ACCELERATION") return Acceleration( self.__state["motion_x"], self.__state["motion_y"], self.__state["motion_z"] ) @property def button_a(self): + telemetry_py.send_telemetry("CPX_API_BUTTON_A") return self.__state["button_a"] @property def button_b(self): + telemetry_py.send_telemetry("CPX_API_BUTTON_B") return self.__state["button_b"] @property def detect_taps(self): - telemetry_py.send_telemetry("DETECT_TAPS") + telemetry_py.send_telemetry("CPX_API_DETECT_TAPS") return self.__state["detect_taps"] @detect_taps.setter def detect_taps(self, value): + telemetry_py.send_telemetry("CPX_API_DETECT_TAPS") value_int = int(value) self.__state["detect_taps"] = ( value_int if (value_int == 1 or value_int == 2) else 1 @@ -96,14 +100,17 @@ def red_led(self, value): @property def switch(self): + telemetry_py.send_telemetry("CPX_API_SWITCH") return self.__state["switch"] @property def temperature(self): + telemetry_py.send_telemetry("CPX_API_TEMPERATURE") return self.__state["temperature"] @property def light(self): + telemetry_py.send_telemetry("CPX_API_LIGHT") return self.__state["light"] def __show(self): @@ -113,6 +120,7 @@ def __show(self): utils.send_to_simulator(self.__state, CONSTANTS.CPX) def __touch(self, i): + telemetry_py.send_telemetry("CPX_API_TOUCH") return self.__state["touch"][i - 1] @property @@ -151,6 +159,7 @@ def adjust_touch_threshold(self, adjustement): raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def shake(self, shake_threshold=30): + telemetry_py.send_telemetry("CPX_API_SHAKE") return self.__state["shake"] def play_file(self, file_name): diff --git a/src/adafruit_circuitplayground/pixel.py b/src/adafruit_circuitplayground/pixel.py index 631311ce8..579a78b10 100644 --- a/src/adafruit_circuitplayground/pixel.py +++ b/src/adafruit_circuitplayground/pixel.py @@ -38,11 +38,11 @@ def __getitem__(self, index): if type(index) is not slice: if not self.__valid_index(index): raise IndexError(CONSTANTS.INDEX_ERROR) - telemetry_py.send_telemetry("PIXELS") + telemetry_py.send_telemetry("CPX_API_PIXELS") return self.__state["pixels"][index] def __setitem__(self, index, val): - telemetry_py.send_telemetry("PIXELS") + telemetry_py.send_telemetry("CPX_API_PIXELS") is_slice = False if type(index) is slice: is_slice = True @@ -115,12 +115,14 @@ def __valid_rgb_value(self, pixValue): @property def brightness(self): + telemetry_py.send_telemetry("CPX_API_BRIGHTNESS") return self.__state["brightness"] @brightness.setter def brightness(self, brightness): if not self.__valid_brightness(brightness): raise ValueError(CONSTANTS.BRIGHTNESS_RANGE_ERROR) + telemetry_py.send_telemetry("CPX_API_BRIGHTNESS") self.__state["brightness"] = brightness self.__show_if_auto_write() diff --git a/src/adafruit_circuitplayground/telemetry.py b/src/adafruit_circuitplayground/telemetry.py index 9fd1edb1c..8e3cd3a6d 100644 --- a/src/adafruit_circuitplayground/telemetry.py +++ b/src/adafruit_circuitplayground/telemetry.py @@ -1,4 +1,4 @@ -from . import constants as CONSTANTS +import constants as CONSTANTS from applicationinsights import TelemetryClient @@ -6,36 +6,23 @@ class Telemetry: def __init__(self): # State of the telemetry self.__enable_telemetry = True - self.telemetry_state = { - "DETECT_TAPS": False, - "TAPPED": False, - "RED_LED": False, - "ADJUST_THRESHOLD": False, - "PLAY_FILE": False, - "PLAY_TONE": False, - "START_TONE": False, - "STOP_TONE": False, - "PIXELS": False, - } self.telemetry_client = TelemetryClient("__AIKEY__") - self.extension_name = "__EXTENSIONNAME__" + self.extension_name = "Device Simulator Express" def send_telemetry(self, event_name): if ( self.__enable_telemetry and self.telemetry_available() - and not self.telemetry_state[event_name] + and event_name in CONSTANTS.TELEMETRY_EVENT_NAMES ): self.telemetry_client.track_event( - "{}/{}".format( - self.extension_name, CONSTANTS.TELEMETRY_EVENT_NAMES[event_name] - ) + f"{self.extension_name}/{CONSTANTS.TELEMETRY_EVENT_NAMES[event_name]}" ) self.telemetry_client.flush() - self.telemetry_state[event_name] = True def telemetry_available(self): - return self.telemetry_client.context.instrumentation_key != "__AIKEY__" + return self.telemetry_client.context.instrumentation_key == "__AIKEY__" + return True -telemetry_py = Telemetry() +telemetry_py = Telemetry() \ No newline at end of file From 8df4da50a31dc23a7c4a33c217558897be4253ec Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 10:50:13 -0800 Subject: [PATCH 02/10] Added used and total telemetry --- src/adafruit_circuitplayground/constants.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/adafruit_circuitplayground/constants.py b/src/adafruit_circuitplayground/constants.py index b41608bd8..c55558212 100644 --- a/src/adafruit_circuitplayground/constants.py +++ b/src/adafruit_circuitplayground/constants.py @@ -28,7 +28,8 @@ VALID_PIXEL_ASSIGN_ERROR = "The pixel color value should be a tuple with three values between 0 and 255 or a hexadecimal color between 0x000000 and 0xFFFFFF." TELEMETRY_EVENT_NAMES = { - "CPX_API_ACCELERATION": "CPX.API.ACCELERATION", + "CPX_API_ACCELERATION_USED": "CPX.API.ACCELERATION.USED", + "CPX_API_ACCELERATION_TOTAL": "CPX.API.ACCELERATION.TOTAL", "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", "CPX_API_SWITCH": "CPX.API.SWITCH", From 6583e7bf7525385ce6349cd8ca5a71215af7e152 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 12:09:36 -0800 Subject: [PATCH 03/10] Added Python telemetry --- src/adafruit_circuitplayground/constants.py | 22 ------------- src/adafruit_circuitplayground/express.py | 5 ++- src/adafruit_circuitplayground/pixel.py | 6 ++-- src/common/constants.py | 33 +++++++++++++++++++ .../telemetry.py | 9 ++--- src/microbit/__init__.py | 2 ++ src/microbit/__model/accelerometer.py | 9 +++++ src/microbit/__model/button.py | 6 ++++ src/microbit/__model/display.py | 14 +++++++- src/microbit/__model/image.py | 22 +++++++++++-- src/process_user_code.py | 3 +- 11 files changed, 94 insertions(+), 37 deletions(-) rename src/{adafruit_circuitplayground => common}/telemetry.py (74%) diff --git a/src/adafruit_circuitplayground/constants.py b/src/adafruit_circuitplayground/constants.py index c55558212..98924bfcc 100644 --- a/src/adafruit_circuitplayground/constants.py +++ b/src/adafruit_circuitplayground/constants.py @@ -27,28 +27,6 @@ VALID_PIXEL_ASSIGN_ERROR = "The pixel color value should be a tuple with three values between 0 and 255 or a hexadecimal color between 0x000000 and 0xFFFFFF." -TELEMETRY_EVENT_NAMES = { - "CPX_API_ACCELERATION_USED": "CPX.API.ACCELERATION.USED", - "CPX_API_ACCELERATION_TOTAL": "CPX.API.ACCELERATION.TOTAL", - "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", - "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", - "CPX_API_SWITCH": "CPX.API.SWITCH", - "CPX_API_TEMPERATURE": "CPX.API.TEMPERATURE", - "CPX_API_BRIGHTNESS": "CPX.API.BRIGHTNESS", - "CPX_API_LIGHT": "CPX.API.LIGHT", - "CPX_API_TOUCH": "CPX.API.TOUCH", - "CPX_API_SHAKE": "CPX.API.SHAKE", - "CPX_API_TAPPED": "CPX.API.TAPPED", - "CPX_API_PLAY_FILE": "CPX.API.PLAY.FILE", - "CPX_API_PLAY_TONE": "CPX.API.PLAY.TONE", - "CPX_API_START_TONE": "CPX.API.START.TONE", - "CPX_API_STOP_TONE": "CPX.API.STOP.TONE", - "CPX_API_DETECT_TAPS": "CPX.API.DETECT.TAPS", - "CPX_API_ADJUST_THRESHOLD": "CPX.API.ADJUST.THRESHOLD", - "CPX_API_RED_LED": "CPX.API.RED.LED", - "CPX_API_PIXELS": "CPX.API.PIXELS", -} - ERROR_SENDING_EVENT = "Error trying to send event to the process : " TIME_DELAY = 0.03 diff --git a/src/adafruit_circuitplayground/express.py b/src/adafruit_circuitplayground/express.py index e063f1434..693ec868f 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -5,13 +5,12 @@ import sys import os import playsound + from common import utils +from common.telemetry import telemetry_py from .pixel import Pixel - from . import constants as CONSTANTS from collections import namedtuple -from applicationinsights import TelemetryClient -from .telemetry import telemetry_py from . import debugger_communication_client Acceleration = namedtuple("acceleration", ["x", "y", "z"]) diff --git a/src/adafruit_circuitplayground/pixel.py b/src/adafruit_circuitplayground/pixel.py index 579a78b10..3c43c8f68 100644 --- a/src/adafruit_circuitplayground/pixel.py +++ b/src/adafruit_circuitplayground/pixel.py @@ -3,12 +3,10 @@ import json import sys -from common import utils -from . import constants as CONSTANTS -from applicationinsights import TelemetryClient +from common import utils +from common.telemetry import telemetry_py from . import constants as CONSTANTS -from .telemetry import telemetry_py from . import debugger_communication_client diff --git a/src/common/constants.py b/src/common/constants.py index 97ea32386..077eb3f2a 100644 --- a/src/common/constants.py +++ b/src/common/constants.py @@ -1,3 +1,36 @@ MAC_OS = "darwin" TIME_DELAY = 0.03 + +TELEMETRY_EVENT_NAMES = { + "CPX_API_ACCELERATION_USED": "CPX.API.ACCELERATION.USED", + "CPX_API_ACCELERATION_TOTAL": "CPX.API.ACCELERATION.TOTAL", + "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", + "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", + "CPX_API_SWITCH": "CPX.API.SWITCH", + "CPX_API_TEMPERATURE": "CPX.API.TEMPERATURE", + "CPX_API_BRIGHTNESS": "CPX.API.BRIGHTNESS", + "CPX_API_LIGHT": "CPX.API.LIGHT", + "CPX_API_TOUCH": "CPX.API.TOUCH", + "CPX_API_SHAKE": "CPX.API.SHAKE", + "CPX_API_TAPPED": "CPX.API.TAPPED", + "CPX_API_PLAY_FILE": "CPX.API.PLAY.FILE", + "CPX_API_PLAY_TONE": "CPX.API.PLAY.TONE", + "CPX_API_START_TONE": "CPX.API.START.TONE", + "CPX_API_STOP_TONE": "CPX.API.STOP.TONE", + "CPX_API_DETECT_TAPS": "CPX.API.DETECT.TAPS", + "CPX_API_ADJUST_THRESHOLD": "CPX.API.ADJUST.THRESHOLD", + "CPX_API_RED_LED": "CPX.API.RED.LED", + "CPX_API_PIXELS": "CPX.API.PIXELS", + "MICROBIT_API_TEMPERATURE": "MICROBIT.API.TEMPERATURE", + "MICROBIT_API_ACCELEROMETER": "MICROBIT.API.ACCELEROMETER", + "MICROBIT_API_GESTURE": "MICROBIT.API.GESTURE", + "MICROBIT_API_DISPLAY_SCROLL": "MICROBIT.API.DISPLAY.SCROLL", + "MICROBIT_API_DISPLAY_SHOW": "MICROBIT.API.DISPLAY.SHOW", + "MICROBIT_API_DISPLAY_OTHER": "MICROBIT.API.DISPLAY_OTHER", + "MICROBIT_API_LIGHT_LEVEL": "MICROBIT.API.LIGHT.LEVEL", + "MICROBIT_API_IMAGE_CREATION": "MICROBIT.API.IMAGE.CREATION", + "MICROBIT_API_IMAGE_OTHER": "MICROBIT.API.IMAGE.OTHER", + "MICROBIT_API_IMAGE_STATIC": "MICROBIT.API.IMAGE.STATIC", + "MICROBIT_API_BUTTON": "MICROBIT.API.BUTTON", +} diff --git a/src/adafruit_circuitplayground/telemetry.py b/src/common/telemetry.py similarity index 74% rename from src/adafruit_circuitplayground/telemetry.py rename to src/common/telemetry.py index 8e3cd3a6d..d1822c0c4 100644 --- a/src/adafruit_circuitplayground/telemetry.py +++ b/src/common/telemetry.py @@ -1,5 +1,5 @@ -import constants as CONSTANTS from applicationinsights import TelemetryClient +from . import constants as CONSTANTS class Telemetry: @@ -7,22 +7,23 @@ def __init__(self): # State of the telemetry self.__enable_telemetry = True self.telemetry_client = TelemetryClient("__AIKEY__") + self.telemetry_state = dict.fromkeys(CONSTANTS.TELEMETRY_EVENT_NAMES, False) self.extension_name = "Device Simulator Express" def send_telemetry(self, event_name): if ( self.__enable_telemetry and self.telemetry_available() - and event_name in CONSTANTS.TELEMETRY_EVENT_NAMES + and not self.telemetry_state[event_name] ): self.telemetry_client.track_event( f"{self.extension_name}/{CONSTANTS.TELEMETRY_EVENT_NAMES[event_name]}" ) self.telemetry_client.flush() + self.telemetry_state[event_name] = True def telemetry_available(self): return self.telemetry_client.context.instrumentation_key == "__AIKEY__" - return True -telemetry_py = Telemetry() \ No newline at end of file +telemetry_py = Telemetry() diff --git a/src/microbit/__init__.py b/src/microbit/__init__.py index bdf3f0779..03201858a 100644 --- a/src/microbit/__init__.py +++ b/src/microbit/__init__.py @@ -1,5 +1,6 @@ from .__model.image import Image from .__model.microbit_model import __mb +from common.telemetry import telemetry_py accelerometer = __mb.accelerometer button_a = __mb.button_a @@ -29,4 +30,5 @@ def temperature(): """ Return the temperature of the micro:bit in degrees Celcius. """ + telemetry_py.send_telemetry("MICROBIT_API_SLEEP") return __mb.temperature() diff --git a/src/microbit/__model/accelerometer.py b/src/microbit/__model/accelerometer.py index 919d3c9db..e5cb138cb 100644 --- a/src/microbit/__model/accelerometer.py +++ b/src/microbit/__model/accelerometer.py @@ -1,4 +1,5 @@ from . import constants as CONSTANTS +from common.telemetry import telemetry_py class Accelerometer: @@ -17,6 +18,7 @@ def get_x(self): negative integer, depending on the direction. The measurement is given in milli-g. """ + telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") return self.__x def get_y(self): @@ -25,6 +27,7 @@ def get_y(self): negative integer, depending on the direction. The measurement is given in milli-g. """ + telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") return self.__y def get_z(self): @@ -33,6 +36,7 @@ def get_z(self): negative integer, depending on the direction. The measurement is given in milli-g. """ + telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") return self.__z def get_values(self): @@ -40,12 +44,14 @@ def get_values(self): Get the acceleration measurements in all axes at once, as a three-element tuple of integers ordered as X, Y, Z. """ + telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") return (self.__x, self.__y, self.__z) def current_gesture(self): """ Return the name of the current gesture. """ + telemetry_py.send_telemetry("MICROBIT_API_GESTURE") self.__add_current_gesture_to_gesture_lists() return self.__current_gesture @@ -53,6 +59,7 @@ def is_gesture(self, name): """ Return True or False to indicate if the named gesture is currently active. """ + telemetry_py.send_telemetry("MICROBIT_API_GESTURE") self.__add_current_gesture_to_gesture_lists() if name not in CONSTANTS.GESTURES: raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) @@ -63,6 +70,7 @@ def was_gesture(self, name): Return True or False to indicate if the named gesture was active since the last [was_gesture] call. """ + telemetry_py.send_telemetry("MICROBIT_API_GESTURE") self.__add_current_gesture_to_gesture_lists() if name not in CONSTANTS.GESTURES: raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) @@ -75,6 +83,7 @@ def get_gestures(self): Return a tuple of the gesture history. The most recent is listed last. Also clears the gesture history before returning. """ + telemetry_py.send_telemetry("MICROBIT_API_GESTURE") self.__add_current_gesture_to_gesture_lists() gestures = tuple(self.__gestures) self.__gestures.clear() diff --git a/src/microbit/__model/button.py b/src/microbit/__model/button.py index 32689f485..5a20307e8 100644 --- a/src/microbit/__model/button.py +++ b/src/microbit/__model/button.py @@ -1,3 +1,6 @@ +from common.telemetry import telemetry_py + + class Button: # The implementation is based off of https://microbit-micropython.readthedocs.io/en/v1.0.1/button.html. def __init__(self): @@ -10,6 +13,7 @@ def is_pressed(self): Returns ``True`` if the specified button ``button`` is currently being held down, and ``False`` otherwise. """ + telemetry_py.send_telemetry("MICROBIT_API_BUTTON") return self.__pressed def was_pressed(self): @@ -20,6 +24,7 @@ def was_pressed(self): that the button must be pressed again before this method will return ``True`` again. """ + telemetry_py.send_telemetry("MICROBIT_API_BUTTON") res = self.__prev_pressed self.__prev_pressed = False return res @@ -29,6 +34,7 @@ def get_presses(self): Returns the running total of button presses, and resets this total to zero before returning. """ + telemetry_py.send_telemetry("MICROBIT_API_BUTTON") res = self.__presses self.__presses = 0 return res diff --git a/src/microbit/__model/display.py b/src/microbit/__model/display.py index ff62e4e59..875c80169 100644 --- a/src/microbit/__model/display.py +++ b/src/microbit/__model/display.py @@ -1,8 +1,9 @@ import copy import time import threading -from common import utils +from common import utils +from common.telemetry import telemetry_py from . import constants as CONSTANTS from .image import Image @@ -44,6 +45,8 @@ def scroll(self, value, delay=150, wait=True, loop=False, monospace=False): thread.start() return + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_SCROLL") + # Set current_pid to the thread's identifier self.__lock.acquire() self.__current_pid = threading.get_ident() @@ -123,6 +126,8 @@ def show(self, value, delay=400, wait=True, loop=False, clear=False): thread.start() return + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_SHOW") + # Set current_pid to the thread's identifier self.__lock.acquire() self.__current_pid = threading.get_ident() @@ -183,6 +188,7 @@ def get_pixel(self, x, y): Return the brightness of the LED at column ``x`` and row ``y`` as an integer between 0 (off) and 9 (bright). """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") self.__lock.acquire() pixel = self.__image.get_pixel(x, y) self.__lock.release() @@ -193,6 +199,7 @@ def set_pixel(self, x, y, value): Set the brightness of the LED at column ``x`` and row ``y`` to ``value``, which has to be an integer between 0 and 9. """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") self.__lock.acquire() self.__image.set_pixel(x, y, value) self.__lock.release() @@ -202,6 +209,7 @@ def clear(self): """ Set the brightness of all LEDs to 0 (off). """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") self.__lock.acquire() self.__image = Image() self.__lock.release() @@ -211,18 +219,21 @@ def on(self): """ Use on() to turn on the display. """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") self.__on = True def off(self): """ Use off() to turn off the display. """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") self.__on = False def is_on(self): """ Returns ``True`` if the display is on, otherwise returns ``False``. """ + telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") return self.__on def read_light_level(self): @@ -231,6 +242,7 @@ def read_light_level(self): falling on the display. Returns an integer between 0 and 255 representing the light level, with larger meaning more light. """ + telemetry_py.send_telemetry("MICROBIT_API_LIGHT_LEVEL") return self.__light_level def __set_light_level(self, level): diff --git a/src/microbit/__model/image.py b/src/microbit/__model/image.py index a1aef09c6..0e29f6cad 100644 --- a/src/microbit/__model/image.py +++ b/src/microbit/__model/image.py @@ -1,5 +1,6 @@ from . import constants as CONSTANTS from .producer_property import ProducerProperty +from common.telemetry import telemetry_py class Image: @@ -114,7 +115,7 @@ class Image: def __init__(self, *args, **kwargs): # Depending on the number of arguments # in constructor, it treat args differently. - + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_CREATION") if len(args) == 0: # default constructor self.__LED = self.__string_to_square_array(CONSTANTS.BLANK_5X5) @@ -140,13 +141,13 @@ def __init__(self, *args, **kwargs): self.__LED = self.__bytes_to_array(width, height, byte_arr) else: self.__LED = self.__create_leds(width, height) - self.read_only = False def width(self): """ Return the number of columns in the image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") if len(self.__LED) > 0: return len(self.__LED[0]) else: @@ -156,6 +157,7 @@ def height(self): """ Return the numbers of rows in the image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return len(self.__LED) def set_pixel(self, x, y, value): @@ -166,6 +168,7 @@ def set_pixel(self, x, y, value): This method will raise an exception when called on any of the built-in read-only images, like ``Image.HEART``. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") if self.read_only: raise TypeError(CONSTANTS.COPY_ERR_MESSAGE) elif not self.__valid_pos(x, y): @@ -180,6 +183,7 @@ def get_pixel(self, x, y): Return the brightness of pixel at column ``x`` and row ``y`` as an integer between 0 and 9. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") if self.__valid_pos(x, y): return self.__LED[y][x] else: @@ -189,12 +193,14 @@ def shift_up(self, n): """ Return a new image created by shifting the picture up by ``n`` rows. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return self.__shift_vertical(-n) def shift_down(self, n): """ Return a new image created by shifting the picture down by ``n`` rows. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return self.__shift_vertical(n) def shift_right(self, n): @@ -202,6 +208,7 @@ def shift_right(self, n): Return a new image created by shifting the picture right by ``n`` columns. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return self.__shift_horizontal(n) def shift_left(self, n): @@ -209,6 +216,7 @@ def shift_left(self, n): Return a new image created by shifting the picture left by ``n`` columns. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return self.__shift_horizontal(-n) def crop(self, x, y, w, h): @@ -216,6 +224,7 @@ def crop(self, x, y, w, h): Return a new image by cropping the picture to a width of ``w`` and a height of ``h``, starting with the pixel at column ``x`` and row ``y``. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") res = Image(w, h) res.blit(self, x, y, w, h) return res @@ -224,6 +233,7 @@ def copy(self): """ Return an exact copy of the image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") return Image(self.__create_string()) # This inverts the brightness of each LED. @@ -234,6 +244,7 @@ def invert(self): Return a new image by inverting the brightness of the pixels in the source image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") for y in range(self.height()): for x in range(self.width()): self.set_pixel(x, y, CONSTANTS.BRIGHTNESS_MAX - self.get_pixel(x, y)) @@ -247,6 +258,7 @@ def fill(self, value): This method will raise an exception when called on any of the built-in read-only images, like ``Image.HEART``. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") for y in range(self.height()): for x in range(self.width()): self.set_pixel(x, y, value) @@ -258,6 +270,7 @@ def blit(self, src, x, y, w, h, xdest=0, ydest=0): this image at ``xdest``, ``ydest``. Areas in the source rectangle, but outside the source image are treated as having a value of 0. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") if not src.__valid_pos(x, y): raise ValueError(CONSTANTS.INDEX_ERR) @@ -276,6 +289,7 @@ def __add__(self, other): """ Create a new image by adding the brightness values from the two images for each pixel. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") if not isinstance(other, Image): raise TypeError( CONSTANTS.UNSUPPORTED_ADD_TYPE + f"'{type(self)}', '{type(other)}'" @@ -298,6 +312,7 @@ def __mul__(self, other): """ Create a new image by multiplying the brightness of each pixel by n. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") try: float_val = float(other) except TypeError: @@ -316,6 +331,7 @@ def __repr__(self): """ Get a compact string representation of the image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") ret_str = "Image('" for index_y in range(self.height()): ret_str += self.__row_to_str(index_y) @@ -328,6 +344,7 @@ def __str__(self): """ Get a readable string representation of the image. """ + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") ret_str = "Image('\n" for index_y in range(self.height()): ret_str += "\t" + self.__row_to_str(index_y) + "\n" @@ -486,6 +503,7 @@ def __same_image(i1, i2): # This is for generating functions like Image.HEART # that return a new read-only Image def create_const_func(func_name): + telemetry_py.send_telemetry("MICROBIT_API_IMAGE_STATIC") def func(*args): const_instance = Image(CONSTANTS.IMAGE_PATTERNS[func_name]) const_instance.read_only = True diff --git a/src/process_user_code.py b/src/process_user_code.py index e34c19c21..0748cd501 100644 --- a/src/process_user_code.py +++ b/src/process_user_code.py @@ -28,8 +28,9 @@ sys.path.insert(0, abs_path_to_lib) # This import must happen after the sys.path is modified +from common.telemetry import telemetry_py + from adafruit_circuitplayground.express import cpx -from adafruit_circuitplayground.telemetry import telemetry_py from adafruit_circuitplayground.constants import CPX from microbit.__model.microbit_model import __mb as mb From cba41bc86555bdb33a91246964651c4f940900f3 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 12:20:56 -0800 Subject: [PATCH 04/10] Fixed bug with acceleration api telemetry --- src/common/constants.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/constants.py b/src/common/constants.py index 077eb3f2a..5dbe6b926 100644 --- a/src/common/constants.py +++ b/src/common/constants.py @@ -3,8 +3,7 @@ TIME_DELAY = 0.03 TELEMETRY_EVENT_NAMES = { - "CPX_API_ACCELERATION_USED": "CPX.API.ACCELERATION.USED", - "CPX_API_ACCELERATION_TOTAL": "CPX.API.ACCELERATION.TOTAL", + "CPX_API_ACCELERATION": "CPX.API.ACCELERATION", "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", "CPX_API_SWITCH": "CPX.API.SWITCH", From 40e385dcd7f85b4537dde3cf3bf841fca68df82e Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 12:23:30 -0800 Subject: [PATCH 05/10] Fixed bug --- src/microbit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/microbit/__init__.py b/src/microbit/__init__.py index 03201858a..97adc75b0 100644 --- a/src/microbit/__init__.py +++ b/src/microbit/__init__.py @@ -30,5 +30,5 @@ def temperature(): """ Return the temperature of the micro:bit in degrees Celcius. """ - telemetry_py.send_telemetry("MICROBIT_API_SLEEP") + telemetry_py.send_telemetry("MICROBIT_API_TEMPERATURE") return __mb.temperature() From 1a4d037b220fc8317e30822e43cfdf13c6f8d767 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 12:23:46 -0800 Subject: [PATCH 06/10] Formatted with black --- src/microbit/__model/image.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/microbit/__model/image.py b/src/microbit/__model/image.py index 0e29f6cad..affa8a987 100644 --- a/src/microbit/__model/image.py +++ b/src/microbit/__model/image.py @@ -504,6 +504,7 @@ def __same_image(i1, i2): # that return a new read-only Image def create_const_func(func_name): telemetry_py.send_telemetry("MICROBIT_API_IMAGE_STATIC") + def func(*args): const_instance = Image(CONSTANTS.IMAGE_PATTERNS[func_name]) const_instance.read_only = True From 87def93f1419bbe4129636d6814a8f7897ab468b Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 13:26:32 -0800 Subject: [PATCH 07/10] Updated names of telemetry events --- src/adafruit_circuitplayground/express.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/adafruit_circuitplayground/express.py b/src/adafruit_circuitplayground/express.py index 693ec868f..ad53f2a64 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -83,17 +83,17 @@ def detect_taps(self, value): def tapped(self): """ Not Implemented! """ - telemetry_py.send_telemetry("TAPPED") + telemetry_py.send_telemetry("CPX_API_TAPPED") raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) @property def red_led(self): - telemetry_py.send_telemetry("RED_LED") + telemetry_py.send_telemetry("CPX_API_RED_LED") return self.__state["red_led"] @red_led.setter def red_led(self, value): - telemetry_py.send_telemetry("RED_LED") + telemetry_py.send_telemetry("CPX_API_RED_LED") self.__state["red_led"] = bool(value) self.__show() @@ -154,7 +154,7 @@ def adjust_touch_threshold(self, adjustement): """Not implemented! The CPX Simulator doesn't use capacitive touch threshold. """ - telemetry_py.send_telemetry("ADJUST_THRESHOLD") + telemetry_py.send_telemetry("CPX_API_ADJUST_THRESHOLD") raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def shake(self, shake_threshold=30): @@ -162,7 +162,7 @@ def shake(self, shake_threshold=30): return self.__state["shake"] def play_file(self, file_name): - telemetry_py.send_telemetry("PLAY_FILE") + telemetry_py.send_telemetry("CPX_API_PLAY_FILE") file_name = utils.remove_leading_slashes(file_name) abs_path_parent_dir = os.path.abspath( os.path.join(self.__abs_path_to_code_file, os.pardir) @@ -187,19 +187,19 @@ def play_file(self, file_name): def play_tone(self, frequency, duration): """ Not Implemented! """ - telemetry_py.send_telemetry("PLAY_TONE") + telemetry_py.send_telemetry("CPX_API_PLAY_TONE") raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def start_tone(self, frequency): """ Not Implemented! """ - telemetry_py.send_telemetry("START_TONE") + telemetry_py.send_telemetry("CPX_API_START_TONE") raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def stop_tone(self): """ Not Implemented! """ - telemetry_py.send_telemetry("STOP_TONE") + telemetry_py.send_telemetry("CPX_API_STOP_TONE") raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def update_state(self, new_state): From b4a8bb92108387d0ab6b4fb21281dd4489905c52 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 15:59:35 -0800 Subject: [PATCH 08/10] Made constants into enum --- src/adafruit_circuitplayground/express.py | 37 ++++++++++----------- src/adafruit_circuitplayground/pixel.py | 9 +++--- src/common/constants.py | 32 ------------------- src/common/telemetry.py | 15 +++++---- src/microbit/__init__.py | 3 +- src/microbit/__model/accelerometer.py | 17 +++++----- src/microbit/__model/button.py | 7 ++-- src/microbit/__model/display.py | 19 +++++------ src/microbit/__model/image.py | 39 ++++++++++++----------- 9 files changed, 78 insertions(+), 100 deletions(-) diff --git a/src/adafruit_circuitplayground/express.py b/src/adafruit_circuitplayground/express.py index ad53f2a64..5eb9a3d7e 100644 --- a/src/adafruit_circuitplayground/express.py +++ b/src/adafruit_circuitplayground/express.py @@ -8,6 +8,7 @@ from common import utils from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent from .pixel import Pixel from . import constants as CONSTANTS from collections import namedtuple @@ -51,29 +52,29 @@ def __init__(self): @property def acceleration(self): - telemetry_py.send_telemetry("CPX_API_ACCELERATION") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_ACCELERATION) return Acceleration( self.__state["motion_x"], self.__state["motion_y"], self.__state["motion_z"] ) @property def button_a(self): - telemetry_py.send_telemetry("CPX_API_BUTTON_A") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BUTTON_A) return self.__state["button_a"] @property def button_b(self): - telemetry_py.send_telemetry("CPX_API_BUTTON_B") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BUTTON_B) return self.__state["button_b"] @property def detect_taps(self): - telemetry_py.send_telemetry("CPX_API_DETECT_TAPS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_DETECT_TAPS) return self.__state["detect_taps"] @detect_taps.setter def detect_taps(self, value): - telemetry_py.send_telemetry("CPX_API_DETECT_TAPS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_DETECT_TAPS) value_int = int(value) self.__state["detect_taps"] = ( value_int if (value_int == 1 or value_int == 2) else 1 @@ -83,33 +84,33 @@ def detect_taps(self, value): def tapped(self): """ Not Implemented! """ - telemetry_py.send_telemetry("CPX_API_TAPPED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TAPPED) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) @property def red_led(self): - telemetry_py.send_telemetry("CPX_API_RED_LED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_RED_LED) return self.__state["red_led"] @red_led.setter def red_led(self, value): - telemetry_py.send_telemetry("CPX_API_RED_LED") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_RED_LED) self.__state["red_led"] = bool(value) self.__show() @property def switch(self): - telemetry_py.send_telemetry("CPX_API_SWITCH") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_SWITCH) return self.__state["switch"] @property def temperature(self): - telemetry_py.send_telemetry("CPX_API_TEMPERATURE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TEMPERATURE) return self.__state["temperature"] @property def light(self): - telemetry_py.send_telemetry("CPX_API_LIGHT") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_LIGHT) return self.__state["light"] def __show(self): @@ -119,7 +120,7 @@ def __show(self): utils.send_to_simulator(self.__state, CONSTANTS.CPX) def __touch(self, i): - telemetry_py.send_telemetry("CPX_API_TOUCH") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TOUCH) return self.__state["touch"][i - 1] @property @@ -154,15 +155,15 @@ def adjust_touch_threshold(self, adjustement): """Not implemented! The CPX Simulator doesn't use capacitive touch threshold. """ - telemetry_py.send_telemetry("CPX_API_ADJUST_THRESHOLD") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_ADJUST_THRESHOLD) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def shake(self, shake_threshold=30): - telemetry_py.send_telemetry("CPX_API_SHAKE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_SHAKE) return self.__state["shake"] def play_file(self, file_name): - telemetry_py.send_telemetry("CPX_API_PLAY_FILE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PLAY_FILE) file_name = utils.remove_leading_slashes(file_name) abs_path_parent_dir = os.path.abspath( os.path.join(self.__abs_path_to_code_file, os.pardir) @@ -187,19 +188,19 @@ def play_file(self, file_name): def play_tone(self, frequency, duration): """ Not Implemented! """ - telemetry_py.send_telemetry("CPX_API_PLAY_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PLAY_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def start_tone(self, frequency): """ Not Implemented! """ - telemetry_py.send_telemetry("CPX_API_START_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_START_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def stop_tone(self): """ Not Implemented! """ - telemetry_py.send_telemetry("CPX_API_STOP_TONE") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_STOP_TONE) raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR) def update_state(self, new_state): diff --git a/src/adafruit_circuitplayground/pixel.py b/src/adafruit_circuitplayground/pixel.py index 3c43c8f68..410f2861d 100644 --- a/src/adafruit_circuitplayground/pixel.py +++ b/src/adafruit_circuitplayground/pixel.py @@ -6,6 +6,7 @@ from common import utils from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent from . import constants as CONSTANTS from . import debugger_communication_client @@ -36,11 +37,11 @@ def __getitem__(self, index): if type(index) is not slice: if not self.__valid_index(index): raise IndexError(CONSTANTS.INDEX_ERROR) - telemetry_py.send_telemetry("CPX_API_PIXELS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS) return self.__state["pixels"][index] def __setitem__(self, index, val): - telemetry_py.send_telemetry("CPX_API_PIXELS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS) is_slice = False if type(index) is slice: is_slice = True @@ -113,14 +114,14 @@ def __valid_rgb_value(self, pixValue): @property def brightness(self): - telemetry_py.send_telemetry("CPX_API_BRIGHTNESS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BRIGHTNESS) return self.__state["brightness"] @brightness.setter def brightness(self, brightness): if not self.__valid_brightness(brightness): raise ValueError(CONSTANTS.BRIGHTNESS_RANGE_ERROR) - telemetry_py.send_telemetry("CPX_API_BRIGHTNESS") + telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BRIGHTNESS) self.__state["brightness"] = brightness self.__show_if_auto_write() diff --git a/src/common/constants.py b/src/common/constants.py index 5dbe6b926..97ea32386 100644 --- a/src/common/constants.py +++ b/src/common/constants.py @@ -1,35 +1,3 @@ MAC_OS = "darwin" TIME_DELAY = 0.03 - -TELEMETRY_EVENT_NAMES = { - "CPX_API_ACCELERATION": "CPX.API.ACCELERATION", - "CPX_API_BUTTON_A": "CPX.API.BUTTON.A", - "CPX_API_BUTTON_B": "CPX.API.BUTTON.B", - "CPX_API_SWITCH": "CPX.API.SWITCH", - "CPX_API_TEMPERATURE": "CPX.API.TEMPERATURE", - "CPX_API_BRIGHTNESS": "CPX.API.BRIGHTNESS", - "CPX_API_LIGHT": "CPX.API.LIGHT", - "CPX_API_TOUCH": "CPX.API.TOUCH", - "CPX_API_SHAKE": "CPX.API.SHAKE", - "CPX_API_TAPPED": "CPX.API.TAPPED", - "CPX_API_PLAY_FILE": "CPX.API.PLAY.FILE", - "CPX_API_PLAY_TONE": "CPX.API.PLAY.TONE", - "CPX_API_START_TONE": "CPX.API.START.TONE", - "CPX_API_STOP_TONE": "CPX.API.STOP.TONE", - "CPX_API_DETECT_TAPS": "CPX.API.DETECT.TAPS", - "CPX_API_ADJUST_THRESHOLD": "CPX.API.ADJUST.THRESHOLD", - "CPX_API_RED_LED": "CPX.API.RED.LED", - "CPX_API_PIXELS": "CPX.API.PIXELS", - "MICROBIT_API_TEMPERATURE": "MICROBIT.API.TEMPERATURE", - "MICROBIT_API_ACCELEROMETER": "MICROBIT.API.ACCELEROMETER", - "MICROBIT_API_GESTURE": "MICROBIT.API.GESTURE", - "MICROBIT_API_DISPLAY_SCROLL": "MICROBIT.API.DISPLAY.SCROLL", - "MICROBIT_API_DISPLAY_SHOW": "MICROBIT.API.DISPLAY.SHOW", - "MICROBIT_API_DISPLAY_OTHER": "MICROBIT.API.DISPLAY_OTHER", - "MICROBIT_API_LIGHT_LEVEL": "MICROBIT.API.LIGHT.LEVEL", - "MICROBIT_API_IMAGE_CREATION": "MICROBIT.API.IMAGE.CREATION", - "MICROBIT_API_IMAGE_OTHER": "MICROBIT.API.IMAGE.OTHER", - "MICROBIT_API_IMAGE_STATIC": "MICROBIT.API.IMAGE.STATIC", - "MICROBIT_API_BUTTON": "MICROBIT.API.BUTTON", -} diff --git a/src/common/telemetry.py b/src/common/telemetry.py index d1822c0c4..f90ab8b99 100644 --- a/src/common/telemetry.py +++ b/src/common/telemetry.py @@ -1,5 +1,5 @@ from applicationinsights import TelemetryClient -from . import constants as CONSTANTS +from .telemetry_events import TelemetryEvent class Telemetry: @@ -7,23 +7,26 @@ def __init__(self): # State of the telemetry self.__enable_telemetry = True self.telemetry_client = TelemetryClient("__AIKEY__") - self.telemetry_state = dict.fromkeys(CONSTANTS.TELEMETRY_EVENT_NAMES, False) + self.telemetry_state = dict.fromkeys( + [name for name, _ in TelemetryEvent.__members__.items()], False + ) self.extension_name = "Device Simulator Express" - def send_telemetry(self, event_name): + def send_telemetry(self, event_name: TelemetryEvent): if ( self.__enable_telemetry and self.telemetry_available() - and not self.telemetry_state[event_name] + and not self.telemetry_state[event_name.name] ): self.telemetry_client.track_event( - f"{self.extension_name}/{CONSTANTS.TELEMETRY_EVENT_NAMES[event_name]}" + f"{self.extension_name}/{event_name.value}" ) self.telemetry_client.flush() - self.telemetry_state[event_name] = True + self.telemetry_state[event_name.name] = True def telemetry_available(self): return self.telemetry_client.context.instrumentation_key == "__AIKEY__" telemetry_py = Telemetry() +print(telemetry_py.telemetry_state) diff --git a/src/microbit/__init__.py b/src/microbit/__init__.py index 97adc75b0..e444b34f0 100644 --- a/src/microbit/__init__.py +++ b/src/microbit/__init__.py @@ -1,6 +1,7 @@ from .__model.image import Image from .__model.microbit_model import __mb from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent accelerometer = __mb.accelerometer button_a = __mb.button_a @@ -30,5 +31,5 @@ def temperature(): """ Return the temperature of the micro:bit in degrees Celcius. """ - telemetry_py.send_telemetry("MICROBIT_API_TEMPERATURE") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_TEMPERATURE) return __mb.temperature() diff --git a/src/microbit/__model/accelerometer.py b/src/microbit/__model/accelerometer.py index e5cb138cb..6360ce982 100644 --- a/src/microbit/__model/accelerometer.py +++ b/src/microbit/__model/accelerometer.py @@ -1,5 +1,6 @@ from . import constants as CONSTANTS from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent class Accelerometer: @@ -18,7 +19,7 @@ def get_x(self): negative integer, depending on the direction. The measurement is given in milli-g. """ - telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) return self.__x def get_y(self): @@ -27,7 +28,7 @@ def get_y(self): negative integer, depending on the direction. The measurement is given in milli-g. """ - telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) return self.__y def get_z(self): @@ -36,7 +37,7 @@ def get_z(self): negative integer, depending on the direction. The measurement is given in milli-g. """ - telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) return self.__z def get_values(self): @@ -44,14 +45,14 @@ def get_values(self): Get the acceleration measurements in all axes at once, as a three-element tuple of integers ordered as X, Y, Z. """ - telemetry_py.send_telemetry("MICROBIT_API_ACCELEROMETER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER) return (self.__x, self.__y, self.__z) def current_gesture(self): """ Return the name of the current gesture. """ - telemetry_py.send_telemetry("MICROBIT_API_GESTURE") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) self.__add_current_gesture_to_gesture_lists() return self.__current_gesture @@ -59,7 +60,7 @@ def is_gesture(self, name): """ Return True or False to indicate if the named gesture is currently active. """ - telemetry_py.send_telemetry("MICROBIT_API_GESTURE") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) self.__add_current_gesture_to_gesture_lists() if name not in CONSTANTS.GESTURES: raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) @@ -70,7 +71,7 @@ def was_gesture(self, name): Return True or False to indicate if the named gesture was active since the last [was_gesture] call. """ - telemetry_py.send_telemetry("MICROBIT_API_GESTURE") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) self.__add_current_gesture_to_gesture_lists() if name not in CONSTANTS.GESTURES: raise ValueError(CONSTANTS.INVALID_GESTURE_ERR) @@ -83,7 +84,7 @@ def get_gestures(self): Return a tuple of the gesture history. The most recent is listed last. Also clears the gesture history before returning. """ - telemetry_py.send_telemetry("MICROBIT_API_GESTURE") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_GESTURE) self.__add_current_gesture_to_gesture_lists() gestures = tuple(self.__gestures) self.__gestures.clear() diff --git a/src/microbit/__model/button.py b/src/microbit/__model/button.py index 5a20307e8..1bbe4ddbc 100644 --- a/src/microbit/__model/button.py +++ b/src/microbit/__model/button.py @@ -1,4 +1,5 @@ from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent class Button: @@ -13,7 +14,7 @@ def is_pressed(self): Returns ``True`` if the specified button ``button`` is currently being held down, and ``False`` otherwise. """ - telemetry_py.send_telemetry("MICROBIT_API_BUTTON") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) return self.__pressed def was_pressed(self): @@ -24,7 +25,7 @@ def was_pressed(self): that the button must be pressed again before this method will return ``True`` again. """ - telemetry_py.send_telemetry("MICROBIT_API_BUTTON") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) res = self.__prev_pressed self.__prev_pressed = False return res @@ -34,7 +35,7 @@ def get_presses(self): Returns the running total of button presses, and resets this total to zero before returning. """ - telemetry_py.send_telemetry("MICROBIT_API_BUTTON") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_BUTTON) res = self.__presses self.__presses = 0 return res diff --git a/src/microbit/__model/display.py b/src/microbit/__model/display.py index 875c80169..791e1ea8b 100644 --- a/src/microbit/__model/display.py +++ b/src/microbit/__model/display.py @@ -4,6 +4,7 @@ from common import utils from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent from . import constants as CONSTANTS from .image import Image @@ -45,7 +46,7 @@ def scroll(self, value, delay=150, wait=True, loop=False, monospace=False): thread.start() return - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_SCROLL") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_SCROLL) # Set current_pid to the thread's identifier self.__lock.acquire() @@ -126,7 +127,7 @@ def show(self, value, delay=400, wait=True, loop=False, clear=False): thread.start() return - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_SHOW") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_SHOW) # Set current_pid to the thread's identifier self.__lock.acquire() @@ -188,7 +189,7 @@ def get_pixel(self, x, y): Return the brightness of the LED at column ``x`` and row ``y`` as an integer between 0 (off) and 9 (bright). """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) self.__lock.acquire() pixel = self.__image.get_pixel(x, y) self.__lock.release() @@ -199,7 +200,7 @@ def set_pixel(self, x, y, value): Set the brightness of the LED at column ``x`` and row ``y`` to ``value``, which has to be an integer between 0 and 9. """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) self.__lock.acquire() self.__image.set_pixel(x, y, value) self.__lock.release() @@ -209,7 +210,7 @@ def clear(self): """ Set the brightness of all LEDs to 0 (off). """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) self.__lock.acquire() self.__image = Image() self.__lock.release() @@ -219,21 +220,21 @@ def on(self): """ Use on() to turn on the display. """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) self.__on = True def off(self): """ Use off() to turn off the display. """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) self.__on = False def is_on(self): """ Returns ``True`` if the display is on, otherwise returns ``False``. """ - telemetry_py.send_telemetry("MICROBIT_API_DISPLAY_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_DISPLAY_OTHER) return self.__on def read_light_level(self): @@ -242,7 +243,7 @@ def read_light_level(self): falling on the display. Returns an integer between 0 and 255 representing the light level, with larger meaning more light. """ - telemetry_py.send_telemetry("MICROBIT_API_LIGHT_LEVEL") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_LIGHT_LEVEL) return self.__light_level def __set_light_level(self, level): diff --git a/src/microbit/__model/image.py b/src/microbit/__model/image.py index affa8a987..391e17e1e 100644 --- a/src/microbit/__model/image.py +++ b/src/microbit/__model/image.py @@ -1,6 +1,7 @@ from . import constants as CONSTANTS from .producer_property import ProducerProperty from common.telemetry import telemetry_py +from common.telemetry_events import TelemetryEvent class Image: @@ -115,7 +116,7 @@ class Image: def __init__(self, *args, **kwargs): # Depending on the number of arguments # in constructor, it treat args differently. - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_CREATION") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_CREATION) if len(args) == 0: # default constructor self.__LED = self.__string_to_square_array(CONSTANTS.BLANK_5X5) @@ -147,7 +148,7 @@ def width(self): """ Return the number of columns in the image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) if len(self.__LED) > 0: return len(self.__LED[0]) else: @@ -157,7 +158,7 @@ def height(self): """ Return the numbers of rows in the image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return len(self.__LED) def set_pixel(self, x, y, value): @@ -168,7 +169,7 @@ def set_pixel(self, x, y, value): This method will raise an exception when called on any of the built-in read-only images, like ``Image.HEART``. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) if self.read_only: raise TypeError(CONSTANTS.COPY_ERR_MESSAGE) elif not self.__valid_pos(x, y): @@ -183,7 +184,7 @@ def get_pixel(self, x, y): Return the brightness of pixel at column ``x`` and row ``y`` as an integer between 0 and 9. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) if self.__valid_pos(x, y): return self.__LED[y][x] else: @@ -193,14 +194,14 @@ def shift_up(self, n): """ Return a new image created by shifting the picture up by ``n`` rows. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return self.__shift_vertical(-n) def shift_down(self, n): """ Return a new image created by shifting the picture down by ``n`` rows. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return self.__shift_vertical(n) def shift_right(self, n): @@ -208,7 +209,7 @@ def shift_right(self, n): Return a new image created by shifting the picture right by ``n`` columns. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return self.__shift_horizontal(n) def shift_left(self, n): @@ -216,7 +217,7 @@ def shift_left(self, n): Return a new image created by shifting the picture left by ``n`` columns. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return self.__shift_horizontal(-n) def crop(self, x, y, w, h): @@ -224,7 +225,7 @@ def crop(self, x, y, w, h): Return a new image by cropping the picture to a width of ``w`` and a height of ``h``, starting with the pixel at column ``x`` and row ``y``. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) res = Image(w, h) res.blit(self, x, y, w, h) return res @@ -233,7 +234,7 @@ def copy(self): """ Return an exact copy of the image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) return Image(self.__create_string()) # This inverts the brightness of each LED. @@ -244,7 +245,7 @@ def invert(self): Return a new image by inverting the brightness of the pixels in the source image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) for y in range(self.height()): for x in range(self.width()): self.set_pixel(x, y, CONSTANTS.BRIGHTNESS_MAX - self.get_pixel(x, y)) @@ -258,7 +259,7 @@ def fill(self, value): This method will raise an exception when called on any of the built-in read-only images, like ``Image.HEART``. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) for y in range(self.height()): for x in range(self.width()): self.set_pixel(x, y, value) @@ -270,7 +271,7 @@ def blit(self, src, x, y, w, h, xdest=0, ydest=0): this image at ``xdest``, ``ydest``. Areas in the source rectangle, but outside the source image are treated as having a value of 0. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) if not src.__valid_pos(x, y): raise ValueError(CONSTANTS.INDEX_ERR) @@ -289,7 +290,7 @@ def __add__(self, other): """ Create a new image by adding the brightness values from the two images for each pixel. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) if not isinstance(other, Image): raise TypeError( CONSTANTS.UNSUPPORTED_ADD_TYPE + f"'{type(self)}', '{type(other)}'" @@ -312,7 +313,7 @@ def __mul__(self, other): """ Create a new image by multiplying the brightness of each pixel by n. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) try: float_val = float(other) except TypeError: @@ -331,7 +332,7 @@ def __repr__(self): """ Get a compact string representation of the image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) ret_str = "Image('" for index_y in range(self.height()): ret_str += self.__row_to_str(index_y) @@ -344,7 +345,7 @@ def __str__(self): """ Get a readable string representation of the image. """ - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_OTHER") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_OTHER) ret_str = "Image('\n" for index_y in range(self.height()): ret_str += "\t" + self.__row_to_str(index_y) + "\n" @@ -503,7 +504,7 @@ def __same_image(i1, i2): # This is for generating functions like Image.HEART # that return a new read-only Image def create_const_func(func_name): - telemetry_py.send_telemetry("MICROBIT_API_IMAGE_STATIC") + telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_IMAGE_STATIC) def func(*args): const_instance = Image(CONSTANTS.IMAGE_PATTERNS[func_name]) From 8cf89ba2f7c8bea1b0162fe938f55c46974880c6 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Thu, 20 Feb 2020 16:01:36 -0800 Subject: [PATCH 09/10] Added enum --- src/common/telemetry_events.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/common/telemetry_events.py diff --git a/src/common/telemetry_events.py b/src/common/telemetry_events.py new file mode 100644 index 000000000..d150076d0 --- /dev/null +++ b/src/common/telemetry_events.py @@ -0,0 +1,33 @@ +import enum + + +class TelemetryEvent(enum.Enum): + CPX_API_ACCELERATION = "CPX.API.ACCELERATION" + CPX_API_BUTTON_A = "CPX.API.BUTTON.A" + CPX_API_BUTTON_B = "CPX.API.BUTTON.B" + CPX_API_SWITCH = "CPX.API.SWITCH" + CPX_API_TEMPERATURE = "CPX.API.TEMPERATURE" + CPX_API_BRIGHTNESS = "CPX.API.BRIGHTNESS" + CPX_API_LIGHT = "CPX.API.LIGHT" + CPX_API_TOUCH = "CPX.API.TOUCH" + CPX_API_SHAKE = "CPX.API.SHAKE" + CPX_API_TAPPED = "CPX.API.TAPPED" + CPX_API_PLAY_FILE = "CPX.API.PLAY.FILE" + CPX_API_PLAY_TONE = "CPX.API.PLAY.TONE" + CPX_API_START_TONE = "CPX.API.START.TONE" + CPX_API_STOP_TONE = "CPX.API.STOP.TONE" + CPX_API_DETECT_TAPS = "CPX.API.DETECT.TAPS" + CPX_API_ADJUST_THRESHOLD = "CPX.API.ADJUST.THRESHOLD" + CPX_API_RED_LED = "CPX.API.RED.LED" + CPX_API_PIXELS = "CPX.API.PIXELS" + MICROBIT_API_TEMPERATURE = "MICROBIT.API.TEMPERATURE" + MICROBIT_API_ACCELEROMETER = "MICROBIT.API.ACCELEROMETER" + MICROBIT_API_GESTURE = "MICROBIT.API.GESTURE" + MICROBIT_API_DISPLAY_SCROLL = "MICROBIT.API.DISPLAY.SCROLL" + MICROBIT_API_DISPLAY_SHOW = "MICROBIT.API.DISPLAY.SHOW" + MICROBIT_API_DISPLAY_OTHER = "MICROBIT.API.DISPLAY_OTHER" + MICROBIT_API_LIGHT_LEVEL = "MICROBIT.API.LIGHT.LEVEL" + MICROBIT_API_IMAGE_CREATION = "MICROBIT.API.IMAGE.CREATION" + MICROBIT_API_IMAGE_OTHER = "MICROBIT.API.IMAGE.OTHER" + MICROBIT_API_IMAGE_STATIC = "MICROBIT.API.IMAGE.STATIC" + MICROBIT_API_BUTTON = "MICROBIT.API.BUTTON" From 391f0c9f7840f6ce0fe6f41e02df99aa378e2d96 Mon Sep 17 00:00:00 2001 From: Vandy Liu Date: Fri, 21 Feb 2020 13:44:11 -0800 Subject: [PATCH 10/10] removed print statement --- src/common/telemetry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/telemetry.py b/src/common/telemetry.py index f90ab8b99..44a22d058 100644 --- a/src/common/telemetry.py +++ b/src/common/telemetry.py @@ -29,4 +29,3 @@ def telemetry_available(self): telemetry_py = Telemetry() -print(telemetry_py.telemetry_state)