Welcome to FMBP, a Python framework for contextual reconfiguration of behavioral programs. It includes an extension so the models@run.time approach can be utilised using the UVL-BP GLSP VS Code extension.
- Install Python 3.12 and
uv. - Clone this repository and enter the workspace.
- Install dependencies with
uv sync. - Set up the config file for usage with UVLS / UVL-GLSP
- Start the water tank example with:
uv run python -m examples.water_tank.water_tankRequirements:
- Python >=3.10, <3.13 (BPpy is currently not compatible to 3.13; Tested with 3.12)
- Linux is recommended, but Windows should work
The project should be platform-independent, but is especially tested on Linux.
Using uv (recommended):
- Install
uvusing your package manager or from the official installation instructions. - Clone this repository.
- Install all dependencies and create the environment:
uv sync - Run commands inside the environment with
uv run ....
Requirements:
- Rust >= 1.83.0
- (For the drone sim) OpenJDK 21
- (For UVL language support) VSCode + UVL extension
General Setup:
-
All examples use the UVL LSP with BP extensions. To obtain the binary, clone the following repository: https://github.com/tfelbr/uvl-bp-lsp
In the repository, follow the instructions to build the binary and optionally set up the VSCode IDE.
Important
Make sure to install Z3 as outlined in the repositroy above. This is used to solve new configurations and is crucial for the examples.
- Inside the
examplesdirectory, create a file namedconfig.jsonwith the following content:This file should contain the path to the uvls executable obtained in the previous step. All examples reference this config file.{"uvls_path": "/path/to/uvl-bp-lsp/target/release/uvls"}
This setup is sufficient to run the water tank and smart home examples.
Drone Example Setup:
The drone example is simulated in Alchemist. To set up and run the simulation environment, follow these steps:
- Make sure OpenJDK 21 is installed and active on your PATH.
- Clone this repository: https://github.com/tfelbr/fmbp-alchemist
Running:
We recommend starting with the water tank example.
- Run the Python file within the respective example subdirectory, either within your IDE or via command line.
Use
uv runwith module mode:uv run python -m examples.water_tank.water_tank uv run python -m examples.smart_home.smart_home
- For the drones, first run the Python file and then start the simulation with
./gradlew runDronesinside the simulation's repository. This command installs all dependencies, builds the Scala classes and runs the simulation.In the Alchemist simulation, hit the Add Effect button and select the last item DrawSmartCam to see the drones' visual radius.uv run python -m examples.drones.drones # and then ./gradlew runDrones # inside the root directory of the sim repo
Important
Make sure to start the Python program before the Alchemist simulation. Otherwise, the simulation cannot find the REST endpoints and will crash.
Altering Program Behavior:
To get UVL language support, use VSCode to edit the supplemental UVL files to adapt the programs' behaviors at runtime. The UVL files can be found inside the same directories as the Python files.
Important
Deactivate Auto Save to prevent VSCode from saving the file too early while editing.
While you generally can edit the entire file, there are a few things to consider:
- The ConsistencyChecker employed in all examples ensures consistency between runtime and model in realtime. Editing the feature model part will like cause an instant exception, as model and runtime are no longer aligned.
- The Env feature contains variables for context measurements. The actual values are acquired by the runtime and updated internally. The water tank and smart home examples respect the initial values at start. However, editing these values in the model while the programs are active will have no effect. The drone scenario receives their state from Alchemist, and will not consider the initial values.
- The Config feature holds variables explicitly designed to be altered by the user.
- You may also adapt the list of constraints.
Using UVL-BP GLSP VSCode Extension:
The UVL-BP GLSP VSCode extension provides a graphical interface for editing the UVL files and visualizing the feature model. It allows you to change configurations and see the effects in real-time using the streaming capabilities of this fork. To use the extension, follow these steps:
- Install the extension from OpenVSX: https://open-vsx.org/extension/NickRuider/uvl-bp-vscode-extension or clone the repository directly: https://github.com/xXNicksdaXx/uvl-glsp
- In
examples/config.json, setworkspace_pathto the workspace root expected by the extension.- When using the prebuilt Open VSX extension, set it to the
examplesdirectory of FMBP-SSE. - When using the cloned repository, set it to the workspace path of the
uvl-glsprepository.
- When using the prebuilt Open VSX extension, set it to the
The provided workspace path is used when executing the examples in this repository, using the UVL files available in the respective workspace. This allows you to edit the UVL files in the extension and see the changes reflected in the running examples.
This fork introduces a BPConfigurator extension mechanism, a built-in SSE streaming module for B-Events and context updates, and related example/runtime updates.
-
Added
fmbp/extensions.py:- Defines the
BPConfiguratorExtensionprotocol withstarting(...)andevent_selected(...)hooks.
- Defines the
-
Updated
fmbp/fm_bp.py:BPConfiguratornow acceptsextensionsin its constructor.- Registered extensions are invoked on startup and on every selected B-Event.
- Extension failures are isolated and logged, so they do not crash the runtime by default.
-
Added
fmbp/event_stream.py:- Provides
EventStreamServeras a generic SSE backend for both B-Event streaming and context snapshot streaming. - Exposes
/events(stream) and/health(status). - Provides
EventStreamFactoryto create stream integrations:b_event_stream(source)for BPConfigurator extension wiring.context_source(source, context_source)for ContextSource decoration.
- Includes
BEventStreamerExtensionfor direct BPConfigurator integration. - Includes
ContextSourceStreamDecoratorthat publishescontext_updatepayloads wheneverget_data()is called. - Deduplicates repeated payloads to avoid unnecessary SSE traffic:
- Context updates are skipped if the payload is unchanged.
- B-Events are skipped if unchanged, but are republished after
refresh_after_seconds(default: 5s).
- Uses SSE framing helpers, keep-alive comments, CORS, and queue backpressure handling.
- Provides
-
Updated examples to use the extension:
examples/water_tank/water_tank.pyexamples/smart_home/smart_home.pyexamples/drones/drones.py- Streaming is now wired via
EventStreamFactory:BPConfigurator(..., extensions=[event_stream_factory.b_event_stream(...)])ContextConfigurationProvider(event_stream_factory.context_source(...), ...)
sourcein streamed payloads now uses file paths (uvl_path.resolve()).- Drone runtime now uses
threading.Thread(DroneProcess) instead ofmultiprocessing.Process.
-
Extended
config.jsonwith{"workspace_path": "/path/to/workspace"}
