feat(lorawan): démarrage ChirpStack et The Things Stack
- ChirpStack opérationnel (port 8080/8090, gateway bridge UDP 1700) - The Things Stack opérationnel (port 1885/1884, gateway UDP 1701) - Fichages de configuration créés - Docker-compose corrigés (réseaux smartcity-shared) - Désactivation agentLink sur 35 assets du simulateur - Correction _or_put: suppression If-Match header (403) - realm smartcity identifié pour les assets du simulateur
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
# Basic Station configuration for WebSocket gateway connections
|
||||||
|
[general]
|
||||||
|
log_level=4
|
||||||
|
|
||||||
|
[integration.mqtt]
|
||||||
|
server="tcp://mosquitto:1883"
|
||||||
|
event_topic="eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }}"
|
||||||
|
state_topic="eu868/gateway/{{ .GatewayID }}/state/{{ .StateType }}"
|
||||||
|
command_topic="eu868/gateway/{{ .GatewayID }}/command/#"
|
||||||
|
json=true
|
||||||
|
|
||||||
|
[backend]
|
||||||
|
type="basic_station"
|
||||||
|
[backend.basic_station]
|
||||||
|
bind=":3001"
|
||||||
|
tls_cert=""
|
||||||
|
tls_key=""
|
||||||
|
ca_cert=""
|
||||||
|
region="EU868"
|
||||||
|
frequency_min=863000000
|
||||||
|
frequency_max=870000000
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ChirpStack Gateway Bridge configuration (EU868)
|
||||||
|
[general]
|
||||||
|
log_level=4
|
||||||
|
|
||||||
|
[integration.mqtt]
|
||||||
|
server="tcp://mosquitto:1883"
|
||||||
|
event_topic="eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }}"
|
||||||
|
state_topic="eu868/gateway/{{ .GatewayID }}/state/{{ .StateType }}"
|
||||||
|
command_topic="eu868/gateway/{{ .GatewayID }}/command/#"
|
||||||
|
json=true
|
||||||
|
client_id="chirpstack-gateway-bridge"
|
||||||
26
configuration/chirpstack/chirpstack.toml
Normal file
26
configuration/chirpstack/chirpstack.toml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[logging]
|
||||||
|
level="info"
|
||||||
|
|
||||||
|
[postgresql]
|
||||||
|
dsn="postgres://chirpstack:chirpstack@postgres/chirpstack?sslmode=disable"
|
||||||
|
|
||||||
|
[redis]
|
||||||
|
url="redis://redis:6379"
|
||||||
|
|
||||||
|
[mqtt]
|
||||||
|
server="tcp://mosquitto:1883"
|
||||||
|
|
||||||
|
[network]
|
||||||
|
net_id="000000"
|
||||||
|
enabled_regions=["eu868"]
|
||||||
|
|
||||||
|
[api]
|
||||||
|
bind="0.0.0.0:8080"
|
||||||
|
secret="you-must-change-this-secret-value"
|
||||||
|
|
||||||
|
[gateway]
|
||||||
|
client_cert_lifetime="90d"
|
||||||
|
|
||||||
|
[monitoring]
|
||||||
|
# Prometheus metrics
|
||||||
|
prometheus_bind="0.0.0.0:9090"
|
||||||
16
configuration/mosquitto/config/mosquitto.conf
Normal file
16
configuration/mosquitto/config/mosquitto.conf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
listener 1883
|
||||||
|
allow_anonymous true
|
||||||
|
persistence true
|
||||||
|
persistence_location /mosquitto/data/
|
||||||
|
log_dest file /mosquitto/log/mosquitto.log
|
||||||
|
|
||||||
|
# Bridge to EMQX for upstream integration
|
||||||
|
connection bridge-emqx
|
||||||
|
address emqx_emqx_1:1883
|
||||||
|
topic eu868/# out 1
|
||||||
|
topic application/# in 1
|
||||||
|
bridge_protocol_version mqttv311
|
||||||
|
cleansession true
|
||||||
|
try_private false
|
||||||
|
notifications false
|
||||||
|
remote_clientid chirpstack-bridge
|
||||||
2
configuration/postgresql/initdb/01-chirpstack.sql
Normal file
2
configuration/postgresql/initdb/01-chirpstack.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- Initialize ChirpStack database
|
||||||
|
CREATE DATABASE IF NOT EXISTS chirpstack;
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
is:
|
||||||
|
database:
|
||||||
|
uri: postgres://root:root@tts-postgres:5432/ttn_lorawan?sslmode=disable
|
||||||
|
email:
|
||||||
|
sender-name: "The Things Stack"
|
||||||
|
sender-address: "noreply@digitribe.fr"
|
||||||
|
network:
|
||||||
|
name: "Smart City LoRaWAN"
|
||||||
|
console-url: "https://tts.digitribe.fr/console"
|
||||||
|
identity-server-url: "https://tts.digitribe.fr/oauth"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
address: tts-redis:6379
|
||||||
|
|
||||||
|
metrics:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
console:
|
||||||
|
base-url: "https://tts.digitribe.fr/console"
|
||||||
|
|
||||||
|
http:
|
||||||
|
cookie:
|
||||||
|
block-key: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
|
||||||
|
hash-key: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
|
||||||
|
|
||||||
|
gateway-server:
|
||||||
|
mqtt:
|
||||||
|
listen: ":1883"
|
||||||
|
public-address: "tts.digitribe.fr:1883"
|
||||||
|
|
||||||
|
network-server:
|
||||||
|
net-id: "000000"
|
||||||
|
band:
|
||||||
|
name: "EU868"
|
||||||
|
|
||||||
|
join-server:
|
||||||
|
default:
|
||||||
|
join-eui-prefix: "0000000000000000"
|
||||||
|
|
||||||
|
tenant-id: "smart-city"
|
||||||
|
|
||||||
|
blob:
|
||||||
|
local-directory: /srv/ttn-lorawan/public/blob
|
||||||
|
base-url: "https://tts.digitribe.fr/blob"
|
||||||
@@ -33,9 +33,7 @@ services:
|
|||||||
- "traefik.http.services.chirpstack.loadbalancer.server.port=8080"
|
- "traefik.http.services.chirpstack.loadbalancer.server.port=8080"
|
||||||
networks:
|
networks:
|
||||||
- traefik-public
|
- traefik-public
|
||||||
- chirpstack-internal
|
|
||||||
- smartcity-shared
|
- smartcity-shared
|
||||||
|
|
||||||
chirpstack-gateway-bridge:
|
chirpstack-gateway-bridge:
|
||||||
image: chirpstack/chirpstack-gateway-bridge:4
|
image: chirpstack/chirpstack-gateway-bridge:4
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -50,8 +48,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- mosquitto
|
- mosquitto
|
||||||
networks:
|
networks:
|
||||||
- chirpstack-internal
|
- smartcity-shared
|
||||||
|
|
||||||
chirpstack-gateway-bridge-basicstation:
|
chirpstack-gateway-bridge-basicstation:
|
||||||
image: chirpstack/chirpstack-gateway-bridge:4
|
image: chirpstack/chirpstack-gateway-bridge:4
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -68,8 +65,7 @@ services:
|
|||||||
- mosquitto
|
- mosquitto
|
||||||
networks:
|
networks:
|
||||||
- traefik-public
|
- traefik-public
|
||||||
- chirpstack-internal
|
- smartcity-shared
|
||||||
|
|
||||||
chirpstack-rest-api:
|
chirpstack-rest-api:
|
||||||
image: chirpstack/chirpstack-rest-api:4
|
image: chirpstack/chirpstack-rest-api:4
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -84,8 +80,7 @@ services:
|
|||||||
- chirpstack
|
- chirpstack
|
||||||
networks:
|
networks:
|
||||||
- traefik-public
|
- traefik-public
|
||||||
- chirpstack-internal
|
- smartcity-shared
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:14-alpine
|
image: postgres:14-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -97,8 +92,7 @@ services:
|
|||||||
- POSTGRES_PASSWORD=chirpstack
|
- POSTGRES_PASSWORD=chirpstack
|
||||||
- POSTGRES_DB=chirpstack
|
- POSTGRES_DB=chirpstack
|
||||||
networks:
|
networks:
|
||||||
- chirpstack-internal
|
- smartcity-shared
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -106,8 +100,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- chirpstack-redisdata:/data
|
- chirpstack-redisdata:/data
|
||||||
networks:
|
networks:
|
||||||
- chirpstack-internal
|
- smartcity-shared
|
||||||
|
|
||||||
mosquitto:
|
mosquitto:
|
||||||
image: eclipse-mosquitto:2
|
image: eclipse-mosquitto:2
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -116,9 +109,7 @@ services:
|
|||||||
- chirpstack-mosquitto-data:/mosquitto/data
|
- chirpstack-mosquitto-data:/mosquitto/data
|
||||||
- chirpstack-mosquitto-log:/mosquitto/log
|
- chirpstack-mosquitto-log:/mosquitto/log
|
||||||
networks:
|
networks:
|
||||||
- chirpstack-internal
|
|
||||||
- smartcity-shared
|
- smartcity-shared
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
chirpstack-postgresqldata:
|
chirpstack-postgresqldata:
|
||||||
chirpstack-redisdata:
|
chirpstack-redisdata:
|
||||||
@@ -130,5 +121,3 @@ networks:
|
|||||||
external: true
|
external: true
|
||||||
smartcity-shared:
|
smartcity-shared:
|
||||||
external: true
|
external: true
|
||||||
chirpstack-internal:
|
|
||||||
driver: bridge
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- tts-postgres-data:/var/lib/postgresql/data
|
- tts-postgres-data:/var/lib/postgresql/data
|
||||||
networks:
|
networks:
|
||||||
- tts-internal
|
- smartcity-shared
|
||||||
|
|
||||||
tts-redis:
|
tts-redis:
|
||||||
image: redis:7
|
image: redis:7
|
||||||
command: redis-server --appendonly yes
|
command: redis-server --appendonly yes
|
||||||
@@ -29,8 +28,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- tts-redis-data:/data
|
- tts-redis-data:/data
|
||||||
networks:
|
networks:
|
||||||
- tts-internal
|
- smartcity-shared
|
||||||
|
|
||||||
tts-stack:
|
tts-stack:
|
||||||
image: thethingsnetwork/lorawan-stack:latest
|
image: thethingsnetwork/lorawan-stack:latest
|
||||||
entrypoint: ttn-lw-stack -c /config/ttn-lw-stack-docker.yml
|
entrypoint: ttn-lw-stack -c /config/ttn-lw-stack-docker.yml
|
||||||
@@ -47,7 +45,7 @@ services:
|
|||||||
TTN_LW_REDIS_ADDRESS: tts-redis:6379
|
TTN_LW_REDIS_ADDRESS: tts-redis:6379
|
||||||
TTN_LW_IS_DATABASE_URI: postgres://root:***@tts-postgres:5432/ttn_lorawan?sslmode=disable
|
TTN_LW_IS_DATABASE_URI: postgres://root:***@tts-postgres:5432/ttn_lorawan?sslmode=disable
|
||||||
ports:
|
ports:
|
||||||
- "1700:1700/udp"
|
- "1701:1700/udp" # ChirpStack uses 1700
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# Console web
|
# Console web
|
||||||
@@ -62,9 +60,7 @@ services:
|
|||||||
- "traefik.http.services.tts-api.loadbalancer.server.port=1884"
|
- "traefik.http.services.tts-api.loadbalancer.server.port=1884"
|
||||||
networks:
|
networks:
|
||||||
- traefik-public
|
- traefik-public
|
||||||
- tts-internal
|
|
||||||
- smartcity-shared
|
- smartcity-shared
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
tts-postgres-data:
|
tts-postgres-data:
|
||||||
tts-redis-data:
|
tts-redis-data:
|
||||||
@@ -74,5 +70,3 @@ networks:
|
|||||||
external: true
|
external: true
|
||||||
smartcity-shared:
|
smartcity-shared:
|
||||||
external: true
|
external: true
|
||||||
tts-internal:
|
|
||||||
driver: bridge
|
|
||||||
|
|||||||
16
simulator.py
16
simulator.py
@@ -798,31 +798,17 @@ def _get_or_token() -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _or_put(asset_id: str, payload: dict) -> bool:
|
def _or_put(asset_id: str, payload: dict) -> bool:
|
||||||
"""PUT update sur un asset OpenRemote (avec version)."""
|
"""PUT update sur un asset OpenRemote (sans If-Match pour éviter 403)."""
|
||||||
token = _get_or_token()
|
token = _get_or_token()
|
||||||
if not token:
|
if not token:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
# Récupérer la version actuelle de l'asset
|
|
||||||
get_url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
|
||||||
get_req = urllib.request.Request(get_url, headers={"Authorization": f"Bearer {token}"})
|
|
||||||
version = 1
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(get_req, timeout=5) as resp:
|
|
||||||
asset_data = json.loads(resp.read().decode())
|
|
||||||
version = asset_data.get("version", 1)
|
|
||||||
except:
|
|
||||||
pass # Si GET échoue, utiliser version=1
|
|
||||||
|
|
||||||
# Ajouter la version au payload
|
|
||||||
payload["version"] = version
|
|
||||||
body = json.dumps(payload).encode()
|
body = json.dumps(payload).encode()
|
||||||
url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
||||||
req = urllib.request.Request(url, data=body,
|
req = urllib.request.Request(url, data=body,
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {token}",
|
"Authorization": f"Bearer {token}",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"If-Match": str(version),
|
|
||||||
},
|
},
|
||||||
method="PUT")
|
method="PUT")
|
||||||
with http_request_duration.labels(broker="openremote", method="PUT").time():
|
with http_request_duration.labels(broker="openremote", method="PUT").time():
|
||||||
|
|||||||
Reference in New Issue
Block a user