Skip to content

String type problem in Python 3: Pump object #9

@filipanies

Description

@filipanies

Similar to the issue raised by martinks, I have encountered an issue when attempting to use pumpy in Python 3, particularly when trying to use any function in the Pump object. (This differs slightly from the issue raised by martinks, since his is regarding the Chain object, but it is similar in nature.)

After entering:

chain = pumpy.Chain('COM3')
pumpy.Pump(chain, address=1).infuse()

I get:

Traceback (most recent call last):

  File "<ipython-input-798-21e248ae4c48>", line 1, in <module>
    pumpy.Pump(chain, address=1).infuse()

  File "C:\Users\Filip\Anaconda3\Lib\site-packages\pumpy.py", line 63, in __init__
    self.write('VER')

  File "C:\Users\Filip\Anaconda3\Lib\site-packages\pumpy.py", line 83, in write
    self.serialcon.write(self.address + command + '\r')

  File "C:\Users\Filip\Anaconda3\lib\site-packages\serial\serialwin32.py", line 308, in write
    data = to_bytes(data)

  File "C:\Users\Filip\Anaconda3\lib\site-packages\serial\serialutil.py", line 63, in to_bytes
    raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))

TypeError: unicode strings are not supported, please encode to bytes: '01VER\r'

This is linked to strings and bytestrings being linked in Python 2 but not in Python 3, as explained by martinks. This becomes relevant at any time that the program communicates with the pump, i.e. in the write and read functions, as the communication with the pump goes via bytestrings, but is interpreted as strings throughout the program. Fortunately the solution is quite simple: you just have to ensure that commands are entered as bytestrings in the write function, and feedback is converted to strings in the read function. I suggest the following:

Changing lines 82-91 from:

    def write(self,command):
        self.serialcon.write(self.address + command + '\r')

    def read(self,bytes=5):
        response = self.serialcon.read(bytes)

        if len(response) == 0:
            raise PumpError('%s: no response to command' % self.name)
        else:
            return response

to:

    def write(self,command):
        self.serialcon.write(str.encode(self.address) + str.encode(command) + b'\r')

    def read(self,bytes=5):
        response = self.serialcon.read(bytes)

        if len(response) == 0:
            raise PumpError('%s: no response to command' % self.name)
        else:
            return response.decode('utf-8')

So far, this has solved all issues for me, and with these changes I'm able to use the code in Python 3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions