diff --git a/.idea/dictionaries/t.xml b/.idea/dictionaries/t.xml
index edd0e1afa7..62cfa2e832 100644
--- a/.idea/dictionaries/t.xml
+++ b/.idea/dictionaries/t.xml
@@ -31,6 +31,7 @@
chamorro
codeberg
colmi
+ coospo
criogenic
croisez
dakhno
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoH6Coordinator.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoH6Coordinator.kt
index 3b717c6ba4..0e006197d8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoH6Coordinator.kt
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoH6Coordinator.kt
@@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices.coospo
import nodomain.freeyourgadget.gadgetbridge.R
import java.util.regex.Pattern
+/// #5025
class CoospoH6Coordinator: CoospoHeartRateCoordinator() {
override fun getSupportedDeviceName(): Pattern? {
return Pattern.compile("^H6M [0-9]{5}$")
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoHW9Coordinator.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoHW9Coordinator.kt
index b1e17531a9..21cf0fbf98 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoHW9Coordinator.kt
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/coospo/CoospoHW9Coordinator.kt
@@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices.coospo
import nodomain.freeyourgadget.gadgetbridge.R
import java.util.regex.Pattern
+/// #5110
class CoospoHW9Coordinator: CoospoHeartRateCoordinator() {
override fun getSupportedDeviceName(): Pattern? {
return Pattern.compile("^HW9 [0-9]{5}$")
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrm200Coordinator.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrm200Coordinator.kt
new file mode 100644
index 0000000000..22261df44b
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrm200Coordinator.kt
@@ -0,0 +1,15 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.garmin.hrm
+
+import nodomain.freeyourgadget.gadgetbridge.R
+import java.util.regex.Pattern
+
+/// #5110
+class GarminHrm200Coordinator: GarminHrmCoordinator() {
+ override fun getSupportedDeviceName(): Pattern? {
+ return Pattern.compile("^HRM 200$")
+ }
+
+ override fun getDeviceNameResource(): Int {
+ return R.string.devicetype_garmin_hrm_200
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrmCoordinator.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrmCoordinator.kt
new file mode 100644
index 0000000000..e0a2faf322
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/hrm/GarminHrmCoordinator.kt
@@ -0,0 +1,81 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.garmin.hrm
+
+import de.greenrobot.dao.AbstractDao
+import de.greenrobot.dao.Property
+import nodomain.freeyourgadget.gadgetbridge.R
+import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator
+import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider
+import nodomain.freeyourgadget.gadgetbridge.devices.generic_hr.GenericHeartRateActivitySampleProvider
+import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample
+import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession
+import nodomain.freeyourgadget.gadgetbridge.entities.GenericHeartRateSampleDao
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
+import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport
+import nodomain.freeyourgadget.gadgetbridge.service.devices.generic_hr.GenericHeartRateSupport
+
+/**
+ * This class pulls most of the logic from the
+ * {@link nodomain.freeyourgadget.gadgetbridge.devices.generic_hr.GenericHeartRateCoordinator}.
+ */
+abstract class GarminHrmCoordinator: AbstractBLEDeviceCoordinator() {
+ override fun isExperimental(): Boolean {
+ return true
+ }
+
+ override fun getBondingStyle(): Int {
+ return BONDING_STYLE_NONE
+ }
+
+ override fun suggestUnbindBeforePair(): Boolean {
+ // Not needed
+ return false
+ }
+
+ override fun getManufacturer(): String {
+ return "Garmin"
+ }
+
+ override fun getDeviceSupportClass(device: GBDevice?): Class {
+ return GenericHeartRateSupport::class.java
+ }
+
+ override fun getDefaultIconResource(): Int {
+ return R.drawable.ic_device_lovetoy
+ }
+
+ override fun supportsHeartRateMeasurement(device: GBDevice): Boolean {
+ return true
+ }
+
+ override fun supportsActivityTracking(): Boolean {
+ return true
+ }
+
+ override fun supportsActivityTabs(): Boolean {
+ return false
+ }
+
+ override fun supportsSleepMeasurement(): Boolean {
+ return false
+ }
+
+ override fun supportsStepCounter(): Boolean {
+ return false
+ }
+
+ override fun supportsSpeedzones(): Boolean {
+ return false
+ }
+
+ override fun getSampleProvider(device: GBDevice, session: DaoSession): SampleProvider? {
+ return GenericHeartRateActivitySampleProvider(device, session)
+ }
+
+ override fun getAllDeviceDao(session: DaoSession): MutableMap, Property> {
+ return object : HashMap, Property>() {
+ init {
+ put(session.genericHeartRateSampleDao, GenericHeartRateSampleDao.Properties.DeviceId)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
index 844c8803c1..f55668bbd9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsProDev
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.bike.GarminEdge130PlusCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.bike.GarminEdgeExplore2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.gps.GarminETrexSeCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.garmin.hrm.GarminHrm200Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.watches.descent.GarminDescentMk3Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.watches.enduro.GarminEnduro3Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.watches.epix.GarminEpixProCoordinator;
@@ -540,6 +541,7 @@ public enum DeviceType {
IKEA_IDASEN(IdasenCoordinator.class),
NUTMINI(NutCoordinator.class),
VIVOMOVE_HR(GarminVivomoveHrCoordinator.class),
+ GARMIN_HRM_200(GarminHrm200Coordinator.class),
GARMIN_EDGE_130_PLUS(GarminEdge130PlusCoordinator.class),
GARMIN_EDGE_EXPLORE_2(GarminEdgeExplore2Coordinator.class),
GARMIN_ETREX_SE(GarminETrexSeCoordinator.class),
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e423f15a72..b58de9dc34 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2107,6 +2107,7 @@
Heart Rate Sensor
Coospo H6
Coospo HW9
+ Garmin HRM 200
Nothing
Status