# Heart Beat GATT: ble_hr_0a.py

# ggf. TTGO resetten
# Programm starten
# nRF APP starten -> CONNECT -> Heart Rate "öffnen"
# wiederhole:
# S0 bei TTGO betätigen und bpm-Wert eingeben (<= 255)
# Heart Rate value bei nRF Connect zeigt den eingegebenen Wert erst an,
# nachdem er mit mit der GET-Schaltfläche (Pfeil nach unten) angefordert worden ist (Polling).


# oberer Taster:

from machine import Pin
taster0 = Pin(0, Pin.IN, Pin.PULL_UP) # interner Pullup; parallel zum Taster 100 nF


# Bluetooth-Klasse MyBLEServer:

import ubluetooth
from micropython import const 
_ADV_TYP_NAME = const(9)
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_FLAG_READ = const(2)

    
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()


    def register(self):
        
        # Heart Rate (HR)
        HR_UUID = ubluetooth.UUID(0x180D)  
        HR_CHAR = (ubluetooth.UUID(0x2A37), _FLAG_READ)
        HR_SERVICE = (HR_UUID, (HR_CHAR,)) 
        SERVICES = (HR_SERVICE, )
        ((self.hr,),) = self.ble.gatts_register_services(SERVICES) 


    def write(self, data):
        
        self.ble.gatts_write(self.hr, 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')


# main:
ble = MyBLEServer("ESP32-HR")

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

while True:
    if taster0.value(): # warten, bis Taster0 betätigt wurde
        pass
    elif ble.conn: # für den Fall, dass die Verbindug inzwischen wieder getrennt wurde
        bpm = int(input('Eingabe: '))  # maximal 255
        bpm = bpm & 0xff # sicherheitshalber...
        bpm = bytes([0, bpm]) # Erstes Byte (0) signalisiert, dass der bpm_Wert nur aus einem 1 Byte besteht.
        ble.write(bpm)
        print()