mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-13 03:07:32 +01:00
Pixoo: Decode alarms from device, support sending alarms
This is probably not quite right yet. Also we need to properly chunk incoming protocol messages before decoding them
This commit is contained in:
parent
275deb4d06
commit
198800e087
@ -61,6 +61,11 @@ public class PixooCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlarmSlotCount(GBDevice device) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultIconResource() {
|
||||
return R.drawable.ic_device_lovetoy;
|
||||
|
@ -31,19 +31,24 @@ import java.util.Arrays;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.nothing.NothingProtocol;
|
||||
|
||||
public class PixooIOThread extends BtClassicIoThread {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PixooIOThread.class);
|
||||
private final PixooProtocol mPixooProtocol;
|
||||
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
write(mPixooProtocol.encodeReqestAlarms());
|
||||
|
||||
setUpdateState(GBDevice.State.INITIALIZED);
|
||||
}
|
||||
|
||||
public PixooIOThread(GBDevice device, Context context, PixooProtocol deviceProtocol,
|
||||
PixooSupport PixooSupport, BluetoothAdapter bluetoothAdapter) {
|
||||
super(device, context, deviceProtocol, PixooSupport, bluetoothAdapter);
|
||||
mPixooProtocol = deviceProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,8 +17,12 @@
|
||||
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.divoom;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -26,17 +30,22 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import lineageos.weather.util.WeatherUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||
@ -64,10 +73,86 @@ public class PixooProtocol extends GBDeviceProtocol {
|
||||
|
||||
ByteBuffer incoming = ByteBuffer.wrap(responseData);
|
||||
incoming.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
if (incoming.get() != 0x01) {
|
||||
LOG.warn("first byte not 0x01");
|
||||
return devEvts.toArray(new GBDeviceEvent[0]);
|
||||
}
|
||||
int length = incoming.getShort() & 0xffff;
|
||||
byte status = incoming.get(); // unsure
|
||||
if (status != 0x04) {
|
||||
LOG.warn("status byte not 0x04");
|
||||
return devEvts.toArray(new GBDeviceEvent[0]);
|
||||
}
|
||||
byte endpoint = incoming.get(); // unsure
|
||||
LOG.info("endpoint " + endpoint);
|
||||
if (endpoint == 0x42) {
|
||||
decodeAlarms(incoming);
|
||||
}
|
||||
return devEvts.toArray(new GBDeviceEvent[0]);
|
||||
}
|
||||
|
||||
private void decodeAlarms(ByteBuffer incoming) {
|
||||
byte unknown = incoming.get();
|
||||
if (unknown != 0x55) { // expected
|
||||
LOG.warn("unexpected byte when decoding Alarms " + unknown);
|
||||
return;
|
||||
}
|
||||
// Map of alarm position to Alarm, as returned by the band
|
||||
final Map<Integer, nodomain.freeyourgadget.gadgetbridge.model.Alarm> payloadAlarms = new HashMap<>();
|
||||
|
||||
while (incoming.remaining() > 10) {
|
||||
int position = incoming.get();
|
||||
boolean enabled = incoming.get() == 1;
|
||||
int hour = incoming.get();
|
||||
int minute = incoming.get();
|
||||
int repeatMask = incoming.get();
|
||||
int unknown2 = incoming.getInt();
|
||||
byte unknown3 = incoming.get(); // normally 0x01, on fresh alarms 0x32
|
||||
final Alarm alarm = new nodomain.freeyourgadget.gadgetbridge.entities.Alarm();
|
||||
alarm.setEnabled(enabled);
|
||||
alarm.setPosition(position);
|
||||
alarm.setHour(hour);
|
||||
alarm.setMinute(minute);
|
||||
alarm.setRepetition(repeatMask);
|
||||
alarm.setUnused(unknown3 == 0x32 && !enabled);
|
||||
payloadAlarms.put(position, alarm);
|
||||
}
|
||||
final List<nodomain.freeyourgadget.gadgetbridge.entities.Alarm> dbAlarms = DBHelper.getAlarms(getDevice());
|
||||
int numUpdatedAlarms = 0;
|
||||
|
||||
for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : dbAlarms) {
|
||||
final int pos = alarm.getPosition();
|
||||
final nodomain.freeyourgadget.gadgetbridge.model.Alarm updatedAlarm = payloadAlarms.get(pos);
|
||||
final boolean alarmNeedsUpdate = updatedAlarm == null ||
|
||||
alarm.getUnused() != updatedAlarm.getUnused() ||
|
||||
alarm.getEnabled() != updatedAlarm.getEnabled() ||
|
||||
alarm.getSmartWakeup() != updatedAlarm.getSmartWakeup() ||
|
||||
alarm.getHour() != updatedAlarm.getHour() ||
|
||||
alarm.getMinute() != updatedAlarm.getMinute() ||
|
||||
alarm.getRepetition() != updatedAlarm.getRepetition();
|
||||
|
||||
if (alarmNeedsUpdate) {
|
||||
numUpdatedAlarms++;
|
||||
LOG.info("Updating alarm index={}, unused={}", pos, updatedAlarm == null);
|
||||
alarm.setUnused(updatedAlarm == null);
|
||||
if (updatedAlarm != null) {
|
||||
alarm.setEnabled(updatedAlarm.getEnabled());
|
||||
alarm.setUnused(updatedAlarm.getUnused());
|
||||
alarm.setSmartWakeup(updatedAlarm.getSmartWakeup());
|
||||
alarm.setHour(updatedAlarm.getHour());
|
||||
alarm.setMinute(updatedAlarm.getMinute());
|
||||
alarm.setRepetition(updatedAlarm.getRepetition());
|
||||
}
|
||||
DBHelper.store(alarm);
|
||||
}
|
||||
}
|
||||
|
||||
if (numUpdatedAlarms > 0) {
|
||||
final Intent intent = new Intent(DeviceService.ACTION_SAVE_ALARMS);
|
||||
LocalBroadcastManager.getInstance(GBApplication.getContext()).sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeSendConfiguration(String config) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
|
||||
@ -171,6 +256,26 @@ public class PixooProtocol extends GBDeviceProtocol {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeSetAlarms(ArrayList<? extends nodomain.freeyourgadget.gadgetbridge.model.Alarm> alarms) {
|
||||
byte[] complete_command = new byte[]{};
|
||||
for (nodomain.freeyourgadget.gadgetbridge.model.Alarm alarm : alarms) {
|
||||
byte[] cmd = new byte[]{
|
||||
0x43,
|
||||
(byte) alarm.getPosition(),
|
||||
(byte) (alarm.getEnabled() && !alarm.getUnused() ? 1 : 0),
|
||||
(byte) alarm.getHour(),
|
||||
(byte) alarm.getMinute(),
|
||||
(byte) alarm.getRepetition(),
|
||||
0, 0, 0, 0,
|
||||
(byte) (alarm.getUnused() ? 0x32 : 0x00)};
|
||||
|
||||
complete_command = ArrayUtils.addAll(complete_command, encodeProtocol(cmd));
|
||||
}
|
||||
return complete_command;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] encodeSendWeather(WeatherSpec weatherSpec) {
|
||||
byte pixooWeatherCode = 0;
|
||||
@ -238,6 +343,10 @@ public class PixooProtocol extends GBDeviceProtocol {
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] encodeReqestAlarms() {
|
||||
return encodeProtocol(new byte[]{0x42});
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeTestNewFunction() {
|
||||
//return encodeAudioModeCommand(1); // works
|
||||
@ -262,3 +371,4 @@ public class PixooProtocol extends GBDeviceProtocol {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.divoom;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
|
@ -25,6 +25,7 @@ import java.util.UUID;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
@ -286,6 +287,12 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
|
||||
sendToDevice(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
|
||||
byte[] bytes = gbDeviceProtocol.encodeSetAlarms(alarms);
|
||||
sendToDevice(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetReminders(ArrayList<? extends Reminder> reminders) {
|
||||
byte[] bytes = gbDeviceProtocol.encodeReminders(reminders);
|
||||
|
@ -24,6 +24,7 @@ import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
@ -158,6 +159,10 @@ public abstract class GBDeviceProtocol {
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] encodeSetAlarms(ArrayList<? extends Alarm> alarms) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] encodeReminders(ArrayList<? extends Reminder> reminders) {
|
||||
return null;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user