一个简单的OPC UA/ModbusTCP 网关(Python)

        使用我前面几篇博文的内容,能够使用Python编写一个最简单的OPC UA /ModbusTCP网关。

从这个程序可以看出:

  1. 应用OPC UA 并不难,现在我们就可以应用到工程应用中,甚至DIY项目也可以。不必采用复杂的工具软件。
  2. 使用Python 来构建工业自动化领域的原型机程序是不错的选择。

OPCUA_modbus 网关

import sys
sys.path.insert(0, "..")
import time
from opcua import  Server
from pyModbusTCP.client import ModbusClient # Modbus TCP Client
from pyModbusTCP import utils 
if __name__ == "__main__":

    # setup our server
    server = Server()
    server.set_endpoint("opc.tcp://127.0.0.1:48400/freeopcua/server/")
    # setup our own namespace, not really necessary but should as spec
    uri = "http://examples.freeopcua.github.io"
    idx = server.register_namespace(uri)

    # get Objects node, this is where we should put our nodes
    objects = server.get_objects_node()

    # populating our address space
    myobj = objects.add_object(idx, "MyObject")
    myvar = myobj.add_variable(idx, "MyVariable", 6.7)
    myvar.set_writable()    # Set MyVariable to be writable by clients
    ModbusInterface = ModbusClient(host="localhost", port=502, unit_id=1, auto_open=True, auto_close=False) 
    
    # starting!
    server.start()
    
    try:
        count = 0
        while True:
            time.sleep(1)
            reg_l=ModbusInterface.read_input_registers(0,2)
            val=utils.word_list_to_long(reg_l)
            print(utils.decode_ieee(val[0],False)) 
            myvar.set_value(utils.decode_ieee(val[0],False))
    finally:
        #close connection, remove subcsriptions, etc
        server.stop()

modbusTCP服务器程序

import argparse
from pyModbusTCP.server import ModbusServer, DataBank
from pyModbusTCP import utils
from datetime import datetime

import numpy as np 
Fs = 8000
f = 50
x=0
coil_state=True 
class MyDataBank(DataBank):
    """A custom ModbusServerDataBank for override get_holding_registers method."""

    def __init__(self):
        # turn off allocation of memory for standard modbus object types
        # only "holding registers" space will be replaced by dynamic build values.
        super().__init__(virtual_mode=True)
    def get_coils(self, address, number=1, srv_info=None):
        global coil_state
        coil_state=not coil_state
        return coil_state
            
    def get_holding_registers(self, address, number=1, srv_info=None):
        """Get virtual holding registers."""
        # populate virtual registers dict with current datetime values
        now = datetime.now()
        return now.second
       
    def get_input_registers(self, address, number=1, srv_info=None):
        global x
        wave=np.sin(2 * np.pi * f * x / Fs)*10
        x=x+1
        b32_l=[utils.encode_ieee(wave,False)]
        b16_l = utils.long_list_to_word(b32_l)
        print(b16_l)              
        return  b16_l
 
if __name__ == '__main__':
    # parse args
    parser = argparse.ArgumentParser()
    parser.add_argument('-H', '--host', type=str, default='localhost', help='Host (default: localhost)')
    parser.add_argument('-p', '--port', type=int, default=502, help='TCP port (default: 502)')
    args = parser.parse_args()
    # init modbus server and start it
    server = ModbusServer(host=args.host, port=args.port, data_bank=MyDataBank())
    server.start()

        最后透过uaExpert 程序访问OPCUA Server。可以看到myVar 变量在变化。

 OPCUA 客户端 

import sys
sys.path.insert(0, "..")
import numpy as np 
import matplotlib.pyplot as plt
from opcua import Client

x = np.arange(0,1000,1,dtype=np.int16)
y=np.arange(-10,10,0.02,dtype=np.float32)
if __name__ == "__main__":

    client = Client("opc.tcp://localhost:48400/freeopcua/server/")
    # client = Client("opc.tcp://admin@localhost:4840/freeopcua/server/") #connect using a user
    try:
        client.connect()

        # Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects
        root = client.get_root_node()
        print("Objects node is: ", root)
        # Node objects have methods to read and write node attributes as well as browse or populate address space
        print("Children of root are: ", root.get_children())
        while True:
            myvar = root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
            obj = root.get_child(["0:Objects", "2:MyObject"])
            print("myvar is: ", myvar.get_value())
            y=np.append(y,myvar.get_value())
            y=np.delete(y, 0, axis=0)      
            plt.clf()
            plt.plot(x, y, ls="-", lw=2, label="plot figure")
            plt.legend()
            plt.show()
            plt.pause(0.1)
        # Stacked myvar access
        # print("myvar is: ", root.get_children()[0].get_children()[1].get_variables()[0].get_value())

    finally:
        client.disconnect()

看出来了吧这些程序都短小精悍。编写程序是学习计算机网络协议最好的方法。

猜你喜欢

转载自blog.csdn.net/yaojiawan/article/details/131494145