python 使用Redis订阅,处理客户端读写PLC请求(smart 200),写入Hash

此程序的思路,依然是要屏蔽高级程序对底层访问的繁琐。

每次请求读写需要包含一个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("清理完成,程序退出")
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值