Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions tests/runner/mpremote_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def _run(self, code, mount_dir=None):

result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, check=False)
if result.returncode != 0:
raise RuntimeError(
f"mpremote failed: {result.stderr.strip()}"
)
stderr = result.stderr.strip()
stdout = result.stdout.strip()
parts = [p for p in (stderr, stdout) if p]
detail = "\n".join(parts) or "(no output)"
raise RuntimeError(f"mpremote failed: {detail}")
# mpremote mount adds "Local directory ... is mounted at /remote"
# to stdout; filter it out and keep only the script output
lines = [
Expand Down Expand Up @@ -142,20 +144,33 @@ def run_script(
last_line = output.strip().rsplit("\n", 1)[-1]
return json.loads(last_line)

def run_raw_script(self, script):
def run_raw_script(self, script, mount_dir=None):
"""Run a raw MicroPython script on the board without driver context.

The script must set a ``result`` variable. Returns the
JSON-decoded value of ``result``.

Args:
mount_dir: optional local directory to mount on the board.
"""
code = (
f"import json\n"
f"{script}\n"
f"print(json.dumps(result))"
)
output = self._run(code)
last_line = output.strip().rsplit("\n", 1)[-1]
return json.loads(last_line)
output = self._run(code, mount_dir=mount_dir)
lines = output.strip().splitlines()
# Print non-JSON lines (diagnostic output from the script)
for line in lines[:-1]:
print(line)
last_line = lines[-1] if lines else ""
try:
return json.loads(last_line)
except json.JSONDecodeError:
full = "\n".join(lines)
raise RuntimeError(
f"Script did not produce valid JSON result.\nFull output:\n{full}"
)

Comment thread
nedseb marked this conversation as resolved.
def scan_bus(self, i2c_config):
"""Scan I2C bus and return list of addresses."""
Expand Down
107 changes: 107 additions & 0 deletions tests/scenarios/board_temperature_comparison.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
type: board
name: "Temperature comparison (all sensors)"

i2c:
id: 1

# List of drivers needed — triggers mounting lib/ via mpremote
drivers:
- hts221
- wsen-hids
- wsen-pads
- lis2mdl

tests:
- name: "Read all temperature sensors"
action: hardware_script
script: |
import sys
sys.path.insert(0, '/remote/hts221')
sys.path.insert(0, '/remote/wsen-hids')
sys.path.insert(0, '/remote/wsen-pads')
sys.path.insert(0, '/remote/lis2mdl')

from machine import I2C
from time import sleep_ms

i2c = I2C(1)

temps = {}

# HTS221
from hts221.device import HTS221
hts = HTS221(i2c)
hts.poweroff()
sleep_ms(20)
hts.poweron()
sleep_ms(50)
temps['HTS221'] = hts.temperature()

# WSEN-HIDS
from wsen_hids.device import WSEN_HIDS
hids = WSEN_HIDS(i2c)
temps['WSEN-HIDS'] = hids.temperature()

# WSEN-PADS
from wsen_pads.device import WSEN_PADS
pads = WSEN_PADS(i2c)
temps['WSEN-PADS'] = pads.temperature()

# LIS2MDL (auxiliary, offset not guaranteed by datasheet)
from lis2mdl.device import LIS2MDL
mag = LIS2MDL(i2c)
temps['LIS2MDL'] = mag.read_temperature_c()

Comment thread
nedseb marked this conversation as resolved.
# Print comparison table
print('--- Temperature Comparison ---')
for name, t in temps.items():
pad = ' ' * (12 - len(name))
print(' ' + name + pad + ': ' + str(round(t, 2)) + ' C')

# Check thermometers in plausible range (HTS221, WSEN-HIDS, WSEN-PADS)
thermometers = [temps['HTS221'], temps['WSEN-HIDS'], temps['WSEN-PADS']]
all_ok = all(5.0 <= t <= 50.0 for t in thermometers)

# Check spread between thermometers
spread = max(thermometers) - min(thermometers)
print(' Spread: ' + str(round(spread, 2)) + ' C')

result = all_ok and spread < 8.0
expect_true: true
mode: [hardware]

- name: "Temperature spread with barometer"
action: hardware_script
script: |
import sys
sys.path.insert(0, '/remote/hts221')
sys.path.insert(0, '/remote/wsen-pads')

from machine import I2C
from time import sleep_ms

i2c = I2C(1)

from hts221.device import HTS221
hts = HTS221(i2c)
hts.poweroff()
sleep_ms(20)
hts.poweron()
sleep_ms(50)
t_hts = hts.temperature()

from wsen_pads.device import WSEN_PADS
pads = WSEN_PADS(i2c)
t_pads = pads.temperature()

spread = abs(t_hts - t_pads)
print(' HTS221: ' + str(round(t_hts, 2)) + ' C | WSEN-PADS: ' + str(round(t_pads, 2)) + ' C | Spread: ' + str(round(spread, 2)) + ' C')
result = spread < 5.0
expect_true: true
mode: [hardware]

- name: "Temperature values feel correct"
action: manual
prompt: "Les températures lues sont-elles cohérentes entre elles et avec l'ambiance ?"
expect_true: true
mode: [hardware]
7 changes: 6 additions & 1 deletion tests/test_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ def test_scenario(scenario, test, mode, port):
else:
print(f" [INTERACTIVE] {pre_prompt}")
if is_board:
result = bridge.run_raw_script(test["script"])
mount_dir = None
if scenario.get("drivers"):
mount_dir = Path(__file__).parent.parent / "lib"
result = bridge.run_raw_script(
test["script"], mount_dir=mount_dir,
)
else:
result = bridge.run_script(
scenario["driver"],
Expand Down
Loading