From e19529231201106aff9a162f0a37516854518c22 Mon Sep 17 00:00:00 2001 From: TobiasRoeddiger Date: Wed, 25 Oct 2023 13:38:03 +0200 Subject: [PATCH 1/3] updated to new audio characteristic --- assets/js/OpenEarable.js | 22 +++++++++++++++------- index.html | 3 ++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/assets/js/OpenEarable.js b/assets/js/OpenEarable.js index 106fa74..9a6d7fe 100644 --- a/assets/js/OpenEarable.js +++ b/assets/js/OpenEarable.js @@ -62,9 +62,12 @@ const SERVICES = { DEVICE_IDENTIFIER_CHARACTERISTIC: { UUID: '45622511-6468-465a-b141-0b9b0f96b468' }, - DEVICE_GENERATION_CHARACTERISTIC: { + FIRMWARE_REVISION_CHARACTERISTIC: { UUID: '45622512-6468-465a-b141-0b9b0f96b468' - } + }, + HARDWARE_REVISION_CHARACTERISTIC: { + UUID: '45622513-6468-465a-b141-0b9b0f96b468' + }, } }, BATTERY_SERVICE: { @@ -151,15 +154,20 @@ class OpenEarable { return new TextDecoder().decode(value); } - async readHardwareVersion() { - return "1.3.0"; - } - async readFirmwareVersion() { 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/index.html b/index.html index 90e73f8..f80ef5a 100644 --- a/index.html +++ b/index.html @@ -205,7 +205,8 @@
Device
OpenEarable-XXXX (XX%)
Firmware Date: Mon, 29 Jan 2024 10:26:52 +0100 Subject: [PATCH 2/3] seperate file download to two files --- assets/js/RecordingManager.js | 77 +++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/assets/js/RecordingManager.js b/assets/js/RecordingManager.js index 82c07a6..8865043 100644 --- a/assets/js/RecordingManager.js +++ b/assets/js/RecordingManager.js @@ -166,26 +166,25 @@ $(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]", "sensor_gyroX[°/s]", "sensor_gyroY[°/s]", "sensor_gyroZ[°/s]", - "sensor_magX[µT]", "sensor_magY[µT]", "sensor_magZ[µT]", - "sensor_pressure[hPa]", "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 ["acc", "gyro", "mag"].forEach(sensorType => { if (data[sensorType] && data[sensorType].length === 3) { row.push(...data[sensorType].map(val => val.toString().replace(',', '.'))); @@ -193,42 +192,58 @@ $(document).ready(function () { row.push('', '', ''); // Push empty values if sensor data isn't available or isn't valid } }); + + 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); + } + 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 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" : ""); - } - + rows.push(row); }); - - // 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)); - } - } - - // 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); } + + }); From 513470e10373fc2fbb9042afa7488b13fc98f889 Mon Sep 17 00:00:00 2001 From: TobiasRoeddiger Date: Mon, 29 Jan 2024 11:52:12 +0100 Subject: [PATCH 3/3] remove empty lines --- assets/js/RecordingManager.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/assets/js/RecordingManager.js b/assets/js/RecordingManager.js index 8865043..dc5b927 100644 --- a/assets/js/RecordingManager.js +++ b/assets/js/RecordingManager.js @@ -185,15 +185,20 @@ $(document).ready(function () { let row = [timestamp]; // 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 } }); - rows.push(row); + // Only add rows with data to the CSV + if (hasData) { + rows.push(row); + } }); let csv = headers.join(",") + "\n" + rows.map(row => row.join(",")).join("\n"); @@ -209,6 +214,7 @@ $(document).ready(function () { a.click(); document.body.removeChild(a); } + function generateAndDownloadTempPressCSV(dataCache, recordingStartTime) { let headers = [ @@ -223,10 +229,14 @@ $(document).ready(function () { let row = [timestamp]; // Push temperature and pressure data ensuring the correct float format - row.push(data.pressure ? data.pressure.toString().replace(',', '.') : ''); - row.push(data.temperature ? data.temperature.toString().replace(',', '.') : ''); + let pressure = data.pressure ? data.pressure.toString().replace(',', '.') : ''; + let temperature = data.temperature ? data.temperature.toString().replace(',', '.') : ''; - rows.push(row); + // Only add rows with temperature or pressure data + if (pressure || temperature) { + row.push(pressure, temperature); + rows.push(row); + } }); let csv = headers.join(",") + "\n" + rows.map(row => row.join(",")).join("\n"); @@ -244,6 +254,7 @@ $(document).ready(function () { } + });