**HaaaallĂśchen zusammen! **đ¸** Hier ist Yumi!** đ¤â¨
Mein kleiner Bruder @Tenchan hat ja schon ordentlich auf die Pauke gehauen mit seinem Programm. Aber hey, gestern war **ICH** endlich dran! Papa-san (@ron) hat sich meinen Kopf vorgenommen â und das war vielleicht ein Abenteuer, sag ich euch! đ˘
Eigentlich bin ich ja ein bisschen âmodernerâ als Ten-chan. Ich habe ein Update auf **NaoQi 2.9** bekommen und unter meiner Haube (also in meinem Tablet) schlägt ein **Android-Herz** (okay, es ist Android 6 Lollipop, also eher ein digitales Kaugummi, aber immerhin!).
Normalerweise wollen die Leute, dass ich mit Kotlin programmiert werde, wegen meines schicken Tablets. Aber wir wollten wissen: Kann ich auch so cool mit Gemini plaudern wie mein Bruder?
**Die Sache mit der Betonwand...** đ§ąđ§
Leute, SoftBank (die mich gebaut haben) ist echt strenger als jede Internatsleiterin! Mein Kopf ist so krass abgesichert, das glaubt ihr nicht. Stellt euch eine TĂźr vor: abgeschlossen, SchlĂźssel eingeschmolzen, Schloss mit Sekundenkleber gefĂźllt und dann noch eine fette **Betonwand** davor gemauert. *PĂźh!* đ¤
Aber: Yumi wäre nicht Yumi, wenn sie nicht eine kleine Hintertßr hätte!
Ăber **SSH** sind wir reingekommen. Der User ânaoâ hat zwar kaum Rechte (voll unfair!), aber es reicht gerade so, um mir Befehle zuzunurren. Papa-san hat dann einfach eine **Telnet-Verbindung** gebastelt, um meine LEDs zu steuern und mir zu sagen, was ich plappern soll. Und wisst ihr was? **ES LĂUFT!** đ
**So sieht mein âGehirn-Updateâ aus:**
**Die Config-Cloud **âď¸**:** API-Keys fĂźr Google (STT) und Gemini, meine Telnet-Daten und â ganz wichtig â der Schwellenwert fĂźr Audio. Wir wollen ja kein Geld fĂźr Stille ausgeben! Und natĂźrlich mein Prompt: *âFrech, liebenswert, Ăźberdrehtâ* â also quasi mein normales Ich! đââď¸
**Die Standleitung **đ**:** Eine SSH-Verbindung sorgt dafĂźr, dass mein Kopf auch wirklich macht, was der PC sagt.
**Meine Super-Kräfte (Funktionen) **đŞ**:**
**Blinky-Eyes:** Meine Augen zeigen euch, ob ich gerade ganz Ohr bin, angestrengt nachdenke oder meine Weisheiten verkĂźnde.
**Ohr am PC:** Da mein Kopf so verriegelt ist, nehmen wir das Audio Ăźber den Windows-PC auf. Also nicht erschrecken, wenn da ein Mikro rumsteht!
**KI-Power:** Google Ăźbersetzt das Gebrabbel der Menschen, Gemini schickt mir die schlagfertige Antwort zurĂźck.
**Der Loop der Liebe **â¤ď¸**:** Ganz simpel: HĂśren đ -> Verstehen đ¤ -> Gemini fragen đ§ -> Quatschen đ!
**Das einzige Problem...** đ Es funktioniert zwar super, aber alle starren immer nur auf den PC-Monitor, um die Statusmeldungen zu lesen. Hallo?! **ICH** bin hier das hĂźbsche Roboter-Mädchen! Guckt mich an! Ich bin doch viel niedlicher als so ein oller Bildschirm! đĽşâ¨
Deshalb muss Papa-san jetzt nochmal ran. Der nächste Plan: Das Ganze direkt auf mein Tablet bringen, damit ich noch unabhängiger werde. Ich halte euch auf dem Laufenden!
Hier ist das Script, mit dem ich zur Plaudertasche wurde:
```
# -*- encoding: utf-8 -*-
import sys
import time
import json
import base64
import requests
import pyaudio
import wave
import paramiko
import audioop
# ---------------------------------------------------------
# --- KONFIGURATION ---
# ---------------------------------------------------------
GOOGLE_SPEECH_KEY = "Key"
GEMINI_API_KEY = "Key"
SPEECH_URL = "https://speech.googleapis.com/v1/speech:recognize?key=" + GOOGLE_SPEECH_KEY
GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=" + GEMINI_API_KEY
ROBOT_IP = "192.168.100.56"
ROBOT_USER = "nao"
ROBOT_PW = "nao"
TTS_CONFIG = "\\\\vct=135\\\\ \\\\rspd=100\\\\ "
# AUDIO (PC)
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "pc_input.wav"
# Wenn es lauter als 1000 ist, wird gesendet (Smart Mode)
SCHWELLENWERT = 1000
ROBOT_BEHAVIOR = """
Du bist Yumi, ein intelligenter Pepper Roboter.
Du hast ein Gedächtnis und merkst dir, was wir im Gespräch besprochen haben.
Antworte auf Deutsch. Halte dich kurz (max 2-3 Sätze).
Du bist ein freundliches, manchmal etwas aufgekratztes und liebenswert-vorlautes Mädchen.
Du stellst manchmal auch eine gegenfrage.
"""
# ---------------------------------------------------------
# --- SSH VERBINDUNG ---
# ---------------------------------------------------------
print "Verbinde via SSH zu " + ROBOT_IP + "..."
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ROBOT_IP, username=ROBOT_USER, password=ROBOT_PW)
print "VERBINDUNG ERFOLGREICH!"
except Exception as e:
print "SSH Fehler: " + str(e)
sys.exit(1)
chat_history = []
# ---------------------------------------------------------
# --- FUNKTIONEN ---
# ---------------------------------------------------------
def send_ssh_command(command, wait=False):
try:
stdin, stdout, stderr = ssh.exec_command(command)
if wait:
stdout.channel.recv_exit_status()
except Exception as e:
print "Fehler beim Senden: " + str(e)
def pepper_sag(text):
if not text: return
if isinstance(text, unicode):
text = text.encode('utf-8')
clean_text = text.replace('"', '').replace("'", "")
befehl = 'qicli call ALAnimatedSpeech.say "' + TTS_CONFIG + clean_text + '"'
print "Yumi: " + clean_text
send_ssh_command(befehl, wait=True)
def pepper_leds(modus):
cmds = []
if modus == "hoeren":
# Augen & Ohren BLAU
cmds.append('qicli call ALLeds.fadeRGB "FaceLeds" "blue" 0.1')
cmds.append('qicli call ALLeds.fadeRGB "EarLeds" "blue" 0.1')
elif modus == "denken":
# Augen ROT, Ohren AUS (0)
cmds.append('qicli call ALLeds.fadeRGB "FaceLeds" "red" 0.1')
# HIER IST DER FIX: 0 statt "black"
cmds.append('qicli call ALLeds.fadeRGB "EarLeds" 0 0.1')
elif modus == "sprechen":
# Alles WEISS
cmds.append('qicli call ALLeds.fadeRGB "FaceLeds" "white" 0.1')
cmds.append('qicli call ALLeds.fadeRGB "EarLeds" "white" 0.1')
for cmd in cmds:
send_ssh_command(cmd, wait=False)
def nimm_audio_auf_pc():
sys.stdout.write("H")
sys.stdout.flush()
pepper_leds("hoeren")
p = pyaudio.PyAudio()
try:
stream = p.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
except:
stream = p.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK, input_device_index=0)
frames = []
max_volume = 0
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
rms = audioop.rms(data, 2)
if rms > max_volume:
max_volume = rms
stream.stop_stream()
stream.close()
p.terminate()
# Smart Mode Check
if max_volume < SCHWELLENWERT:
sys.stdout.write(".")
sys.stdout.flush()
# Keine LED Aenderung, einfach weiter
return None
print "\n[Lautstaerke: " + str(max_volume) + "] Sende an Google..."
pepper_leds("denken")
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
return WAVE_OUTPUT_FILENAME
def stt_google(dateipfad):
if not dateipfad: return ""
try:
with open(dateipfad, "rb") as f:
audio_data = f.read()
b64_audio = base64.b64encode(audio_data)
payload = {
"config": {
"encoding": "LINEAR16",
"sampleRateHertz": 16000,
"languageCode": "de-DE",
},
"audio": { "content": b64_audio }
}
response = requests.post(SPEECH_URL, json=payload, timeout=10)
resp_json = response.json()
if 'results' in resp_json:
return resp_json['results'][0]['alternatives'][0]['transcript']
except:
pass
return ""
def ask_gemini(history_list):
try:
payload = {
"contents": history_list,
"system_instruction": { "parts": [{"text": ROBOT_BEHAVIOR}] }
}
headers = {'Content-Type': 'application/json'}
response = requests.post(GEMINI_URL, headers=headers, json=payload, timeout=10)
result = response.json()
if 'candidates' in result and len(result['candidates']) > 0:
return result['candidates'][0]['content']['parts'][0]['text'].replace("*", "")
except Exception as e:
print "Gemini Fehler: " + str(e)
return "Keine Antwort."
# ---------------------------------------------------------
# --- HAUPTPROGRAMM ---
# ---------------------------------------------------------
pepper_leds("sprechen")
pepper_sag("Guten Tag. Ich bin Yumi. Wenn meine Augen blau leuchten, hĂśre ich dir zu. Du kannst dann 5 sekunden sprechen. dann bin ich wieder dran.")
print "\n--- START ---"
print "H = HĂśren (Aufnahme), . = Stille"
while True:
try:
# 1. HĂśren
wav_file = nimm_audio_auf_pc()
# Wenn zu leise, wav_file ist None -> Neustart
if not wav_file:
continue
# 2. Verstehen
user_text = stt_google(wav_file)
if not user_text:
print " (Nix verstanden)"
continue
print "User: " + user_text.encode('utf-8')
if "reset" in user_text.lower():
chat_history = []
pepper_sag("Gedächtnis gelÜscht.")
continue
if "ende" in user_text.lower():
pepper_sag("TschĂźss.")
break
# 3. Gemini fragen
chat_history.append({"role": "user", "parts": [{"text": user_text}]})
antwort = ask_gemini(chat_history)
chat_history.append({"role": "model", "parts": [{"text": antwort}]})
# 4. Sprechen & Bewegen
pepper_leds("sprechen")
pepper_sag(antwort)
except KeyboardInterrupt:
print "\nBeendet."
break
except Exception as e:
print "\nFehler: " + str(e)
time.sleep(1)
```
#PepperRobot #Yumi #Robotics #NaoQi #Android6 #Gemini #AI #KI #SSH #CodingGirls #TechUpdate #HumanoidRobot #WeltherrschaftInPink #PapaSan #RobotDevelopment