{ "info": { "author": "Justin Engel", "author_email": "jengel@sealandaire.com", "bugtrack_url": null, "classifiers": [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3" ], "description": "# pyiridium9602 \nPython 3 iridium satelite communication library for the iridium 9602 modem.\n\n## Purpose\nI wrote this library after trying to work with pyRockBlock foud at https://github.com/MakerSnake/pyRockBlock. The pyRockblock library \nwas a great resource to start with, but I quickly found out it did not suit the needs for my application. I had too many problems \nwith the serial port readline commands and long timeouts hanging my GUI application. I ended up digging through the documentation \nabout the iridium 9602 modem at http://www.nalresearch.com/Info/AT%20Commands%20for%20Models%209602.pdf and wrote this library. \nThis library is strictly a callback based library, although blocking methods are provided as well.\n\nSee the modules under the tests folder for examples of how to use the library.\n\n## Example\nTry running `python -m pyiridium9602.pyiridium_server COM1` and `python -m pyiridium9602.pyiridium COM1` to see how the library works.\n\n```\n# ===== Command Line: pyiridium_server.py COM2 =====\nEnter a message to send: Hello World!\nEnter a message to send: Hi\nEnter a message to send: \n\n# ===== Command Line: pyiridium.py COM2 =====\nWarning No threads are listening for responses. A thread will be created \nSignal Quality (0 - 5): 5\nSystem Time: 3521898596\nSerial Number: 60134\nMessage acquired: b'Hello'\nMessage acquired: b'Hi'\n\n# ===== pyiridium_server.py COM2 =====\nEnter a message to send: exit\n\n# ===== Command Line: pyiridium.py COM2 =====\nMessage acquired: b'exit'\n\n# Both programs close\n```\n\nUse the Signal class (or create your own class) and use custom callback methods while the IridiumCommunicator class manages all of the communications.\n\n```python\nimport pyiridium9602\n\n# Create your own serial port object and give it as the first argument or just give it the port name.\niridium_port = pyiridium9602.IridiumCommunicator(\"COM2\")\n\n# Message parser\ndef parse_data(data):\n print(\"My data:\", data)\n\ndef message_failed(msg_len, content, checksum, calc_check):\n print(\"Message Failed checksum or length!\", msg_len, content, checksum, calc_check)\n\n# Use the default signal class and override the Signal API methods or create your own object.\niridium_port.signal.connected = lambda: print(\"Connected!\")\niridium_port.signal.disconnected = lambda: print(\"Disconnected!\")\niridium_port.signal.serial_number_updated = lambda s: print(\"Serial Number:\", s)\niridium_port.signal.system_time_updated = lambda s: print(\"System Time:\", s)\niridium_port.signal.signal_quality_updated = lambda sig: print(\"Signal Quality (0-5):\", sig)\niridium_port.signal.check_ring_updated = lambda tri, sri: print(\"Telephone Indicator:\", tri, \n \"\\nSBD Indicator:\", sri)\niridium_port.signal.message_received = parse_data\niridium_port.signal.message_receive_failed = message_failed\niridium_port.signal.notification = print\n\n# NOTE: There is no thread in this example, so `connect()` creates a thread to Complete the connection process\niridium_port.connect() # Raises IridiumError if the port cannot be opened or if the ping did not find a response.\n\n# Non blocking command requests\niridium_port.request_signal_quality()\niridium_port.queue_system_time()\n\n# If you run a request immediately after a request then the response will error\n# This is because the first command will have it's value returned while the new request is the expected command\n#iridium_port.request_serial_number()\n\n# Blocking command (wait for previous command and wait to complete)\nwith iridium_port.wait_for_command():\n iridium_port.request_signal_quality()\n\n# Blocking command (wait for previous command and wait to complete)\nwith iridium_port.wait_for_command():\n iridium_port.check_ring() # If an SBD ring is found automatically start the session to read the value.\n\n# Blocking Command (Do not wait for previous `wait_for_previous=0`)\nserial_number = iridium_port.acquire_response(pyiridium9602.Command.SERIAL_NUMBER, wait_for_previous=0)\nprint(\"Manual Serial Number:\", serial_number)\n\n# Pre-made Blocking Command\nsig = iridium_port.acquire_signal_quality()\nprint(\"Manual Signal Quality (0 - 5):\", sig)\n\n# Stop the `iridium_port.listen_thread` and close the port\niridium_port.close()\n\n```\n\n## Threading\nThe IridiumCommunicator was created to work with threading that is why the Signal callback class exists.\n\nTo use threading follow the example below.\n\n```python\nimport pyiridium9602\nimport threading\nimport time\n\n# Create your own serial port object and give it as the first argument or just give it the port name.\niridium_port = pyiridium9602.IridiumCommunicator(\"COM2\")\n\nclass CustomSignal(object):\n \"\"\"Create a cusotm Signal callback manager.\n \n Note:\n If other Signal methods do not exist they will be created as empty methods. If the notification method\n does not exist it will use the print function. You may want to use the notification method for logging special events.\n\n See Also:\n pyiridium9602.Signal\n \"\"\"\n\n def connected(self):\n \"\"\"This method is called after the connection is verified.\"\"\"\n print(\"Connected!\")\n \n def disconnected(self):\n \"\"\"This method is called after the connection is closed.\"\"\"\n print(\"Disconnected!\")\n\n def signal_quality_updated(self, signal):\n \"\"\"This method is called after a new signal quality has been received.\"\"\"\n print(\"Signal Quality (0-5):\", signal)\n \n def check_ring_updated(self, tri, sri):\n \"\"\"This method is called after a new check ring response has been received.\n \n Args:\n tri (int): Telephone ring indicator\n sri (int): SBD ring indicator\n \"\"\"\n print(\"Check Ring Response\", tri, sri)\n \n def message_received(self, data):\n \"\"\"This method is called after a message has been received and has passed the checksum.\n \n Args:\n data (bytes): Message contents without the length or checksum bytes.\n \"\"\"\n print(\"Message Received:\", data)\n\n def message_receive_failed(self, msg_len, content, checksum, calc_check):\n \"\"\"This method is called after a message has benn received and it failed the checksum or does not meet the \n message length.\n\n Args:\n msg_len (int): Parsed length of the message (the first 2 byes).\n content (bytes): Content portion of the message without the first 2 bytes (message length) and the last \n 2 bytes (checksum).\n checksum (bytes): 2 checksum bytes that were included with the message.\n calc_check (bytes): 2 calculated checksum bytes from the content.\n \"\"\"\n print(\"Message Failed checksum or length!\", msg_len, content, checksum, calc_check)\n\n# Set the signal callback manager\niridium_port.signal = CustomSignal()\n\n# Manually creating the thread\nth = threading.Thread(target=iridium_port.listen)\nth.start()\n\n# The IridiumCommunicator needs to know if a method is reading the serial port `IridiumCommunicator.listen()`\n# If the thread isn't using `IridiumCommunicator.listen()` and tell the that it is listening\n#iridium_port.set_listening(True)\n\n# Because the iridium_port knows it is listening it will not create it's own thread. \niridium_port.connect() # Raises IridiumError if the port cannot be opened or if the ping did not find a response.\n\n# Blocking methods example\nsys_time = iridium_port.acquire_system_time()\nprint(\"System Time:\", sys_time)\n\nserial_number = iridium_port.acquire_serial_number()\nprint(\"Serial Number:\", serial_number)\n\n# Non blocking command requests.\n# Note the previous command was blocking so we know it is finished\niridium_port.request_signal_quality()\n\n# Wait for the response\ntime.sleep(2)\n\n# Note `time.sleep(2)` is blocking so the previous command should be finished. We don't really know how long it takes\nwith iridium_port.wait_for_command(wait_for_previous=0):\n iridium_port.check_ring()\n\n# Note the ring command finished, but the subsequent (if SBD Ring was more than 0) Session SBDIX probably did not.\ntime.sleep(2)\n\n# Stop the `iridium_port.listen_thread` and close the port\niridium_port.close()\nth.join()\n\n```", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/justengel/pyiridium9602/archive/v1.2.3.zip", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/justengel/pyiridium9602", "keywords": "iridium 9602 iridium9602 serial", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pyiridium9602", "package_url": "https://pypi.org/project/pyiridium9602/", "platform": "any", "project_url": "https://pypi.org/project/pyiridium9602/", "project_urls": { "Download": "https://github.com/justengel/pyiridium9602/archive/v1.2.3.zip", "Homepage": "https://github.com/justengel/pyiridium9602" }, "release_url": "https://pypi.org/project/pyiridium9602/1.2.3/", "requires_dist": null, "requires_python": "", "summary": "Python 3 iridium communication library for the iridium 9602 modem.", "version": "1.2.3" }, "last_serial": 5222975, "releases": { "1.2.0": [ { "comment_text": "", "digests": { "md5": "395c93d77f01b3c157b056a9636d9310", "sha256": "a4c48019ea2821b64d22ac7b20abf65c54a97b060eef4de4247b18a5ec2152e4" }, "downloads": -1, "filename": "pyiridium9602-1.2.0.tar.gz", "has_sig": false, "md5_digest": "395c93d77f01b3c157b056a9636d9310", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30785, "upload_time": "2018-05-04T22:26:26", "url": "https://files.pythonhosted.org/packages/d2/a9/b39ada72fec2f50ca690f74bbd6aca630079768c3f542d663772c9370ccc/pyiridium9602-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "15f0cfdfe18a705b181a2668f78a326d", "sha256": "347e8c34a86279607c6fb61217af6a1bfbf60ab25c1c6ef71a11911fe696d313" }, "downloads": -1, "filename": "pyiridium9602-1.2.1.tar.gz", "has_sig": false, "md5_digest": "15f0cfdfe18a705b181a2668f78a326d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30794, "upload_time": "2018-05-12T12:33:27", "url": "https://files.pythonhosted.org/packages/f1/40/48d6cd22bf0214ec6a08af316a5be376764eb688047b2ba2d5925605af1b/pyiridium9602-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "4d3662ca659636e20ec4325106c29288", "sha256": "0c59aa250d214317fc928181d548975106d4789f4de6834323818cd0fe1f5d2b" }, "downloads": -1, "filename": "pyiridium9602-1.2.2.tar.gz", "has_sig": false, "md5_digest": "4d3662ca659636e20ec4325106c29288", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30947, "upload_time": "2018-08-15T18:34:44", "url": "https://files.pythonhosted.org/packages/3d/00/783571102c481b90ebbcc04b940f095e065188bb133499d411debde93b49/pyiridium9602-1.2.2.tar.gz" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "dd3b410c0f0e8cb30ea299d75d9c8b7e", "sha256": "adfbc455a5d4eededbb2575bad1a375eb66b15e33fd635df29c7fc8e1e8b5214" }, "downloads": -1, "filename": "pyiridium9602-1.2.3.tar.gz", "has_sig": false, "md5_digest": "dd3b410c0f0e8cb30ea299d75d9c8b7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31564, "upload_time": "2019-05-03T17:42:08", "url": "https://files.pythonhosted.org/packages/53/9b/39586983eb4582763d8405455712a56c7e074d249f8dde17d24bbb1a3d8b/pyiridium9602-1.2.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "dd3b410c0f0e8cb30ea299d75d9c8b7e", "sha256": "adfbc455a5d4eededbb2575bad1a375eb66b15e33fd635df29c7fc8e1e8b5214" }, "downloads": -1, "filename": "pyiridium9602-1.2.3.tar.gz", "has_sig": false, "md5_digest": "dd3b410c0f0e8cb30ea299d75d9c8b7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31564, "upload_time": "2019-05-03T17:42:08", "url": "https://files.pythonhosted.org/packages/53/9b/39586983eb4582763d8405455712a56c7e074d249f8dde17d24bbb1a3d8b/pyiridium9602-1.2.3.tar.gz" } ] }