faucamp / python-gsmmodem

Python module to control a GSM modem attached to the system: send/receive SMS messages, handle calls, etc
GNU Lesser General Public License v3.0
384 stars 302 forks source link

"TypeError: an integer is required" when used with Python 3.2 on rpi #39

Open timitt opened 10 years ago

timitt commented 10 years ago

When I try sendsms.py using Python 3.2.3 I get this:

Traceback (most recent call last): File "/usr/local/bin/sendsms.py", line 88, in main() File "/usr/local/bin/sendsms.py", line 53, in main modem.connect(args.pin) File "/usr/local/lib/python3.2/dist-packages/gsmmodem/modem.py", line 177, in connect self.write('ATZ') # reset configuration File "/usr/local/lib/python3.2/dist-packages/gsmmodem/modem.py", line 398, in write responseLines = SerialComms.write(self, data + writeTerm, waitForResponse=waitForResponse, timeout=timeout, expectedResponseTermSeq=expectedResponseTermSeq) File "/usr/local/lib/python3.2/dist-packages/gsmmodem/serial_comms.py", line 127, in write self.serial.write(data) File "/usr/local/lib/python3.2/dist-packages/serial/serialposix.py", line 491, in write d = to_bytes(data) File "/usr/local/lib/python3.2/dist-packages/serial/serialutil.py", line 76, in to_bytes b.append(item) # this one handles int and str for our emulation and ints for Python 3.x TypeError: an integer is required

Error comes from pyserial, but I found this as solution http://stackoverflow.com/questions/22275079/pyserial-write-wont-take-my-string so maybe gsmmodem should handle string to bytes conversion.

I have latest pySerial (2.7). Maybe you have used older version of that or something since I assume that this has not happened to you when you have tested this with python 3.

Also using 0.9 python-gsmmodem and Python 3.2.3 on Raspberry Pi.

It also happens with my own code and it happens if I use pyserial and it's write with string directly. Still I don't know I should blame pyserial (as it might be meant to be take bytes).

Do you think this is bug in gsmmodem or should this be talked with pyserial devs?

timitt commented 10 years ago

Ok, I looked more and I think the issue is in this library.

My python skills are too limited to make real patch, but how I managed to make it work was to add serial_comms.py few things. I have never touched to Python 2 so no idea what happens there with these modifications. write() function needed line that modifies source data to bytes from str

   with self._txLock:            
       if isinstance(data, str):
          data = data.encode()
       if waitForResponse:

_readLoop() needed to convert bytes to be converted to str

      while self.alive:
         data = self.serial.read(1).decode()
         if data != '': # check for timeout

Also sendsms.py seemed to use raw_input() when it is not available anymore ( input() does the same now according to Python docs).

faucamp commented 10 years ago

Hi, thanks for reporting this. The systems I am currently actively using this library are indeed running Python 2.7, and I mostly make use of the build system to ensure Python 3 compatibility. I will apply a fix shortly...

timitt commented 10 years ago

Thanks for looking for it this fast. Any plans on newer version in pypi? There seems to be quite a few fixes closed after that 0.9 version from year back.

Anyways with those changes this whole thing seems to work when I use smsTextMode, but if it is set to False (and use PDU which would be safer) then it fails to parse delivery status data, but since PDU data looks this

000000FF0006030C915348347288684170724193002141707241

I doubt it is related to Python 3 or anything else but ancient Wavecom M1206B (have had it unused close to 10 years).

valerycolong commented 9 years ago

Hello Francois, I must say great work with python gsmmodem. Because of this module, I decided to port my SMS application to Python which has gone so well until now. I ran into the TypeError: an integer is required which occurred at "C:\Python\34\lib\site-packages\gsmmodem\serial_comms.py", line 127, in write self.serial.write(data) I am using Python 3.4 and python gsmmodem 0.9 with a Sierra Wireless GSM Modem. I was able to solve the issue above by extending the GsmModem class and override the _readLoop and write methods with the patches suggested on this thread by youtux. Beyond this, I ran again into another error; this time it was a gsmmodem.exceptions.TimeoutException which is raised from File "C:\Python\34\lib\site-packages\gsmmodem\modem.py", line 177, in connect self.write('ATZ') # reset configuration Is there any solution you can propose for me?

adisciple50 commented 8 years ago

++++++++SMS.py+++++++++++ import gsmmodem as Modem

huwei = Modem.GsmModem("COM4")

huwei.connect()

FirstMessage = huwei.readStoredSms(0)

print(FirstMessage.number()) ++++++++++++++++++++ returns:

Traceback (most recent call last): File "C:/Users/Jason/Documents/Code/Python/SmsTimeclock/SMS.py", line 6, in huwei.connect() File "C:\Program Files\Python 3.5\lib\site-packages\python_gsmmodem-0.9-py3.5.egg\gsmmodem\modem.py", line 177, in connect File "C:\Program Files\Python 3.5\lib\site-packages\python_gsmmodem-0.9-py3.5.egg\gsmmodem\modem.py", line 413, in write File "C:\Program Files\Python 3.5\lib\site-packages\python_gsmmodem-0.9-py3.5.egg\gsmmodem\serial_comms.py", line 127, in write File "C:\Program Files\Python 3.5\lib\site-packages\serial\serialwin32.py", line 283, in write data = to_bytes(data) File "C:\Program Files\Python 3.5\lib\site-packages\serial\serialutil.py", line 76, in to_bytes b.append(item) # this one handles int and str for our emulation and ints for Python 3.x TypeError: an integer is required

Process finished with exit code 1

in windows 7 Ultimate x64 using python 3.5 i tried converting item to int (see immediately above) but item handles strings as well, it threw a TypeError exception on "A"! (possibly whilst echoing "AT")

adisciple50 commented 8 years ago

Having rung up the phone company to get a puk code and change the sim pin. huwei.connect(pin=1234) and huwei.connect(pin="1234") do nothing to change the situation

dwaynez commented 8 years ago

I too am having problems running under Python 3.2. I needed to make 2 changes in order for my program to run. In modem.py; write function, I needed to add an encode to the call for super: responseLines = super(GsmModem, self).write((data + writeTerm).encode(), waitForResponse=waitForResponse, timeout=timeout, expectedResponseTermSeq=expectedResponseTermSeq)

In serial_comms.py in the function _readLoop, I needed to add decode: data = self.serial.read(1) data = data.decode()

This last fix causes a crash sometimes (I was testing without a sim card in my GSM module and received the error):

Traceback (most recent call last): File "/usr/lib/python3.2/threading.py", line 740, in _bootstrap_inner self.run() File "/usr/lib/python3.2/threading.py", line 693, in run self._target(_self._args, *_self._kwargs) File "/usr/local/lib/python3.2/dist-packages/python_gsmmodem-0.9-py3.2.egg/gsmmodem/serial_comms.py", line 94, in _readLoop data = data.decode() UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Any suggestiions on a proper fix for Python 3.2?

blylei commented 6 years ago

I also meet this exception with python3.5,just like this"an integer is required (got type str)"

tomchy commented 6 years ago

Could you confirm that this issue is also present in this updated fork? There are several fixes merged and it could be found in pip as python-gsmmodem-new.