code.py
  1  # SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  """
  6  PyPortal Smart Scale
  7  an internet of things smart-scale for Adafruit IO
  8  
  9  Brent Rubell for Adafruit Industries, 2019
 10  """
 11  import time
 12  import board
 13  import adafruit_dymoscale
 14  import busio
 15  import digitalio
 16  
 17  import displayio
 18  from adafruit_display_text.label import Label
 19  from adafruit_bitmap_font import bitmap_font
 20  
 21  from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager
 22  import neopixel
 23  from adafruit_io.adafruit_io import IO_HTTP
 24  
 25  # Get wifi details and more from a secrets.py file
 26  try:
 27      from secrets import secrets
 28  except ImportError:
 29      print("WiFi secrets are kept in secrets.py, please add them there!")
 30      raise
 31  
 32  # the current working directory (where this file is)
 33  cwd = ("/"+__file__).rsplit('/', 1)[0]
 34  large_font = cwd+"/fonts/Helvetica-Bold-36.bdf"
 35  small_font = cwd+"/fonts/Helvetica-Bold-16.bdf"
 36  
 37  root_group = displayio.Group()
 38  print('loading fonts...')
 39  weight_font = bitmap_font.load_font(large_font)
 40  weight_font.load_glyphs(b'0123456789.goz-SCALEROIO ')
 41  
 42  text_font = bitmap_font.load_font(small_font)
 43  text_font.load_glyphs(b'sendig!t.')
 44  
 45  print('making labels...')
 46  weight_label = Label(weight_font)
 47  weight_label.x = 75
 48  weight_label.y = 120
 49  root_group.append(weight_label)
 50  weight_label.text = "---"
 51  
 52  title_label = Label(weight_font)
 53  title_label.x = 65
 54  title_label.y = 20
 55  root_group.append(title_label)
 56  title_label.text = "IO SCALE"
 57  
 58  text_label = Label(text_font)
 59  text_label.x = 100
 60  text_label.y = 200
 61  text_label.color = 0xFFFFFF
 62  root_group.append(text_label)
 63  
 64  board.DISPLAY.show(root_group)
 65  
 66  # PyPortal ESP32 Setup
 67  esp32_cs = digitalio.DigitalInOut(board.ESP_CS)
 68  esp32_ready = digitalio.DigitalInOut(board.ESP_BUSY)
 69  esp32_reset = digitalio.DigitalInOut(board.ESP_RESET)
 70  spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
 71  esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
 72  status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
 73  wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
 74  
 75  # Set your Adafruit IO Username and Key in secrets.py
 76  # (visit io.adafruit.com if you need to create an account,
 77  # or if you need your Adafruit IO key.)
 78  aio_username = secrets['aio_username']
 79  aio_key = secrets['aio_key']
 80  
 81  # Create an instance of the IO_HTTP client
 82  io = IO_HTTP(aio_username, aio_key, wifi)
 83  
 84  # Get the weight feed from IO
 85  weight_feed = io.get_feed('weight')
 86  
 87  # initialize the dymo scale
 88  units_pin = digitalio.DigitalInOut(board.D3)
 89  units_pin.switch_to_output()
 90  dymo = adafruit_dymoscale.DYMOScale(board.D4, units_pin)
 91  
 92  # take a reading of the current time, used for toggling the device out of sleep
 93  time_stamp = time.monotonic()
 94  
 95  while True:
 96      try:
 97          reading = dymo.weight
 98          text = "%0.1f g"%reading.weight
 99          print(text)
100          weight_label.text = text
101          weight_label.color = 0xFFFFFF
102          try:
103              print('Sending to Adafruit IO...')
104              text_label.text = 'sending...'
105              # send data to Adafruit IO (rounded to one decimal place)
106              io.send_data(weight_feed['key'], round(reading.weight, 1))
107          except (ValueError, RuntimeError, ConnectionError, OSError) as e:
108              print("failed to send data..retrying...")
109              wifi.reset()
110              continue
111          print('Data sent!')
112          text_label.text = 'sent!'
113          # to avoid sleep mode, toggle the units pin every 2mins.
114          if (time.monotonic() - time_stamp) > 120:
115              print('toggling units button')
116              dymo.toggle_unit_button()
117              # reset the time
118              time_stamp = time.monotonic()
119      except RuntimeError as e:
120          weight_label.text = "SCALE\nERROR"
121          weight_label.color = 0xFF0000
122          print("Error: ", e)