Skip to content
RAKWirelessPublic

About

Linux CLI utility based on WisBlock Pin Mapper

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

WisMAP - WisBlock Pin Mapper

WisMAP identifies potential pin conflicts between modules in RAKwireless WisBlock integrations, with a web interface and a CLI tool. Its module catalog comes from the wisblock-data repository, which is the source of truth for WisBlock module data.

Features:

  • Browse all WisBlock modules with filtering by type and category (filters persist across navigation)
  • Search modules by name, description, or tags (protocol, sensor type, communication, use case)
  • View detailed pin mappings, documentation links, and clickable tags for any module
  • Combine modules on a base board and detect pin conflicts, I2C address collisions, and signal incompatibilities
  • Export combine results to Markdown or PDF
  • Shareable URLs for combine configurations
  • Versioned JSON API (/api/v1/*) with interactive Swagger UI documentation at /api/v1/docs
  • Supports ~140 modules across all WisBlock types (Base, Core, IO, Sensor, Power, Module, Accessories)

The REST API (Flask) and the web frontend (React) have been developed with the assistance of Claude Code, Anthropic's AI coding tool.

Deploy with Docker

The quickest way to run WisMAP is with Docker Compose:

git clone https://github.com/rakwireless/wismap
cd wismap
docker compose up -d --build

The web interface will be available at http://localhost:5000.

To stop the service:

docker compose down

Alternatively, using plain Docker:

docker build -t wismap .
docker run -p 5000:5000 wismap

Deploy manually

Requirements: Python 3, Node.js, virtualenv and make.

git clone https://github.com/rakwireless/wismap
cd wismap
make init
make frontend-install
make frontend-build
make serve

This starts the Flask server on port 5000, serving both the API and the built frontend.

Development

For local development, run the Flask API and the Vite dev server simultaneously in two terminals:

make serve
make frontend-dev

The Vite dev server proxies /api requests to Flask on port 5000 and provides hot module replacement.

Updating module definitions

data/definitions.yml (141 modules), data/config.yml (slot pin maps, slot catalogue, function groups) and data/rules.yml (conflict rules) are committed to this repository but are not authored here — they are verbatim copies of the dist/wismap/ artifacts generated by wisblock-data, which authors WisBlock module facts once and feeds every consumer from them.

Automatically

.github/workflows/sync-data.yml does this on its own: daily, on manual dispatch, and whenever wisblock-data announces a new build with a wisblock-data-updated repository dispatch. It pulls the upstream artifacts, regenerates the contract fixtures to match, and opens a pull request on chore/sync-wisblock-data when anything moved. Nothing lands on master without review — a catalog change alters what the API reports.

One-time setup:

  • Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests", so the workflow can open the PR.
  • secrets.WISBLOCK_DATA_TOKEN — a token with read access to wisblock-data. Needed only while that repository is private: sharing an organisation does not let one repository's GITHUB_TOKEN read another's. Once it is public the workflows fall back to the built-in token on their own and the secret can be deleted.

Optionally set secrets.SYNC_PR_TOKEN to a PAT as well: a branch pushed with GITHUB_TOKEN does not trigger other workflows, so without it ci.yml will not run on the sync PR.

By hand

Point WISBLOCK_DATA at a wisblock-data checkout (it defaults to ../../wisblock-data):

make sync-data      # copy dist/wismap/*.yml into data/
make check-fixtures # regenerate the consumer fixtures; fails if they had gone stale
make check-data     # assert data/ matches upstream

With no checkout there, tools/sync-data.sh clones upstream for the run instead, so the same command works on a machine that has never checked wisblock-data out. Override WISBLOCK_DATA_REPO / WISBLOCK_DATA_REF to sync from a fork or a branch.

data/UPSTREAM records which upstream commit produced the vendored files.

A wrong or missing module value is fixed upstream — in wisblock-data's modules/<id>/{meta,hardware}.yml — then regenerated there with wbdata generate and synced here. Editing the files under data/ directly loses the change on the next sync and puts WisMAP out of step with the other consumers of the same data.

Continuous integration

.github/workflows/ci.yml runs three drift guards on every pull request and push to master. Each regenerates a committed artifact and requires that it did not move:

Target Guards
make check-data data/ still matches the upstream artifacts it was vendored from
make check-fixtures tests/fixtures/ still describes what the server returns
make check-openapi wismap/openapi.yaml still matches the registered routes and version

check-data skips with a notice on pull requests from forks, which get no secrets and so cannot check out the private upstream repository.

CLI

WisMAP also provides a command-line interface for terminal usage. See CLI.md for full documentation.

Quick examples:

python wismap.py -v              # show version
python wismap.py list            # list all modules
python wismap.py search modbus   # search modules by tag, type, or description
python wismap.py info rak12008   # show module details
python wismap.py combine rak6421 rak5802 rak5801 empty empty rak12002 rak18001

HTTP API

WisMAP exposes a versioned JSON API at /api/v1/*. The full contract is machine-readable as OpenAPI 3.1:

Endpoints:

Method Path Description
GET /api/v1/healthz Liveness probe
GET /api/v1/cores · /cores/:id List / get a Core
GET /api/v1/bases · /bases/:id List / get a Base
GET /api/v1/modules · /modules/:id List / get a non-Core, non-Base module
POST /api/v1/validate Validate a {core, base, slots[]} configuration; returns structured conflicts and a resolved pin map
POST /api/v1/solve Solve which slot each requested module goes in; returns up to max_solutions ranked placements (no pin map — call /validate on the chosen one)

Test fixtures — canonical request/response pairs for /api/v1/validate and /api/v1/solve — live in tests/fixtures/{validate,solve}/ for downstream-consumer CI.

Authentication

POST /api/v1/validate and POST /api/v1/solve (the compute-bound endpoints) require authentication; all discovery/read (GET) endpoints stay public.

Machine consumers send an API key as a bearer token:

curl -X POST http://localhost:5000/api/v1/validate \
     -H "Authorization: Bearer <key>" \
     -H "Content-Type: application/json" \
     -d @request.json

Keys live in a YAML file pointed at by WISMAP_API_KEYS_FILE — one {key, label} entry each; see data/api_keys.example.yml. Generate a key with:

python -c "import secrets; print(secrets.token_urlsafe(48))"

Keys are read once at boot, so rotation is a file edit plus a server restart.

The browser SPA needs no key: on load the server mints a wismap_session cookie and a wismap_csrf token, and the SPA replays the CSRF token as an X-CSRF-Token header on each /validate / /solve call.

Auth is on by default. For local development without keys, set WISMAP_AUTH_ENABLED=false. When enabled, WISMAP_API_KEYS_FILE and WISMAP_SECRET_KEY are required — the server refuses to start without them (fail closed).

Environment variables

The following environment variables can be used to configure the server:

Variable Default Description
FLASK_DEBUG false Enable Flask debug mode (true, 1, or yes to enable)
RATELIMIT_ENABLED true Enable API rate limiting (false to disable, e.g. during development)
RATELIMIT_DEFAULT 120/minute Default rate limit for all API endpoints
RATELIMIT_PROXY 60/minute Rate limit for GET /api/image-proxy
RATELIMIT_STORAGE_URI memory:// Storage backend for rate limit counters (use redis://host:6379 for multi-worker deployments)
WISMAP_AUTH_ENABLED true Gate POST /validate + /solve behind auth. Set false for local dev (no keys needed; ephemeral session secret)
WISMAP_API_KEYS_FILE (none) Path to the YAML API-keys file (a {key, label} list). Required when auth is enabled
WISMAP_SECRET_KEY (none) Secret that signs the SPA session cookie and derives CSRF tokens. Required when auth is enabled
WISMAP_LOG_LEVEL INFO Level for the wismap.* loggers (boot key-load line, per-request auth label, denials). Set WARNING for quieter logs

Rate limit values use the format <amount>/<period> where period is second, minute, hour, or day.

When running with Docker Compose, set these in a .env file or pass them directly:

docker compose up -d -e RATELIMIT_DEFAULT=240/minute

Roadmap

  • Suggest which module should go to which slot
  • Add dependencies between modules (i.e. RAK14011 depends on RAK14004)

Contribute

There are several ways to contribute to this project. You can report bugs or ask for new features directly on GitHub. You can also submit your own new features of bug fixes via a pull request.

License

This project is licensed under Apache 2.0 license.

About

Linux CLI utility based on WisBlock Pin Mapper

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages