Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.1.6] - 2025-07-30

### Changed
- `Sink`, `Source` and `SourceAndSink` now accept multiple `flows` as `inputs` and `outputs` instead of just one. This enables to model more use cases using these classes.
- Further, both `Sink` and `Source` now have a `prevent_simultaneous_flow_rates` argument to prevent simultaneous flow rates of more than one of their Flows.
- `Sink`, `Source` and `SourceAndSink` now accept multiple `flows` as `inputs` and `outputs` instead of just one. This enables to model more use cases using these classes. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]
- Further, both `Sink` and `Source` now have a `prevent_simultaneous_flow_rates` argument to prevent simultaneous flow rates of more than one of their Flows. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]

### Added
- Added `FlowSystem.start_network_app()` and `FlowSystem.stop_network_app()` to easily visualize the network structure of a flow system in an interactive dash web app. This is still experimental and might change in the future. [[#293](https://github.com/flixOpt/flixopt/pull/293) by [@FBumann](https://github.com/FBumann)]

### Deprecated
- For the classes `Sink`, `Source` and `SourceAndSink`: `.sink`, `.source` and `.prevent_simultaneous_sink_and_source` are deprecated in favor of the new arguments `inputs`, `outputs` and `prevent_simultaneous_flow_rates`.
- For the classes `Sink`, `Source` and `SourceAndSink`: `.sink`, `.source` and `.prevent_simultaneous_sink_and_source` are deprecated in favor of the new arguments `inputs`, `outputs` and `prevent_simultaneous_flow_rates`. [[#291](https://github.com/flixOpt/flixopt/pull/291) by [@FBumann](https://github.com/FBumann)]

### Fixed
- Fixed testing issue with new `linopy` version 0.5.6 [[#296](https://github.com/PyPSA/linopy/pull/296) by [@FBumann](https://github.com/FBumann)]
- Fixed testing issue with new `linopy` version 0.5.6 [[#296](https://github.com/flixOpt/flixopt/pull/296) by [@FBumann](https://github.com/FBumann)]

## [2.1.5] - 2025-07-08

Expand Down
1 change: 1 addition & 0 deletions examples/02_Complex/complex_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
flow_system.add_elements(bhkw_2) if use_chp_with_piecewise_conversion else flow_system.add_elements(bhkw)

pprint(flow_system) # Get a string representation of the FlowSystem
flow_system.start_network_app() # Start the network app. DOes only work with extra dependencies installed

# --- Solve FlowSystem ---
calculation = fx.FullCalculation('complex example', flow_system, time_indices)
Expand Down
53 changes: 53 additions & 0 deletions flixopt/flow_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def __init__(

self._connected = False

self._network_app = None

@classmethod
def from_dataset(cls, ds: xr.Dataset):
timesteps_extra = pd.DatetimeIndex(ds.attrs['timesteps_extra'], name='time')
Expand Down Expand Up @@ -241,6 +243,57 @@ def plot_network(
node_infos, edge_infos = self.network_infos()
return plotting.plot_network(node_infos, edge_infos, path, controls, show)

def start_network_app(self):
"""Visualizes the network structure of a FlowSystem using Dash, Cytoscape, and networkx.
Requires optional dependencies: dash, dash-cytoscape, networkx, werkzeug.
"""
from .network_app import DASH_CYTOSCAPE_AVAILABLE, VISUALIZATION_ERROR, flow_graph, shownetwork

warnings.warn(
'The network visualization is still experimental and might change in the future.',
stacklevel=2,
category=UserWarning,
)

if not DASH_CYTOSCAPE_AVAILABLE:
raise ImportError(
f"Network visualization requires optional dependencies. "
f"Install with: pip install flixopt[viz], flixopt[full] or pip install dash dash_cytoscape networkx werkzeug. "
f"Original error: {VISUALIZATION_ERROR}"
)

if not self._connected:
self._connect_network()

if self._network_app is not None:
logger.warning('The network app is already running. Restarting it.')
self.stop_network_app()

self._network_app = shownetwork(flow_graph(self))

def stop_network_app(self):
"""Stop the network visualization server."""
from .network_app import DASH_CYTOSCAPE_AVAILABLE, VISUALIZATION_ERROR
if not DASH_CYTOSCAPE_AVAILABLE:
raise ImportError(
f'Network visualization requires optional dependencies. '
f'Install with: pip install flixopt[viz]. '
f'Original error: {VISUALIZATION_ERROR}'
)

if self._network_app is None:
logger.warning('No network app is currently running. Cant stop it')
return

try:
logger.info('Stopping network visualization server...')
self._network_app.server_instance.shutdown()
logger.info('Network visualization stopped.')
except Exception as e:
logger.error(f'Failed to stop the network visualization app: {e}')
finally:
self._network_app = None

def network_infos(self) -> Tuple[Dict[str, Dict[str, str]], Dict[str, Dict[str, str]]]:
if not self._connected:
self._connect_network()
Expand Down
Loading