Fix simulator (use FM client), install entsoe+weather plugins, fix Redis

- Simulator rewritten to use flexmeasures_client (works!)
- flexmeasures-entsoe installed (ENTSO-E data import)
- flexmeasures-weather installed (weather data)
- FlexMeasures Redis connection fixed (DNS resolution)
- Dashboard Grafana updated with Cariflex asset types
- Simulator running in background, posting to 40 sensors

TODO:
- S2 CEM deployment
- Scheduler FlexMeasures
- Logo Cariflex in FM UI
This commit is contained in:
Eric F
2026-06-08 08:33:16 -04:00
parent 8f7c24acd4
commit 6fe79471f3
2 changed files with 112 additions and 183 deletions

View File

@@ -10,123 +10,79 @@
"panels": [
{
"id": 1,
"title": "Capteurs Air Quality (10)",
"title": "Production PV (kW) - 10 panneaux",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /airquality/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /pv_/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "none"},
"overrides": []
}
"fieldConfig": {"defaults": {"unit": "kW", "min": 0, "max": 50}}
},
{
"id": 2,
"title": "Capteurs Weather (10)",
"title": "Consommation Bornes VE (kW) - 10 bornes",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /weather/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /chg_/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "celsius", "min": 15, "max": 40},
"overrides": []
}
"fieldConfig": {"defaults": {"unit": "kW", "min": 0, "max": 220}}
},
{
"id": 3,
"title": "Capteurs Traffic (10)",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8},
"title": "Batteries - État de Charge (kWh) - 10 batteries",
"type": "gauge",
"gridPos": {"h": 8, "w": 8, "x": 0, "y": 8},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /traffic/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /bat_/) |> mean()",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "kmh", "min": 0, "max": 100},
"overrides": []
"defaults": {"unit": "kWh", "min": 0, "max": 100, "thresholds": {"steps": [{"color": "red", "value": 0}, {"color": "yellow", "value": 20}, {"color": "green", "value": 50}]}}
}
},
{
"id": 4,
"title": "Capteurs Parking (10)",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 8},
"title": "VE V2G - État de Charge (kWh) - 10 véhicules",
"type": "gauge",
"gridPos": {"h": 8, "w": 8, "x": 8, "y": 8},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /parking/) |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /ev_/) |> mean()",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "percent", "min": 0, "max": 100},
"overrides": []
"defaults": {"unit": "kWh", "min": 0, "max": 75, "thresholds": {"steps": [{"color": "red", "value": 0}, {"color": "yellow", "value": 15}, {"color": "green", "value": 40}]}}
}
},
{
"id": 5,
"title": "Battery Level (tous capteurs)",
"type": "gauge",
"gridPos": {"h": 6, "w": 6, "x": 0, "y": 16},
"title": "Flexibilité Disponible (kW)",
"type": "stat",
"gridPos": {"h": 8, "w": 8, "x": 16, "y": 8},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"_field\"] == \"battery_level\") |> mean()",
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"topic\"] =~ /bat_|ev_/) |> mean()",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "percent", "min": 0, "max": 100, "thresholds": {"steps": [{"color": "red", "value": 0}, {"color": "yellow", "value": 20}, {"color": "green", "value": 50}]}},
"overrides": []
}
"fieldConfig": {"defaults": {"unit": "kW", "min": 0}}
},
{
"id": 6,
"title": "Temperature (°C)",
"type": "stat",
"gridPos": {"h": 6, "w": 6, "x": 6, "y": 16},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"title": "Carte des Actifs Cariflex",
"type": "geomap",
"gridPos": {"h": 10, "w": 24, "x": 0, "y": 16},
"datasource": {"type": "postgres", "uid": "PostgreSQL-SmartCity"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"_field\"] == \"temperature_celsius\") |> mean()",
"rawSql": "SELECT g.name, g.latitude, g.longitude, gt.name as type FROM generic_asset g JOIN generic_asset_type gt ON g.generic_asset_type_id = gt.id WHERE g.account_id = 1 ORDER BY gt.id, g.id",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "celsius", "min": 15, "max": 40},
"overrides": []
}
},
{
"id": 7,
"title": "Noise Level (dB)",
"type": "stat",
"gridPos": {"h": 6, "w": 6, "x": 12, "y": 16},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: -5m) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"_field\"] == \"noise_level_db\") |> mean()",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "dB", "min": 0, "max": 120},
"overrides": []
}
},
{
"id": 8,
"title": "Rain (mm)",
"type": "stat",
"gridPos": {"h": 6, "w": 6, "x": 18, "y": 16},
"datasource": {"type": "influxdb", "uid": "influxdb-v2"},
"targets": [{
"query": "from(bucket:\"smartcity\") |> range(start: -1h) |> filter(fn: (r) => r[\"_measurement\"] == \"mqtt_consumer\") |> filter(fn: (r) => r[\"_field\"] == \"rain_mm\") |> sum()",
"refId": "A"
}],
"fieldConfig": {
"defaults": {"unit": "mm", "min": 0},
"overrides": []
}
"options": {"view": {"center": [14.6, -61.2], "zoom": 10}}
}
]
},