def setup(): require( "directory", "venv_directory", "www_directory", "package_name", "repository", "project_name") # 1. clone project utils.clone_project() # 2. create virtualenv utils.create_virtualenv() # 3. install requirements utils.install_requirements() # 4. configure supervisor env.supervisor = { "command": supervisor.tornado_command() } supervisor.setup() supervisor.reload() # 5. configure nginx nginx.setup() nginx.reload()
def fetch(self): """Fetch data from the url we initialized with, perfom any parsing, and display text or graphics. This function does pretty much everything""" json_out = None image_url = None values = [] gc.collect() if self._debug: print("Free mem: ", gc.mem_free()) # pylint: disable=no-member r = None if self._uselocal: print("*** USING LOCALFILE FOR DATA - NOT INTERNET!!! ***") r = Fake_Requests(LOCALFILE) if not r: self._connect_esp() # great, lets get the data print("Retrieving data...", end='') self.neo_status((100, 100, 0)) # yellow = fetching data gc.collect() r = requests.get(self._url) gc.collect() self.neo_status((0, 0, 100)) # green = got data print("Reply is OK!") if self._debug: print(r.text) if self._image_json_path or self._json_path: try: gc.collect() json_out = r.json() gc.collect() except ValueError: # failed to parse? print("Couldn't parse json: ", r.text) raise except MemoryError: supervisor.reload() if self._regexp_path: import re # extract desired text/values from json if self._json_path: for path in self._json_path: try: values.append(PyPortal._json_traverse(json_out, path)) except KeyError: print(json_out) raise elif self._regexp_path: for regexp in self._regexp_path: values.append(re.search(regexp, r.text).group(1)) else: values = r.text if self._image_json_path: try: image_url = PyPortal._json_traverse(json_out, self._image_json_path) except KeyError as error: print("Error finding image data. '" + error.args[0] + "' not found.") self.set_background(self._default_bg) # we're done with the requests object, lets delete it so we can do more! json_out = None r = None gc.collect() if image_url: try: print("original URL:", image_url) image_url = self.image_converter_url(image_url, self._image_resize[0], self._image_resize[1]) print("convert URL:", image_url) # convert image to bitmap and cache #print("**not actually wgetting**") filename = "/cache.bmp" chunk_size = 12000 # default chunk size is 12K (for QSPI) if self._sdcard: filename = "/sd" + filename chunk_size = 512 # current bug in big SD writes -> stick to 1 block try: self.wget(image_url, filename, chunk_size=chunk_size) except OSError as error: print(error) raise OSError("""\n\nNo writable filesystem found for saving datastream. Insert an SD card or set internal filesystem to be unsafe by setting 'disable_concurrent_write_protection' in the mount options in boot.py""") # pylint: disable=line-too-long self.set_background(filename, self._image_position) except ValueError as error: print("Error displaying cached image. " + error.args[0]) self.set_background(self._default_bg) finally: image_url = None gc.collect() # if we have a callback registered, call it now if self._success_callback: self._success_callback(values) # fill out all the text blocks if self._text: for i in range(len(self._text)): string = None if self._text_transform[i]: func = self._text_transform[i] string = func(values[i]) else: try: string = "{:,d}".format(int(values[i])) except (TypeError, ValueError): string = values[i] # ok its a string if self._debug: print("Drawing text", string) if self._text_wrap[i]: if self._debug: print("Wrapping text") lines = PyPortal.wrap_nicely(string, self._text_wrap[i]) string = '\n'.join(lines) self.set_text(string, index=i) if len(values) == 1: return values[0] return values
def fetch_data( self, url, *, headers=None, json_path=None, regexp_path=None, timeout=10, ): """Fetch data from the specified url and perfom any parsing""" json_out = None values = [] content_type = CONTENT_TEXT response = self.fetch(url, headers=headers, timeout=timeout) headers = {} for title, content in response.headers.items(): headers[title.lower()] = content gc.collect() if self._debug: print("Headers:", headers) if response.status_code == 200: print("Reply is OK!") self.neo_status(STATUS_DATA_RECEIVED) # green = got data if "content-type" in headers: if "image/" in headers["content-type"]: content_type = CONTENT_IMAGE elif "application/json" in headers["content-type"]: content_type = CONTENT_JSON elif "application/javascript" in headers["content-type"]: content_type = CONTENT_JSON else: if self._debug: if "content-length" in headers: print("Content-Length: {}".format( int(headers["content-length"]))) if "date" in headers: print("Date: {}".format(headers["date"])) self.neo_status((100, 0, 0)) # red = http error raise HttpError("Code {}: {}".format( response.status_code, response.reason.decode("utf-8"))) if content_type == CONTENT_JSON and json_path is not None: if isinstance( json_path, (list, tuple)) and (not json_path or not isinstance(json_path[0], (list, tuple))): json_path = (json_path, ) try: gc.collect() json_out = response.json() if self._debug: print(json_out) gc.collect() except ValueError: # failed to parse? print("Couldn't parse json: ", response.text) raise except MemoryError: supervisor.reload() if regexp_path: import re # pylint: disable=import-outside-toplevel # optional JSON post processing, apply any transformations # these MAY change/add element for idx, json_transform in enumerate(self.json_transform): try: json_transform(json_out) except Exception as error: print("Exception from json_transform: ", idx, error) raise # extract desired text/values from json if json_out and json_path: for path in json_path: try: values.append(self.json_traverse(json_out, path)) except KeyError: print(json_out) raise elif content_type == CONTENT_TEXT and regexp_path: for regexp in regexp_path: values.append(re.search(regexp, response.text).group(1)) else: if json_out: # No path given, so return JSON as string for compatibility import json # pylint: disable=import-outside-toplevel values = json.dumps(response.json()) else: values = response.text # we're done with the requests object, lets delete it so we can do more! json_out = None response = None gc.collect() if self._extract_values and len(values) == 1: return values[0] return values
def restart(self, key, val): log.message("Restarting MatrixClock") time_keeper.clock.chip.square_wave_frequency = 0 time_keeper.clock.sqw.deinit() supervisor.reload()
last_sqw = sqw display.update() # Once per second, increment the time if not sqw: time_keeper.local_time_secs += 1 time_keeper.uptime += 1 # If we processed some long running operation above, # update the running time (local_time_secs) from the clock_chip timer.stop if timer.diff > 300_000_000: # update the time from the clock_chip time_keeper.sync_time() except Exception as e: log.message(str(e), add_time=False, traceback=True, exception_value=e) supervisor.reload() time.sleep(0.050) except (KeyboardInterrupt, SystemExit): log.message("Exit to REPL") try: time_keeper.clock.chip.square_wave_frequency = 0 time_keeper.clock.sqw.deinit() except NameError: pass
else: handler.load(sys_config.settings_prog, sys_config.settings_path) handler.cur_cont.current.command(cmd) '''if audio_active: if not audio.speaker.playing: audio.speaker.stop() audio.speaker.play_wav('system/audio_files/button_press.wav')''' #while audio.speaker.playing: #time.sleep(.01) #try:handler.unload('example') #except: print('dsflkjs') '''if audio_active and not audio.speaker.playing: audio.speaker.stop() time.sleep(.05) audio.speaker.play_wav('system/audio_files/looping.wav')''' if audio_active: while audio.speaker.playing: time.sleep(.01) del cmd_list except MemoryError: print('memory error! this is going to be fixed but currently is not') try: handler.cur_prog._save() except: pass reload() #time.sleep(.05)
def fetch(self): json_out = None image_url = None values = [] gc.collect() if self._debug: print("Free mem: ", gc.mem_free()) r = None if self._uselocal: print("*** USING LOCALFILE FOR DATA - NOT INTERNET!!! ***") r = fake_requests(LOCALFILE) if not r: self.neo_status((0, 0, 100)) while not self._esp.is_connected: if self._debug: print("Connecting to AP") # settings dictionary must contain 'ssid' and 'password' at a minimum self.neo_status((100, 0, 0)) # red = not connected self._esp.connect(settings) # great, lets get the data print("Retrieving data...", end='') self.neo_status((100, 100, 0)) # yellow = fetching data gc.collect() r = requests.get(self._url) gc.collect() self.neo_status((0, 0, 100)) # green = got data print("Reply is OK!") if self._debug: print(r.text) if self._image_json_path or self._json_path: try: gc.collect() json_out = r.json() gc.collect() except ValueError: # failed to parse? print("Couldn't parse json: ", r.text) raise except MemoryError: supervisor.reload() if self._xml_path: try: import xmltok print("*" * 40) tokens = [] for i in xmltok.tokenize(r.text): print(i) print(tokens) print("*" * 40) except ValueError: # failed to parse? print("Couldn't parse XML: ", r.text) raise # extract desired text/values from json if self._json_path: for path in self._json_path: values.append(self._json_pather(json_out, path)) else: values = r.text if self._image_json_path: image_url = self._json_pather(json_out, self._image_json_path) # we're done with the requests object, lets delete it so we can do more! json_out = None r = None gc.collect() if image_url: print("original URL:", image_url) image_url = IMAGE_CONVERTER_SERVICE + image_url print("convert URL:", image_url) # convert image to bitmap and cache #print("**not actually wgetting**") self.wget(image_url, "/cache.bmp") self.set_background("/cache.bmp") image_url = None gc.collect() # if we have a callback registered, call it now if self._success_callback: self._success_callback(values) # fill out all the text blocks if self._text: for i in range(len(self._text)): string = None try: string = "{:,d}".format(int(values[i])) except ValueError: string = values[i] # ok its a string if self._debug: print("Drawing text", string) if self._text_wrap[i]: if self._debug: print("Wrapping text") string = '\n'.join( self.wrap_nicely(string, self._text_wrap[i])) self.set_text(string, index=i) if len(values) == 1: return values[0] return values
def depress(self): supervisor.reload()
def game_over_scene(final_score): # Game over scene # SOUND sound = ugame.audio sound.stop() # IMAGE_BANK over_image_bank = stage.Bank.from_bmp16("splash_over_image_bank.bmp") # BACKGROUND # sets the background to image 0 in the image Bank over_background = stage.Grid(over_image_bank, constants.SCREEN_GRID_X, constants.SCREEN_GRID_Y) # TEXT text = [] text1 = stage.Text(width=29, height=12, font=None, palette=constants.PALETTE, buffer=None) text1.move(22, 20) text1.text("Final Score: {:0>2d}".format(final_score)) text.append(text1) text2 = stage.Text(width=29, height=14, font=None, palette=constants.PALETTE, buffer=None) text2.move(43, 60) text2.text("GAME OVER") text.append(text2) text3 = stage.Text(width=29, height=14, font=None, palette=constants.PALETTE, buffer=None) text3.move(35, 110) text3.text("PRESS START") text.append(text3) # STAGE AND RENDER # Creates a stage for the background # Sets frame rate to 60fps game = stage.Stage(ugame.display, constants.FPS) # Sets sprite layers and show up in order game.layers = text + [over_background] # Renders all sprites, only once game.render_block() while True: # get user input keys = ugame.buttons.get_pressed() # Start button pressed if keys & ugame.K_START != 0: supervisor.reload() # update game logic game.tick()
def fetch(self, refresh_url=None, timeout=10): """Fetch data from the url we initialized with, perfom any parsing, and display text or graphics. This function does pretty much everything Optionally update the URL """ if refresh_url: self.url = refresh_url response = self.network.fetch(self.url, headers=self._headers, timeout=timeout) json_out = None content_type = self.network.check_response(response) json_path = self._json_path if content_type == CONTENT_JSON: if json_path is not None: # Drill down to the json path and set json_out as that node if isinstance( json_path, (list, tuple)) and (not json_path or not isinstance(json_path[0], (list, tuple))): json_path = (json_path, ) try: gc.collect() json_out = response.json() if self._debug: print(json_out) gc.collect() except ValueError: # failed to parse? print("Couldn't parse json: ", response.text) raise except MemoryError: supervisor.reload() try: filename, position = self.network.process_image( json_out, self.peripherals.sd_check()) if filename and position is not None: self.graphics.set_background(filename, position) except ValueError as error: print("Error displaying cached image. " + error.args[0]) if self._default_bg is not None: self.graphics.set_background(self._default_bg) except KeyError as error: print("Error finding image data. '" + error.args[0] + "' not found.") self.set_background(self._default_bg) if content_type == CONTENT_JSON: values = self.network.process_json(json_out, json_path) elif content_type == CONTENT_TEXT: values = self.network.process_text(response.text, self._regexp_path) # if we have a callback registered, call it now if self._success_callback: self._success_callback(values) self._fill_text_labels(values) # Clean up json_out = None response = None gc.collect() if len(values) == 1: values = values[0] return values
def process(self): # Call the debouncing library frequently self.joy_z.update() self.dpad.update() dx = self.x_axis.readJoystickAxis() dy = self.y_axis.readJoystickAxis() # Command Center State Machine # if self.state == _UNWIRED: self.dotstar_led[0] = ((time.monotonic_ns() >> 23) % 256, 0, 0) if dx == 0 and dy == 0: self.state = _WAITING self.timer = time.monotonic() elif self.state == _WAITING: self.dotstar_led[0] = ((time.monotonic_ns() >> 23) % 256, 0, 0) if dx != 0 or dy != 0: self.state = _UNWIRED else: if time.monotonic() - self.timer > 0.5: self.state = _JOYSTICK elif self.state == _JOYSTICK: self.dotstar_led[0] = (0, 255, 0) if self.joy_z.zPressed(): self.timer = time.monotonic() self.state = _JWAITING elif self.state == _JWAITING: if not self.joy_z.zPressed(): self.state = _JOYSTICK else: if time.monotonic() - self.timer > 1.0: self.mouse.release(Mouse.LEFT_BUTTON) self.mouse.release(Mouse.RIGHT_BUTTON) self.state = _USERCODE elif self.state == _USERCODE: self.dotstar_led[0] = (0, 0, 0) self.dotstar_led.deinit() self.joystick_gnd.deinit() self.x_axis.deinit() self.y_axis.deinit() self.dpad.deinit() self.joy_z.deinit() try: # Load usercode.py __import__("usercode") except ImportError: print("Missing usercode.py file") # If we get here due to an exception or the user code exiting # then restart as it's probably going to by the most stable # strategy # supervisor.reload() # Command Center Joystick Handling # if self.state == _JOYSTICK or self.state == _JWAITING: # Determine mouse wheel direction # dwheel = 0 if self.dpad.upPressed(): dwheel = -1 elif self.dpad.downPressed(): dwheel = 1 # Initial quick and dirty mouse movement pacing # if time.monotonic() - self.last_mouse > 0.005: self.last_mouse = time.monotonic() self.mouse.move(x=dx, y=dy) # Initial quick and dirty mouse scroll wheel pacing # if time.monotonic() - self.last_mouse_wheel > 0.1: self.last_mouse_wheel = time.monotonic() self.mouse.move(wheel=dwheel) if self.dpad.leftPressedEvent(): self.mouse.press(Mouse.LEFT_BUTTON) elif self.dpad.leftReleasedEvent(): self.mouse.release(Mouse.LEFT_BUTTON) if self.dpad.rightPressedEvent(): self.mouse.press(Mouse.RIGHT_BUTTON) elif self.dpad.rightReleasedEvent(): self.mouse.release(Mouse.RIGHT_BUTTON)
def driver(): # Controlling the pixels on the board. #pixel_pin = board.NEOPIXEL # Controlling the LED strip attached to A1. # DEBUG - one of these is wrong, not sure which... # A #pixel_pin = digitalio.DigitalInOut( board.A0 ) #pixel_pin.direction = digitalio.Direction.OUTPUT # B pixel_pin = board.A0 # # DEBUG - when I figure out which it is, use the other to control # the circular LED lights. circle_pin = board.A1 # Code for digital switches button_1 = digitalio.DigitalInOut(board.A2) button_1.direction = digitalio.Direction.INPUT button_1.pull = digitalio.Pull.UP button_2 = digitalio.DigitalInOut(board.A3) button_2.direction = digitalio.Direction.INPUT button_2.pull = digitalio.Pull.UP button_3 = digitalio.DigitalInOut(board.A4) button_3.direction = digitalio.Direction.INPUT button_3.pull = digitalio.Pull.UP button_4 = digitalio.DigitalInOut(board.A5) button_4.direction = digitalio.Direction.INPUT button_4.pull = digitalio.Pull.UP # Set up our Circle Pixels # # DEBUG - for the circle pixels we just want them always on doing # rainbow stuff. num_circle_pixels = 16 circle_pixels = neopixel.NeoPixel(circle_pin, num_circle_pixels, brightness=1.0, auto_write=False) for i in range(len(circle_pixels)): circle_pixels[i] = (0, 0, 0) circle_path_length = 30 circle_speed = 11 circle_trail = 30 circle_lead = 0 circle_ps = get_light_ps(circle_path_length, num_circle_pixels) # Set up our LED strip num_pixels = 28 pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=1.0, auto_write=False) for i in range(len(pixels)): pixels[i] = (0, 0, 0) zero_pixels = [(0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)] # Overall model properties for our light. path_length = 30 speed = 24 trail = 7 lead = 1.5 # Light positions for segment 1, and for segment 2, 3, 4. # # Segments 2, 3, 4 are arranged this way so as to make the # animation of the light flow smoothly from segment 1 into the # other segments. light_ps_1 = [0, 3, 6, 9, 12, 15, 18] light_ps_234 = [21, 24, 27, 0, 3, 6, 9] # The current time used by the animation model, and the interval # in time between updates in the model. t = 0 interval = 3 / 100 # Establish the initial colors of each of the four ranges to a # different spot in the RGB rainbow cycle. color_a = 0 * (256 / 4) color_b = 1 * (256 / 4) color_c = 2 * (256 / 4) color_d = 3 * (256 / 4) # Loop forever. reset_count = 0 while True: # The system locks up after a while - try to hard reboot it around 10 hours in. reset_count += 1 if reset_count > 1000000: reset_count = 0 supervisor.reload() # Determine what we need to animate, the rules are: # button_1 -> LED segment 1 is # button_1 && button_2 -> Segment 2 # button_1 && button_2 && button_3 -> Segment 3 # button_1 && button_2 && button_4 -> Segment 4 # button_1 && button_2 && button_3 && button_4 -> Circle # Set up the colors for the light source on each of the four # segments. peak_a = rainbow(color_a) peak_b = rainbow(color_b) peak_c = rainbow(color_c) peak_d = rainbow(color_d) # Update colors for next iteration. color_a += 1 color_a = color_a % 256 color_b += 1 color_b = color_b % 256 color_c += 1 color_c = color_c % 256 color_d += 1 color_d = color_d % 256 #print( "Buttons: ", [ button_1.value, button_2.value, button_3.value, button_4.value ] ) button_override = True # Light up the appropriate pixels. # # Switches are active when they read as false. tmp = zero_pixels if button_override or not button_1.value: tmp = animate_path(path_length, speed, trail, lead, light_ps_1, t, peak=peak_a) for i in range(len(tmp)): pixels[i] = tmp[i] tmp = zero_pixels if button_override or (not button_1.value and not button_2.value): tmp = animate_path(path_length, speed, trail, lead, light_ps_234, t, peak=peak_b) for i in range(len(tmp)): pixels[7 + i] = tmp[i] tmp = zero_pixels if button_override or (not button_1.value and not button_2.value and not button_3.value): tmp = animate_path(path_length, speed, trail, lead, light_ps_234, t, peak=peak_c) for i in range(len(tmp)): pixels[14 + i] = tmp[i] tmp = zero_pixels if button_override or (not button_1.value and not button_2.value and not button_4.value): tmp = animate_path(path_length, speed, trail, lead, light_ps_234, t, peak=peak_d) for i in range(len(tmp)): pixels[21 + i] = tmp[i] if button_override or (not button_1.value and not button_2.value and not button_3.value and not button_4.value): #circle_tmp = animate_path( circle_path_length, circle_speed, circle_trail, circle_lead, circle_ps, t, peak=peak_a ) for i in range(len(circle_pixels)): circle_pixels[i] = rainbow(255 & int( (i * 256 / num_circle_pixels) + color_a * 10)) else: for i in range(len(circle_pixels)): circle_pixels[i] = (0, 0, 0) #print( pixels ) pixels.show() circle_pixels.show() time.sleep(interval) t += interval #print( t ) if t > path_length / speed: t -= path_length / speed
def datadog_get_metrics(current_time, query, metric_name, trailing_string, prefix_string, rounding_places, high_threshold): ''' Fetches last data point for a given datadog metric query ''' FROM_TIME = int(current_time) - INTERVAL JSON_URL = "https://api.datadoghq.com/api/v1/query?api_key=" + DD_CLIENT_API_KEY + "&application_key=" + DD_CLIENT_APP_KEY + "&from=" + str( FROM_TIME) + "&to=" + str(current_time) + "&query=" + query print('Using time range in DD request:', FROM_TIME, "to", current_time) print('Running query:', query) try: r = requests.get(JSON_URL) print("-" * 60) json_resp = r.json() # print(json_resp) # Raw JSON last_data_point = json_resp["series"][0]["pointlist"][ -1] # Get latest value in time series print('Last data point:', last_data_point[1]) # Format results # Hack for displaying percentages better if "percent_usage" in query: print('Formating as percentage') formatted_last_data_point = "{:.0%}".format( float(last_data_point[1])) print(last_data_point[1]) else: if rounding_places < 1: # Adjust displayed value based on places to round to formatted_last_data_point = int(last_data_point[1]) else: formatted_last_data_point = round(last_data_point[1], rounding_places) # Update display with result title_text.text = metric_name # Set colour to red if value over threshold if last_data_point[1] > high_threshold: print('Value over threshold!') data_display_label.color = red else: data_display_label.color = white data_display_label.text = prefix_string + str( formatted_last_data_point) + trailing_string # Process Response headers # Check we're not smashing the API rate limit if int(r.headers["x-ratelimit-remaining"]) < 500: print('Warning! Approaching rate limit. Backing off.') print('Rate limit remaining:', r.headers["x-ratelimit-remaining"], 'out of', r.headers["x-ratelimit-limit"], 'Period is', r.headers["x-ratelimit-period"]) time.sleep(RATE_LIMIT_BACKOFF) print("-" * 60) r.close() except Exception as e: print(e) if "socket failures" in str( e ): # TODO: Find out why these intermittent socket failures happen and handle them better. Not sure if its due to flakey wifi, a bug in the Adafruit libs or something else. print('Restarting due to socket failures..') supervisor.reload() else: return # Just return if we dont get a good value from DD time.sleep(DELAY_BETWEEN) return