93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
openWakeWord to MQTT publisher
|
|
Publishes wake word detections to Home Assistant MQTT broker
|
|
"""
|
|
|
|
import time
|
|
import json
|
|
import paho.mqtt.client as mqtt
|
|
import openwakeword
|
|
from openwakeword.model import Model
|
|
import numpy as np
|
|
import sounddevice as sd
|
|
|
|
# MQTT Configuration
|
|
MQTT_HOST = "192.168.0.39" # Home Assistant IP
|
|
MQTT_PORT = 1883
|
|
MQTT_USER = "your_mqtt_username" # Replace with your MQTT username
|
|
MQTT_PASS = "your_mqtt_password" # Replace with your MQTT password
|
|
MQTT_TOPIC = "homeassistant/openwakeword/detection"
|
|
|
|
# Wake word detection threshold (0.0 - 1.0)
|
|
THRESHOLD = 0.5
|
|
|
|
# Audio settings
|
|
CHUNK_SIZE = 1600 # 100ms of audio @ 16kHz
|
|
|
|
def on_connect(client, userdata, flags, rc):
|
|
if rc == 0:
|
|
print(f"Connected to MQTT broker at {MQTT_HOST}")
|
|
else:
|
|
print(f"Failed to connect, return code {rc}")
|
|
|
|
def publish_detection(wake_word, confidence):
|
|
payload = json.dumps({
|
|
"wake_word": wake_word,
|
|
"confidence": float(confidence),
|
|
"timestamp": time.time()
|
|
})
|
|
client.publish(MQTT_TOPIC, payload)
|
|
print(f"Published: {wake_word} ({confidence:.2f})")
|
|
|
|
def main():
|
|
global client
|
|
|
|
# Initialize MQTT client
|
|
client = mqtt.Client(client_id="openwakeword")
|
|
client.username_pw_set(MQTT_USER, MQTT_PASS)
|
|
client.on_connect = on_connect
|
|
client.connect(MQTT_HOST, MQTT_PORT, 60)
|
|
client.loop_start()
|
|
|
|
# Initialize openwakeword model
|
|
print("Loading openwakeword models...")
|
|
oww_model = Model()
|
|
|
|
# Get audio stream (adjust for your microphone)
|
|
# Using sounddevice for microphone input
|
|
import sounddevice as sd
|
|
|
|
def audio_callback(indata, frames, time, status):
|
|
if status:
|
|
print(status)
|
|
# Process audio for wake word detection
|
|
audio_data = indata.flatten()
|
|
predictions = oww_model.predict(audio_data)
|
|
|
|
# Check for detections
|
|
for wake_word, score in predictions.items():
|
|
if score >= THRESHOLD:
|
|
publish_detection(wake_word, score)
|
|
|
|
print("Listening for wake words...")
|
|
print("Press Ctrl+C to stop")
|
|
|
|
# Start streaming from microphone
|
|
with sd.InputStream(
|
|
channels=1,
|
|
samplerate=16000,
|
|
dtype='int16',
|
|
blocksize=CHUNK_SIZE,
|
|
callback=audio_callback
|
|
):
|
|
try:
|
|
while True:
|
|
time.sleep(0.1)
|
|
except KeyboardInterrupt:
|
|
print("\nStopping...")
|
|
client.loop_stop()
|
|
client.disconnect()
|
|
|
|
if __name__ == "__main__":
|
|
main() |