<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HKデータフォーマット切り取り</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            font-size: 14px;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            font-size: 12px;
        }

        th,
        td {
            border: 1px solid #ccc;
            padding: 4px 8px;
            text-align: left;
        }

        th {
            background-color: #f4f4f4;
        }

        tr.selected {
            background-color: #d3f9d8;
        }

        pre {
            background-color: #f4f4f4;
            padding: 10px;
            border: 1px solid #ccc;
            overflow-x: auto;
        }

        .output-section {
            margin-top: 20px;
        }
    </style>
</head>

<body>
    <h1>HKデータフォーマット切り取り</h1>
    <input type="file" id="fileInput" accept=".txt">
    <table id="textTable">
        <thead>
            <tr>
                <th>#</th>
                <th>内容</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <button id="showSelected">選択された行を表示</button>
    <div id="selectedItems"></div>
    <div id="output"></div>
    <div id="parsedOutput"></div>

    <script>
        // バイト列を検出する関数
        function findSequence(array, pattern) {
            for (let i = 0; i <= array.length - pattern.length; i++) {
                if (pattern.every((value, index) => array[i + index] === value)) {
                    return i; // 最初の位置を返す
                }
            }
            return -1; // 見つからない場合
        }

        function parseHKData(hkData) {
            const parsedData = {
                // Header: hkData.slice(0, 2).map(byte => `0x${byte.toString(16).toUpperCase()}`),
                Time: {
                    sec: hkData[2],
                    min: hkData[3],
                    hour: hkData[4],
                    day: hkData[5] + hkData[6],
                },
                // MiddlePattern: hkData.slice(7, 10).map(byte => `0x${byte.toString(16).toUpperCase()}`),
                Temperatures: {
                    "+X Temp": (100 * ((parseInt(hkData[10].toString(16) + hkData[11].toString(16), 16) / 4096) * 2.5) - 50).toFixed(1),

                    "-X Temp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[12].toString(16) + hkData[13].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),

                    "+Y Temp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[14].toString(16) + hkData[15].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),

                    "-Y Temp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[16].toString(16) + hkData[17].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),

                    "+Z Temp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[18].toString(16) + hkData[19].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),

                    "-Z Temp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[20].toString(16) + hkData[21].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),

                    "BPBTemp": ((
                        (
                            5.506 -
                            Math.sqrt(
                                Math.pow(5.506, 2) +
                                (4 * 0.00176 * (
                                    870.6 -
                                    ((parseInt(hkData[22].toString(16) + hkData[23].toString(16), 16) / 4096) * 2.5 * Math.pow(10, 3))
                                ))
                            )
                        ) / (2 * -0.00176)
                    ) + 30).toFixed(1),


                },
                Voltages: {
                    "-X Voltage": ((parseInt(hkData[24].toString(16) + hkData[25].toString(16), 16) / 4096) * 2.5 * 5 / 3).toFixed(1),
                    "+Y Voltage": ((parseInt(hkData[26].toString(16) + hkData[27].toString(16), 16) / 4096) * 2.5 * 5 / 3).toFixed(1),
                    "-Y Voltage": ((parseInt(hkData[28].toString(16) + hkData[29].toString(16), 16) / 4096) * 2.5 * 5 / 3).toFixed(1),
                    "+Z Voltage": ((parseInt(hkData[30].toString(16) + hkData[31].toString(16), 16) / 4096) * 2.5 * 5 / 3).toFixed(1),
                    "-Z Voltage": ((parseInt(hkData[32].toString(16) + hkData[33].toString(16), 16) / 4096) * 2.5 * 5 / 3).toFixed(1),
                },
                Currents: {
                    "-X Current": ((parseInt(hkData[34].toString(16), 16) * 3.3) / 256 / 50 / 0.05).toFixed(1),
                    "+Y Current": ((parseInt(hkData[35].toString(16), 16) * 3.3) / 256 / 50 / 0.05).toFixed(1),
                    "-Y Current": ((parseInt(hkData[36].toString(16), 16) * 3.3) / 256 / 50 / 0.05).toFixed(1),
                    "+Z Current": ((parseInt(hkData[37].toString(16), 16) * 3.3) / 256 / 50 / 0.05).toFixed(1),
                    "-Z Current": ((parseInt(hkData[38].toString(16), 16) * 3.3) / 256 / 50 / 0.05).toFixed(1),
                },
                BatteryStatus: {
                    "BatteryTemp": ((3976 * (25 + 273) / (3976 + (25 + 273) * Math.log10((parseInt("6f", 16) / 256 * 3.3) / (3.3 - (parseInt("6f", 16) / 256 * 3.3))))) - 273).toFixed(1),

                    "Battery Voltage": ((parseInt(hkData[40].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "Battery Current": ((
                        (((parseInt(hkData[41].toString(16) + hkData[42].toString(16), 16) / 4096) * 3.3) - 3.3 * 0.5) * 1000 / 264
                    )).toFixed(1),

                    "FAB RAW Voltage": ((
                        parseInt(hkData[43].toString(16), 16) / 256 * 3.3 * 2
                    )).toFixed(1),

                    "FAB RAW Current": ((
                        (((parseInt(hkData[44].toString(16), 16) / 256) * 3.3) - 0.33) * 1000 / 264
                    )).toFixed(1),

                    "SRC Voltage": ((parseInt(hkData[45].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "SRC Current": ((
                        (((parseInt(hkData[46].toString(16) + hkData[47].toString(16), 16) / 4096) * 3.3) - 0.33) * 1000 / 264
                    )).toFixed(1),

                    "Heater": hkData[48],

                    "Kill": hkData[49],

                    "RESET RAW Voltage": ((parseInt(hkData[51].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "3V3#1 Current": ((parseInt(hkData[52].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "3V3#2 Current": ((parseInt(hkData[53].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "UHF_COM Current": ((parseInt(hkData[54].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "DEP_ANT_I": ((parseInt(hkData[55].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "5V Current": ((parseInt(hkData[56].toString(16), 16) / 256) * 3.3 * 2).toFixed(1),

                    "RESET_SW_STATUS": hkData[57] + hkData[58],
                    "RESET_SW_TIME": hkData[59],


                },
                // Footer: hkData.slice(76, 78).map(byte => `0x${byte.toString(16).toUpperCase()}`),
            };
            return parsedData;
        }

        function displayParsedData(parsedData) {
            let outputHTML = "<table><thead><tr><th>項目</th><th>値</th></tr></thead><tbody>";
            for (const [key, value] of Object.entries(parsedData)) {
                if (typeof value === "object" && !Array.isArray(value)) {
                    outputHTML += `<tr><td colspan="2"><strong>${key}</strong></td></tr>`;
                    for (const [subKey, subValue] of Object.entries(value)) {
                        outputHTML += `<tr><td>${subKey}</td><td>${subValue}</td></tr>`;
                    }
                } else {
                    outputHTML += `<tr><td>${key}</td><td>${Array.isArray(value) ? value.join(", ") : value}</td></tr>`;
                }
            }
            outputHTML += "</tbody></table>";
            return outputHTML;
        }

        document.getElementById("fileInput").addEventListener("change", function (event) {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function (e) {
                    const lines = e.target.result.trim().split(/\r?\n/);
                    const tableBody = document.querySelector("#textTable tbody");
                    tableBody.innerHTML = ""; // テーブルをクリア

                    lines.forEach((line, index) => {
                        const row = document.createElement("tr");
                        row.dataset.index = index;

                        const numberCell = document.createElement("td");
                        numberCell.textContent = index + 1;

                        const contentCell = document.createElement("td");
                        contentCell.textContent = line.trim();

                        row.appendChild(numberCell);
                        row.appendChild(contentCell);
                        tableBody.appendChild(row);

                        row.addEventListener("click", function () {
                            document.querySelectorAll("#textTable tbody tr").forEach(r => r.classList.remove("selected"));
                            row.classList.add("selected");
                        });
                    });
                };
                reader.readAsText(file);
            }
        });

        document.getElementById("showSelected").addEventListener("click", function () {
            const selectedRow = document.querySelector("#textTable tbody tr.selected");
            const selectedDiv = document.getElementById("selectedItems");
            const outputDiv = document.getElementById("output");
            const parsedOutputDiv = document.getElementById("parsedOutput");

            if (selectedRow) {
                const content = selectedRow.querySelector("td:last-child").textContent;
                selectedDiv.innerHTML = `<h2>選択された行:</h2><p>${content}</p>`;

                // データを16進数の配列に変換
                const byteArray = content.split(/\s+/).map(byte => parseInt(byte, 16));

                // 検出するパターン
                const headerPattern = [0x33, 0x33];
                const footerPattern = [0x44, 0x44];
                const middlePattern = [0xAA, 0xAA, 0xAA];

                // ヘッダーとフッターを検出
                const headerIndex = findSequence(byteArray, headerPattern);
                const footerIndex = findSequence(byteArray, footerPattern);

                let hkData;
                if (headerIndex !== -1 && footerIndex !== -1) {
                    // ヘッダーとフッターが見つかった場合
                    hkData = byteArray.slice(headerIndex, headerIndex + 78);
                } else {
                    // 中間パターンを基準に切り取る
                    const middleIndex = findSequence(byteArray, middlePattern);
                    if (middleIndex !== -1) {
                        const startIndex = middleIndex - 7; // 中間が index 7 に来るように調整
                        hkData = byteArray.slice(startIndex, startIndex + 78);
                    } else {
                        outputDiv.innerHTML = '<p>ヘッダー、フッター、中間パターンが見つかりませんでした。</p>';
                        return;
                    }
                }

                // デコード結果
                const decodedOutput = hkData.map((value, index) => `Index ${index}: 0x${value.toString(16).toUpperCase()}`);

                // 解析結果
                const parsedData = parseHKData(hkData);
                const parsedOutputHTML = displayParsedData(parsedData);

                // 結果を表示
                outputDiv.innerHTML = `
                    <h2>切り取られたHKデータ:</h2>
                    <pre>${decodedOutput.join("\n")}</pre>
                `;

                parsedOutputDiv.innerHTML = `
                    <h2>解析結果:</h2>
                    ${parsedOutputHTML}
                `;
            } else {
                selectedDiv.innerHTML = "<h2>選択された行:</h2><p>何も選択されていません。</p>";
                outputDiv.innerHTML = "";
                parsedOutputDiv.innerHTML = "";
            }
        });
    </script>
</body>

</html>
