利用python的snap7读取S7-1200PLC的数据,保存并定时发送到邮箱中
本文介绍了如何利用Python读取西门子S7-1200 PLC的生产数据,并实现定时发送报表到指定邮箱的功能。通过snap7库读取PLC中的合格数和不合格数数据,保存为Excel文件后,使用SMTP协议自动发送邮件。系统设置为每天早上8点自动执行,可部署为长期运行的监控程序。该方案实现了生产数据的可视化监控和自动化报表发送,提高了质量管理效率。完整代码已开源在Gitee平台。
·
文章目录
前言
为了方便监控产品合格数量和不合格数量,本文利用python读取S7-1200中数据,并定时发送到客户邮箱中。完整代码可见于笔者gitee.
一、西门子S7-1200的PLC数据如何读取?
问了ai,回答说是用snap7库可以读取。下面来尝试一下。
1.网线连接到PLC
电脑通过网线连接到PLC,并修改电脑IP,与PLC同网段。修改之后,ping能通过,说明连接成功:
2.python运行环境
笔者使用anaconda prompt新建data_sender虚拟环境(python3.9),后续程序运行在data_sender下。需要安装必要的包。
3.使用snap7读取PLC数据
具体代码如下。由于笔者第一次尝试连接PLC,不懂PLC的内存机制,此处读取DB块,要按照2块的固定大小读取,不能直接读取4块或者8块。
import snap7
# 读取plc数据,返回:合格数和不合格数
def read_plc():
# PLC IP地址
ip = '192.168.3.120'
# 创建PLC客户端
plc = snap7.client.Client()
# 连接PLC
plc.connect(ip, 0, 1)
# 指定要读取的DB块编号、起始地址和大小
db_number = 1
# 读取数据
# 读取第一个 16 位变量(MW100)
data1 = plc.db_read(db_number, 0, 2)
value1 = int.from_bytes(data1, byteorder='big', signed=True)
# 读取第二个 16 位变量(MW102)
data2 = plc.db_read(db_number, 2, 2)
value2 = int.from_bytes(data2, byteorder='big', signed=True)
# 打印结果
print(f"变量1 (MW0): {value1}")#合格数
print(f"变量2 (MW2): {value2}")#不合格数
# 断开与PLC的连接
plc.disconnect()
return value1, value2
二、数据保存到本地excel表中,并定时发送到邮箱
其中用到的邮箱授权码’sender_password’,可以自行查询并申请。
代码如下(示例):
import pandas as pd
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
import os
import schedule
import time
from datetime import datetime
from fun2 import read_plc
# 邮箱配置
email_config = {
'smtp_server': 'smtp.qq.com',
'smtp_port': 465,
'sender_email': '@qq.com',
'sender_password': '',
'receiver_email': '@qq.com'
}
# Excel 文件路径
excel_file_path = 'output_data.xlsx'
def fetch_data_and_save_to_excel():
try:
# 从PLC获取数据
value1, value2 = read_plc()
# 获取今天的日期
today = datetime.today().date()
data = {
'日期': [today],
'合格数': [value1],
'不合格数': [value2]
}
df = pd.DataFrame(data)
# 保存到Excel文件中
df.to_excel(excel_file_path, index=False)
print(f"Data saved to {excel_file_path}")
# 发送邮件
send_email_with_attachment()
except Exception as e:
print("Error:", str(e))
def send_email_with_attachment():
msg = MIMEMultipart()
msg['From'] = email_config['sender_email']
msg['To'] = email_config['receiver_email']
msg['Subject'] = '数据报表 - Excel附件'
body = '这是您的数据库报表,请查收附件。'
msg.attach(MIMEText(body, 'plain'))
# 添加附件
try:
with open(excel_file_path, 'rb') as attachment:
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
f'attachment; filename="{os.path.basename(excel_file_path)}"'
)
msg.attach(part)
# 使用 SMTP_SSL 发送邮件(QQ邮箱465端口需要SSL)
server = smtplib.SMTP_SSL(email_config['smtp_server'], email_config['smtp_port'])
server.login(email_config['sender_email'], email_config['sender_password'])
server.sendmail(email_config['sender_email'], email_config['receiver_email'], msg.as_string())
print("Email sent successfully")
except Exception as e:
print("Failed to send email:", str(e))
finally:
try:
server.quit()
except:
pass # 如果server未定义,忽略关闭操作
if __name__ == '__main__':
# 先执行一次
try:
fetch_data_and_save_to_excel()
except Exception as e:
print("Initial run failed:", e)
exit(1)
# 定时任务设置(每天早上8点执行)
schedule.every().day.at("08:00").do(fetch_data_and_save_to_excel)
print("Starting scheduler...")
while True:
schedule.run_pending()
time.sleep(60)
总结
需要包装成exe文件,方便部署在目标机器上。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)