- outputs/platform, outputs/prospect : scripts de construction des decks commerciaux + captures sources et .pptx generes. - outputs/mnaha : seed complet de l'instance de demo luxembourgeoise (scripts par etape, contenus, images generees), le deck en version marque blanche et en version brandee, le PDF de presentation. - outputs/Wireframes : maquettes app mobile, app web et manager. - interview clients : notes de l'entretien Fourneau St Michel. state.json et les __pycache__ sont ignores : le premier porte les cles d'API de l'instance seedee, les scripts le regenerent.
93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Étape 8 — parc de bornes.
|
|
|
|
Trois tablettes déclarées, avec leur état de connexion, leur batterie et leur
|
|
version : c'est ce que montre l'écran « Applications → Kiosk » du back-office.
|
|
Chaque appareil est ensuite rattaché au lien de configuration de son site, sans
|
|
quoi les cartes de l'écran restent « aucune tablette appairée ».
|
|
"""
|
|
|
|
import json
|
|
from datetime import datetime, timedelta, timezone
|
|
from pathlib import Path
|
|
|
|
from api import Api
|
|
|
|
STATE = Path(__file__).resolve().parent / "state.json"
|
|
|
|
DEVICES = [
|
|
{"site": "feschmaart", "name": "Fëschmaart — hall d'accueil",
|
|
"identifier": "MNAHA-FM-01", "wlan": "192.168.20.41", "eth": "10.0.20.41",
|
|
"battery": "94", "connection": "excellent", "version": "3.4.1",
|
|
"connected": True, "seen_minutes": 2},
|
|
{"site": "feschmaart", "name": "Fëschmaart — salles d'archéologie",
|
|
"identifier": "MNAHA-FM-02", "wlan": "192.168.20.42", "eth": "",
|
|
"battery": "61", "connection": "bon", "version": "3.4.1",
|
|
"connected": True, "seen_minutes": 7},
|
|
{"site": "draieechelen", "name": "Dräi Eechelen — billetterie",
|
|
"identifier": "MNAHA-DE-01", "wlan": "192.168.30.11", "eth": "10.0.30.11",
|
|
"battery": "18", "connection": "faible", "version": "3.3.8",
|
|
"connected": False, "seen_minutes": 1490},
|
|
]
|
|
|
|
|
|
def utc(dt):
|
|
return dt.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
|
|
|
|
def main():
|
|
api = Api()
|
|
state = json.loads(STATE.read_text(encoding="utf-8"))
|
|
instance_id = state["instanceId"]
|
|
now = datetime.now(timezone.utc)
|
|
|
|
existing = {d["identifier"]: d
|
|
for d in (api.get(f"/api/Device?instanceId={instance_id}") or [])}
|
|
|
|
created = {}
|
|
for spec in DEVICES:
|
|
seen = now - timedelta(minutes=spec["seen_minutes"])
|
|
body = {
|
|
"instanceId": instance_id,
|
|
"identifier": spec["identifier"],
|
|
"name": spec["name"],
|
|
"configurationId": state["configs"][spec["site"]],
|
|
"ipAddressWLAN": spec["wlan"],
|
|
"ipAddressETH": spec["eth"],
|
|
"connected": spec["connected"],
|
|
"batteryLevel": spec["battery"],
|
|
"lastBatteryLevel": utc(seen),
|
|
"connectionLevel": spec["connection"],
|
|
"lastConnectionLevel": utc(seen),
|
|
"appVersion": spec["version"],
|
|
"lastSeen": utc(seen),
|
|
}
|
|
if spec["identifier"] in existing:
|
|
body["id"] = existing[spec["identifier"]]["id"]
|
|
device = api.put("/api/Device", body)
|
|
print(f" ~ {spec['name']}")
|
|
else:
|
|
device = api.post("/api/Device", body)
|
|
print(f" + {spec['name']}")
|
|
created[spec["identifier"]] = device["id"] if device else \
|
|
existing[spec["identifier"]]["id"]
|
|
|
|
# Rattachement aux liens de configuration de l'application borne.
|
|
kiosk_id = state["apps"]["kiosk"]
|
|
links = api.get(f"/api/ApplicationInstance/{kiosk_id}/application-link") or []
|
|
by_config = {l["configurationId"]: l for l in links}
|
|
|
|
for spec in DEVICES:
|
|
link = by_config.get(state["configs"][spec["site"]])
|
|
if not link or link.get("deviceId"):
|
|
continue
|
|
link["deviceId"] = created[spec["identifier"]]
|
|
api.put("/api/ApplicationInstance/application-link", link)
|
|
print(f" lien borne {spec['site']} <- {spec['identifier']}")
|
|
|
|
print("\nétape 8 terminée")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|