diff --git a/assets/js/OpenEarable.js b/assets/js/OpenEarable.js index 390f724..c44c8a2 100644 --- a/assets/js/OpenEarable.js +++ b/assets/js/OpenEarable.js @@ -62,7 +62,7 @@ const SERVICES = { DEVICE_IDENTIFIER_CHARACTERISTIC: { UUID: '45622511-6468-465a-b141-0b9b0f96b468' }, - DEVICE_GENERATION_CHARACTERISTIC: { + FIRMWARE_REVISION_CHARACTERISTIC: { UUID: '45622512-6468-465a-b141-0b9b0f96b468' }, HARDWARE_GENERATION_CHARACTERISTIC: { @@ -158,7 +158,16 @@ class OpenEarable { this.bleManager.ensureConnected(); const value = await this.bleManager.readCharacteristic( SERVICES.DEVICE_INFO_SERVICE.UUID, - SERVICES.DEVICE_INFO_SERVICE.CHARACTERISTICS.DEVICE_GENERATION_CHARACTERISTIC.UUID + SERVICES.DEVICE_INFO_SERVICE.CHARACTERISTICS.FIRMWARE_REVISION_CHARACTERISTIC.UUID + ); + return new TextDecoder().decode(value); + } + + async readHardwareVersion() { + this.bleManager.ensureConnected(); + const value = await this.bleManager.readCharacteristic( + SERVICES.DEVICE_INFO_SERVICE.UUID, + SERVICES.DEVICE_INFO_SERVICE.CHARACTERISTICS.HARDWARE_REVISION_CHARACTERISTIC.UUID ); return new TextDecoder().decode(value); } diff --git a/assets/js/RecordingManager.js b/assets/js/RecordingManager.js index daf356b..d4bb35f 100644 --- a/assets/js/RecordingManager.js +++ b/assets/js/RecordingManager.js @@ -166,69 +166,95 @@ $(document).ready(function () { }); function generateAndDownloadCSV(dataCache, recordingStartTime) { + generateAndDownloadIMUCSV(dataCache, recordingStartTime); + generateAndDownloadTempPressCSV(dataCache, recordingStartTime); + } + + function generateAndDownloadIMUCSV(dataCache, recordingStartTime) { let headers = [ - "time", "sensor_accX[m/s]", "sensor_accY[m/s]", "sensor_accZ[m/s]", + "time", "sensor_accX[g]", "sensor_accY[g]", "sensor_accZ[g]", "sensor_gyroX[°/s]", "sensor_gyroY[°/s]", "sensor_gyroZ[°/s]", - "sensor_magX[µT]", "sensor_magY[µT]", "sensor_magZ[µT]", - "sensor_pressure[Pa]", "sensor_temperature[°C]" + "sensor_magX[µT]", "sensor_magY[µT]", "sensor_magZ[µT]" ]; - - for (let i = 0; i < buttonIds.length - 1; i++) { - let buttonId = buttonIds[i]; - headers.push("label_OpenEarable_" + $('#' + buttonId).text()); - } - + let rows = []; - + // Sorting the timestamps and generating the CSV lines Object.keys(dataCache).sort().forEach(timestamp => { let data = dataCache[timestamp]; let row = [timestamp]; - - // Push sensor data ensuring the correct float format + + // Push IMU sensor data ensuring the correct float format + let hasData = false; ["acc", "gyro", "mag"].forEach(sensorType => { if (data[sensorType] && data[sensorType].length === 3) { row.push(...data[sensorType].map(val => val.toString().replace(',', '.'))); + hasData = true; } else { - row.push('', '', ''); // Push empty values if sensor data isn't available or isn't valid + row.push('', '', ''); // Fill with empty values but do not count as data } }); - - row.push(data.pressure ? data.pressure.toString().replace(',', '.') : ''); - row.push(data.temperature ? data.temperature.toString().replace(',', '.') : ''); - - - for (let i = 0; i < buttonIds.length - 1; i++) { - let buttonId = buttonIds[i]; - let labelName = $('#' + buttonId).text(); - row.push(data.labels.includes(labelName) ? "x" : ""); + + // Only add rows with data to the CSV + if (hasData) { + rows.push(row); } - - rows.push(row); }); + + let csv = headers.join(",") + "\n" + rows.map(row => row.join(",")).join("\n"); + + // Trigger a download + const blob = new Blob([csv], { type: 'text/csv' }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.setAttribute('hidden', ''); + a.setAttribute('href', url); + a.setAttribute('download', `IMU_recording_${recordingStartTime}.csv`); + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + } + - // Check if any columns are empty across all rows and remove them - for (let colIdx = headers.length - 1; colIdx >= 0; colIdx--) { - if (rows.every(row => !row[colIdx])) { - headers.splice(colIdx, 1); - rows.forEach(row => row.splice(colIdx, 1)); + function generateAndDownloadTempPressCSV(dataCache, recordingStartTime) { + let headers = [ + "time", "sensor_pressure[Pa]", "sensor_temperature[°C]" + ]; + + let rows = []; + + // Sorting the timestamps and generating the CSV lines + Object.keys(dataCache).sort().forEach(timestamp => { + let data = dataCache[timestamp]; + let row = [timestamp]; + + // Push temperature and pressure data ensuring the correct float format + let pressure = data.pressure ? data.pressure.toString().replace(',', '.') : ''; + let temperature = data.temperature ? data.temperature.toString().replace(',', '.') : ''; + + // Only add rows with temperature or pressure data + if (pressure || temperature) { + row.push(pressure, temperature); + rows.push(row); } - } - - // Construct the CSV content + }); + let csv = headers.join(",") + "\n" + rows.map(row => row.join(",")).join("\n"); - + // Trigger a download const blob = new Blob([csv], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.setAttribute('hidden', ''); a.setAttribute('href', url); - a.setAttribute('download', `recording_${recordingStartTime}.csv`); // filename based on when the recording was started + a.setAttribute('download', `TempPress_recording_${recordingStartTime}.csv`); document.body.appendChild(a); a.click(); document.body.removeChild(a); } + + + }); diff --git a/index.html b/index.html index 0e9750f..ceddddc 100644 --- a/index.html +++ b/index.html @@ -205,7 +205,8 @@