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:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

106
scripts/configure_flex.py Normal file
View 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!")