2016-04-08 2 views
-1

Ich habe 2 Schleifen, die ich ausführen muss, eins für Sprachbefehle zu hören und das andere, um mit einem MQTT-Broker verbunden zu bleiben und nach/nach einem MQTT-Thema zu warten, wenn ein Sprachbefehl ausgegeben wird. Problem ist, ich bin mir nicht sicher über die beste Möglichkeit, dies einzurichten. Wie würde ich diese beiden Runs einrichten, wenn MQTT auf einen Sprachbefehl wartet, um Funktionen auszuführen/wo würde ich anfangen, nach der Lösung zu suchen? Klassen? Multithreading? Nicht wirklich sicher, wo ich anfangen soll.Lassen Sie 2 Schleifen gleichzeitig laufen, dass der Anruf von einander funktioniert?

Auch - Randnotiz - diese Spracherkennung (PocketSphinx) ist absolut schrecklich. Es nimmt vielleicht 5% der Zeit an/aus und gibt alle Arten von zufälliger Antwort zu jeder anderen Zeit. Bonus-Punkte, wenn Sie mich in die richtige Richtung weisen können, um das zu beheben, indem Sie ein besseres Modul oder eine mögliche Kodierung von Taschensphinx verwenden (ich habe mich bereits für einen Google Cloud-Speech API-Schlüssel angemeldet, ihn aber noch nicht erhalten) .

Hier ist der Code

voice.py:

import pyaudio, os 
import mqttPublisher 
import speech_recognition as sr 

def mainfunction(source): 
    audio = r.listen(source) 
    user = r.recognize_sphinx(audio) 
    print(user) 
    if user == 'on': 
     mqttPublisher.led_on() 
    elif user == 'off': 
     mqttPublisher.led_off() 

if __name__ == '__main__': 
    r = sr.Recognizer() 
    with sr.Microphone() as source: 
     while 1: 
      mainfunction(source) 

mqttPublisher.py:

import paho.mqtt.client as mqtt 

def led_on(): 
    mqttc.publish("IoT/LED", payload="1") 
    print("LED is ON") 

def led_off(): 
    mqttc.publish("IoT/LED", payload="2") 
    print("LED is OFF") 

def get_status(): 
    mqttc.publish("IoT/LED", payload="3") 

def on_connect(client, userdata, flags, rc): 
    mqttc.publish("IoT/LED", "connected") 
    print("connected") 

def on_subscribe(client, userdata, mid, granted_qos): 
    mqttc.publish("IoT/LED", payload="3") 
    print("subscribed") 

def on_publish(client, userdata, mid): 
    print("message published") 

def on_message(client, userdata, message): 
    print("message printed to topic") 

def on_disconnect(client, userdata, rc): 
    print("Client Disconnected") 

mqttc = mqtt.Client() 
mqttc.on_connect = on_connect 
mqttc.on_subscribe = on_subscribe 
mqttc.on_message = on_message 
mqttc.on_publish = on_publish 
mqttc.on_disconnect = on_disconnect 

mqttc.connect("192.168.1.3", 1883) 
mqttc.subscribe("IoT/LED", 1) 

run = True 
while run: 
    mqttc.loop_start() 
+1

Führen Sie die Schleifen auf separaten Threads – hardillb

+0

Es klingt für mich, dass Coroutines sind, was Sie implementieren möchten. – AndyG

Antwort

-1

Per hardillb Vorschlag, ich recherchiert Einfädeln und einige Fragen gefunden, die das Problem mit Klassen gelöst . Die Antworten, die ich verwendet, um meine Lösung zu kommen sind hier:

Running infinite loops using threads in python

Thread issue while subscribing to MQTT in Python using Paho MQTT

Unterhalb der fertige Code ist wie erwartet funktioniert. Er startet das Sprachmodul und den Mqtt-Client, wartet auf Ja/Nein (das sind die einzigen konsistenten Wörter, die das Sprachmodul erkennen kann ...) und schaltet meine Aruidno-LED ein/aus, wenn sie die entsprechenden Befehle empfängt. Für diejenigen, die interessiert sind, werde ich auch den Arduino-Code einschließen. Die IP-Adresse 192.168.1.2 zeigt auf meinen Raspberry Pi, auf dem ein Mosquitto-Broker läuft, der die MQTT-Themen behandelt.

voice.py:

import pyaudio, os 
from mqttPublisher import MqttHandler 
import speech_recognition as sr 
from threading import Thread 

class Amy(Thread): 
    def mainfunction(self, source): 
     audio = self.r.listen(source) 
     user = self.r.recognize_sphinx(audio) 
     print(user) 
     if user == 'yes': 
      mqtt.led_on() 
     elif user == 'no': 
      mqtt.led_off() 
     elif user == 'get': 
      mqtt.get_status() 

    def __init__(self): 
     Thread.__init__(self) 
     self.daemon = True 
     self.start() 

    def run(self): 
     self.r = sr.Recognizer() 
     with sr.Microphone() as source: 
      while True: 
       self.mainfunction(source) 

amy = Amy() 
mqtt = MqttHandler() 

amy 
mqtt 

while True: 
    pass 

mqttPublisher.py:

import paho.mqtt.client as mqtt 
from threading import Thread 

class MqttHandler(Thread): 

    client = mqtt.Client() 

    def __init__(self): 
     Thread.__init__(self) 
     self.daemon = True 
     self.start() 

     self.client.on_connect = self.on_connect 
     self.client.on_subscribe = self.on_subscribe 
     self.client.on_message = self.on_message 
     self.client.on_publish = self.on_publish 
     self.client.on_disconnect = self.on_disconnect 
     self.client.led_on = self.led_on 
     self.client.led_off = self.led_off 
     self.client.get_status = self.get_status 

     self.client.connect("192.168.1.2", 1883) 
     self.client.subscribe("IoT/LED", 1) 

    def run(self): 
     while True: 
      self.client.loop() 

    def led_on(self): 
     self.client.publish("IoT/LED", payload="1") 
     print("LED is ON") 

    def led_off(self): 
     self.client.publish("IoT/LED", payload="2") 
     print("LED is OFF") 

    def get_status(self): 
     self.client.publish("IoT/LED", payload="3") 

    def on_connect(self, client, userdata, flags, rc): 
     self.client.publish("IoT/LED", "connected") 
     print("connected") 

    def on_subscribe(self, client, userdata, mid, granted_qos): 
     self.client.publish("IoT/LED", payload="3") 
     print("subscribed") 

    def on_publish(self, client, userdata, mid): 
     print("message published") 

    def on_message(self, client, userdata, message): 
     print("message printed to topic") 

    def on_disconnect(self, client, userdata, rc): 
     print("Client Disconnected") 

Arduino Code:

#include <PubSubClient.h> 
#include <Ethernet.h> 
#include <SPI.h> 

byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xEF }; 
byte ip[] = { 192, 168, 1, 6 }; 
byte localserver[] = { 192, 168, 1, 2 }; 

const char clientID[8] = "Arduino"; 
const char topicName[8] = "IoT/LED"; 
const char on[3] = "On"; 
const char off[4] = "Off"; 
const int led = 9; 

int status; 

EthernetClient ethClient; 
PubSubClient client(localserver, 1883, callback, ethClient); 

void callback(char* topic, byte* payload, unsigned int length) { 
    int load = atoi ((const char*) payload); 
    if (load != 0) { 
    Serial.print("\n"); 
    Serial.print("Payload= "); 
    Serial.println(load); 
    switch(load) { 
     case 1: 
     digitalWrite(led, HIGH); 
     client.publish(topicName, on); 
     Serial.print("Light turned on"); 
     break; 
     case 2: 
     digitalWrite(led, LOW); 
     client.publish(topicName, off); 
     Serial.print("Light turned off"); 
     break; 
     case 3: 
     status = digitalRead(led); 
     if (status == 0) { 
      client.publish(topicName, off); 
      Serial.print("Light status: "); 
      Serial.println(off); 
      break; 
     } 
     else if (status == 1) { 
      client.publish(topicName, on); 
      Serial.print("Light status: "); 
      Serial.println(on); 
      break; 
     } 
     default: 
     break; 
    } 
    } 
} 

void setup() { 
    Serial.begin(9600); 
    pinMode(led, OUTPUT); 
    Ethernet.begin(mac, ip); 

    if (!client.connected()) { 
    Serial. print("Trying to connect..."); 
    client.connect(clientID); 
    } 
    if (client.connected()) { 
    Serial.print("Connected"); 
    client.subscribe(topicName); 
    } 
} 

void loop() { 
    client.loop(); 
} 
1

paho.mqtt.client.loop_start() startet einen Thread für Sie seine Netzwerkschleife zu behandeln. Ruf es einfach an und es sollte dir gut gehen.

Verwandte Themen