Skip to content

Getting started ​

Prerequisites ​

On the Brain:

  • muxen-uds installed and working. It is a hard dependency of the package. muxen-blocswap does everything through it: the bus scan, the configuration write, the reset. If muxen-uds cannot reach the bus, this daemon can do nothing and will say nothing.
  • muxen-systemd (≥ 1.2.0), which provides the muxen.target / muxen-deploy.target pair the unit hangs off, and the muxen system user the daemon runs as. Also a hard dependency.
  • The MUXEN bus up, because muxen-uds needs it. The daemon itself never opens a CAN socket.
  • /etc/muxen/deploy.json — the boat's deployment file, shared with the other MUXEN daemons. This package does not install one. Without it the daemon monitors nothing.
  • /var/lib/muxen/deployed.json — the record of what was last deployed to which device. It is written by muxen-uds deploy, so it exists on any boat that has been commissioned. The daemon only reads it, once, at startup.

Nothing else. The daemon opens no socket, publishes nothing, and creates no file other than a temporary scan file it deletes immediately.

Install ​

sh
sudo apt install muxen-blocswap

The package carries one binary, /usr/bin/muxen-blocswap, and its systemd unit. There is no configuration file, no bash completion and no command-line tool.

It Replaces and Breaks the older muxen-auto-deploy package, which is the same program under its original name; installing this one removes that one.

Start it ​

The unit is WantedBy=muxen-deploy.target, so it comes up with the rest of the MUXEN stack and needs no enabling by hand:

sh
systemctl status muxen-blocswap

The unit runs /usr/bin/muxen-blocswap with no arguments — the binary accepts none — as user muxen, with Restart=always and RestartSec=30.

It is also PartOf=muxen-deploy.target, so systemctl restart muxen-deploy.target restarts it along with every other daemon that reads the deployment file. muxen-systemd watches /etc/muxen/deploy.json and restarts that target when the file changes, which is how a configuration change reaches this daemon. The configuration is read once, at startup, and never re-read.

Turn the feature on ​

The daemon runs on every Brain that has the package, but it monitors nothing until the boat's configuration says so. The switch is a setting in /etc/muxen/deploy.json:

json
{
  "settings": [
    { "name": "FeatureBlocSwap", "value": "1" }
  ]
}

Three details that bite:

  • The setting lives in the root settings[] array and is matched on its name, exactly — case included.
  • The value is compared as a string against "1". A JSON number 1, "true", "on" or "yes" all leave the feature off.
  • In normal use this setting is written by the boat's configuration tool rather than edited on the Brain. Editing the file directly works, and the deploy watcher restarts the daemon for you; editing it by some route that does not touch the file's modification time needs an explicit systemctl restart muxen-blocswap.

With the feature off, the daemon logs one line and monitors no device:

Auto deploy is not activated in the deployed configuration

It keeps running, and it keeps scanning the bus every 30 seconds even then — see Tips.

Verify it is watching the right blocs ​

Everything the daemon knows, it says at startup. There is no status command and no runtime query, so this startup block is the whole commissioning tool.

Feature BlocSwap enabled
Monitoring device 65 (0x041)
Monitoring device 66 (0x042)
Monitoring device 67 (0x043)
Monitoring device 320 (0x140)
Loading deployed.json
65 => 27005E000B504256
66 => 2D005E000B504256
67 => 31005E000B504256
320 => 490019000A504147

Read it in three passes:

1. Feature BlocSwap enabled. If this line is absent and the "not activated" line is there instead, stop here and fix the setting.

2. One Monitoring device line per bloc. These are every entry in devices[] of the deployment file except those carrying a VirtualDevice parameter set to "1", which are skipped silently. The decimal number is the deviceId; the hex in brackets is the same value, which is the form the rest of the MUXEN tooling uses. Split it as

deviceId = function * 64 + instance

so 65 is function 1, instance 1, and 320 is function 5, instance 0.

A bloc you expect to be covered and that is not listed is either absent from the deployment file or flagged virtual.

3. One <deviceId> => <UID> line per bloc. This is the serial number the daemon expects to find at that address. Anything else appearing there is a swap.

A line with an empty right-hand side is the one to look at. It means the deployment file declares that device but /var/lib/muxen/deployed.json holds no UID for it — the device has never been deployed, or was deployed before that record was kept. An empty expected UID matches nothing, so the daemon treats the unit currently at that address as a replacement and deploys it, once, on its second tick.

That is usually harmless and arguably correct. It is not harmless on a boat where somebody has hand-tuned a device's parameters outside the deployment file, because a deploy overwrites them. Check for empty right-hand sides before enabling the feature on an existing boat.

Expect the journal to lag ​

The daemon writes its log lines to standard output without flushing them. Standard output is fully buffered whenever it is not a terminal, which is exactly the case under systemd, so lines accumulate in a several-kilobyte buffer and reach the journal in blocks rather than as they happen.

On a boat with a couple of dozen devices, the whole startup block above fits inside that buffer. journalctl -u muxen-blocswap can therefore show nothing at all after a restart, for a long time, on a perfectly healthy daemon.

When you need to see what it is doing now, run it by hand instead.

Running it by hand ​

Useful while commissioning, on a Brain where the service is stopped:

sh
sudo systemctl stop muxen-blocswap
sudo -u muxen /usr/bin/muxen-blocswap

Standard output is then a terminal, so the lines appear as they are written. The first scan runs 30 seconds after start; leave it running for a minute or two.

Stop the service first. Two copies would each run their own bus scan every 30 seconds, and there is no coordination between muxen-uds invocations — concurrent ones share the same client address on the bus and can consume each other's answers. For the same reason, do not leave the service running while you drive muxen-uds by hand.

Ctrl-C ends it. If it is in the middle of a scan or a deploy the signal is only handled once that finishes, so it can take a few seconds.

What a healthy boat looks like ​

Nothing. Once the startup block is out, a boat where no bloc has been touched produces no further output, ever. The daemon logs only transitions:

LineMeaning
device <id> has been changeda different unit is answering at that address — a deploy and a reset follow
device <id> become OFFLINEthree consecutive scans found nothing at that address
device <id> become ONLINEthe same unit came back after being offline

Silence is the normal state, and it is also what a wedged daemon looks like. Troubleshooting opens with how to tell the two apart.

Where to go next ​

Integration of multiplexed solutions
MUXEN and the MUXEN logo are trademarks of MUXEN SAS.