From 7643d88ffb0bff7853a845ef5a6797b71bce059c Mon Sep 17 00:00:00 2001 From: Eric FELIXINE Date: Tue, 26 May 2026 13:14:01 -0400 Subject: [PATCH] Add GeoMap dashboard + ChirpStack REST API config - Grafana GeoMap dashboard (PostGIS + InfluxDB) for real-time sensor visualization - Dashboard accessible at: https://grafana.digitribe.fr/d/geosmart-city-2026/smart-city-geomap-temps-reel - PostGIS datasource added (user: grafana, network: smartcity-shared) - InfluxDB-SmartCity-Correct datasource configured - ChirpStack REST API: added --cors-origins flag --- docker-compose.chirpstack.yml | 2 +- docs/dashboards/geosmart_city_dashboard_2026-05-26.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/dashboards/geosmart_city_dashboard_2026-05-26.json diff --git a/docker-compose.chirpstack.yml b/docker-compose.chirpstack.yml index 832a3298..375cbbd4 100644 --- a/docker-compose.chirpstack.yml +++ b/docker-compose.chirpstack.yml @@ -26,7 +26,7 @@ services: container_name: smart-city-chirpstack-rest-api image: chirpstack/chirpstack-rest-api:4 restart: unless-stopped - command: --server chirpstack:8080 --bind 0.0.0.0:8090 --insecure + command: --server chirpstack:8080 --bind 0.0.0.0:8090 --insecure --cors-origins="*" depends_on: - chirpstack labels: diff --git a/docs/dashboards/geosmart_city_dashboard_2026-05-26.json b/docs/dashboards/geosmart_city_dashboard_2026-05-26.json new file mode 100644 index 00000000..6b26eb13 --- /dev/null +++ b/docs/dashboards/geosmart_city_dashboard_2026-05-26.json @@ -0,0 +1 @@ +{"meta":{"type":"db","canSave":true,"canEdit":true,"canAdmin":true,"canStar":true,"canDelete":true,"slug":"smart-city-geomap-temps-reel","url":"/d/geosmart-city-2026/smart-city-geomap-temps-reel","expires":"0001-01-01T00:00:00Z","created":"2026-05-26T16:59:13Z","updated":"2026-05-26T16:59:13Z","updatedBy":"admin","createdBy":"admin","version":1,"hasAcl":false,"isFolder":false,"folderId":0,"folderUid":"","folderTitle":"General","folderUrl":"","provisioned":false,"provisionedExternalId":"","annotationsPermissions":{"dashboard":{"canAdd":true,"canEdit":true,"canDelete":true},"organization":{"canAdd":true,"canEdit":true,"canDelete":true}}},"dashboard":{"id":37,"panels":[{"datasource":{"type":"postgres","uid":"a9b60854-60c5-4c86-bb0b-d98852df0c89"},"gridPos":{"h":16,"w":24,"x":0,"y":0},"id":1,"options":{"basemap":{"name":"OpenStreetMap","type":"default"},"layers":[{"config":{"color":{"fixed":"green"},"size":{"fixed":10,"max":20,"min":6},"tooltip":{"mode":"details"}},"location":{"latitude":"lat","longitude":"lon","mode":"coords"},"name":"Capteurs","type":"markers"}],"view":{"id":"custom","lat":14.6164,"lon":-61.07,"zoom":12}},"targets":[{"format":"table","rawSql":"SELECT s.id, s.name, s.type, ST_Y(s.location::geometry) AS lat, ST_X(s.location::geometry) AS lon FROM public.sensors s WHERE s.location IS NOT NULL;","refId":"A"}],"title":"Carte des Capteurs - Martinique","type":"geomap"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":15,"lineWidth":2},"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"yellow","value":40},{"color":"orange","value":100},{"color":"red","value":200}]},"unit":"concppb"}},"gridPos":{"h":8,"w":12,"x":0,"y":16},"id":2,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"no2_ugm3\")\n |\u003e aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |\u003e set(key: \"_field\", value: \"NO2 (ug/m3)\")\n |\u003e yield(name: \"mean\")","refId":"A"}],"title":"NO2 en temps reel","type":"timeseries"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"custom":{"fillOpacity":15,"lineWidth":2},"unit":"percent"}},"gridPos":{"h":8,"w":12,"x":12,"y":16},"id":3,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"humidity_percent\")\n |\u003e aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |\u003e set(key: \"_field\", value: \"Humidite (%)\")\n |\u003e yield(name: \"mean\")","refId":"A"}],"title":"Humidite en temps reel","type":"timeseries"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"max":100,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"red","value":null},{"color":"orange","value":20},{"color":"yellow","value":50},{"color":"green","value":80}]},"unit":"percent"}},"gridPos":{"h":6,"w":6,"x":0,"y":24},"id":4,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: -5m)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"battery_level\")\n |\u003e last()","refId":"A"}],"title":"Niveau de batterie","type":"gauge"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"max":50,"min":-10,"thresholds":{"mode":"absolute","steps":[{"color":"blue","value":null},{"color":"green","value":15},{"color":"yellow","value":30},{"color":"red","value":40}]},"unit":"celsius"}},"gridPos":{"h":6,"w":6,"x":6,"y":24},"id":5,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: -5m)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"temperature_c\")\n |\u003e last()","refId":"A"}],"title":"Temperature","type":"gauge"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"max":300,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"yellow","value":100},{"color":"orange","value":180},{"color":"red","value":240}]},"unit":"concppb"}},"gridPos":{"h":6,"w":6,"x":12,"y":24},"id":6,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: -5m)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"o3_ugm3\")\n |\u003e last()","refId":"A"}],"title":"O3 (Ozone)","type":"gauge"},{"datasource":{"type":"influxdb","uid":"dd1bfc24-de9d-4c23-8a3c-151d153f8169"},"fieldConfig":{"defaults":{"max":10,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"yellow","value":2},{"color":"orange","value":5},{"color":"red","value":8}]},"unit":"concmgpm3"}},"gridPos":{"h":6,"w":6,"x":18,"y":24},"id":7,"targets":[{"query":"from(bucket: \"smartcity\")\n |\u003e range(start: -5m)\n |\u003e filter(fn: (r) =\u003e r._measurement == \"mqtt_consumer\")\n |\u003e filter(fn: (r) =\u003e r._field == \"co_mgm3\")\n |\u003e last()","refId":"A"}],"title":"CO (Monoxyde de carbone)","type":"gauge"}],"refresh":"10s","schemaVersion":38,"tags":["smartcity","geomap","iot","martinique"],"time":{"from":"now-1h","to":"now"},"timezone":"America/Martinique","title":"Smart City - GeoMap Temps Réel","uid":"geosmart-city-2026","version":1}} \ No newline at end of file