# ble_observe_1.py: Zeigt Botschaft (MSG) eines Boradcasters auf dem Display an,
# in diesem Fall einen Temperaturwert

# Benutze einen weiteren TTGO als Broadcaster (ble_broadcast_1.py)

# Stand 13.04.2021


# Importe:

from time import sleep
from machine import Pin, I2C, SPI
from ubluetooth import BLE
from micropython import const
import vga2_bold_16x16 as font1 # mit Sonderzeichen (für °)
import vga1_bold_16x32 as font2
import st7789

_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)

_ADV_TYP_NAME = const(9)
_TX_POWER_LEVEL = const(10)
_ADV_TYP_MSG = const(250) # Eigener ADV_Typ


# Funktionen:

def find_adv(adv_type, data): 
  i = 0
  while i + 1 < len(data): 
    ad_structure_len = data[i]  
    ad_structure_type = data[i + 1] 
    ad_structure_payload = data[i + 2: i + ad_structure_len + 1] 
    if ad_structure_type == adv_type: 
       return ad_structure_payload 
    i += ad_structure_len + 1 
  return None


def find_adv_name(data):
  n = find_adv(_ADV_TYP_NAME, data)   
  if n:
    return str(n, 'UTF-8') # Text
  return None


def find_adv_msg(data):
  n = find_adv(_ADV_TYP_MSG, data)   
  if n:
    return str(n, 'UTF-8') # Text
  return None


def bt_irq_handler(event, data):
  if event == _IRQ_SCAN_RESULT: # Advertiser-Datenpaket erhalten
    addr_type, addr, adv_type, rssi, adv_data = data # data ist ein Tupel
    name = find_adv_name(adv_data)
    if name == 'ESP32':
      print('-----------------------------------------------------------')
      print('ADV-Data (Name): ', name)
      msg = find_adv_msg(adv_data)
      print('ADV_Data (Message): ', msg)
      temp_displ = b'Temp: ' + bytes(msg, 'utf-8') + b' \xF8C ' # Temperaturanzeige
      display.text(font1, temp_displ, 10, 60)
      print()
      
  elif event == _IRQ_SCAN_DONE: # Scan beendet
    print('-----------------------------------------------------------')
    print('scan complete')

# Hauptptrogramm:

    # Display:

spi = SPI(2, baudrate=20000000, polarity=1, sck=Pin(18), mosi=Pin(19))
display = st7789.ST7789(spi, 135, 240,  reset=Pin(23, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(16, Pin.OUT), backlight=Pin(4, Pin.OUT), rotation=3) # Landscape

display.init()
display.fill(0)  # loeschen; Bildschirm schwarz
display.text(font2, 'Observer', 10, 10, st7789.GREEN)

    # Observer:

ble = BLE()
ble.active(True)
ble.irq(bt_irq_handler)
ble.gap_scan(0, 100000, 25000, False) # Observer ist bis zum Abtrennen der el. Quelle aktiv




