{"id":72,"date":"2025-06-26T22:30:50","date_gmt":"2025-06-26T20:30:50","guid":{"rendered":"https:\/\/fk.kehu.dk\/?page_id=72"},"modified":"2025-06-27T11:17:52","modified_gmt":"2025-06-27T09:17:52","slug":"raspberry-pi-controller","status":"publish","type":"page","link":"https:\/\/fk.kehu.dk\/","title":{"rendered":"Raspberry Pi Controller"},"content":{"rendered":"    <div id=\"led-controller\" style=\"display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px;\">\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"0\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 1            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"1\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 2            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"2\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 3            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"3\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 4            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"4\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 5            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"5\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 6            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"6\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 7            <\/button>\r\n                    <button \r\n                class=\"led-button\" \r\n                data-led=\"7\" \r\n                style=\"background-color: grey; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer;\"\r\n            >\r\n                OUT 8            <\/button>\r\n            <\/div>\r\n\r\n    <div id=\"input-visualization\" style=\"display: flex; gap: 10px; flex-wrap: wrap;\">\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"0\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN1            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"1\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN2            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"2\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN3            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"3\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN4            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"4\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN5            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"5\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN6            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"6\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN7            <\/div>\r\n                    <div \r\n                class=\"input-field\" \r\n                data-input=\"7\" \r\n                style=\"width: 50px; height: 50px; background-color: lightgrey; display: flex; align-items: center; justify-content: center; border-radius: 5px;\"\r\n            >\r\n                IN8            <\/div>\r\n            <\/div>\r\n\r\n    <script>\r\n        document.addEventListener('DOMContentLoaded', function () {\r\n\t\t\t\r\n\t\t\t\/\/ Start polling every 1 second\r\n\t\t\tsetInterval(fetchDeviceState, 1000);\r\n\t\t\t\r\n            const buttons = document.querySelectorAll('.led-button');\r\n            const inputFields = document.querySelectorAll('.input-field');\r\n            let ledStates = Array(8).fill(false); \/\/ Track LED ON\/OFF states\r\n\r\n            function updateUI(outputPort, inputPort) {\r\n                \/\/ Update LED buttons based on outputPort bits\r\n                buttons.forEach((button, idx) => {\r\n                    if (outputPort & (1 << idx)) {\r\n                        button.style.backgroundColor = 'green';\r\n                        ledStates[idx] = true;\r\n                    } else {\r\n                        button.style.backgroundColor = 'grey';\r\n                        ledStates[idx] = false;\r\n                    }\r\n                });\r\n\r\n                \/\/ Update input fields based on inputPort bits\r\n                inputFields.forEach((field, idx) => {\r\n                    if (inputPort & (1 << idx)) {\r\n                        field.style.backgroundColor = 'blue';\r\n                        field.style.color = 'white';\r\n                    } else {\r\n                        field.style.backgroundColor = 'lightgrey';\r\n                        field.style.color = 'black';\r\n                    }\r\n                });\r\n            }\r\n\r\n            \/\/ Initial fetch to sync UI with device state\r\n            fetchDeviceState();\r\n\r\n            function fetchDeviceState() {\r\n                const data = new URLSearchParams();\r\n                data.append('action', 'toggle_led'); \/\/ Same handler can be used without hex\r\n\r\n                fetch('https:\/\/fk.kehu.dk\/wp-admin\/admin-ajax.php', {\r\n                    method: 'POST',\r\n                    body: data\r\n                })\r\n                .then(response => response.json())\r\n                .then(data => {\r\n                    if (data.success) {\r\n                        console.log('Device Response:', data.data);\r\n                        const deviceResponse = data.data;\r\n                        updateUI(deviceResponse.output_port, deviceResponse.input_port);\r\n                    } else {\r\n                        \/\/alert('Error: ' + data.data);\r\n                    }\r\n                })\r\n                .catch(error => {\r\n                    \/\/alert('Fetch Error: ' + error);\r\n                });\r\n            }\r\n\r\n            buttons.forEach(button => {\r\n                button.addEventListener('click', function () {\r\n                    const ledIndex = parseInt(this.getAttribute('data-led'));\r\n                    const newState = !ledStates[ledIndex];\r\n\r\n                    ledStates[ledIndex] = newState;\r\n\r\n                    \/\/ Calculate total hex value from current ledStates\r\n                    let totalHex = 0;\r\n                    ledStates.forEach((state, idx) => {\r\n                        if (state) totalHex |= (1 << idx);\r\n                    });\r\n\r\n                    const data = new URLSearchParams();\r\n                    data.append('action', 'toggle_led');\r\n                    data.append('hex', totalHex.toString(16).toUpperCase().padStart(2, '0'));\r\n\r\n                    fetch('https:\/\/fk.kehu.dk\/wp-admin\/admin-ajax.php', {\r\n                        method: 'POST',\r\n                        body: data\r\n                    })\r\n                    .then(response => response.json())\r\n                    .then(data => {\r\n                        if (data.success) {\r\n                            const deviceResponse = data.data;\r\n                            updateUI(deviceResponse.output_port, deviceResponse.input_port);\r\n                        } else {\r\n                            \/\/alert('Error: ' + data.data);\r\n                        }\r\n                    })\r\n                    .catch(error => {\r\n                        \/\/alert('Fetch Error: ' + error);\r\n                    });\r\n                });\r\n            });\r\n        });\r\n    <\/script>\r\n    \n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-72","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/pages\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=72"}],"version-history":[{"count":13,"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/pages\/72\/revisions"}],"predecessor-version":[{"id":92,"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=\/wp\/v2\/pages\/72\/revisions\/92"}],"wp:attachment":[{"href":"https:\/\/fk.kehu.dk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}