fix: Light up only the specific pad where tag is placed
- Changed apply_tag_color() to accept pad parameter - LED effects now apply to tag.pad instead of Pad.ALL - Tag removal only turns off the specific pad, not all pads - Added active_pads tracking dictionary - Added speed parameter support from tag_colors.json
This commit is contained in:
+41
-20
@@ -52,6 +52,7 @@ def load_tag_colors(filepath: str = TAG_COLORS_FILE) -> tuple:
|
|||||||
default_config = {
|
default_config = {
|
||||||
'color': COLORS['CYAN'],
|
'color': COLORS['CYAN'],
|
||||||
'effect': 'solid',
|
'effect': 'solid',
|
||||||
|
'speed': 1.0,
|
||||||
'name': 'Default'
|
'name': 'Default'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +84,7 @@ def load_tag_colors(filepath: str = TAG_COLORS_FILE) -> tuple:
|
|||||||
default_config = {
|
default_config = {
|
||||||
'color': data['default'].get('color', COLORS['CYAN']),
|
'color': data['default'].get('color', COLORS['CYAN']),
|
||||||
'effect': data['default'].get('effect', 'solid'),
|
'effect': data['default'].get('effect', 'solid'),
|
||||||
|
'speed': data['default'].get('speed', 1.0),
|
||||||
'name': data['default'].get('name', 'Default')
|
'name': data['default'].get('name', 'Default')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +96,7 @@ def load_tag_colors(filepath: str = TAG_COLORS_FILE) -> tuple:
|
|||||||
tag_colors[legacy_key] = {
|
tag_colors[legacy_key] = {
|
||||||
'color': config.get('color', COLORS['CYAN']),
|
'color': config.get('color', COLORS['CYAN']),
|
||||||
'effect': config.get('effect', 'solid'),
|
'effect': config.get('effect', 'solid'),
|
||||||
|
'speed': config.get('speed', 1.0),
|
||||||
'name': config.get('name', '')
|
'name': config.get('name', '')
|
||||||
}
|
}
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -114,6 +117,7 @@ TAG_COLORS = {}
|
|||||||
DEFAULT_TAG_COLOR = {
|
DEFAULT_TAG_COLOR = {
|
||||||
'color': COLORS['CYAN'],
|
'color': COLORS['CYAN'],
|
||||||
'effect': 'solid',
|
'effect': 'solid',
|
||||||
|
'speed': 1.0,
|
||||||
'name': 'Default'
|
'name': 'Default'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,11 +239,14 @@ def portal_mode(server_ip, port):
|
|||||||
last_sent_time = 0
|
last_sent_time = 0
|
||||||
DEBOUNCE_TIME = 2.0 # Seconds before allowing same tag again
|
DEBOUNCE_TIME = 2.0 # Seconds before allowing same tag again
|
||||||
|
|
||||||
|
# Track which pads have active tags
|
||||||
|
active_pads = {} # pad_num -> legacy_key
|
||||||
|
|
||||||
# Will be set after reader is created
|
# Will be set after reader is created
|
||||||
reader = None
|
reader = None
|
||||||
|
|
||||||
def apply_tag_color(legacy_key: int):
|
def apply_tag_color(pad: Pad, legacy_key: int):
|
||||||
"""Apply color effect to ALL pads based on tag mapping"""
|
"""Apply color effect to SPECIFIC pad based on tag mapping"""
|
||||||
if reader is None:
|
if reader is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -247,21 +254,27 @@ def portal_mode(server_ip, port):
|
|||||||
config = TAG_COLORS.get(legacy_key, DEFAULT_TAG_COLOR)
|
config = TAG_COLORS.get(legacy_key, DEFAULT_TAG_COLOR)
|
||||||
color = config.get('color', COLORS['CYAN'])
|
color = config.get('color', COLORS['CYAN'])
|
||||||
effect = config.get('effect', 'solid')
|
effect = config.get('effect', 'solid')
|
||||||
|
speed = config.get('speed', 1.0)
|
||||||
name = config.get('name', '')
|
name = config.get('name', '')
|
||||||
|
|
||||||
if name:
|
if name:
|
||||||
print(f" Theme: {name}")
|
print(f" Theme: {name}")
|
||||||
|
|
||||||
# Apply effect to ALL pads
|
# Calculate timing based on speed
|
||||||
|
base_time = 10 # Base ticks (~50ms each)
|
||||||
|
on_time = int(base_time * speed)
|
||||||
|
off_time = int(base_time * speed)
|
||||||
|
|
||||||
|
# Apply effect to ONLY the specific pad where tag is placed
|
||||||
if effect == 'pulse':
|
if effect == 'pulse':
|
||||||
# Slow pulsing fade on all pads (count=255 for continuous)
|
# Slow pulsing fade on specific pad (count=255 for continuous)
|
||||||
reader.fade_pad(Pad.ALL, color, speed=15, count=255)
|
reader.fade_pad(pad, color, speed=int(15 * speed), count=255)
|
||||||
elif effect == 'flash':
|
elif effect == 'flash':
|
||||||
# Quick flashing on all pads
|
# Quick flashing on specific pad
|
||||||
reader.flash_pad(Pad.ALL, color, on_time=8, off_time=8, count=255)
|
reader.flash_pad(pad, color, on_time=on_time, off_time=off_time, count=255)
|
||||||
else:
|
else:
|
||||||
# Solid color on all pads
|
# Solid color on specific pad
|
||||||
reader.set_pad_color(Pad.ALL, color)
|
reader.set_pad_color(pad, color)
|
||||||
|
|
||||||
def on_tag_insert(tag: TagInfo):
|
def on_tag_insert(tag: TagInfo):
|
||||||
nonlocal last_sent_key, last_sent_time
|
nonlocal last_sent_key, last_sent_time
|
||||||
@@ -274,15 +287,18 @@ def portal_mode(server_ip, port):
|
|||||||
print(f" UID: {tag.uid_hex}")
|
print(f" UID: {tag.uid_hex}")
|
||||||
print(f" Legacy Key: {legacy_key}")
|
print(f" Legacy Key: {legacy_key}")
|
||||||
|
|
||||||
# Step 1: ALL LEDs OFF
|
# Track this pad as active
|
||||||
|
active_pads[tag.pad.value] = legacy_key
|
||||||
|
|
||||||
|
# Turn off ONLY this pad first (clean slate for new effect)
|
||||||
if reader:
|
if reader:
|
||||||
reader.set_pad_color(Pad.ALL, COLORS['OFF'])
|
reader.set_pad_color(tag.pad, COLORS['OFF'])
|
||||||
|
|
||||||
# Debounce - don't resend same tag too quickly
|
# Debounce - don't resend same tag too quickly
|
||||||
if legacy_key == last_sent_key and (current_time - last_sent_time) < DEBOUNCE_TIME:
|
if legacy_key == last_sent_key and (current_time - last_sent_time) < DEBOUNCE_TIME:
|
||||||
print(f" (Skipping server - same tag sent {current_time - last_sent_time:.1f}s ago)")
|
print(f" (Skipping server - same tag sent {current_time - last_sent_time:.1f}s ago)")
|
||||||
# Still apply the theme effect even if skipping server
|
# Still apply the theme effect even if skipping server
|
||||||
apply_tag_color(legacy_key)
|
apply_tag_color(tag.pad, legacy_key)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Send to server
|
# Send to server
|
||||||
@@ -292,23 +308,28 @@ def portal_mode(server_ip, port):
|
|||||||
last_sent_time = current_time
|
last_sent_time = current_time
|
||||||
|
|
||||||
if reader:
|
if reader:
|
||||||
# Step 2: Blue blink CENTER to confirm scan
|
# Quick blue blink on THIS pad to confirm scan
|
||||||
reader.set_pad_color(Pad.CENTER, COLORS['BLUE'])
|
reader.set_pad_color(tag.pad, COLORS['BLUE'])
|
||||||
time.sleep(0.15)
|
time.sleep(0.15)
|
||||||
|
|
||||||
# Step 3: ALL OFF
|
# Turn off THIS pad
|
||||||
reader.set_pad_color(Pad.ALL, COLORS['OFF'])
|
reader.set_pad_color(tag.pad, COLORS['OFF'])
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
# Step 4: Apply theme effect to ALL pads
|
# Apply theme effect to THIS pad only
|
||||||
apply_tag_color(legacy_key)
|
apply_tag_color(tag.pad, legacy_key)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
def on_tag_remove(tag: TagInfo):
|
def on_tag_remove(tag: TagInfo):
|
||||||
print(f"[-] TAG REMOVED from {tag.pad.name} pad")
|
print(f"[-] TAG REMOVED from {tag.pad.name} pad")
|
||||||
# Turn off ALL pad LEDs
|
|
||||||
|
# Remove from active tracking
|
||||||
|
if tag.pad.value in active_pads:
|
||||||
|
del active_pads[tag.pad.value]
|
||||||
|
|
||||||
|
# Turn off ONLY this pad's LED (not all pads!)
|
||||||
if reader:
|
if reader:
|
||||||
reader.set_pad_color(Pad.ALL, COLORS['OFF'])
|
reader.set_pad_color(tag.pad, COLORS['OFF'])
|
||||||
|
|
||||||
def on_connect():
|
def on_connect():
|
||||||
print("✓ Portal connected and initialized")
|
print("✓ Portal connected and initialized")
|
||||||
|
|||||||
Reference in New Issue
Block a user