您的位置:首页 > 编程语言 > Python开发

基于邮件系统的远程实时监控系统的实现 Python版

2017-07-03 00:22 906 查看
人生苦短,我用Python~ 界内的Python宣传标语,对Python而言,这是种标榜,实际上,Python确实是当下最好用的开发语言之一。

在相继学习了C++/C#/Java之后,接触Python,最一开始突然一片茫然,似乎是进入了新世界,所有C家族的语法,在这里都或多或少地发生了改变,方法没有大括号,喜闻乐见的格式。定义变量不需要声明,时间长了,竟爱上了这个简介明了,高效快捷的语言,当然,也是当下开发语言界内的宠儿,不可否认,Python是当下最流行的开发语言了。

【前言】

本文拟使用Python开发语言实现在任何能链接上互联网的地方,远程启动在其他地方部署的监控系统,并且实时地进行图像连拍,将实时图像以邮件形式反馈到手机邮箱,达到远程实时监控的目的。

【实现功能】

这篇文章将要介绍的主要内容如下:

1、远程发送监控命令

2、监控系统做出相应,进行图像连拍(或者是录制一段视频)

3、监控系统将处理结果以邮件形式发送到移动端

【实现思路】

远程向某邮箱服务器发送一封邮件,监控系统循环检测此邮箱最新接受的邮件,通过获取并分析邮件的信息确定是否需要执行监控功能操作。如果需要,做出响应,拍照并且将拍照结果反馈回邮件发送方。

【所需技术】

1、Python语言的熟练掌握,Python版本2.7

2、利用Python语言,实现SMTP协议以及POP3协议。已达到发送邮件和接收邮件的功能。

3、正则表达式的简单使用

4、OpenCV 图像处理,图像识别,跨平台开发库的使用

5、邮箱服务器SMTP,POP3协议的开通

【实现过程】

1、实现Python发送接收邮件代码,最后封装成Email_Helper_DG类,便于后续调用,当然本文的Python_Helper_DG还没有达到更高层次的封装,毕竟要发送图片的,适当做了一些对本系统的适应。

邮件发送接受的Email_Helper_DG代码如下:

# -*- coding: UTF-8 -*-
import os
import poplib
import smtplib
from email.mime.application import MIMEApplication
from email.mime.audio import MIMEAudio
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr

class Mail_Helper_DG:
my_smtp_server = 'smtp.sina.com'  # smtp 邮件服务地址
my_pop3_server = 'pop.sina.com'  # pop3 邮件服务地址
mail_type = 'html'  # 发送的邮件的格式,HTML或者Plain
my_account = '******@example.com'  # 发件人邮箱账号
my_pwd = '******'  # 发件人邮箱密码
toAddressArray = ['xxxxx@example.com', ]  # 收件人的邮箱,可发送给多人

def __init__(self):
pass

# 发送邮件
def SendMail(self, toAddressArray, senderName, subject, content):
try:
server = smtplib.SMTP(self.my_smtp_server, 25)  # 发件人邮箱中的SMTP服务器,端口是25

try:
msg = MIMEText(content, self.mail_type, 'utf-8')
msg['From'] = formataddr([senderName, self.my_account])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
# msg['To'] = formataddr(["FK", my_account])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
msg['Subject'] = subject  # 邮件的主题,也可以说是标题

server.login(self.my_account, self.my_pwd)  # 括号中对应的是发件人邮箱账号、邮箱密码
server.sendmail(self.my_account, toAddressArray, msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
except Exception:
print(Exception)
return False
finally:
server.quit()  # 关闭连接
return True
except Exception:
print(Exception)
return False

# 发送邮件带附件
def SendMailAttachment(self, toAddressArray, senderName, subject, content, attachment_path):
try:
server = smtplib.SMTP(self.my_smtp_server, 25)  # 发件人邮箱中的SMTP服务器,端口是25

try:
server.login(self.my_account, self.my_pwd)  # 括号中对应的是发件人邮箱账号、邮箱密码

msg = MIMEMultipart()  # create MIMEMultipart
msg['From'] = formataddr([senderName, self.my_account])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
# msg['To'] = formataddr(["FK", my_account])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
msg['Subject'] = subject  # 邮件的主题,也可以说是标题
content2 = MIMEText(content,
_charset='utf-8')  # add email content  ,coding is gbk, becasue chinese exist
msg.attach(content2)
for attachment_name in os.listdir(attachment_path):
attachment_file = os.path.join(attachment_path, attachment_name)

with open(attachment_file, 'rb') as attachment:
if 'application' == 'text':
attachment = MIMEText(attachment.read(), _subtype='octet-stream', _charset='GB2312')
elif 'application' == 'image':
attachment = MIMEImage(attachment.read(), _subtype='octet-stream')
elif 'application' == 'audio':
attachment = MIMEAudio(attachment.read(), _subtype='octet-stream')
else:
attachment = MIMEApplication(attachment.read(), _subtype='octet-stream')

attachment.add_header('Content-Disposition', 'attachment', filename=('gbk', '', attachment_name))
# make sure "attachment_name is chinese" right
msg.attach(attachment)

server.sendmail(self.my_account, toAddressArray, msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
except Exception:
print(Exception)
return False
finally:
server.quit()  # 关闭连接
return True
except Exception:
print(Exception)
return

# 接收邮件
def ReceiveMail(self):
# 创建一个pop3对象,这个时候实际上已经连接上服务器了
pp = poplib.POP3(self.my_pop3_server)
# 设置调试模式,可以看到与服务器的交互信息
pp.set_debuglevel(1)
# 向服务器发送用户名
pp.user(self.my_account)
# 向服务器发送密码
pp.pass_(self.my_pwd)
# 返回邮箱的状态,返回2元祖(消息的数量,消息的总字节)
# msgCount, msgSize = pp.stat()

ret = pp.list()

mailBody = pp.retr(len(ret[1]))
# 释放pp
pp.quit()

return mailBody


2、主要业务逻辑代码,其中包含对POP3邮箱的实时监测,且对捕获到的命令进行分析判断,最后做出响应:

# -*- coding: UTF-8 -*-
import re
import time
import cv2

from Email import Mail_Helper_DG

toAddressArray = ['wd8622088@foxmail.com']  # 收件人的邮箱,可发送给多人

content = """
当前摄像头捕获的结果:
"""

# 获取当前时间
def getCurrentTime():
return str(time.strftime('’%Y-%m-%d %X’', time.localtime(time.time())))

# 程序启动标识
print('QiXiao`s SHS Starting ...')
# 初始化邮件发送类
mail = Mail_Helper_DG()

# 声明一个变量,来作为一个标记判断是否已经检测过当前这封邮件了
last_receiveMailDate = ''
# 输出显示当前扫描邮箱服务器的次数
scan_index = 0
# 设置一个循环检测邮箱的方法
while True:
time.sleep(10)  # 设置检测邮箱服务器的时间间隔
print(getCurrentTime() + ' : scan item >>> ' + str(scan_index))
scan_index += 1  # 扫描次数累加
try:
# 通过Pop3 获取到邮件的第一条
mailBody = mail.ReceiveMail()

# 解析第一条邮件,并得到发件人,主题,日期
sender = re.search("X-Sender: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)
subject = re.search("Subject: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)
date = re.search("Date: (.*?)'.", str(mailBody[1]).decode(('utf-8')), re.S).group(1)

# 判断解析到的参数值
if date != last_receiveMailDate:
# 对发送方进行邮箱判断,否则任何人都可以发送命令,你懂得
if sender == 'wd8622088@foxmail.com':
# 对命令进行分析
if subject.__contains__('qx_cmd:'):
cmd = subject.split(':')[1]
# 按cmd的命令来匹配要执行的操作:
# catch-camera 捕获摄像头的操作
if cmd == 'catch-camera':
# 载入图像,连续捕获数张图片,间隔三秒
video = cv2.VideoCapture(0)
time.sleep(3)
ret, img = video.read()
cv2.imwrite('files\\shoot_001.jpg', img)

time.sleep(3)
ret, img = video.read()
cv2.imwrite('files\\shoot_002.jpg', img)

time.sleep(3)
ret, img = video.read()
cv2.imwrite('files\\shoot_003.jpg', img)

video.release()  # 关闭摄像头
result = mail.SendMailAttachment(toAddressArray, "QiXiao",
"QiXiao`s SHS (QiXiao`s Smart Home System v1.0)", content,
"files")
if result is True:
print(getCurrentTime() + ' : send mail success !')
else:
print(getCurrentTime() + ' : send fail #')

# 让当前这条信息的日期赋值给标记变量,以便下次略过当前这条信息
last_receiveMailDate = date
except Exception:
print(getCurrentTime() + 'Error:' + Exception)


至于代码逻辑的分析,代码内部已有适当的注释进行讲解,这里不再赘述,如有任何疑问,请留言,本人进行一一回复。

【系统测试】

首先我们启动我们的服务器,让代码跑起来。

每隔一段时间,服务器就会自动请求一次POP3服务器,判断是否有新的命令输入。

然后我们在任何地点进行邮件命令的发送:这里以Ios自带的Mail来进行邮件的发送(邮件客户端无所谓,微信里的也可以)

我们首先要填写好要发送的邮箱地址,以及主题(这里是约定好的执行命令)



填写好后,点击发送。



可以看到在0:00发送了一条邮件,这就是我们刚才发送的邮件。然后打开收件箱,准备进行邮件的查收。



我们可以看到,两分钟后,服务端以邮件形式返回监控的结果。打开邮箱进行查看。





我们可以看到,摄像头正对的部位被成功捕获,并且反馈到我们发送邮件的邮箱中。

通过这样的方式,我们可以在全球任意位置,向邮箱发送邮件,只要存在网络的地方,都可以实时对任意位置部署的摄像头进行监控,实时返回监控结果。

我们打开我们的接收命令的邮箱查看一下我们接受到的邮件:



没错,是我们刚才发送的邮件。

我们程序文件目录下保存的截取图片:



至此,我们的远程监控系统已经测试完毕,可见,完美达到了预期的效果!

【系统展望】

系统虽然功能已经实现,然还有很多不尽人意之处,未来将在第二版进行改进的有:

1、系统每隔一定时间间隔自动进行拍照,然后图像分析是否有区别(有物体入侵),如果有立即发送邮件推送报警信息。

2、对图片进行人脸识别,用方框圈出人连范围,以便增加提醒。

3、系统将搭建于Raspberry Pi Linux微机系统上,并且配备摄像头全天候进行跟踪拍摄。

4、未来可能搭建web服务,在网站或者App上进行此功能的使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: