mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Polar H10: Add configuration settings
This commit is contained in:
+5
@@ -575,6 +575,11 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_SONY_ADAPTIVE_VOLUME_CONTROL = "pref_adaptive_volume_control";
|
||||
public static final String PREF_SONY_WIDE_AREA_TAP = "pref_wide_area_tap";
|
||||
|
||||
public static final String PREF_GYMLINK_ENABLED = "gymlink_enabled";
|
||||
public static final String PREF_ANTPLUS_ENABLED = "antplus_enabled";
|
||||
public static final String PREF_HR_BROADCAST = "hr_broadcast";
|
||||
public static final String PREF_DUAL_CONNECTION = "dual_connection";
|
||||
|
||||
public static final String PREF_MEDIA_SOURCE = "pref_media_source";
|
||||
public static final String PREF_MEDIA_PLAYBACK_MODE = "pref_media_playback_mode";
|
||||
public static final String PREF_SHOKZ_EQUALIZER_BLUETOOTH = "pref_shokz_equalizer_bluetooth";
|
||||
|
||||
+5
@@ -857,6 +857,11 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
||||
addPreferenceHandlerFor(PREF_SONY_ADAPTIVE_VOLUME_CONTROL);
|
||||
addPreferenceHandlerFor(PREF_SONY_WIDE_AREA_TAP);
|
||||
|
||||
addPreferenceHandlerFor(PREF_GYMLINK_ENABLED);
|
||||
addPreferenceHandlerFor(PREF_ANTPLUS_ENABLED);
|
||||
addPreferenceHandlerFor(PREF_HR_BROADCAST);
|
||||
addPreferenceHandlerFor(PREF_DUAL_CONNECTION);
|
||||
|
||||
addPreferenceHandlerFor(PREF_MEDIA_SOURCE);
|
||||
addPreferenceHandlerFor(PREF_MEDIA_PLAYBACK_MODE);
|
||||
addPreferenceHandlerFor(PREF_SHOKZ_EQUALIZER_BLUETOOTH);
|
||||
|
||||
+9
@@ -3,6 +3,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.polar;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class PolarH10DeviceCoordinator extends AbstractPolarDeviceCoordinator {
|
||||
@Override
|
||||
@@ -14,4 +16,11 @@ public class PolarH10DeviceCoordinator extends AbstractPolarDeviceCoordinator {
|
||||
protected Pattern getSupportedDeviceName() {
|
||||
return Pattern.compile("^Polar H10.*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_polar);
|
||||
return deviceSpecificSettings;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -597,6 +597,7 @@ public class BleNamesResolver {
|
||||
mServices.put("000056ff-0000-1000-8000-00805f9b34fb", "(Propr: GloryFit Data");
|
||||
mServices.put("af9df7a1-e595-11e3-96b4-0002a5d5c51b", "(Propr: OneTouch");
|
||||
mServices.put("9b012401-bc30-ce9a-e111-0f67e491abde", "(Propr: Garmin GFDI V0)");
|
||||
mServices.put("6217ff4b-fb31-1140-ad5a-a45545d7ecf3", "(Propr: Polar Settings)");
|
||||
mServices.put("6a4e2401-667b-11e3-949a-0800200c9a66", "(Propr: Garmin GFDI V1)");
|
||||
mServices.put("6a4e2800-667b-11e3-949a-0800200c9a66", "(Propr: Garmin ML)");
|
||||
mServices.put("86f61000-f706-58a0-95b2-1fb9261e4dc7", "(Propr: Ultrahuman State)");
|
||||
@@ -1194,6 +1195,7 @@ public class BleNamesResolver {
|
||||
mCharacteristics.put("86f65002-f706-58a0-95b2-1fb9261e4dc7", "(Propr: Ultrahuman Response)");
|
||||
mCharacteristics.put("86f66001-f706-58a0-95b2-1fb9261e4dc7", "(Propr: Ultrahuman Data)");
|
||||
mCharacteristics.put("da2e7828-fbce-4e01-ae9e-261174997c48", "(Propr: SMP - Simple Management Protocol)");
|
||||
mCharacteristics.put("6217ff4d-91bb-91d0-7e2a-7cd3bda8a1f3", "(Propr: Polar Settings)");
|
||||
mCharacteristics.put("6e400002-b5a3-f393-e0a9-e50e24dcca9e", "(Propr: Nordic UART TX)");
|
||||
mCharacteristics.put("6e400003-b5a3-f393-e0a9-e50e24dcca9e", "(Propr: Nordic UART RX)");
|
||||
mCharacteristics.put("de5bf729-d711-4e47-af26-65e3012a5dc7", "(Propr: Yawell Notify)");
|
||||
|
||||
+121
@@ -1,5 +1,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.polar;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ANTPLUS_ENABLED;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DUAL_CONNECTION;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GYMLINK_ENABLED;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HR_BROADCAST;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
@@ -18,6 +23,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.HeartRrIntervalSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.polar.PolarH10ActivitySampleProvider;
|
||||
@@ -50,12 +56,26 @@ public class PolarH10DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
public static final UUID UUID_SERVICE_HEART_RATE = GattService.UUID_SERVICE_HEART_RATE;
|
||||
public static final UUID UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT = GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT;
|
||||
|
||||
public static final UUID UUID_SERVICE_POLAR_SETTINGS = UUID.fromString("6217ff4b-fb31-1140-ad5a-a45545d7ecf3");
|
||||
public static final UUID UUID_CHARACTERISTIC_POLAR_SETTINGS = UUID.fromString("6217ff4d-91bb-91d0-7e2a-7cd3bda8a1f3");
|
||||
|
||||
public static final byte CMD_HR_BROADCAST_SET = (byte) 0x01;
|
||||
public static final byte CMD_HR_BROADCAST_GET = (byte) 0x02;
|
||||
public static final byte CMD_GYM_LINK_SET = (byte) 0x03;
|
||||
public static final byte CMD_GYM_LINK_GET = (byte) 0x04;
|
||||
public static final byte CMD_DUAL_CONNECTION_SET = (byte) 0x08;
|
||||
public static final byte CMD_DUAL_CONNECTION_GET = (byte) 0x09;
|
||||
public static final byte CMD_ANT_SET = (byte) 0x0a;
|
||||
public static final byte CMD_ANT_GET = (byte) 0x0b;
|
||||
public static final byte CMD_RESPONSE = (byte) 0xf0;
|
||||
|
||||
public PolarH10DeviceSupport() {
|
||||
super(LOG);
|
||||
|
||||
addSupportedService(UUID_SERVICE_DEVICE_INFORMATION);
|
||||
addSupportedService(UUID_SERVICE_BATTERY_SERVICE);
|
||||
addSupportedService(UUID_SERVICE_HEART_RATE);
|
||||
addSupportedService(UUID_SERVICE_POLAR_SETTINGS);
|
||||
|
||||
IntentListener mListener = intent -> {
|
||||
String action = intent.getAction();
|
||||
@@ -101,6 +121,12 @@ public class PolarH10DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
|
||||
heartRateProfile.enableNotify(builder, true);
|
||||
|
||||
builder.notify(UUID_CHARACTERISTIC_POLAR_SETTINGS, true);
|
||||
builder.write(UUID_CHARACTERISTIC_POLAR_SETTINGS, CMD_HR_BROADCAST_GET);
|
||||
builder.write(UUID_CHARACTERISTIC_POLAR_SETTINGS, CMD_GYM_LINK_GET);
|
||||
builder.write(UUID_CHARACTERISTIC_POLAR_SETTINGS, CMD_DUAL_CONNECTION_GET);
|
||||
builder.write(UUID_CHARACTERISTIC_POLAR_SETTINGS, CMD_ANT_GET);
|
||||
|
||||
// Set defaults
|
||||
getDevice().setFirmwareVersion("N/A");
|
||||
getDevice().setFirmwareVersion2("N/A");
|
||||
@@ -142,11 +168,106 @@ public class PolarH10DeviceSupport extends AbstractBTLESingleDeviceSupport {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UUID_CHARACTERISTIC_POLAR_SETTINGS.equals(characteristic.getUuid())) {
|
||||
handlePolarSetting(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG.warn("Unhandled characteristic change: {} = {}", characteristic.getUuid(), GB.hexdump(value));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendConfiguration(final String config) {
|
||||
final byte preferenceCommand;
|
||||
final boolean preferenceValue;
|
||||
|
||||
switch (config) {
|
||||
case PREF_GYMLINK_ENABLED:
|
||||
preferenceCommand = CMD_GYM_LINK_SET;
|
||||
preferenceValue = getDevicePrefs().getBoolean(config, false);
|
||||
break;
|
||||
case PREF_ANTPLUS_ENABLED:
|
||||
preferenceCommand = CMD_ANT_SET;
|
||||
preferenceValue = getDevicePrefs().getBoolean(config, false);
|
||||
break;
|
||||
case PREF_HR_BROADCAST:
|
||||
preferenceCommand = CMD_HR_BROADCAST_SET;
|
||||
preferenceValue = getDevicePrefs().getBoolean(config, false);
|
||||
break;
|
||||
case PREF_DUAL_CONNECTION:
|
||||
preferenceCommand = CMD_DUAL_CONNECTION_SET;
|
||||
preferenceValue = getDevicePrefs().getBoolean(config, false);
|
||||
break;
|
||||
default:
|
||||
super.onSendConfiguration(config);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug("Setting {} = {}", config, preferenceValue);
|
||||
|
||||
final TransactionBuilder builder = createTransactionBuilder("set " + config + " = " + preferenceValue);
|
||||
builder.write(UUID_CHARACTERISTIC_POLAR_SETTINGS, preferenceCommand, (byte) (preferenceValue ? 1 : 0));
|
||||
builder.queue();
|
||||
}
|
||||
|
||||
private void handlePolarSetting(final byte[] value) {
|
||||
if (value[0] != CMD_RESPONSE) {
|
||||
LOG.warn("Unexpected first byte {}", String.format("0x%02x", value[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value[1]) {
|
||||
case CMD_HR_BROADCAST_SET:
|
||||
LOG.debug("HR broadcast set response, success = {}", value[2]);
|
||||
break;
|
||||
case CMD_HR_BROADCAST_GET:
|
||||
if (value[2] != 0x01) {
|
||||
LOG.warn("HR broadcast get failed, status = {}", String.format("0x%02x", value[2]));
|
||||
return;
|
||||
}
|
||||
LOG.debug("Got HR broadcast setting, value = {}", value[3] != 0);
|
||||
evaluateGBDeviceEvent(new GBDeviceEventUpdatePreferences(PREF_HR_BROADCAST, value[3] != 0));
|
||||
break;
|
||||
case CMD_GYM_LINK_SET:
|
||||
LOG.debug("GymLink set response, success = {}", value[2]);
|
||||
break;
|
||||
case CMD_GYM_LINK_GET:
|
||||
if (value[2] != 0x01) {
|
||||
LOG.warn("GymLink get failed, status = {}", String.format("0x%02x", value[2]));
|
||||
return;
|
||||
}
|
||||
LOG.debug("Got GymLink setting, value = {}", value[3] != 0);
|
||||
evaluateGBDeviceEvent(new GBDeviceEventUpdatePreferences(PREF_GYMLINK_ENABLED, value[3] != 0));
|
||||
break;
|
||||
case CMD_DUAL_CONNECTION_SET:
|
||||
LOG.debug("Dual connection set response, success = {}", value[2]);
|
||||
break;
|
||||
case CMD_DUAL_CONNECTION_GET:
|
||||
if (value[2] != 0x01) {
|
||||
LOG.warn("Dual connection get failed, status = {}", String.format("0x%02x", value[2]));
|
||||
return;
|
||||
}
|
||||
LOG.debug("Got dual connection setting, value = {}", value[3] != 0);
|
||||
evaluateGBDeviceEvent(new GBDeviceEventUpdatePreferences(PREF_DUAL_CONNECTION, value[3] != 0));
|
||||
break;
|
||||
case CMD_ANT_SET:
|
||||
LOG.debug("ANT+ set response, success = {}", value[2]);
|
||||
break;
|
||||
case CMD_ANT_GET:
|
||||
if (value[2] != 0x01) {
|
||||
LOG.warn("ANT+ get failed, status = {}", String.format("0x%02x", value[2]));
|
||||
return;
|
||||
}
|
||||
LOG.debug("Got ANT+ setting, value = {}", value[3] != 0);
|
||||
evaluateGBDeviceEvent(new GBDeviceEventUpdatePreferences(PREF_ANTPLUS_ENABLED, value[3] != 0));
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unknown response byte: {}", String.format("0x%02x", value[1]));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeviceInfo(nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo info) {
|
||||
LOG.warn("Device info: {}", info);
|
||||
|
||||
|
||||
@@ -4769,4 +4769,12 @@
|
||||
<string name="qhybrid_button_function_step_goal">Step goal progress</string>
|
||||
<string name="qhybrid_button_function_control_music">Control music player</string>
|
||||
<string name="qhybrid_button_function_ring_phone">Ring phone</string>
|
||||
<string name="gymlink_title">GymLink</string>
|
||||
<string name="gymlink_summary">Allow GymLink-compatible equipment to connect to the device.</string>
|
||||
<string name="antplus_title">ANT+</string>
|
||||
<string name="antplus_summary">Nearby compatible ANT+ devices can pick up your heart rate.</string>
|
||||
<string name="broadcast_heart_rate_title">Broadcast heart rate</string>
|
||||
<string name="broadcast_heart_rate_summary">Any nearby device or app can pick up your heart rate.</string>
|
||||
<string name="dual_connection_title">Dual connection</string>
|
||||
<string name="dual_connection_summary">Allow two apps or devices to connect simultaneously.</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="gymlink_enabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/gymlink_summary"
|
||||
android:title="@string/gymlink_title" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="antplus_enabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/antplus_summary"
|
||||
android:title="@string/antplus_title" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="hr_broadcast"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/broadcast_heart_rate_summary"
|
||||
android:title="@string/broadcast_heart_rate_title" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="dual_connection"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/dual_connection_summary"
|
||||
android:title="@string/dual_connection_title" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
Reference in New Issue
Block a user