# ble_UART_Temperatur.py

# NUS (Nordic UART SERVICE),  Temperaturwerte vom BME/BMP280 werden mit Notification gesendet.

# Stand: 08.05.2021

# Anschlüsse:
#-------------------------#
# BME/P280  ---  TTGO     #
#-------------------------#
# VIN       ---  3V       #
# GND       ---  G        #
# SCL       ---  22       #
# SDA       ---  21       #
#-------------------------#

# Das Modul Bme280.py muss zunächst auf den ESP323 hochgeladen werden!

# ggf. TTGO resetten
# Programm starten
# App nRF Connect starten und verbinden


# Bluetooth-Klasse MyBLEServer:

import ubluetooth
from micropython import const 
_ADV_TYP_NAME = const(9)
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_FLAG_READ = const(2)
_FLAG_WRITE = const(8)
_FLAG_NOTIFY = const(16)

class MyBLEServer():

    def __init__(self, name):
        
        self.name = name
        self.ble = ubluetooth.BLE()
        self.ble.active(True)

        self.ble.irq(self.my_ble_irq)
        self.register()
        self.advertiser()
        
        self.conn = False


    def my_ble_irq(self, event, data):
        
        if event == _IRQ_CENTRAL_CONNECT:
            print('Central connected')
            self.conn = True
        
        elif event == _IRQ_CENTRAL_DISCONNECT:
            print('Central disconnected')
            self.conn = False
            self.advertiser()
            
        elif event == _IRQ_GATTS_WRITE:
            print('Received: ', end='')
            buffer = self.ble.gatts_read(self.rx)
            message = buffer.decode('UTF-8')
            print(message)    


    def register(self):
        
        # Nordic UART Service (NUS)
        
        NUS_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
        RX_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
        TX_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
            
        BLE_NUS = ubluetooth.UUID(NUS_UUID)
        BLE_RX = (ubluetooth.UUID(RX_UUID), _FLAG_WRITE)
        BLE_TX = (ubluetooth.UUID(TX_UUID), _FLAG_NOTIFY)
            
        BLE_UART = (BLE_NUS, (BLE_TX, BLE_RX,))
        SERVICES = (BLE_UART, )
        ((self.tx, self.rx,), ) = self.ble.gatts_register_services(SERVICES)


    def notify(self, data):
        
        self.ble.gatts_notify(0, self.tx, data)


    def advertiser(self):
        
        adv_data = b'\x02\x01\x06'
        name = bytes(self.name, 'UTF-8')
        adv_data = adv_data +  bytearray((len(name) + 1, _ADV_TYP_NAME)) + name
        self.ble.gap_advertise(200000, adv_data, connectable=True)   # 200 ms Adv_Antervall 
        print('advertising')


# Vorbereitungen für BMP/E280 und sleep:

from machine import Pin, I2C
from time import sleep
import Bme280  # Original-Modul (s. o.) geringfügig modifiziert (Einheiten bei den Properties entfernt)
i2c = I2C(1, scl=Pin(22), sda=Pin(21), freq=10000)


# Hauptprogramm:

ble = MyBLEServer('ESP32-Temperatur')

while not ble.conn: # warten, bis Verbindung besteht
    pass

while True:
    bme = Bme280.BME280(i2c=i2c) 
    temp = bme.temperature # Der gelieferte Temperaturwert liegt hier als Zeichenkette vor!
    ble.notify(temp + ' °C')
    sleep(3)
    