TypeError: write_register() takes 3 positional arguments but 4 were given

Viewed 3147

Traceback:

mbAddress:  402
splitVal[0]:  62915
deviceId:  1
Traceback (most recent call last):
  File "E:\Jobs\Velocio\Development\XboxSpeedController\clsModbusClientTester.py", line 5, in <module>
    mbClient.sendFloat(402, 3.14)
  File "E:\Jobs\Velocio\Development\XboxSpeedController\clsModbusClient.py", line 50, in sendFloat
    self.mbClient.write_register(mbAddress, splitVal[0], self.deviceId)
TypeError: write_register() takes 3 positional arguments but 4 were given

Here are the files.

clsModbusClientTester.py:

from clsModbusClient import ModbusClient

mbClient = ModbusClient(1, 'COM6', 115200)

mbClient.sendFloat(402, 3.14)

clsModbusClient.py:

from pymodbus.client.sync import ModbusSerialClient
import ModbusConversions as mbConv

class ModbusClient:
    def __init__(self, deviceId, port, baud):
        self.baud = baud
        self.port = port
        self.mbClient = ModbusSerialClient(
            method='rtu',
            port=port,
            baudrate=baud,
            timeout=3,
            parity='N',
            stopbits=1,
            bytesize=8
        )
        if self.mbClient.connect():
            self.mbConnected = True
            self.deviceId = deviceId
        else:
            self.mbConnected = False
    
    def sendFloat(self, mbAddress, value):
        if self.mbConnected:
            splitVal = mbConv.FloatTo2Words(value)
            print("mbAddress: ", mbAddress)
            print("splitVal[0]: ", splitVal[0])
            print("deviceId: ", self.deviceId)
            self.mbClient.write_register(mbAddress, splitVal[0], self.deviceId)
            print("mbAddress+1: ", mbAddress+1)
            self.mbClient.write_register(mbAddress+1, splitVal[1], self.deviceId)

ModbusConversions.py:

def FloatTo2Words(FloatNumber):
    WordsResponse = struct.unpack('<HH', struct.pack('<f', FloatNumber))
        #the HH makes sure you get all 4 bytes which is both (2) words,the 2 converted integers
        #if you have a number that does not use enough bytes (like 0) it will fail w/o HH   
    return WordsResponse

I am confused. This is the error message that I would expect if I did not put selfs in an instance function, like this func(self, arguments). Maybe I need more selfs :-)

Does anyone have suggestions? Thanks for your help.

2 Answers

it worked, when I put ModelC into new second line

admin.site.register(ModelA, ModelB)
admin.site.register(ModelC)

I found my problem by digging into pymodbus. The method, write_register(), has the following signature:

write_register(address, value, **kwargs)

So the fix is to replace

        self.mbClient.write_register(mbAddress, splitVal[0], self.deviceId)

with

        self.mbClient.write_register(mbAddress, splitVal[0], unit = self.deviceId)
Related