我正在使用Azure IoT中心,Python中的Azure IoT SDK和带有温度和湿度传感器的树莓派进行遥测应用程序。
湿度+温度传感器=> Rasperry Pi => Azure IoT中心
在我的第一个实现中,通过azure示例,我使用了一个循环,该循环从温度传感器和湿度传感器收集数据,并每60秒一次将它们发送到Azure IoT中心。
>>> 1 Loop every 60s = Collect data & send data of temperature and humidity
现在我想以不同的频率发送它们,我的意思是: 一个循环将每60秒收集一次温度传感器的数据并将其发送到Azure IoT中心; 而第二个循环将每隔600秒收集一次湿度传感器的数据并将其发送到Azure IoT中心。
>>> 1 Loop every 60s= Collect data & send data of temperature
>>> 2 Loop every 600s= Collect data & send data of humidity
我认为我需要的工具是多线程,但是我不了解我必须实现哪种库或结构。
这是Azure提供的代码,其中包括一个同时处理温度和湿度的循环。每60秒读取一次数据并发送到Azure。
import random
import time
import sys
# Using the Python Device SDK for IoT Hub:
from iothub_client import IoTHubClient, IoTHubClientError,
IoTHubTransportProvider, IoTHubClientResult
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult,
IoTHubError, DeviceMethodReturnValue
# The device connection string to authenticate the device with your IoT hub.
CONNECTION_STRING = "{Your IoT hub device connection string}"
# Using the MQTT protocol.
PROTOCOL = IoTHubTransportProvider.MQTT
MESSAGE_TIMEOUT = 10000
# Define the JSON message to send to IoT Hub.
TEMPERATURE = 20.0
HUMIDITY = 60
MSG_TXT = "{\"temperature\": %.2f,\"humidity\": %.2f}"
def send_confirmation_callback(message, result, user_context):
print ( "IoT Hub responded to message with status: %s" % (result) )
def iothub_client_init():
# Create an IoT Hub client
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
return client
def iothub_client_telemetry_sample_run():
try:
client = iothub_client_init()
print ( "IoT Hub device sending periodic messages, press Ctrl-C to exit" )
#******************LOOP*******************************
while True:
# Build the message with simulated telemetry values.
temperature = TEMPERATURE + (random.random() * 15)
humidity = HUMIDITY + (random.random() * 20)
msg_txt_formatted = MSG_TXT % (temperature, humidity)
message = IoTHubMessage(msg_txt_formatted)
# Send the message.
print( "Sending message: %s" % message.get_string() )
client.send_event_async(message, send_confirmation_callback, None)
time.sleep(60)
except IoTHubError as iothub_error:
print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )
if __name__ == '__main__':
print ( "IoT Hub Quickstart #1 - Simulated device" )
print ( "Press Ctrl-C to exit" )
iothub_client_telemetry_sample_run()
我想使用相同的功能结构,包括两个处理温度和湿度的循环,每60s循环一次,每600s循环一次。
while True:
# Build the message with simulated telemetry values.
temperature = TEMPERATURE + (random.random() * 15)
msg_txt_formatted1 = MSG_TXT1 % (temperature)
message1 = IoTHubMessage(msg_txt_formatted1)
# Send the message.
print( "Sending message: %s" % message1.get_string() )
client.send_event_async(message1, send_confirmation_callback, None)
time.sleep(60)
while True:
# Build the message with simulated telemetry values.
humidity = HUMIDITY + (random.random() * 20)
msg_txt_formatted2 = MSG_TXT2 % (humidity)
message2 = IoTHubMessage(msg_txt_formatted2)
# Send the message.
print( "Sending message: %s" % message2.get_string() )
client.send_event_async(message2, send_confirmation_callback, None)
time.sleep(600)
我该怎么做?如何使用多线程或其他方法调用这些循环?
答案 0 :(得分:0)
做类似的事情可能更简单
while True:
loop_b()
for _ in range(10):
loop_a()
time.sleep(60)
甚至
while True:
time.sleep(1)
now = time.time()
if now % 60 == 0:
loop_a()
if now % 600 == 0:
loop_b()
但是,如果您真的想使用线程,那么:
import threading
class LoopAThread(threading.Thread):
def run(self):
loop_a()
class LoopBThread(threading.Thread):
def run(self):
loop_b()
...
thread_a = LoopAThread()
thread_b = LoopBThread()
thread_a.start()
thread_b.start()
thread_a.join()
thread_b.join()
答案 1 :(得分:0)
这里有两种相互竞争的方法可供考虑
根本不用理会线程。像现在一样,每60秒钟休眠一次。跟踪上次发送湿度数据的时间。如果经过600秒,则发送它。否则,请跳过它并入睡60秒钟。像这样:
# load packages
library(data.table)
library(lubridate)
# define a vector evenly spaced each 30 minutes:
b <- data.table(dates = seq(as.POSIXct("2018-03-25", tz = "UTC"),
as.POSIXct("2018-03-26", tz = "UTC"),
by = "30 min"))
# reproduce data
dt <- data.table(detect_date = as.character(c("25/03/2018 00:09", "25/03/2018 01:17", "25/03/2016 14:37", "25/03/2016 23:43")),
Station = c("SS01", "SS03", "SS04", "SS04"),
Individual = c("A", "B", "C", "B"))
# convert detect_date to date format
dt[, detect_date := dmy_hm(detect_date)]
# make a join
dt[, .(Location = Station, Individual), by = .(dates = floor_date(detect_date, "30 minutes"))][b, on = "dates"]
将from datetime import datetime, timedelta
def iothub_client_telemetry_sample_run():
last_humidity_run = None
humidity_period = timedelta(seconds=600)
client = iothub_client_init()
while True:
now = datetime.now()
send_temperature_data(client)
if not last_humidity_run or now - last_humidity_run >= humidity_period:
send_humidity_data(client)
last_humidity_run = now
time.sleep(60)
重命名为iothub_client_telemetry_sample_run
或类似的名称。创建一个单独的功能,看起来就像湿度一样。从程序的主要功能中产生两个线程。将它们设置为守护程序模式,以便在用户退出时关闭
temperature_thread_func
注释:
from threading import Thread
def temperature_thread_func():
client = iothub_client_init()
while True:
send_temperature_data(client)
time.sleep(60)
def humidity_thread_func():
client = iothub_client_init()
while True:
send_humidity_data(client)
time.sleep(600)
if __name__ == '__main__':
temp_thread = Thread(target=temperature_thread_func)
temp_thread.daemon = True
humidity_thread = Thread(target=humidity_thread_func)
humidity_thread.daemon = True
input('Polling for data. Press a key to exit')
不是一种精确的保留方法
时间。如果样本需要,您可能需要不同的计时机制
在精确的时刻拍摄。