采集
import threading # 导入多线程模块
import requests # 导入处理HTTP请求的模块
import json # 导入处理JSON数据的模块
import datetime # 导入处理日期和时间的模块
import snap7 # 导入snap7库
from snap7.util import * # 导入snap7工具模块
from .my_static import * # 导入自定义的静态数据
def conn(plc_ip, dbNr):
# 连接到PLC
plc = snap7.client.Client()
plc.connect(plc_ip, 0, 2)
# 读取指定DB块的数据
db = plc.db_read(dbNr, 0, 4)
return plc, db
def read_bool(db, by, bo):
# 读取指定DB块的布尔值
value = get_bool(db, by, bo)
return value
def read_int(db, fr, to):
# 读取指定DB块的整数值
v = db[fr:to]
v1 = int.from_bytes(v, byteorder='big', signed=True)
if v1 < 0:
v1 += 65536
v2 = hex(v1)
v3 = v2.split('x')[1].zfill(4)
return v3
def read_Q(plc, db):
# 读取指定区域(PA)的数据
data = plc.read_area(Areas.PA, 0, 0, 1)
# 获取前进和后退状态
forward_status = get_bool(data, 0, 5)
backward_status = get_bool(data, 0, 6)
if forward_status == False or backward_status == False:
# 如果前进或后退状态为False,则写入指定DB块的值
set_bool(db, 0, 2, False)
set_bool(db, 0, 2, False)
plc.db_write(dbNr, 0, db)
def compare(k, v):
# 比较传入的键值对,并根据需要发送数据
if status[k] != v:
status[k] = v
send(k, v)
def send_cmp(data):
# 发送比较数据到cmp_url
r = requests.post(cmp_url, json=data)
print(r)
def send_mnp(data):
# 发送数据到mnp_url
r = requests.post(mnp_url, json=data)
print(r)
def send(k, v):
# 发送数据
t = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
if k == 'h1':
# 如果键为'h1',则发送指定数据
data = {
'time': t,
'ip': plc_ip,
'mnpName': 'forward'
}
send_cmp(data)
return
if k == 'h2':
# 如果键为'h2',则发送指定数据
data = {
'time': t,
'ip': plc_ip,
'mnpName': 'backward'
}
send_cmp(data)
return
# 否则发送一般数据
data = {
"cmpName": k,
"ip": plc_ip,
"time": t,
"value": v
}
send_cmp(data)
def run():
# 主运行函数
while True:
try:
# 尝试连接PLC并读取数据
plc, db = conn(plc_ip, dbNr)
threads = []
for k, v in point.items():
if k == 'num':
# 如果键为'num',则创建线程并读取整数值
threads.append(threading.Thread(target=compare(k, read_int(db, int(v[0]), int(v[1])))))
else:
# 否则创建线程并读取布尔值
threads.append(threading.Thread(target=compare(k, read_bool(db, int(v[0]), int(v[1])))))
# 启动线程
for t in threads:
t.start()
# 等待所有线程完成
for t in threads:
t.join()
# 等待一段时间
time.sleep(0.5)
except Exception as e:
# 捕获异常并打印
print(e)
接收指令
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .my_collect import * # 导入自定义的数据收集模块
import snap7 # 导入snap7库
from snap7.util import * # 导入snap7工具模块
# 创建Django视图函数
@csrf_exempt # 允许跨站请求伪造(CSRF)免除,这意味着该视图可以接收POST请求而无需CSRF令牌
def control(request):
if request.method == 'POST': # 如果是POST请求
data = json.loads(request.body) # 从请求的body中加载JSON数据
ip = data.get('ip') # 获取数据中的IP地址
key = data.get('mnpName') # 获取数据中的mnpName键对应的值
# 获取当前时间并格式化
t = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
# 构建要发送的JSON数据
json_data = {'ip': ip, 'mnpName': key, 'time': t}
# 发送数据到指定URL
requests.post(mnp_url, json=json_data)
try:
# 尝试连接到PLC并进行操作
plc, db = conn(ip, dbNr)
set_bool(db, *instruct[key]) # 根据指定的mnpName设置PLC中的布尔值
plc.db_write(dbNr, 0, db) # 将数据写入PLC的指定DB块
return JsonResponse({'ok'}) # 返回一个JSON响应,表示操作成功
finally:
plc.disconnect() # 最终确保与PLC的连接关闭
静态变量
静态
plc_ip = '192.168.0.10'
dbNr = 3000
base_url ='http://10.65.0.78:8080'
cmp_url = base_url + '/acqEnd/sendComponent'
mnp_url = base_url + '/acqEnd/sendManipulation'
status = {
'start':None,
'stop':None,
's1':None,
's2':None,
's3':None,
's4':None,
'h1':None,
'h2':None,
'h3': None,
'h4': None,
'num':'1111',
}
point = {
'start':'00',
'stop':'01',
's1':'06',
's2':'07',
's3':'10',
's4':'11',
'h1':'12',
'h2':'13',
'h3': '14',
'h4': '15',
'num':'24',
}
instruct = {
'start':(0,0b00000001),
'stop':(0,0b00000010),
'forward':(0,0b00000101),
'backward':(0,0b00001001),
'fault':(0,0b00010001),
'ack':(0,0b00100001),
}