simstadt 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simstadt-0.2.2 → simstadt-0.2.3}/PKG-INFO +6 -2
- {simstadt-0.2.2 → simstadt-0.2.3}/README.md +5 -1
- {simstadt-0.2.2 → simstadt-0.2.3}/pyproject.toml +1 -1
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/cli.py +6 -1
- simstadt-0.2.3/src/simstadt/install.py +117 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/base.py +30 -12
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/energy_grid.py +1 -3
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/solar_potential.py +2 -4
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/runner.py +3 -2
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/__init__.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/__init__.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/green_water.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/heat_demand.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/kpi.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/load_profile.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/photovoltaic.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/providers.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/results/unknown_workflow.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/01_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/01_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/02_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/03_IrradianceProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/04_Visualization.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/100_Solar.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/01_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/01_Preprocessing.step/01_GeometricEstimator.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/01_Preprocessing.step/02_PhysicsPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/01_Preprocessing.step/03_UsagePreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/01_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/02_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/03_IrradianceProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/04_RefurbishmentScenarioMaker.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/05_MonthlyEnergyBalance.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/101_HeatDemand.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/102_GreenWater.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/102_GreenWater.flow/01_ShadowProcessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/102_GreenWater.flow/02_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/102_GreenWater.flow/03_GreenWater.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/102_GreenWater.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/.gitignore +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/CACHEDIR.TAG +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/README.md +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/v/cache/nodeids +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/v/cache/stepwise +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/01_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/01_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/02_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/03_IrradianceProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/04_PhotovoltaicEconomics.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/05_PhotovoltaicPotential.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/01_ShadowProcessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/02_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/02_Preprocessing.step/01_GeometricEstimator.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/02_Preprocessing.step/02_PhysicsPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/02_Preprocessing.step/03_UsagePreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/02_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/03_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/04_IrradianceShadow.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/05_RefurbishmentScenarioMaker.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/06_MonthlyEnergyBalance.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/01_ShadowProcessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/02_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/02_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/03_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/04_IrradianceShadow.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/05_PhotovoltaicEconomics.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/06_PhotovoltaicPotential.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/105_PVWithShadow.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/00_ImportCityGml.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/01_Preprocessing.step/00_GeometricPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/01_Preprocessing.step/01_GeometricEstimator.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/01_Preprocessing.step/02_PhysicsPreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/01_Preprocessing.step/03_UsagePreprocessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/01_Preprocessing.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/02_RefurbishmentScenarioMaker.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/03_WeatherProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/04_IrradianceProcessor.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/05_MonthlyEnergyBalance.step/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/106_HeatDemandWithRefurbishment.flow/params.xml +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/utils.py +0 -0
- {simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/workflows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: simstadt
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python library for using and testing SimStadt workflows.
|
|
5
5
|
Author: Eric Duminil
|
|
6
6
|
Author-email: Eric Duminil <eric.duminil@hft-stuttgart.de>
|
|
@@ -20,7 +20,8 @@ SimStadt is a city simulation tool for energy and urban analysis developed at HF
|
|
|
20
20
|
## Requirements
|
|
21
21
|
|
|
22
22
|
- Python 3.10+
|
|
23
|
-
-
|
|
23
|
+
- Java 17+
|
|
24
|
+
- [SimStadt](https://simstadt.hft-stuttgart.de/download/InstallFiles/SimStadt2_latest.zip) installed separately (or use `simstadt --install`)
|
|
24
25
|
|
|
25
26
|
## Installation
|
|
26
27
|
|
|
@@ -73,6 +74,9 @@ If no project path is specified, workflows are run in a temporary repository und
|
|
|
73
74
|
# Print detected SimStadt installation path and version
|
|
74
75
|
simstadt
|
|
75
76
|
|
|
77
|
+
# Download and install the latest SimStadt release to ~/Desktop
|
|
78
|
+
simstadt --install
|
|
79
|
+
|
|
76
80
|
# Launch the SimStadt GUI
|
|
77
81
|
simstadt --gui
|
|
78
82
|
|
|
@@ -7,7 +7,8 @@ SimStadt is a city simulation tool for energy and urban analysis developed at HF
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
9
9
|
- Python 3.10+
|
|
10
|
-
-
|
|
10
|
+
- Java 17+
|
|
11
|
+
- [SimStadt](https://simstadt.hft-stuttgart.de/download/InstallFiles/SimStadt2_latest.zip) installed separately (or use `simstadt --install`)
|
|
11
12
|
|
|
12
13
|
## Installation
|
|
13
14
|
|
|
@@ -60,6 +61,9 @@ If no project path is specified, workflows are run in a temporary repository und
|
|
|
60
61
|
# Print detected SimStadt installation path and version
|
|
61
62
|
simstadt
|
|
62
63
|
|
|
64
|
+
# Download and install the latest SimStadt release to ~/Desktop
|
|
65
|
+
simstadt --install
|
|
66
|
+
|
|
63
67
|
# Launch the SimStadt GUI
|
|
64
68
|
simstadt --gui
|
|
65
69
|
|
|
@@ -6,10 +6,10 @@ import re
|
|
|
6
6
|
import subprocess
|
|
7
7
|
import sys
|
|
8
8
|
from pathlib import Path
|
|
9
|
+
from .install import cmd_install
|
|
9
10
|
from .utils import chdir
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
|
|
13
13
|
def cmd_info(args: argparse.Namespace) -> None:
|
|
14
14
|
from .runner import get_simstadt_folder, get_simstadt_output, _simstadt_script
|
|
15
15
|
|
|
@@ -82,6 +82,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
82
82
|
description="simstadt - Python library for SimStadt workflows.",
|
|
83
83
|
)
|
|
84
84
|
parser.add_argument("--gui", action="store_true", help="Launch the SimStadt GUI.")
|
|
85
|
+
parser.add_argument("--install", action="store_true", help="Download and install the latest SimStadt release to ~/Desktop.")
|
|
85
86
|
parser.add_argument("template", nargs="?", help="Template name (from SIMSTADT_TEMPLATE_PATH) or path to a .flow directory.")
|
|
86
87
|
parser.add_argument("citygml", nargs="?", type=Path, help="Path to the CityGML input file.")
|
|
87
88
|
parser.add_argument("-d", "--description", help="Human-readable label for the result.")
|
|
@@ -96,6 +97,10 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
96
97
|
def app() -> None:
|
|
97
98
|
parser = build_parser()
|
|
98
99
|
args = parser.parse_args()
|
|
100
|
+
|
|
101
|
+
if args.install:
|
|
102
|
+
cmd_install()
|
|
103
|
+
|
|
99
104
|
if args.template and args.citygml:
|
|
100
105
|
cmd_run(args)
|
|
101
106
|
else:
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Download and install SimStadt from the official release ZIP."""
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import re
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
import tempfile
|
|
9
|
+
import urllib.request
|
|
10
|
+
import zipfile
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from .runner import SIMSTADT_VERSION_FORMAT
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _parse_simstadt_name(manifest: str) -> str:
|
|
17
|
+
m = re.search(f"Implementation-Version: *{SIMSTADT_VERSION_FORMAT}", manifest)
|
|
18
|
+
if not m:
|
|
19
|
+
raise ValueError("Cannot parse Implementation-Version from MANIFEST.MF")
|
|
20
|
+
version, branch, rev, date = m.groups()
|
|
21
|
+
return f"SimStadt2_{version}_{branch}_{date}_{rev}"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _get_java_version() -> int | None:
|
|
25
|
+
try:
|
|
26
|
+
result = subprocess.run(["java", "-version"], capture_output=True, text=True)
|
|
27
|
+
m = re.search(r'version "(\d+)', result.stderr)
|
|
28
|
+
return int(m.group(1)) if m else None
|
|
29
|
+
except FileNotFoundError:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def cmd_install() -> None:
|
|
34
|
+
url = "https://simstadt.hft-stuttgart.de/download/InstallFiles/SimStadt2_latest.zip"
|
|
35
|
+
desktop = Path.home() / "Desktop"
|
|
36
|
+
|
|
37
|
+
if not desktop.exists():
|
|
38
|
+
print(f"Error: {desktop} not found", file=sys.stderr)
|
|
39
|
+
raise SystemExit(1)
|
|
40
|
+
|
|
41
|
+
print("Downloading SimStadt...", file=sys.stderr)
|
|
42
|
+
tmp = None
|
|
43
|
+
try:
|
|
44
|
+
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as f:
|
|
45
|
+
tmp = Path(f.name)
|
|
46
|
+
try:
|
|
47
|
+
urllib.request.urlretrieve(url, tmp)
|
|
48
|
+
except Exception as e:
|
|
49
|
+
print(f"Error: Download failed: {e}", file=sys.stderr)
|
|
50
|
+
raise SystemExit(1)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
with zipfile.ZipFile(tmp) as zf:
|
|
54
|
+
jar_entry = next(
|
|
55
|
+
(
|
|
56
|
+
n
|
|
57
|
+
for n in zf.namelist()
|
|
58
|
+
if re.match(r"lib/simstadt-desktop-.*\.jar$", n)
|
|
59
|
+
),
|
|
60
|
+
None,
|
|
61
|
+
)
|
|
62
|
+
if not jar_entry:
|
|
63
|
+
print(
|
|
64
|
+
"Error: simstadt-desktop JAR not found in ZIP", file=sys.stderr
|
|
65
|
+
)
|
|
66
|
+
raise SystemExit(1)
|
|
67
|
+
with zipfile.ZipFile(io.BytesIO(zf.read(jar_entry))) as jar:
|
|
68
|
+
if "META-INF/MANIFEST.MF" not in jar.namelist():
|
|
69
|
+
print("Error: MANIFEST.MF not found in JAR", file=sys.stderr)
|
|
70
|
+
raise SystemExit(1)
|
|
71
|
+
manifest = jar.read("META-INF/MANIFEST.MF").decode(errors="replace")
|
|
72
|
+
try:
|
|
73
|
+
name = _parse_simstadt_name(manifest)
|
|
74
|
+
except ValueError as e:
|
|
75
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
76
|
+
raise SystemExit(1)
|
|
77
|
+
dest = desktop / name
|
|
78
|
+
if dest.exists():
|
|
79
|
+
print(f"Already installed: {name}")
|
|
80
|
+
return
|
|
81
|
+
dest.mkdir()
|
|
82
|
+
try:
|
|
83
|
+
for member in zf.infolist():
|
|
84
|
+
member_path = (dest / member.filename).resolve()
|
|
85
|
+
if not member_path.is_relative_to(dest.resolve()):
|
|
86
|
+
print(
|
|
87
|
+
f"Error: ZIP contains unsafe path: {member.filename}",
|
|
88
|
+
file=sys.stderr,
|
|
89
|
+
)
|
|
90
|
+
raise SystemExit(1)
|
|
91
|
+
zf.extractall(dest)
|
|
92
|
+
for member in zf.infolist():
|
|
93
|
+
mode = member.external_attr >> 16
|
|
94
|
+
if mode:
|
|
95
|
+
(dest / member.filename).chmod(mode)
|
|
96
|
+
except BaseException:
|
|
97
|
+
shutil.rmtree(dest, ignore_errors=True)
|
|
98
|
+
raise
|
|
99
|
+
print(f"Installed: {dest}")
|
|
100
|
+
except zipfile.BadZipFile as e:
|
|
101
|
+
print(f"Error: Invalid ZIP file: {e}", file=sys.stderr)
|
|
102
|
+
raise SystemExit(1)
|
|
103
|
+
finally:
|
|
104
|
+
if tmp and tmp.exists():
|
|
105
|
+
tmp.unlink()
|
|
106
|
+
|
|
107
|
+
java_version = _get_java_version()
|
|
108
|
+
if java_version is None:
|
|
109
|
+
print(
|
|
110
|
+
"Warning: Java not found. SimStadt requires Java 17. Download: https://bell-sw.com/pages/downloads/#jdk-17-lts",
|
|
111
|
+
file=sys.stderr,
|
|
112
|
+
)
|
|
113
|
+
elif java_version < 17:
|
|
114
|
+
print(
|
|
115
|
+
f"Warning: Java {java_version} found but SimStadt requires Java 17. Download: https://bell-sw.com/pages/downloads/#jdk-17-lts",
|
|
116
|
+
file=sys.stderr,
|
|
117
|
+
)
|
|
@@ -119,15 +119,22 @@ class SimStadtResults(ABC):
|
|
|
119
119
|
|
|
120
120
|
@property
|
|
121
121
|
def name(self) -> str:
|
|
122
|
-
return
|
|
122
|
+
return (
|
|
123
|
+
self._params_element(".//void[@property='name']/string").text or "Unknown"
|
|
124
|
+
)
|
|
123
125
|
|
|
124
126
|
@property
|
|
125
127
|
def short_name(self) -> str:
|
|
126
|
-
return
|
|
128
|
+
return (
|
|
129
|
+
self._params_element(".//void[@property='shortName']/string").text
|
|
130
|
+
or "Unknown"
|
|
131
|
+
)
|
|
127
132
|
|
|
128
133
|
@property
|
|
129
134
|
def workflow_provider(self) -> str:
|
|
130
|
-
return self._params_element(".//void[@property='workflowProvider']/object").get(
|
|
135
|
+
return self._params_element(".//void[@property='workflowProvider']/object").get(
|
|
136
|
+
"class", "Unknown provider"
|
|
137
|
+
)
|
|
131
138
|
|
|
132
139
|
@property
|
|
133
140
|
def workflow_path(self) -> Path:
|
|
@@ -136,7 +143,10 @@ class SimStadtResults(ABC):
|
|
|
136
143
|
|
|
137
144
|
@property
|
|
138
145
|
def citygml(self) -> str:
|
|
139
|
-
return
|
|
146
|
+
return (
|
|
147
|
+
self._params_element(".//void[@property='cityGmlFileNames']//string").text
|
|
148
|
+
or "Unknown CityGML"
|
|
149
|
+
)
|
|
140
150
|
|
|
141
151
|
@property
|
|
142
152
|
def project_path(self) -> Path:
|
|
@@ -170,13 +180,7 @@ class SimStadtResults(ABC):
|
|
|
170
180
|
|
|
171
181
|
@property
|
|
172
182
|
def csv_path(self) -> Path:
|
|
173
|
-
|
|
174
|
-
relevant_csvs = [csv for csv in csvs if self.csv_identifier in csv.name]
|
|
175
|
-
if len(relevant_csvs) == 0:
|
|
176
|
-
raise ValueError("Workflow didn't seem to have returned any CSV file!")
|
|
177
|
-
if len(relevant_csvs) > 1:
|
|
178
|
-
logger.warning("Too many CSV results found for %s", self)
|
|
179
|
-
return relevant_csvs[-1]
|
|
183
|
+
return self.get_unique_by_extension('.csv', self.csv_identifier)
|
|
180
184
|
|
|
181
185
|
def csv_content(self) -> bytes:
|
|
182
186
|
with open(self.csv_path, "rb") as f:
|
|
@@ -185,6 +189,16 @@ class SimStadtResults(ABC):
|
|
|
185
189
|
def get_all_by_extension(self, ext: str) -> list[Path]:
|
|
186
190
|
return [f for f in sorted(self.output_files) if f.suffix == ext]
|
|
187
191
|
|
|
192
|
+
def get_unique_by_extension(self, ext: str, filter: str | None = None) -> Path:
|
|
193
|
+
files_by_extension = self.get_all_by_extension(ext)
|
|
194
|
+
if filter:
|
|
195
|
+
files_by_extension = [f for f in files_by_extension if filter in f.name]
|
|
196
|
+
if len(files_by_extension) == 0:
|
|
197
|
+
raise ValueError(f"Workflow didn't seem to have returned any {ext} file!")
|
|
198
|
+
if len(files_by_extension) > 1:
|
|
199
|
+
raise ValueError(f"Too many {ext} results found for {self}!")
|
|
200
|
+
return files_by_extension[0]
|
|
201
|
+
|
|
188
202
|
@property
|
|
189
203
|
def diagrams(self) -> dict[str, Path]:
|
|
190
204
|
return {}
|
|
@@ -243,6 +257,10 @@ class SimStadtResults(ABC):
|
|
|
243
257
|
def create(cls, provider: str, **kwargs) -> "SimStadtResults":
|
|
244
258
|
if provider not in cls._registry:
|
|
245
259
|
from .unknown_workflow import UnknownWorkflowResults
|
|
246
|
-
|
|
260
|
+
|
|
261
|
+
logger.warning(
|
|
262
|
+
"Unknown workflow provider: %s. Returning UnknownWorkflowResults.",
|
|
263
|
+
provider,
|
|
264
|
+
)
|
|
247
265
|
return UnknownWorkflowResults(**kwargs)
|
|
248
266
|
return cls._registry[provider](**kwargs)
|
|
@@ -19,9 +19,7 @@ class EnergyGridResults(SimStadtResults):
|
|
|
19
19
|
csv_identifier = "json_only"
|
|
20
20
|
|
|
21
21
|
def _parse_results(self) -> pd.DataFrame:
|
|
22
|
-
|
|
23
|
-
assert len(jsons) == 1, f"Exactly one JSON file should have been written: {len(jsons)} were found."
|
|
24
|
-
json_output = jsons[0]
|
|
22
|
+
json_output = self.get_unique_by_extension(".json")
|
|
25
23
|
with open(json_output, encoding="utf-8") as out:
|
|
26
24
|
content = json.load(out)
|
|
27
25
|
buildings = content["buildings"]
|
|
@@ -20,11 +20,9 @@ class SolarPotentialResults(SimStadtResults):
|
|
|
20
20
|
csv_identifier = "_solar_potential" # no CSV output; csv_path will raise if called
|
|
21
21
|
|
|
22
22
|
def _parse_results(self) -> pd.DataFrame:
|
|
23
|
-
|
|
24
|
-
if len(prn_paths) != 1:
|
|
25
|
-
raise ValueError(f"Expected exactly one .prn file, found {len(prn_paths)}")
|
|
23
|
+
prn_path = self.get_unique_by_extension(".prn")
|
|
26
24
|
return pd.read_csv(
|
|
27
|
-
|
|
25
|
+
prn_path, sep=r"\s+", names=["GHI", "DHI", "Ta"], header=None
|
|
28
26
|
)
|
|
29
27
|
|
|
30
28
|
@property
|
|
@@ -26,6 +26,7 @@ from .utils import chdir, random_id
|
|
|
26
26
|
PARAMS = "params.xml"
|
|
27
27
|
SIMSTADT2_GLOB = "SimStadt2_0.*/"
|
|
28
28
|
SIMSTADT_TEMP_REPO = Path(tempfile.gettempdir()) / "simstadt_repo"
|
|
29
|
+
SIMSTADT_VERSION_FORMAT = r"(\S+)\s*\((\w+), rev. (\w+), (\d+)\s*\)"
|
|
29
30
|
|
|
30
31
|
load_dotenv()
|
|
31
32
|
|
|
@@ -69,9 +70,9 @@ def get_template_path() -> Path:
|
|
|
69
70
|
)
|
|
70
71
|
|
|
71
72
|
def get_version_and_date() -> tuple[str, str]:
|
|
72
|
-
|
|
73
|
+
SIMSTADT_VERSION_PATTERN = re.compile(f"Launching SimStadt {SIMSTADT_VERSION_FORMAT}")
|
|
73
74
|
output = get_simstadt_output(get_simstadt_folder())
|
|
74
|
-
m =
|
|
75
|
+
m = SIMSTADT_VERSION_PATTERN.search(output)
|
|
75
76
|
if not m:
|
|
76
77
|
raise ValueError(f"No SimStadt version string found in output:\n{output}")
|
|
77
78
|
version, _branch, _commit, date = m.groups()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/.gitignore
RENAMED
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/CACHEDIR.TAG
RENAMED
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/README.md
RENAMED
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/v/cache/nodeids
RENAMED
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/103_PV.flow/.pytest_cache/v/cache/stepwise
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simstadt-0.2.2 → simstadt-0.2.3}/src/simstadt/templates/104_HeatDemandWithShadow.flow/params.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|