mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-24 16:31:13 +01:00
Improved DB-based alarms
- got rid of GBAlarm - added migration for prefs-based alarms - various cleanups
This commit is contained in:
parent
e7dc55821d
commit
903b50c2c5
@ -345,6 +345,7 @@ public class GBDaoGenerator {
|
|||||||
|
|
||||||
private static void addAlarms(Schema schema, Entity user, Entity device) {
|
private static void addAlarms(Schema schema, Entity user, Entity device) {
|
||||||
Entity alarm = addEntity(schema, "Alarm");
|
Entity alarm = addEntity(schema, "Alarm");
|
||||||
|
alarm.implementsInterface("nodomain.freeyourgadget.gadgetbridge.model.Alarm");
|
||||||
Property deviceId = alarm.addLongProperty("deviceId").notNull().getProperty();
|
Property deviceId = alarm.addLongProperty("deviceId").notNull().getProperty();
|
||||||
Property userId = alarm.addLongProperty("userId").notNull().getProperty();
|
Property userId = alarm.addLongProperty("userId").notNull().getProperty();
|
||||||
Property position = alarm.addIntProperty("position").notNull().getProperty();
|
Property position = alarm.addIntProperty("position").notNull().getProperty();
|
||||||
@ -355,8 +356,11 @@ public class GBDaoGenerator {
|
|||||||
indexUnique.makeUnique();
|
indexUnique.makeUnique();
|
||||||
alarm.addIndex(indexUnique);
|
alarm.addIndex(indexUnique);
|
||||||
alarm.addBooleanProperty("enabled").notNull();
|
alarm.addBooleanProperty("enabled").notNull();
|
||||||
alarm.addBooleanProperty("smartAlarm").notNull();
|
alarm.addBooleanProperty("smartWakeup").notNull();
|
||||||
alarm.addIntProperty("repetition").notNull();
|
alarm.addIntProperty("repetition").notNull().codeBeforeGetter(
|
||||||
|
"public boolean isRepetitive() { return getRepetition() != ALARM_ONCE; } " +
|
||||||
|
"public boolean getRepetition(int dow) { return (this.repetition & dow) > 0; }"
|
||||||
|
);
|
||||||
alarm.addIntProperty("hour").notNull();
|
alarm.addIntProperty("hour").notNull();
|
||||||
alarm.addIntProperty("minute").notNull();
|
alarm.addIntProperty("minute").notNull();
|
||||||
alarm.addToOne(user, userId);
|
alarm.addToOne(user, userId);
|
||||||
|
@ -31,7 +31,6 @@ import java.util.Calendar;
|
|||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
@ -26,14 +26,16 @@ import android.widget.TimePicker;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
|
|
||||||
public class AlarmDetails extends AbstractGBActivity {
|
public class AlarmDetails extends AbstractGBActivity {
|
||||||
|
|
||||||
private GBAlarm alarm;
|
private Alarm alarm;
|
||||||
private TimePicker timePicker;
|
private TimePicker timePicker;
|
||||||
private CheckedTextView cbSmartWakeup;
|
private CheckedTextView cbSmartWakeup;
|
||||||
private CheckedTextView cbMonday;
|
private CheckedTextView cbMonday;
|
||||||
@ -50,7 +52,7 @@ public class AlarmDetails extends AbstractGBActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_alarm_details);
|
setContentView(R.layout.activity_alarm_details);
|
||||||
|
|
||||||
alarm = getIntent().getParcelableExtra("alarm");
|
alarm = (Alarm) getIntent().getSerializableExtra(nodomain.freeyourgadget.gadgetbridge.model.Alarm.EXTRA_ALARM);
|
||||||
device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||||
|
|
||||||
timePicker = findViewById(R.id.alarm_time_picker);
|
timePicker = findViewById(R.id.alarm_time_picker);
|
||||||
@ -109,17 +111,17 @@ public class AlarmDetails extends AbstractGBActivity {
|
|||||||
timePicker.setCurrentHour(alarm.getHour());
|
timePicker.setCurrentHour(alarm.getHour());
|
||||||
timePicker.setCurrentMinute(alarm.getMinute());
|
timePicker.setCurrentMinute(alarm.getMinute());
|
||||||
|
|
||||||
cbSmartWakeup.setChecked(alarm.isSmartWakeup());
|
cbSmartWakeup.setChecked(alarm.getSmartWakeup());
|
||||||
int smartAlarmVisibility = supportsSmartWakeup() ? View.VISIBLE : View.GONE;
|
int smartAlarmVisibility = supportsSmartWakeup() ? View.VISIBLE : View.GONE;
|
||||||
cbSmartWakeup.setVisibility(smartAlarmVisibility);
|
cbSmartWakeup.setVisibility(smartAlarmVisibility);
|
||||||
|
|
||||||
cbMonday.setChecked(alarm.getRepetition(GBAlarm.ALARM_MON));
|
cbMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
|
||||||
cbTuesday.setChecked(alarm.getRepetition(GBAlarm.ALARM_TUE));
|
cbTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
|
||||||
cbWednesday.setChecked(alarm.getRepetition(GBAlarm.ALARM_WED));
|
cbWednesday.setChecked(alarm.getRepetition(Alarm.ALARM_WED));
|
||||||
cbThursday.setChecked(alarm.getRepetition(GBAlarm.ALARM_THU));
|
cbThursday.setChecked(alarm.getRepetition(Alarm.ALARM_THU));
|
||||||
cbFriday.setChecked(alarm.getRepetition(GBAlarm.ALARM_FRI));
|
cbFriday.setChecked(alarm.getRepetition(Alarm.ALARM_FRI));
|
||||||
cbSaturday.setChecked(alarm.getRepetition(GBAlarm.ALARM_SAT));
|
cbSaturday.setChecked(alarm.getRepetition(Alarm.ALARM_SAT));
|
||||||
cbSunday.setChecked(alarm.getRepetition(GBAlarm.ALARM_SUN));
|
cbSunday.setChecked(alarm.getRepetition(Alarm.ALARM_SUN));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,10 +146,11 @@ public class AlarmDetails extends AbstractGBActivity {
|
|||||||
|
|
||||||
private void updateAlarm() {
|
private void updateAlarm() {
|
||||||
alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked());
|
alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked());
|
||||||
alarm.setRepetition(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
|
int repetitionMask = AlarmUtils.createRepetitionMassk(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
|
||||||
|
alarm.setRepetition(repetitionMask);
|
||||||
alarm.setHour(timePicker.getCurrentHour());
|
alarm.setHour(timePicker.getCurrentHour());
|
||||||
alarm.setMinute(timePicker.getCurrentMinute());
|
alarm.setMinute(timePicker.getCurrentMinute());
|
||||||
alarm.store();
|
DBHelper.store(alarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,31 +19,33 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
|
||||||
|
|
||||||
|
|
||||||
public class ConfigureAlarms extends AbstractGBActivity {
|
public class ConfigureAlarms extends AbstractGBActivity {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ConfigureAlarms.class);
|
||||||
|
|
||||||
private static final int REQ_CONFIGURE_ALARM = 1;
|
private static final int REQ_CONFIGURE_ALARM = 1;
|
||||||
|
|
||||||
@ -84,44 +86,48 @@ public class ConfigureAlarms extends AbstractGBActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the available alarms from the database and updates the view afterwards.
|
||||||
|
*/
|
||||||
private void updateAlarmsFromDB() {
|
private void updateAlarmsFromDB() {
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
List<Alarm> alarms = DBHelper.getAlarms(getGbDevice());
|
||||||
int reservedSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0);
|
if (alarms.isEmpty()) {
|
||||||
|
alarms = AlarmUtils.readAlarmsFromPrefs(getGbDevice());
|
||||||
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
storeMigratedAlarms(alarms);
|
||||||
int alarmSlots = coordinator.getAlarmSlotCount();
|
|
||||||
|
|
||||||
Long deviceId;
|
|
||||||
List<Alarm> allAlarms = null;
|
|
||||||
try (DBHandler db = GBApplication.acquireDB()) {
|
|
||||||
AlarmDao alarmDao = db.getDaoSession().getAlarmDao();
|
|
||||||
Device dbDevice = DBHelper.findDevice(gbDevice, db.getDaoSession());
|
|
||||||
deviceId = dbDevice.getId();
|
|
||||||
QueryBuilder<Alarm> qb = alarmDao.queryBuilder();
|
|
||||||
qb.where(AlarmDao.Properties.DeviceId.eq(deviceId)).orderAsc(AlarmDao.Properties.Position).limit(alarmSlots - reservedSlots);
|
|
||||||
allAlarms = qb.build().list();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
addMissingAlarms(alarms);
|
||||||
|
|
||||||
List<GBAlarm> gbAlarms = new ArrayList<>();
|
mGBAlarmListAdapter.setAlarmList(alarms);
|
||||||
if (allAlarms != null) {
|
|
||||||
for (Alarm alarm : allAlarms) {
|
|
||||||
gbAlarms.add(new GBAlarm(deviceId, alarm.getPosition(), alarm.getEnabled(),
|
|
||||||
alarm.getSmartAlarm(), alarm.getRepetition(), alarm.getHour(), alarm.getMinute()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int hour = 5;
|
|
||||||
while (gbAlarms.size() < alarmSlots) {
|
|
||||||
GBAlarm gbAlarm = new GBAlarm(deviceId, gbAlarms.size(), false, false, 31, hour++, 30);
|
|
||||||
gbAlarms.add(gbAlarm);
|
|
||||||
gbAlarm.store();
|
|
||||||
}
|
|
||||||
|
|
||||||
mGBAlarmListAdapter.setAlarmList(gbAlarms);
|
|
||||||
mGBAlarmListAdapter.notifyDataSetChanged();
|
mGBAlarmListAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeMigratedAlarms(List<Alarm> alarms) {
|
||||||
|
for (Alarm alarm : alarms) {
|
||||||
|
DBHelper.store(alarm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingAlarms(List<Alarm> alarms) {
|
||||||
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(getGbDevice());
|
||||||
|
int supportedNumAlarms = coordinator.getAlarmSlotCount();
|
||||||
|
if (supportedNumAlarms > alarms.size()) {
|
||||||
|
try (DBHandler db = GBApplication.acquireDB()) {
|
||||||
|
DaoSession daoSession = db.getDaoSession();
|
||||||
|
Device device = DBHelper.getDevice(getGbDevice(), daoSession);
|
||||||
|
User user = DBHelper.getUser(daoSession);
|
||||||
|
while (supportedNumAlarms > alarms.size()) {
|
||||||
|
alarms.add(createDefaultAlarm(device, user, alarms.size()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error accessing database", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Alarm createDefaultAlarm(@NonNull Device device, @NonNull User user, int position) {
|
||||||
|
return new Alarm(device.getId(), user.getId(), position, false, false,0, 6, 30);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
@ -133,10 +139,10 @@ public class ConfigureAlarms extends AbstractGBActivity {
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureAlarm(GBAlarm alarm) {
|
public void configureAlarm(Alarm alarm) {
|
||||||
avoidSendAlarmsToDevice = true;
|
avoidSendAlarmsToDevice = true;
|
||||||
Intent startIntent = new Intent(getApplicationContext(), AlarmDetails.class);
|
Intent startIntent = new Intent(getApplicationContext(), AlarmDetails.class);
|
||||||
startIntent.putExtra("alarm", alarm);
|
startIntent.putExtra(Alarm.EXTRA_ALARM, alarm);
|
||||||
startIntent.putExtra(GBDevice.EXTRA_DEVICE, getGbDevice());
|
startIntent.putExtra(GBDevice.EXTRA_DEVICE, getGbDevice());
|
||||||
startActivityForResult(startIntent, REQ_CONFIGURE_ALARM);
|
startActivityForResult(startIntent, REQ_CONFIGURE_ALARM);
|
||||||
}
|
}
|
||||||
|
@ -35,33 +35,32 @@ import java.util.List;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter for displaying GBAlarm instances.
|
* Adapter for displaying GBAlarm instances.
|
||||||
*/
|
*/
|
||||||
public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.ViewHolder> {
|
public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private List<GBAlarm> alarmList;
|
private ArrayList<Alarm> alarmList;
|
||||||
|
|
||||||
public GBAlarmListAdapter(Context context) {
|
public GBAlarmListAdapter(Context context) {
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlarmList(List<GBAlarm> alarmList) {
|
public void setAlarmList(List<Alarm> alarms) {
|
||||||
this.alarmList = alarmList;
|
this.alarmList = new ArrayList<>(alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList getAlarmList() {
|
public ArrayList<Alarm> getAlarmList() {
|
||||||
return (ArrayList) alarmList;
|
return alarmList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateInDB(Alarm alarm) {
|
||||||
public void update(GBAlarm alarm) {
|
DBHelper.store(alarm);
|
||||||
alarm.store();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -74,7 +73,7 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
|
|||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
|
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
|
||||||
|
|
||||||
final GBAlarm alarm = alarmList.get(position);
|
final Alarm alarm = alarmList.get(position);
|
||||||
|
|
||||||
holder.alarmDayMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
|
holder.alarmDayMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
|
||||||
holder.alarmDayTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
|
holder.alarmDayTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
|
||||||
@ -88,7 +87,7 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
|
|||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
alarm.setEnabled(isChecked);
|
alarm.setEnabled(isChecked);
|
||||||
update(alarm);
|
updateInDB(alarm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,16 +97,15 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.
|
|||||||
((ConfigureAlarms) mContext).configureAlarm(alarm);
|
((ConfigureAlarms) mContext).configureAlarm(alarm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
holder.alarmTime.setText(alarm.getTime());
|
holder.alarmTime.setText(DateTimeUtils.formatTime(alarm.getHour(), alarm.getMinute()));
|
||||||
holder.isEnabled.setChecked(alarm.isEnabled());
|
holder.isEnabled.setChecked(alarm.getEnabled());
|
||||||
if (alarm.isSmartWakeup()) {
|
if (alarm.getSmartWakeup()) {
|
||||||
holder.isSmartWakeup.setVisibility(TextView.VISIBLE);
|
holder.isSmartWakeup.setVisibility(TextView.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
holder.isSmartWakeup.setVisibility(TextView.GONE);
|
holder.isSmartWakeup.setVisibility(TextView.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return alarmList.size();
|
return alarmList.size();
|
||||||
|
@ -21,7 +21,6 @@ import android.content.Context;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.net.Uri;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
@ -33,6 +32,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -44,8 +44,11 @@ import de.greenrobot.dao.query.QueryBuilder;
|
|||||||
import de.greenrobot.dao.query.WhereCondition;
|
import de.greenrobot.dao.query.WhereCondition;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescription;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescription;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescriptionDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ActivityDescriptionDao;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes;
|
||||||
@ -62,6 +65,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -362,6 +366,13 @@ public class DBHelper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the corresponding Device entity for the given GBDevice.
|
||||||
|
* @param gbDevice
|
||||||
|
* @param session
|
||||||
|
* @return the corresponding Device entity, or null if none
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
public static Device findDevice(GBDevice gbDevice, DaoSession session) {
|
public static Device findDevice(GBDevice gbDevice, DaoSession session) {
|
||||||
DeviceDao deviceDao = session.getDeviceDao();
|
DeviceDao deviceDao = session.getDeviceDao();
|
||||||
Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build();
|
Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build();
|
||||||
@ -561,6 +572,49 @@ public class DBHelper {
|
|||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all user-configurable alarms for the given user and device. The list is sorted by
|
||||||
|
* {@link Alarm#position}. Calendar events that may also be modeled as alarms are not stored
|
||||||
|
* in the database and hence not returned by this method.
|
||||||
|
* @param gbDevice the device for which the alarms shall be loaded
|
||||||
|
* @return the list of alarms for the given device
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static List<Alarm> getAlarms(@NonNull GBDevice gbDevice) {
|
||||||
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
||||||
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
|
// TODO: this alarm reservation is a device dependent detail
|
||||||
|
int reservedSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0);
|
||||||
|
int alarmSlots = coordinator.getAlarmSlotCount();
|
||||||
|
|
||||||
|
try (DBHandler db = GBApplication.acquireDB()) {
|
||||||
|
DaoSession daoSession = db.getDaoSession();
|
||||||
|
User user = getUser(daoSession);
|
||||||
|
Device dbDevice = DBHelper.findDevice(gbDevice, daoSession);
|
||||||
|
if (dbDevice != null) {
|
||||||
|
AlarmDao alarmDao = daoSession.getAlarmDao();
|
||||||
|
Long deviceId = dbDevice.getId();
|
||||||
|
QueryBuilder<Alarm> qb = alarmDao.queryBuilder();
|
||||||
|
qb.where(
|
||||||
|
AlarmDao.Properties.UserId.eq(user.getId()),
|
||||||
|
AlarmDao.Properties.DeviceId.eq(deviceId)).orderAsc(AlarmDao.Properties.Position).limit(alarmSlots - reservedSlots);
|
||||||
|
return qb.build().list();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warn("Error reading alarms from db", e);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void store(Alarm alarm) {
|
||||||
|
try (DBHandler db = GBApplication.acquireDB()) {
|
||||||
|
DaoSession daoSession = db.getDaoSession();
|
||||||
|
daoSession.insertOrReplace(alarm);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error acquiring database", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void clearSession() {
|
public static void clearSession() {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
DaoSession session = dbHandler.getDaoSession();
|
DaoSession session = dbHandler.getDaoSession();
|
||||||
|
@ -1,215 +0,0 @@
|
|||||||
/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
|
||||||
Gobbetti
|
|
||||||
|
|
||||||
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 <http://www.gnu.org/licenses/>. */
|
|
||||||
package nodomain.freeyourgadget.gadgetbridge.impl;
|
|
||||||
|
|
||||||
import android.os.Parcel;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
|
||||||
|
|
||||||
|
|
||||||
public class GBAlarm implements Alarm {
|
|
||||||
|
|
||||||
private final int index;
|
|
||||||
private boolean enabled;
|
|
||||||
private boolean smartWakeup;
|
|
||||||
private int repetition;
|
|
||||||
private int hour;
|
|
||||||
private int minute;
|
|
||||||
private long deviceId;
|
|
||||||
|
|
||||||
public GBAlarm(Long deviceId, int index, boolean enabled, boolean smartWakeup, int repetition, int hour, int minute) {
|
|
||||||
this.deviceId = deviceId;
|
|
||||||
this.index = index;
|
|
||||||
this.enabled = enabled;
|
|
||||||
this.smartWakeup = smartWakeup;
|
|
||||||
this.repetition = repetition;
|
|
||||||
this.hour = hour;
|
|
||||||
this.minute = minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GBAlarm createSingleShot(long deviceId, int index, boolean smartWakeup, Calendar calendar) {
|
|
||||||
return new GBAlarm(deviceId, index, true, smartWakeup, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GBAlarm readFromParcel(Parcel pc) {
|
|
||||||
long deviceId = pc.readLong();
|
|
||||||
int index = pc.readInt();
|
|
||||||
boolean enabled = Boolean.parseBoolean(pc.readString());
|
|
||||||
boolean smartWakeup = Boolean.parseBoolean(pc.readString());
|
|
||||||
int repetition = pc.readInt();
|
|
||||||
int hour = pc.readInt();
|
|
||||||
int minute = pc.readInt();
|
|
||||||
return new GBAlarm(deviceId, index, enabled, smartWakeup, repetition, hour, minute);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o instanceof GBAlarm) {
|
|
||||||
GBAlarm comp = (GBAlarm) o;
|
|
||||||
return comp.getIndex() == getIndex();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return getIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int describeContents() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
|
||||||
dest.writeLong(deviceId);
|
|
||||||
dest.writeInt(this.index);
|
|
||||||
dest.writeString(String.valueOf(this.enabled));
|
|
||||||
dest.writeString(String.valueOf(this.smartWakeup));
|
|
||||||
dest.writeInt(this.repetition);
|
|
||||||
dest.writeInt(this.hour);
|
|
||||||
dest.writeInt(this.minute);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NonNull Alarm another) {
|
|
||||||
if (this.getIndex() < another.getIndex()) {
|
|
||||||
return -1;
|
|
||||||
} else if (this.getIndex() > another.getIndex()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getIndex() {
|
|
||||||
return this.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTime() {
|
|
||||||
return String.format(Locale.US, "%02d", this.hour) + ":" + String.format(Locale.US, "%02d", this.minute);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHour() {
|
|
||||||
return this.hour;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinute() {
|
|
||||||
return this.minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Calendar getAlarmCal() {
|
|
||||||
|
|
||||||
Calendar alarm = Calendar.getInstance();
|
|
||||||
Calendar now = Calendar.getInstance();
|
|
||||||
alarm.set(Calendar.HOUR_OF_DAY, this.hour);
|
|
||||||
alarm.set(Calendar.MINUTE, this.minute);
|
|
||||||
if (now.after(alarm) && repetition == ALARM_ONCE) {
|
|
||||||
//if the alarm is in the past set it to tomorrow
|
|
||||||
alarm.add(Calendar.DATE, 1);
|
|
||||||
}
|
|
||||||
return alarm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSmartWakeup() {
|
|
||||||
return this.smartWakeup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getRepetition(int dow) {
|
|
||||||
return (this.repetition & dow) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRepetitionMask() {
|
|
||||||
return this.repetition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRepetitive() {
|
|
||||||
return getRepetitionMask() != ALARM_ONCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSmartWakeup(boolean smartWakeup) {
|
|
||||||
this.smartWakeup = smartWakeup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRepetition(boolean mon, boolean tue, boolean wed, boolean thu, boolean fri, boolean sat, boolean sun) {
|
|
||||||
this.repetition = (mon ? ALARM_MON : 0) |
|
|
||||||
(tue ? ALARM_TUE : 0) |
|
|
||||||
(wed ? ALARM_WED : 0) |
|
|
||||||
(thu ? ALARM_THU : 0) |
|
|
||||||
(fri ? ALARM_FRI : 0) |
|
|
||||||
(sat ? ALARM_SAT : 0) |
|
|
||||||
(sun ? ALARM_SUN : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHour(int hour) {
|
|
||||||
this.hour = hour;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinute(int minute) {
|
|
||||||
this.minute = minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void store() {
|
|
||||||
try (DBHandler db = GBApplication.acquireDB()) {
|
|
||||||
DaoSession daoSession = db.getDaoSession();
|
|
||||||
Long userId = DBHelper.getUser(daoSession).getId();
|
|
||||||
nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm = new nodomain.freeyourgadget.gadgetbridge.entities.Alarm(deviceId, userId, index, enabled, smartWakeup, repetition, hour, minute);
|
|
||||||
daoSession.insertOrReplace(alarm);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// LOG.error("Error acquiring database", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Creator CREATOR = new Creator() {
|
|
||||||
@Override
|
|
||||||
public GBAlarm createFromParcel(Parcel in) {
|
|
||||||
return readFromParcel(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GBAlarm[] newArray(int size) {
|
|
||||||
return new GBAlarm[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
@ -176,7 +176,7 @@ public class GBDeviceService implements DeviceService {
|
|||||||
@Override
|
@Override
|
||||||
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
|
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
|
||||||
Intent intent = createIntent().setAction(ACTION_SET_ALARMS)
|
Intent intent = createIntent().setAction(ACTION_SET_ALARMS)
|
||||||
.putParcelableArrayListExtra(EXTRA_ALARMS, alarms);
|
.putExtra(EXTRA_ALARMS, alarms);
|
||||||
invokeService(intent);
|
invokeService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,11 +16,14 @@
|
|||||||
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.model;
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||||
|
|
||||||
import android.os.Parcelable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import java.util.Calendar;
|
public interface Alarm extends Serializable {
|
||||||
|
/**
|
||||||
|
* The {@link android.os.Bundle} name for transferring pacreled alarms.
|
||||||
|
*/
|
||||||
|
String EXTRA_ALARM = "alarm";
|
||||||
|
|
||||||
public interface Alarm extends Parcelable, Comparable<Alarm> {
|
|
||||||
byte ALARM_ONCE = 0;
|
byte ALARM_ONCE = 0;
|
||||||
byte ALARM_MON = 1;
|
byte ALARM_MON = 1;
|
||||||
byte ALARM_TUE = 2;
|
byte ALARM_TUE = 2;
|
||||||
@ -30,19 +33,19 @@ public interface Alarm extends Parcelable, Comparable<Alarm> {
|
|||||||
byte ALARM_SAT = 32;
|
byte ALARM_SAT = 32;
|
||||||
byte ALARM_SUN = 64;
|
byte ALARM_SUN = 64;
|
||||||
|
|
||||||
int getIndex();
|
int getPosition();
|
||||||
|
|
||||||
Calendar getAlarmCal();
|
boolean getEnabled();
|
||||||
|
|
||||||
String getTime();
|
boolean getSmartWakeup();
|
||||||
|
|
||||||
boolean isEnabled();
|
int getRepetition();
|
||||||
|
|
||||||
boolean isSmartWakeup();
|
|
||||||
|
|
||||||
int getRepetitionMask();
|
|
||||||
|
|
||||||
boolean isRepetitive();
|
boolean isRepetitive();
|
||||||
|
|
||||||
boolean getRepetition(int dow);
|
boolean getRepetition(int dow);
|
||||||
|
|
||||||
|
int getHour();
|
||||||
|
|
||||||
|
int getMinute();
|
||||||
}
|
}
|
@ -548,7 +548,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_SET_ALARMS:
|
case ACTION_SET_ALARMS:
|
||||||
ArrayList<Alarm> alarms = intent.getParcelableArrayListExtra(EXTRA_ALARMS);
|
ArrayList<? extends Alarm> alarms = (ArrayList<? extends Alarm>) intent.getSerializableExtra(EXTRA_ALARMS);
|
||||||
mDeviceSupport.onSetAlarms(alarms);
|
mDeviceSupport.onSetAlarms(alarms);
|
||||||
break;
|
break;
|
||||||
case ACTION_ENABLE_REALTIME_STEPS: {
|
case ACTION_ENABLE_REALTIME_STEPS: {
|
||||||
|
@ -58,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
@ -430,13 +431,13 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
for (Alarm alarm : alarms) {
|
for (Alarm alarm : alarms) {
|
||||||
|
|
||||||
if (!alarm.isEnabled())
|
if (!alarm.getEnabled())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (alarm.isSmartWakeup()) //Not available
|
if (alarm.getSmartWakeup()) //Not available
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Calendar t = alarm.getAlarmCal();
|
Calendar t = AlarmUtils.toCalendar(alarm);
|
||||||
setAlarm(builder, t);
|
setAlarm(builder, t);
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
|
|
||||||
|
@ -72,11 +72,11 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
@ -113,6 +113,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.Upd
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
||||||
@ -614,7 +615,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
TransactionBuilder builder = performInitialized("Set alarm");
|
TransactionBuilder builder = performInitialized("Set alarm");
|
||||||
boolean anyAlarmEnabled = false;
|
boolean anyAlarmEnabled = false;
|
||||||
for (Alarm alarm : alarms) {
|
for (Alarm alarm : alarms) {
|
||||||
anyAlarmEnabled |= alarm.isEnabled();
|
anyAlarmEnabled |= alarm.getEnabled();
|
||||||
queueAlarm(alarm, builder, characteristic);
|
queueAlarm(alarm, builder, characteristic);
|
||||||
}
|
}
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
@ -1402,29 +1403,29 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
* @param characteristic
|
* @param characteristic
|
||||||
*/
|
*/
|
||||||
private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) {
|
private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) {
|
||||||
Calendar calendar = alarm.getAlarmCal();
|
Calendar calendar = AlarmUtils.toCalendar(alarm);
|
||||||
|
|
||||||
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
||||||
int maxAlarms = coordinator.getAlarmSlotCount();
|
int maxAlarms = coordinator.getAlarmSlotCount();
|
||||||
|
|
||||||
if (alarm.getIndex() >= maxAlarms) {
|
if (alarm.getPosition() >= maxAlarms) {
|
||||||
if (alarm.isEnabled()) {
|
if (alarm.getEnabled()) {
|
||||||
GB.toast(getContext(), "Only " + maxAlarms + " alarms are currently supported.", Toast.LENGTH_LONG, GB.WARN);
|
GB.toast(getContext(), "Only " + maxAlarms + " alarms are currently supported.", Toast.LENGTH_LONG, GB.WARN);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int base = 0;
|
int base = 0;
|
||||||
if (alarm.isEnabled()) {
|
if (alarm.getEnabled()) {
|
||||||
base = 128;
|
base = 128;
|
||||||
}
|
}
|
||||||
int daysMask = alarm.getRepetitionMask();
|
int daysMask = alarm.getRepetition();
|
||||||
if (!alarm.isRepetitive()) {
|
if (!alarm.isRepetitive()) {
|
||||||
daysMask = 128;
|
daysMask = 128;
|
||||||
}
|
}
|
||||||
byte[] alarmMessage = new byte[] {
|
byte[] alarmMessage = new byte[] {
|
||||||
(byte) 0x2, // TODO what is this?
|
(byte) 0x2, // TODO what is this?
|
||||||
(byte) (base + alarm.getIndex()), // 128 is the base, alarm slot is added
|
(byte) (base + alarm.getPosition()), // 128 is the base, alarm slot is added
|
||||||
(byte) calendar.get(Calendar.HOUR_OF_DAY),
|
(byte) calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
(byte) calendar.get(Calendar.MINUTE),
|
(byte) calendar.get(Calendar.MINUTE),
|
||||||
(byte) daysMask,
|
(byte) daysMask,
|
||||||
@ -1477,14 +1478,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
CalendarEvents upcomingEvents = new CalendarEvents();
|
CalendarEvents upcomingEvents = new CalendarEvents();
|
||||||
List<CalendarEvents.CalendarEvent> mEvents = upcomingEvents.getCalendarEventList(getContext());
|
List<CalendarEvents.CalendarEvent> mEvents = upcomingEvents.getCalendarEventList(getContext());
|
||||||
|
|
||||||
Long deviceId;
|
|
||||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
|
||||||
DaoSession session = handler.getDaoSession();
|
|
||||||
deviceId = DBHelper.getDevice(getDevice(), session).getId();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.error("Could not acquire DB", e);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
|
|
||||||
for (CalendarEvents.CalendarEvent mEvt : mEvents) {
|
for (CalendarEvents.CalendarEvent mEvt : mEvents) {
|
||||||
@ -1494,7 +1487,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
int slotToUse = 2 - iteration;
|
int slotToUse = 2 - iteration;
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
calendar.setTimeInMillis(mEvt.getBegin());
|
calendar.setTimeInMillis(mEvt.getBegin());
|
||||||
Alarm alarm = GBAlarm.createSingleShot(deviceId, slotToUse, false, calendar);
|
Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, calendar);
|
||||||
queueAlarm(alarm, builder, characteristic);
|
queueAlarm(alarm, builder, characteristic);
|
||||||
iteration++;
|
iteration++;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
@ -277,11 +278,11 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport {
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Calendar cal = alarms.get(i).getAlarmCal();
|
Calendar cal = AlarmUtils.toCalendar(alarms.get(i));
|
||||||
builder.write(ctrlCharacteristic, commandWithChecksum(
|
builder.write(ctrlCharacteristic, commandWithChecksum(
|
||||||
cmd,
|
cmd,
|
||||||
alarms.get(i).isEnabled() ? cal.get(Calendar.HOUR_OF_DAY) : -1,
|
alarms.get(i).getEnabled() ? cal.get(Calendar.HOUR_OF_DAY) : -1,
|
||||||
alarms.get(i).isEnabled() ? cal.get(Calendar.MINUTE) : -1
|
alarms.get(i).getEnabled() ? cal.get(Calendar.MINUTE) : -1
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
|
@ -56,7 +56,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
@ -87,6 +86,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotific
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.FetchActivityOperation;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.FetchActivityOperation;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.UpdateFirmwareOperation;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.UpdateFirmwareOperation;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
||||||
@ -560,7 +560,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
TransactionBuilder builder = performInitialized("Set alarm");
|
TransactionBuilder builder = performInitialized("Set alarm");
|
||||||
boolean anyAlarmEnabled = false;
|
boolean anyAlarmEnabled = false;
|
||||||
for (Alarm alarm : alarms) {
|
for (Alarm alarm : alarms) {
|
||||||
anyAlarmEnabled |= alarm.isEnabled();
|
anyAlarmEnabled |= alarm.getEnabled();
|
||||||
queueAlarm(alarm, builder, characteristic);
|
queueAlarm(alarm, builder, characteristic);
|
||||||
}
|
}
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
@ -1134,20 +1134,20 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
* @param characteristic
|
* @param characteristic
|
||||||
*/
|
*/
|
||||||
private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) {
|
private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) {
|
||||||
byte[] alarmCalBytes = MiBandDateConverter.calendarToRawBytes(alarm.getAlarmCal());
|
byte[] alarmCalBytes = MiBandDateConverter.calendarToRawBytes(AlarmUtils.toCalendar(alarm));
|
||||||
|
|
||||||
byte[] alarmMessage = new byte[]{
|
byte[] alarmMessage = new byte[]{
|
||||||
MiBandService.COMMAND_SET_TIMER,
|
MiBandService.COMMAND_SET_TIMER,
|
||||||
(byte) alarm.getIndex(),
|
(byte) alarm.getPosition(),
|
||||||
(byte) (alarm.isEnabled() ? 1 : 0),
|
(byte) (alarm.getEnabled() ? 1 : 0),
|
||||||
alarmCalBytes[0],
|
alarmCalBytes[0],
|
||||||
alarmCalBytes[1],
|
alarmCalBytes[1],
|
||||||
alarmCalBytes[2],
|
alarmCalBytes[2],
|
||||||
alarmCalBytes[3],
|
alarmCalBytes[3],
|
||||||
alarmCalBytes[4],
|
alarmCalBytes[4],
|
||||||
alarmCalBytes[5],
|
alarmCalBytes[5],
|
||||||
(byte) (alarm.isSmartWakeup() ? 30 : 0),
|
(byte) (alarm.getSmartWakeup() ? 30 : 0),
|
||||||
(byte) alarm.getRepetitionMask()
|
(byte) alarm.getRepetition()
|
||||||
};
|
};
|
||||||
builder.write(characteristic, alarmMessage);
|
builder.write(characteristic, alarmMessage);
|
||||||
}
|
}
|
||||||
@ -1231,15 +1231,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
CalendarEvents upcomingEvents = new CalendarEvents();
|
CalendarEvents upcomingEvents = new CalendarEvents();
|
||||||
List<CalendarEvents.CalendarEvent> mEvents = upcomingEvents.getCalendarEventList(getContext());
|
List<CalendarEvents.CalendarEvent> mEvents = upcomingEvents.getCalendarEventList(getContext());
|
||||||
|
|
||||||
Long deviceId;
|
|
||||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
|
||||||
DaoSession session = handler.getDaoSession();
|
|
||||||
deviceId = DBHelper.getDevice(getDevice(), session).getId();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.error("Could not acquire DB", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
for (CalendarEvents.CalendarEvent mEvt : mEvents) {
|
for (CalendarEvents.CalendarEvent mEvt : mEvents) {
|
||||||
if (iteration >= availableSlots || iteration > 2) {
|
if (iteration >= availableSlots || iteration > 2) {
|
||||||
@ -1248,7 +1239,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
int slotToUse = 2 - iteration;
|
int slotToUse = 2 - iteration;
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
calendar.setTimeInMillis(mEvt.getBegin());
|
calendar.setTimeInMillis(mEvt.getBegin());
|
||||||
Alarm alarm = GBAlarm.createSingleShot(deviceId, slotToUse, false, calendar);
|
Alarm alarm = AlarmUtils.createSingleShot(slotToUse, false, calendar);
|
||||||
queueAlarm(alarm, builder, characteristic);
|
queueAlarm(alarm, builder, characteristic);
|
||||||
iteration++;
|
iteration++;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.math.NumberUtils.min;
|
import static org.apache.commons.lang3.math.NumberUtils.min;
|
||||||
@ -188,20 +189,20 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
TransactionBuilder builder = performInitialized("Set alarm");
|
TransactionBuilder builder = performInitialized("Set alarm");
|
||||||
boolean anyAlarmEnabled = false;
|
boolean anyAlarmEnabled = false;
|
||||||
for (Alarm alarm : alarms) {
|
for (Alarm alarm : alarms) {
|
||||||
anyAlarmEnabled |= alarm.isEnabled();
|
anyAlarmEnabled |= alarm.getEnabled();
|
||||||
Calendar calendar = alarm.getAlarmCal();
|
Calendar calendar = AlarmUtils.toCalendar(alarm);
|
||||||
|
|
||||||
int maxAlarms = 3;
|
int maxAlarms = 3;
|
||||||
if (alarm.getIndex() >= maxAlarms) {
|
if (alarm.getPosition() >= maxAlarms) {
|
||||||
if (alarm.isEnabled()) {
|
if (alarm.getEnabled()) {
|
||||||
GB.toast(getContext(), "Only 3 alarms are supported.", Toast.LENGTH_LONG, GB.WARN);
|
GB.toast(getContext(), "Only 3 alarms are supported.", Toast.LENGTH_LONG, GB.WARN);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int daysMask = 0;
|
int daysMask = 0;
|
||||||
if (alarm.isEnabled()) {
|
if (alarm.getEnabled()) {
|
||||||
daysMask = alarm.getRepetitionMask();
|
daysMask = alarm.getRepetition();
|
||||||
// Mask for this device starts from sunday and not from monday.
|
// Mask for this device starts from sunday and not from monday.
|
||||||
daysMask = (daysMask / 64) + (daysMask >> 1);
|
daysMask = (daysMask / 64) + (daysMask >> 1);
|
||||||
}
|
}
|
||||||
@ -210,11 +211,11 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
(byte) daysMask,
|
(byte) daysMask,
|
||||||
(byte) calendar.get(Calendar.HOUR_OF_DAY),
|
(byte) calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
(byte) calendar.get(Calendar.MINUTE),
|
(byte) calendar.get(Calendar.MINUTE),
|
||||||
(byte) (alarm.isEnabled() ? 2 : 0), // vibration duration
|
(byte) (alarm.getEnabled() ? 2 : 0), // vibration duration
|
||||||
(byte) (alarm.isEnabled() ? 10 : 0), // vibration count
|
(byte) (alarm.getEnabled() ? 10 : 0), // vibration count
|
||||||
(byte) (alarm.isEnabled() ? 2 : 0), // unknown
|
(byte) (alarm.getEnabled() ? 2 : 0), // unknown
|
||||||
(byte) 0,
|
(byte) 0,
|
||||||
(byte) (alarm.getIndex() + 1)
|
(byte) (alarm.getPosition() + 1)
|
||||||
};
|
};
|
||||||
builder.write(ctrlCharacteristic, alarmMessage);
|
builder.write(ctrlCharacteristic, alarmMessage);
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.operations.InitOperation;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.operations.InitOperation;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||||
|
|
||||||
public class Watch9DeviceSupport extends AbstractBTLEDeviceSupport {
|
public class Watch9DeviceSupport extends AbstractBTLEDeviceSupport {
|
||||||
@ -331,7 +332,7 @@ public class Watch9DeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized("setAlarms");
|
TransactionBuilder builder = performInitialized("setAlarms");
|
||||||
for (Alarm alarm : alarms) {
|
for (Alarm alarm : alarms) {
|
||||||
setAlarm(alarm, alarm.getIndex() + 1, builder);
|
setAlarm(alarm, alarm.getPosition() + 1, builder);
|
||||||
}
|
}
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -352,14 +353,14 @@ public class Watch9DeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private void setAlarm(Alarm alarm, int index, TransactionBuilder builder) {
|
private void setAlarm(Alarm alarm, int index, TransactionBuilder builder) {
|
||||||
// Shift the GB internal repetition mask to match the device specific one.
|
// Shift the GB internal repetition mask to match the device specific one.
|
||||||
byte repetitionMask = (byte) ((alarm.getRepetitionMask() << 1) | (alarm.isRepetitive() ? 0x80 : 0x00));
|
byte repetitionMask = (byte) ((alarm.getRepetition() << 1) | (alarm.isRepetitive() ? 0x80 : 0x00));
|
||||||
repetitionMask |= (alarm.getRepetition(Alarm.ALARM_SUN) ? 0x01 : 0x00);
|
repetitionMask |= (alarm.getRepetition(Alarm.ALARM_SUN) ? 0x01 : 0x00);
|
||||||
if (0 < index && index < 4) {
|
if (0 < index && index < 4) {
|
||||||
byte[] alarmValue = new byte[]{(byte) index,
|
byte[] alarmValue = new byte[]{(byte) index,
|
||||||
Conversion.toBcd8(alarm.getAlarmCal().get(Calendar.HOUR_OF_DAY)),
|
Conversion.toBcd8(AlarmUtils.toCalendar(alarm).get(Calendar.HOUR_OF_DAY)),
|
||||||
Conversion.toBcd8(alarm.getAlarmCal().get(Calendar.MINUTE)),
|
Conversion.toBcd8(AlarmUtils.toCalendar(alarm).get(Calendar.MINUTE)),
|
||||||
repetitionMask,
|
repetitionMask,
|
||||||
(byte) (alarm.isEnabled() ? 0x01 : 0x00),
|
(byte) (alarm.getEnabled() ? 0x01 : 0x00),
|
||||||
0x00 // TODO: Unknown
|
0x00 // TODO: Unknown
|
||||||
};
|
};
|
||||||
builder.write(getCharacteristic(Watch9Constants.UUID_CHARACTERISTIC_WRITE),
|
builder.write(getCharacteristic(Watch9Constants.UUID_CHARACTERISTIC_WRITE),
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some utility methods for dealing with Alarms.
|
||||||
|
*/
|
||||||
|
public class AlarmUtils {
|
||||||
|
/**
|
||||||
|
* Creates an auto-generated (not user-configurable), non-recurring alarm. This alarm
|
||||||
|
* may not be stored in the database. Some features are not available (e.g. device id, user id).
|
||||||
|
* @param index
|
||||||
|
* @param smartWakeup
|
||||||
|
* @param calendar
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, Calendar calendar) {
|
||||||
|
return new Alarm(-1, -1, index, true, smartWakeup, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Calendar object representing the time of the given alarm (not taking the
|
||||||
|
* day/date into account.
|
||||||
|
* @param alarm
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Calendar toCalendar(nodomain.freeyourgadget.gadgetbridge.model.Alarm alarm) {
|
||||||
|
Calendar result = Calendar.getInstance();
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
result.set(Calendar.HOUR_OF_DAY, alarm.getHour());
|
||||||
|
result.set(Calendar.MINUTE, alarm.getMinute());
|
||||||
|
if (now.after(result) && alarm.getRepetition() == Alarm.ALARM_ONCE) {
|
||||||
|
//if the alarm is in the past set it to tomorrow
|
||||||
|
result.add(Calendar.DATE, 1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a repetition mask suitable for {@link Alarm#repetition}
|
||||||
|
* @param mon whether the alarm shall repeat every Monday
|
||||||
|
* @param tue whether the alarm shall repeat every Tuesday
|
||||||
|
* @param wed whether the alarm shall repeat every Wednesday
|
||||||
|
* @param thu whether the alarm shall repeat every Thursday
|
||||||
|
* @param fri whether the alarm shall repeat every Friday
|
||||||
|
* @param sat whether the alarm shall repeat every Saturday
|
||||||
|
* @param sun whether the alarm shall repeat every Sunday
|
||||||
|
* @return the created repetition mask
|
||||||
|
*/
|
||||||
|
public static int createRepetitionMassk(boolean mon, boolean tue, boolean wed, boolean thu, boolean fri, boolean sat, boolean sun) {
|
||||||
|
int repetitionMask = (mon ? Alarm.ALARM_MON : 0) |
|
||||||
|
(tue ? Alarm.ALARM_TUE : 0) |
|
||||||
|
(wed ? Alarm.ALARM_WED : 0) |
|
||||||
|
(thu ? Alarm.ALARM_THU : 0) |
|
||||||
|
(fri ? Alarm.ALARM_FRI : 0) |
|
||||||
|
(sat ? Alarm.ALARM_SAT : 0) |
|
||||||
|
(sun ? Alarm.ALARM_SUN : 0);
|
||||||
|
return repetitionMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just for backward compatibility, do not call in new code.
|
||||||
|
* @param gbDevice
|
||||||
|
* @return
|
||||||
|
* @deprecated use {@link DBHelper#getAlarms(GBDevice)} instead
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static List<Alarm> readAlarmsFromPrefs(GBDevice gbDevice) {
|
||||||
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
|
Set<String> stringAlarms = prefs.getStringSet(MiBandConst.PREF_MIBAND_ALARMS, new HashSet<String>());
|
||||||
|
List<Alarm> alarms = new ArrayList<>(stringAlarms.size());
|
||||||
|
|
||||||
|
try {
|
||||||
|
DBHandler db = GBApplication.acquireDB();
|
||||||
|
DaoSession daoSession = db.getDaoSession();
|
||||||
|
User user = DBHelper.getUser(daoSession);
|
||||||
|
Device device = DBHelper.getDevice(gbDevice, daoSession);
|
||||||
|
for (String stringAlarm : stringAlarms) {
|
||||||
|
alarms.add(createAlarmFromPreference(stringAlarm, device, user));
|
||||||
|
}
|
||||||
|
Collections.sort(alarms, AlarmUtils.createComparator());
|
||||||
|
return alarms;
|
||||||
|
} catch (Exception e) {
|
||||||
|
GB.log("Error accessing database", GB.ERROR, e);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Alarm createAlarmFromPreference(String fromPreferences, Device device, User user) {
|
||||||
|
String[] tokens = fromPreferences.split(",");
|
||||||
|
int index = Integer.parseInt(tokens[0]);
|
||||||
|
boolean enabled = Boolean.parseBoolean(tokens[1]);
|
||||||
|
boolean smartWakeup = Boolean.parseBoolean(tokens[2]);
|
||||||
|
int repetition = Integer.parseInt(tokens[3]);
|
||||||
|
int hour = Integer.parseInt(tokens[4]);
|
||||||
|
int minute = Integer.parseInt(tokens[5]);
|
||||||
|
|
||||||
|
return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, repetition, hour, minute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Comparator<Alarm> createComparator() {
|
||||||
|
return new Comparator<Alarm>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Alarm o1, Alarm o2) {
|
||||||
|
int p1 = o1.getPosition();
|
||||||
|
int p2 = o2.getPosition();
|
||||||
|
|
||||||
|
return Integer.compare(p1, p2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,7 @@ import java.util.TimeZone;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
|
|
||||||
public class DateTimeUtils {
|
public class DateTimeUtils {
|
||||||
private static SimpleDateFormat DAY_STORAGE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
private static SimpleDateFormat DAY_STORAGE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||||
@ -136,6 +137,11 @@ public class DateTimeUtils {
|
|||||||
return HOURS_MINUTES_FORMAT.format(date);
|
return HOURS_MINUTES_FORMAT.format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatTime(int hours, int minutes) {
|
||||||
|
return String.format(Locale.US, "%02d", hours) + ":" + String.format(Locale.US, "%02d", minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Date todayUTC() {
|
public static Date todayUTC() {
|
||||||
Calendar cal = getCalendarUTC();
|
Calendar cal = getCalendarUTC();
|
||||||
return cal.getTime();
|
return cal.getTime();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user