Initial Cariflex project
- 40 FlexMeasures assets (10 PV, 10 Bat, 10 Chg, 10 EV) - Geolocated on Martinique - Documentation: architecture, deployment, concepts - Standards: Flex Ready, S2, OpenADR, EPEX SPOT - R&D tools: HAMLET, OPLEM, lemlab - Map patch: Mapbox -> OpenStreetMap
This commit is contained in:
96
scripts/relocate_assets.py
Normal file
96
scripts/relocate_assets.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Re-localise les assets Cariflex sur la Martinique."""
|
||||
import subprocess, random
|
||||
|
||||
def run_sql(query):
|
||||
subprocess.run([
|
||||
"docker", "exec", "flexmeasures-db", "psql", "-U", "flexmeasures", "-d", "flexmeasures",
|
||||
"-t", "-c", query
|
||||
], capture_output=True, text=True)
|
||||
|
||||
# Martinique bounding box (approximate)
|
||||
# Lat: 14.38 to 14.87, Lon: -61.25 to -60.82
|
||||
# But we need to avoid the sea - use known land areas
|
||||
|
||||
# Realistic zones on Martinique (lat, lon) - major towns and industrial zones
|
||||
ZONES = [
|
||||
# Fort-de-France area (capital, dense urban)
|
||||
(14.6091, -61.2155), # Fort-de-France center
|
||||
(14.6150, -61.2080), # Fort-de-France north
|
||||
(14.6050, -61.2200), # Fort-de-France south
|
||||
(14.6200, -61.2000), # Fort-de-France east
|
||||
(14.5950, -61.2100), # Fort-de-France west
|
||||
# Le Lamentin (airport, industrial zone)
|
||||
(14.6100, -61.0100), # Le Lamentin center
|
||||
(14.6150, -61.0050), # Airport area
|
||||
(14.6050, -61.0200), # Industrial zone
|
||||
# Sainte-Marie (north-east)
|
||||
(14.7800, -60.9800), # Sainte-Marie town
|
||||
(14.7900, -60.9700), # North coast
|
||||
# Le Robert (north-east coast)
|
||||
(14.6800, -60.9400), # Le Robert town
|
||||
# Le François (south-east coast)
|
||||
(14.6600, -60.9000), # Le François town
|
||||
# Le Vauclin (south-east tip)
|
||||
(14.5500, -60.8400), # Le Vauclin
|
||||
# Le Marin (south)
|
||||
(14.4700, -60.8700), # Le Marin town
|
||||
# Sainte-Anne (south coast)
|
||||
(14.4400, -60.8500), # Sainte-Anne
|
||||
# Le Diamant (south-west)
|
||||
(14.4800, -61.0200), # Le Diamant
|
||||
# Les Anses-d'Arlet (south-west coast)
|
||||
(14.5000, -61.0800), # Les Anses-d'Arlet
|
||||
# Sainte-Luce (south-east)
|
||||
(14.4600, -60.9300), # Sainte-Luce
|
||||
# Le Lorrain (north)
|
||||
(14.7200, -60.9300), # Le Lorrain
|
||||
]
|
||||
|
||||
random.seed(42) # Reproducible
|
||||
|
||||
# Shuffle zones and pick 10 for each asset type (with some overlap for co-location)
|
||||
random.shuffle(ZONES)
|
||||
|
||||
# Get all assets ordered by type and name
|
||||
result = subprocess.run([
|
||||
"docker", "exec", "flexmeasures-db", "psql", "-U", "flexmeasures", "-d", "flexmeasures",
|
||||
"-t", "-c", """
|
||||
SELECT g.id, g.name, gt.name as type_name
|
||||
FROM generic_asset g
|
||||
JOIN generic_asset_type gt ON g.generic_asset_type_id = gt.id
|
||||
ORDER BY gt.id, g.name;
|
||||
"""
|
||||
], capture_output=True, text=True)
|
||||
|
||||
assets = []
|
||||
for line in result.stdout.strip().split('\n'):
|
||||
parts = [p.strip() for p in line.split('|')]
|
||||
if len(parts) == 3:
|
||||
assets.append((int(parts[0]), parts[1], parts[2]))
|
||||
|
||||
# Assign random locations per type (4 types, 10 assets each)
|
||||
type_groups = {}
|
||||
for aid, name, atype in assets:
|
||||
if atype not in type_groups:
|
||||
type_groups[atype] = []
|
||||
type_groups[atype].append((aid, name))
|
||||
|
||||
zone_idx = 0
|
||||
for atype, group in type_groups.items():
|
||||
# Pick 10 random zones for this type (zones can repeat slightly for density)
|
||||
type_zones = [ZONES[i % len(ZONES)] for i in range(zone_idx, zone_idx + 10)]
|
||||
random.shuffle(type_zones)
|
||||
zone_idx += 10
|
||||
|
||||
for i, (aid, name) in enumerate(group):
|
||||
lat, lon = type_zones[i]
|
||||
# Add small random jitter (±0.005 degrees ≈ 500m)
|
||||
lat += random.uniform(-0.005, 0.005)
|
||||
lon += random.uniform(-0.005, 0.005)
|
||||
|
||||
run_sql("UPDATE generic_asset SET latitude = {}, longitude = {} WHERE id = {};".format(
|
||||
round(lat, 6), round(lon, 6), aid))
|
||||
print(" {} ({}) -> {:.4f}, {:.4f}".format(name, atype[:3], lat, lon))
|
||||
|
||||
print("\nDone!")
|
||||
Reference in New Issue
Block a user