Skip to content

Commit e1da991

Browse files
authored
Merge pull request #426 from quartiq/feature/miniconf-bump
Feature/miniconf bump
2 parents 13c5f7e + bd39676 commit e1da991

File tree

11 files changed

+227
-253
lines changed

11 files changed

+227
-253
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
mainboard flash and will overwrite EEPROM-based settings during device boot. Reversion to older
1818
firmware variants will still be able to use existing EEPROM settings, but the EEPROM contents
1919
are no longer modified when settings are changed.
20+
* [python] Python client has had `TelemetryReader` removed, `BoosterApi` was renamed to `Booster`
21+
and now takes an `aiomqtt-client` as the constructor.
2022

2123
### Fixed
2224
* Heavy network traffic no longer causes Booster to encounter watchdog resets or other spurious

Cargo.lock

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ usbd-serial = "0.2.2"
5151
encdec = { version = "0.9", default-features = false }
5252
crc-any = { version = "2.5.0", default-features = false }
5353
panic-persist = { version = "0.3", features = ["custom-panic-handler", "utf8"] }
54-
miniconf = { version = "0.11.0", features = ["json-core", "derive", "postcard"]}
55-
miniconf_mqtt = "0.11"
54+
miniconf = { version = "0.13", features = ["json-core", "derive", "postcard"]}
55+
miniconf_mqtt = "0.13"
5656
# Note: Keep `py/pyproject.toml` version in sync with the Minimq version used in FW.
5757
minimq = "0.9.0"
5858
w5500 = "0.5"
@@ -64,7 +64,7 @@ enc424j600 = "0.4"
6464
embedded-hal = "1"
6565
smoltcp-nal = { version = "0.5", features=["shared-stack"] }
6666

67-
serial-settings = {git = "https://github.com/quartiq/stabilizer", rev = "3ef00cbd9"}
67+
serial-settings = {git = "https://github.com/quartiq/stabilizer", rev = "5452272931e1ad70547b578052ffbb186fb72514"}
6868
stm32f4xx-hal = {version = "0.21.0", features = ["stm32f407", "usb_fs"] }
6969

7070
postcard = "1"

hitl/basic.py

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import contextlib
1010
import sys
1111
import time
12+
import json
13+
import logging
1214

13-
from booster import BoosterApi, TelemetryReader
15+
from booster import Booster
16+
import miniconf
1417

1518
# The default bias current to tune to.
1619
DEFAULT_BIAS_CURRENT = 0.05
@@ -33,66 +36,65 @@ async def channel_on(booster, channel, initial_state='Enabled'):
3336
""" Context manager to ensure a channel is disabled upon exit.
3437
3538
Args:
36-
booster: The BoosterApi objct.
39+
booster: The Booster connection
3740
channel: The channel to configure.
3841
initial_state: The state to configure the channel into.
3942
"""
4043
try:
4144
print(f'Commanding channel {channel} into {initial_state}')
42-
await booster.settings_interface.set(f'/channel/{channel}/state', initial_state)
45+
await booster.miniconf.set(f'/channel/{channel}/state', initial_state)
4346
yield
4447
finally:
4548
print(f'Commanding channel {channel} off')
46-
await booster.settings_interface.set(f'/channel/{channel}/state', 'Off')
49+
await booster.miniconf.set(f'/channel/{channel}/state', 'Off')
4750

4851

49-
async def test_channel(booster, channel, prefix, broker):
52+
async def test_channel(booster, channel, tele_queue):
5053
""" Basic testing of a single RF channel.
5154
5255
Args:
53-
booster: The BoosterApi.
56+
booster: The Booster connection.
5457
channel: The channel index to test.
55-
prefix: Booster's miniconf prefix.
56-
broker: The broker IP address.
58+
tele: The received telemetry
5759
"""
5860
print(f'-> Conducting self-test on channel {channel}')
5961

60-
# Start receiving telemetry for the channel under test.
61-
telemetry = await TelemetryReader.create(prefix, broker, channel)
62-
6362
# Tune the bias current on the channel
6463
async with channel_on(booster, channel, 'Powered'):
6564
vgs, ids = await booster.tune_bias(channel, DEFAULT_BIAS_CURRENT)
6665
print(f'Channel {channel} bias tuning: Vgs = {vgs}, Ids = {ids}')
6766

6867
# Disable the channel.
69-
await booster.settings_interface.set(f'/channel/{channel}/state', 'Off')
68+
await booster.miniconf.set(f'/channel/{channel}/state', 'Off')
7069

7170
# Check that telemetry indicates channel is powered off.
7271
async def is_off() -> bool:
73-
_, tlm = await telemetry.get_next_telemetry()
72+
msg = await tele_queue.__anext__()
73+
tlm = json.loads(msg.payload)
7474
return tlm['state'] == 'Off'
7575

7676
await periodic_check(is_off, timeout=5)
7777

7878
# Set the interlock threshold so that it won't trip.
7979
print('Setting output interlock threshold to 30 dB')
80-
await booster.settings_interface.set(f'/channel/{channel}/output_interlock_threshold', 30)
80+
await booster.miniconf.set(f'/channel/{channel}/output_interlock_threshold', 30)
8181

8282
# Enable the channel, verify telemetry indicates it is now enabled.
8383
async with channel_on(booster, channel):
8484
async def is_enabled() -> bool:
85-
_, tlm = await telemetry.get_next_telemetry()
85+
msg = await tele_queue.__anext__()
86+
tlm = json.loads(msg.payload)
8687
return tlm['state'] == 'Enabled'
8788

8889
await periodic_check(is_enabled, timeout=5)
8990

9091
# Lower the interlock threshold so it trips.
9192
print('Setting output interlock threshold to -5 dB, verifying interlock trips')
92-
await booster.settings_interface.set(f'/channel/{channel}/output_interlock_threshold', -5.7)
93+
await booster.miniconf.set(f'/channel/{channel}/output_interlock_threshold', -5.7)
9394

9495
async def is_tripped() -> bool:
95-
_, tlm = await telemetry.get_next_telemetry()
96+
msg = await tele_queue.__anext__()
97+
tlm = json.loads(msg.payload)
9698
return tlm['state'] == 'Tripped(Output)'
9799

98100
# Verify the channel is now tripped.
@@ -104,8 +106,11 @@ async def is_tripped() -> bool:
104106

105107
def main():
106108
""" Main program entry point. """
107-
parser = argparse.ArgumentParser(description='Loopback tests for Stabilizer HITL testing',)
108-
parser.add_argument('--prefix', type=str, help='The MQTT prefix of the target')
109+
parser = argparse.ArgumentParser(description='Loopback tests for Booster HITL testing')
110+
parser.add_argument('--prefix', default='dt/sinara/booster/+', type=str,
111+
help='The prefix of the booster to test')
112+
parser.add_argument("--no-discover", "-d", action="store_true",
113+
help="Do not discover device prefix.")
109114
parser.add_argument('--broker', '-b', default='mqtt', type=str,
110115
help='The MQTT broker address')
111116
parser.add_argument('--channels', '-c', nargs='+', help='Channels indices to test',
@@ -115,18 +120,43 @@ def main():
115120

116121
async def test():
117122
""" The actual testing being completed. """
118-
booster = await BoosterApi.create(args.prefix, args.broker)
119-
120-
# Disable configure the telemetry rate.
121-
await booster.settings_interface.set('/telemetry_period', 1, retain=False)
122-
123-
# Test operation of an RF channel
124-
for channel in args.channels:
125-
await test_channel(booster, channel, booster.prefix, args.broker)
123+
async with miniconf.Client(
124+
args.broker,
125+
protocol=miniconf.MQTTv5,
126+
logger=logging.getLogger("aiomqtt-client"),
127+
queue_type=asyncio.LifoQueue,
128+
max_queued_incoming_messages=1,
129+
) as client:
130+
if not args.no_discover:
131+
prefix, _alive = await miniconf.discover_one(client, args.prefix)
132+
else:
133+
prefix = args.prefix
134+
135+
booster = Booster(client, prefix)
136+
137+
# Disable configure the telemetry rate.
138+
await booster.miniconf.set('/telemetry_period', 1)
139+
140+
# Test operation of an RF channel
141+
async with miniconf.Client(
142+
args.broker, protocol=miniconf.MQTTv5,
143+
logger=logging.getLogger("aiomqtt-client")
144+
) as tele:
145+
for channel in args.channels:
146+
await tele.subscribe(f"{prefix}/telemetry/ch{channel}")
147+
await test_channel(booster, channel, tele.messages)
148+
await tele.unsubscribe(f"{prefix}/telemetry/ch{channel}")
126149

127150
loop = asyncio.get_event_loop()
128151
sys.exit(loop.run_until_complete(test()))
129152

130153

131154
if __name__ == '__main__':
155+
import os
156+
import sys
157+
if sys.platform.lower() == "win32" or os.name.lower() == "nt":
158+
from asyncio import set_event_loop_policy, WindowsSelectorEventLoopPolicy
159+
160+
set_event_loop_policy(WindowsSelectorEventLoopPolicy())
161+
132162
main()

0 commit comments

Comments
 (0)