此程序的思路,依然是要屏蔽高级程序对底层访问的繁琐。
每次请求读写需要包含一个id,Redis收到之后处理了读写,会按照id写入hash,上位机延时30ms后,再从hash中读出来即可。
import json
import redis
import snap7
from snap7.util import *
import struct
import numpy as np
# Redis连接
redis_client = redis.StrictRedis(host='127.0.0.1', port=6379, db=0, password='123456')
# PLC连接参数
plc_ip = '127.0.0.1' # PLC的IP地址
plc_rack = 0 # 机架号
plc_slot = 1 # 插槽号
# 创建PLC连接
plc = snap7.client.Client()
plc.connect(plc_ip, plc_rack, plc_slot)
# Redis频道订阅
pubsub = redis_client.pubsub()
pubsub.subscribe('plc_commands')
def convert_to_int16(data):
int16_values = []
for i in range(0, len(data), 2):
# 使用struct解包两个字节
value = struct.unpack('>h', data[i:i+2])[0]
int16_values.append(value)
return int16_values
# 处理接收到的消息
def handle_message(message):
data = json.loads(message['data'])
print(f"Received message: {data}")
request_id = data['id']
operation = data['operation']
if operation == 'read':
db_number = data['db_number']
start = data['start']
size = data['size'] # 对于int16,size应该是2的倍数
result = plc.db_read(db_number, start, size)
# 将读取结果(int16数组)存储到Redis哈希表中
# 注意:这里我们将结果转换为十六进制字符串列表
redis_client.hset('plc_results', request_id, json.dumps(convert_to_int16(result)))
elif operation == 'write':
db_number = data['db_number']
start = data['start']
# 假设data_to_write是一个整数列表,每个整数代表一个int16值
data_to_write = [np.int16(val) for val in data['data_to_write']]
result = plc.db_write(db_number, start, data_to_write)
# 将写入结果存储到Redis哈希表中
redis_client.hset('plc_results', request_id, 'success' if result else 'failure')
# 消息循环
try:
# 消息循环
for message in pubsub.listen():
if message['type'] == 'message':
handle_message(message)
except KeyboardInterrupt:
print("程序被用户中断")
# 这里可以添加一些清理代码,比如断开PLC连接,关闭Redis连接等
plc.disconnect()
redis_client.close()
print("清理完成,程序退出")