fix: OpenRemote PUT 403/409, MQTTv5 callback, geojson-proxy API REST
- simulator.py: Fix MQTTv5 callback crash (5th arg *args) - simulator.py: Fix _or_put() - GET version+realm before PUT, inject version in payload - simulator.py: Fix token TTL (min 30s cache) - simulator.py: Round-robin OR updates (~5 assets/iteration instead of 60) - geojson-proxy: Rewrite using REST API instead of psycopg2 (PG auth issue) - geojson-proxy: Add sensorType + attributes in properties for map styling - docker-compose.yml: Add openremote_default network + DB vars for proxy - docker-compose.yml: Add OR_REALM=master for geojson-proxy Resolves: OpenRemote 403 (wrong realm in payload), 409 (missing version), MQTTv5 callback crash, geojson-proxy DB connection failure
This commit is contained in:
42
simulator.py
42
simulator.py
@@ -506,8 +506,8 @@ class MultiMQTT:
|
||||
c.tls_insecure_set(True)
|
||||
if ws:
|
||||
c.ws_set(b"/mqtt")
|
||||
c.on_connect = lambda _c, _, __, rc: self._on_connect(name, rc)
|
||||
c.on_disconnect = lambda _c, _, __: self._on_disconnect(name)
|
||||
c.on_connect = lambda _c, _, __, rc, *args: self._on_connect(name, rc)
|
||||
c.on_disconnect = lambda _c, _, __, *args: self._on_disconnect(name)
|
||||
try:
|
||||
c.connect(host, port, keepalive=120)
|
||||
c.loop_start()
|
||||
@@ -791,21 +791,41 @@ def _get_or_token() -> str:
|
||||
with urllib.request.urlopen(req, timeout=5) as r:
|
||||
token_data = json.loads(r.read().decode())
|
||||
_or_token_cache["token"] = token_data["access_token"]
|
||||
_or_token_cache["expires"] = time.time() + token_data.get("expires_in", 300) - 60
|
||||
_or_token_cache["expires"] = time.time() + max(token_data.get("expires_in", 300) - 60, 30)
|
||||
return _or_token_cache["token"]
|
||||
except Exception as e:
|
||||
print(f" ⚠️ OpenRemote token → {e}")
|
||||
return ""
|
||||
|
||||
def _or_put(asset_id: str, payload: dict) -> bool:
|
||||
"""PUT update sur un asset OpenRemote (sans If-Match pour éviter 403)."""
|
||||
"""PUT update sur un asset OpenRemote (avec version pour éviter 409 Conflict).
|
||||
Always uses OR_REALM (master) for the API URL, which has cross-realm access.
|
||||
The payload realm is corrected to match the asset's actual realm."""
|
||||
token = _get_or_token()
|
||||
if not token:
|
||||
return False
|
||||
try:
|
||||
# GET current asset to obtain version and actual realm
|
||||
get_url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
||||
get_req = urllib.request.Request(get_url, headers={"Authorization": f"Bearer {token}"})
|
||||
version = None
|
||||
try:
|
||||
with urllib.request.urlopen(get_req, timeout=5) as get_resp:
|
||||
current = json.loads(get_resp.read().decode())
|
||||
version = current.get("version")
|
||||
# Correct the payload realm to match the asset's actual realm
|
||||
payload["realm"] = current.get("realm", OR_REALM)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Inject version into payload to avoid 409 Conflict
|
||||
if version is not None:
|
||||
payload["version"] = version
|
||||
|
||||
body = json.dumps(payload).encode()
|
||||
url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
||||
req = urllib.request.Request(url, data=body,
|
||||
# Always use OR_REALM for PUT URL (master has cross-realm access)
|
||||
put_url = f"{OR_URL}/api/{OR_REALM}/asset/{asset_id}"
|
||||
req = urllib.request.Request(put_url, data=body,
|
||||
headers={
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json",
|
||||
@@ -1150,10 +1170,14 @@ def main():
|
||||
if isinstance(lo, (int, float)):
|
||||
or_values[field] = round(random.uniform(lo, hi), 1)
|
||||
|
||||
# --- OpenRemote REST ---
|
||||
# --- OpenRemote REST (round-robin: seulement quelques assets/itération) ---
|
||||
if ENABLE_OPENREMOTE:
|
||||
ok_or = publish_openremote(sid, sensor, or_values)
|
||||
print(f" 🏠 OpenRemote: {'✅' if ok_or else '⚠️ skipped'}")
|
||||
# Mettre à jour seulement ~5 assets par itération pour éviter timeups
|
||||
# sensor_num % 12 == iteration % 12 → chaque asset est mis à jour toutes les ~60s
|
||||
if sensor_num % 12 == iteration % 12:
|
||||
ok_or = publish_openremote(sid, sensor, or_values)
|
||||
print(f" 🏠 OpenRemote: {'✅' if ok_or else '⚠️ skipped'}")
|
||||
# else: skip OR update this iteration (asset updated in previous cycle)
|
||||
|
||||
# # --- Orion-LD --- (DÉSACTIVÉ: tout passe par les IoT-Agents MQTT)
|
||||
# # if ENABLE_ORION:
|
||||
|
||||
Reference in New Issue
Block a user