Metadata-Version: 2.4
Name: motorcortex-python-tools
Version: 1.4.5
Summary: Python tools for Motorcortex Engine
Home-page: https://www.motorcortex.io
Author: Philippe Piatkiewitz
Author-email: philippe.piatkiewitz@vectioneer.com
License: MIT
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>0.22
Requires-Dist: matplotlib>2.1
Requires-Dist: motorcortex-python>0.20.1
Provides-Extra: autotest
Requires-Dist: jinja2>3.0.3; extra == "autotest"
Requires-Dist: weasyprint>54.1; extra == "autotest"
Dynamic: author
Dynamic: author-email
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: summary

# motorcortex-python-tools

Command-line tools and a Python helper library for logging and plotting
signals from a [Motorcortex](https://www.motorcortex.io) server.

This package ships:

- **`mcx-datalogger`** — subscribe to server signals and stream them to a
  CSV (or LZMA-compressed `.csv.xz`) file, optionally gated by a trigger
  condition.
- **`mcx-dataplot`** — plot signals from a logged CSV file with flexible
  multi-axis / multi-subplot layouts.
- **`motorcortex_tools`** — a small Python package with the `DataLogger`
  class, a `loadData()` helper, and a `waitFor()` utility, for building
  your own logging and automated-testing scripts.

---

## Installation

### Linux (system Python + apt)

```bash
sudo apt install python3 python3-matplotlib python3-jinja2
sudo pip3 install motorcortex-python motorcortex-python-tools
```

### Any platform (pip)

```bash
pip3 install matplotlib jinja2 motorcortex-python motorcortex-python-tools
```

Requires **Python 3.x** and `motorcortex-python`. `pandas`, `matplotlib`
and `jinja2` are pulled in as dependencies. The optional `autotest`
extra (`pip install motorcortex-python-tools[autotest]`) adds
`weasyprint` for PDF report generation.

Full tool help:

```bash
mcx-datalogger --help
mcx-dataplot --help
```

---

## `mcx-datalogger`

### Quick start

```bash
# Log a set of signals until Ctrl-C
mcx-datalogger -p parameters.json -u wss://192.168.2.100:5568:5567 -s mcx.cert.crt

# Use a trigger: start/stop logging when a boolean signal goes high/low
mcx-datalogger -p parameters.json \
               --trigger root/ControlSystem/logEnable \
               --triggervalue 1 --triggerop ==

# Write compressed output into a folder, with a comment in the filename
mcx-datalogger -p parameters.json -F ./logs -c bench_run_42 -C
```

Output filenames default to `<UTC timestamp>[_comment].csv` (or `.csv.xz`
with `-C`). A sibling `<file>.params` dump of all server parameters is
written alongside each trace unless `--noparamdump` is set.

### Parameter file (`-p/--parameterfile`)

Two JSON formats are accepted.

**Legacy — flat list of paths:**

```json
[
  {"path": "root/Control_task/actual_cycle_max"},
  {"path": "root/Fieldbus_task/actual_cycle_max"}
]
```

**Scope export — object with a `subscriptions` array:**

```json
{
  "subscriptions": [
    {"path": "root/MainControlLoop/goToMoves/velocityFilter/output",
     "channel": 0, "color": "#109618", "axis": "y1", "hidden": false},
    {"path": "root/MainControlLoop/goToMoves/velocityFilter/output",
     "channel": 1},
    {"path": "root/MainControlLoop/jointPositionsTarget",
     "channel": 0}
  ]
}
```

This is the format exported by the updated Motorcortex scope / plot
tool. Extra fields (`channel`, `color`, `axis`, `hidden`, …) are
ignored for logging, and repeated paths are de-duplicated — a signal
with multiple channels is logged once, not once per channel.

### Key options

| Flag | Purpose |
| ---- | ------- |
| `-p, --parameterfile` | Parameter JSON (required, see above). |
| `-u, --url` | Server URL. Default `wss://192.168.2.100:5568:5567`. Supports `user:pass@host` in the URL. |
| `-s, --certificate` | TLS certificate. Default `mcx.cert.crt`. |
| `-f, --file` / `-F, --folder` / `-c, --comment` | Output filename / folder / comment. |
| `-d, --divider` | Frequency divider at the server. `1` = max rate, default `10`. |
| `-C, --compress` | Stream output through LZMA (`.xz`). |
| `--trigger` / `--triggervalue` / `--triggerop` / `--triggerinterval` / `--triggeroffdelay` | Condition-based logging. |
| `--watchdogpulse` | Periodic boolean `true` write — lets the server detect an active logger. |
| `--noparamdump` | Skip the `.params` side-car dump. |

---

## `mcx-dataplot`

```bash
# List the columns in a logged file
mcx-dataplot -l data.csv

# Plot signals 1 and 2 on the same axis; 3 on a second y-axis; 4 and 5 in a new subplot
mcx-dataplot -s 1,2:3 4,5 data.csv

# Save the plot to disk instead of showing it
mcx-dataplot -s 1,2 --output plot.png data.csv
```

`-s`/`--signals` syntax:
- `,` — add signal to the same axis
- `:` — put signal on an additional y-axis within the same subplot
- *space* (between `-s` arguments) — start a new subplot

Compressed `.xz` inputs are handled transparently.

---

## `motorcortex_tools` (library)

```python
from motorcortex_tools import DataLogger, loadData, waitFor

logger = DataLogger(
    "wss://192.168.2.100:5568:5567",
    ["root/signal1", "root/signal2"],
    divider=10, certificate="mcx.cert.crt",
)
logger.openFileAndWriteHeader("trace.csv")
logger.start()
# ... wait for some condition ...
logger.stop()
logger.close()

# Later, from any Python process:
df = loadData("trace.csv")          # pandas.DataFrame
df_with_time = loadData("trace.csv.xz", nodateconv=False)
```

`DataLogger` can also log to memory — call `start()` without
`openFileAndWriteHeader()` first and read from `logger.traces`.

See the `automatic_testing_examples/` folder for a fuller scripted-test
pattern (uses `waitFor()` with comparison operators).

---

## Changelog

Notable changes are tracked in [CHANGELOG.md](CHANGELOG.md).

---

## Release process (maintainers)

1. Update `CHANGELOG.md` — move items out of `[Unreleased]` into a new
   version section dated today.
2. Bump the version in `setup.py`.
3. Tag the release:
   ```bash
   git tag -a <version> -m "version <version>"
   git push origin <version>
   ```
4. Build:
   ```bash
   python3 ./setup.py sdist bdist_wheel
   ```
5. Upload to PyPI:
   ```bash
   python3 -m twine upload dist/motorcortex-python-tools-<version>.tar.gz
   ```

---

## License

MIT — see [LICENSE](LICENSE). © 2019–2026 VECTIONEER.
