confidence.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # -*- coding: utf-8 -*-
  2. """
  3. Confidence-Strategie für Arbitration.
  4. Wählt den Satellite mit der höchsten Wakeword-Erkennungs-Confidence.
  5. Nützlich wenn die Audio-Qualität variiert (z.B. verschiedene Mikrofone).
  6. """
  7. from typing import Any
  8. from trixy_core.arbitration.candidate import ArbitrationCandidate
  9. from trixy_core.arbitration.strategies.base import ArbitrationStrategy
  10. class ConfidenceStrategy(ArbitrationStrategy):
  11. """
  12. Strategie: Höchste Wakeword-Confidence gewinnt.
  13. Diese Strategie wählt den Satellite aus, bei dem das Wakeword
  14. mit der höchsten Konfidenz erkannt wurde. Nützlich wenn
  15. verschiedene Mikrofone unterschiedliche Qualität haben.
  16. Beispiel:
  17. ```python
  18. strategy = ConfidenceStrategy()
  19. candidates = [
  20. ArbitrationCandidate(satellite_id="kitchen", confidence=0.92),
  21. ArbitrationCandidate(satellite_id="living_room", confidence=0.88),
  22. ]
  23. winner = strategy.select(candidates)
  24. # winner.satellite_id == "kitchen"
  25. ```
  26. """
  27. def __init__(self, min_confidence: float = 0.5) -> None:
  28. """
  29. Initialisiert die Strategie.
  30. Args:
  31. min_confidence: Minimale Confidence für Gültigkeit
  32. """
  33. self.min_confidence = min_confidence
  34. @property
  35. def name(self) -> str:
  36. return "confidence"
  37. @property
  38. def description(self) -> str:
  39. return "Wählt den Satellite mit der höchsten Wakeword-Confidence"
  40. def calculate_score(
  41. self,
  42. candidate: ArbitrationCandidate,
  43. context: dict[str, Any] | None = None,
  44. ) -> float:
  45. """
  46. Score basiert nur auf Confidence.
  47. Args:
  48. candidate: Der Kandidat
  49. context: Nicht verwendet
  50. Returns:
  51. Confidence als Score (0.0-1.0)
  52. """
  53. candidate.score_details = {
  54. "confidence": candidate.confidence,
  55. }
  56. return candidate.confidence
  57. def select(
  58. self,
  59. candidates: list[ArbitrationCandidate],
  60. context: dict[str, Any] | None = None,
  61. ) -> ArbitrationCandidate | None:
  62. """
  63. Wählt Kandidaten mit höchster Confidence.
  64. Args:
  65. candidates: Liste der Kandidaten
  66. context: Nicht verwendet
  67. Returns:
  68. Kandidat mit höchster confidence oder None
  69. """
  70. valid = self.filter_valid(candidates)
  71. if not valid:
  72. return None
  73. # Scores berechnen
  74. for candidate in valid:
  75. candidate.score = self.calculate_score(candidate, context)
  76. # Höchsten Score auswählen
  77. winner = max(valid, key=lambda c: c.score)
  78. return winner
  79. def validate_candidate(self, candidate: ArbitrationCandidate) -> bool:
  80. """Prüft ob Confidence über Minimum liegt."""
  81. base_valid = super().validate_candidate(candidate)
  82. return base_valid and candidate.confidence >= self.min_confidence