mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-27 04:16:49 +01:00
Moyoung: Implement sending calendar items
This commit is contained in:
parent
b5b4727564
commit
cb2b216dde
@ -208,6 +208,19 @@ public class MoyoungConstants {
|
|||||||
public static final byte CMD_QUERY_ALARM_CLOCK = 33; // (?) {} -> a list of entries like below
|
public static final byte CMD_QUERY_ALARM_CLOCK = 33; // (?) {} -> a list of entries like below
|
||||||
public static final byte CMD_SET_ALARM_CLOCK = 17; // (?) {id, enable ? 1 : 0, repeat, hour, minute, i >> 8, i, repeatMode}, repeatMode is 0(SINGLE), 127(EVERYDAY), or bitmask of 1,2,4,8,16,32,64(SUNDAY-SATURDAY) is 0,1,2, i is ((year << 12) + (month << 8) + day) where year is 2015-based, month and day start at 1 for repeatMode=SINGLE and 0 otherwise, repeat is 0(SINGLE),1(EVERYDAY),2(OTHER)
|
public static final byte CMD_SET_ALARM_CLOCK = 17; // (?) {id, enable ? 1 : 0, repeat, hour, minute, i >> 8, i, repeatMode}, repeatMode is 0(SINGLE), 127(EVERYDAY), or bitmask of 1,2,4,8,16,32,64(SUNDAY-SATURDAY) is 0,1,2, i is ((year << 12) + (month << 8) + day) where year is 2015-based, month and day start at 1 for repeatMode=SINGLE and 0 otherwise, repeat is 0(SINGLE),1(EVERYDAY),2(OTHER)
|
||||||
|
|
||||||
|
public static final byte CMD_ADVANCED_QUERY = (byte) 0xb9;
|
||||||
|
public static final byte CMD_DAGPT = (byte) 0xbb;
|
||||||
|
|
||||||
|
public static final byte ARG_ADVANCED_SET_CALENDAR = 0x08;
|
||||||
|
public static final byte ARG_ADVANCED_QUERY_STOCKS = 0x0e;
|
||||||
|
|
||||||
|
public static final byte ARG_CALENDAR_ADD_ITEM = 0x00;
|
||||||
|
public static final byte ARG_CALENDAR_DISABLE = 0x04;
|
||||||
|
public static final byte ARG_CALENDAR_FINISHED = 0x05;
|
||||||
|
public static final byte ARG_CALENDAR_CLEAR = 0x06;
|
||||||
|
|
||||||
|
public static final int MAX_CALENDAR_ITEMS = 12; // Tested only on Colmi i28 Ultra, move to coordinator if different on other devices
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
public static final byte CMD_SET_USER_INFO = 18; // (?) {height, weight, age, gender}, MALE = 0, FEMALE = 1
|
public static final byte CMD_SET_USER_INFO = 18; // (?) {height, weight, age, gender}, MALE = 0, FEMALE = 1
|
||||||
|
|
||||||
@ -280,9 +293,6 @@ public class MoyoungConstants {
|
|||||||
public static final byte CMD_QUERY_BREATHING_LIGHT = -120; // {} -> {value}
|
public static final byte CMD_QUERY_BREATHING_LIGHT = -120; // {} -> {value}
|
||||||
public static final byte CMD_SET_BREATHING_LIGHT = 120; // {enabled ? 1 : 0}
|
public static final byte CMD_SET_BREATHING_LIGHT = 120; // {enabled ? 1 : 0}
|
||||||
|
|
||||||
public static final byte CMD_QUERY_STOCKS = (byte) 0xb9;
|
|
||||||
public static final byte CMD_DAGPT = (byte) 0xbb;
|
|
||||||
|
|
||||||
public static final byte TRAINING_TYPE_WALK = 0;
|
public static final byte TRAINING_TYPE_WALK = 0;
|
||||||
public static final byte TRAINING_TYPE_RUN = 1;
|
public static final byte TRAINING_TYPE_RUN = 1;
|
||||||
public static final byte TRAINING_TYPE_BIKING = 2;
|
public static final byte TRAINING_TYPE_BIKING = 2;
|
||||||
|
@ -19,9 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.moyoung;
|
|||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -37,10 +35,11 @@ import java.text.ParseException;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -74,7 +73,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungEnum
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungEnumTimeSystem;
|
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungEnumTimeSystem;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSetting;
|
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSetting;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSettingEnum;
|
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSettingEnum;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSettingLanguage;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSettingRemindersToMove;
|
import nodomain.freeyourgadget.gadgetbridge.devices.moyoung.settings.MoyoungSettingRemindersToMove;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
|
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummaryDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummaryDao;
|
||||||
@ -116,6 +114,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarEvent;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarManager;
|
||||||
|
|
||||||
public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MoyoungDeviceSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MoyoungDeviceSupport.class);
|
||||||
@ -143,6 +143,7 @@ public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private boolean realTimeHeartRate;
|
private boolean realTimeHeartRate;
|
||||||
private boolean findMyPhoneActive = false;
|
private boolean findMyPhoneActive = false;
|
||||||
|
private final Set<CalendarEvent> lastSync = new HashSet<>();
|
||||||
|
|
||||||
public int getMtu() {
|
public int getMtu() {
|
||||||
return this.mtu;
|
return this.mtu;
|
||||||
@ -451,7 +452,7 @@ public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packetType == MoyoungConstants.CMD_QUERY_STOCKS)
|
if (packetType == MoyoungConstants.CMD_ADVANCED_QUERY && payload[0] == MoyoungConstants.ARG_ADVANCED_QUERY_STOCKS)
|
||||||
{
|
{
|
||||||
LOG.info("Stocks queried from watch");
|
LOG.info("Stocks queried from watch");
|
||||||
return true;
|
return true;
|
||||||
@ -744,12 +745,104 @@ public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
|
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
|
||||||
// TODO
|
syncCalendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeleteCalendarEvent(byte type, long id) {
|
public void onDeleteCalendarEvent(byte type, long id) {
|
||||||
// TODO
|
syncCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncCalendar() {
|
||||||
|
if (!getDevicePrefs().getBoolean("sync_calendar", false)) {
|
||||||
|
LOG.debug("Ignoring calendar sync request, sync is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CalendarManager upcomingEvents = new CalendarManager(getContext(), getDevice().getAddress());
|
||||||
|
final List<CalendarEvent> calendarEvents = upcomingEvents.getCalendarEventList();
|
||||||
|
|
||||||
|
final Set<CalendarEvent> thisSync = new HashSet<>();
|
||||||
|
int nEvents = 0;
|
||||||
|
|
||||||
|
for (final CalendarEvent calendarEvent : calendarEvents) {
|
||||||
|
if (++nEvents > MoyoungConstants.MAX_CALENDAR_ITEMS) {
|
||||||
|
LOG.warn("Syncing only first {} events of {}", MoyoungConstants.MAX_CALENDAR_ITEMS, calendarEvents.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thisSync.add(calendarEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisSync.equals(lastSync)) {
|
||||||
|
LOG.debug("Already synced this set of events, won't send to device");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSync.clear();
|
||||||
|
lastSync.addAll(thisSync);
|
||||||
|
|
||||||
|
List<CalendarEvent> sortedEventList = new ArrayList<>(thisSync);
|
||||||
|
Collections.sort(sortedEventList, Comparator.comparingLong(CalendarEvent::getBegin));
|
||||||
|
|
||||||
|
LOG.debug("Syncing {} calendar events", sortedEventList.size());
|
||||||
|
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("sendCalendar");
|
||||||
|
byte[] payload = new byte[]{
|
||||||
|
MoyoungConstants.ARG_ADVANCED_SET_CALENDAR,
|
||||||
|
MoyoungConstants.ARG_CALENDAR_CLEAR
|
||||||
|
};
|
||||||
|
sendPacket(builder, MoyoungPacketOut.buildPacket(mtu, MoyoungConstants.CMD_ADVANCED_QUERY, payload));
|
||||||
|
int itemNr = 0;
|
||||||
|
for(CalendarEvent event : sortedEventList) {
|
||||||
|
byte[] title = event.getTitle().getBytes();
|
||||||
|
Calendar start = Calendar.getInstance();
|
||||||
|
start.setTimeInMillis(event.getBegin());
|
||||||
|
Calendar end = Calendar.getInstance();
|
||||||
|
end.setTimeInMillis(event.getEnd());
|
||||||
|
ByteBuffer packet = ByteBuffer.allocate(title.length + 12);
|
||||||
|
packet.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
packet.put(MoyoungConstants.ARG_ADVANCED_SET_CALENDAR);
|
||||||
|
packet.put(MoyoungConstants.ARG_CALENDAR_ADD_ITEM);
|
||||||
|
packet.put((byte) itemNr);
|
||||||
|
packet.put((byte) title.length);
|
||||||
|
packet.put(title);
|
||||||
|
packet.put((byte) start.get(Calendar.HOUR_OF_DAY));
|
||||||
|
packet.put((byte) start.get(Calendar.MINUTE));
|
||||||
|
packet.put((byte) end.get(Calendar.HOUR_OF_DAY));
|
||||||
|
packet.put((byte) end.get(Calendar.MINUTE));
|
||||||
|
packet.putInt(MoyoungConstants.LocalTimeToWatchTime(start.getTime()));
|
||||||
|
sendPacket(builder, MoyoungPacketOut.buildPacket(mtu, MoyoungConstants.CMD_ADVANCED_QUERY, packet.array()));
|
||||||
|
itemNr++;
|
||||||
|
}
|
||||||
|
payload = new byte[]{
|
||||||
|
MoyoungConstants.ARG_ADVANCED_SET_CALENDAR,
|
||||||
|
MoyoungConstants.ARG_CALENDAR_FINISHED
|
||||||
|
};
|
||||||
|
sendPacket(builder, MoyoungPacketOut.buildPacket(mtu, MoyoungConstants.CMD_ADVANCED_QUERY, payload));
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Error sending notification: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableCalendar() {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("disableCalendar");
|
||||||
|
byte[] payload = new byte[]{
|
||||||
|
MoyoungConstants.ARG_ADVANCED_SET_CALENDAR,
|
||||||
|
MoyoungConstants.ARG_CALENDAR_CLEAR
|
||||||
|
};
|
||||||
|
sendPacket(builder, MoyoungPacketOut.buildPacket(mtu, MoyoungConstants.CMD_ADVANCED_QUERY, payload));
|
||||||
|
payload = new byte[]{
|
||||||
|
MoyoungConstants.ARG_ADVANCED_SET_CALENDAR,
|
||||||
|
MoyoungConstants.ARG_CALENDAR_DISABLE
|
||||||
|
};
|
||||||
|
sendPacket(builder, MoyoungPacketOut.buildPacket(mtu, MoyoungConstants.CMD_ADVANCED_QUERY, payload));
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Error while disabling calendar: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1478,6 +1571,14 @@ public class MoyoungDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sendSetting(getSetting("REMINDERS_TO_MOVE_PERIOD"),
|
sendSetting(getSetting("REMINDERS_TO_MOVE_PERIOD"),
|
||||||
new MoyoungSettingRemindersToMove.RemindersToMove(sedentaryPeriod, sedentarySteps, sedentaryStart, sedentaryEnd));
|
new MoyoungSettingRemindersToMove.RemindersToMove(sedentaryPeriod, sedentarySteps, sedentaryStart, sedentaryEnd));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "sync_calendar":
|
||||||
|
if (prefs.getBoolean("sync_calendar", false)) {
|
||||||
|
syncCalendar();
|
||||||
|
} else {
|
||||||
|
disableCalendar();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query the setting to make sure the configuration got actually applied
|
// Query the setting to make sure the configuration got actually applied
|
||||||
|
Loading…
Reference in New Issue
Block a user