首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ModbusTCP服务器/从机在Python语言中的实现

ModbusTCP服务器/从机在Python语言中的实现
EN

Stack Overflow用户
提问于 2016-11-13 09:15:49
回答 1查看 5.8K关注 0票数 4

我试着写一个与ı数据库连接的ModbusTCP服务器软件。我使用pyModbus库来完成这项任务。该库有一个更新服务器示例。通过使用该代码,我将我的代码写成:

代码语言:javascript
复制
'''
Pymodbus Server With Updating Thread
--------------------------------------------------------------------------
This is an example of having a background thread updating the
context while the server is operating. This can also be done with
a python thread::
    from threading import Thread
    thread = Thread(target=updating_writer, args=(context,))
    thread.start()
'''
#---------------------------------------------------------------------------# 
# import the modbus libraries we need
#---------------------------------------------------------------------------# 
from pymodbus.server.async import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer

#---------------------------------------------------------------------------# 
# import the twisted libraries we need
#---------------------------------------------------------------------------# 
from twisted.internet.task import LoopingCall

#---------------------------------------------------------------------------# 
# configure the service logging
#---------------------------------------------------------------------------# 
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

#---------------------------------------------------------------------------# 
# for database reading
#---------------------------------------------------------------------------# 

import sqlite3
import sys

sqlite_file = 'ModbusTable.db'

thermostats = 25
registers_per_thermostat = 3

global total_registers
total_registers = thermostats * registers_per_thermostat

#---------------------------------------------------------------------------# 
# define your callback process
#---------------------------------------------------------------------------# 
def updating_writer(a):
    ''' A worker process that runs every so often and
    updates live values of the context. It should be noted
    that there is a race condition for the update.
    :param arguments: The input arguments to the call
    '''
    log.debug("updating the context")
    context  = a[0]
    functioncode = 3 
    slave_id = 0x01 # slave address
    address  = 0x10 # start register : 400017

    values = []

    # Connecting to the database file
    conn = sqlite3.connect(sqlite_file)
    c1 = conn.cursor()

    c1.execute("""SELECT ID, SetPoint, ActualTemp FROM ModbusData""")

    registers = c1.fetchall()

    c1.close()

    for register in registers:
        for value in register:
            values.append(value)

    log.debug("values from database: " + str(values))

    context[slave_id].setValues(functioncode, address, values)

    values = context[slave_id].getValues(functioncode, address, count=total_registers)

    log.debug("values to be written to database: " + str(values))

    c2 = conn.cursor()

    for index in range(len(values)):
        if (index+2)<len(values):
            column1 = values[index]
            column2 = values[index+1]
            column3 = values[index+2]
            c2.execute("""UPDATE ModbusData set SetPoint = ?, ActualTemp = ? where ID=?""",[column2, column3, column1])

    # Committing changes and closing the connection to the database file
    c2.close()
    conn.close()



#---------------------------------------------------------------------------# 
# initialize your data store
#---------------------------------------------------------------------------# 
store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [17]*total_registers),
    co = ModbusSequentialDataBlock(0, [17]*total_registers),
    hr = ModbusSequentialDataBlock(0, [17]*total_registers),
    ir = ModbusSequentialDataBlock(0, [17]*total_registers))
context = ModbusServerContext(slaves=store, single=True)

#---------------------------------------------------------------------------# 
# initialize the server information
#---------------------------------------------------------------------------# 
identity = ModbusDeviceIdentification()
identity.VendorName  = 'pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl   = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'pymodbus Server'
identity.ModelName   = 'pymodbus Server'
identity.MajorMinorRevision = '1.0'

#---------------------------------------------------------------------------# 
# run the server you want
#---------------------------------------------------------------------------# 
time = 5 # 5 seconds delay
loop = LoopingCall(f=updating_writer, a=(context,))
loop.start(time, now=False) # initially delay by time
StartTcpServer(context, identity=identity, address=("", 5007))

基本上,我试图实现的是服务器上下文与数据库同步。我尝试从数据库到上下文读取值,然后最后将上下文值更新到数据库。我成功地将数据从数据库转换到上下文。因为当我向位于另一台lan计算机上的modbus客户端请求值时,我成功地在那里获得了所请求的数据。但是,我不能通过TCP服务器写入数据库。在另一台局域网计算机上使用相同的modbus客户端,我发送请求以写入服务器上下文中的一些寄存器,然后将其写入数据库。在这一点上我失败了。我无法将服务器上下文的最新更新情况写入数据库。我想,我可能会从pymodbus文档中的“数据库数据存储示例”中受益,但我不知道如何做到这一点。所以我需要你对这项任务的想法。

EN

回答 1

Stack Overflow用户

发布于 2018-05-30 17:58:16

您没有为游标C2调用"commit()“。您只需关闭连接即可。因此,您的更改将不会被写入database.The sqlite文档中明确提到了这一点。参见here。在关闭连接之前尝试执行c2.commit(),看看数据是否正在写入。

如果这不起作用,请分享你得到的错误。这将有助于理解这个问题。

希望这能有所帮助!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40569522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档