GithubHelp home page GithubHelp logo

pygsm's Introduction

class GsmModem(__builtin__.object)
 |  pyGSM is a Python module which uses pySerial to provide a nifty
 |  interface to send and receive SMS via a GSM Modem. It was ported
 |  from RubyGSM, and provides (almost) all of the same features. It's
 |  easy to get started:
 |
 |    # create a GsmModem object:
 |    >>> modem = pygsm.GsmModem(port="/dev/ttyUSB0")
 |
 |    # harass Evan over SMS:
 |    # (try to do this before 11AM)
 |    >>> modem.send_sms(*REDACTED*, "Hey, wake up!")
 |
 |    # check for incoming SMS:
 |    >>> print modem.next_message()
 |    <pygsm.IncomingMessage from *REDACTED*: "Leave me alone!">
 |
 |  pyGSM is distributed via GitHub:
 |  http://github.com/adammck/pygsm
 |
 |  Bug reports (especially for
 |  unsupported devices) are welcome:
 |  http://github.com/adammck/pygsm/issues
 |
 |
 |
 |
 |  Methods defined here:
 |
 |
 |  __init__(self, *args, **kwargs)
 |      Create a GsmModem object. All of the arguments are passed along
 |      to serial.Serial.__init__ when GsmModem.connect is called. For
 |      all of the possible configration options, see:
 |
 |      http://pyserial.wiki.sourceforge.net/pySerial#tocpySerial10
 |
 |      Alternatively, a single 'device' kwarg can be passed, which
 |      overrides the default proxy-args-to-pySerial behavior. This is
 |      useful when testing, or wrapping the serial connection with some
 |      custom logic.
 |
 |      NOTE: The serial connection isn't created until GsmModem.connect
 |      is called. It might still fail (but should raise GsmConnectError
 |      when it does so.)
 |
 |
 |  boot(self, reboot=False)
 |      (Re-)Connect to the modem and configure it in an (often vain)
 |      attempt to standardize the behavior of the many vendors and
 |      models. Should be called before reading or writing.
 |
 |      This method isn't called during __init__ (since 5f41ba6d), since
 |      it's often useful to create GsmModem objects without writing to
 |      the modem. To compensate, this method returns 'self', so it can
 |      be easily chained onto the constructor, like so:
 |
 |        >>> gsm = GsmModem(port="whatever").boot()
 |
 |      This is exactly the same as:
 |
 |        >>> gsm = GsmModem(port="whatever")
 |        >>> gsm.boot()
 |
 |
 |  command(self, cmd, read_term=None, read_timeout=None, write_term='\r', raise_errors=True)
 |      Issue an AT command to the modem, and return the sanitized
 |      response. Sanitization removes status notifications, command
 |      echo, and incoming messages, (hopefully) leaving only the actual
 |      response to the command.
 |
 |      If Error 515 (init or command in progress) is returned, the
 |      command is automatically retried up to 'GsmModem.max_retries'
 |      times.
 |
 |
 |  connect(self, reconnect=False)
 |      Connect to the modem via pySerial, using the args and kwargs
 |      provided to the constructor. If 'reconnect' is True, and the
 |      modem is already connected, the entire serial.Serial object is
 |      destroyed and re-established.
 |
 |      Returns self.device, or raises GsmConnectError
 |
 |
 |  disconnect(self)
 |      Disconnect from the modem.
 |
 |
 |  hardware(self)
 |      Return a dict of containing information about the modem. The
 |      contents of each value are entirely manufacturer-dependant, and
 |      can vary wildly between devices.
 |
 |
 |  next_message(self, ping=True, fetch=True)
 |      Returns the next waiting IncomingMessage object, or None if the
 |      queue is empty. The optional 'ping' and 'fetch' args control
 |      whether the modem is pinged (to allow new messages to be
 |      delivered instantly, on those modems which support it) and
 |      queried for unread messages in storage, which can both be
 |      disabled in case you're already polling in a separate thread.
 |
 |
 |  ping(self)
 |      Send the "AT" command to the device, and return true if it is
 |      acknowledged. Since incoming notifications and messages are
 |      intercepted automatically, this is a good way to poll for new
 |      messages without using a worker thread like RubyGSM.
 |
 |
 |  query(self, cmd, prefix=None)
 |      Issue an AT command to the modem, and returns the relevant part
 |      of the response. This only works for commands that return a
 |      single line followed by "OK", but conveniently, this covers
 |      almost all AT commands that I've ever needed to use. Example:
 |
 |        >>> modem.query("AT+CSQ")
 |        "+CSQ: 20,99"
 |
 |      Optionally, the 'prefix' argument can specify a string to check
 |      for at the beginning of the output, and strip it from the return
 |      value. This is useful when you want to both verify that the
 |      output was as expected, but ignore the prefix. For example:
 |
 |        >>> modem.query("AT+CSQ", prefix="+CSQ:")
 |        "20,99"
 |
 |      For all unexpected responses (errors, no output, or too much
 |      output), returns None.
 |
 |
 |  query_list(self, cmd, prefix=None)
 |      Issue a single AT command to the modem, checks that the last
 |      line of the response is "OK", and returns a list containing the
 |      other lines. An empty list is returned if a command fails, so
 |      the output of this method can always be assumed to be iterable.
 |
 |      The 'prefix' argument can optionally specify a string to filter
 |      the output lines by. Matching lines are returned (sans prefix),
 |      and the rest are dropped.
 |
 |      Most AT commands return a single line, which is better handled
 |      by GsmModem.query, which returns a single value.
 |
 |
 |  reboot(self)
 |      Disconnect from the modem, reconnect, and reboot it (AT+CFUN=1,
 |      which clears all volatile state). This drops the connection to
 |      the network, so it's wise to call _GsmModem.wait_for_network_
 |      after rebooting.
 |
 |
 |  send_sms(self, recipient, text)
 |      Send an SMS to 'recipient' containing 'text'. Some networks will
 |      automatically split long messages into multiple parts, and join
 |      them upon delivery -- but some will silently drop them. pyGSM
 |      does nothing to avoid this (for now), so try to keep 'text'
 |      under 160 characters.
 |
 |
 |  signal_strength(self)
 |      Return an integer between 1 and 99, representing the current
 |      signal strength of the GSM network, False if we don't know, or
 |      None if the modem can't report it.
 |
 |
 |  wait_for_network(self)
 |      Block until the signal strength indicates that the device is
 |      active on the GSM network. It's a good idea to call this before
 |      trying to send or receive anything.
 |
 |
 |
 |
 |  Data descriptors defined here:
 |
 |
 |  network
 |      Return the name of the currently selected GSM network.
 |
 |
 |  service_center
 |      Get or set the service center address currently in use by the
 |      modem. Returns None if the modem does not support the AT+CSCA
 |      command.

pygsm's People

Contributors

adammck avatar jwishnie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pygsm's Issues

sytax errors

in a few places e.g.:
"def _log(self, str, type="debug"):"

a reserved keywords are used as parameters, this should be avoided

Message format not received correctly

Hi,
I am using a Siemens MC35i GSM modem. Compatbility with pygsm seems quite good.

However we are using the MC35i to send messages to a remote telemetry unit. An example of a response from the remote unit is:
"INSYS GSM 4.X:
BLOCK:

100:
Ax=+01234

OK"
I believe the "OK" at the end of the query message would be confused as the end of the CMGL command response.

The actual response we get using the next_message() method is:

"Ax=+01234 4.x:BLOCK:"

Any suggestions for fixing this issue?

If you need anymore information let me know.

Thanks,
Mitch

Nokia N900

Hi,

I'm trying to use pygsm with the nokia N900.

There is no problem when starting the pygsm.GsmModem object, and when sending a message. But reading incoming messages raise an error.

Here is the log:

>>> modem = pygsm.GsmModem(port="/dev/ttyACM0")
debug Booting
debug Connecting
write 'ATE0\r'
read 'ATE0\r\r\n'
read 'OK\r\n'
write 'AT+CMEE=1\r'
read '\r\n'
read 'OK\r\n'
write 'AT+WIND=0\r'
read '\r\n'
read 'ERROR\r\n'
write 'AT+CSMS=1\r'
read '\r\n'
read 'ERROR\r\n'
write 'AT+CMGF=0\r'
read '\r\n'
read 'OK\r\n'
write 'AT+CNMI=2,2,0,0,0\r'
read '\r\n'
read 'ERROR\r\n'
write 'AT+CMGL=0\r'
read '\r\n'
read 'ERROR\r\n'

>>> print modem.next_message()
write 'AT\r'
read '\r\n'
read 'OK\r\n'
write 'AT+CMGL=0\r'
read '\r\n'
read 'ERROR\r\n'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/francis/Projects/virtualenv/pygsm/lib/python2.6/site-packages/pygsm/gsmmodem.py", line 567, in next_message
self._fetch_stored_messages()
File "/home/francis/Projects/virtualenv/pygsm/lib/python2.6/site-packages/pygsm/gsmmodem.py", line 544, in _fetch_stored_messages
lines = self.command('AT+CMGL=%s' % self.smshandler.CMGL_STATUS)
File "/home/francis/Projects/virtualenv/pygsm/lib/python2.6/site-packages/pygsm/gsmmodem.py", line 375, in command
raise(err)
pygsm.errors.GsmModemError: Unknown GSM Error

Thanks,
Francis

Syntax error in gsmmodem.py

It looks like line 692 of gsmmodem.py has a syntax error:

Traceback (most recent call last):
File "sms_rest.py", line 1, in
import cherrypy, pygsm, sqlite3, ConfigParser
File "/Users/tmcw/Apps/sms_rest/pygsm/init.py", line 5, in
from gsmmodem import GsmModem
File "/Users/tmcw/Apps/sms_rest/pygsm/gsmmodem.py", line 692
except Exception as err:
^
Replacing 'as', with a comma works.

Error in Disconnect method

def disconnect(self):
    """Disconnect from the modem."""

    self._log("Disconnecting")

    # attempt to close and destroy the device
    if hasattr(self, "device") and (self.device is None):
        with self._modem_lock:
            if self.device.isOpen():
                self.device.close()
                self.device = None
                return True

    # for some reason, the device
    # couldn't be closed. it probably
    # just isn't open yet
    return False

It should be "if hasattr(self, "device") and (self.device is not None):"

erron in gsmmodem.py

>>> import pygsm
>>> m = pygsm.GsmModem(port="/dev/ttyS0")
>>> m.send_sms("+919500889199", "testing from python")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/site-packages/pygsm/gsmmodem.py", line 794, in send_sms
    self._write(chr(27))
  File "/usr/lib/python2.5/site-packages/pygsm/gsmmodem.py", line 268, in _write
    self.device.write(str)
AttributeError: 'NoneType' object has no attribute 'write'

Iso Latin (accented) characters garbled: FIXED

please review this commit for merge back into adammck/pygsm

http://github.com/jwishnie/pygsm/commit/f509c7c70825dc589319af7595b1c8f8c1334cfb

The approach is:

  1. Set message format to HEX (+CSCS="HEX")
  2. Parse all incoming messages with incoming_buffer.decode('hex').decode('raw_unicode_escape') which turns a string of hex letters into a decoded unicode string
  3. convert all outgoing text with the reverse out.encode('raw_unicode_escape').encode('hex')

This might even work for full Unicode IF unicode sms are sent UTF8 (dunno if they are)

Python 3 Support

This is a very useful modules as it abstracts much of the learning curve behind serial. But Python 3 support would be amazing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.