Я знаю, что topi c рассматривался несколько раз, однако я пытался или, по крайней мере, пробовал практически все решения, однако, будучи довольно новым python basher, я не смог получить ни одно из предыдущих решений
Основная предпосылка c сценария заключается в том, что он подписан на брокера MQTT и ожидает команд, команды одиночного действия работают на 100%, однако одна из команд требует al oop для работать бесконечно, пока не будет получена другая команда, поэтому наиболее подходящим решением было запустить «l oop» в отдельном потоке, в то время как основной подписчик l oop продолжает «слушать» следующую команду.
Все работает на 95%, команды "stati c" проходят и задачи выполняются нормально, затем, когда проходит команда "mtg", он выполняет действия с потоком, и l oop выполняется на 100%, однако это где он падает, когда получена следующая команда, я могу подтвердить, что оператор "if" обрабатывает команду, поскольку он печатает сообщение в c onsole, но thread.stop () не запущен, или он может быть запущен, но не завершает поток --- Я выдергиваю волосы, пытаясь понять это.
Некоторый код:
from sys import exit
import blinkt
import threading
import time
MQTT_SERVER = '192.168.x.x'
MQTT_PORT = 1883
MQTT_TOPIC = 'mytopic'
REDS = [0, 0, 0, 0, 0, 16, 64, 255, 64, 16, 0, 0, 0, 0, 0, 0]
start_time = time.time()
class task(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.kill = threading.Event()
self.event = threading.Event()
self._stop = threading.Event()
def run(self):
# while not self.kill.is_set():
while True:
if self.stopped():
return
self.start_run()
def stop(self):
# self.event.set()
self._stop.set()
def stopped(self):
return self._stop.isSet()
def start_run(self):
# while True: <-- no longer needed as the run method loops the process.
delta = (time.time() - start_time) * 16
offset = int(abs((delta % len(REDS)) - blinkt.NUM_PIXELS))
for i in range(blinkt.NUM_PIXELS):
blinkt.set_pixel(i, REDS[offset + i], 0, 0)
blinkt.show()
time.sleep(0.1)
def on_connect(client, userdata, flags, rc):
print('Connected with result code ' + str(rc))
client.subscribe(MQTT_TOPIC)
def on_message(client, userdata, msg):
data = msg.payload
if type(data) is bytes:
data = data.decode('utf-8')
data = data.split(',')
command = data.pop(0)
if command == 'clr' and len(data) == 0:
blinkt.clear()
blinkt.show()
t1.stop() #<--- I've tried a few ways to get the task to stop when the "clr" command is recieved
task.stop()
return
if command == 'rgb' and len(data) == 4: #<-- This code block works fine, msg arrives and LEDs are set correctly
try:
pixel = data.pop(0)
if pixel == '*':
pixel = None
else:
pixel = int(pixel)
if pixel > 7:
print('Pixel out of range: ' + str(pixel))
return
r, g, b = [int(x) & 0xff for x in data]
print(command, pixel, r, g, b)
except ValueError:
print('Malformed command: ' + str(msg.payload))
return
if pixel is None:
for x in range(blinkt.NUM_PIXELS):
blinkt.set_pixel(x, r, g, b)
else:
blinkt.set_pixel(pixel, r, g, b)
blinkt.show()
return
if command == 'mtg' and len(data) == 0:
print(command)
t1 = task()
t1.start() #<-- Here is where the Thread is called to start and seems to run ok
return
blinkt.set_clear_on_exit()
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, MQTT_PORT, 60)
client.loop_forever()