2014-11-06 2 views
0

Я использую pymodbus для создания сервера Modbus RTU.Pymodbus RTU Server - запросы на управление

Я создал сервер в очень простой форме из примеров в документации.

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [0x0]*10000), 
    co = ModbusSequentialDataBlock(0, [0x0]*10000), 
    hr = ModbusSequentialDataBlock(0, [0x0]*10000), 
    ir = ModbusSequentialDataBlock(0, [0x0]*10000)) 
context = ModbusServerContext(slaves=store, single=True) 

StartSerialServer(context, port='/dev/ttyUSB0', framer=ModbusRtuFramer) 

Мой клиент связывает соответствие. Сервер распечатывает шестнадцатеричные значения запроса.

Теперь я хочу обрабатывать различные запросы.
Пример: Если клиент хочет прочитать регистр 4128 из регистров хранения, я хотел бы отправить значение обратно в ответ.

я не могу найти какие-либо полезные примеры в документации (или, может быть, я просто не понимаю?)
Я уже пытался подкласс ModbusSequentialDataBlock и переопределить get/setValue методы без успеха.

Это код моего хранилища данных. Это очень просто, и я ожидаю увидеть отпечатки в своих методах get/setValues. Но я ничего не вижу.

class MyData(ModbusSequentialDataBlock): 
    def __init__(self, address, values): 
     self.address = address 
     self.values = values 

    def validate(self, address, count=1): 
     print "validate" 

    def getValues(self, address, count=1): 
     print "getValues" 
     print address 

    def setValues(self, address, count=1): 
     print "setValues" 
     print address 

как ди, Co, и т.д. Я использовал MyData(...) вместо ModbusSequentialDataBlock в ModbusSlaveContext.

EDIT

Оказалось, что это была ошибка в pymodbus. При использовании асинхронного сервера вы не можете использовать RTU Framer. я открыл ошибку и это, кажется, исправлено: https://github.com/bashwork/pymodbus/issues/70#event-213935076

ответ

1

Я делаю вещи немного по-другому ... ModbusTCP вместо ModbusRTU ... однако я понял, как заставить его возвращать разные значения, Я думаю, это то, что вы ищете (getValues ​​/ setValues). Здесь вы идете ...

from pymodbus.server.async import StartTcpServer 
from pymodbus.datastore import ModbusSequentialDataBlock 
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext 
import sys 
import logging 
from twisted.internet.task import LoopingCall 

logging.basicConfig() 
log = logging.getLogger() 
log.setLevel(logging.DEBUG) 


def getModbusSlaveContext(): 
    hr_block = ModbusSequentialDataBlock(0, [9999 for x in range(10000)]) 
    return ModbusSlaveContext(hr=hr_block) 

def incdecvalues(valuelist): 
    lengthOfList = len(valuelist) 
    for counter in range(lengthOfList): 
     if counter % 2: 
      valuelist[counter]+=1 
     #else: 
     # valuelist[counter]+=-1 

def updatevalues(a): 
    context = a[0] 
    register = 3 
    slave_id = 0x01 
    address = 0x00 
    values = context[slave_id].getValues(register, address, count=10) 
    incdecvalues(values) 
    context[slave_id].setValues(register, address, values) 

slaves = { 
    0x01 : getModbusSlaveContext() 
    } 

context = ModbusServerContext(slaves=slaves, single=False) 

time = 2 
loop = LoopingCall(f=updatevalues, a=(context,)) 
loop.start(time, now=True) 
StartTcpServer(context, identity=None, address=('localhost', 9091)) 

всех регистров хранения (начиная с 3001 и есть 10000 из них) устанавливаются в начальное значение 9999. ведомого ID 1 и любой другой регистр увеличивается на 1 каждые 2 секунд для первых десяти регистров.

Надеюсь, что вам поможет.

К сожалению, pimodbus вызывает ошибку, когда я пытаюсь установитьValues ​​на отрицательное целое число. Это то, что я поставлен в тупик на ...

https://stackoverflow.com/questions/28244730/pymodbus-setvalues-how-to-resolve-error-integer-out-of-range-for-h-format-co

+0

Благодарим Вас за Tipps. См. Мое редактирование. Это была ошибка при использовании RTU и асинхронного сервера. – 0xAffe

Смежные вопросы