Skip to content

Commit 25373cc

Browse files
committed
Make changes to support HitL testing.
1 parent b52e7bb commit 25373cc

File tree

10 files changed

+1105
-71
lines changed

10 files changed

+1105
-71
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ The documentation for this library can be found
136136
The [examples](examples/) directory contains examples for using this
137137
library with:
138138

139-
- [Serial](examples/notecard-basics/serial-example.py)
140-
- [I2C](examples/notecard-basics/i2c-example.py)
141-
- [RaspberryPi](examples/notecard-basics/rpi-example.py)
142-
- [CircuitPython](examples/notecard-basics/cpy-example.py)
143-
- [MicroPython](examples/notecard-basics/mpy-example.py)
139+
- [Serial](examples/notecard-basics/serial_example.py)
140+
- [I2C](examples/notecard-basics/i2c_example.py)
141+
- [RaspberryPi](examples/notecard-basics/rpi_example.py)
142+
- [CircuitPython](examples/notecard-basics/cpy_example.py)
143+
- [MicroPython](examples/notecard-basics/mpy_example.py)
144144

145145
## Contributing
146146

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@
77
import time
88
import notecard
99

10-
productUID = "com.your-company.your-project"
11-
12-
# Choose either UART or I2C for Notecard
13-
use_uart = True
14-
15-
if sys.implementation.name != 'circuitpython':
10+
if sys.implementation.name != "circuitpython":
1611
raise Exception("Please run this example in a CircuitPython environment.")
1712

1813
import board # noqa: E402
@@ -30,18 +25,18 @@ def NotecardExceptionInfo(exception):
3025
"""
3126
name = exception.__class__.__name__
3227
return sys.platform + ": " + name \
33-
+ ": " + ' '.join(map(str, exception.args))
28+
+ ": " + " ".join(map(str, exception.args))
3429

3530

36-
def configure_notecard(card):
31+
def configure_notecard(card, product_uid):
3732
"""Submit a simple JSON-based request to the Notecard.
3833
3934
Args:
4035
card (object): An instance of the Notecard class
4136
4237
"""
4338
req = {"req": "hub.set"}
44-
req["product"] = productUID
39+
req["product"] = product_uid
4540
req["mode"] = "continuous"
4641

4742
try:
@@ -76,41 +71,38 @@ def get_temp_and_voltage(card):
7671
return temp, voltage
7772

7873

79-
def main():
74+
def run_example(product_uid, use_uart=True):
8075
"""Connect to Notcard and run a transaction test."""
8176
print("Opening port...")
82-
try:
83-
if use_uart:
84-
port = busio.UART(board.TX, board.RX, baudrate=9600)
85-
else:
86-
port = busio.I2C(board.SCL, board.SDA)
87-
except Exception as exception:
88-
raise Exception("error opening port: "
89-
+ NotecardExceptionInfo(exception))
77+
if use_uart:
78+
port = busio.UART(board.TX, board.RX, baudrate=9600)
79+
else:
80+
port = busio.I2C(board.SCL, board.SDA)
9081

9182
print("Opening Notecard...")
92-
try:
93-
if use_uart:
94-
card = notecard.OpenSerial(port, debug=True)
95-
else:
96-
card = notecard.OpenI2C(port, 0, 0, debug=True)
97-
except Exception as exception:
98-
raise Exception("error opening notecard: "
99-
+ NotecardExceptionInfo(exception))
83+
if use_uart:
84+
card = notecard.OpenSerial(port, debug=True)
85+
else:
86+
card = notecard.OpenI2C(port, 0, 0, debug=True)
10087

10188
# If success, configure the Notecard and send some data
102-
configure_notecard(card)
89+
configure_notecard(card, product_uid)
10390
temp, voltage = get_temp_and_voltage(card)
10491

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

109-
try:
110-
card.Transaction(req)
111-
except Exception as exception:
112-
print("Transaction error: " + NotecardExceptionInfo(exception))
113-
time.sleep(5)
96+
card.Transaction(req)
97+
98+
# Developer note: do not modify the line below, as we use this as to signify
99+
# that the example ran successfully to completion. We then use that to
100+
# determine pass/fail for certain tests that leverage these examples.
101+
print("Example complete.")
114102

115103

116-
main()
104+
if __name__ == "__main__":
105+
product_uid = "com.your-company.your-project"
106+
# Choose either UART or I2C for Notecard
107+
use_uart = True
108+
run_example(product_uid, use_uart)
Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@
77
import time
88
import notecard
99

10-
productUID = "com.your-company.your-project"
11-
12-
# Choose either UART or I2C for Notecard
13-
use_uart = True
14-
15-
if sys.implementation.name != 'micropython':
10+
if sys.implementation.name != "micropython":
1611
raise Exception("Please run this example in a MicroPython environment.")
1712

1813
from machine import UART # noqa: E402
1914
from machine import I2C # noqa: E402
15+
from machine import Pin
2016

2117

2218
def NotecardExceptionInfo(exception):
@@ -30,18 +26,18 @@ def NotecardExceptionInfo(exception):
3026
"""
3127
name = exception.__class__.__name__
3228
return sys.platform + ": " + name + ": " \
33-
+ ' '.join(map(str, exception.args))
29+
+ " ".join(map(str, exception.args))
3430

3531

36-
def configure_notecard(card):
32+
def configure_notecard(card, product_uid):
3733
"""Submit a simple JSON-based request to the Notecard.
3834
3935
Args:
4036
card (object): An instance of the Notecard class
4137
4238
"""
4339
req = {"req": "hub.set"}
44-
req["product"] = productUID
40+
req["product"] = product_uid
4541
req["mode"] = "continuous"
4642

4743
try:
@@ -76,43 +72,43 @@ def get_temp_and_voltage(card):
7672
return temp, voltage
7773

7874

79-
def main():
75+
def run_example(product_uid, use_uart=True):
8076
"""Connect to Notcard and run a transaction test."""
8177
print("Opening port...")
82-
try:
83-
if use_uart:
84-
port = UART(2, 9600)
85-
port.init(9600, bits=8, parity=None, stop=1,
86-
timeout=3000, timeout_char=100)
78+
if use_uart:
79+
port = UART(2, 9600)
80+
port.init(9600, bits=8, parity=None, stop=1,
81+
timeout=3000, timeout_char=100)
82+
else:
83+
# If you"re using an ESP32, connect GPIO 22 to SCL and GPIO 21 to SDA.
84+
if "ESP32" in sys.implementation._machine:
85+
port = I2C(1, scl=Pin(22), sda=Pin(21))
8786
else:
8887
port = I2C()
89-
except Exception as exception:
90-
raise Exception("error opening port: "
91-
+ NotecardExceptionInfo(exception))
9288

9389
print("Opening Notecard...")
94-
try:
95-
if use_uart:
96-
card = notecard.OpenSerial(port, debug=True)
97-
else:
98-
card = notecard.OpenI2C(port, 0, 0, debug=True)
99-
except Exception as exception:
100-
raise Exception("error opening notecard: "
101-
+ NotecardExceptionInfo(exception))
90+
if use_uart:
91+
card = notecard.OpenSerial(port, debug=True)
92+
else:
93+
card = notecard.OpenI2C(port, 0, 0, debug=True)
10294

10395
# If success, configure the Notecard and send some data
104-
configure_notecard(card)
96+
configure_notecard(card, product_uid)
10597
temp, voltage = get_temp_and_voltage(card)
10698

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

111-
try:
112-
card.Transaction(req)
113-
except Exception as exception:
114-
print("Transaction error: " + NotecardExceptionInfo(exception))
115-
time.sleep(5)
103+
card.Transaction(req)
116104

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

118-
main()
110+
if __name__ == "__main__":
111+
product_uid = "com.your-company.your-project"
112+
# Choose either UART or I2C for Notecard
113+
use_uart = True
114+
run_example(product_uid, use_uart)
File renamed without changes.

pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
addopts = --ignore=test/hitl/

test/hitl/conftest.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from pathlib import Path
2+
import shutil
3+
import sys
4+
5+
# Add the 'deps' folder to the path so we can import the pyboard module from
6+
# it.
7+
deps_path = str(Path(__file__).parent / 'deps')
8+
sys.path.append(deps_path)
9+
import pyboard
10+
11+
12+
def mkdir_on_host(pyb, dir):
13+
pyb.enter_raw_repl()
14+
try:
15+
pyb.fs_mkdir(dir)
16+
except pyboard.PyboardError as e:
17+
already_exists = ["EEXIST", "File exists"]
18+
if any([keyword in str(e) for keyword in already_exists]):
19+
# If the directory already exists, that's fine.
20+
pass
21+
else:
22+
raise
23+
finally:
24+
pyb.exit_raw_repl()
25+
26+
27+
def copy_files_to_host(pyb, files, dest_dir):
28+
pyb.enter_raw_repl()
29+
try:
30+
for f in files:
31+
pyb.fs_put(f, f'{dest_dir}/{f.name}', chunk_size=4096)
32+
finally:
33+
pyb.exit_raw_repl()
34+
35+
36+
def copy_file_to_host(pyb, file, dest):
37+
pyb.enter_raw_repl()
38+
try:
39+
pyb.fs_put(file, dest, chunk_size=4096)
40+
finally:
41+
pyb.exit_raw_repl()
42+
43+
def setup_host(port, platform):
44+
pyb = pyboard.Pyboard(port, 115200)
45+
# Get the path to the root of the note-python repository.
46+
note_python_root_dir = Path(__file__).parent.parent.parent
47+
notecard_dir = note_python_root_dir / 'notecard'
48+
# Get a list of all the .py files in note-python/notecard/.
49+
notecard_files = list(notecard_dir.glob('*.py'))
50+
51+
mkdir_on_host(pyb, '/lib')
52+
mkdir_on_host(pyb, '/lib/notecard')
53+
copy_files_to_host(pyb, notecard_files, '/lib/notecard')
54+
55+
# Copy over mpy_example.py. We'll run this example code on the MicroPython
56+
# host to 1) verify that the host is able to use note-python to communicate
57+
# with the Notecard and 2) verify that the example isn't broken.
58+
if platform == 'circuitpython':
59+
example_file = 'cpy_example.py'
60+
else:
61+
example_file = 'mpy_example.py'
62+
examples_dir = note_python_root_dir / 'examples'
63+
example_file_path = examples_dir / 'notecard-basics' / example_file
64+
copy_file_to_host(pyb, example_file_path, '/example.py')
65+
66+
pyb.close()
67+
68+
69+
def pytest_addoption(parser):
70+
parser.addoption(
71+
'--port',
72+
required=True,
73+
help='The serial port of the CircuitPython host (e.g. /dev/ttyACM0).'
74+
)
75+
parser.addoption(
76+
'--platform',
77+
required=True,
78+
help='Choose the platform to run the tests on.',
79+
choices=["circuitpython", "micropython"]
80+
)
81+
parser.addoption(
82+
'--productuid',
83+
required=True,
84+
help='The ProductUID to set on the Notecard.'
85+
)
86+
parser.addoption(
87+
"--skipsetup",
88+
action="store_true",
89+
help="Skip host setup (copying over note-python, etc.) (default: False)"
90+
)
91+
92+
93+
def pytest_configure(config):
94+
config.port = config.getoption("port")
95+
config.platform = config.getoption("platform")
96+
config.product_uid = config.getoption("productuid")
97+
config.skip_setup = config.getoption("skipsetup")
98+
99+
if not config.skip_setup:
100+
setup_host(config.port, config.platform)

0 commit comments

Comments
 (0)