我目前正在用python Tornado做一个WebSocket服务器来管理我家的家庭自动化,原理如下:用户从网页发送命令(例如:打开供水),服务器接收该命令并激活连接到ESP32的继电器。
为了创建浇水时间表,我想我可以创建一个具有无限循环的线程,它查看数据库中保存的时间,我做了一个时间。睡眠的浇水时间减去当前时间,然后开始浇水。这部分是好的一切工作正常。但在那之后,我必须沟通连接的用户浇水是开着的,因此做了一个客户端。write_message(“浇水开始了”)但不幸的是,龙卷风不允许这样做。那么我怎么才能实现这样的目标呢?
在一些论坛上,人们建议用一个无限循环来一个接一个地处理命令,但这不适合我,它阻止了我的程序。
提前感谢您的回答。
class WSHandler(tornado.websocket.WebSocketHandler):
def wateringProgram():
time.sleep(secondsBeforeOnWatering) # secondsBeforeOnWatering in a db
watering.on()
for client in clients:
client.write_message('watering is on')
time.sleep(wateringDuration) # wateringDuration in a db
watering.off()
for client in clients:
client.write_message('watering is off')
threadProgram = threading.Thread(target=wateringProgram, args=())
threadProgram.start()
def open(self):
WSHandler.clients.add(self)
self.write_message('logs')
print ('[SERVEUR] Connection was opened')
def on_message(self, message):
if message == 'program changing':
threadProgram.restart() # restart with the new timing
def on_close(self):
WSHandler.clients.remove(self)
print ('[WS] Connection was closed.')
application = tornado.web.Application([
(r'/ws', WSHandler),
],**settings)
if __name__ == "__main__":
try:
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(PORT)
main_loop = tornado.ioloop.IOLoop.instance()
print ("Tornado Server started")
main_loop.start()
except:
print ("Exception triggered - Tornado Server stopped.")
以上代码经过简化,更加简洁
1条答案
按热度按时间2wnc66cl1#
我不认为你可以从龙卷风的线程发送消息。你必须调用主线程来传递消息。
首先,将当前IOLoop示例传递给
wateringProgram
函数。第二步,使用
IOLoop.add_callback
从主线程发送消息。下面是一个例子: