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

Commit

Permalink
Add telemetry for python (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
vandyliu committed Feb 22, 2020
1 parent 97cb358 commit 72b9f1e
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 74 deletions.
11 changes: 0 additions & 11 deletions src/adafruit_circuitplayground/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +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 = {
"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",
}
ERROR_SENDING_EVENT = "Error trying to send event to the process : "

TIME_DELAY = 0.03
Expand Down
33 changes: 21 additions & 12 deletions src/adafruit_circuitplayground/express.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import sys
import os
import playsound

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
from applicationinsights import TelemetryClient
from .telemetry import telemetry_py
from . import debugger_communication_client

Acceleration = namedtuple("acceleration", ["x", "y", "z"])
Expand Down Expand Up @@ -52,25 +52,29 @@ def __init__(self):

@property
def acceleration(self):
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(TelemetryEvent.CPX_API_BUTTON_A)
return self.__state["button_a"]

@property
def button_b(self):
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_BUTTON_B)
return self.__state["button_b"]

@property
def detect_taps(self):
telemetry_py.send_telemetry("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(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
Expand All @@ -80,30 +84,33 @@ def detect_taps(self, value):
def tapped(self):
""" Not Implemented!
"""
telemetry_py.send_telemetry("TAPPED")
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TAPPED)
raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR)

@property
def red_led(self):
telemetry_py.send_telemetry("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("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(TelemetryEvent.CPX_API_SWITCH)
return self.__state["switch"]

@property
def temperature(self):
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TEMPERATURE)
return self.__state["temperature"]

@property
def light(self):
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_LIGHT)
return self.__state["light"]

def __show(self):
Expand All @@ -113,6 +120,7 @@ def __show(self):
utils.send_to_simulator(self.__state, CONSTANTS.CPX)

def __touch(self, i):
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_TOUCH)
return self.__state["touch"][i - 1]

@property
Expand Down Expand Up @@ -147,14 +155,15 @@ 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(TelemetryEvent.CPX_API_ADJUST_THRESHOLD)
raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR)

def shake(self, shake_threshold=30):
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_SHAKE)
return self.__state["shake"]

def play_file(self, file_name):
telemetry_py.send_telemetry("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)
Expand All @@ -179,19 +188,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(TelemetryEvent.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(TelemetryEvent.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(TelemetryEvent.CPX_API_STOP_TONE)
raise NotImplementedError(CONSTANTS.NOT_IMPLEMENTED_ERROR)

def update_state(self, new_state):
Expand Down
13 changes: 7 additions & 6 deletions src/adafruit_circuitplayground/pixel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

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 common.telemetry_events import TelemetryEvent
from . import constants as CONSTANTS
from .telemetry import telemetry_py
from . import debugger_communication_client


Expand Down Expand Up @@ -38,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("PIXELS")
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS)
return self.__state["pixels"][index]

def __setitem__(self, index, val):
telemetry_py.send_telemetry("PIXELS")
telemetry_py.send_telemetry(TelemetryEvent.CPX_API_PIXELS)
is_slice = False
if type(index) is slice:
is_slice = True
Expand Down Expand Up @@ -115,12 +114,14 @@ def __valid_rgb_value(self, pixValue):

@property
def brightness(self):
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(TelemetryEvent.CPX_API_BRIGHTNESS)
self.__state["brightness"] = brightness
self.__show_if_auto_write()

Expand Down
41 changes: 0 additions & 41 deletions src/adafruit_circuitplayground/telemetry.py

This file was deleted.

31 changes: 31 additions & 0 deletions src/common/telemetry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from applicationinsights import TelemetryClient
from .telemetry_events import TelemetryEvent


class Telemetry:
def __init__(self):
# State of the telemetry
self.__enable_telemetry = True
self.telemetry_client = TelemetryClient("__AIKEY__")
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: TelemetryEvent):
if (
self.__enable_telemetry
and self.telemetry_available()
and not self.telemetry_state[event_name.name]
):
self.telemetry_client.track_event(
f"{self.extension_name}/{event_name.value}"
)
self.telemetry_client.flush()
self.telemetry_state[event_name.name] = True

def telemetry_available(self):
return self.telemetry_client.context.instrumentation_key == "__AIKEY__"


telemetry_py = Telemetry()
33 changes: 33 additions & 0 deletions src/common/telemetry_events.py
Original file line number Diff line number Diff line change
@@ -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"
3 changes: 3 additions & 0 deletions src/microbit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +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
Expand Down Expand Up @@ -29,4 +31,5 @@ def temperature():
"""
Return the temperature of the micro:bit in degrees Celcius.
"""
telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_TEMPERATURE)
return __mb.temperature()
10 changes: 10 additions & 0 deletions src/microbit/__model/accelerometer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import constants as CONSTANTS
from common.telemetry import telemetry_py
from common.telemetry_events import TelemetryEvent


class Accelerometer:
Expand All @@ -17,6 +19,7 @@ def get_x(self):
negative integer, depending on the direction. The measurement is given in
milli-g.
"""
telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER)
return self.__x

def get_y(self):
Expand All @@ -25,6 +28,7 @@ def get_y(self):
negative integer, depending on the direction. The measurement is given in
milli-g.
"""
telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER)
return self.__y

def get_z(self):
Expand All @@ -33,26 +37,30 @@ def get_z(self):
negative integer, depending on the direction. The measurement is given in
milli-g.
"""
telemetry_py.send_telemetry(TelemetryEvent.MICROBIT_API_ACCELEROMETER)
return self.__z

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(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(TelemetryEvent.MICROBIT_API_GESTURE)
self.__add_current_gesture_to_gesture_lists()
return self.__current_gesture

def is_gesture(self, name):
"""
Return True or False to indicate if the named gesture is currently active.
"""
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)
Expand All @@ -63,6 +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(TelemetryEvent.MICROBIT_API_GESTURE)
self.__add_current_gesture_to_gesture_lists()
if name not in CONSTANTS.GESTURES:
raise ValueError(CONSTANTS.INVALID_GESTURE_ERR)
Expand All @@ -75,6 +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(TelemetryEvent.MICROBIT_API_GESTURE)
self.__add_current_gesture_to_gesture_lists()
gestures = tuple(self.__gestures)
self.__gestures.clear()
Expand Down
Loading

0 comments on commit 72b9f1e

Please sign in to comment.