/ examples / esp_atcontrol_countviewer.py
esp_atcontrol_countviewer.py
  1  """
  2  This example will access an API, grab a number like hackaday skulls, github
  3  stars, price of bitcoin, twitter followers... if you can find something that
  4  spits out JSON data, we can display it!
  5  """
  6  import gc
  7  import time
  8  import board
  9  import busio
 10  from digitalio import DigitalInOut
 11  from digitalio import Direction
 12  import neopixel
 13  import adafruit_espatcontrol.adafruit_espatcontrol_socket as socket
 14  from adafruit_espatcontrol import adafruit_espatcontrol
 15  from adafruit_ht16k33 import segments
 16  import adafruit_requests as requests
 17  
 18  # Get wifi details and more from a secrets.py file
 19  try:
 20      from secrets import secrets
 21  except ImportError:
 22      print("WiFi secrets are kept in secrets.py, please add them there!")
 23      raise
 24  
 25  #              CONFIGURATION
 26  PLAY_SOUND_ON_CHANGE = False
 27  NEOPIXELS_ON_CHANGE = False
 28  TIME_BETWEEN_QUERY = 60  # in seconds
 29  
 30  # Some data sources and JSON locations to try out
 31  
 32  # Bitcoin value in USD
 33  DATA_SOURCE = "http://api.coindesk.com/v1/bpi/currentprice.json"
 34  DATA_LOCATION = ["bpi", "USD", "rate_float"]
 35  
 36  # Github stars! You can query 1ce a minute without an API key token
 37  # DATA_SOURCE = "https://api.github.com/repos/adafruit/circuitpython"
 38  # if 'github_token' in secrets:
 39  #    DATA_SOURCE += "?access_token="+secrets['github_token']
 40  # DATA_LOCATION = ["stargazers_count"]
 41  
 42  # Youtube stats
 43  # CHANNEL_ID = "UCpOlOeQjj7EsVnDh3zuCgsA" # this isn't a secret but you have to look it up
 44  # DATA_SOURCE = "https://www.googleapis.com/youtube/v3/channels/?part=statistics&id=" \
 45  #              + CHANNEL_ID +"&key="+secrets['youtube_token']
 46  # try also 'viewCount' or 'videoCount
 47  # DATA_LOCATION = ["items", 0, "statistics", "subscriberCount"]
 48  
 49  
 50  # Subreddit subscribers
 51  # DATA_SOURCE = "https://www.reddit.com/r/circuitpython/about.json"
 52  # DATA_LOCATION = ["data", "subscribers"]
 53  
 54  # Hackaday Skulls (likes), requires an API key
 55  # DATA_SOURCE = "https://api.hackaday.io/v1/projects/1340?api_key="+secrets['hackaday_token']
 56  # DATA_LOCATION = ["skulls"]
 57  
 58  # Twitter followers
 59  # DATA_SOURCE = "https://cdn.syndication.twimg.com/widgets/followbutton/info.json?" + \
 60  # "screen_names=adafruit"
 61  # DATA_LOCATION = [0, "followers_count"]
 62  
 63  
 64  # With a Particle Argon
 65  RX = board.ESP_TX
 66  TX = board.ESP_RX
 67  resetpin = DigitalInOut(board.ESP_WIFI_EN)
 68  rtspin = DigitalInOut(board.ESP_CTS)
 69  uart = busio.UART(TX, RX, timeout=0.1)
 70  esp_boot = DigitalInOut(board.ESP_BOOT_MODE)
 71  esp_boot.direction = Direction.OUTPUT
 72  esp_boot.value = True
 73  
 74  
 75  # Create the connection to the co-processor and reset
 76  esp = adafruit_espatcontrol.ESP_ATcontrol(
 77      uart, 115200, run_baudrate=921600, reset_pin=resetpin, rts_pin=rtspin, debug=False
 78  )
 79  esp.hard_reset()
 80  
 81  requests.set_socket(socket, esp)
 82  
 83  # Create the I2C interface.
 84  i2c = busio.I2C(board.SCL, board.SDA)
 85  # Attach a 7 segment display and display -'s so we know its not live yet
 86  display = segments.Seg7x4(i2c)
 87  display.print("----")
 88  
 89  # neopixels
 90  if NEOPIXELS_ON_CHANGE:
 91      pixels = neopixel.NeoPixel(board.A1, 16, brightness=0.4, pixel_order=(1, 0, 2, 3))
 92      pixels.fill(0)
 93  
 94  # music!
 95  if PLAY_SOUND_ON_CHANGE:
 96      import audioio
 97  
 98      wave_file = open("coin.wav", "rb")
 99      wave = audioio.WaveFile(wave_file)
100  
101  # we'll save the value in question
102  last_value = value = None
103  the_time = None
104  times = 0
105  
106  
107  def chime_light():
108      """Light up LEDs and play a tune"""
109      if NEOPIXELS_ON_CHANGE:
110          for i in range(0, 100, 10):
111              pixels.fill((i, i, i))
112      if PLAY_SOUND_ON_CHANGE:
113          with audioio.AudioOut(board.A0) as audio:
114              audio.play(wave)
115              while audio.playing:
116                  pass
117      if NEOPIXELS_ON_CHANGE:
118          for i in range(100, 0, -10):
119              pixels.fill((i, i, i))
120          pixels.fill(0)
121  
122  
123  while True:
124      try:
125          while not esp.is_connected:
126              # secrets dictionary must contain 'ssid' and 'password' at a minimum
127              esp.connect(secrets)
128  
129          the_time = esp.sntp_time
130  
131          # great, lets get the data
132          print("Retrieving data source...", end="")
133          r = requests.get(DATA_SOURCE)
134          print("Reply is OK!")
135      except (ValueError, RuntimeError, adafruit_espatcontrol.OKError) as e:
136          print("Failed to get data, retrying\n", e)
137          continue
138      # print('-'*40,)
139      # print("Headers: ", r.headers)
140      # print("Text:", r.text)
141      # print('-'*40)
142  
143      value = r.json()
144      for x in DATA_LOCATION:
145          value = value[x]
146      if not value:
147          continue
148      print(times, the_time, "value:", value)
149      display.print(int(value))
150  
151      if last_value != value:
152          chime_light()  # animate the neopixels
153          last_value = value
154      times += 1
155  
156      # normally we wouldn't have to do this, but we get bad fragments
157      r = value = None
158      gc.collect()
159      print(gc.mem_free())  # pylint: disable=no-member
160      time.sleep(TIME_BETWEEN_QUERY)