Quantcast
Channel: OpenEnergyMonitor aggregator
Viewing all articles
Browse latest Browse all 328

JeeLabs: Hub configuration guide

$
0
0

The JET/Hub process has two types of configuration settings:

  • startup configuration, such as how to connect to MQTT and the name of the data store
  • run-time configuration, such as which serial ports to open, and which packs to launch

Command-line options

Since the hub is intended to run virtually “indefinitely” once started, only very few configuration settings are specified via command-line options, and any changes will require a hub restart:

-datafilename

the filename of the hub’s persistent data store (default: ./store.db)

-loggerdirname

the directory where the logger stores its daily log diles (default: ./logger)

-mqtturl

the host and port of the MQTT server (default: tcp://localhost:1883)

-packsdirname

the directory where packs are launched from (default: ./packs)

Serial port configuration

Serial port configuration in the hub uses a more flexible mechanism: the hub continuously listens for topics matching the pattern “serial/+” and treats them as serial port configuration requests, as described earlier. To set up a serial port listener for a device on USB port 0, you simply need to send a message to MQTT with a specific format:

topic = serial/<name>
payload = {"device":"/dev/<usb-name>","sendto":"<publish-topic>"}

The payload must be a valid JSON object, with device and sendto fields.

The “jet” utility makes it very easy to set this up from the command line, once the hub and MQTT server are up and running. Here is an example:

jet pub serial/jeelink '{"device":"/dev/ttyUSB0","sendto":"logger/jeelink"}'

Note the use of single quotes to simplify passing JSON’s double quotes without further escapes.

If you have more serial ports, just send more messages and use different names:

jet pub serial/arduino '{"device":"/dev/ttyUSB1","sendto":"logger/arduino"}'

And if you don’t know which device is on which port, or if this might change from one power-up cycle to the next, then there’s a trick for that too in Linux:

Each serial device is listed in a little-known directory called /dev/serial/by-id/. By looking up your device and using that (much longer) device name instead of ttyUSB0, you can force the hub to always open a specific device. Here is an example:

long=/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A40117UK-if00-port0
json='{"device":"XYZ","sendto":"logger/jeelink"}'
jet serial/jeelink `echo $json | sed "s/XYZ/$long"`

As you can see, this may require some nasty massaging to avoid quoting hell and keep all the double quotes in that JSON payload intact. Note that if you replace “jet” by “echo” in that last line, you can see what’s going on without publishing to MQTT.

To close a serial port, send an empty payload. This can be done with JET’s “delete” command:

jet delete serial/jeelink

These commands can be sent at any time. There is no need to stop-and-restart the hub.

Persistent settings

The above message sent to MQTT are once-only, i.e. on restart the hub won’t reopen serial ports. But there is a simple solution for this in MQTT: the RETAIN flag. By adding the -r flag to the above “jet pub“ commands, the messages will be sent as before, but also stored and re-sent when the hub is restarted and reconnects to MQTT at a later time:

jet pub -r serial/jeelink '{"device":"/dev/ttyUSB0","sendto":"logger/jeelink"}'
jet pub -r serial/arduino '{"device":"/dev/ttyUSB1","sendto":"logger/arduino"}'

The RETAIN flag is also sent by “jet delete”, i.e. a deletion / close request is also permanent. One little detail to keep in mind is that when a retained message is stored in MQTT, subsequent non-retained messages do not affect it: the original message will still be sent after a hub restart.

You can use “jet config” as a quick way to see all retained messages (i.e. persistent settings).

Managing JET packs

Apart from routing some messages to and from serial ports, logging, and a few other built-in features, one of the hub’s main tasks is to manage “JET packs”, i.e. separate processes (in any language) which are tied into the system as equal citizens and communicate through MQTT.

As with serial ports, the hub supports starting and stopping JET packs at any time. And again, this is driven via MQTT messages. Here is the bird’s eye view:

Here is how to add a new JET pack and manage it with the hub:

  • place the JET pack’s executable or a small shell script wrapper in the “packs” directory - it must have the executable bit set (“chmod +x”), and in the case of a shell script, it must also start with the line “!/bin/sh“ so the hub can launch it
  • send an MQTT message to “packs/<name>” with as payload a JSON array, containing the name of the executable or shell script plus optional arguments

So for example, if packs/abc.sh exists, we can issue the following command:

jet pub packs/abc '["abc.sh","arg1","arg2"]'

The hub will report what it’s doing in the log, as well as any errors it runs into.

For security reasons, the hub will only launch packs present in the “packs“ directory. Path names are not accepted as first item of the JSON payload.

All stdout and stderr output from the pack is also reported by the hub and sent out as MQTT messages to “packs/<name>/log”. Output lines from stderr will be prefixed with "(stderr)".

Send an empty message to stop the pack again, e.g. “jet delete packs/abc”. If the pack is running when another launch request comes in, the old one will be killed first (using SIGQUIT). If you want to temporarily prevent a pack from starting up, you can remove its executable bit (”chmod -x packs/abc.sh”) and add it back in later (”chmod +x packs/abc.sh”).

As with serial ports, JET pack launch requests only persist across hub restarts if you include the RETAIN flag by using “jet pub -r ...”.


Viewing all articles
Browse latest Browse all 328

Trending Articles