-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
160 lines (133 loc) · 5.03 KB
/
main.py
File metadata and controls
160 lines (133 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import time
import os
import glob
import serial
import requests
from adafruit_pn532.uart import PN532_UART
# ----------------------------
# Helper: find PN532 serial device
# ----------------------------
def find_uart_device():
devices = glob.glob("/dev/ttyUSB*")
return devices[0] if devices else None
# ----------------------------
# Helper: parse NDEF URI
# ----------------------------
def parse_ndef_uri(tag_data):
uri_tnf_index = tag_data.find(b'\x55') # Look for URI record
if uri_tnf_index == -1 or uri_tnf_index + 2 >= len(tag_data):
return None
prefix_code = tag_data[uri_tnf_index + 1]
raw_uri_bytes = tag_data[uri_tnf_index + 2:]
prefix_map = {
0x00: "", 0x01: "http://www.", 0x02: "https://www.",
0x03: "http://", 0x04: "https://"
}
prefix = prefix_map.get(prefix_code, "")
uri_path = raw_uri_bytes.decode("utf-8", errors="ignore")
full_url = prefix + uri_path
full_url = full_url.rstrip(" \n\r\x00\xfe\t")
return full_url
# ----------------------------
# NFC reader setup
# ----------------------------
def connect_reader():
while True:
device = find_uart_device()
if not device:
print("Waiting for NFC reader...")
time.sleep(2)
continue
try:
ser = serial.Serial(device, baudrate=115200, timeout=1)
pn532 = PN532_UART(ser, debug=False)
pn532.SAM_configuration()
print(f"NFC reader connected on {device}")
return pn532
except Exception as e:
print(f"Failed to connect to {device}: {e}")
time.sleep(2)
# ----------------------------
# Debounce & memory variables
# ----------------------------
last_uid = None
last_url = None
last_seen_time = 0
forget_after = 30 # seconds to "forget" a tag after removal
# ----------------------------
# Main
# ----------------------------
if __name__ == "__main__":
pn532 = connect_reader()
while True:
try:
uid = pn532.read_passive_target(timeout=0.5)
now = time.time()
if uid is None:
# If no tag present for a while, forget the last one
if last_uid and (now - last_seen_time) > forget_after:
print("Forgetting last tag (timeout reached).")
last_uid = None
last_url = None
continue
# Format UID
uid_str = ''.join([f"{i:02x}" for i in uid])
# If same UID still present and not expired, skip
if uid == last_uid and (now - last_seen_time) <= forget_after:
continue
print(f"Tag detected! UID: {uid_str}")
last_uid = uid
last_seen_time = now
# Read all relevant NTAG blocks
tag_data = bytearray()
for block in range(4, 50):
try:
block_data = pn532.ntag2xx_read_block(block)
if block_data:
tag_data += block_data
except Exception:
continue
if not tag_data:
print("No data read from tag.")
continue
# Parse URI
full_url = parse_ndef_uri(tag_data)
if not full_url:
print("No valid NDEF URI found.")
continue
print(f"Parsed tag URL: {full_url}")
# Classify and filter playable URLs
kind = None
if "metadata" in full_url:
kind = "Track/Album"
elif "playlists" in full_url:
kind = "Playlist"
elif "stations" in full_url:
kind = "Station"
elif "sections" in full_url:
kind = "Library Section/Artist"
if not kind:
print("URL not recognized as playable — attempting playback.")
kind = "Unknown"
print(f"Detected tag type: {kind}")
# Convert to local Plexamp URL
local_url = full_url.replace("https://listen.plex.tv", "http://localhost:32500")
local_url = local_url.replace("http://listen.plex.tv", "http://localhost:32500")
print(f"Local Plexamp URL: {local_url}")
# If same URL as before and still within active session, skip
if local_url == last_url and (now - last_seen_time) <= forget_after:
print("Same tag & URL already active — skipping trigger.")
continue
last_url = local_url
# Trigger Plexamp playback
try:
response = requests.get(local_url)
if response.ok:
print(f"Playback triggered! ({kind})")
else:
print(f"Error triggering playback: {response.status_code}")
except Exception as e:
print(f"Failed to trigger Plexamp: {e}")
except Exception as e:
print(f"Reader error: {e}. Reconnecting...")
pn532 = connect_reader()