Skip to content

Commit

Permalink
Merge pull request #29 from AmedeeBulle/classc
Browse files Browse the repository at this point in the history
 Bump version: 0.8.4 → 0.8.5
  • Loading branch information
AmedeeBulle committed Feb 27, 2022
2 parents 6e48edc + 5778541 commit f08c1d8
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 53 deletions.
60 changes: 60 additions & 0 deletions .github/workflows/test-and-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Test and Publish

on:
- push
- pull_request

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8']

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox tox-gh-actions
- name: Run tests
run: tox
- name: Upload coverage
if: ${{ matrix.python-version == '3.8' }}
uses: codecov/codecov-action@v2
publish:
needs: test
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
python -m pip install build
- name: Build package
run: |
python -m build --sdist --wheel --outdir dist/ .
- name: Publish untagged package to Test PyPI
if: ${{ ! startsWith(github.ref, 'refs/tags/v') }}
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
- name: Publish tagged package to PyPI
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ build
dist
.coverage
htmlcov
coverage.xml
.tox
40 changes: 0 additions & 40 deletions .travis.yml

This file was deleted.

7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# RAK811 Python 3 library for Raspberry Pi

[![Latest Version](https://img.shields.io/pypi/v/rak811.svg)](https://pypi.org/project/rak811/)
[![Build Status](https://travis-ci.org/AmedeeBulle/pyrak811.svg?branch=main)](https://travis-ci.org/AmedeeBulle/pyrak811)
[![GitHub Action (Test and Publish)](https://github.com/AmedeeBulle/pyrak811/actions/workflows/test-and-publish.yml/badge.svg)](https://github.com/AmedeeBulle/pyrak811)
[![codecov](https://codecov.io/gh/AmedeeBulle/pyrak811/branch/main/graph/badge.svg)](https://codecov.io/gh/AmedeeBulle/pyrak811)

## About

RAK811 Python 3 library and command-line interface for use with the Raspberry Pi LoRa pHAT.
RAK811 Python 3 library and command-line interface for use with the Raspberry Pi LoRa (p)HAT.

The library exposes the RAK811 module AT commands as described in the following documents:

Expand All @@ -18,7 +18,7 @@ The command-line interface exposes all API calls to the command line.
## Requirements

- A Raspberry Pi!
- A RAK811 LoRa module ([PiSupply IoT LoRa Node pHAT for Raspberry Pi](https://uk.pi-supply.com/products/iot-lora-node-phat-for-raspberry-pi))
- A RAK811 LoRa module ([PiSupply IoT LoRa Node pHAT for Raspberry Pi](https://uk.pi-supply.com/products/iot-lora-node-phat-for-raspberry-pi) / [RAK811 WisNode - LoRa](https://news.rakwireless.com/wisnode-lora-quick-start/))
- On the Raspberry Pi the hardware serial port must be enabled and the serial console disabled (use `raspi-config`)
- The user running the application must be in the `dialout` and `gpio` groups (this is the default for the `pi` user)

Expand Down Expand Up @@ -119,6 +119,7 @@ See the [example directory on GitHub](https://github.com/AmedeeBulle/pyrak811/tr

- `api_demo.py`: demo most of the V2.0.x API calls
- `otaa.py` / `otaa_v3.py`: OTAA example
- `otaa_v3_class_c.py`: OTAA example with device in Class C mode
- `abp.py` / `abp_v3.py`: ABP example
- `p2p.py` / `p2p_v3.py`: P2P example
- `p2p.sh` / `p2p_v3.sh`: P2P example based on the command-line interface (see below)
Expand Down
111 changes: 111 additions & 0 deletions examples/otaa_v3_class_c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""RAK811 OTAA Class C demo.
Minimalistic OTAA demo with Class C device (v3.x firmware).
The module will wait on downlink message, run a task and send an the same data
back as uplink
The module uses receive_p2p to get out-of-band downlinks.
The device must be configured as a Class C device in your LoRaWan Application
Server (TTN/TTS).
Note that delivery of downlinks is not guaranteed:
- Device might not receive the signal
- The device is not listening when in send mode
Copyright 2022 Philippe Vanhaesendonck
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
"""
import logging
from random import randint
from sys import exit
from time import sleep
from timeit import default_timer as timer
from traceback import print_exc

from rak811.rak811_v3 import Rak811, Rak811ResponseError
from ttn_secrets import APP_EUI, APP_KEY

# Set level to logging.DEBUG for a verbose output
logging.basicConfig(level=logging.INFO)

lora = Rak811()

# Most of the setup should happen only once...
print("Setup")
# Ensure we are in LoRaWan mode / Class C
lora.set_config("lora:work_mode:0")
lora.set_config("lora:class:2")
# Select OTAA
lora.set_config("lora:join_mode:0")
# Select region
lora.set_config("lora:region:EU868")
# Set keys
lora.set_config(f"lora:app_eui:{APP_EUI}")
lora.set_config(f"lora:app_key:{APP_KEY}")
# Set data rate
# Note that DR is different from SF and depends on the region
# See: https://docs.exploratory.engineering/lora/dr_sf/
# Set Data Rate to 5 which is SF7/125kHz for EU868
lora.set_config("lora:dr:5")

# Print config
for line in lora.get_config("lora:status"):
print(f" {line}")

print("Joining")
start_time = timer()
lora.join()
print("Joined in {:.2f} secs".format(timer() - start_time))

print("Sending initial Hello packet")
start_time = timer()
lora.send("Hello")
print("Packet sent in {:.2f} secs".format(timer() - start_time))
print("Entering wait loop")
print("You can send downlinks from the TTN console")
try:
while True:
print("Waiting for downlinks...")
try:
lora.receive_p2p(60)
except Rak811ResponseError as e:
print("Error while waiting for downlink {}: {}".format(e.errno, e.strerror))
while lora.nb_downlinks:
data = lora.get_downlink()["data"]
if data != b"":
print("Downlink received", data.hex())
# simulate some processing time
sleep(randint(5, 10))
print("Sending back results")
start_time = timer()
try:
lora.send(data)
print("Packet sent in {:.2f} secs".format(timer() - start_time))
except Rak811ResponseError as e:
print("Error while sendind data {}: {}".format(e.errno, e.strerror))


except KeyboardInterrupt:
print()
except Exception:
print_exc()

print("Cleaning up")
lora.close()
exit(0)
10 changes: 10 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[build-system]
requires = [
"setuptools>=45",
"setuptools_scm[toml]>=6.2",
"wheel",
]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
local_scheme = "no-local-version"
4 changes: 2 additions & 2 deletions rak811/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
from .exception import Rak811Error # noqa: F401

try:
__version__ = pkg_resources.get_distribution('setuptools').version
__version__ = pkg_resources.get_distribution("rak811").version
except Exception:
__version__ = 'unknown'
__version__ = "unknown"
23 changes: 17 additions & 6 deletions rak811/rak811_v3.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Interface with the RAK811 module (Firmware V3.0).
Copyright 2021 Philippe Vanhaesendonck
Copyright 2021, 2022 Philippe Vanhaesendonck
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -241,14 +241,21 @@ def _send_command(self, command: str, timeout: float = None) -> str:
if timeout is None:
timeout = self._response_timeout

# Process possible pending events
try:
self._process_events(timeout=0.01)
logger.debug('Pending event queue flushed')
except (Rak811ResponseError, Rak811TimeoutError):
pass

self._serial.send_command(command)
response = self._serial.receive(timeout=timeout)

# Ignore anything but OK/ERROR messages
while not (response.startswith(RESPONSE_OK)
or response.startswith(RESPONSE_INIT_OK)
or response.startswith(RESPONSE_ERROR)):
response = self._serial.receive()
response = self._serial.receive(timeout=timeout)

if response.startswith(RESPONSE_ERROR):
raise Rak811ResponseError(response[len(RESPONSE_ERROR):])
Expand Down Expand Up @@ -524,9 +531,11 @@ def send(self, data: Union[bytes, str], port: int = 1) -> None:
try:
self._process_events(timeout=0.1)
except Rak811TimeoutError:
logger.debug('No downlink')
else:
pass
if self.nb_downlinks:
logger.debug('Downlink available')
else:
logger.debug('No downlink')

@property
def nb_downlinks(self) -> int:
Expand Down Expand Up @@ -587,6 +596,8 @@ def receive_p2p(self, timeout: float) -> None:
try:
self._process_events(timeout=timeout)
except Rak811TimeoutError:
logger.debug('Nothing received')
else:
pass
if self.nb_downlinks:
logger.debug('Message available')
else:
logger.debug('Nothing received')
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

setup(
name='rak811',
version='0.8.4',
use_scm_version={"local_scheme": "no-local-version"},
description='Interface for RAK811 LoRa module',
long_description=long_description,
long_description_content_type='text/markdown',
Expand All @@ -46,6 +46,7 @@
],
packages=find_packages(),
python_requires='>=3.5',
setup_requires=['setuptools_scm'],
install_requires=[
'click>=7.1',
'pyserial',
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
envlist = flake8, py37, py38
skip_missing_interpreters = true

[travis]
[gh-actions]
python =
3.7: py37
3.8: flake8, py38
Expand All @@ -21,6 +21,7 @@ commands =
coverage erase
coverage run --source rak811 -m py.test -v
coverage html
coverage xml
coverage report --fail-under 95

[testenv:flake8]
Expand Down

0 comments on commit f08c1d8

Please sign in to comment.