Skip to content

Commit

Permalink
Make changes to support HitL testing.
Browse files Browse the repository at this point in the history
- Rename all examples so that they have underscores instead of hyphens. .py
files with hyphens in their names can't be imported.
- Add a test/hitl/ directory with one test (so far): cpy_test.py. This test
makes sure that cpy_example.py runs successfully on a CircuitPython host
connected to a Notecard. I tested using a Notecarrier F and a Swan.
- cpy_test.py relies on pyboard.py from MicroPython. I have added that file
from MicroPython's master branch here.
  • Loading branch information
haydenroche5 committed Aug 1, 2023
1 parent b52e7bb commit e3b1bb5
Show file tree
Hide file tree
Showing 8 changed files with 1,007 additions and 42 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ The documentation for this library can be found
The [examples](examples/) directory contains examples for using this
library with:

- [Serial](examples/notecard-basics/serial-example.py)
- [I2C](examples/notecard-basics/i2c-example.py)
- [RaspberryPi](examples/notecard-basics/rpi-example.py)
- [CircuitPython](examples/notecard-basics/cpy-example.py)
- [MicroPython](examples/notecard-basics/mpy-example.py)
- [Serial](examples/notecard-basics/serial_example.py)
- [I2C](examples/notecard-basics/i2c_example.py)
- [RaspberryPi](examples/notecard-basics/rpi_example.py)
- [CircuitPython](examples/notecard-basics/cpy_example.py)
- [MicroPython](examples/notecard-basics/mpy_example.py)

## Contributing

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
import time
import notecard

productUID = "com.your-company.your-project"

# Choose either UART or I2C for Notecard
use_uart = True

if sys.implementation.name != 'circuitpython':
if sys.implementation.name != "circuitpython":
raise Exception("Please run this example in a CircuitPython environment.")

import board # noqa: E402
Expand All @@ -30,18 +25,18 @@ def NotecardExceptionInfo(exception):
"""
name = exception.__class__.__name__
return sys.platform + ": " + name \
+ ": " + ' '.join(map(str, exception.args))
+ ": " + " ".join(map(str, exception.args))


def configure_notecard(card):
def configure_notecard(card, product_uid):
"""Submit a simple JSON-based request to the Notecard.
Args:
card (object): An instance of the Notecard class
"""
req = {"req": "hub.set"}
req["product"] = productUID
req["product"] = product_uid
req["mode"] = "continuous"

try:
Expand Down Expand Up @@ -76,41 +71,37 @@ def get_temp_and_voltage(card):
return temp, voltage


def main():
def run_example(product_uid, use_uart=True):
"""Connect to Notcard and run a transaction test."""
print("Opening port...")
try:
if use_uart:
port = busio.UART(board.TX, board.RX, baudrate=9600)
else:
port = busio.I2C(board.SCL, board.SDA)
except Exception as exception:
raise Exception("error opening port: "
+ NotecardExceptionInfo(exception))
if use_uart:
port = busio.UART(board.TX, board.RX, baudrate=9600)
else:
port = busio.I2C(board.SCL, board.SDA)

print("Opening Notecard...")
try:
if use_uart:
card = notecard.OpenSerial(port, debug=True)
else:
card = notecard.OpenI2C(port, 0, 0, debug=True)
except Exception as exception:
raise Exception("error opening notecard: "
+ NotecardExceptionInfo(exception))
if use_uart:
card = notecard.OpenSerial(port, debug=True)
else:
card = notecard.OpenI2C(port, 0, 0, debug=True)

# If success, configure the Notecard and send some data
configure_notecard(card)
configure_notecard(card, product_uid)
temp, voltage = get_temp_and_voltage(card)

req = {"req": "note.add"}
req["sync"] = True
req["body"] = {"temp": temp, "voltage": voltage}

try:
card.Transaction(req)
except Exception as exception:
print("Transaction error: " + NotecardExceptionInfo(exception))
time.sleep(5)
card.Transaction(req)

# Developer note: do not modify the line below, as we use this as to signify
# that the example ran successfully to completion. We then use that to
# determine pass/fail for certain tests that leverage these examples.
print('Example complete.')

main()
if __name__ == '__main__':
product_uid = "com.your-company.your-project"
# Choose either UART or I2C for Notecard
use_uart = True
run_example(product_uid, use_uart)
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import time
import notecard

productUID = "com.your-company.your-project"
productUID = "com.blues.hroche:python_hitl_testing"

# Choose either UART or I2C for Notecard
use_uart = True
Expand Down Expand Up @@ -76,7 +76,7 @@ def get_temp_and_voltage(card):
return temp, voltage


def main():
def run_example():
"""Connect to Notcard and run a transaction test."""
print("Opening port...")
try:
Expand Down Expand Up @@ -114,5 +114,4 @@ def main():
print("Transaction error: " + NotecardExceptionInfo(exception))
time.sleep(5)


main()
run_example()
File renamed without changes.
File renamed without changes.
55 changes: 55 additions & 0 deletions test/hitl/cpy_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import argparse
from pathlib import Path
import shutil
import pyboard

def main(args):
# Get the path to the root of the note-python repository.
note_python_root_dir = Path(__file__).parent.parent.parent
notecard_dir = note_python_root_dir / 'notecard'
# Get a list of all the .py files in note-python/notecard/.
notecard_files = list(notecard_dir.glob('*.py'))
circuitpy_dir = Path(args.circuitpy_dir)
cpy_notecard_dir = circuitpy_dir / 'lib' / 'notecard'
# Create the /lib/notecard directory on the CircuitPython host.
cpy_notecard_dir.mkdir(exist_ok=True, parents=True)

print(f'Copying notecard .py files to host...')
for f in notecard_files:
print(f' {f.name}')
shutil.copy(f, cpy_notecard_dir / f.name)
print('Done.')

# Copy over cpy_example.py. We'll run this example code on the CircuitPython
# host to 1) verify that the host is able to use note-python to communicate
# with the Notecard and 2) verify that the example isn't broken.
examples_dir = note_python_root_dir / 'examples'
cpy_example_file = examples_dir / 'notecard-basics' / 'cpy_example.py'
print(f'Copying over {cpy_example_file}...', end='')
shutil.copy(cpy_example_file, circuitpy_dir / cpy_example_file.name)
print('Done.')

# We use pyboard from the MicroPython project to run code remotely on the
# host: https://github.com/micropython/micropython/blob/master/tools/pyboard.py
pyb = pyboard.Pyboard(args.port, 115200)
for use_uart in [False, True]:
pyb.enter_raw_repl()
# Run the example code, with serial (use_uart True) and I2C
# (use_uart False).
cmd = f'from cpy_example import run_example; run_example("{args.product_uid}", {use_uart})'
print(f"Running test command: {cmd}")
output = pyb.exec(cmd)
output = output.decode()
print(output)
if 'Example complete.' not in output:
raise Exception(f'Test failed. See output above.')

print('Tests passed!')

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Run hardware-in-the-loop test against a CircuitPython host.')
parser.add_argument('--circuitpy-dir', '-c', required=True, help='The path to the CIRCUITPY directory.')
parser.add_argument('--port', '-p', required=True, help='The serial port of the CircuitPython host (e.g. /dev/ttyACM0).')
parser.add_argument('--product-uid', '-i', required=True, help='The ProductUID to set on the Notecard.')
args = parser.parse_args()
main(args)
Loading

0 comments on commit e3b1bb5

Please sign in to comment.