Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
106
scripts/configure_flex.py
Normal file
106
scripts/configure_flex.py
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cariflex - Configure flex_context and flex_model for all 40 assets in FlexMeasures.
|
||||
"""
|
||||
import subprocess, json
|
||||
|
||||
def run_sql(query):
|
||||
result = subprocess.run([
|
||||
"docker", "exec", "flexmeasures-db", "psql", "-U", "flexmeasures", "-d", "flexmeasures",
|
||||
"-t", "-c", query
|
||||
], capture_output=True, text=True)
|
||||
return result.stdout.strip()
|
||||
|
||||
# Flex context per asset type
|
||||
FLEX_CONTEXTS = {
|
||||
1: { # Panneau PV
|
||||
"consumption-capacity": "0kW",
|
||||
"production-capacity": "5kW",
|
||||
"soc-min": "0kWh",
|
||||
"soc-max": "0kWh"
|
||||
},
|
||||
2: { # Batterie
|
||||
"consumption-capacity": "50kW",
|
||||
"production-capacity": "50kW",
|
||||
"soc-min": "10kWh",
|
||||
"soc-max": "100kWh",
|
||||
"charging-efficiency": "95%",
|
||||
"discharging-efficiency": "95%"
|
||||
},
|
||||
3: { # Borne VE
|
||||
"consumption-capacity": "22kW",
|
||||
"production-capacity": "0kW",
|
||||
"soc-min": "0kWh",
|
||||
"soc-max": "0kWh"
|
||||
},
|
||||
4: { # Véhicule EV (V2G)
|
||||
"consumption-capacity": "11kW",
|
||||
"production-capacity": "11kW",
|
||||
"soc-min": "15kWh",
|
||||
"soc-max": "75kWh",
|
||||
"charging-efficiency": "95%",
|
||||
"discharging-efficiency": "95%"
|
||||
}
|
||||
}
|
||||
|
||||
# Flex model per asset type (storage-specific)
|
||||
FLEX_MODELS = {
|
||||
2: { # Batterie
|
||||
"soc-at-start": "50kWh",
|
||||
"soc-target": "80kWh",
|
||||
"soc-min": "10kWh",
|
||||
"soc-max": "100kWh",
|
||||
"roundtrip-efficiency": "90%",
|
||||
"storage-efficiency": "99%",
|
||||
"power-capacity": "50kW"
|
||||
},
|
||||
4: { # EV V2G
|
||||
"soc-at-start": "40kWh",
|
||||
"soc-target": "60kWh",
|
||||
"soc-min": "15kWh",
|
||||
"soc-max": "75kWh",
|
||||
"roundtrip-efficiency": "90%",
|
||||
"storage-efficiency": "99%",
|
||||
"power-capacity": "11kW"
|
||||
}
|
||||
}
|
||||
|
||||
print("=== Configuring flex_context and flex_model for Cariflex assets ===\n")
|
||||
|
||||
# Get assets by type
|
||||
for type_id, type_name in [(1, "PV"), (2, "Battery"), (3, "EV Charger"), (4, "EV V2G")]:
|
||||
assets = run_sql(f"SELECT id, name FROM generic_asset WHERE generic_asset_type_id = {type_id} ORDER BY id;")
|
||||
flex_context = json.dumps(FLEX_CONTEXTS.get(type_id, {}))
|
||||
flex_model = json.dumps(FLEX_MODELS.get(type_id, {}))
|
||||
|
||||
# Escape single quotes for SQL
|
||||
flex_context_sql = flex_context.replace("'", "''")
|
||||
flex_model_sql = flex_model.replace("'", "''")
|
||||
|
||||
# Update all assets of this type
|
||||
result = run_sql(f"""
|
||||
UPDATE generic_asset
|
||||
SET flex_context = '{flex_context_sql}'::jsonb,
|
||||
flex_model = '{flex_model_sql}'::jsonb
|
||||
WHERE generic_asset_type_id = {type_id};
|
||||
""")
|
||||
|
||||
count = len([l for l in assets.split('\n') if l.strip()])
|
||||
print(f" ✅ {type_name}: {count} assets updated")
|
||||
print(f" flex_context: {flex_context}")
|
||||
if type_id in FLEX_MODELS:
|
||||
print(f" flex_model: {flex_model}")
|
||||
print()
|
||||
|
||||
# Verify
|
||||
print("=== Verification ===")
|
||||
for type_id, type_name in [(1, "PV"), (2, "Battery"), (3, "EV Charger"), (4, "EV V2G")]:
|
||||
sample = run_sql(f"""
|
||||
SELECT name, flex_context::text, flex_model::text
|
||||
FROM generic_asset
|
||||
WHERE generic_asset_type_id = {type_id}
|
||||
LIMIT 1;
|
||||
""")
|
||||
print(f" {type_name}: {sample}")
|
||||
|
||||
print("\n✅ Flex context and model configured for all 40 assets!")
|
||||
Reference in New Issue
Block a user