# Time libraries
import rtc
import time
import alarm # for sleep and deep sleep

# Adafruit hts221 and supporting libraries
import board
import busio
import adafruit_hts221 # this library is dependent on adafruit_bus_device and adafruit_register

# Adafruit lps25 library
import adafruit_lps2x

# Adafruit lc709203f library
import adafruit_lc709203f

# Internet libraries
import ssl
import wifi
import ipaddress
import socketpool
import adafruit_requests

# AdaFruit IO libraries
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError

# AdaFruit DotStar library
import adafruit_dotstar as dotstar

# Library for internal LED and helper functions
import feathers2

# Import secrets
from secrets import secrets

# Timeout between sending data to Adafruit IO, in seconds
IO_DELAY = 60

def set_diag_leds(state, color):
  feathers2.led_set(state)
  feathers2.rgb_led_set(color)

def take_nap(nap_duration):
  t = time.localtime()
  print('{}/{}/{} {:02}:{:02}:{:02} - Entering deep sleep.'.format(t.tm_mon, t.tm_mday, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec))
  time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + nap_duration)
  print("Sleeping for: {0}".format(time_alarm.monotonic_time - time.monotonic()))
  alarm.exit_and_deep_sleep_until_alarms(time_alarm)

# --- DIAG LEDS ---
feathers2.enable_LDO2(True)
set_diag_leds(True, "Off")
t = time.localtime()
print('{}/{}/{} {:02}:{:02}:{:02} - Starting script.'.format(t.tm_mon, t.tm_mday, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec))

# Set up HTS221 Temp & Humidity Sensor and capture data for this run
i2c = busio.I2C(board.SCL, board.SDA)
hts = adafruit_hts221.HTS221(i2c)
hts_data = hts
print("HTS221 sensor reading:")
print("\tTemperature: {0:.2f} °C / {1:.2f} °F".format(hts_data.temperature, ((hts_data.temperature * 9/5) + 32)))
print("\tRelative Humidity: {0:.1f} % rH".format(hts_data.relative_humidity))

# Set up LPS25 Pressure Sensor and capture data for this run
lps = adafruit_lps2x.LPS25(i2c)
lps_data = lps
print("LPS25 sensor reading:")
print("\tPressure: {0:.1f} inHg".format(lps_data.pressure / 33.864))

# Set up LC709203F LiPo Fuel Gauge and capture data for this run
lc = adafruit_lc709203f.LC709203F(i2c)
lc_data = lc
print("LC709203F LiPo Fuel Gauge sensor readings: ")
print("\tBattery voltage: %0.3f Volts" % (lc_data.cell_voltage))
print("\tBattery percentage: %0.1f %%" % (lc_data.cell_percent))

# Network / Wi-Fi Setup
while not wifi.radio.ap_info:
  try:
    print("Attempting to connect to Wi-Fi.")
    wifi.radio.connect(secrets['ssid'], secrets['password'])
  except:
    print("Could not connect to AP.")
    take_nap(300)
print("Successfully connected to Wi-Fi.")
# --- DIAG LEDS ---
set_diag_leds(False, "Yellow")

# Test Internet connectivity
google_dns = ipaddress.ip_address("8.8.8.8")
ping_result = wifi.radio.ping(google_dns)
if ping_result == None:
  # No result received
  print("Could not connect to Internet.")
  take_nap(300)
# --- DIAG LEDS ---
set_diag_leds(True, "Yellow")

# Create an instance of the Adafruit IO HTTP client
aio_username = secrets["aio_username"]
aio_key = secrets["aio_key"]
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

# Initialize an Adafruit IO HTTP API object
io = IO_HTTP(aio_username, aio_key, requests)

# Set real time clock
try:
  (rtc.RTC()).datetime = io.receive_time()
except:
  print("Could not retreive RTC information from AdaFruit IO.")
  take_nap(300)
# --- DIAG LEDS ---
set_diag_leds(False, "Green")

# Initialize Feeds
try:
  temperature = io.get_feed("feathers2.temperature")
  humidity = io.get_feed("feathers2.humidity")
  pressure = io.get_feed("feathers2.pressure")
  battery_voltage = io.get_feed("feathers2.battery-voltage")
  battery_percent = io.get_feed("feathers2.battery-percent")

except:
  print("Could not connect to feeds.")
  take_nap(300)
# --- DIAG LEDS ---
set_diag_leds(True, "Green")

t = time.localtime()
try:
  print('{}/{}/{} {:02}:{:02}:{:02} - Uploading data.'.format(t.tm_mon, t.tm_mday, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec))
  io.send_data(temperature["key"], hts_data.temperature * 9/5 + 32)
  io.send_data(humidity["key"], hts_data.relative_humidity)
  io.send_data(pressure["key"], lps_data.pressure / 33.864)
  io.send_data(battery_voltage["key"], lc_data.cell_voltage)
  io.send_data(battery_percent["key"], lc_data.cell_percent)
  # --- DIAG LEDS ---
  set_diag_leds(False, "Blue")
except RuntimeError:
  print("Could not POST to IO.")
  take_nap(300)

# Normal delay
take_nap(IO_DELAY)