我需要运行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()
答案 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();
}