demo.py
  1  # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  import os
  6  import subprocess
  7  import random
  8  import json
  9  import re
 10  from datetime import datetime
 11  import board
 12  import displayio
 13  import adafruit_dotstar
 14  from adafruit_st7789 import ST7789
 15  
 16  IMAGE_FOLDER = "images"
 17  
 18  listen_command = "/usr/bin/voice2json transcribe-stream | /usr/bin/voice2json recognize-intent"
 19  speak_command = "/usr/bin/voice2json speak-sentence '{}'"
 20  pattern = re.compile(r'(?<!^)(?=[A-Z])')
 21  
 22  dots = adafruit_dotstar.DotStar(board.D6, board.D5, 3, brightness=0.2, pixel_order=adafruit_dotstar.RBG)
 23  dots.fill(0)
 24  
 25  colors = {
 26      'red': 0xff0000,
 27      'green': 0x00ff00,
 28      'blue': 0x0000ff,
 29      'yellow': 0xffff00,
 30      'orange': 0xff8800,
 31      'purple': 0x8800ff,
 32      'white': 0xffffff,
 33      'off': 0
 34  }
 35  
 36  lights = ['left', 'middle', 'right']
 37  
 38  def get_time():
 39      now = datetime.now()
 40      speak("The time is {}".format(now.strftime("%-I:%M %p")))
 41  
 42  def display_picture(category):
 43      path = os.getcwd() + "/" + IMAGE_FOLDER + "/" + category
 44      print("Showing a random image from {}".format(category))
 45      load_image(path + "/" + get_random_file(path))
 46  
 47  def get_random_file(folder):
 48      filenames = []
 49      for item in os.listdir(folder):
 50          if os.path.isfile(os.path.join(folder, item)) and item.endswith((".jpg", ".bmp", ".gif")):
 51              filenames.append(item)
 52      if len(filenames):
 53          return filenames[random.randrange(len(filenames))]
 54      return None
 55  
 56  def load_image(path):
 57      "Load an image from the path"
 58      if len(splash):
 59          splash.pop()
 60      # CircuitPython 6 & 7 compatible
 61      bitmap = displayio.OnDiskBitmap(open(path, "rb"))
 62      sprite = displayio.TileGrid(bitmap, pixel_shader=getattr(bitmap, 'pixel_shader', displayio.ColorConverter()))
 63  
 64      # # CircuitPython 7+ compatible
 65      # bitmap = displayio.OnDiskBitmap(path)
 66      # sprite = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
 67  
 68      splash.append(sprite)
 69  
 70  def change_light_color(lightname, color):
 71      dotstar_number = lights.index(lightname)
 72      dots[dotstar_number] = colors[color]
 73      print("Setting Dotstar {} to 0x{:06X}".format(dotstar_number, colors[color]))
 74  
 75  def speak(sentence):
 76      for output_line in shell_command(speak_command.format(sentence)):
 77          print(output_line, end='')
 78  
 79  def shell_command(cmd):
 80      popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
 81      for stdout_line in iter(popen.stdout.readline, ""):
 82          yield stdout_line 
 83      popen.stdout.close()
 84      return_code = popen.wait()
 85      if return_code:
 86          raise subprocess.CalledProcessError(return_code, cmd)
 87  
 88  def process_output(line):
 89      data = json.loads(line)
 90      if not data['timeout'] and data['intent']['name']:
 91          func_name = pattern.sub('_', data['intent']['name']).lower()
 92          if func_name in globals():
 93              globals()[func_name](**data['slots'])
 94  
 95  displayio.release_displays()
 96  spi = board.SPI()
 97  tft_cs = board.CE0
 98  tft_dc = board.D25
 99  tft_lite = board.D26
100  
101  display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs)
102  
103  display = ST7789(
104      display_bus,
105      width=240,
106      height=240,
107      rowstart=80,
108      rotation=180,
109      backlight_pin=tft_lite,
110  )
111  
112  splash = displayio.Group()
113  display.show(splash)
114  
115  for output_line in shell_command(listen_command):
116      process_output(output_line)