.. _configuration-reference: Configuration ============= Joule decentralizes signal processing into discrete **modules**. These modules are connected by **streams** as shown in the figure below. The interconnection of modules and streams form a data **pipeline**. A pipeline may execute as a single proces, a collection of processes, or even be distributed across multiple nodes in a network without adjusting any module code. .. figure:: /images/data_pipeline.png Joule **pipelines** are composed of **modules** and **streams** Joule is a system service. Use the ``joule`` command to interact with the service. .. raw:: html
# joule is a systemd service $> sudo service joule restart # use journalctl to view joule logs $> sudo journalctl -u joule.service ... journalctl output # use the joule CLI to interact with the service $> joule --help Usage: joule [OPTIONS] COMMAND [ARGS]...
Joule constructs the pipeline based on configuration files in **/etc/joule**. Details on these configuration files is provided in the sections below. .. _sec-modules: Module Configuration -------------------- :ref:`modules` are executable programs managed by Joule. The module configuration format is shown below: .. raw:: html
: Module Configuration File [Main] #required name = module name exec_cmd = /path/to/executable #optional is_app = no description = a short description # Specify command line arguments # (may also include in the exec_cmd) [Arguments] arg1 = val1 arg2 = val2 # additional arguments... [Inputs] path1 = /data/input/stream1 path2 = /data/input/stream2 # additional inputs... [Outputs] path1 = /data/output/stream1 path2 = /data/output/stream2 # additional outputs...
Module configuration files must end with the **.conf** suffix and should be placed in **/etc/joule/module_configs**. See the list below for information on each setting. Only the **[Main]** section is required, other sections should be included as necessary. **[Main]** * ``exec_cmd`` -- path to module executable, may include command line arguments * ``name`` -- module name * ``is_app`` -- **[yes|no]** whether the module provides a web interface * ``description`` -- optional module description **[Arguments]** * ``key = value`` -- keyword arguments (these may also be specified in the ``exec_cmd``) **[Inputs]** * ``name = /stream/path`` -- input :ref:`sec-pipes` **[Outputs]** * ``name = /stream/path`` -- output pipe configuration Note: Reader Modules may only have a single output and no inputs. Filter modules have no restrictions on the number of inputs and outputs. .. _sec-pipes: Pipe Configuration ------------------ :ref:`pipes` connect modules to streams and are configured in the **[Inputs]** and **[Outputs]** section of the :ref:`sec-modules` file. At a minimum the configuration specifies a pipe name and a stream path shown in Example 1 below. .. raw:: html
: Pipe Configuration Format #1. basic configuration [pipe name] = [stream path] simple = /stream/path/simple #2. with inline stream configuration inline = /stream/path/inline:float32[x,y,z] #3. remote connection, must include inline stream config remote = node2.net:8088 /stream/path/remote:float32[x,y,z]
The pipe configuration can also include an inline stream configuration. This can be used in place of a :ref:`sec-streams` file or in addition to it. Using both enables static type checking for the pipeline. The inline configuration is separated from the stream path by a colon ``:``. The stream datatype is followed by a list of comma separated element names enclosed with brackets ``[ ]``. If the stream is not explicitly configured or does not already exist in the database it is created with default attributes. In Example 2 above the ``inline`` pipe is connected to ``/stream/path/inline`` which has three ``float32`` elements named ``x``, ``y``, and ``z``. If this stream already exists with a different datatype or number of elements, Joule will not start the module. Pipes can also connect to remote streams. To specify a remote source or destination add the URL and optional port number before the stream path. The URL is separated from the stream path by a single space. Remote pipes must include an inline stream configuration. In example 3 above the ``remote`` pipe is connected to ``/stream/path/remote`` on ``node2.net``. If this stream does not exist on **node2**, it will be created with default attributes. If it does exist with a different datatype, or number of elements, Joule will not start the module. Streams can be connected to multiple input pipes but may only be connected to a single output pipe. If a module attempts to connect an output pipe to a stream that already has a producer, Joule will not start the module. .. _sec-streams: DataStream Configuration ------------------------ Streams are timestamped data flows. They are composed of one or more elements as shown below. Timestamps are in Unix microseconds (elapsed time since January 1, 1970). ========= ======== ======== === ======== Timestamp Element1 Element2 ... ElementN ========= ======== ======== === ======== 1003421 0.0 10.5 ... 2.3 1003423 1.0 -8.0 ... 2.3 1003429 8.0 12.5 ... 2.3 1003485 4.0 83.5 ... 2.3 ... ... ... ... ... ========= ======== ======== === ======== The configuration format is shown below: .. raw:: html
: DataStream Configuration File [Main] #required settings (examples) name = stream name path = /stream/path datatype = float32 keep = 1w #optional settings (defaults) decimate = yes [Element1] #required settings (examples) name = stream name #optional settings (defaults) plottable = yes display_type = continuous offset = 0.0 scale_factor = 1.0 default_max = None default_min = None #additional elements...
DataStream configuration files must end with the **.conf** suffix and should be placed in **/etc/joule/stream_configs**. Both **[Main]** and **[Element1]** are required. For streams with more than one element include additional sections **[Element2]**, **[Element3]**, etc. See the list below for information on each setting. **[Main]** * ``name`` -- stream identifier, white space is permitted * ``path`` -- unique identifier which follows the Unix file naming convention. The web UI visualizes the path as a folder hierarchy. * ``datatype`` -- element datatype. Valid types for TimeScale backend (default): .. csv-table:: float32, int16 float64, int32 , int64 Valid types for NilmDB backend: .. csv-table:: float32, int8, uint8 float64, int16, uint16 , int32, uint32 , int64, uint64 * ``keep`` -- how long to store stream data. Format is a value and unit. Units are **h**: hours, **d**: days, **w**: weeks, **m**: months, **y**: years. For example **6d** will keep the last six days of data. Specify **None** to keep no data or **all** to keep all data. * ``decimate`` -- **[yes|no]** whether decimated data will be stored for this stream. Decimation roughly doubles the required storage but enables web UI visualization. **[Element#]** * ``name`` -- element identifier, may contain whitespace * ``plottable`` -- **[yes|no]** whether the element can be plotted * ``display_type`` -- **[continuous|discrete|event]** controls the plot type * ``offset``-- apply linear scaling to data visualization **y=(x-offset)*scale_factor** * ``scale_factor``-- apply linear scaling to data visualization **y=(x-offset)*scale_factor** * ``default_max``-- control axis scaling, set to None for auto scale * ``default_min``-- control axis scaling, set to None for auto scale Streams may also be configured using an abbreviated inline syntax in a module's :ref:`sec-pipes`. .. _sec-system-configuration: System Configuration -------------------- Joule uses a set of default configurations that should work for most cases. These defaults can be customized by editing **/etc/joule/main.conf**. Start joule with the **--config** flag to use a configuration file at an alternate location. The example **main.conf** below shows the full set of options and their default settings: .. raw:: html
: /etc/joule/main.conf #default settings shown [Main] Name = # Module configuration files # files must end with *.conf ModuleDirectory = /etc/joule/module_configs # DataStream configuration files # files must end with *.conf StreamDirectory = /etc/joule/stream_configs # Listen on address # set to 0.0.0.0 to listen on all interfaces # omit to only listen on UNIX socket # IPAddress = 127.0.0.1 # Listen on port # required if IPAddress is specified # Port = 8088 # UNIX Socket directory (must be writable by joule user) SocketDirectory = /tmp/joule # PostgreSQL database connection # DSN format # username:password@[domain|ip_address]:port/database Database = # How often to flush stream data to database InsertPeriod = 5 # How often to remove old data (from DataStream keep settings) CleanupPeriod = 60 # How many lines to keep in each module log (rolling) MaxLogLines = 100 # Manager users with a configuration file # UsersFile = /etc/joule/users.conf # This section enables HTTPS, omit to run server with HTTP. # The default configuration produced by [joule admin initialize] # creates a self signed certificate and associated key. # To prevent MitM attacks, use a PKI to generate credentials [Security] # X.509 certificate Certificate = /etc/joule/security/server.crt # Private key for X.509 certificate Key = /etc/joule/security/server.key # Optional CA Certificate when using a PKI # CertificateAuthority = /etc/joule/security/ca.crt [Proxies] # forward local sites as joule interfaces # list proxies by [site_name = URL] example: # NOTE: do not use "localhost", use the 127.0.0.1 address # rails_app = http://127.0.0.1:3000
See the list below for information on each setting. * ``Name`` Node name, a random value is generated by the ``joule admin initialize`` command * ``ModuleDirectory`` Absolute path to module configuration files. Only files ending with **.conf** will be loaded * ``StreamDirectory`` Absolute path to stream configuration files. Only files ending with **.conf** will be loaded * ``IPAddress`` IP address of interface to listen on. Use **0.0.0.0** to listen on all interfaces. * ``Port`` TCP port to listen on * ``Database`` PostgreSQL connection information as DSN string. Format is **username:password@[domain|ip_address]:port/database**. Database must have TimescaleDB extension loaded and initialized. * ``InsertPeriod`` how often to send stream data to NilmDB (in seconds) * ``CleanupPeriod`` how often to remove old data (in seconds) as specified by stream **keep** parameters * ``MaxLogLines`` max number of lines to keep in a module log file (automatically rolls) * ``UsersFile`` control access using the specified file (example below), no reload is required. * ``[Security]`` This section enables HTTPS using the specified credentials. If this section is omitted the server will run with HTTP. * ``[Proxies]`` This section lists sites to proxy. This allows access to locally hosted sites through Lumen. Example Users File Syntax: .. raw:: html
: /etc/joule/users.conf # Specify user name and key separated by a , # Keys must be unique and at least 32 characters long # If the user exists with a different key, the key is updated. # ---------------------------------------------- # Name, Key alice, 044b1a5153e5f736cd787870cc949f2a bob, f5b37cd7207ac314a74d57d9c2ff8bb0 charlie, 126374f04d61ea485883f6fb287defc0 # Remove users using DELETE, add LIKE for SQL wildcard match (%,_) # ---------------------------------------------------------------- # remove any users with names that begin with temp DELETE LIKE temp% # remove the user named remote_admin DELETE remote_admin
.. _sec-configure-docker: Docker Configuration -------------------- Joule is available as a Docker container on Docker Hub. The container tags match the release versions on PyPi, use the latest tag to retrieve the most recent version of the container. .. raw:: html
docker pull wattsworth/joule:latest
The container can be configured using environment variables as well as mounted volumes. Configuration variables with their default values are listed below: * ``NODE_NAME`` : ``joule`` name of the node * ``POSTGRES_USER`` : ``joule`` PostgreSQL username * ``POSTGRES_PASSWORD`` : ``joule`` PostgreSQL password * ``POSTGRES_HOST`` : ``postgres`` PostgreSQL host name or IP address * ``POSTGRES_PORT`` : ``5432`` PostgreSQL port number * ``POSTGRES_DB`` : ``joule`` PostgreSQL database name * ``USER_KEY`` : no default value, use a 32 character random string * ``HOST_PORT`` : ``80`` Forward facing port when running behind a reverse proxy * ``HOST_SCHEME`` : ``http`` Reverse proxy scheme (http or https) In addition to these environment variables the container can be further customized by mounting the following volumes: * ``/etc/joule/configs/users.conf`` : user configuration file, this replaces the ``USER_KEY`` value * ``/etc/joule/configs/proxies.conf`` : list of sites to proxy. The format is the same as the main configuration file with one ``=`` pair per line. For complete control of system configuration mount a volume to ``/etc/joule`` with a ``main.conf`` and files. This supersedes all other configuration options.