This project includes multiple AI/ML-based lottery number generators for German Lotto 6aus49, including pattern analysis, weighted predictions, and hybrid approaches. Features automated weekly tip generation, performance tracking, and Telegram bot integration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
341 lines
12 KiB
Python
341 lines
12 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Lotto 6aus49 Benachrichtigungs-System
|
|
|
|
Unterstützt:
|
|
- Telegram Bot Notifications
|
|
- Email Notifications (optional)
|
|
|
|
Konfiguration über config/notifications.json
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import requests
|
|
from typing import List, Dict, Any
|
|
|
|
|
|
class LottoNotifier:
|
|
"""Benachrichtigungs-System für Lotto 6aus49."""
|
|
|
|
def __init__(self, config_path: str = None):
|
|
"""
|
|
Initialisiert Notifier.
|
|
|
|
Args:
|
|
config_path: Pfad zur Konfigurationsdatei
|
|
"""
|
|
if config_path is None:
|
|
# Default: config/notifications.json im Projekt-Root
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
project_root = os.path.dirname(os.path.dirname(script_dir))
|
|
config_path = os.path.join(project_root, 'config', 'notifications.json')
|
|
|
|
self.config_path = config_path
|
|
self.config = self._load_config()
|
|
|
|
def _load_config(self) -> dict:
|
|
"""Lädt Konfiguration."""
|
|
if not os.path.exists(self.config_path):
|
|
print(f"⚠️ Konfigurationsdatei nicht gefunden: {self.config_path}")
|
|
return {
|
|
"telegram": {"enabled": False},
|
|
"email": {"enabled": False}
|
|
}
|
|
|
|
try:
|
|
with open(self.config_path, 'r') as f:
|
|
config = json.load(f)
|
|
return config
|
|
except Exception as e:
|
|
print(f"⚠️ Fehler beim Laden der Konfiguration: {e}")
|
|
return {
|
|
"telegram": {"enabled": False},
|
|
"email": {"enabled": False}
|
|
}
|
|
|
|
def send_tips_generated(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
|
"""
|
|
Sendet Benachrichtigung über generierte Tipps.
|
|
|
|
Args:
|
|
tips: Liste aller generierten Tipps
|
|
timestamp: Timestamp der Generierung
|
|
best_tip: Bester Tipp (höchste Confidence)
|
|
"""
|
|
if self.config['telegram']['enabled']:
|
|
self._send_telegram_tips(tips, timestamp, best_tip)
|
|
|
|
if self.config['email']['enabled']:
|
|
self._send_email_tips(tips, timestamp, best_tip)
|
|
|
|
def _send_telegram_tips(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
|
"""Sendet Telegram-Nachricht."""
|
|
try:
|
|
bot_token = self.config['telegram']['bot_token']
|
|
chat_id = self.config['telegram']['chat_id']
|
|
|
|
# Formatiere Nachricht
|
|
message = self._format_telegram_message(tips, timestamp, best_tip)
|
|
|
|
# Sende über Telegram Bot API
|
|
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
|
data = {
|
|
"chat_id": chat_id,
|
|
"text": message,
|
|
"parse_mode": "Markdown"
|
|
}
|
|
|
|
response = requests.post(url, data=data, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
print("✅ Telegram-Benachrichtigung gesendet")
|
|
else:
|
|
print(f"⚠️ Telegram-Fehler: {response.status_code}")
|
|
print(f" Response: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Telegram-Benachrichtigung fehlgeschlagen: {e}")
|
|
|
|
def _format_telegram_message(self, tips: List[Dict], timestamp: str, best_tip: Dict) -> str:
|
|
"""Formatiert Telegram-Nachricht."""
|
|
# Header
|
|
message = "🎲 *LOTTO 6AUS49 - NEUE TIPPS GENERIERT*\n"
|
|
message += "=" * 40 + "\n\n"
|
|
|
|
# Timestamp
|
|
message += f"📅 *Generiert:* {timestamp}\n"
|
|
message += f"📊 *Anzahl Tipps:* {len(tips)}\n\n"
|
|
|
|
# Bester Tipp
|
|
message += "⭐ *BESTER TIPP:*\n"
|
|
numbers_str = ' - '.join([f"{n:02d}" for n in best_tip['numbers']])
|
|
message += f"🎯 Zahlen: `{numbers_str}`\n"
|
|
message += f"🌟 Superzahl: `{best_tip['superzahl']}`\n"
|
|
message += f"📈 Confidence: `{best_tip['confidence']:.4f}`\n"
|
|
message += f"🎨 Strategie: `{best_tip['strategy']}`\n\n"
|
|
|
|
# Statistiken
|
|
avg_conf = sum(t['confidence'] for t in tips) / len(tips)
|
|
avg_qual = sum(t['quality'] for t in tips) / len(tips)
|
|
|
|
message += "📊 *STATISTIKEN:*\n"
|
|
message += f"🎯 Ø Confidence: `{avg_conf:.4f}`\n"
|
|
message += f"💎 Ø Quality: `{avg_qual:.4f}`\n\n"
|
|
|
|
# Top 3 Tipps
|
|
message += "🏆 *TOP 3 TIPPS:*\n"
|
|
sorted_tips = sorted(tips, key=lambda t: t['confidence'], reverse=True)[:3]
|
|
|
|
for i, tip in enumerate(sorted_tips, 1):
|
|
nums = ' - '.join([f"{n:02d}" for n in tip['numbers']])
|
|
message += f"{i}. `{nums}` + SZ `{tip['superzahl']}` "
|
|
message += f"({tip['confidence']:.3f})\n"
|
|
|
|
message += "\n🍀 *Viel Glück!*"
|
|
|
|
return message
|
|
|
|
def _send_email_tips(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
|
"""Sendet Email-Benachrichtigung."""
|
|
# TODO: Email-Versand implementieren wenn gewünscht
|
|
print("⚠️ Email-Benachrichtigung noch nicht implementiert")
|
|
|
|
def send_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
|
"""
|
|
Sendet Benachrichtigung über Ziehungs-Ergebnisse und Tipp-Evaluation.
|
|
|
|
Args:
|
|
draw: Dict mit Ziehungsdaten (date, Z1-Z6, SZ)
|
|
evaluation_summary: Dict mit avg_main, sz_rate
|
|
best_match: Dict mit main_matches, sz_match
|
|
"""
|
|
if self.config['telegram']['enabled']:
|
|
self._send_telegram_draw_results(draw, evaluation_summary, best_match)
|
|
|
|
if self.config['email']['enabled']:
|
|
self._send_email_draw_results(draw, evaluation_summary, best_match)
|
|
|
|
def _send_telegram_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
|
"""Sendet Telegram-Nachricht mit Ziehungsergebnissen."""
|
|
try:
|
|
bot_token = self.config['telegram']['bot_token']
|
|
chat_id = self.config['telegram']['chat_id']
|
|
|
|
# Formatiere Nachricht
|
|
message = self._format_draw_results_message(draw, evaluation_summary, best_match)
|
|
|
|
# Sende über Telegram Bot API
|
|
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
|
data = {
|
|
"chat_id": chat_id,
|
|
"text": message,
|
|
"parse_mode": "Markdown"
|
|
}
|
|
|
|
response = requests.post(url, data=data, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
print("✅ Telegram-Benachrichtigung gesendet")
|
|
else:
|
|
print(f"⚠️ Telegram-Fehler: {response.status_code}")
|
|
print(f" Response: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Telegram-Benachrichtigung fehlgeschlagen: {e}")
|
|
|
|
def _format_draw_results_message(self, draw: Dict, evaluation_summary: Dict, best_match: Dict) -> str:
|
|
"""Formatiert Telegram-Nachricht für Ziehungsergebnisse."""
|
|
# Header
|
|
message = "🎲 *LOTTO 6AUS49 - ZIEHUNGSERGEBNISSE*\n"
|
|
message += "=" * 40 + "\n\n"
|
|
|
|
# Ziehungsdatum
|
|
draw_date = draw['date']
|
|
if hasattr(draw_date, 'strftime'):
|
|
date_str = draw_date.strftime('%d.%m.%Y')
|
|
else:
|
|
date_str = str(draw_date)
|
|
|
|
message += f"📅 *Ziehung vom:* {date_str}\n\n"
|
|
|
|
# Gezogene Zahlen
|
|
drawn_numbers = [draw.get(f'Z{i}') for i in range(1, 7)]
|
|
numbers_str = ' - '.join([f"{n:02d}" for n in drawn_numbers if n is not None])
|
|
message += f"🎯 *Gewinnzahlen:* `{numbers_str}`\n"
|
|
|
|
if draw.get('SZ') is not None:
|
|
message += f"🌟 *Superzahl:* `{draw['SZ']}`\n\n"
|
|
else:
|
|
message += "\n"
|
|
|
|
# Evaluation Summary
|
|
message += "📊 *TIPP-EVALUATION:*\n"
|
|
if evaluation_summary:
|
|
avg_main = evaluation_summary.get('avg_main', 0)
|
|
sz_rate = evaluation_summary.get('sz_rate', 0)
|
|
message += f"🎯 Ø Treffer Hauptzahlen: `{avg_main:.2f}`\n"
|
|
message += f"🌟 Superzahl-Rate: `{sz_rate*100:.1f}%`\n\n"
|
|
|
|
# Bester Tipp
|
|
message += "🏆 *BESTER TIPP:*\n"
|
|
if best_match:
|
|
main_matches = best_match.get('main_matches', 0)
|
|
sz_match = best_match.get('sz_match', False)
|
|
|
|
# Rating emoji
|
|
if main_matches == 6 and sz_match:
|
|
rating = "🏆 JACKPOT!"
|
|
elif main_matches == 6:
|
|
rating = "💰 Klasse 2"
|
|
elif main_matches == 5 and sz_match:
|
|
rating = "💰 Klasse 3"
|
|
elif main_matches == 5:
|
|
rating = "💰 Klasse 4"
|
|
elif main_matches == 4:
|
|
rating = "💵 Klasse 6"
|
|
elif main_matches == 3:
|
|
rating = "✅ Klasse 8"
|
|
elif main_matches >= 2:
|
|
rating = "👍 OK"
|
|
else:
|
|
rating = "⚪ Niedrig"
|
|
|
|
sz_indicator = "✅" if sz_match else "⚪"
|
|
message += f"🎯 Treffer Hauptzahlen: `{main_matches}/6`\n"
|
|
message += f"🌟 Superzahl: {sz_indicator}\n"
|
|
message += f"📈 Bewertung: {rating}\n"
|
|
|
|
message += "\n🔄 *System wurde aktualisiert und trainiert!*"
|
|
|
|
return message
|
|
|
|
def _send_email_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
|
"""Sendet Email-Benachrichtigung."""
|
|
# TODO: Email-Versand implementieren wenn gewünscht
|
|
print("⚠️ Email-Benachrichtigung noch nicht implementiert")
|
|
|
|
def send_test_notification(self):
|
|
"""Sendet Test-Benachrichtigung."""
|
|
if self.config['telegram']['enabled']:
|
|
try:
|
|
bot_token = self.config['telegram']['bot_token']
|
|
chat_id = self.config['telegram']['chat_id']
|
|
|
|
message = "🧪 *LOTTO 6AUS49 TEST*\n\n"
|
|
message += "✅ Benachrichtigungs-System funktioniert!\n"
|
|
message += f"📅 {os.popen('date').read().strip()}"
|
|
|
|
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
|
data = {
|
|
"chat_id": chat_id,
|
|
"text": message,
|
|
"parse_mode": "Markdown"
|
|
}
|
|
|
|
response = requests.post(url, data=data, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
print("✅ Test-Benachrichtigung erfolgreich gesendet")
|
|
return True
|
|
else:
|
|
print(f"❌ Fehler: {response.status_code}")
|
|
print(f" Response: {response.text}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Test fehlgeschlagen: {e}")
|
|
return False
|
|
else:
|
|
print("⚠️ Telegram nicht aktiviert in config/notifications.json")
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""Test-Funktion."""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Lotto 6aus49 Notifier Test")
|
|
parser.add_argument(
|
|
'--test',
|
|
action='store_true',
|
|
help='Sende Test-Benachrichtigung'
|
|
)
|
|
parser.add_argument(
|
|
'--config',
|
|
type=str,
|
|
help='Pfad zur Config-Datei'
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
notifier = LottoNotifier(config_path=args.config)
|
|
|
|
if args.test:
|
|
notifier.send_test_notification()
|
|
else:
|
|
# Beispiel-Tipps
|
|
example_tips = [
|
|
{
|
|
'numbers': [7, 14, 21, 28, 35, 42],
|
|
'superzahl': 3,
|
|
'confidence': 0.7234,
|
|
'quality': 0.6891,
|
|
'strategy': 'PURE-AI'
|
|
},
|
|
{
|
|
'numbers': [2, 11, 19, 27, 36, 45],
|
|
'superzahl': 7,
|
|
'confidence': 0.6978,
|
|
'quality': 0.6543,
|
|
'strategy': 'HYBRID-OPT'
|
|
}
|
|
]
|
|
|
|
best = example_tips[0]
|
|
notifier.send_tips_generated(example_tips, "2024-11-27 16:00", best)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|