{ "info": { "author": "Anne Wood", "author_email": "anne.w@fastmail.us", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries", "Topic :: System :: Hardware" ], "description": "# Overview\n\nThis project is a Python library for using HopeRF RFM95/96/97/98 LoRa radios with a Raspberry Pi. The design was inspired by the [RadioHead](http://www.airspayce.com/mikem/arduino/RadioHead) project that is popular on Arduino-based platforms. Several handy features offered by RadioHead are present here, including encryption, addressing, acknowledgments and retransmission. The motivation of this project is to allow Raspberry Pis to communicate with devices using the [RadioHead RF95](http://www.airspayce.com/mikem/arduino/RadioHead/classRH__RF95.html) driver along with [RHReliableDatagram](http://www.airspayce.com/mikem/arduino/RadioHead/classRHReliableDatagram.html) and [RHEncryptedDriver](http://www.airspayce.com/mikem/arduino/RadioHead/classRHEncryptedDriver.html).\n\n# Usage\n### Installation\nRequires Python >= 3.5. [RPi.GPIO](https://pypi.python.org/pypi/RPi.GPIO) and [spidev](https://pypi.python.org/pypi/spidev) will be installed as requirements\n```\npip install raspi-lora\n```\n\n### Getting Started\nHere's a quick example that sets things up and sends a message:\n```\nfrom raspi_lora import LoRa, ModemConfig\n\n# This is our callback function that runs when a message is received\ndef on_recv(payload):\n print(\"From:\", payload.header_from)\n print(\"Received:\", payload.message)\n print(\"RSSI: {}; SNR: {}\".format(payload.rssi, payload.snr))\n\n# Use chip select 0. GPIO pin 17 will be used for interrupts\n# The address of this device will be set to 2\nlora = LoRa(0, 17, 2, modem_config=ModemConfig.Bw125Cr45Sf128, tx_power=14, acks=True)\nlora.on_recv = on_recv\n\nlora.set_mode_rx()\n\n# Send a message to a recipient device with address 10\n# Retry sending the message twice if we don't get an acknowledgment from the recipient\nmessage = \"Hello there!\"\nstatus = lora.send_to_wait(message, 10, retries=2)\nif status is True:\n print(\"Message sent!\")\nelse:\n print(\"No acknowledgment from recipient\")\n\n# And remember to call this as your program exits...\nlora.close()\n```\n\n### Encryption\nIf you'd like to send and receive encrypted packets, you'll need to install the [PyCryptodome](https://pycryptodome.readthedocs.io) package. If you're working with devices running RadioHead with RHEncryptedDriver, I recommend using the AES cipher.\n```\npip install pycryptodome\n```\n\nand in your code:\n```\nfrom Crypto.Cipher import AES\ncrypto = AES.new(b\"my-secret-encryption-key\", AES.MODE_EAX)\n```\nthen pass in `crypto` when instantiating the `LoRa` object:\n```\nlora = LoRa(0, 17, 2, crypto=crypto)\n```\n\n### Configuration\n##### Initialization\n```\nLoRa(channel, interrupt, this_address, freq=915, tx_power=14,\n modem_config=ModemConfig.Bw125Cr45Sf128, acks=False, crypto=None)\n```\n**`channel`** SPI channel to use (either 0 or 1, if your LoRa radio is connected to CE0 or CE1, respectively)\n\n**`interrupt`** GPIO pin (BCM-style numbering) to use for the interrupt\n\n**`this_address`** The address number (0-254) your device will use when sending and receiving packets.\n\n**`freq`** Frequency used by your LoRa radio. Defaults to 915Mhz\n\n**`tx_power`** Transmission power level from 5 to 23. Keep this as low as possible. Defaults to 14\n\n**`model_config`** Modem configuration. See [RadioHead docs](http://www.airspayce.com/mikem/arduino/RadioHead/classRH__RF95.html#ab9605810c11c025758ea91b2813666e3). Default to Bw125Cr45Sf128.\n\n**`receive_all`** Receive messages regardless of the destination address\n\n**`acks`** If `True`, send an acknowledgment packet when a message is received and wait for an acknowledgment when transmitting a message. This is equivalent to using RadioHead's RHReliableDatagram\n\n**`crypto`** An instance of PyCryptodome Cipher.AES (see above example)\n\n\n##### Other options:\nA `LoRa` instance also has the following attributes that can be changed:\n- **cad_timeout** Timeout for channel activity detection. Default is 0\n- **retry_timeout** Time to wait for an acknowledgment before attempting a retry. Defaults to 0.2 seconds\n- **wait_packet_sent_timeout** Timeout for waiting for a packet to transmit. Default is 0.2 seconds\n\n##### Methods\n###### `send_to_wait(data, header_to, header_flags=0)`\nSend a message and block until an acknowledgment is received or a timeout occurs. Returns `True` if successful\n- ``data`` Your message. Can be a string or byte string\n- ``header_to`` Address of recipient (0-255). If address is 255, the message will be broadcast to all devices and **`send_to_wait()`** will return `True` without waiting for acknowledgments\n- ``header_flags`` Bitmask that can contain flags specific to your application\n\n###### `send(data, header_to, header_id=0, header_flags=0)`\nSimilar to `send_to_wait` but does not block or wait for acknowledgments and will always return `True`\n- ``data`` Your message. Can be a string or byte string\n- ``header_id`` Unique ID of message (0-255)\n- ``header_to`` Address of recipient (0-255). If address is 255, the message will be broadcast to all devices\n- ``header_flags`` Bitmask that can contain flags specific to your application\n\n###### `set_mode_rx()`\nSet radio to RX continuous mode\n\n###### `set_mode_tx()`\nSet radio to TX mode\n\n###### `set_mode_idle()`\nSet radio to idle (disabling receiving or transmitting)\n\n###### `sleep()`\nSet radio to low-power sleep mode\n\n###### `wait_packet_sent()`\nBlocks until a packet has finished transmitting. Returns `False` if a timeout occurs\n\n###### `close()`\nCleans up GPIO pins and closes the SPI connection. This should be called when your program exits.\n\n\n#### Callbacks\n`on_recv(payload)` \nCallback function that runs when a message is received\n`payload` has the following attributes:\n`header_from`, `header_to`, `header_id`, `header_flags`, `message`, `rssi`, `snr`\n\n# Resources\n[RadioHead](http://www.airspayce.com/mikem/arduino/RadioHead/) - The RadioHead project. Very useful source of information on working with LoRa radios.\n\n[Forked version of RadioHead for Raspberry Pi](https://github.com/hallard/RadioHead) - A fork of the original RadioHead project that better accommodates the Raspberry Pi. Currently is a few years out of date.\n\n[pySX127x](https://github.com/mayeranalytics/pySX127x) - Another Python LoRa library that allows for a bit more configuration. \n\n[Adafruit CircuitPython module for the RFM95/6/7/8](https://github.com/adafruit/Adafruit_CircuitPython_RFM9x) - LoRa library for CircuitPython\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://gitlab.com/the-plant/raspi-lora", "keywords": "lora rfm95 rfm9x rfm96 rfm97 rfm98 hardware raspberrypi", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "raspi-lora", "package_url": "https://pypi.org/project/raspi-lora/", "platform": "", "project_url": "https://pypi.org/project/raspi-lora/", "project_urls": { "Homepage": "https://gitlab.com/the-plant/raspi-lora" }, "release_url": "https://pypi.org/project/raspi-lora/0.2/", "requires_dist": [ "RPi.GPIO", "spidev" ], "requires_python": "", "summary": "LoRa RFM9x library for Raspberry Pi inspired by RadioHead", "version": "0.2" }, "last_serial": 5269535, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "d13517e0ea65eab65fc40eb2c58beb23", "sha256": "523eada1ef30e0ecffb84574f885e40f8b8134d8488cb63a4219c11a42df11d1" }, "downloads": -1, "filename": "raspi_lora-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "d13517e0ea65eab65fc40eb2c58beb23", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5749, "upload_time": "2019-02-11T22:09:59", "url": "https://files.pythonhosted.org/packages/e9/99/1246f07e7a0c4319469f44fd6222f6972fc21021ce40790004cdb9572b27/raspi_lora-0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "49d1c36ec102aa50e536398453622922", "sha256": "822201aa2b745294c89dbd7fe9265124585dcc032f9c63220b66bbbf53779638" }, "downloads": -1, "filename": "raspi-lora-0.1.tar.gz", "has_sig": false, "md5_digest": "49d1c36ec102aa50e536398453622922", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6341, "upload_time": "2019-02-11T22:10:00", "url": "https://files.pythonhosted.org/packages/d2/6b/878d0925cea6e6bda29fac09e17e21fd602dae45e47a96c84671b0529e10/raspi-lora-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "2d1a824f74e0ab096534bbc6b04c8403", "sha256": "845c3703f0850498ffd729e32251c5cfd979686a267fd8c418e431f7735911ca" }, "downloads": -1, "filename": "raspi_lora-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "2d1a824f74e0ab096534bbc6b04c8403", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8260, "upload_time": "2019-05-14T21:51:50", "url": "https://files.pythonhosted.org/packages/46/f1/16a1fcc072995832cdc7b482be248ff4b494be517a4515b96fd696b98871/raspi_lora-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7904679832589968ea3c9d1b2f41a540", "sha256": "476e10881acb0874e2019927a0725ec902019e3c90afec6f628d5e615dbdb045" }, "downloads": -1, "filename": "raspi-lora-0.2.tar.gz", "has_sig": false, "md5_digest": "7904679832589968ea3c9d1b2f41a540", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6959, "upload_time": "2019-05-14T21:51:51", "url": "https://files.pythonhosted.org/packages/64/ab/1cebc01cb64935de6cd421656ed4d2779740a843b73a9afd7b6d9dde76f1/raspi-lora-0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2d1a824f74e0ab096534bbc6b04c8403", "sha256": "845c3703f0850498ffd729e32251c5cfd979686a267fd8c418e431f7735911ca" }, "downloads": -1, "filename": "raspi_lora-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "2d1a824f74e0ab096534bbc6b04c8403", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8260, "upload_time": "2019-05-14T21:51:50", "url": "https://files.pythonhosted.org/packages/46/f1/16a1fcc072995832cdc7b482be248ff4b494be517a4515b96fd696b98871/raspi_lora-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7904679832589968ea3c9d1b2f41a540", "sha256": "476e10881acb0874e2019927a0725ec902019e3c90afec6f628d5e615dbdb045" }, "downloads": -1, "filename": "raspi-lora-0.2.tar.gz", "has_sig": false, "md5_digest": "7904679832589968ea3c9d1b2f41a540", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6959, "upload_time": "2019-05-14T21:51:51", "url": "https://files.pythonhosted.org/packages/64/ab/1cebc01cb64935de6cd421656ed4d2779740a843b73a9afd7b6d9dde76f1/raspi-lora-0.2.tar.gz" } ] }