同时运行2个循环,相互调用函数?

时间:2016-04-08 10:58:17

标签: python mqtt pocketsphinx

我需要运行2个循环,一个用于侦听语音命令,另一个用于保持连接到MQTT代理并监听/发布到MQTT主题,在发出语音命令时发布。问题是,我不确定设置它的最佳方法。如何将这些设置为同时运行,MQTT等待语音命令执行功能/我将在哪里开始研究解决方案?类?多线程?不确定从哪里开始。

另外 - 旁注 - 这种语音识别(pocketsphinx)绝对可怕。它可以在5%的时间内开启/关闭,每隔一段时间提供各种随机响应。如果你可以通过使用更好的模块或可能的编码pocketphinx更准确(我已经注册了Google Cloud-Speech API密钥但尚未收到),我可以指出正确的方向来解决问题它)。

这是代码

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()

2 个答案:

答案 0 :(得分:1)

paho.mqtt.client.loop_start()启动一个线程来为您处理其网络循环。只需打电话一次就可以了。

答案 1 :(得分:0)

根据hardillb的建议,我研究了线程并发现了一些解决了类问题的问题。我以前来到我的解决方案的答案在这里:

Running infinite loops using threads in python

Thread issue while subscribing to MQTT in Python using Paho MQTT

以下是完成的代码按预期工作。它启动语音模块和Mqtt客户端,等待是/否(这是我可以让语音模块识别的唯一一致的单词......)并在收到适当的命令时打开/关闭我的Aruidno LED。对于那些感兴趣的人,我也会包含Arduino代码。 IP地址192.168.1.2指向我的Raspberry Pi,它运行一个Mosquitto代理来处理MQTT主题。

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代码:

#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();
}