python - 有冷却的功能
问题描述
您好,我有一个人员检测器脚本,如果有人通过邮件检测到任何人,我想发送信息。为了防止垃圾邮件,我需要一个用于 sendMail 功能的计时器。该功能可能随时触发,但只有在其未处于冷却状态时才会响应。
我尝试使用异步任务但无法实现,因为如果有人检测到它会进入一个循环,它每 5 分钟发送一次电子邮件,即使在第一次看到后没有检测到任何人。
例子:
- 人员检测脚本正在运行。
- 在相机上检测到的人 -> 发送电子邮件(开始 5 分钟的冷却时间)
- 2 分钟后再次看到人(没有发送任何电子邮件,因为还有 3 分钟的冷却时间)。
- 6 分钟后发现的人发送另一封电子邮件(因为 5 分钟的冷却时间已经结束)。
我的代码摘要。(仅检测和发送邮件的必要部分工作冷却(计时器)不起作用
async def sendAlert():
server.sendmail(sender_email, receiver_email, message)
print('sent!')
await asyncio.sleep(300)
if __name__ == "__main__":
while True:
for i in range(len(boxes)):
if classes[i] == 1 and scores[i] > threshold:
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
sendAlert(server)
box = boxes[i]
cv2.rectangle(img,(box[1],box[0]),(box[3],box[2]),(255,0,0),2)
如果检测到人,脚本将通过电子邮件发送警报。之后,如果在 5 分钟内再次检测到人,则 sendAlert 函数不应该响应,直到 5 分钟过去
解决方案
我同意@Prune 的观点,即您需要创建一个小(最小)用例并展示您的代码,以便它不仅与您相关,而且与其他人相关。此外,您的问题应该有一个带有可验证示例的部分。如果没有这些属性,您的问题将变得难以让人们掌握、解决和/或提出任何可验证的解决方案。
但是,据我了解,您有一些想要在cool-off
一段时间后执行的操作(如果检测到一个人,则发送电子邮件)。因此,换句话说,您需要一种跟踪时间的机制。因此,您将需要该datetime
库。
因此,您的伪代码应如下所示:
伪代码
import datetime
start = capture_timestamp()
cutoff = '00:05:00'
dt_cutoff = read_in_cutoff_as_timedelta(cutoff)
if person_detected:
now = capture_timestamp()
dt = now - start
if dt >= dt_cutoff:
# Send notification
send_email_notification()
else:
# Do not Send Notification
print('now: {} | dt: {}'.format(now, dt))
您可以使用datetime.datetime.utcnow()
时间戳。并datetime.timedelta()
用于定义dt_cutoff
. 要在时间字符串中读取时间,您可以这样做:
tm = datetime.datetime.strptime(cutoff).time()
dt_cutoff = datetime.timedelta(hours = tm.hour, minutes = tm.minute, seconds = tm.second)
我希望这能给你一些关于如何建模的想法。
其他资源
- https://www.guru99.com/date-time-and-datetime-classes-in-python.html
- https://docs.python.org/3/library/datetime.html
- https://thispointer.com/python-how-to-convert-a-timestamp-string-to-a-datetime-object-using-datetime-strptime/
完整的解决方案
现在,最后,如果您急于使用现成的解决方案,您可以使用如下所示的类对象。您所需要的只是通过指定您的冷却期 ( timer_cutoff
) 来实例化类对象,然后调用方法is_timeout()
。如果返回True
,则您发送通知。还有一个obj.istimeout
存储这个决定的属性(True
/ False
)。
import time
# Set cutoff time to 2 seconds to test the output
# after 5 seconds: expect istimeout = True
# and instantiate the TimeTracker class object.
ttk = TimeTracker(timer_cutoff = '00:00:02') # 'HH:MM:SS'
# Wait for 3 seconds
time.sleep(3)
print('start timestamp: {}'.format(ttk.timestamp_start_str))
print('cutoff timestamp'.format(ttk.timestamp_cutoff_str))
print('timer_cutoff: {}'.format(ttk.timer_cutoff_str))
# Now check if cutoff time reached
ttk.is_timeout()
print('Send Notification: {}'.format(ttk.istimeout))
print('now_timestamp: {}'.format(ttk.timestamp_now_str))
类时间跟踪器
这是TimeTracker
班级:
import datetime
class TimeTracker(object):
def __init__(self,
timer_cutoff = '00:05:00',
cutoff_strformat = '%H:%M:%S'):
self.timer_cutoff_str = timer_cutoff
self.cutoff_strformat = cutoff_strformat
self.timestamp_start, self.timestamp_start_str = self.get_timestamp()
self.dt_cutoff = None # timedelta for cutoff
self.timestamp_cutoff = None
self.timestamp_cutoff_str = None
self.update_timestamp_cutoff()
self.timestamp_now = None
self.timestamp_now_str = None
self.dt_elapsed = None
self.istimeout = False
def get_timestamp(self):
ts = datetime.datetime.utcnow()
tss = str(ts)
return (ts, tss)
def readin_cutoff_as_timedelta(self):
td = datetime.datetime.strptime(self.timer_cutoff_str,
self.cutoff_strformat)
tdm = td.time()
self.dt_cutoff = datetime.timedelta(hours = tdm.hour,
minutes = tdm.minute,
seconds = tdm.second)
def update_timestamp_cutoff(self):
self.readin_cutoff_as_timedelta()
self.timestamp_cutoff = self.timestamp_start + self.dt_cutoff
self.timestamp_cutoff_str = str(self.timestamp_cutoff)
def time_elapsed(self):
self.dt_elapsed = self.timestamp_now - self.timestamp_start
def is_timeout(self):
self.timestamp_now, self.timestamp_now_str = self.get_timestamp()
self.time_elapsed()
if (self.dt_elapsed < self.dt_cutoff):
self.istimeout = False
else:
self.istimeout = True
return self.istimeout
推荐阅读
- reactjs - 使用 FB.ui() 对话框共享
- javascript - 具有接口类类型的泛型
- r - 如何在不排序键的情况下将 JSON 转换为 R 中的数据框
- java - 使用来自 Java 的 PHP 评估 PHP 脚本
- maven-3 - Jcoco exce 检查目标错误 - 分析了 0 个类的捆绑包“jacoco-merge”
- java - java.lang.NoClassDefFoundError:解析失败:Ljava/time/format/DateTimeFormatter
- javascript - 如何使用Django中的按钮对表格列进行排序
- javascript - 表单提交 isset 不起作用,当我单击按钮时,它总是说大声笑而不是说工作
- outlook - OneNote 加载项在 Outlook 中灰显
- visual-studio-code - VSCode 扩展贡献下拉菜单