Getting Started#

  1. Install LEAF

    python -m pip install leaf-framework
    
  2. Start LEAF

    You can start LEAF with a graphical web interface by running:

    python -m leaf.start
    

    This will launch a local web server, and you can access the LEAF web interface by navigating to http://localhost:4242 in your web browser. This NiceGUI ready to go on http://localhost:4242, http://172.28.36.57:4242, and http://192.168.1.26:4242 message indicates that the server is running and accessible from the browser.

LEAF Welcome UI

When opening the browser and navigating to the LEAF web interface, you will see the log output by default. This page provides information about what is happening within the system.

Guidelines for defining configuration#

When using an adapter, unique information about each physical instance is needed. Each piece may have different identifiers, data paths, and settings. The configuration file provides this individual context by bridging the general adapter code with the specific details of each setup. This configuration allows the adapter system to customise its behaviour for each instance, enabling a single adapter class to be reused across multiple pieces of equipment, each with its configuration.

Equipment Instances#

Each entry under EQUIPMENT_INSTANCES represents an individual EquipmentAdapter instance for a piece of equipment (A single process can support running multiple adapters). This section provides information necessary to distinguish each instance and configure it according to specific needs:

  • equipment:

    • adapter: This field specifies the adapter type, which is the equipment ID within the device.json file of the given adapter (e.g.,ConcreteAdapter1), which is the name of the adapter class. It is needed for adapter discovery. Below, we discuss each aspect of a config file. Due to the config file’s specific nature, some examples for specific adapters are given, denoted with the (EquipmentAdapter specific) tag.

    • data: This field contains identifiers/metadata. It is required for discovery and ensuring uniqueness within the larger network of equipment. If the instance_id is not unique, the program will fail at initialisation.

      • instance_id: A unique identifier for this equipment instance.

      • institute: The organisation or location where the equipment is based.

    • requirements: Defines adapter-specific required operational parameters:

      • write_file (EquipmentAdapter specific): Specifies the path where data from the equipment will be written.

      • broker/host (EquipmentAdapter specific): Connection information, such as the host address.

      • port (EquipmentAdapter specific): The connection port for the host.

      • token (EquipmentAdapter specific): Code for authentication.

    • simulation (optional): This nested data is only required for adapters running in simulated mode, which varies by adapter. Not all adapters support simulations.

      • filename: (EquipmentAdapter specific) A path to a file with simulated data (Note this may change for different adapters).

      • interval: (EquipmentAdapter specific) The interval in seconds when the simulation will feed the adapter another chunk of data (measurement).

    • maximum_message_size (optional): If present, it sets the maximum number of measurements that will be transmitted within a single message. The higher this option, the fewer messages will be sent, but each message will be a larger payload.

    • experiment_timeout (optional): If present, when an experiment is running, and a new measurement hasn’t been taken within this timeout period, the experiment will be stopped. This is used for cases where the lack of measurement data will be due to an error in a given time.

    • external_input (optional): If present, it will use the external input modules that take data—typically commands—from sources other than the equipment the adapter is designed for. This external source could be another tool for analysing the outgoing data. The external input serves as the entry point to “close the loop”—that is, to feed control signals back into the system based on the analysis. Note that this system is in early development and isn’t fully developed. See (here) for progress. The ExternalEventWatcher names are added as the plugin name and requirements provided below. This process is the same as defining an OutputModule discussed below.

Outputs#

Each entry under OUTPUTS represents an OutputModule for transmitting or storing data. Output modules can be chained together through a fallback mechanism, where the next module in the sequence is used if the primary output fails. Like the requirement section within the EquipmentAdapters, most of the fields within an OUTPUTS element are specific to the type of module that is defined to be used.

  • plugin: This specifies the type of output module, e.g., MQTT, KEYDB, SQL or FILE. The name needs to be the same as the OutputModule class.

  • broker/host (OutputModule specific): Connection information, such as the broker or host address for MQTT or KEYDB outputs.

  • port (OutputModule specific): The connection port for the output module.

  • username/password (OutputModule specific): Credentials for authentication (for secure output modules like MQTT).

  • fallback: Defines the next output in the chain if the primary output fails. For example, if both previous outputs fail, an MQTT output can fall back to KEYDB, which can then fall back to a FILE or SQL output.

  • filename (OutputModule specific): Specifies the path to a file where data will be stored locally if other outputs are unavailable (Used in FILE or SQL output modules).

This structure enables flexible data transmission. Primary outputs can be backed up by secondary methods, ensuring data persistence even if one output method encounters issues. This data must be specified within a file known as a “yaml” file. This is essentially a dictionary of keys and values, as seen below.

EQUIPMENT_INSTANCES:
  - equipment:
      adapter: ConcreteAdapter1
      data:
        instance_id: example_equipment_id1
        institute: example_equipment_institute1
      requirements:
        write_file: test/tmp123.csv
  - equipment:
      adapter: ConcreteAdapter1
      data:
        instance_id: example_equipment_id1
        institute: example_equipment_institute1
      requirements:
        write_file: test/tmp.csv
      simulation:
        filename: tests/static_files/biolector1_full.csv
        interval: 10
  - equipment:
      adapter: ConcreteAdapter2
      data:
        instance_id: example_equipment_id3
        institute: example_equipment_institute3
      requirements:
        host: localhost
        port: 9501
        token: c50dcbbd-fa64-4f9c-98f7-85c39d98c3c2
      maximum_message_size: 1
      external_input:
          plugin: MQTTExternalEventWatcher
          broker: localhost
          port: 1883
          topics: 
            - test_topic/external_action
OUTPUTS:
  - plugin: MQTT
    broker: localhost
    port: 1883
    fallback: KEYDB
  - plugin: KEYDB
    host: localhost
    port: 6379
    db: 0
    fallback: SQL
  - plugin: SQL
    filename: local.db
    fallback: FILE
  - plugin: FILE
    filename: local.json
    fallback: null