{"id":14483352,"url":"https://github.com/adammck/pygsm","last_synced_at":"2025-08-19T22:32:15.707Z","repository":{"id":585121,"uuid":"218764","full_name":"adammck/pygsm","owner":"adammck","description":"Send and receive SMS via a GSM modem in Python","archived":false,"fork":false,"pushed_at":"2021-12-24T23:42:19.000Z","size":591,"stargazers_count":132,"open_issues_count":5,"forks_count":57,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-12-09T19:53:21.733Z","etag":null,"topics":["python","sms"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adammck.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-06-04T20:08:50.000Z","updated_at":"2024-11-28T16:27:40.000Z","dependencies_parsed_at":"2022-07-18T10:48:44.921Z","dependency_job_id":null,"html_url":"https://github.com/adammck/pygsm","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adammck%2Fpygsm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adammck%2Fpygsm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adammck%2Fpygsm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adammck%2Fpygsm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adammck","download_url":"https://codeload.github.com/adammck/pygsm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230374118,"owners_count":18216041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","sms"],"created_at":"2024-09-03T00:01:42.835Z","updated_at":"2024-12-19T04:07:00.194Z","avatar_url":"https://github.com/adammck.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"class GsmModem(__builtin__.object)\n |  pyGSM is a Python module which uses pySerial to provide a nifty\n |  interface to send and receive SMS via a GSM Modem. It was ported\n |  from RubyGSM, and provides (almost) all of the same features. It's\n |  easy to get started:\n |\n |    # create a GsmModem object:\n |    \u003e\u003e\u003e modem = pygsm.GsmModem(port=\"/dev/ttyUSB0\")\n |\n |    # harass Evan over SMS:\n |    # (try to do this before 11AM)\n |    \u003e\u003e\u003e modem.send_sms(*REDACTED*, \"Hey, wake up!\")\n |\n |    # check for incoming SMS:\n |    \u003e\u003e\u003e print modem.next_message()\n |    \u003cpygsm.IncomingMessage from *REDACTED*: \"Leave me alone!\"\u003e\n |\n |  pyGSM is distributed via GitHub:\n |  http://github.com/adammck/pygsm\n |\n |  Bug reports (especially for\n |  unsupported devices) are welcome:\n |  http://github.com/adammck/pygsm/issues\n |\n |\n |\n |\n |  Methods defined here:\n |\n |\n |  __init__(self, *args, **kwargs)\n |      Create a GsmModem object. All of the arguments are passed along\n |      to serial.Serial.__init__ when GsmModem.connect is called. For\n |      all of the possible configration options, see:\n |\n |      http://pyserial.wiki.sourceforge.net/pySerial#tocpySerial10\n |\n |      Alternatively, a single 'device' kwarg can be passed, which\n |      overrides the default proxy-args-to-pySerial behavior. This is\n |      useful when testing, or wrapping the serial connection with some\n |      custom logic.\n |\n |      NOTE: The serial connection isn't created until GsmModem.connect\n |      is called. It might still fail (but should raise GsmConnectError\n |      when it does so.)\n |\n |\n |  boot(self, reboot=False)\n |      (Re-)Connect to the modem and configure it in an (often vain)\n |      attempt to standardize the behavior of the many vendors and\n |      models. Should be called before reading or writing.\n |\n |      This method isn't called during __init__ (since 5f41ba6d), since\n |      it's often useful to create GsmModem objects without writing to\n |      the modem. To compensate, this method returns 'self', so it can\n |      be easily chained onto the constructor, like so:\n |\n |        \u003e\u003e\u003e gsm = GsmModem(port=\"whatever\").boot()\n |\n |      This is exactly the same as:\n |\n |        \u003e\u003e\u003e gsm = GsmModem(port=\"whatever\")\n |        \u003e\u003e\u003e gsm.boot()\n |\n |\n |  command(self, cmd, read_term=None, read_timeout=None, write_term='\\r', raise_errors=True)\n |      Issue an AT command to the modem, and return the sanitized\n |      response. Sanitization removes status notifications, command\n |      echo, and incoming messages, (hopefully) leaving only the actual\n |      response to the command.\n |\n |      If Error 515 (init or command in progress) is returned, the\n |      command is automatically retried up to 'GsmModem.max_retries'\n |      times.\n |\n |\n |  connect(self, reconnect=False)\n |      Connect to the modem via pySerial, using the args and kwargs\n |      provided to the constructor. If 'reconnect' is True, and the\n |      modem is already connected, the entire serial.Serial object is\n |      destroyed and re-established.\n |\n |      Returns self.device, or raises GsmConnectError\n |\n |\n |  disconnect(self)\n |      Disconnect from the modem.\n |\n |\n |  hardware(self)\n |      Return a dict of containing information about the modem. The\n |      contents of each value are entirely manufacturer-dependant, and\n |      can vary wildly between devices.\n |\n |\n |  next_message(self, ping=True, fetch=True)\n |      Returns the next waiting IncomingMessage object, or None if the\n |      queue is empty. The optional 'ping' and 'fetch' args control\n |      whether the modem is pinged (to allow new messages to be\n |      delivered instantly, on those modems which support it) and\n |      queried for unread messages in storage, which can both be\n |      disabled in case you're already polling in a separate thread.\n |\n |\n |  ping(self)\n |      Send the \"AT\" command to the device, and return true if it is\n |      acknowledged. Since incoming notifications and messages are\n |      intercepted automatically, this is a good way to poll for new\n |      messages without using a worker thread like RubyGSM.\n |\n |\n |  query(self, cmd, prefix=None)\n |      Issue an AT command to the modem, and returns the relevant part\n |      of the response. This only works for commands that return a\n |      single line followed by \"OK\", but conveniently, this covers\n |      almost all AT commands that I've ever needed to use. Example:\n |\n |        \u003e\u003e\u003e modem.query(\"AT+CSQ\")\n |        \"+CSQ: 20,99\"\n |\n |      Optionally, the 'prefix' argument can specify a string to check\n |      for at the beginning of the output, and strip it from the return\n |      value. This is useful when you want to both verify that the\n |      output was as expected, but ignore the prefix. For example:\n |\n |        \u003e\u003e\u003e modem.query(\"AT+CSQ\", prefix=\"+CSQ:\")\n |        \"20,99\"\n |\n |      For all unexpected responses (errors, no output, or too much\n |      output), returns None.\n |\n |\n |  query_list(self, cmd, prefix=None)\n |      Issue a single AT command to the modem, checks that the last\n |      line of the response is \"OK\", and returns a list containing the\n |      other lines. An empty list is returned if a command fails, so\n |      the output of this method can always be assumed to be iterable.\n |\n |      The 'prefix' argument can optionally specify a string to filter\n |      the output lines by. Matching lines are returned (sans prefix),\n |      and the rest are dropped.\n |\n |      Most AT commands return a single line, which is better handled\n |      by GsmModem.query, which returns a single value.\n |\n |\n |  reboot(self)\n |      Disconnect from the modem, reconnect, and reboot it (AT+CFUN=1,\n |      which clears all volatile state). This drops the connection to\n |      the network, so it's wise to call _GsmModem.wait_for_network_\n |      after rebooting.\n |\n |\n |  send_sms(self, recipient, text)\n |      Send an SMS to 'recipient' containing 'text'. Some networks will\n |      automatically split long messages into multiple parts, and join\n |      them upon delivery -- but some will silently drop them. pyGSM\n |      does nothing to avoid this (for now), so try to keep 'text'\n |      under 160 characters.\n |\n |\n |  signal_strength(self)\n |      Return an integer between 1 and 99, representing the current\n |      signal strength of the GSM network, False if we don't know, or\n |      None if the modem can't report it.\n |\n |\n |  wait_for_network(self)\n |      Block until the signal strength indicates that the device is\n |      active on the GSM network. It's a good idea to call this before\n |      trying to send or receive anything.\n |\n |\n |\n |\n |  Data descriptors defined here:\n |\n |\n |  network\n |      Return the name of the currently selected GSM network.\n |\n |\n |  service_center\n |      Get or set the service center address currently in use by the\n |      modem. Returns None if the modem does not support the AT+CSCA\n |      command.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadammck%2Fpygsm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadammck%2Fpygsm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadammck%2Fpygsm/lists"}