人生苦短,我用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上进行此功能的使用

基于邮件系统的远程实时监控系统的实现 Python版的更多相关文章

  1. 基于Android的远程视频监控系统(含源码)

    基本过程是android作为socket客户端将采集到的每一帧图像数据发送出去,PC作为服务器接收并显示每一帧图像实现远程监控.图片如下(后来PC端加了个拍照功能)... (PS.刚学android和 ...

  2. 项目-基于视频压缩的实时监控系统--tiny6410

    项目-基于视频压缩的实时监控系统--tiny6410 @国嵌linux学习笔记. 1. 构造服务端结构体 server struct server { int epfd; //保存epoll指针 st ...

  3. 如何利用SimpleNVR建立全天候远程视频监控系统

    随着社会经济的发展,5G.AI.云计算.大数据.物联网等新兴技术迭代更新的驱动下,传统的安防监控早已无法满足我们的需求.那么我们如何建立全天候远程视频监控系统来替代传统监控呢?如何进一步优化城市管理. ...

  4. 转: 透过CAT,来看分布式实时监控系统的设计与实现

    评注: 开源的分布式监控系统 转:http://www.infoq.com/cn/articles/distributed-real-time-monitoring-and-control-syste ...

  5. 透过CAT,来看分布式实时监控系统的设计与实现

    2011年底,我加入大众点评网,出于很偶然的机会,决定开发CAT,为各个业务线打造分布式实时监控系统,CAT的核心概念源自eBay闭源系统CAL----eBay的几大法宝之一. 在当今互联网时代,业务 ...

  6. Telegraf+InfluxDB+Grafana快速搭建实时监控系统 监控postgresql

    Telegraf+InfluxDB+Grafana快速搭建实时监控系统  监控postgresql

  7. python3 主机实时监控系统

    主机实时监控系统(可在局域网访问) 一.思路: 前端: 1.管理员登录(编写一个管理员登录界面) 技术:html+css 2.资源数据显示(用于显示主机资源数据情况) 插件:echarts+jquer ...

  8. 【数量技术宅 | Python爬虫系列分享】实时监控股市重大公告的Python爬虫

    实时监控股市重大公告的Python爬虫小技巧 精力有限的我们,如何更加有效率地监控信息? 很多时候特别是交易时,我们需要想办法监控一些信息,比如股市的公告.如果现有的软件没有办法实现我们的需求,那么就 ...

  9. 【转】点评cat高可用实时监控系统

    CAT总体介绍CAT(Central Application Tracking)是由吴其敏(前大众点评首席架构师,现携程架构负责人)主导设计基于Java开发打造的实时应用监控平台,为大众点评网提供了全 ...

随机推荐

  1. nginx+gridfs+mongodb 配置访问png图片显示无法加载问题

    上传文件后,浏览器中请求:http://<nginx server ip>:<port>/gfs/<my file> 浏览器出现"无法打开页面" ...

  2. java企业架构 spring mvc +mybatis + KafKa+Flume+Zookeeper

    声明:该框架面向企业,是大型互联网分布式企业架构,后期会介绍linux上部署高可用集群项目. 项目基础功能截图(自提供了最小部分)      平台简介        Jeesz是一个分布式的框架,提供 ...

  3. UGUI ScrollRect 性能优化

    测试环境 操作系统:Windows8.1 开发工具:Unity5.5.2 1.问题描述,在实际开发过程中经常会使用ScrollRect实现滚动列表,当初次加载数据比较多的情形时,Unity3D会出现比 ...

  4. 【踩坑】360安全浏览器“极速模式”和“兼容模式”,套路还是bug?

    分享踩坑点: 项目中需要兼容360安全浏览器,大家当然都希望用极速模式打开网站,但是发现总是被兼容模式打开 网址类似 aa.xx.dd.com 网上找了很多地方,有以下两种方法 1.<meta ...

  5. apply/call/bind和this的使用

    fun.apply(context,[argsArray]) 立即调用fun,同时将fun函数原来的this指向传入的新context对象,实现同一个方法在不同对象上重复使用. context:传入的 ...

  6. 微服务框架下的思维变化-OSS.Core基础思路

    如今框架两字已经烂大街了,xx公司架构设计随处可见,不过大多看个热闹,这些框架如何来的,细节又是如何思考的,相互之间的隔离依据又是什么...相信很多朋友应该依然存在自己的疑惑,特别是越来越火热的微服务 ...

  7. 7.java 加解密技术系列之 AES

    java 加解密技术系列之 AES 序 概念 原理 应用 代码实现 结束语 序 这篇文章继续介绍对称加密算法,至于今天的主角,不用说,也是个厉害的角色 — — AES.AES 的出现,就是为了来替代原 ...

  8. 第 16 章 MySQL Cluster

    前言: MySQL Cluster 是一个基于 NDB Cluster 存储引擎的完整的分布式数据库系统.不仅仅具有高可用性,而且可以自动切分数据,冗余数据等高级功能.和 Oracle Real Cl ...

  9. R笔记(1):formula和Formula

    #####开一个新的系列.关于R的一些笔记,就是遇到过的一些问题的简单整理.可能很基本,也可能没什么大的用处,作为一个记录而已.------------------------------------ ...

  10. Vulkan Tutorial 05 逻辑设备与队列

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 在选择要使用的物理设备之后,我们需要设置一个逻辑设备用于交 ...