# Joulectl CLI

Joulectl helps you deploy and manage use cases within the Joule platform. It uses a context configuration which connects to the desired Joule platform.

## Installation

To install joulectl visit [here](https://pypi.org/project/joulectl/).

```bash
pip install joulectl
```

## Joule usecase Lifecycle

Joulectl allows you to manage the entire usecase lifecycle which includes these phases:

* Deployment
* Getting status
* Runtime management
* Undeployment

The follwing sections cover each of these areas.

## Available Commands

Joulectl has a set of commands to support the deployment and management of use cases for both single node and cluster deployment:

* [config](#configure-command)
* [deploy](#deploy-command)
* [list](#list-command)
* [inspect](#inspect-command)
* [process](#process-command)
* [undeploy](#undeploy-command)

Execute `joulectl <command> --help` will show further details on how to use a command.

```bash
$ joulectl --help
Usage: joulectl [OPTIONS] COMMAND [ARGS]...

  Joule deployment and management tool

  joulctl version 0.1.0

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  config    Configure tool setting.
  deploy    Deploy command for transports, streams and use cases.
  inspect   Get deployed specifications for transports, streams and use...
  ls        List deployed transports, streams and use cases.
  undeploy  Undeploy command for transports, streams and use cases.
  usecase   Management command for use cases
```

### Configure command

Joulectl can be configured to execute commands against a cluster or single node.&#x20;

**Command:**  `joulectl config <sub-command> <arguments>`&#x20;

```bash
$ joulectl config --help
Usage: joulectl config [OPTIONS] COMMAND [ARGS]...

  Configure joulectl setting.

Options:
  --help  Show this message and exit.

Commands:
  create  Create a new configuration file.
  show    Show configuration setting
  update  Update configuration setting
```

#### create

On first usage of the tool a configuration file must be created. A `config.json` file will created using default setting under the `~/.config/joule` directory.

The default setting will be applied for single Joule node operation on `127.0.0.1:9080`

```bash
$ joulectl config create
Configuration created.
```

#### update

To change the host address and port using the update command. The example below configures connects to the Joule Guardian process which manages a cluster of Joule processes, to learn more about Joule's capabilities running in cluster mode under the [deployment](https://docs.fractalworks.io/joule/deployment-strategies) section.&#x20;

```bash
$ joulectl config update 192.168.1.10:60110
Joule host set to 192.168.1.10:60110
```

#### show

Display the current configuration setting.

```bash
$ joulectl config show         
Key         Configuration
----------  ---------------------------
joule_dir   /Users/joule/.config/joule
joule_host  localhost:60110
```

### Deploy command

Deploying a use requires at minimum four components to be deploy:

1. Source data transport
2. Stream definition
3. Sink data transport
4. Use case definition which binds source, stream and sink together

A set of sub command elements provide these functionalities.

{% hint style="info" %}
We shall use the **IoT valve control** use case found under the quick start project
{% endhint %}

{% hint style="info" %}
Note the --pod option will be used to deploy artefacts to a specifc cluster of Joule nodes
{% endhint %}

**Command:**  `joulectl deploy <sub-command> <json-filename> --pod <pod-name>`&#x20;

#### Transports

Register transports in to the system.

{% hint style="info" %}
Transports are reusable across use cases
{% endhint %}

#### Sources

Connect to the MQTT sensor data event source

```bash
$ joulectl deploy transport sensor_consumer.json --pod sensor_pod
Host                 Command             Response    Message
-------------------  ------------------  ----------  ---------------------------------
192.168.86.40:50220  REGISTER_TRANSPORT  SUCCESS     Transport registered successfully
```

#### Sinks

Deploy a MQTT event publisher and a file sink.

```bash
$ joulectl deploy transport activation_mqtt_publisher.json --pod sensor_pod 
Host                 Command             Response    Message
-------------------  ------------------  ----------  ---------------------------------
192.168.86.40:50220  REGISTER_TRANSPORT  SUCCESS     Transport registered successfully
```

```bash
$ joulectl deploy transport activation_file.json --pod sensor_pod 
Host                 Command             Response    Message
-------------------  ------------------  ----------  ---------------------------------
192.168.86.40:50220  REGISTER_TRANSPORT  SUCCESS     Transport registered successfully
```

Now list out the deployed transports

```bash
$ joulectl list transports
Pod         Name                     Transport      Type    Created At
----------  -----------------------  -------------  ------  --------------------------
sensor_pod  arduino_sensor_consumer  mqttConsumer   SOURCE  2025-05-03 12:09:04.65979
sensor_pod  test_mqtt_publisher      mqttPublisher  SINK    2025-05-03 12:11:27.069958
sensor_pod  activation_file          file           SINK    2025-05-03 12:12:09.593675
```

#### Stream

```bash
$ joulectl deploy stream valve_control_stream.json --pod sensor_pod
Host                 Command          Response    Message
-------------------  ---------------  ----------  ------------------------------
192.168.86.40:50220  REGISTER_STREAM  SUCCESS     Stream registered successfully
```

#### Use case&#x20;

By deploying a use case the Joule platform creates a runtime context which binds all defined dependencies together to act as a single use case unit

```bash
$ joulectl deploy usecase valve_control_uc.json --pod sensor_pod
Host                 Command         Response    Message
-------------------  --------------  ----------  ------------------------------
192.168.86.40:50220  DEPLOY_USECASE  SUCCESS     Use case deployed successfully
```

At this point you will have a running use case processing sensor event data and publishing alerts both to MQTT and to file.&#x20;

### List command

List deployed clusters, artefacts and running processes:

* Pods
* Members
* Transports
* Streams
* Use cases

**Command:**  `joulectl ls <type>`&#x20;

#### Pods

List the deployed clusters joule nodes.

```bash
$ joulectl ls pods              
Pod           Members
----------  ---------
sensor_pod          1
```

#### Members

List the cluster connected Joule nodes.

```bash
$ joulectl ls members sensor_pod 
Host           Process              Status    Created At           Updated At
-------------  -------------------  --------  -------------------  -------------------
192.168.86.40  192.168.86.40:50220  ONLINE    2025-05-03 12:06:00  2025-05-03 14:31:24
```

#### Transports

List deployed transports.

```bash
$ joulectl ls transports 
Pod         Name                     Transport      Type    Created At
----------  -----------------------  -------------  ------  --------------------------
sensor_pod  sensor_consumer          mqttConsumer   SOURCE  2025-05-03 12:09:04.65979
sensor_pod  mqtt_publisher           mqttPublisher  SINK    2025-05-03 12:11:27.069958
sensor_pod  activation_file          file           SINK    2025-05-03 12:12:09.593675
```

#### Streams

List the deployed stream processing definitions.

```bash
$ joulectl ls streams
Pod         Name                              Metrics Enabled    Telemetry Enabled    Valid From                  Valid To               Created At
----------  --------------------------------  -----------------  -------------------  --------------------------  ---------------------  --------------------------
sensor_pod  sensor_analytics_processing       false              false                2025-05-03 12:15:55.335223  2099-12-31 23:59:59.0  2025-05-03 12:15:55.352551
```

#### Use cases

List the deployed use cases.

```bash
$ joulectl ls usecases
Pod         Name                      Stream                            Sources                  Sinks                                Reference Data      Valid From                  Valid To               Created At
----------  ------------------------  --------------------------------  -----------------------  -----------------------------------  ----------------    --------------------------  ---------------------  --------------------------
sensor_pod  sensor_analytics_uc       sensor_analytics_processing       sensor_consumer          activation_file,mqtt_publisher                           2025-05-03 12:17:07.734485  2099-12-31 23:59:59.0  2025-05-03 12:17:07.738864
```

### Inspect command

This command queries the Joule registry for a given data-type and returns the deployed artefact as a file.

Supported sub commands:

* usecase
* stream
* transport

**Command:**  `joulectl inspect <sub-command> --help` for required arguments.

```bash
$ joulectl inspect usecase sensor_analytics_uc --pod sensor_pod
```

This will return a `sensor_analytics_uc.json` file in to the local directory.&#x20;

### Process command

Control a deployed use case by either pausing processing or resuming the stream processing. This may be useful in the event of debugging.

**Command:**  `joulectl process <sub-command> <usecase-name> --pod <pod-name>`&#x20;

#### Pause

Pause a use case processing

```bash
$ joulectl process pause sensor_analytics_uc --pod sensor_pod
Name                      Command        Response
------------------------  -------------  ----------
test_sensor_analytics_uc  PAUSE_USECASE  SUCCESS
```

#### Resume

Resume a use case processing

```bash
$ joulectl process resume sensor_analytics_uc --pod sensor_pod
Name                      Command         Response
------------------------  --------------  ----------
test_sensor_analytics_uc  RESUME_USECASE  SUCCESS
```

### Undeploy command

To undeploy use cases, stream and transport from the Joule platform.

**Command:** `joulectl undeploy <type> <deployment-name> --pod <pod-name>`&#x20;

{% hint style="info" %}
Note streams and transports cannot be undeployed if there is a dependency on them.
{% endhint %}

#### Usecase

```bash
$ joulectl undeploy usecase sensor_analytics_uc --pod sensor_pod
Host                 Command           Response    Message
-------------------  ----------------  ----------  ----------------------------------
192.168.86.40:50220  UNDEPLOY_USECASE  SUCCESS     Use case unregistered successfully
```

#### Stream

```bash
$ joulectl undeploy stream sensor_analytics_processing --pod sensor_pod
Host                 Command            Response    Message
-------------------  -----------------  ----------  --------------------------------
192.168.86.40:50220  UNREGISTER_STREAM  SUCCESS     Stream unregistered successfully
```

#### Transport

```bash
$ joulectl undeploy transport activation_file SINK --pod sensor_pod
Host                 Command               Response    Message
-------------------  --------------------  ----------  -----------------------------------
192.168.86.40:50220  UNREGISTER_TRANSPORT  SUCCESS     Transport unregistered successfully
```
