|
| 1 | +# SPDX-FileCopyrightText: 2022 Tod Kurt for Adafruit Industries |
| 2 | +# SPDX-License-Identifier: MIT |
| 3 | + |
| 4 | +""" |
| 5 | +This example solicits notifications from Apple devices paired with it, |
| 6 | +detecting specifically the IncomingCall and ActiveCall notification categories |
| 7 | +and sending back Positive Actions to accept calls or Negative Actions to |
| 8 | +decline or hang up calls. It also shows initiating pairing, prints existing |
| 9 | +notifications and prints any new ones as they arrive. |
| 10 | +""" |
| 11 | + |
| 12 | +import time |
| 13 | +import board |
| 14 | +import digitalio |
| 15 | +import neopixel |
| 16 | +import adafruit_ble |
| 17 | +from adafruit_ble.advertising.standard import SolicitServicesAdvertisement |
| 18 | +import adafruit_ble_apple_notification_center as ancs |
| 19 | + |
| 20 | +# Circuit Playground Bluefruit buttons and LED setup |
| 21 | +butA = digitalio.DigitalInOut(board.D4) # CPB "A" button |
| 22 | +butB = digitalio.DigitalInOut(board.D5) # CPB "B" button |
| 23 | +butA.switch_to_input(digitalio.Pull.DOWN) # buttons are active HIGH |
| 24 | +butB.switch_to_input(digitalio.Pull.DOWN) |
| 25 | + |
| 26 | +leds = neopixel.NeoPixel(board.D8, 10, brightness=0.1) |
| 27 | + |
| 28 | +(coff, cred, cgrn, cblu, cgra) = (0x000000, 0xFF0000, 0x00FF00, 0x0000FF, 0x111111) |
| 29 | +leds_off = (coff, coff, coff, coff, coff, coff, coff, coff, coff, coff) |
| 30 | +leds_idle = (cgra, cgra, cgra, cgra, cgra, cgra, cgra, cgra, cgra, cgra) |
| 31 | +leds_incoming_call = (coff, cgrn, cgrn, cgrn, coff, coff, cred, cred, cred, coff) |
| 32 | +leds_active_call = (cgrn, coff, coff, coff, cgrn, cgrn, cred, cred, cred, cgrn) |
| 33 | + |
| 34 | +print("starting...") |
| 35 | +radio = adafruit_ble.BLERadio() # pylint: disable=no-member |
| 36 | +a = SolicitServicesAdvertisement() |
| 37 | +# a.complete_name = "CIRPYCALLHANDLER" # this crashes things? |
| 38 | +a.solicited_services.append(ancs.AppleNotificationCenterService) |
| 39 | +radio.start_advertising(a) |
| 40 | + |
| 41 | +last_display_time = time.monotonic() |
| 42 | + |
| 43 | +while True: |
| 44 | + while not radio.connected: |
| 45 | + print("not connected") |
| 46 | + time.sleep(1) |
| 47 | + |
| 48 | + for connection in radio.connections: |
| 49 | + if not connection.paired: |
| 50 | + connection.pair() |
| 51 | + print("paired") |
| 52 | + |
| 53 | + ans = connection[ancs.AppleNotificationCenterService] |
| 54 | + |
| 55 | + for notification in ans.wait_for_new_notifications(): |
| 56 | + print("New Notification:\n- ", notification) |
| 57 | + |
| 58 | + leds[:] = leds_idle |
| 59 | + |
| 60 | + for notification in ans.active_notifications.values(): |
| 61 | + # incoming call category, has positive & negative actions |
| 62 | + if notification.category_id == 1: |
| 63 | + leds[:] = leds_incoming_call |
| 64 | + if butA.value: |
| 65 | + print("Action: accepting call") |
| 66 | + notification.send_positive_action() |
| 67 | + time.sleep(1) # simple debounce |
| 68 | + if butB.value: |
| 69 | + print("Action: declining call") |
| 70 | + notification.send_negative_action() |
| 71 | + time.sleep(1) # simple debounce |
| 72 | + # active call category, only has negative action |
| 73 | + if notification.category_id == 12: |
| 74 | + leds[:] = leds_active_call |
| 75 | + if butB.value: |
| 76 | + print("Action: hanging up call") |
| 77 | + notification.send_negative_action() |
| 78 | + time.sleep(1) # simple debounce |
| 79 | + |
| 80 | + if time.monotonic() - last_display_time > 3.0: |
| 81 | + last_display_time = time.monotonic() |
| 82 | + print( |
| 83 | + "Current Notifications:", |
| 84 | + len(ans.active_notifications), |
| 85 | + time.monotonic(), |
| 86 | + ) |
| 87 | + for nid, n in ans.active_notifications.items(): |
| 88 | + print( |
| 89 | + "- uid:", |
| 90 | + n.id, |
| 91 | + "catid:", |
| 92 | + n.category_id, |
| 93 | + "title:", |
| 94 | + n.title, |
| 95 | + "msg:", |
| 96 | + n.message, |
| 97 | + ) |
0 commit comments