| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>HTTP with Client-Side Sensor Data and Flags</title> |
| <style> |
| body { |
| font-family: Arial, sans-serif; |
| } |
| #container { |
| margin: 50px; |
| } |
| #output, #client-refresh, #client-sensor, #controls, #flags, #export, #send-data, #send-flags { |
| margin-top: 10px; |
| padding: 10px; |
| border: 1px solid #ccc; |
| background-color: #f9f9f9; |
| width: 320px; |
| } |
| #status { |
| margin-top: 10px; |
| font-weight: bold; |
| } |
| #error { |
| margin-top: 10px; |
| color: red; |
| } |
| button { |
| margin-right: 5px; |
| margin-bottom: 5px; |
| } |
| .flag-button.active { |
| background-color: #4CAF50; |
| color: white; |
| } |
| </style> |
| </head> |
| <body> |
| <div id="container"> |
| <h1>HTTP & Client-Side Sensor Data with Flags</h1> |
| <p>データを送信するサーバーのURLを指定してください(例: https://example.com/api/):</p> |
| <input type="text" id="server-url" placeholder="https://example.com/api/"> |
| <div id="send-flags"> |
| <button onclick="setServerUrl()">設定</button> |
| </div> |
|
|
| <div id="controls"> |
| <button onclick="startRecording()">記録開始</button> |
| <button onclick="stopRecording()">記録停止</button> |
| </div> |
| |
| <div id="flags"> |
| <h3>フラグ設定</h3> |
| <button id="flag-start" class="flag-button" onclick="toggleFlag('start')">Start</button> |
| <button id="flag-stop" class="flag-button" onclick="toggleFlag('stop')">Stop</button> |
| <button id="flag-pause" class="flag-button" onclick="toggleFlag('pause')">Pause</button> |
| <button id="flag-walk" class="flag-button" onclick="toggleFlag('walk')">Walk</button> |
| <button id="flag-inBag" class="flag-button" onclick="toggleFlag('inBag')">In Bag</button> |
| <button id="flag-inPocket" class="flag-button" onclick="toggleFlag('inPocket')">In Pocket</button> |
| <button id="flag-inHand" class="flag-button" onclick="toggleFlag('inHand')">In Hand</button> |
| <div id="current-flags"> |
| <strong>現在のフラグ:</strong> なし |
| </div> |
| <button onclick="sendFlagsToServer()">フラグを送信</button> |
| </div> |
|
|
| <div id="export"> |
| <button onclick="exportToCSV()">CSVとしてエクスポート</button> |
| </div> |
| <div id="send-data"> |
| <button onclick="sendDataToServer()">データを送信</button> |
| </div> |
|
|
| <div id="status">Status: Not connected</div> |
| <div id="output">最新サーバーデータがここに表示されます</div> |
| <div id="client-sensor">クライアントサイドデータ: 加速度と回転率がここに表示されます</div> |
| <div id="client-refresh">クライアント リフレッシュレート: 計測中...</div> |
| <div id="error">エラー: なし</div> |
| </div> |
|
|
| <script> |
| |
| let serverUrl = ''; |
| |
| |
| let isRecording = false; |
| let sensorData = []; |
| |
| |
| const flags = { |
| start: false, |
| stop: false, |
| pause: false, |
| walk: false, |
| inBag: false, |
| inPocket: false, |
| inHand: false |
| }; |
| |
| |
| function updateFlagButtons() { |
| for (let key in flags) { |
| const button = document.getElementById(`flag-${key}`); |
| if (flags[key]) { |
| button.classList.add('active'); |
| } else { |
| button.classList.remove('active'); |
| } |
| } |
| |
| |
| const activeFlags = Object.keys(flags).filter(key => flags[key]); |
| const currentFlagsDiv = document.getElementById('current-flags'); |
| currentFlagsDiv.innerHTML = `<strong>現在のフラグ:</strong> ${activeFlags.length > 0 ? activeFlags.join(', ') : 'なし'}`; |
| } |
| |
| |
| function toggleFlag(flag) { |
| if (flags.hasOwnProperty(flag)) { |
| flags[flag] = !flags[flag]; |
| updateFlagButtons(); |
| } |
| } |
| |
| |
| function setServerUrl() { |
| const inputUrl = document.getElementById('server-url').value.trim(); |
| if (inputUrl) { |
| serverUrl = inputUrl.endsWith('/') ? inputUrl : inputUrl + '/'; |
| document.getElementById('status').innerHTML = `Status: Server URL set to ${serverUrl}`; |
| document.getElementById('error').innerHTML = "エラー: なし"; |
| } else { |
| alert("有効なサーバーURLを入力してください。"); |
| } |
| } |
| |
| |
| function requestSensorPermissions() { |
| try { |
| if (typeof DeviceMotionEvent.requestPermission === 'function') { |
| DeviceMotionEvent.requestPermission() |
| .then(permissionState => { |
| if (permissionState === 'granted') { |
| document.getElementById('status').innerHTML = "センサーアクセスが許可されました"; |
| startMotionDetection(); |
| } else { |
| document.getElementById('status').innerHTML = "センサーアクセスが拒否されました"; |
| } |
| }) |
| .catch(error => { |
| handleError(error); |
| }); |
| } else { |
| |
| startMotionDetection(); |
| } |
| } catch (error) { |
| handleError(error); |
| } |
| } |
| |
| |
| function startMotionDetection() { |
| try { |
| window.addEventListener('devicemotion', function(event) { |
| let acceleration = event.accelerationIncludingGravity; |
| let rotationRate = event.rotationRate; |
| let timestamp = event.timeStamp; |
| |
| let sensorInfo = { |
| timestamp: timestamp, |
| acceleration: { |
| x: acceleration.x, |
| y: acceleration.y, |
| z: acceleration.z |
| }, |
| rotationRate: { |
| alpha: rotationRate.alpha, |
| beta: rotationRate.beta, |
| gamma: rotationRate.gamma |
| }, |
| flags: { ...flags } |
| }; |
| |
| document.getElementById('client-sensor').innerHTML = |
| `加速度: <br> X: ${acceleration.x} <br> Y: ${acceleration.y} <br> Z: ${acceleration.z} <br>` + |
| `回転率: <br> alpha: ${rotationRate.alpha} <br> beta: ${rotationRate.beta} <br> gamma: ${rotationRate.gamma}`; |
| |
| if (isRecording) { |
| sensorData.push(sensorInfo); |
| } |
| |
| |
| sendFlagsToServer(); |
| }); |
| } catch (error) { |
| handleError(error); |
| } |
| } |
| |
| |
| function startRecording() { |
| sensorData = []; |
| isRecording = true; |
| document.getElementById('status').innerHTML = "ステータス: 記録中..."; |
| } |
| |
| |
| function stopRecording() { |
| isRecording = false; |
| document.getElementById('status').innerHTML = "ステータス: 記録停止"; |
| } |
| |
| |
| function exportToCSV() { |
| if (sensorData.length === 0) { |
| alert("記録されたデータがありません。"); |
| return; |
| } |
| |
| let csvContent = "data:text/csv;charset=utf-8,"; |
| csvContent += "timestamp,acceleration_x,acceleration_y,acceleration_z,rotation_alpha,rotation_beta,rotation_gamma,flags\n"; |
| |
| sensorData.forEach(function(row) { |
| let flagsString = Object.keys(row.flags).filter(key => row.flags[key]).join(';') || 'none'; |
| let dataString = `${row.timestamp},${row.acceleration.x},${row.acceleration.y},${row.acceleration.z},${row.rotationRate.alpha},${row.rotationRate.beta},${row.rotationRate.gamma},${flagsString}`; |
| csvContent += dataString + "\n"; |
| }); |
| |
| let encodedUri = encodeURI(csvContent); |
| let link = document.createElement("a"); |
| link.setAttribute("href", encodedUri); |
| let currentDate = new Date(); |
| let filename = `sensor_data_${currentDate.getFullYear()}-${String(currentDate.getMonth()+1).padStart(2, '0')}-${String(currentDate.getDate()).padStart(2, '0')}_${String(currentDate.getHours()).padStart(2, '0')}-${String(currentDate.getMinutes()).padStart(2, '0')}-${String(currentDate.getSeconds()).padStart(2, '0')}.csv`; |
| link.setAttribute("download", filename); |
| document.body.appendChild(link); |
| link.click(); |
| document.body.removeChild(link); |
| } |
| |
| |
| function sendDataToServer() { |
| if (sensorData.length === 0) { |
| alert("送信するデータがありません。"); |
| return; |
| } |
| |
| if (!serverUrl) { |
| alert("サーバーURLを設定してください。"); |
| return; |
| } |
| |
| fetch(`${serverUrl}sensor-data`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json' |
| }, |
| body: JSON.stringify(sensorData) |
| }) |
| .then(response => { |
| if (response.ok) { |
| alert("データが正常に送信されました。"); |
| document.getElementById('output').innerHTML = "データがサーバーに送信されました。"; |
| } else { |
| alert("データの送信に失敗しました。ステータスコード: " + response.status); |
| } |
| }) |
| .catch(error => { |
| handleError(error); |
| }); |
| } |
| |
| |
| function sendFlagsToServer() { |
| if (!serverUrl) { |
| console.warn("サーバーURLが設定されていません。フラグを送信できません。"); |
| return; |
| } |
| |
| |
| fetch(`${serverUrl}flags`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json' |
| }, |
| body: JSON.stringify({ flags: { ...flags } }) |
| }) |
| .then(response => { |
| if (response.ok) { |
| console.log("フラグが正常に送信されました。"); |
| } else { |
| console.error("フラグの送信に失敗しました。ステータスコード: " + response.status); |
| } |
| }) |
| .catch(error => { |
| handleError(error); |
| }); |
| } |
| |
| |
| function handleError(error) { |
| console.error(error); |
| let errorMessage = error.message || error; |
| document.getElementById('error').innerHTML = "エラー: " + errorMessage; |
| } |
| |
| |
| window.onload = function() { |
| updateFlagButtons(); |
| }; |
| </script> |
| </body> |
| </html> |
|
|