{"id":4777,"date":"2025-10-30T18:09:37","date_gmt":"2025-10-30T17:09:37","guid":{"rendered":"https:\/\/workboot.fr\/ciela\/?page_id=4777"},"modified":"2025-10-30T18:09:38","modified_gmt":"2025-10-30T17:09:38","slug":"gpio-par-site-web","status":"publish","type":"page","link":"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/","title":{"rendered":"GPIO par site WEB"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">&nbsp;Installation des paquets n\u00e9cessaires<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update<br>sudo apt install apache2 php libapache2-mod-php gpiod<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration des permissions GPIO<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Ajouter l'utilisateur www-data au groupe gpio\nsudo usermod -a -G gpio www-data\n\n# V\u00e9rifier les groupes\ngroups www-data\n\n# Red\u00e9marrer Apache\nsudo systemctl restart apache2\n\n# V\u00e9rifier les devices GPIO\nls -la \/dev\/gpiochip*\n\n# Tester les commandes gpiod\ngpiodetect<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Script PHP principal (<code>\/var\/www\/html\/index.php<\/code>)<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nheader('Content-Type: application\/json');\nheader('Access-Control-Allow-Origin: *');\nheader('Access-Control-Allow-Methods: GET, POST');\n\nclass GPIOControl {\n    private $chip = 'gpiochip0';\n    \n    public function setGPIO($pin, $state) {\n        try {\n            \/\/ Commande SANS sudo\n            $command = \"gpioset {$this->chip} {$pin}={$state}\";\n            exec($command . \" 2>&amp;1\", $output, $return_var);\n            \n            if ($return_var === 0) {\n                return ['success' => true, 'pin' => $pin, 'state' => $state];\n            } else {\n                return ['success' => false, 'error' => implode(', ', $output)];\n            }\n        } catch (Exception $e) {\n            return ['success' => false, 'error' => $e->getMessage()];\n        }\n    }\n    \n    public function getGPIOStatus($pin) {\n        try {\n            \/\/ Commande SANS sudo\n            exec(\"gpioget {$this->chip} {$pin} 2>&amp;1\", $output, $return_var);\n            \n            if ($return_var === 0 &amp;&amp; isset($output[0])) {\n                $state = intval(trim($output[0]));\n                return ['success' => true, 'pin' => $pin, 'state' => $state];\n            } else {\n                return ['success' => false, 'error' => implode(', ', $output)];\n            }\n        } catch (Exception $e) {\n            return ['success' => false, 'error' => $e->getMessage()];\n        }\n    }\n    \n    public function getAllStatus($pins) {\n        $status = [];\n        foreach ($pins as $pin) {\n            $result = $this->getGPIOStatus($pin);\n            if ($result['success']) {\n                $status[$pin] = $result['state'];\n            }\n        }\n        return $status;\n    }\n}\n\n\/\/ Configuration des GPIOs disponibles\n$availablePins = [17, 27, 22];\n$gpio = new GPIOControl();\n\n\/\/ Traitement des requ\u00eates AJAX\nif ($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['ajax'])) {\n    $action = $_POST['action'] ?? $_GET['action'] ?? '';\n    \n    switch ($action) {\n        case 'set':\n            $pin = intval($_POST['pin'] ?? $_GET['pin'] ?? 0);\n            $state = intval($_POST['state'] ?? $_GET['state'] ?? 0);\n            \n            if (in_array($pin, $availablePins) &amp;&amp; ($state === 0 || $state === 1)) {\n                $result = $gpio->setGPIO($pin, $state);\n                echo json_encode($result);\n            } else {\n                echo json_encode(['success' => false, 'error' => 'Param\u00e8tres invalides']);\n            }\n            exit;\n            \n        case 'status':\n            $pin = intval($_POST['pin'] ?? $_GET['pin'] ?? 0);\n            if (in_array($pin, $availablePins)) {\n                $result = $gpio->getGPIOStatus($pin);\n                echo json_encode($result);\n            } else {\n                echo json_encode(['success' => false, 'error' => 'GPIO non configur\u00e9']);\n            }\n            exit;\n            \n        case 'all_status':\n            $result = $gpio->getAllStatus($availablePins);\n            echo json_encode(['success' => true, 'status' => $result]);\n            exit;\n            \n        case 'system_info':\n            $info = [\n                'php_version' => phpversion(),\n                'gpio_chip' => 'gpiochip0',\n                'available_pins' => $availablePins,\n                'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Inconnu'\n            ];\n            echo json_encode(['success' => true, 'info' => $info]);\n            exit;\n            \n        default:\n            echo json_encode(['success' => false, 'error' => 'Action non reconnue']);\n            exit;\n    }\n}\n?>\n\n&lt;!DOCTYPE html>\n&lt;html lang=\"fr\">\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    &lt;title>Contr\u00f4le GPIOs - Apache2 + PHP + gpiod&lt;\/title>\n    &lt;style>\n        :root {\n            --primary-color: #667eea;\n            --success-color: #4CAF50;\n            --error-color: #f44336;\n            --warning-color: #ff9800;\n        }\n        \n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n            padding: 20px;\n        }\n        \n        .container {\n            max-width: 1000px;\n            margin: 0 auto;\n        }\n        \n        .header {\n            background: white;\n            padding: 30px;\n            border-radius: 15px 15px 0 0;\n            box-shadow: 0 5px 15px rgba(0,0,0,0.1);\n            text-align: center;\n        }\n        \n        h1 {\n            color: #333;\n            font-size: 2.5em;\n            margin-bottom: 10px;\n        }\n        \n        .subtitle {\n            color: #666;\n            font-size: 1.2em;\n        }\n        \n        .main-content {\n            background: white;\n            padding: 30px;\n            border-radius: 0 0 15px 15px;\n            box-shadow: 0 10px 30px rgba(0,0,0,0.2);\n        }\n        \n        .gpios-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n            gap: 20px;\n            margin-bottom: 30px;\n        }\n        \n        .gpio-control {\n            border: 2px solid #e0e0e0;\n            border-radius: 12px;\n            padding: 25px;\n            background: #fafafa;\n            transition: all 0.3s ease;\n        }\n        \n        .gpio-control:hover {\n            border-color: #bbb;\n            box-shadow: 0 5px 15px rgba(0,0,0,0.1);\n        }\n        \n        .gpio-control.active {\n            border-color: var(--success-color);\n        }\n        \n        .gpio-control.inactive {\n            border-color: var(--error-color);\n        }\n        \n        .gpio-title {\n            font-size: 1.3em;\n            font-weight: bold;\n            margin-bottom: 15px;\n            color: #333;\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n        }\n        \n        .gpio-icon {\n            font-size: 1.5em;\n        }\n        \n        .status {\n            margin: 15px 0;\n            padding: 12px;\n            font-size: 16px;\n            font-weight: bold;\n            border-radius: 8px;\n            text-align: center;\n            transition: all 0.3s ease;\n        }\n        \n        .status.on {\n            background-color: #e8f5e8;\n            color: var(--success-color);\n            border: 2px solid var(--success-color);\n        }\n        \n        .status.off {\n            background-color: #ffeaea;\n            color: var(--error-color);\n            border: 2px solid var(--error-color);\n        }\n        \n        .status.unknown {\n            background-color: #fff3e0;\n            color: var(--warning-color);\n            border: 2px solid var(--warning-color);\n        }\n        \n        .gpio-buttons {\n            display: flex;\n            gap: 10px;\n        }\n        \n        button {\n            padding: 12px 20px;\n            font-size: 14px;\n            border: none;\n            border-radius: 8px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            font-weight: bold;\n            flex: 1;\n        }\n        \n        .btn-on {\n            background: var(--success-color);\n            color: white;\n        }\n        \n        .btn-off {\n            background: var(--error-color);\n            color: white;\n        }\n        \n        button:hover:not(:disabled) {\n            transform: translateY(-2px);\n            box-shadow: 0 5px 15px rgba(0,0,0,0.2);\n        }\n        \n        button:active:not(:disabled) {\n            transform: translateY(0);\n        }\n        \n        button:disabled {\n            opacity: 0.6;\n            cursor: not-allowed;\n        }\n        \n        .system-info {\n            background: #f8f9fa;\n            border-radius: 10px;\n            padding: 25px;\n            margin-top: 30px;\n            border-left: 4px solid var(--primary-color);\n        }\n        \n        .system-info h3 {\n            margin-bottom: 15px;\n            color: #333;\n        }\n        \n        .info-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n            gap: 15px;\n        }\n        \n        .info-item {\n            padding: 10px;\n            background: white;\n            border-radius: 5px;\n            border-left: 3px solid var(--primary-color);\n        }\n        \n        .message {\n            position: fixed;\n            top: 20px;\n            right: 20px;\n            padding: 15px 25px;\n            border-radius: 8px;\n            color: white;\n            font-weight: bold;\n            z-index: 1000;\n            opacity: 0;\n            transform: translateX(100px);\n            transition: all 0.3s ease;\n        }\n        \n        .message.show {\n            opacity: 1;\n            transform: translateX(0);\n        }\n        \n        .message.success {\n            background: var(--success-color);\n        }\n        \n        .message.error {\n            background: var(--error-color);\n        }\n        \n        .loading {\n            display: inline-block;\n            width: 16px;\n            height: 16px;\n            border: 2px solid #f3f3f3;\n            border-top: 2px solid var(--primary-color);\n            border-radius: 50%;\n            animation: spin 1s linear infinite;\n        }\n        \n        @keyframes spin {\n            0% { transform: rotate(0deg); }\n            100% { transform: rotate(360deg); }\n        }\n        \n        @media (max-width: 768px) {\n            .gpios-grid {\n                grid-template-columns: 1fr;\n            }\n            \n            .gpio-buttons {\n                flex-direction: column;\n            }\n            \n            h1 {\n                font-size: 2em;\n            }\n        }\n    &lt;\/style>\n&lt;\/head>\n&lt;body>\n    &lt;div class=\"container\">\n        &lt;div class=\"header\">\n            &lt;h1>\ud83c\udf9b\ufe0f Contr\u00f4le GPIOs Raspberry Pi&lt;\/h1>\n            &lt;div class=\"subtitle\">Apache2 + PHP + gpiod&lt;\/div>\n        &lt;\/div>\n        \n        &lt;div class=\"main-content\">\n            &lt;div class=\"gpios-grid\">\n                &lt;?php foreach ($availablePins as $pin): ?>\n                &lt;div class=\"gpio-control\" id=\"gpio-&lt;?= $pin ?>\">\n                    &lt;div class=\"gpio-title\">\n                        &lt;span>\ud83d\udccd GPIO &lt;?= $pin ?>&lt;\/span>\n                        &lt;span id=\"loading-&lt;?= $pin ?>\" class=\"loading\" style=\"display: none;\">&lt;\/span>\n                    &lt;\/div>\n                    &lt;div class=\"status unknown\" id=\"status-&lt;?= $pin ?>\">\n                        \ud83d\udd04 Chargement...\n                    &lt;\/div>\n                    &lt;div class=\"gpio-buttons\">\n                        &lt;button class=\"btn-on\" onclick=\"setGPIO(&lt;?= $pin ?>, 1)\" id=\"btn-on-&lt;?= $pin ?>\">\n                            \u2705 ACTIVER\n                        &lt;\/button>\n                        &lt;button class=\"btn-off\" onclick=\"setGPIO(&lt;?= $pin ?>, 0)\" id=\"btn-off-&lt;?= $pin ?>\">\n                            \u274c D\u00c9SACTIVER\n                        &lt;\/button>\n                    &lt;\/div>\n                &lt;\/div>\n                &lt;?php endforeach; ?>\n            &lt;\/div>\n            \n            &lt;div class=\"system-info\">\n                &lt;h3>\ud83d\udcca Informations Syst\u00e8me&lt;\/h3>\n                &lt;div class=\"info-grid\">\n                    &lt;div class=\"info-item\">\n                        &lt;strong>Serveur:&lt;\/strong> Apache2\n                    &lt;\/div>\n                    &lt;div class=\"info-item\">\n                        &lt;strong>PHP Version:&lt;\/strong> &lt;?= phpversion() ?>\n                    &lt;\/div>\n                    &lt;div class=\"info-item\">\n                        &lt;strong>Interface GPIO:&lt;\/strong> gpiod\n                    &lt;\/div>\n                    &lt;div class=\"info-item\">\n                        &lt;strong>GPIOs Configur\u00e9s:&lt;\/strong> &lt;?= implode(', ', $availablePins) ?>\n                    &lt;\/div>\n                &lt;\/div>\n            &lt;\/div>\n        &lt;\/div>\n    &lt;\/div>\n\n    &lt;div id=\"message\" class=\"message\">&lt;\/div>\n\n    &lt;script>\n        function setGPIO(pin, state) {\n            \/\/ D\u00e9sactiver les boutons pendant l'op\u00e9ration\n            setButtonsState(pin, true);\n            showLoading(pin, true);\n            \n            const formData = new FormData();\n            formData.append('action', 'set');\n            formData.append('pin', pin);\n            formData.append('state', state);\n            \n            fetch('index.php', {\n                method: 'POST',\n                body: formData\n            })\n            .then(response => response.json())\n            .then(data => {\n                setButtonsState(pin, false);\n                showLoading(pin, false);\n                \n                if (data.success) {\n                    updateStatus(data.pin, data.state);\n                    showMessage('\u2705 GPIO ' + pin + ' mis \u00e0 ' + data.state, 'success');\n                } else {\n                    showMessage('\u274c Erreur: ' + data.error, 'error');\n                    \/\/ Re-v\u00e9rifier le statut actuel\n                    checkPinStatus(pin);\n                }\n            })\n            .catch(error => {\n                setButtonsState(pin, false);\n                showLoading(pin, false);\n                console.error('Erreur:', error);\n                showMessage('\u274c Erreur de communication avec le serveur', 'error');\n            });\n        }\n\n        function updateStatus(pin, state) {\n            const statusElement = document.getElementById(`status-${pin}`);\n            const gpioControl = document.getElementById(`gpio-${pin}`);\n            \n            if (statusElement &amp;&amp; gpioControl) {\n                \/\/ Mettre \u00e0 jour le statut\n                if (state === 1) {\n                    statusElement.innerHTML = '\ud83d\udfe2 \u00c9TAT: ACTIF (1)';\n                    statusElement.className = 'status on';\n                    gpioControl.classList.add('active');\n                    gpioControl.classList.remove('inactive');\n                } else {\n                    statusElement.innerHTML = '\ud83d\udd34 \u00c9TAT: INACTIF (0)';\n                    statusElement.className = 'status off';\n                    gpioControl.classList.add('inactive');\n                    gpioControl.classList.remove('active');\n                }\n            }\n        }\n\n        function setButtonsState(pin, disabled) {\n            const btnOn = document.getElementById(`btn-on-${pin}`);\n            const btnOff = document.getElementById(`btn-off-${pin}`);\n            \n            if (btnOn) btnOn.disabled = disabled;\n            if (btnOff) btnOff.disabled = disabled;\n        }\n\n        function showLoading(pin, show) {\n            const loadingElement = document.getElementById(`loading-${pin}`);\n            if (loadingElement) {\n                loadingElement.style.display = show ? 'inline-block' : 'none';\n            }\n        }\n\n        function checkPinStatus(pin) {\n            fetch(`index.php?ajax=1&amp;action=status&amp;pin=${pin}`)\n                .then(response => response.json())\n                .then(data => {\n                    if (data.success) {\n                        updateStatus(data.pin, data.state);\n                    } else {\n                        document.getElementById(`status-${pin}`).innerHTML = '\u274c Erreur de lecture';\n                        document.getElementById(`status-${pin}`).className = 'status unknown';\n                    }\n                })\n                .catch(error => {\n                    console.error('Erreur pour GPIO ' + pin + ':', error);\n                    document.getElementById(`status-${pin}`).innerHTML = '\u274c Erreur connexion';\n                    document.getElementById(`status-${pin}`).className = 'status unknown';\n                });\n        }\n\n        function checkAllStatus() {\n            fetch(`index.php?ajax=1&amp;action=all_status`)\n                .then(response => response.json())\n                .then(data => {\n                    if (data.success) {\n                        for (const [pin, state] of Object.entries(data.status)) {\n                            updateStatus(parseInt(pin), state);\n                        }\n                    }\n                })\n                .catch(error => {\n                    console.error('Erreur lors de la v\u00e9rification des statuts:', error);\n                });\n        }\n\n        function showMessage(message, type) {\n            const messageDiv = document.getElementById('message');\n            messageDiv.textContent = message;\n            messageDiv.className = `message ${type} show`;\n            \n            setTimeout(() => {\n                messageDiv.classList.remove('show');\n            }, 4000);\n        }\n\n        \/\/ V\u00e9rifier l'\u00e9tat au chargement de la page\n        document.addEventListener('DOMContentLoaded', function() {\n            console.log('\ud83d\ude80 Initialisation du contr\u00f4le GPIO...');\n            checkAllStatus();\n            \n            \/\/ V\u00e9rifier l'\u00e9tat toutes les 3 secondes\n            setInterval(checkAllStatus, 3000);\n        });\n    &lt;\/script>\n&lt;\/body>\n&lt;\/html><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">V\u00e9rification finale<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Testez les permissions en acc\u00e9dant \u00e0 :\nhttp:&#47;&#47;votre-pi\/test_permissions.php\n\n# Puis acc\u00e9dez \u00e0 l'interface principale :\nhttp:\/\/votre-pi\/<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">S\u00e9curisation suppl\u00e9mentaire (optionnel)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Cr\u00e9er un fichier .htaccess pour s\u00e9curiser l'acc\u00e8s\nsudo nano \/var\/www\/html\/.htaccess<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Emp\u00eacher l'acc\u00e8s aux fichiers sensibles\n&lt;Files \"test_permissions.php\">\n    Order deny,allow\n    Deny from all\n    Allow from 127.0.0.1\n&lt;\/Files><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;Installation des paquets n\u00e9cessaires Configuration des permissions GPIO Script PHP principal (\/var\/www\/html\/index.php) V\u00e9rification finale S\u00e9curisation suppl\u00e9mentaire (optionnel)<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-4777","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GPIO par site WEB - workboot<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GPIO par site WEB - workboot\" \/>\n<meta property=\"og:description\" content=\"&nbsp;Installation des paquets n\u00e9cessaires Configuration des permissions GPIO Script PHP principal (\/var\/www\/html\/index.php) V\u00e9rification finale S\u00e9curisation suppl\u00e9mentaire (optionnel)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/\" \/>\n<meta property=\"og:site_name\" content=\"workboot\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-30T17:09:38+00:00\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/gpio-par-site-web\\\/\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/gpio-par-site-web\\\/\",\"name\":\"GPIO par site WEB - workboot\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#website\"},\"datePublished\":\"2025-10-30T17:09:37+00:00\",\"dateModified\":\"2025-10-30T17:09:38+00:00\",\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/workboot.fr\\\/ciela\\\/gpio-par-site-web\\\/\"]}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#website\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/\",\"name\":\"workboot\",\"description\":\"Open Source, Open Minds \",\"publisher\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#organization\",\"name\":\"workboot\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/logo_ciel-dorian-1.png\",\"contentUrl\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/logo_ciel-dorian-1.png\",\"width\":1024,\"height\":950,\"caption\":\"workboot\"},\"image\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GPIO par site WEB - workboot","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/","og_locale":"fr_FR","og_type":"article","og_title":"GPIO par site WEB - workboot","og_description":"&nbsp;Installation des paquets n\u00e9cessaires Configuration des permissions GPIO Script PHP principal (\/var\/www\/html\/index.php) V\u00e9rification finale S\u00e9curisation suppl\u00e9mentaire (optionnel)","og_url":"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/","og_site_name":"workboot","article_modified_time":"2025-10-30T17:09:38+00:00","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/","url":"https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/","name":"GPIO par site WEB - workboot","isPartOf":{"@id":"https:\/\/workboot.fr\/ciela\/#website"},"datePublished":"2025-10-30T17:09:37+00:00","dateModified":"2025-10-30T17:09:38+00:00","inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/workboot.fr\/ciela\/gpio-par-site-web\/"]}]},{"@type":"WebSite","@id":"https:\/\/workboot.fr\/ciela\/#website","url":"https:\/\/workboot.fr\/ciela\/","name":"workboot","description":"Open Source, Open Minds ","publisher":{"@id":"https:\/\/workboot.fr\/ciela\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/workboot.fr\/ciela\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/workboot.fr\/ciela\/#organization","name":"workboot","url":"https:\/\/workboot.fr\/ciela\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/workboot.fr\/ciela\/#\/schema\/logo\/image\/","url":"https:\/\/workboot.fr\/ciela\/wp-content\/uploads\/2025\/05\/logo_ciel-dorian-1.png","contentUrl":"https:\/\/workboot.fr\/ciela\/wp-content\/uploads\/2025\/05\/logo_ciel-dorian-1.png","width":1024,"height":950,"caption":"workboot"},"image":{"@id":"https:\/\/workboot.fr\/ciela\/#\/schema\/logo\/image\/"}}]}},"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"https:\/\/workboot.fr\/ciela\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"&nbsp;Installation des paquets n\u00e9cessaires Configuration des permissions GPIO Script PHP principal (\/var\/www\/html\/index.php) V\u00e9rification finale S\u00e9curisation suppl\u00e9mentaire (optionnel)","_links":{"self":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/4777","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/comments?post=4777"}],"version-history":[{"count":1,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/4777\/revisions"}],"predecessor-version":[{"id":4779,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/4777\/revisions\/4779"}],"wp:attachment":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/media?parent=4777"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}