mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-07-02 17:56:35 +02:00
Mi Band 8: Implement reminders
This commit is contained in:
parent
cca34af13b
commit
7124d337e1
|
@ -16,13 +16,17 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Reminder;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Reminder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,12 +65,25 @@ public class ConfigureReminders extends AbstractGBActivity {
|
||||||
private GBReminderListAdapter mGBReminderListAdapter;
|
private GBReminderListAdapter mGBReminderListAdapter;
|
||||||
private GBDevice gbDevice;
|
private GBDevice gbDevice;
|
||||||
|
|
||||||
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
|
if (DeviceService.ACTION_SAVE_REMINDERS.equals(intent.getAction())) {
|
||||||
|
updateRemindersFromDB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_configure_reminders);
|
setContentView(R.layout.activity_configure_reminders);
|
||||||
|
|
||||||
|
IntentFilter filterLocal = new IntentFilter();
|
||||||
|
filterLocal.addAction(DeviceService.ACTION_SAVE_REMINDERS);
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
|
||||||
|
|
||||||
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||||
|
|
||||||
mGBReminderListAdapter = new GBReminderListAdapter(this);
|
mGBReminderListAdapter = new GBReminderListAdapter(this);
|
||||||
|
@ -118,6 +135,12 @@ public class ConfigureReminders extends AbstractGBActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
|
@ -213,13 +213,13 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator {
|
||||||
@Override
|
@Override
|
||||||
public int getMaximumReminderMessageLength() {
|
public int getMaximumReminderMessageLength() {
|
||||||
// TODO does it?
|
// TODO does it?
|
||||||
return 0;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getReminderSlotCount(final GBDevice device) {
|
public int getReminderSlotCount(final GBDevice device) {
|
||||||
// TODO Does it?
|
// TODO fetch from watch
|
||||||
return 0;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -59,6 +59,7 @@ public interface DeviceService extends EventHandler {
|
||||||
String ACTION_SET_CONSTANT_VIBRATION = PREFIX + ".action.set_constant_vibration";
|
String ACTION_SET_CONSTANT_VIBRATION = PREFIX + ".action.set_constant_vibration";
|
||||||
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
||||||
String ACTION_SAVE_ALARMS = PREFIX + ".action.save_alarms";
|
String ACTION_SAVE_ALARMS = PREFIX + ".action.save_alarms";
|
||||||
|
String ACTION_SAVE_REMINDERS = PREFIX + ".action.save_reminders";
|
||||||
String ACTION_SET_REMINDERS = PREFIX + ".action.set_reminders";
|
String ACTION_SET_REMINDERS = PREFIX + ".action.set_reminders";
|
||||||
String ACTION_SET_LOYALTY_CARDS = PREFIX + ".action.set_loyalty_cards";
|
String ACTION_SET_LOYALTY_CARDS = PREFIX + ".action.set_loyalty_cards";
|
||||||
String ACTION_SET_WORLD_CLOCKS = PREFIX + ".action.set_world_clocks";
|
String ACTION_SET_WORLD_CLOCKS = PREFIX + ".action.set_world_clocks";
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
||||||
|
|
||||||
|
@ -42,6 +43,18 @@ public final class XiaomiPreferences {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Date toDate(final XiaomiProto.Date date, final XiaomiProto.Time time) {
|
||||||
|
// For some reason, the watch expects those in UTC...
|
||||||
|
// TODO double-check with official app, this does not make sense
|
||||||
|
final Calendar calendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
calendar.set(
|
||||||
|
date.getYear(), date.getMonth() - 1, date.getDay(),
|
||||||
|
time.getHour(), time.getMinute(), time.getSecond()
|
||||||
|
);
|
||||||
|
|
||||||
|
return calendar.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the preference key where to save the list of possible value for a preference, comma-separated.
|
* Returns the preference key where to save the list of possible value for a preference, comma-separated.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,14 +24,25 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Reminder;
|
import nodomain.freeyourgadget.gadgetbridge.model.Reminder;
|
||||||
|
@ -55,6 +66,10 @@ public class XiaomiScheduleService extends AbstractXiaomiService {
|
||||||
private static final int CMD_SLEEP_MODE_SET = 9;
|
private static final int CMD_SLEEP_MODE_SET = 9;
|
||||||
private static final int CMD_WORLD_CLOCKS_GET = 10;
|
private static final int CMD_WORLD_CLOCKS_GET = 10;
|
||||||
private static final int CMD_WORLD_CLOCKS_SET = 11;
|
private static final int CMD_WORLD_CLOCKS_SET = 11;
|
||||||
|
private static final int CMD_REMINDERS_GET = 14;
|
||||||
|
private static final int CMD_REMINDERS_CREATE = 15;
|
||||||
|
private static final int CMD_REMINDERS_EDIT = 17;
|
||||||
|
private static final int CMD_REMINDERS_DELETE = 18;
|
||||||
|
|
||||||
private static final int REPETITION_ONCE = 0;
|
private static final int REPETITION_ONCE = 0;
|
||||||
private static final int REPETITION_DAILY = 1;
|
private static final int REPETITION_DAILY = 1;
|
||||||
|
@ -65,17 +80,22 @@ public class XiaomiScheduleService extends AbstractXiaomiService {
|
||||||
private static final int ALARM_SMART = 1;
|
private static final int ALARM_SMART = 1;
|
||||||
private static final int ALARM_NORMAL = 2;
|
private static final int ALARM_NORMAL = 2;
|
||||||
|
|
||||||
|
// Reminders created by this service will have this prefix
|
||||||
|
private static final String REMINDER_DB_PREFIX = "xiaomi_";
|
||||||
|
|
||||||
private static final Map<String, String> WORLD_CLOCK_CODES = new HashMap<String, String>() {{
|
private static final Map<String, String> WORLD_CLOCK_CODES = new HashMap<String, String>() {{
|
||||||
put("Europe/Lisbon", "C173");
|
put("Europe/Lisbon", "C173");
|
||||||
put("Australia/Sydney", "C151");
|
put("Australia/Sydney", "C151");
|
||||||
// TODO map everything
|
// TODO map everything
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Map of alarm position to Alarm, as returned by the band, indexed by GB watch position (0-indexed),
|
// Map of alarm position to Alarm/Reminder, as returned by the watch, indexed by GB position (0-indexed),
|
||||||
// does NOT match watch ID
|
// does NOT match the ID returned by the watch, but should be offset by 1
|
||||||
private final Map<Integer, Alarm> watchAlarms = new HashMap<>();
|
private final Map<Integer, Alarm> watchAlarms = new HashMap<>();
|
||||||
|
private final Map<String, Reminder> watchReminders = new HashMap<>();
|
||||||
|
|
||||||
private int pendingAlarmAcks = 0;
|
private int pendingAlarmAcks = 0;
|
||||||
|
private int pendingReminderAcks = 0;
|
||||||
|
|
||||||
public XiaomiScheduleService(final XiaomiSupport support) {
|
public XiaomiScheduleService(final XiaomiSupport support) {
|
||||||
super(support);
|
super(support);
|
||||||
|
@ -101,12 +121,26 @@ public class XiaomiScheduleService extends AbstractXiaomiService {
|
||||||
case CMD_SLEEP_MODE_GET:
|
case CMD_SLEEP_MODE_GET:
|
||||||
handleSleepModeConfig(cmd.getSchedule().getSleepMode());
|
handleSleepModeConfig(cmd.getSchedule().getSleepMode());
|
||||||
break;
|
break;
|
||||||
|
case CMD_REMINDERS_GET:
|
||||||
|
handleReminders(cmd.getSchedule().getReminders());
|
||||||
|
break;
|
||||||
|
case CMD_REMINDERS_CREATE:
|
||||||
|
pendingReminderAcks--;
|
||||||
|
if (pendingReminderAcks <= 0) {
|
||||||
|
final TransactionBuilder builder = getSupport().createTransactionBuilder("request reminders after all acks");
|
||||||
|
requestReminders(builder);
|
||||||
|
builder.queue(getSupport().getQueue());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG.warn("Unknown schedule command {}", cmd.getSubtype());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(final TransactionBuilder builder) {
|
public void initialize(final TransactionBuilder builder) {
|
||||||
requestAlarms(builder);
|
requestAlarms(builder);
|
||||||
|
requestReminders(builder);
|
||||||
requestWorldClocks(builder);
|
requestWorldClocks(builder);
|
||||||
getSupport().sendCommand(builder, COMMAND_TYPE, CMD_SLEEP_MODE_GET);
|
getSupport().sendCommand(builder, COMMAND_TYPE, CMD_SLEEP_MODE_GET);
|
||||||
}
|
}
|
||||||
|
@ -126,8 +160,204 @@ public class XiaomiScheduleService extends AbstractXiaomiService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestReminders(final TransactionBuilder builder) {
|
||||||
|
getSupport().sendCommand(builder, COMMAND_TYPE, CMD_REMINDERS_GET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleReminders(final XiaomiProto.Reminders reminders) {
|
||||||
|
LOG.debug("Got {} reminders from the watch", reminders.getReminderCount());
|
||||||
|
|
||||||
|
watchReminders.clear();
|
||||||
|
for (final XiaomiProto.Reminder reminder : reminders.getReminderList()) {
|
||||||
|
final nodomain.freeyourgadget.gadgetbridge.entities.Reminder gbReminder = new nodomain.freeyourgadget.gadgetbridge.entities.Reminder();
|
||||||
|
gbReminder.setReminderId(REMINDER_DB_PREFIX + reminder.getId());
|
||||||
|
gbReminder.setMessage(reminder.getReminderDetails().getTitle());
|
||||||
|
gbReminder.setDate(XiaomiPreferences.toDate(reminder.getReminderDetails().getDate(), reminder.getReminderDetails().getTime()));
|
||||||
|
|
||||||
|
switch (reminder.getReminderDetails().getRepeatMode()) {
|
||||||
|
case REPETITION_ONCE:
|
||||||
|
gbReminder.setRepetition(Alarm.ALARM_ONCE);
|
||||||
|
break;
|
||||||
|
case REPETITION_DAILY:
|
||||||
|
gbReminder.setRepetition(Alarm.ALARM_DAILY);
|
||||||
|
break;
|
||||||
|
case REPETITION_WEEKLY:
|
||||||
|
gbReminder.setRepetition(reminder.getReminderDetails().getRepeatFlags());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
watchReminders.put(gbReminder.getReminderId(), gbReminder);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<nodomain.freeyourgadget.gadgetbridge.entities.Reminder> dbReminders = DBHelper.getReminders(getSupport().getDevice());
|
||||||
|
|
||||||
|
final Set<String> dbReminderIds = new HashSet<>();
|
||||||
|
|
||||||
|
int numUpdatedReminders = 0;
|
||||||
|
|
||||||
|
// Delete reminders that do not exist on the watch anymore
|
||||||
|
for (nodomain.freeyourgadget.gadgetbridge.entities.Reminder reminder : dbReminders) {
|
||||||
|
if (!reminder.getReminderId().startsWith(REMINDER_DB_PREFIX)) {
|
||||||
|
LOG.debug("Deleting reminder {}", reminder.getReminderId());
|
||||||
|
DBHelper.delete(reminder);
|
||||||
|
numUpdatedReminders++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbReminderIds.add(reminder.getReminderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist unknown reminders
|
||||||
|
// We assume that reminders are not modifiable from the watch, unlike alarms
|
||||||
|
try (DBHandler db = GBApplication.acquireDB()) {
|
||||||
|
final DaoSession daoSession = db.getDaoSession();
|
||||||
|
final Device device = DBHelper.getDevice(getSupport().getDevice(), daoSession);
|
||||||
|
final User user = DBHelper.getUser(daoSession);
|
||||||
|
|
||||||
|
for (final Reminder watchReminder : watchReminders.values()) {
|
||||||
|
final String reminderId = watchReminder.getReminderId();
|
||||||
|
if (dbReminderIds.contains(reminderId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reminder not known - persist it to database
|
||||||
|
LOG.info("Persisting reminder {}", reminderId);
|
||||||
|
|
||||||
|
final nodomain.freeyourgadget.gadgetbridge.entities.Reminder reminder = new nodomain.freeyourgadget.gadgetbridge.entities.Reminder();
|
||||||
|
reminder.setReminderId(watchReminder.getReminderId());
|
||||||
|
reminder.setDate(watchReminder.getDate());
|
||||||
|
reminder.setMessage(watchReminder.getMessage());
|
||||||
|
reminder.setRepetition(watchReminder.getRepetition());
|
||||||
|
reminder.setDeviceId(device.getId());
|
||||||
|
reminder.setUserId(user.getId());
|
||||||
|
|
||||||
|
DBHelper.store(reminder);
|
||||||
|
|
||||||
|
numUpdatedReminders++;
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Error accessing database", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numUpdatedReminders > 0) {
|
||||||
|
final Intent intent = new Intent(DeviceService.ACTION_SAVE_REMINDERS);
|
||||||
|
LocalBroadcastManager.getInstance(getSupport().getContext()).sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onSetReminders(final ArrayList<? extends Reminder> reminders) {
|
public void onSetReminders(final ArrayList<? extends Reminder> reminders) {
|
||||||
// TODO
|
final List<Integer> remindersToDelete = new ArrayList<>();
|
||||||
|
|
||||||
|
pendingReminderAcks = 0;
|
||||||
|
|
||||||
|
final Set<String> newReminderIds = new HashSet<>();
|
||||||
|
for (final Reminder reminder : reminders) {
|
||||||
|
newReminderIds.add(reminder.getReminderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Reminder watchReminder : watchReminders.values()) {
|
||||||
|
if (!newReminderIds.contains(watchReminder.getReminderId())) {
|
||||||
|
final Integer watchId = Integer.parseInt(watchReminder.getReminderId().replace(REMINDER_DB_PREFIX, ""));
|
||||||
|
remindersToDelete.add(watchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Integer id : remindersToDelete) {
|
||||||
|
watchReminders.remove(REMINDER_DB_PREFIX + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Reminder reminder : reminders) {
|
||||||
|
final boolean isCreateReminder;
|
||||||
|
if (reminder.getReminderId().startsWith(REMINDER_DB_PREFIX) && watchReminders.containsKey(reminder.getReminderId())) {
|
||||||
|
// Update reminder on the watch if needed
|
||||||
|
final Reminder watchReminder = watchReminders.get(reminder.getReminderId());
|
||||||
|
if (watchReminder != null && remindersEqual(reminder, watchReminder)) {
|
||||||
|
LOG.debug("Reminder {} is already up-to-date on watch", watchReminder.getReminderId());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
isCreateReminder = (watchReminder == null);
|
||||||
|
} else {
|
||||||
|
isCreateReminder = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Calendar reminderTime = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
reminderTime.setTimeInMillis(reminder.getDate().getTime());
|
||||||
|
|
||||||
|
final XiaomiProto.ReminderDetails.Builder reminderDetails = XiaomiProto.ReminderDetails.newBuilder()
|
||||||
|
.setTime(XiaomiProto.Time.newBuilder()
|
||||||
|
.setHour(reminderTime.get(Calendar.HOUR_OF_DAY))
|
||||||
|
.setMinute(reminderTime.get(Calendar.MINUTE))
|
||||||
|
.setSecond(reminderTime.get(Calendar.SECOND))
|
||||||
|
.setMillisecond(reminderTime.get(Calendar.MILLISECOND))
|
||||||
|
.build())
|
||||||
|
.setDate(XiaomiProto.Date.newBuilder()
|
||||||
|
.setYear(reminderTime.get(Calendar.YEAR))
|
||||||
|
.setMonth(reminderTime.get(Calendar.MONTH) + 1)
|
||||||
|
.setDay(reminderTime.get(Calendar.DATE))
|
||||||
|
.build())
|
||||||
|
.setTitle(reminder.getMessage());
|
||||||
|
|
||||||
|
switch (reminder.getRepetition()) {
|
||||||
|
case Alarm.ALARM_ONCE:
|
||||||
|
reminderDetails.setRepeatMode(REPETITION_ONCE);
|
||||||
|
break;
|
||||||
|
case Alarm.ALARM_DAILY:
|
||||||
|
reminderDetails.setRepeatMode(REPETITION_DAILY);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reminderDetails.setRepeatMode(REPETITION_WEEKLY);
|
||||||
|
reminderDetails.setRepeatFlags(reminder.getRepetition());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final XiaomiProto.Schedule.Builder schedule = XiaomiProto.Schedule.newBuilder();
|
||||||
|
|
||||||
|
if (!isCreateReminder) {
|
||||||
|
// update existing alarm
|
||||||
|
LOG.debug("Update reminder {}", reminder.getReminderId());
|
||||||
|
watchReminders.put(reminder.getReminderId(), reminder);
|
||||||
|
schedule.setEditReminder(
|
||||||
|
XiaomiProto.Reminder.newBuilder()
|
||||||
|
.setId(Integer.parseInt(reminder.getReminderId().replace(REMINDER_DB_PREFIX, "")))
|
||||||
|
.setReminderDetails(reminderDetails)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
LOG.debug("Create reminder {}", reminder.getReminderId());
|
||||||
|
// watchReminders will be updated later, since we don't know the correct ID here
|
||||||
|
pendingReminderAcks++;
|
||||||
|
schedule.setCreateReminder(reminderDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSupport().sendCommand(
|
||||||
|
(isCreateReminder ? "create" : "update") + " reminder " + reminder.getReminderId(),
|
||||||
|
XiaomiProto.Command.newBuilder()
|
||||||
|
.setType(COMMAND_TYPE)
|
||||||
|
.setSubtype(isCreateReminder ? CMD_REMINDERS_CREATE : CMD_REMINDERS_EDIT)
|
||||||
|
.setSchedule(schedule)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remindersToDelete.isEmpty()) {
|
||||||
|
final XiaomiProto.ReminderDelete reminderDelete = XiaomiProto.ReminderDelete.newBuilder()
|
||||||
|
.addAllId(remindersToDelete)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final XiaomiProto.Schedule schedule = XiaomiProto.Schedule.newBuilder()
|
||||||
|
.setDeleteReminder(reminderDelete)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
getSupport().sendCommand(
|
||||||
|
"delete " + remindersToDelete.size() + " reminders",
|
||||||
|
XiaomiProto.Command.newBuilder()
|
||||||
|
.setType(COMMAND_TYPE)
|
||||||
|
.setSubtype(CMD_REMINDERS_DELETE)
|
||||||
|
.setSchedule(schedule)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSetWorldClocks(final ArrayList<? extends WorldClock> clocks) {
|
public void onSetWorldClocks(final ArrayList<? extends WorldClock> clocks) {
|
||||||
|
@ -338,6 +568,12 @@ public class XiaomiScheduleService extends AbstractXiaomiService {
|
||||||
alarm1.getRepetition() == alarm2.getRepetition();
|
alarm1.getRepetition() == alarm2.getRepetition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean remindersEqual(final Reminder reminder1, final Reminder reminder2) {
|
||||||
|
return Objects.equals(reminder1.getMessage(), reminder2.getMessage()) &&
|
||||||
|
Objects.equals(reminder1.getDate(), reminder2.getDate()) &&
|
||||||
|
reminder1.getRepetition() == reminder2.getRepetition();
|
||||||
|
}
|
||||||
|
|
||||||
private void handleSleepModeConfig(final XiaomiProto.SleepMode sleepMode) {
|
private void handleSleepModeConfig(final XiaomiProto.SleepMode sleepMode) {
|
||||||
LOG.debug("Got sleep mode config");
|
LOG.debug("Got sleep mode config");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user