{"id":154,"date":"2026-03-09T16:12:25","date_gmt":"2026-03-09T15:12:25","guid":{"rendered":"https:\/\/fankepa.com\/?p=154"},"modified":"2026-03-13T14:44:00","modified_gmt":"2026-03-13T13:44:00","slug":"airbnb_manda-module-odoo-gestion-acces-unifi","status":"publish","type":"post","link":"https:\/\/fankepa.com\/?p=154","title":{"rendered":"Projet : airbnb_manda \u2014 Module Odoo Gestion Acc\u00e8s UniFi"},"content":{"rendered":"\n<!-- Introduction accrocheuse -->\n<p style=\"font-size: 20px; font-style: italic; color: #555; border-left: 4px solid #667eea; padding-left: 20px; margin: 30px 0;\">\n  J&rsquo;ai automatis\u00e9 la gestion des acc\u00e8s d&rsquo;une r\u00e9sidence h\u00f4teli\u00e8re avec Odoo 19 et l&rsquo;API UniFi Access Hub. Plus besoin de remettre des cl\u00e9s physiques : chaque client re\u00e7oit automatiquement son code PIN par email \u00e0 la confirmation de sa r\u00e9servation. Voici comment j&rsquo;ai construit ce syst\u00e8me.\n<\/p>\n\n<!-- Image principale -->\n<img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/Resv_1.png\" alt=\"Module Odoo Gestion Acc\u00e8s UniFi \u2014 Vue r\u00e9servation\" style=\"width: 100%; height: auto; border-radius: 10px; margin: 30px 0; box-shadow: 0 4px 6px rgba(0,0,0,0.1);\">\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udca1 Le probl\u00e8me<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  MandaBar, une r\u00e9sidence h\u00f4teli\u00e8re \u00e0 Marche-en-Famenne (Belgique), utilisait un syst\u00e8me de cl\u00e9s physiques : remettre les cl\u00e9s, r\u00e9cup\u00e9rer les cl\u00e9s, g\u00e9rer les doublons, appeler la m\u00e9nag\u00e8re&#8230; Un processus manuel, source d&rsquo;erreurs et peu scalable. L&rsquo;objectif : tout automatiser via le logiciel de gestion existant.\n<\/p>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\u2728 La solution : Module Odoo 19 + API UniFi Access Hub<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  J&rsquo;ai d\u00e9velopp\u00e9 un module Python sur Odoo 19 qui automatise enti\u00e8rement le cycle d&rsquo;acc\u00e8s des clients :\n<\/p>\n\n<ul style=\"font-size: 17px; line-height: 2; color: #555; margin: 20px 0 20px 40px;\">\n  <li>\ud83d\udd10 <strong>G\u00e9n\u00e9ration automatique d&rsquo;un code PIN<\/strong> \u00e0 chaque confirmation de r\u00e9servation<\/li>\n  <li>\ud83d\udce7 <strong>Email automatique au client<\/strong> avec son PIN, num\u00e9ro de chambre et dates de s\u00e9jour<\/li>\n  <li>\ud83d\udd13 <strong>Cr\u00e9ation de l&rsquo;acc\u00e8s UniFi<\/strong> au moment du check-in<\/li>\n  <li>\ud83d\udd12 <strong>R\u00e9vocation automatique de l&rsquo;acc\u00e8s<\/strong> au check-out<\/li>\n  <li>\ud83e\uddf9 <strong>D\u00e9clenchement automatique d&rsquo;une t\u00e2che m\u00e9nage<\/strong> apr\u00e8s chaque d\u00e9part<\/li>\n  <li>\ud83d\udcca <strong>Historique complet<\/strong> des acc\u00e8s et des t\u00e2ches dans Odoo<\/li>\n<\/ul>\n\n<!-- Vid\u00e9o YouTube -->\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83c\udfa5 D\u00e9monstration vid\u00e9o<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  Avant de rentrer dans les d\u00e9tails techniques, voici une d\u00e9monstration du d\u00e9verrouillage en action :\n<\/p>\n\n<div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; margin: 30px 0; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);\">\n  <iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%;\" \n    src=\"https:\/\/www.youtube.com\/embed\/eV3vmP_1Wtc\" \n    frameborder=\"0\" \n    allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" \n    allowfullscreen>\n  <\/iframe>\n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83c\udfd7\ufe0f Comment \u00e7a fonctionne \u2014 Le workflow complet<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  Le syst\u00e8me repose sur 4 \u00e9tapes automatis\u00e9es qui suivent le cycle de vie d&rsquo;une r\u00e9servation :\n<\/p>\n\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; margin: 30px 0;\">\n  \n  <div style=\"background: #f0f7ff; padding: 25px; border-radius: 10px; border-left: 4px solid #2196f3;\">\n    <h3 style=\"color: #1565c0; font-size: 20px; margin-bottom: 15px;\">1\ufe0f\u20e3 Brouillon<\/h3>\n    <p style=\"color: #555; font-size: 15px; line-height: 1.6;\">\n      Cr\u00e9ation de la r\u00e9servation dans Odoo. Saisie du client, de la chambre et des dates. Le syst\u00e8me pr\u00e9pare l&rsquo;acc\u00e8s UniFi.\n    <\/p>\n  <\/div>\n  \n  <div style=\"background: #f3e5f5; padding: 25px; border-radius: 10px; border-left: 4px solid #9c27b0;\">\n    <h3 style=\"color: #6a1b9a; font-size: 20px; margin-bottom: 15px;\">2\ufe0f\u20e3 Confirmation<\/h3>\n    <p style=\"color: #555; font-size: 15px; line-height: 1.6;\">\n      Un code PIN unique est g\u00e9n\u00e9r\u00e9 automatiquement et envoy\u00e9 par email au client avec toutes ses informations de s\u00e9jour.\n    <\/p>\n  <\/div>\n  \n  <div style=\"background: #e8f5e9; padding: 25px; border-radius: 10px; border-left: 4px solid #4caf50;\">\n    <h3 style=\"color: #2e7d32; font-size: 20px; margin-bottom: 15px;\">3\ufe0f\u20e3 Check-in<\/h3>\n    <p style=\"color: #555; font-size: 15px; line-height: 1.6;\">\n      L&rsquo;acc\u00e8s UniFi est cr\u00e9\u00e9 sur le hub. Le client peut d\u00e9sormais utiliser son code PIN pour acc\u00e9der \u00e0 sa chambre.\n    <\/p>\n  <\/div>\n\n  <div style=\"background: #fff3e0; padding: 25px; border-radius: 10px; border-left: 4px solid #ff9800;\">\n    <h3 style=\"color: #e65100; font-size: 20px; margin-bottom: 15px;\">4\ufe0f\u20e3 Check-out<\/h3>\n    <p style=\"color: #555; font-size: 15px; line-height: 1.6;\">\n      L&rsquo;acc\u00e8s est r\u00e9voqu\u00e9 automatiquement. Une t\u00e2che m\u00e9nage est cr\u00e9\u00e9e et assign\u00e9e. Pr\u00eat pour le prochain client.\n    <\/p>\n  <\/div>\n  \n<\/div>\n\n<!-- Architecture -->\n<div style=\"background: #f8f9fa; padding: 30px; border-radius: 10px; margin: 30px 0; text-align: center;\">\n  <h3 style=\"color: #333; font-size: 22px; margin-bottom: 20px;\">\ud83d\udcca Architecture du syst\u00e8me<\/h3>\n  <pre style=\"background: white; padding: 20px; border-radius: 8px; text-align: left; overflow-x: auto; font-size: 14px; color: #333;\">\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     SMTP      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   Client     \u2502 <\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2502   Odoo 19    \u2502\n\u2502   (Email)    \u2502               \u2502   Python     \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518               \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                      \u2502 API REST\n                                      \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   SSH Tunnel  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    LAN      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   VPS OVH    \u2502 <\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2502 Raspberry Pi \u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500> \u2502 UniFi Access Hub\u2502\n\u2502 (Internet)   \u2502               \u2502 Flask Proxy  \u2502             \u2502 172.18.x.x  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518               \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518             \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                                                      \u2502\n                                                              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                                                              \u2502 Serrures IoT  \u2502\n                                                              \u2502 (chambres)    \u2502\n                                                              \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  <\/pre>\n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udcf8 D\u00e9monstration pas \u00e0 pas<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  Voici le syst\u00e8me en action, de la cr\u00e9ation de la r\u00e9servation \u00e0 la r\u00e9ception du code PIN par le client :\n<\/p>\n\n<!-- \u00c9tape 1 -->\n<div style=\"margin: 40px 0;\">\n  <h3 style=\"color: #1565c0; font-size: 22px; margin-bottom: 15px;\">\n    <span style=\"background: #2196f3; color: white; padding: 4px 12px; border-radius: 20px; font-size: 16px; margin-right: 10px;\">\u00c9tape 1<\/span>\n    Cr\u00e9ation de la r\u00e9servation (brouillon)\n  <\/h3>\n  <img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/Resv_1.png\" \n       alt=\"Vue brouillon d'une r\u00e9servation dans Odoo\" \n       style=\"width: 100%; height: auto; border-radius: 10px; margin: 15px 0; box-shadow: 0 4px 12px rgba(0,0,0,0.15); border: 1px solid #e0e0e0;\">\n  <p style=\"font-size: 16px; color: #666; font-style: italic; text-align: center; margin-top: 10px;\">\n    Vue brouillon \u2014 saisie du client, de la chambre et des dates. Le champ \u00ab\u00a0Code PIN\u00a0\u00bb est vide \u00e0 ce stade.\n  <\/p>\n<\/div>\n\n<!-- \u00c9tape 2 -->\n<div style=\"margin: 40px 0;\">\n  <h3 style=\"color: #6a1b9a; font-size: 22px; margin-bottom: 15px;\">\n    <span style=\"background: #9c27b0; color: white; padding: 4px 12px; border-radius: 20px; font-size: 16px; margin-right: 10px;\">\u00c9tape 2<\/span>\n    Confirmation \u2014 PIN g\u00e9n\u00e9r\u00e9 et email envoy\u00e9 automatiquement\n  <\/h3>\n  <img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/Resv_2.png\" \n       alt=\"R\u00e9servation confirm\u00e9e avec code PIN g\u00e9n\u00e9r\u00e9 automatiquement\" \n       style=\"width: 100%; height: auto; border-radius: 10px; margin: 15px 0; box-shadow: 0 4px 12px rgba(0,0,0,0.15); border: 1px solid #e0e0e0;\">\n  <p style=\"font-size: 16px; color: #666; font-style: italic; text-align: center; margin-top: 10px;\">\n    R\u00e9servation confirm\u00e9e \u2014 le code PIN est g\u00e9n\u00e9r\u00e9 et l&#8217;email part automatiquement au client.\n  <\/p>\n<\/div>\n\n<!-- \u00c9tape 3 -->\n<div style=\"margin: 40px 0;\">\n  <h3 style=\"color: #e65100; font-size: 22px; margin-bottom: 15px;\">\n    <span style=\"background: #ff9800; color: white; padding: 4px 12px; border-radius: 20px; font-size: 16px; margin-right: 10px;\">\u00c9tape 3<\/span>\n    Check-out \u2014 r\u00e9vocation de l&rsquo;acc\u00e8s\n  <\/h3>\n  <img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/Resv_3.png\" \n       alt=\"Check-out avec r\u00e9vocation automatique de l'acc\u00e8s UniFi\" \n       style=\"width: 100%; height: auto; border-radius: 10px; margin: 15px 0; box-shadow: 0 4px 12px rgba(0,0,0,0.15); border: 1px solid #e0e0e0;\">\n  <p style=\"font-size: 16px; color: #666; font-style: italic; text-align: center; margin-top: 10px;\">\n    Au check-out, l&rsquo;acc\u00e8s UniFi est r\u00e9voqu\u00e9 et une t\u00e2che m\u00e9nage est cr\u00e9\u00e9e automatiquement.\n  <\/p>\n<\/div>\n\n<!-- \u00c9tape 4 \u2014 Email re\u00e7u par le client -->\n<div style=\"margin: 40px 0;\">\n  <h3 style=\"color: #2e7d32; font-size: 22px; margin-bottom: 15px;\">\n    <span style=\"background: #4caf50; color: white; padding: 4px 12px; border-radius: 20px; font-size: 16px; margin-right: 10px;\">R\u00e9sultat<\/span>\n    Email re\u00e7u par le client\n  <\/h3>\n  <div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin: 15px 0;\">\n    <div>\n      <img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.21-1.jpeg\" \n           alt=\"Email re\u00e7u par le client avec informations de s\u00e9jour\" \n           style=\"width: 100%; height: auto; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);\">\n      <p style=\"font-size: 15px; color: #666; font-style: italic; text-align: center; margin-top: 8px;\">Email avec num\u00e9ro de chambre et informations d&rsquo;acc\u00e8s<\/p>\n    <\/div>\n    <div>\n      <img decoding=\"async\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.21.jpeg\" \n           alt=\"Code PIN unique affich\u00e9 dans l'email client\" \n           style=\"width: 100%; height: auto; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);\">\n      <p style=\"font-size: 15px; color: #666; font-style: italic; text-align: center; margin-top: 8px;\">Code PIN unique valide uniquement entre les dates de s\u00e9jour<\/p>\n    <\/div>\n  <\/div>\n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udcbb Stack technique<\/h2>\n\n<div style=\"display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0;\">\n  <span style=\"background: #3776ab; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83d\udc0d Python 3.12<\/span>\n  <span style=\"background: #714B67; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\u2699\ufe0f Odoo 19<\/span>\n  <span style=\"background: #c51a4a; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83e\udd67 Raspberry Pi<\/span>\n  <span style=\"background: #2496ed; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83c\udf10 API REST UniFi<\/span>\n  <span style=\"background: #333; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83d\udc27 Linux \/ SSH<\/span>\n  <span style=\"background: #e44d26; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83c\udf36\ufe0f Flask Proxy<\/span>\n  <span style=\"background: #0078d4; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\u2601\ufe0f VPS OVH<\/span>\n  <span style=\"background: #4caf50; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px;\">\ud83d\udce7 SMTP Auto<\/span>\n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udcad Retour d&rsquo;exp\u00e9rience<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  Ce projet de stage m&rsquo;a confront\u00e9 \u00e0 des d\u00e9fis techniques r\u00e9els en conditions de production :\n<\/p>\n\n<div style=\"background: #e8f5e9; border-left: 4px solid #4caf50; padding: 20px; margin: 20px 0; border-radius: 5px;\">\n  <h3 style=\"color: #2e7d32; margin-bottom: 10px;\">\u2705 Ce que j&rsquo;ai appris<\/h3>\n  <ul style=\"color: #555; line-height: 1.8;\">\n    <li>Int\u00e9gration IT\/OT : faire communiquer un logiciel de gestion avec des \u00e9quipements physiques<\/li>\n    <li>R\u00e9solution de probl\u00e8mes r\u00e9seau : segmentation LAN\/internet, tunnels SSH s\u00e9curis\u00e9s<\/li>\n    <li>D\u00e9veloppement de modules Odoo : mod\u00e8les, vues, workflows, actions automatiques<\/li>\n    <li>D\u00e9ploiement et maintenance en production sur VPS Linux<\/li>\n  <\/ul>\n<\/div>\n\n<div style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 20px; margin: 20px 0; border-radius: 5px;\">\n  <h3 style=\"color: #e65100; margin-bottom: 10px;\">\u26a0\ufe0f D\u00e9fis rencontr\u00e9s<\/h3>\n  <ul style=\"color: #555; line-height: 1.8;\">\n    <li>Communication VPS (internet) \u2194 hub UniFi (r\u00e9seau local) \u2192 solution : proxy Flask + tunnel SSH inverse<\/li>\n    <li>Migration compatibilit\u00e9 Odoo 17 \u2192 19 : syntaxe XML d\u00e9pr\u00e9ci\u00e9e, vues, champs renomm\u00e9s<\/li>\n    <li>Fiabilit\u00e9 du tunnel SSH : configuration systemd pour reconnexion automatique<\/li>\n  <\/ul>\n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\ude80 \u00c9volutions pr\u00e9vues<\/h2>\n\n<ul style=\"font-size: 17px; line-height: 2; color: #555; margin: 20px 0 20px 40px;\">\n  <li>\ud83d\udcf1 <strong>Application mobile<\/strong> pour les m\u00e9nag\u00e8res avec notifications push<\/li>\n  <li>\ud83d\udd0b <strong>Monitoring en temps r\u00e9el<\/strong> de l&rsquo;\u00e9tat des serrures et des connexions<\/li>\n  <li>\ud83d\udcca <strong>Dashboard analytics<\/strong> : statistiques d&rsquo;utilisation et rapports<\/li>\n  <li>\ud83d\udd14 <strong>Alertes automatiques<\/strong> en cas d&rsquo;anomalie r\u00e9seau ou d&rsquo;acc\u00e8s non autoris\u00e9<\/li>\n<\/ul>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udcda Code source &#038; Documentation<\/h2>\n\n<p style=\"font-size: 17px; line-height: 1.8; color: #555;\">\n  Le code source complet et la documentation technique sont disponibles sur GitHub :\n<\/p>\n\n<div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px; border-radius: 10px; margin: 30px 0;\">\n  \n  <div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;\">\n    \n    <a href=\"https:\/\/github.com\/FILSTOGNO\/odoo-rggh-airbnb\" target=\"_blank\" style=\"background: white; padding: 20px; border-radius: 8px; text-align: center; text-decoration: none; color: #333;\">\n      <div style=\"font-size: 40px; margin-bottom: 10px;\">\ud83d\udce6<\/div>\n      <strong style=\"color: #667eea;\">Code Source<\/strong>\n      <p style=\"font-size: 13px; color: #666; margin-top: 5px;\">GitHub \u2014 odoo-rggh-airbnb<\/p>\n    <\/a>\n    \n    <a href=\"https:\/\/github.com\/FILSTOGNO\/odoo-rggh-airbnb\/blob\/master\/README.md\" target=\"_blank\" style=\"background: white; padding: 20px; border-radius: 8px; text-align: center; text-decoration: none; color: #333;\">\n      <div style=\"font-size: 40px; margin-bottom: 10px;\">\ud83d\udcd6<\/div>\n      <strong style=\"color: #667eea;\">README<\/strong>\n      <p style=\"font-size: 13px; color: #666; margin-top: 5px;\">Documentation compl\u00e8te<\/p>\n    <\/a>\n    \n    <a href=\"https:\/\/github.com\/FILSTOGNO\/odoo-rggh-airbnb\/blob\/master\/PROXY_SETUP.md\" target=\"_blank\" style=\"background: white; padding: 20px; border-radius: 8px; text-align: center; text-decoration: none; color: #333;\">\n      <div style=\"font-size: 40px; margin-bottom: 10px;\">\ud83d\udd27<\/div>\n      <strong style=\"color: #667eea;\">PROXY_SETUP<\/strong>\n      <p style=\"font-size: 13px; color: #666; margin-top: 5px;\">Configuration tunnel SSH &#038; proxy Flask<\/p>\n    <\/a>\n    \n    <a href=\"https:\/\/youtube.com\/shorts\/eV3vmP_1Wtc?feature=share\" target=\"_blank\" style=\"background: white; padding: 20px; border-radius: 8px; text-align: center; text-decoration: none; color: #333;\">\n      <div style=\"font-size: 40px; margin-bottom: 10px;\">\ud83c\udfa5<\/div>\n      <strong style=\"color: #ff0000;\">Vid\u00e9o Demo<\/strong>\n      <p style=\"font-size: 13px; color: #666; margin-top: 5px;\">D\u00e9verrouillage en action<\/p>\n    <\/a>\n    \n  <\/div>\n  \n<\/div>\n\n<h2 style=\"color: #333; font-size: 28px; margin-top: 40px;\">\ud83d\udcac Questions fr\u00e9quentes<\/h2>\n\n<div style=\"margin: 20px 0;\">\n  \n  <details style=\"background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 15px; cursor: pointer;\">\n    <summary style=\"font-weight: bold; font-size: 18px; color: #333;\">Quel est le mat\u00e9riel n\u00e9cessaire ?<\/summary>\n    <p style=\"margin-top: 15px; color: #555; line-height: 1.8;\">\n      Un serveur Odoo 19, un hub UniFi Access avec ses serrures connect\u00e9es, et un Raspberry Pi sur le r\u00e9seau local pour servir de proxy. Un VPS pour h\u00e9berger Odoo en production.\n    <\/p>\n  <\/details>\n  \n  <details style=\"background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 15px; cursor: pointer;\">\n    <summary style=\"font-weight: bold; font-size: 18px; color: #333;\">Le syst\u00e8me fonctionne-t-il si Internet tombe ?<\/summary>\n    <p style=\"margin-top: 15px; color: #555; line-height: 1.8;\">\n      Le hub UniFi Access g\u00e8re les acc\u00e8s localement. Les PIN d\u00e9j\u00e0 cr\u00e9\u00e9s continuent de fonctionner m\u00eame sans connexion internet. Seule la g\u00e9n\u00e9ration de nouveaux acc\u00e8s n\u00e9cessite la connexion au VPS.\n    <\/p>\n  <\/details>\n  \n  <details style=\"background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 15px; cursor: pointer;\">\n    <summary style=\"font-weight: bold; font-size: 18px; color: #333;\">Peut-on l&rsquo;adapter \u00e0 d&rsquo;autres syst\u00e8mes de contr\u00f4le d&rsquo;acc\u00e8s ?<\/summary>\n    <p style=\"margin-top: 15px; color: #555; line-height: 1.8;\">\n      Oui ! L&rsquo;architecture est modulaire. Il suffit de remplacer le module d&rsquo;appel API UniFi par un autre connecteur (Kisi, Salto, Dormakaba&#8230;). Le c\u0153ur Odoo (workflow r\u00e9servation + email) reste identique.\n    <\/p>\n  <\/details>\n\n  <details style=\"background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 15px; cursor: pointer;\">\n    <summary style=\"font-weight: bold; font-size: 18px; color: #333;\">C&rsquo;est un projet de stage ou un produit commercial ?<\/summary>\n    <p style=\"margin-top: 15px; color: #555; line-height: 1.8;\">\n      C&rsquo;est mon projet de stage de fin d&rsquo;\u00e9tudes (Bachelor Informatique Industrielle, Li\u00e8ge), d\u00e9ploy\u00e9 en production r\u00e9elle chez MandaBar. Le code est open source sur GitHub.\n    <\/p>\n  <\/details>\n  \n<\/div>\n\n<!-- Conclusion -->\n<div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 50px 30px; border-radius: 10px; margin: 50px 0; text-align: center; color: white;\">\n  <h2 style=\"font-size: 32px; margin-bottom: 20px; color: white;\">\ud83c\udfaf Int\u00e9ress\u00e9 par ce projet ?<\/h2>\n  <p style=\"font-size: 18px; margin-bottom: 30px; opacity: 0.9; line-height: 1.6;\">\n    Le code source est disponible gratuitement sur GitHub. N&rsquo;h\u00e9sitez pas \u00e0 ouvrir une issue ou \u00e0 me contacter pour toute question technique !\n  <\/p>\n  \n  <div>\n    <a href=\"https:\/\/github.com\/FILSTOGNO\/odoo-rggh-airbnb\" target=\"_blank\" style=\"background: white; color: #667eea; padding: 15px 30px; border-radius: 5px; text-decoration: none; margin: 10px; display: inline-block; font-weight: bold;\">\n      \u2b50 Voir le projet sur GitHub\n    <\/a>\n    <a href=\"https:\/\/youtube.com\/shorts\/eV3vmP_1Wtc?feature=share\" target=\"_blank\" style=\"background: #ff0000; color: white; padding: 15px 30px; border-radius: 5px; text-decoration: none; margin: 10px; display: inline-block; font-weight: bold;\">\n      \ud83d\udcfa Regarder la d\u00e9mo\n    <\/a>\n  <\/div>\n  \n  <p style=\"font-size: 14px; margin-top: 30px; opacity: 0.8;\">\n    \u2b50 Si ce projet vous pla\u00eet, mettez une \u00e9toile sur GitHub ! \u2b50\n  <\/p>\n<\/div>\n\n<!-- Call to action social -->\n<div style=\"background: #f8f9fa; padding: 30px; border-radius: 10px; text-align: center; margin: 40px 0;\">\n  <p style=\"font-size: 16px; color: #555; margin-bottom: 15px;\">\ud83d\udce2 Partagez cet article si vous l&rsquo;avez trouv\u00e9 int\u00e9ressant !<\/p>\n<\/div>\n\n\n<figure class=\"wp-block-post-featured-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"900\" src=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-rotated.jpeg\" class=\"attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" style=\"object-fit:cover;\" srcset=\"https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-rotated.jpeg 1600w, https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-300x169.jpeg 300w, https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-1024x576.jpeg 1024w, https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-768x432.jpeg 768w, https:\/\/fankepa.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-07-at-07.30.22-2-1536x864.jpeg 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\" \/><\/figure>","protected":false},"excerpt":{"rendered":"<p>J&rsquo;ai automatis\u00e9 la gestion des acc\u00e8s d&rsquo;une r\u00e9sidence h\u00f4teli\u00e8re avec Odoo 19 et l&rsquo;API UniFi Access Hub. Plus besoin de [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":282,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_glsr_average":0,"_glsr_ranking":0,"_glsr_reviews":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-154","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-non-classe"],"_links":{"self":[{"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/posts\/154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fankepa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=154"}],"version-history":[{"count":15,"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":283,"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/posts\/154\/revisions\/283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fankepa.com\/index.php?rest_route=\/wp\/v2\/media\/282"}],"wp:attachment":[{"href":"https:\/\/fankepa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fankepa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fankepa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}