Track reviewed status for discovered sensors
Changes: - Added 'reviewed' field to DiscoveredSensor dataclass - By default, only show new (unreviewed) pending sensors - Mark sensors as reviewed when shown in approval CLI - Add --all flag to show all pending sensors (including reviewed) - Add --ignored flag to show ignored sensors - Prevent repeatedly asking for approval of same sensor Usage: approve-sensors # Only new sensors approve-sensors --all # All pending sensors approve-sensors --ignored # Ignored sensors approve-sensors --all --ignored # Everything
This commit is contained in:
@@ -8,6 +8,7 @@ Interactive tool to manage pending and ignored sensors.
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
@@ -191,6 +192,9 @@ def process_sensors(sensors: List[DiscoveredSensor], manager: DiscoveryManager):
|
||||
print(f"\nFound {len(sensors)} sensor(s) to review")
|
||||
|
||||
for i, sensor in enumerate(sensors, 1):
|
||||
# Mark as reviewed when shown
|
||||
manager.mark_reviewed(sensor.mac)
|
||||
|
||||
display_sensor(sensor, i, len(sensors))
|
||||
|
||||
choice = get_user_choice()
|
||||
@@ -209,6 +213,31 @@ def process_sensors(sensors: List[DiscoveredSensor], manager: DiscoveryManager):
|
||||
|
||||
def main():
|
||||
"""Main entry point for approve-sensors CLI."""
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Approve or ignore discovered Bluetooth sensors",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s # Show only new pending sensors
|
||||
%(prog)s --all # Show all pending sensors (including reviewed)
|
||||
%(prog)s --ignored # Show only ignored sensors
|
||||
%(prog)s --all --ignored # Show all sensors
|
||||
"""
|
||||
)
|
||||
parser.add_argument(
|
||||
'--all', '-a',
|
||||
action='store_true',
|
||||
help='Show all pending sensors, including previously reviewed ones'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--ignored', '-i',
|
||||
action='store_true',
|
||||
help='Show ignored sensors'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Setup logging
|
||||
logging.basicConfig(
|
||||
level=logging.WARNING,
|
||||
@@ -223,27 +252,38 @@ def main():
|
||||
# Load discovery manager
|
||||
manager = DiscoveryManager()
|
||||
|
||||
# Get pending and ignored sensors
|
||||
pending = manager.get_pending()
|
||||
ignored = manager.get_ignored()
|
||||
# Get sensors based on flags
|
||||
if args.all:
|
||||
pending = manager.get_pending()
|
||||
pending_label = "all pending"
|
||||
else:
|
||||
pending = manager.get_new_pending()
|
||||
pending_label = "new pending"
|
||||
|
||||
ignored = manager.get_ignored() if args.ignored else []
|
||||
|
||||
if not pending and not ignored:
|
||||
print("\n✅ No pending or ignored sensors found")
|
||||
print("\nDiscovered sensors will appear here when detected.")
|
||||
if args.all or args.ignored:
|
||||
print(f"\n✅ No {pending_label if pending else 'ignored'} sensors found")
|
||||
else:
|
||||
print("\n✅ No new sensors to review")
|
||||
all_pending = manager.get_pending()
|
||||
if all_pending:
|
||||
print(f"\nThere are {len(all_pending)} previously reviewed pending sensor(s).")
|
||||
print("Run with --all to review them again.")
|
||||
return 0
|
||||
|
||||
# Process pending sensors first
|
||||
# Process pending sensors
|
||||
if pending:
|
||||
print(f"\n📋 Processing {len(pending)} pending sensor(s)...")
|
||||
print(f"\n📋 Processing {len(pending)} {pending_label} sensor(s)...")
|
||||
process_sensors(pending, manager)
|
||||
|
||||
# Ask about ignored sensors
|
||||
# Process ignored sensors if requested
|
||||
if ignored:
|
||||
print(f"\n\nThere are {len(ignored)} ignored sensor(s).")
|
||||
review = input("Review ignored sensors? [y/N]: ").strip().lower()
|
||||
|
||||
if review == 'y':
|
||||
process_sensors(ignored, manager)
|
||||
if pending:
|
||||
print("\n" + "=" * 70)
|
||||
print(f"\n📋 Processing {len(ignored)} ignored sensor(s)...")
|
||||
process_sensors(ignored, manager)
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("Done!")
|
||||
|
||||
@@ -27,6 +27,7 @@ class DiscoveredSensor:
|
||||
last_seen: str
|
||||
sample_reading: Dict[str, float]
|
||||
status: str = "pending" # pending, approved, ignored
|
||||
reviewed: bool = False # Has been shown in approval CLI
|
||||
ignored_at: Optional[str] = None
|
||||
ignore_reason: Optional[str] = None
|
||||
|
||||
@@ -195,10 +196,26 @@ class DiscoveryManager:
|
||||
"""Get list of sensors with status 'pending'."""
|
||||
return [s for s in self.sensors.values() if s.status == "pending"]
|
||||
|
||||
def get_new_pending(self) -> List[DiscoveredSensor]:
|
||||
"""Get list of pending sensors that haven't been reviewed yet."""
|
||||
return [s for s in self.sensors.values() if s.status == "pending" and not s.reviewed]
|
||||
|
||||
def get_ignored(self) -> List[DiscoveredSensor]:
|
||||
"""Get list of sensors with status 'ignored'."""
|
||||
return [s for s in self.sensors.values() if s.status == "ignored"]
|
||||
|
||||
def mark_reviewed(self, mac: str):
|
||||
"""
|
||||
Mark a sensor as reviewed (shown in approval CLI).
|
||||
|
||||
Args:
|
||||
mac: MAC address
|
||||
"""
|
||||
mac = mac.upper()
|
||||
if mac in self.sensors:
|
||||
self.sensors[mac].reviewed = True
|
||||
self.save()
|
||||
|
||||
def send_ntfy_notification(self, sensor: DiscoveredSensor):
|
||||
"""
|
||||
Send ntfy notification for a newly discovered sensor.
|
||||
|
||||
Reference in New Issue
Block a user