Skip to content

Commit

Permalink
Merge pull request #12 from OpenEarable/1.3.0
Browse files Browse the repository at this point in the history
1.3.0
  • Loading branch information
TobiasRoeddiger authored Oct 2, 2023
2 parents 2372e4a + 25c24e2 commit be29c17
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 35 deletions.
109 changes: 80 additions & 29 deletions assets/js/OpenEarable.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ const SERVICES = {
DEVICE_INFO_SERVICE: {
UUID: '45622510-6468-465a-b141-0b9b0f96b468',
CHARACTERISTICS: {

DEVICE_IDENTIFIER_CHARACTERISTIC: {
UUID: '45622511-6468-465a-b141-0b9b0f96b468'
},
DEVICE_GENERATION_CHARACTERISTIC: {
UUID: '45622512-6468-465a-b141-0b9b0f96b468'
}
}
},
BATTERY_SERVICE: {
Expand All @@ -75,35 +80,49 @@ const SERVICES = {
PARSE_INFO_SERVICE: {
UUID: 'caa25cb7-7e1b-44f2-adc9-e8c06c9ced43',
CHARACTERISTICS: {

SCHEME_CHARACTERISTIC: {
UUID: 'caa25cb8-7e1b-44f2-adc9-e8c06c9ced43'
}
}
},
SENSOR_SERVICE: {
UUID: '34c2e3bb-34aa-11eb-adc1-0242ac120002',
CHARACTERISTICS: {

SENSOR_CONFIGURATION_CHARACTERISTIC: {
UUID: '34c2e3bd-34aa-11eb-adc1-0242ac120002'
},
SENSOR_DATA_CHARACTERISTIC: {
UUID: '34c2e3bc-34aa-11eb-adc1-0242ac120002'
}
}
},
BUTTON_SERVICE: {
UUID: '29c10bdc-4773-11ee-be56-0242ac120002',
CHARACTERISTICS: {

BUTTON_STATE_CHARACTERISTIC: {
UUID: '29c10f38-4773-11ee-be56-0242ac120002'
}
}
},
LED_SERVICE: {
UUID: '81040a2e-4819-11ee-be56-0242ac120002',
CHARACTERISTICS: {

LED_STATE_CHARACTERISTIC: {
UUID: '81040e7a-4819-11ee-be56-0242ac120002'
}
}
},
AUDIO_SERVICE: {
UUID: '5669146e-476d-11ee-be56-0242ac120002',
CHARACTERISTICS: {

AUDIO_CONTROL_CHARACTERISTIC: {
UUID: '566916a8-476d-11ee-be56-0242ac120002'
}
}
}
}


class OpenEarable {
constructor() {
this.bleManager = new BLEManager();
Expand All @@ -120,19 +139,26 @@ class OpenEarable {

async readDeviceIdentifier() {
this.bleManager.ensureConnected();
const value = await this.bleManager.readCharacteristic('45622510-6468-465a-b141-0b9b0f96b468', '45622511-6468-465a-b141-0b9b0f96b468');
const value = await this.bleManager.readCharacteristic(
SERVICES.DEVICE_INFO_SERVICE.UUID,
SERVICES.DEVICE_INFO_SERVICE.CHARACTERISTICS.DEVICE_IDENTIFIER_CHARACTERISTIC.UUID
);
return new TextDecoder().decode(value);
}

async readHardwareVersion() {
return "1.3.0"
return "1.3.0";
}

async readFirmwareVersion() {
this.bleManager.ensureConnected();
const value = await this.bleManager.readCharacteristic('45622510-6468-465a-b141-0b9b0f96b468', '45622512-6468-465a-b141-0b9b0f96b468');
const value = await this.bleManager.readCharacteristic(
SERVICES.DEVICE_INFO_SERVICE.UUID,
SERVICES.DEVICE_INFO_SERVICE.CHARACTERISTICS.DEVICE_GENERATION_CHARACTERISTIC.UUID
);
return new TextDecoder().decode(value);
}


subscribeBatteryLevelChanged(callback) {
this.batteryLevelChangedSubscribers.push(callback);
Expand Down Expand Up @@ -225,9 +251,11 @@ class BLEManager {
}
async connect() {
return this._enqueueOperation(async () => {
const optionalServiceUUIDs = Object.keys(SERVICES).map((service) => SERVICES[service].UUID);

this.device = await navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: Object.keys(SERVICES).map((service) => SERVICES[service].UUID)
optionalServices: optionalServiceUUIDs
});
this.gattServer = await this.device.gatt.connect();
this.device.addEventListener('gattserverdisconnected', this.handleDisconnected.bind(this));
Expand Down Expand Up @@ -270,7 +298,7 @@ class BLEManager {
setTimeout(() => {
this.notifyAll(this.onDisconnectedSubscribers);
},
5000); // make sure that system has cleaned up everything by delaying a bit
6000); // make sure that system has cleaned up everything by delaying a bit

}

Expand Down Expand Up @@ -320,8 +348,12 @@ class RGBLed {
async writeLedColor(r, g, b) {
this.bleManager.ensureConnected();
const data = new Uint8Array([r, g, b]);
await this.bleManager.writeCharacteristic('81040a2e-4819-11ee-be56-0242ac120002', '81040e7a-4819-11ee-be56-0242ac120002', data);
}
await this.bleManager.writeCharacteristic(
SERVICES.LED_SERVICE.UUID,
SERVICES.LED_SERVICE.CHARACTERISTICS.LED_STATE_CHARACTERISTIC.UUID,
data
);
}
}

class SensorManager {
Expand All @@ -332,7 +364,10 @@ class SensorManager {
}

async init() {
const data = await this.bleManager.readCharacteristic('caa25cb7-7e1b-44f2-adc9-e8c06c9ced43', 'caa25cb8-7e1b-44f2-adc9-e8c06c9ced43');
const data = await this.bleManager.readCharacteristic(
SERVICES.PARSE_INFO_SERVICE.UUID,
SERVICES.PARSE_INFO_SERVICE.CHARACTERISTICS.SCHEME_CHARACTERISTIC.UUID
);
const byteStream = new Uint8Array(data.buffer);

let currentIndex = 0;
Expand Down Expand Up @@ -377,12 +412,16 @@ class SensorManager {
this.sensorSchemes = tempSensorSchemes;


await this.bleManager.subscribeCharacteristicNotifications('34c2e3bb-34aa-11eb-adc1-0242ac120002', '34c2e3bc-34aa-11eb-adc1-0242ac120002', async (data) => {
var parsedData = await this.parseData(data.srcElement.value);
for(let callback of this.onSensorDataReceivedSubscriber) {
callback(parsedData);
await this.bleManager.subscribeCharacteristicNotifications(
SERVICES.SENSOR_SERVICE.UUID,
SERVICES.SENSOR_SERVICE.CHARACTERISTICS.SENSOR_DATA_CHARACTERISTIC.UUID,
async (data) => {
var parsedData = await this.parseData(data.srcElement.value);
for(let callback of this.onSensorDataReceivedSubscriber) {
callback(parsedData);
}
}
});
);
}

async writeSensorConfig(sensorId, samplingRate, latency) {
Expand All @@ -392,7 +431,11 @@ class SensorManager {
view.setUint8(0, sensorId);
view.setFloat32(1, samplingRate, true);
view.setUint32(5, latency, true);
await this.bleManager.writeCharacteristic('34c2e3bb-34aa-11eb-adc1-0242ac120002', '34c2e3bd-34aa-11eb-adc1-0242ac120002', data);
await this.bleManager.writeCharacteristic(
SERVICES.SENSOR_SERVICE.UUID,
SERVICES.SENSOR_SERVICE.CHARACTERISTICS.SENSOR_CONFIGURATION_CHARACTERISTIC.UUID,
data
);
}

async parseData(data) {
Expand Down Expand Up @@ -545,10 +588,6 @@ class AudioPlayer {
*/
constructor(bleManager) {
this.bleManager = bleManager;

// Placeholder service and characteristic UUIDs. Replace these with actual UUIDs.
this.audioServiceUUID = '5669146e-476d-11ee-be56-0242ac120002';
this.audioCharUUID = '566916a8-476d-11ee-be56-0242ac120002';
}

/**
Expand All @@ -561,7 +600,11 @@ class AudioPlayer {
try {
let type = 1; // 1 indicates it's a WAV file
let data = this.prepareData(type, state, fileName);
await this.bleManager.writeCharacteristic(this.audioServiceUUID, this.audioCharUUID, data);
await this.bleManager.writeCharacteristic(
SERVICES.AUDIO_SERVICE.UUID,
SERVICES.AUDIO_SERVICE.CHARACTERISTICS.AUDIO_CONTROL_CHARACTERISTIC.UUID,
data
);
} catch (error) {
log("Error writing wavFile data: " + error, "ERROR");
}
Expand All @@ -585,7 +628,11 @@ class AudioPlayer {
let freqBytes = new Float32Array([frequency]);
data.set(new Uint8Array(freqBytes.buffer), 3);

await this.bleManager.writeCharacteristic(this.audioServiceUUID, this.audioCharUUID, data);
await this.bleManager.writeCharacteristic(
SERVICES.AUDIO_SERVICE.UUID,
SERVICES.AUDIO_SERVICE.CHARACTERISTICS.AUDIO_CONTROL_CHARACTERISTIC.UUID,
data
);
} catch (error) {
log("Error writing frequency data: " + error, "ERROR");
}
Expand All @@ -601,7 +648,11 @@ class AudioPlayer {
try {
let type = 3; // 3 indicates it's a jingle
let data = this.prepareData(type, state, jingleName);
await this.bleManager.writeCharacteristic(this.audioServiceUUID, this.audioCharUUID, data);
await this.bleManager.writeCharacteristic(
SERVICES.AUDIO_SERVICE.UUID,
SERVICES.AUDIO_SERVICE.CHARACTERISTICS.AUDIO_CONTROL_CHARACTERISTIC.UUID,
data
);
} catch (error) {
log("Error writing jingle data: " + error, "ERROR");
}
Expand Down
12 changes: 6 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,19 +372,19 @@ <h5 class="card-title">RGB LED Control</h5>
</p>
<div class="d-flex flex-column justify-content-between align-items-stretch flex-fill">
<div class="d-flex flex-row justify-content-stretch">
<input class="is-connect-enabled w-100 align-self-stretch" type="color" id="colorpicker"
<input disabled class="is-connect-enabled w-100 align-self-stretch" type="color" id="colorpicker"
value="#ffffff">
<input class="ms-2 is-connect-enabled" id="colorInput">
<input disabled class="ms-2 is-connect-enabled" id="colorInput">
</div>

<button class="btn btn-control is-connect-enabled mt-2" onclick="onSetColor()">Set
<button disabled class="btn btn-control is-connect-enabled mt-2" onclick="onSetColor()">Set
</button>

<hr />
<div class="d-flex flex-row">
<button class="btn btn-control flex-fill is-connect-enabled"
<button disabled class="btn btn-control flex-fill is-connect-enabled"
onclick="startRainbowMode()">🦄</button>
<button onclick="onTurnOffLed()"
<button disabled onclick="onTurnOffLed()"
class="btn btn-stop is-connect-enabled flex-fill ms-2">Off</button>
</div>
</div>
Expand Down Expand Up @@ -546,7 +546,7 @@ <h5 class="card-title">Recorder</h5>
<div class="d-flex flex-row mt-2">
<div class="d-flex flex-row justify-content-between align-items-center flex-fill">
<button id="startRecordingButton"
class="btn btn-play is-connect-enabled w-100">Start
class="btn btn-play is-connect-enabled w-100" disabled>Start
Recording</button>
<button id="stopRecordingButton"
class="btn btn-stop is-connect-enabled w-100 d-none">Stop
Expand Down

0 comments on commit be29c17

Please sign in to comment.