Experimental support for Amazfit Active 3 Premium, Cheetah 2 Pro, T-Rex Ultra 2

This commit is contained in:
José Rebelo
2026-05-10 15:48:18 +01:00
parent 44d5992ba9
commit cbe4226a76
10 changed files with 300 additions and 3 deletions
@@ -661,7 +661,7 @@ public abstract class ZeppOsCoordinator extends HuamiCoordinator {
}
public boolean supportsFtpServer(final GBDevice device) {
return false;
return supportsWifiHotspot(device);
}
public boolean hasGps(final GBDevice device) {
@@ -0,0 +1,94 @@
/* Copyright (C) 2026 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class AmazfitActive3PremiumCoordinator extends ZeppOsCoordinator {
@Override
public boolean isExperimental() {
return true;
}
@Override
public ConnectionType getConnectionType() {
return ConnectionType.BOTH;
}
@Override
public List<String> getDeviceBluetoothNames() {
// never seen, assumptions
return Arrays.asList(
"Amazfit Active 3 Premium",
"Active 3 Premium"
);
}
@Override
public Set<Integer> getDeviceSources() {
return new HashSet<>(Arrays.asList(
10944768, // chinese mainland version
10944769,
10944771,
10948867
));
}
@Override
public int getDeviceNameResource() {
return R.string.devicetype_amazfit_active_3_premium;
}
@Override
public boolean mainMenuHasMoreSection() {
return false;
}
@Override
public boolean supportsControlCenter() {
return true;
}
@Override
public boolean supportsToDoList() {
return true;
}
@Override
public boolean supportsWifiHotspot(final GBDevice device) {
return true;
}
@Override
public boolean supportsBluetoothPhoneCalls(final GBDevice device) {
return true;
}
@Override
public DeviceKind getDeviceKind(@NonNull GBDevice device) {
return DeviceKind.WATCH;
}
}
@@ -0,0 +1,93 @@
/* Copyright (C) 2026 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class AmazfitCheetah2ProCoordinator extends ZeppOsCoordinator {
@Override
public boolean isExperimental() {
return true;
}
@Override
public ConnectionType getConnectionType() {
return ConnectionType.BOTH;
}
@Override
public List<String> getDeviceBluetoothNames() {
// never seen, assumption
return Arrays.asList(
"Amazfit Cheetah 2 Pro",
"Cheetah 2 Pro"
);
}
@Override
public Set<Integer> getDeviceSources() {
return new HashSet<>(Arrays.asList(
11010304, // chinese mainland version
11010305,
11010307
));
}
@Override
public int getDeviceNameResource() {
return R.string.devicetype_amazfit_cheetah_2_pro;
}
@Override
public boolean mainMenuHasMoreSection() {
return false;
}
@Override
public boolean supportsControlCenter() {
return true;
}
@Override
public boolean supportsToDoList() {
return true;
}
@Override
public boolean supportsWifiHotspot(final GBDevice device) {
return true;
}
@Override
public boolean supportsBluetoothPhoneCalls(final GBDevice device) {
return true;
}
@Override
public DeviceKind getDeviceKind(@NonNull GBDevice device) {
return DeviceKind.WATCH;
}
}
@@ -0,0 +1,83 @@
/* Copyright (C) 2026 José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches;
import androidx.annotation.NonNull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class AmazfitTRexUltra2Coordinator extends ZeppOsCoordinator {
@Override
public boolean isExperimental() {
return true;
}
@Override
public List<String> getDeviceBluetoothNames() {
// never seen, assumptions
return Arrays.asList(
"Amazfit T-Rex Ultra 2",
"T-Rex Ultra 2"
);
}
@Override
public Set<Integer> getDeviceSources() {
return new HashSet<>(Arrays.asList(
10879232, // chinese mainland version
10879233,
10879235
));
}
@Override
public int getDeviceNameResource() {
return R.string.devicetype_amazfit_trex_ultra_2;
}
@Override
public boolean supportsControlCenter() {
return true;
}
@Override
public boolean supportsToDoList() {
return true;
}
@Override
public boolean supportsWifiHotspot(final GBDevice device) {
return true;
}
@Override
public boolean supportsBluetoothPhoneCalls(final GBDevice device) {
return true;
}
@Override
public DeviceKind getDeviceKind(@NonNull GBDevice device) {
return DeviceKind.WATCH;
}
}
@@ -237,6 +237,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.straps.AmazfitH
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActive2RoundCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActive2NfcCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActive2SquareCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActive3PremiumCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActiveCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActiveEdgeCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitActiveMaxCoordinator;
@@ -247,6 +248,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.Amazfit
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitBip5Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitBip5UnityCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitBip6Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitCheetah2ProCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitCheetahProCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitCheetahRoundCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitCheetahSquareCoordinator;
@@ -263,6 +265,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.Amazfit
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitTRex3Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitTRex3Pro44mmCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitTRex3Pro48mmCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitTRexUltra2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.AmazfitTRexUltraCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.watches.MiBand7Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.freearc.HuaweiFreearcCoordinator;
@@ -572,12 +575,14 @@ public enum DeviceType {
AMAZFITBIP3(AmazfitBip3Coordinator.class),
AMAZFITBIP3PRO(AmazfitBip3ProCoordinator.class),
AMAZFITCHEETAHPRO(AmazfitCheetahProCoordinator.class),
AMAZFITCHEETAH2PRO(AmazfitCheetah2ProCoordinator.class),
AMAZFITCHEETAHSQUARE(AmazfitCheetahSquareCoordinator.class),
AMAZFITCHEETAHROUND(AmazfitCheetahRoundCoordinator.class),
AMAZFITBIP5(AmazfitBip5Coordinator.class),
AMAZFITBIP5UNITY(AmazfitBip5UnityCoordinator.class),
AMAZFITBIP6(AmazfitBip6Coordinator.class),
AMAZFITTREXULTRA(AmazfitTRexUltraCoordinator.class),
AMAZFITTREXULTRA2(AmazfitTRexUltra2Coordinator.class),
AMAZFITGTRMINI(AmazfitGTRMiniCoordinator.class),
AMAZFITFALCON(AmazfitFalconCoordinator.class),
AMAZFITBALANCE(AmazfitBalanceCoordinator.class),
@@ -587,6 +592,7 @@ public enum DeviceType {
AMAZFITACTIVE2(AmazfitActive2RoundCoordinator.class),
AMAZFITACTIVE2NFC(AmazfitActive2NfcCoordinator.class),
AMAZFITACTIVE2SQUARE(AmazfitActive2SquareCoordinator.class),
AMAZFITACTIVE3PREMIUM(AmazfitActive3PremiumCoordinator.class),
AMAZFITACTIVEEDGE(AmazfitActiveEdgeCoordinator.class),
AMAZFITACTIVEMAX(AmazfitActiveMaxCoordinator.class),
AMAZFITHELIORING(AmazfitHelioRingCoordinator.class),
@@ -1,7 +1,8 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos
object ZeppOsDeviceSources {
// jq '.[] | [.value.productId, .value.productVersion, .deviceSource] | @csv' -r devices.json
// jq '.[] | [.value.productId, .value.productVersion, .deviceSource] | @csv' -r devices.json | \
// sed 's/,/, /g; s/^/ZeppOsDeviceInfo(/; s/$/),/'
// TODO: A few are missing: mi band 7, amazfit band 7, amazfit gtr mini
val DEVICE_SOURCES = listOf(
ZeppOsDeviceInfo(94, 256, 224),
@@ -15,6 +16,13 @@ object ZeppOsDeviceSources {
ZeppOsDeviceInfo(115, 259, 247),
ZeppOsDeviceInfo(116, 257, 251),
ZeppOsDeviceInfo(117, 259, 254),
ZeppOsDeviceInfo(103, 256, 260),
ZeppOsDeviceInfo(103, 257, 261),
ZeppOsDeviceInfo(103, 258, 262),
ZeppOsDeviceInfo(103, 259, 263),
ZeppOsDeviceInfo(103, 260, 264),
ZeppOsDeviceInfo(103, 261, 265),
ZeppOsDeviceInfo(103, 262, 266),
ZeppOsDeviceInfo(63, 256, 414),
ZeppOsDeviceInfo(63, 257, 415),
ZeppOsDeviceInfo(113, 256, 418),
@@ -22,6 +30,7 @@ object ZeppOsDeviceSources {
ZeppOsDeviceInfo(93, 258, 6095106),
ZeppOsDeviceInfo(100, 256, 6553856),
ZeppOsDeviceInfo(100, 257, 6553857),
ZeppOsDeviceInfo(103, 263, 6750471),
ZeppOsDeviceInfo(120, 257, 7864577),
ZeppOsDeviceInfo(121, 256, 7930112),
ZeppOsDeviceInfo(121, 257, 7930113),
@@ -82,6 +91,13 @@ object ZeppOsDeviceSources {
ZeppOsDeviceInfo(163, 259, 10682627),
ZeppOsDeviceInfo(165, 257, 10813697),
ZeppOsDeviceInfo(165, 259, 10813699),
ZeppOsDeviceInfo(166, 256, 10879232),
ZeppOsDeviceInfo(166, 257, 10879233),
ZeppOsDeviceInfo(166, 259, 10879235),
ZeppOsDeviceInfo(167, 256, 10944768),
ZeppOsDeviceInfo(167, 257, 10944769),
ZeppOsDeviceInfo(167, 259, 10944771),
ZeppOsDeviceInfo(167, 4355, 10948867),
)
fun resolve(productId: Int, productVersion: Int): ZeppOsDeviceInfo? {
+3
View File
@@ -1907,10 +1907,12 @@
<string name="devicetype_amazfit_active_2_round" translatable="false">Amazfit Active 2 (Round)</string>
<string name="devicetype_amazfit_active_2_square" translatable="false">Amazfit Active 2 (Square)</string>
<string name="devicetype_amazfit_active_2_nfc" translatable="false">Amazfit Active 2 NFC</string>
<string name="devicetype_amazfit_active_3_premium" translatable="false">Amazfit Active 3 Premium</string>
<string name="devicetype_amazfit_active_edge" translatable="false">Amazfit Active Edge</string>
<string name="devicetype_amazfit_cheetah_square" translatable="false">Amazfit Cheetah (Square)</string>
<string name="devicetype_amazfit_cheetah_round" translatable="false">Amazfit Cheetah (Round)</string>
<string name="devicetype_amazfit_cheetah_pro" translatable="false">Amazfit Cheetah Pro</string>
<string name="devicetype_amazfit_cheetah_2_pro" translatable="false">Amazfit Cheetah 2 Pro</string>
<string name="devicetype_amazfit_gts3" translatable="false">Amazfit GTS 3</string>
<string name="devicetype_amazfit_gts4" translatable="false">Amazfit GTS 4</string>
<string name="devicetype_amazfit_gts4_mini" translatable="false">Amazfit GTS 4 Mini</string>
@@ -1929,6 +1931,7 @@
<string name="devicetype_amazfit_trex_3_pro_44mm" translatable="false">Amazfit T-Rex 3 Pro (44mm)</string>
<string name="devicetype_amazfit_trex_3_pro_48mm" translatable="false">Amazfit T-Rex 3 Pro (48mm)</string>
<string name="devicetype_amazfit_trex_ultra" translatable="false">Amazfit T-Rex Ultra</string>
<string name="devicetype_amazfit_trex_ultra_2" translatable="false">Amazfit T-Rex Ultra 2</string>
<string name="devicetype_amazfit_band5" translatable="false">Amazfit Band 5</string>
<string name="devicetype_amazfit_band7" translatable="false">Amazfit Band 7</string>
<string name="devicetype_amazfit_neo" translatable="false">Amazfit Neo</string>
@@ -10,6 +10,7 @@
<change>Initial support for Redmi Buds 8 Active</change>
<change>Initial support for iTECH Active 3 (MoYoung / Da Fit)</change>
<change>Initial support for ZL02D (MoYoung / Da Fit)</change>
<change>Experimental support for Amazfit Active 3 Premium, Cheetah 2 Pro, T-Rex Ultra 2</change>
<change>Experimental support for Sony WH-1000XM6</change>
<change>Add and adjust default sleep range to 18:00</change>
<change>Add auto export of gpx files</change>