From b5357841171e1417a54926200da8fa0e24ec1f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Fri, 22 Dec 2023 12:35:33 +0000 Subject: [PATCH] Mijia LYWSD03MMC: Initial support Same protocol as LYWSD02, but does not support setting the time. --- README.md | 1 + .../AbstractMijiaLywsdCoordinator.java | 74 +++++++++++++++++++ .../mijia_lywsd/MijiaLywsd02Coordinator.java | 59 ++------------- .../mijia_lywsd/MijiaLywsd03Coordinator.java | 49 ++++++++++++ .../gadgetbridge/model/DeviceType.java | 2 + .../mijia_lywsd/MijiaLywsdSupport.java | 8 +- app/src/main/res/values/strings.xml | 1 + 7 files changed, 141 insertions(+), 53 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/AbstractMijiaLywsdCoordinator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd03Coordinator.java diff --git a/README.md b/README.md index f0d4d6156..9a014c42c 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ vendor's servers. - Redmi Watch 3 Active (experimental) [**\[!\]**](#special-pairing-procedures) - Watch S1 Active (experimental) [**\[!\]**](#special-pairing-procedures) - Xiaomi Temperature and Humidity Monitor Clock (LYWSD02/LYWSD02MMC) (partial support) + - Xiaomi Mijia Temperature and Humidity Sensor 2 (LYWSD03MMC) (partial support) - Scale 2 (Currently only displays a toast after stepping on the scale) - [MyKronoz ZeTime](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/MyKronoz-ZeTime) - NO.1 F1 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/AbstractMijiaLywsdCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/AbstractMijiaLywsdCoordinator.java new file mode 100644 index 000000000..59bc4d0a1 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/AbstractMijiaLywsdCoordinator.java @@ -0,0 +1,74 @@ +/* Copyright (C) 2016-2021 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, 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 . */ +package nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd; + +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.mijia_lywsd.MijiaLywsdSupport; + +public abstract class AbstractMijiaLywsdCoordinator extends AbstractBLEDeviceCoordinator { + @Override + public int getBondingStyle() { + return BONDING_STYLE_NONE; + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return false; + } + + @Override + public String getManufacturer() { + return "Xiaomi"; + } + + @NonNull + @Override + public Class getDeviceSupportClass() { + return MijiaLywsdSupport.class; + } + + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + return new int[]{ + R.xml.devicesettings_temperature_scale_cf, + }; + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) { + // nothing to delete, yet + } + + public abstract boolean supportsSetTime(); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd02Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd02Coordinator.java index 2e0f30281..36aabf498 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd02Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd02Coordinator.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2016-2021 Andreas Shimokawa, Carsten Pfeiffer, Daniele +/* Copyright (C) 2016-2023 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti, José Rebelo This file is part of Gadgetbridge. @@ -17,66 +17,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd; -import android.content.Context; -import android.net.Uri; - -import androidx.annotation.NonNull; - import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; -import nodomain.freeyourgadget.gadgetbridge.service.devices.mijia_lywsd.MijiaLywsdSupport; -public class MijiaLywsd02Coordinator extends AbstractBLEDeviceCoordinator { +public class MijiaLywsd02Coordinator extends AbstractMijiaLywsdCoordinator { @Override protected Pattern getSupportedDeviceName() { return Pattern.compile("LYWSD02|LYWSD02MMC"); } - @Override - public int getBondingStyle() { - return BONDING_STYLE_NONE; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public String getManufacturer() { - return "Xiaomi"; - } - - @NonNull - @Override - public Class getDeviceSupportClass() { - return MijiaLywsdSupport.class; - } - - @Override - public int[] getSupportedDeviceSpecificSettings(GBDevice device) { - return new int[]{ - R.xml.devicesettings_temperature_scale_cf, - }; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) { - // nothing to delete, yet - } - @Override public int getDeviceNameResource() { return R.string.devicetype_mijia_lywsd02; @@ -91,4 +41,9 @@ public class MijiaLywsd02Coordinator extends AbstractBLEDeviceCoordinator { public int getDisabledIconResource() { return R.drawable.ic_device_pebble_disabled; } + + @Override + public boolean supportsSetTime() { + return true; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd03Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd03Coordinator.java new file mode 100644 index 000000000..8b6faf0db --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/mijia_lywsd/MijiaLywsd03Coordinator.java @@ -0,0 +1,49 @@ +/* Copyright (C) 2016-2023 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, 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 . */ +package nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd; + +import java.util.regex.Pattern; + +import nodomain.freeyourgadget.gadgetbridge.R; + +public class MijiaLywsd03Coordinator extends AbstractMijiaLywsdCoordinator { + @Override + protected Pattern getSupportedDeviceName() { + return Pattern.compile("LYWSD03MMC"); + } + + @Override + public int getDeviceNameResource() { + return R.string.devicetype_mijia_lywsd03; + } + + @Override + public int getDefaultIconResource() { + return R.drawable.ic_device_thermometer; + } + + @Override + public int getDisabledIconResource() { + return R.drawable.ic_device_thermometer_disabled; + } + + @Override + public boolean supportsSetTime() { + return false; + } +} 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 455bb629a..d482e1a99 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -110,6 +110,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd.MijiaLywsd02Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd.MijiaLywsd03Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miscale2.MiScale2DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear1Coordinator; @@ -255,6 +256,7 @@ public enum DeviceType { TLW64(TLW64Coordinator.class), PINETIME_JF(PineTimeJFCoordinator.class), MIJIA_LYWSD02(MijiaLywsd02Coordinator.class), + MIJIA_LYWSD03(MijiaLywsd03Coordinator.class), LEFUN(LefunDeviceCoordinator.class), BOHEMIC_SMART_BRACELET(BohemicSmartBraceletDeviceCoordinator.class), SMAQ2OSS(SMAQ2OSSCoordinator.class), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd/MijiaLywsdSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd/MijiaLywsdSupport.java index db83af7ad..98a8176f7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd/MijiaLywsdSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/mijia_lywsd/MijiaLywsdSupport.java @@ -34,6 +34,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; +import nodomain.freeyourgadget.gadgetbridge.devices.mijia_lywsd.AbstractMijiaLywsdCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; @@ -80,7 +81,8 @@ public class MijiaLywsdSupport extends AbstractBTLEDeviceSupport { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); requestDeviceInfo(builder); - if (GBApplication.getPrefs().getBoolean("datetime_synconconnect", true)) { + final boolean supportsSetTime = getCoordinator().supportsSetTime(); + if (supportsSetTime && GBApplication.getPrefs().getBoolean("datetime_synconconnect", true)) { setTime(builder); } @@ -90,6 +92,10 @@ public class MijiaLywsdSupport extends AbstractBTLEDeviceSupport { return builder; } + protected AbstractMijiaLywsdCoordinator getCoordinator() { + return (AbstractMijiaLywsdCoordinator) gbDevice.getDeviceCoordinator(); + } + private void setTime(TransactionBuilder builder) { BluetoothGattCharacteristic timeCharacteristc = getCharacteristic(MijiaLywsdSupport.UUID_TIME); long ts = System.currentTimeMillis(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 47754acd3..aec63d525 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1400,6 +1400,7 @@ iTag BFH-16 Mijia Smart Clock + Mijia Temperature and Humidity Sensor 2 Makibes HR3 Bangle.js TLW64