人生苦短,我用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. ZooKeeper实践:(1)配置管理

    一. 前言     配置是每个程序不可或缺的一部分,配置有多重方式:xml.ini.property.database等等,从最初的单机环境到现在的分布式环境. 1. 以文件的格式存储配置,修改任何都 ...

  2. 解决selenium驱动Firefox跳转页慢慢慢的问题

    首先我给自己定义为是一个更新偏执狂.不知道从哪个版本开始,使用selenium驱动打开Firefox浏览器时,会跳转到官网指定页,这个过程真是慢得要死. 为了解决这个问题,我是查了很多资料,解决方案是 ...

  3. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  4. 三、 添加视图View(ASP.NET MVC5 系列)

    在这一章节我们可以修改HelloWorldController类,通过使用视图模板来封装处理产生给客户端的HTML响应. 我们将使用Razor View engine来创建视图文件.基于Razor的视 ...

  5. centos7下,解决Apache错误日志文件过大问题

    1,日志文件太大问题   第一步:停止Apache服务的所有进程,删除 /var/log/httpd目录下的 error.log.access.log文件 第二步:打开 /etc/httpd/conf ...

  6. [oracle]Oracle数据库安全管理

    目录 +  1.数据库安全控制策略概述 +  2.用户管理 +  3.资源限制与口令管理 +  4.权限管理 +  5.角色管理 +  6.审计 1.数据库安全控制策略概述 安全性是评估一个数据库的重 ...

  7. 传统平面广告已OUT出局,VR全景异军突起——VR全景智慧城市

    VR,近两年异军突起的"黑科技".从1935年斯坦利·温鲍姆首次在小说中描述VR眼镜,到如今PC头盔.VR分体机以及VR一体机的相继问世,VR自身已从虚拟走向现实.而当硬件迭代逐步 ...

  8. Tips_of_JS 之 利用JS实现水仙花数的寻找与实现斐波那契数列

    一.水仙花数 1.啥是水仙花数? 水仙花数是指一个 n 位正整数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身.(例如:1^3 + 5^3+ 3^3 = 153) 2.利用JS实现对水 ...

  9. HashSet集合

    HashSet特点 1.无序,不允许重复(无序指元素顺序与添加顺序不一致,每次遍历出来的位置不是恒久不变的) 2.HashSet通过调用hashCode()和equals方法来剔除重复 3.HashS ...

  10. DOS学习札记(一)

    DOS学习入门 最近碰到几个关于cmd命令操作,感觉操作快捷方便(也许是偶尔新鲜感使然),由于重装系统后,系统的资源管理器与功能分布都有一些不同,导致在寻找一些windows功能时有些费劲,比如说关闭 ...