Aller au contenu principal

V0.6.0 — Paramétrage des Caméras par ONVIF

Publiée le 14/10/2026.

Documentation fonctionnelle

Ce que change la version pour les collaborateurs

Pourquoi​

Le nom (CAM01) et la date qui défilent dans le Live ne viennent pas d'ArgOS : la caméra les dessine elle-même dans l'image, et ArgOS relaie le Flux sans réencodage. Pour les changer, il faut régler la caméra. Or l'interface web des caméras génériques exige souvent un vieux module ActiveX, et l'application du fabricant passe par son cloud. Sur la caméra de dev : horloge au 31/12/1999, fuseau australien, nom incrusté qui ne dit rien. La 0.6.0 règle ces points par ONVIF, le standard de réglage des caméras IP, depuis l'Administration.

Ce qu'on peut faire maintenant​

  • Ouvrir, depuis l'Administration, les Réglages d'une Caméra active. ArgOS lit la caméra par ONVIF et trouve seul le port, avec les identifiants de son URL RTSP, sans passer par l'interface web de la caméra ni par le cloud du fabricant. Bouton Réglages sur une Caméra active, absent sur une Caméra désactivée Lecture de la caméra en cours
  • Voir l'Horloge de la caméra (date, écart avec l'heure du Site, fuseau, serveur de temps) et ses Incrustations (nom, date et heure, coin). Réglages lus : Horloge en retard de 26 ans, fuseau AWST-8, CAM01 en haut à gauche
  • Changer le nom incrusté dans l'image (ou reprendre le nom ArgOS de la Caméra), le déplacer dans un coin, cacher ou réafficher la date et l'heure. ArgOS montre, champ par champ, si la caméra a pris ou refusé le réglage. Texte du nom et coin de la date pris Reprendre le nom ArgOS Texte trop long refusé, position prise Confirmation avant de cacher la date et heure Date et heure cachée : pris Date et heure réaffichée : pris Champs modifiés avant Annuler Après Annuler : valeurs d'origine
  • Choisir le fuseau de la caméra dans une liste lisible (Europe/Paris) et la mettre à l'heure du Site d'un clic, sans lui ouvrir internet. Fuseau Europe/Paris pris Fuseau relu à la réouverture, écart inchangé Avant la mise à l'heure du Site : en retard de 26 ans Après la mise à l'heure du Site : à l'heure
  • Comprendre clairement pourquoi une caméra ne se règle pas : pas d'ONVIF, identifiants refusés ou caméra injoignable. Cette caméra ne répond pas en ONVIF La caméra refuse ces identifiants en ONVIF Caméra injoignable
  • Après Enregistrer, voir pour chaque champ envoyé la valeur demandée, la valeur relue sur la caméra et le statut (pris, pas pris, refusé) : une caméra peut accepter un réglage sans l'appliquer. Rien n'est gardé en base, la caméra reste la seule source de vérité ; seul le port ONVIF trouvé est retenu.
  • Développer et tester sans matériel : les Caméras simulées 2 (port 8899, avec identifiants, comme une XiongMai) et 4 (port 80, sans identifiants) répondent en ONVIF, « sortie d'usine » à chaque démarrage (simulation/onvif/).
  • Lire la documentation, la feuille de route et les bugs connus sur un site Docusaurus publié par GitHub Pages.

Documentation technique

Spec versionnée : docs/specs/v0.6.0-parametrage-des-cameras-par-onvif.md

Issue parente : #52

V0.6.0 — Paramétrage des Caméras par ONVIF

Problem Statement​

Le nom (CAM01) et la date qui défilent dans le Live ne viennent pas d'ArgOS : la caméra les dessine elle-même dans l'image, avant de l'encoder. ArgOS relaie le Flux sans réencodage : il ne peut ni les effacer ni les changer. Le seul moyen est de régler la caméra.

Or l'interface web des caméras génériques exige souvent un vieux module Windows (ActiveX), inutilisable depuis un navigateur récent, et l'application du fabricant passe par son cloud, contraire à l'esprit d'ArgOS et à la page sécurité. Résultat sur la caméra de dev : une horloge au 31/12/1999, un fuseau australien, un nom incrusté CAM01 qui ne dit rien. L'heure incrustée est fausse, et le serait dans tout enregistrement futur.

ONVIF, le standard de réglage que suivent la plupart des caméras IP, permet de lire et de modifier ces réglages, avec les identifiants de la caméra. ArgOS ne s'en sert pas encore (doc : docs/cameras/parametrer-une-camera.md).

Solution​

Chaque Caméra active a, dans l'Administration, un panneau Réglages qui lit la caméra par ONVIF et permet de régler :

  • ses deux Incrustations : le nom (texte libre, coin, affichée ou non) et la date et heure (coin, affichée ou non) ;
  • son Horloge : le fuseau (liste lisible, convertie au format POSIX qu'attend ONVIF) et une mise à l'heure du Site à la demande (heure envoyée une fois, sans NTP ni internet).

ArgOS lit les valeurs sur la caméra à chaque ouverture, n'envoie que ce que l'Administrateur a modifié, puis relit la caméra et montre, champ par champ, si le réglage a été pris, pas pris ou refusé. Rien de ces réglages n'est gardé en base : la caméra reste la seule source de vérité. Seul le port ONVIF trouvé est retenu sur la Caméra.

Le port ONVIF varie selon le fabricant : ArgOS le cherche lui-même (ports courants), avec les identifiants de l'URL RTSP de la Caméra. Les Caméras ne reçoivent aucun accès à internet : pas de NTP réglable dans cette version (le Site deviendra serveur de temps après la containerisation).

Deux Caméras simulées répondent en ONVIF (une avec identifiants sur 8899 comme XiongMai, une sans identifiants sur 80), dans un état « sortie d'usine » qui reproduit la caméra de dev.

User Stories​

Ouvrir les Réglages​

  1. En tant qu'Administrateur, je veux ouvrir les Réglages d'une Caméra depuis sa ligne dans l'Administration, pour régler la caméra sans son interface web ni le cloud du fabricant.
  2. En tant qu'Administrateur, je veux que les Réglages affichent les valeurs actuelles lues sur la caméra, pas une copie gardée par ArgOS, pour voir la vérité même si quelqu'un l'a réglée ailleurs.
  3. En tant qu'Administrateur, je veux ne pas avoir à saisir de port ONVIF : ArgOS le trouve seul parmi les ports courants et s'en souvient.
  4. En tant qu'Administrateur, je veux qu'ArgOS réessaie de trouver le port si la caméra ne répond plus sur celui retenu.
  5. En tant qu'Administrateur, je veux qu'ArgOS utilise l'identifiant et le mot de passe déjà présents dans l'URL RTSP de la Caméra, sans les ressaisir.
  6. En tant qu'Administrateur, je veux lire « Cette caméra ne répond pas en ONVIF » quand aucun port courant ne répond en ONVIF.
  7. En tant qu'Administrateur, je veux lire « La caméra refuse ces identifiants en ONVIF » quand elle refuse les identifiants du Flux.
  8. En tant qu'Administrateur, je veux lire « Caméra injoignable » quand la caméra ne répond plus du tout, même si son état était online.
  9. En tant qu'Administrateur, je veux que les Réglages ne soient pas proposés pour une Caméra désactivée.

Incrustations​

  1. En tant qu'Administrateur, je veux changer le texte incrusté du nom, pour qu'il dise où est la caméra.
  2. En tant qu'Administrateur, je veux un bouton « Reprendre le nom ArgOS » qui copie le nom de la Caméra dans ce texte, sans les lier ensuite.
  3. En tant qu'Administrateur, je veux placer le nom et la date et heure chacun dans un des quatre coins de l'image.
  4. En tant qu'Administrateur, je veux voir « position personnalisée » quand la caméra place une Incrustation hors d'un coin, et pouvoir la remettre dans un coin.
  5. En tant qu'Administrateur, je veux cacher une Incrustation, après une confirmation qui prévient que certaines caméras ne permettent pas de la réafficher.
  6. En tant qu'Administrateur, je veux que l'option « Afficher » ne me soit proposée que si la caméra annonce savoir recréer cette Incrustation, pour ne jamais en perdre une sans le savoir.
  7. En tant qu'Administrateur, je veux voir le format de la date incrustée sans pouvoir le changer (les caméras ne le permettent pas de façon fiable).

Horloge​

  1. En tant qu'Administrateur, je veux voir la date et l'heure actuelles de la caméra et leur écart avec l'heure du Site (« en retard de 26 ans », « en avance de 3 min »).
  2. En tant qu'Administrateur, je veux choisir le fuseau de la caméra dans une liste lisible (« Europe/Paris »), sans connaître le format POSIX.
  3. En tant qu'Administrateur, je veux voir tel quel un fuseau que la caméra a et qu'ArgOS ne reconnaît pas (ex. AWST-8).
  4. En tant qu'Administrateur, je veux un bouton « Mettre à l'heure du Site » qui envoie une fois l'heure du serveur ArgOS à la caméra, pour corriger l'heure incrustée sans lui ouvrir internet.
  5. En tant qu'Administrateur, je veux une confirmation avant cette mise à l'heure si la caméra se règle sur un serveur de temps, parce qu'elle coupe cette synchronisation.
  6. En tant qu'Administrateur, je veux voir, en lecture seule, si la caméra utilise un serveur de temps (NTP) et lequel.
  7. En tant qu'Administrateur, je veux qu'ArgOS ne remette jamais une caméra à l'heure sans mon action.

Envoyer et vérifier​

  1. En tant qu'Administrateur, je veux un seul bouton « Enregistrer » qui n'envoie à la caméra que les champs que j'ai modifiés.
  2. En tant qu'Administrateur, je veux qu'un réglage refusé n'empêche pas l'envoi des autres.
  3. En tant qu'Administrateur, je veux qu'ArgOS relise la caméra après l'envoi et m'affiche, pour chaque champ envoyé, la valeur demandée, la valeur relue et le statut (« pris », « pas pris », « refusé »), parce qu'une caméra peut accepter un réglage sans l'appliquer.
  4. En tant qu'Administrateur, je veux que les valeurs d'origine (lues à l'ouverture) restent affichées jusqu'à la fermeture du panneau, pour pouvoir y revenir à la main.
  5. En tant qu'Administrateur, je veux un bouton « Annuler » qui remet le formulaire aux valeurs d'origine sans rien envoyer.

Caméras simulées et dev​

  1. En tant que développeur, je veux que la Caméra simulée 2 réponde en ONVIF sur 8899 avec ses identifiants de dev, comme une caméra XiongMai.
  2. En tant que développeur, je veux que la Caméra simulée 4 réponde en ONVIF sur 80 sans identifiants.
  3. En tant que développeur, je veux que les Caméras simulées 1 et 3 ne répondent pas en ONVIF, pour tester ce cas.
  4. En tant que développeur, je veux que les Caméras simulées ONVIF démarrent « sortie d'usine » (horloge au 31/12/1999, fuseau AWST-8, NTP NTP, Incrustation nom CAM01 en haut à gauche, date et heure en bas à gauche), pour reproduire la caméra de dev.
  5. En tant que développeur, je veux que la simulation ONVIF vive dans son propre dossier, indépendante de l'API, pour pouvoir la déplacer tel quel dans un futur service ou conteneur de dev.

Documentation​

  1. En tant qu'Administrateur, je veux que la page « Paramétrer une Caméra » dise ce qu'ArgOS règle désormais, et comment.
  2. En tant que mainteneur, je veux que le glossaire définisse Incrustation, Horloge et Réglages de la Caméra.

Implementation Decisions​

  • Glossaire (docs/glossaire.md) :
  • Appareil et Caméra : l'UI passe par la Caméra. L'Horloge est celle de l'Appareil : la régler depuis une Caméra la règle pour toutes celles de la même MAC. Les Incrustations sont celles de la première source vidéo ONVIF (premier profil média). Le cas multi-voies reste « Un Appareil, plusieurs Caméras » (Plus tard).
  • Port ONVIF : nouvelle colonne nullable port_onvif sur la Caméra (migration additive), jamais saisie ni exposée en écriture. Recherche : GetSystemDateAndTime (sans identifiants) sur http://\<hôte de l'URL RTSP>:\<port>/onvif/device_service, ports 80, 8899, 2000, 8000, 8080 dans cet ordre ; seule une réponse SOAP compte (un 200 HTML ne prouve rien). Port retenu = premier qui répond ; s'il ne répond plus, nouvelle recherche. Pas de port saisi, pas de WS-Discovery.
  • Identifiants : ceux de l'URL RTSP (WS-Security UsernameToken, empreinte) ; sans identifiants dans l'URL, requêtes sans authentification. Pas de champ séparé.
  • Module ONVIF côté API : un module profond (client ONVIF du Site) qui expose « lire les Réglages », « appliquer une modification », « mettre à l'heure », et cache SOAP, ports, profils et tokens. Bibliothèque onvif-zeep (déjà éprouvée sur la caméra de dev, synchrone comme l'API). Délais courts (quelques secondes par requête).
  • Opérations ONVIF utilisées : appareil : GetSystemDateAndTime, SetSystemDateAndTime, GetNTP, GetCapabilities (adresse du service média) ; média : GetProfiles, GetOSDs, GetOSDOptions, SetOSD, CreateOSD, DeleteOSD. Aucune autre écriture (jamais réseau, IP, utilisateurs, ports).
  • API (routes sous /api/cameras/\{id\}, session exigée) :
    • GET …/reglages : lit la caméra et renvoie Horloge (date et heure UTC de la caméra, écart avec le Site, fuseau POSIX brut + fuseau lisible s'il est reconnu, mode manuel ou NTP, serveur NTP) et Incrustations (nom : texte, position, affichée ; date et heure : format, position, affichée ; « peut être réaffichée » d'après GetOSDOptions).
    • PATCH …/reglages : reçoit seulement les champs modifiés (fuseau, texte du nom, position et affichage de chaque Incrustation), envoie chaque Set… séparément, relit, et renvoie pour chaque champ : demandé, relu, statut pris / pas_pris / refuse.
    • POST …/reglages/mise-a-l-heure : SetSystemDateAndTime en mode manuel avec l'heure UTC du serveur et le fuseau actuel de la caméra, puis relecture.
    • Erreurs : Caméra inconnue ou désactivée → 404 ; caméra sans ONVIF, identifiants refusés, injoignable → 502 avec un code (sans_onvif, identifiants_refuses, injoignable) que le front traduit en messages.
  • Fuseau : liste IANA proposée par le front (zones courantes, Europe/Paris en tête). Conversion IANA → POSIX par l'API, à partir de la chaîne POSIX finale des fichiers TZif (zoneinfo, paquet tzdata). Lecture : un fuseau POSIX reconnu est rendu en nom IANA, sinon affiché tel quel.
  • Incrustations : quatre coins (UpperLeft, UpperRight, LowerLeft, LowerRight) ; position Custom lue, affichée « position personnalisée », non éditable. Cacher = DeleteOSD ; afficher = CreateOSD du même type, proposé seulement si GetOSDOptions l'annonce. Format de date en lecture seule.
  • Front : panneau Réglages dans Administration (ouvert par Caméra active). États : chargement, erreur (messages ci-dessus), formulaire. Formulaire avec valeurs d'origine visibles, « Enregistrer » (diff seulement), « Annuler », statuts par champ après envoi, confirmations (cacher une Incrustation ; mise à l'heure quand la caméra est en NTP).
  • Simulation ONVIF : service SOAP maison en Python (bibliothèque standard), dans simulation/onvif/ : code, Dockerfile, tests, et un README qui explique pourquoi ce dossier existe, pourquoi il ne dépend pas de l'API, et qu'il est prévu pour rejoindre un futur service ou conteneur de dev (structure non figée). Il implémente seulement les opérations ci-dessus, avec état en mémoire et vérification WS-Security quand des identifiants sont configurés. Un service compose par Caméra simulée ONVIF dans compose.simulation.yaml, qui partage le réseau de sa Caméra simulée (network_mode: service:camera-simulee-N) : même IP et même MAC qu'une vraie caméra. Caméra simulée 2 : port 8899, identifiants de dev existants ; Caméra simulée 4 : port 80, sans identifiants. Les Incrustations ne sont pas dessinées dans la vidéo simulée. media/simulated/ reste en place.
  • Doc : docs/cameras/parametrer-une-camera.md mis à jour (ce qu'ArgOS règle, messages, limites ; lien cassé vers la feuille de route corrigé). media/simulated/README.md renvoie vers simulation/onvif/.
  • Pas d'ADR : aucun choix difficile à défaire dans cette version.

Testing Decisions​

  • Un bon test vérifie un comportement observable : réponse HTTP de l'API, état relu sur la Caméra simulée, écran du navigateur. Jamais la forme des requêtes SOAP internes autrement que par leur effet sur la caméra.
  • simulation/onvif/ (tests du simulateur, rattachés à une test-root) : réponses SOAP aux opérations utilisées, état modifié par Set… puis relu, refus sans bons identifiants, état « usine » au démarrage.
  • tests/api/ (stack avec simulation), prior art : test_essai.py, test_codec.py :
    • lecture des Réglages de la Caméra simulée 2 (port 8899 trouvé et retenu) et 4 (port 80, sans identifiants) : valeurs « usine » ;
    • Caméras simulées 1 et 3 → sans_onvif ; mauvais identifiants → identifiants_refuses ; Caméra désactivée → 404 ;
    • modification du texte, du coin, de l'affichage, du fuseau : statut pris et valeur relue ; un champ refusé n'empêche pas les autres ;
    • mise à l'heure du Site : écart ramené à quelques secondes ;
    • conversion de fuseau (Europe/Paris ↔ CET-1CEST,M3.5.0,M10.5.0/3, fuseau inconnu rendu tel quel).
  • tests/web/, prior art : test_administration.py, test_ajout_camera.py : ouverture des Réglages, messages d'erreur, envoi et statuts par champ, « Annuler », confirmations, absence des Réglages pour une Caméra désactivée.
  • Vérification manuelle avant Finalise : la caméra de dev réelle, réglée depuis ArgOS (nom, coins, fuseau, mise à l'heure), changements visibles dans le Live. Elle figure au plan des tests humains.

Out of Scope​

  • Réglages image (infrarouge, luminosité…) et vidéo (résolution, débit…) : 0.6.3 envisagée (via /afr).
  • Réglage du NTP de la caméra, remise à l'heure automatique, Site serveur de temps (après la 0.7.0).
  • Heure manuelle autre que celle du Site.
  • Réseau, IP, DNS, utilisateurs, mot de passe et ports de la caméra : jamais par ArgOS.
  • Événements ONVIF, PTZ.
  • WS-Discovery, port ONVIF saisi, identifiants ONVIF distincts de ceux du Flux.
  • Police, taille, couleur, format de date des Incrustations ; position libre éditable.
  • Plusieurs sources vidéo par Appareil.
  • Dessiner les Incrustations dans la vidéo simulée.
  • HTTPS et authentification des Flux (0.6.1, 0.6.2).

Changements apportés aux versions antérieures​

Aucun.

Further Notes​

  • Sans HTTPS (0.6.1), l'API reçoit les modifications en clair sur le réseau local, comme le reste ; ONVIF envoie le mot de passe de la caméra en empreinte (WS-Security). Toujours pas d'installation sur de vraies caméras avant HTTPS et authentification des Flux, hors dev.
  • Le service média ONVIF 1 décrit mal le H.265 : sans effet ici, les Incrustations et l'Horloge n'en dépendent pas.
  • À ajouter ensuite par /afr : 0.6.3 Réglages image et vidéo par ONVIF ; Plus tard : catalogue du matériel connu (ports et configurations par modèle), Site serveur de temps des Caméras, WS-Discovery, identifiants ONVIF distincts ; Objectif 0.6.0 corrigé (fuseau et mise à l'heure manuelle, NTP en lecture seule).
  • Contexte : feuille de route de dev (section 0.6.0), docs/cameras/parametrer-une-camera.md, docs/securite.md, spec 0.4.2 (Appareil et MAC), media/simulated/README.md.