mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-09 03:37:03 +01:00
Casio GW-B5600: response handlers
This commit is contained in:
parent
b6ba421a62
commit
4a9fd49461
@ -1,6 +1,6 @@
|
||||
/* Copyright (C) 2015-2024 Andreas Böhler, Andreas Shimokawa, Carsten
|
||||
Pfeiffer, Damien Gaignon, Daniel Dakhno, Daniele Gobbetti, Frank Ertl,
|
||||
José Rebelo
|
||||
José Rebelo, Johannes Krude
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -30,6 +30,7 @@ import androidx.annotation.RequiresApi;
|
||||
import java.util.Arrays;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.BondAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.FunctionAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.NotifyAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ReadAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.RequestConnectionPriorityAction;
|
||||
@ -118,6 +119,11 @@ public class TransactionBuilder {
|
||||
return add(action);
|
||||
}
|
||||
|
||||
// Runs the given function/lambda
|
||||
public TransactionBuilder run(FunctionAction.Function function) {
|
||||
return add(new FunctionAction(function));
|
||||
}
|
||||
|
||||
public TransactionBuilder add(BtLEAction action) {
|
||||
mTransaction.add(action);
|
||||
return this;
|
||||
|
@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 2023 Johannes Krude
|
||||
|
||||
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.service.btle.actions;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.PlainAction;
|
||||
|
||||
/**
|
||||
* Invokes the given function
|
||||
*/
|
||||
public class FunctionAction extends PlainAction {
|
||||
|
||||
public interface Function {
|
||||
public void apply(BluetoothGatt gatt);
|
||||
}
|
||||
private Function function;
|
||||
|
||||
public FunctionAction(Function function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(BluetoothGatt gatt) {
|
||||
function.apply(gatt);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean expectsResult() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -17,11 +17,22 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.casio;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.casio.CasioConstants;
|
||||
|
||||
@ -52,12 +63,24 @@ public abstract class Casio2C2DSupport extends CasioSupport {
|
||||
public static final byte FEATURE_SETTING_FOR_USER_PROFILE = 0x45;
|
||||
public static final byte FEATURE_SERVICE_DISCOVERY_MANAGER = 0x47;
|
||||
|
||||
private static Logger LOG;
|
||||
LinkedList<RequestWithHandler> requests = new LinkedList<>();
|
||||
|
||||
public Casio2C2DSupport(Logger logger) {
|
||||
super(logger);
|
||||
LOG = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
requests.clear();
|
||||
return super.connect();
|
||||
}
|
||||
|
||||
public void writeAllFeatures(TransactionBuilder builder, byte[] arr) {
|
||||
if (!requests.isEmpty()) {
|
||||
LOG.warn("writing while waiting for a response may lead to incorrect received responses");
|
||||
}
|
||||
builder.write(getCharacteristic(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID), arr);
|
||||
}
|
||||
|
||||
@ -65,6 +88,123 @@ public abstract class Casio2C2DSupport extends CasioSupport {
|
||||
builder.write(getCharacteristic(CasioConstants.CASIO_READ_REQUEST_FOR_ALL_FEATURES_CHARACTERISTIC_UUID), arr);
|
||||
}
|
||||
|
||||
public interface ResponseHandler {
|
||||
void handle(byte[] response);
|
||||
}
|
||||
|
||||
public interface ResponsesHandler {
|
||||
void handle(Map<FeatureRequest, byte[]> responses);
|
||||
}
|
||||
|
||||
public static class FeatureRequest {
|
||||
byte data[];
|
||||
|
||||
public FeatureRequest(byte arg0) {
|
||||
data = new byte[] {arg0};
|
||||
}
|
||||
|
||||
public FeatureRequest(byte arg0, byte arg1) {
|
||||
data = new byte[] {arg0, arg1};
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof FeatureRequest))
|
||||
return false;
|
||||
|
||||
FeatureRequest fr = (FeatureRequest) o;
|
||||
return Arrays.equals(data, fr.data);
|
||||
}
|
||||
|
||||
public boolean matches(byte[] response) {
|
||||
if (response.length > 2 && response[0] == 0xFF && response[1] == 0x81) {
|
||||
if (data.length < response.length - 2)
|
||||
return false;
|
||||
for (int i = 2; i < response.length; i++) {
|
||||
if (response[i] != data[i-2])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (response.length < data.length)
|
||||
return false;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (response[i] != data[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RequestWithHandler {
|
||||
public FeatureRequest request;
|
||||
public ResponseHandler handler;
|
||||
|
||||
public RequestWithHandler(FeatureRequest request, ResponseHandler handler) {
|
||||
this.request = request;
|
||||
this.handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
public void requestFeature(TransactionBuilder builder, FeatureRequest request, ResponseHandler handler) {
|
||||
builder.notify(getCharacteristic(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID), true);
|
||||
writeAllFeaturesRequest(builder, request.getData());
|
||||
builder.run((gatt) -> requests.add(new RequestWithHandler(request, handler)));
|
||||
}
|
||||
|
||||
public void requestFeatures(TransactionBuilder builder, Set<FeatureRequest> requests, ResponsesHandler handler) {
|
||||
HashMap<FeatureRequest, byte[]> responses = new HashMap();
|
||||
|
||||
HashSet<FeatureRequest> missing = new HashSet();
|
||||
for (FeatureRequest request: requests) {
|
||||
missing.add(request);
|
||||
}
|
||||
|
||||
for (FeatureRequest request: requests) {
|
||||
requestFeature(builder, request, data -> {
|
||||
responses.put(request, data);
|
||||
missing.remove(request);
|
||||
if (missing.isEmpty()) {
|
||||
handler.handle(responses);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
UUID characteristicUUID = characteristic.getUuid();
|
||||
|
||||
if (characteristicUUID.equals(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID)) {
|
||||
byte[] response = characteristic.getValue();
|
||||
Iterator<RequestWithHandler> it = requests.iterator();
|
||||
while (it.hasNext()) {
|
||||
RequestWithHandler rh = it.next();
|
||||
if (rh.request.matches(response)) {
|
||||
it.remove();
|
||||
rh.handler.handle(response);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOG.warn("unhandled response: " + Logging.formatBytes(response));
|
||||
}
|
||||
|
||||
return super.onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
|
||||
public void writeCurrentTime(TransactionBuilder builder, ZonedDateTime time) {
|
||||
byte[] arr = new byte[11];
|
||||
arr[0] = FEATURE_CURRENT_TIME;
|
||||
|
@ -17,19 +17,26 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.widget.Toast;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.TextStyle;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.casio.CasioConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.Casio2C2DSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600.InitOperation;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600.CasioGWB5600TimeZone;
|
||||
|
||||
public class CasioGWB5600DeviceSupport extends Casio2C2DSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CasioGWB5600DeviceSupport.class);
|
||||
@ -61,13 +68,46 @@ public class CasioGWB5600DeviceSupport extends Casio2C2DSupport {
|
||||
connect();
|
||||
return builder;
|
||||
}
|
||||
try {
|
||||
new InitOperation(this, builder).perform();
|
||||
} catch (IOException e) {
|
||||
GB.toast(getContext(), "Initializing watch failed", Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||
}
|
||||
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
|
||||
requestWorldClocks(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void requestWorldClocks(TransactionBuilder builder) {
|
||||
HashSet<FeatureRequest> requests = new HashSet();
|
||||
|
||||
for (byte i = 0; i < 6; i++) {
|
||||
requests.addAll(CasioGWB5600TimeZone.requests(i));
|
||||
}
|
||||
|
||||
requestFeatures(builder, requests, responses -> {
|
||||
TransactionBuilder clockBuilder = createTransactionBuilder("setClocks");
|
||||
setClocks(clockBuilder, responses);
|
||||
clockBuilder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
|
||||
clockBuilder.queue(getQueue());
|
||||
});
|
||||
}
|
||||
|
||||
private void setClocks(TransactionBuilder builder, Map<FeatureRequest, byte[]> responses) {
|
||||
ZoneId tz = ZoneId.systemDefault();
|
||||
Instant now = Instant.now().plusSeconds(2);
|
||||
CasioGWB5600TimeZone[] timezones = {
|
||||
CasioGWB5600TimeZone.fromZoneId(tz, now, tz.getDisplayName(TextStyle.SHORT, Locale.getDefault())),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 1),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 2),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 3),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 4),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 5),
|
||||
};
|
||||
for (int i = 5; i >= 0; i--) {
|
||||
if (i%2 == 0)
|
||||
writeAllFeatures(builder, CasioGWB5600TimeZone.dstWatchStateBytes(i, timezones[i], i+1, timezones[i+1]));
|
||||
writeAllFeatures(builder, timezones[i].dstSettingBytes(i));
|
||||
writeAllFeatures(builder, timezones[i].worldCityBytes(i));
|
||||
}
|
||||
writeCurrentTime(builder, ZonedDateTime.ofInstant(now, tz));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.Instant;
|
||||
@ -128,11 +132,12 @@ PONTA DELGADA E4 00 FC 04 02
|
||||
this.dstSetting = dstSetting;
|
||||
}
|
||||
|
||||
static public byte[] dstWatchStateRequest(int slot) {
|
||||
// request only even slots, the response will also contain the next odd slot
|
||||
return new byte[] {
|
||||
Casio2C2DSupport.FEATURE_DST_WATCH_STATE,
|
||||
(byte) slot};
|
||||
static public Set<Casio2C2DSupport.FeatureRequest> requests(int slot) {
|
||||
HashSet<Casio2C2DSupport.FeatureRequest> requests = new HashSet();
|
||||
requests.add(new Casio2C2DSupport.FeatureRequest(Casio2C2DSupport.FEATURE_DST_WATCH_STATE, (byte) (slot/2*2)));
|
||||
requests.add(new Casio2C2DSupport.FeatureRequest(Casio2C2DSupport.FEATURE_DST_SETTING, (byte) slot));
|
||||
requests.add(new Casio2C2DSupport.FeatureRequest(Casio2C2DSupport.FEATURE_WORLD_CITY, (byte) slot));
|
||||
return requests;
|
||||
}
|
||||
|
||||
static public byte[] dstWatchStateBytes(int slotA, CasioGWB5600TimeZone zoneA, int slotB, CasioGWB5600TimeZone zoneB) {
|
||||
@ -149,12 +154,6 @@ PONTA DELGADA E4 00 FC 04 02
|
||||
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
|
||||
}
|
||||
|
||||
static public byte[] dstSettingRequest(int slot) {
|
||||
return new byte[] {
|
||||
Casio2C2DSupport.FEATURE_DST_SETTING,
|
||||
(byte) slot};
|
||||
}
|
||||
|
||||
public byte[] dstSettingBytes(int slot) {
|
||||
return new byte[] {
|
||||
Casio2C2DSupport.FEATURE_DST_SETTING,
|
||||
@ -166,12 +165,6 @@ PONTA DELGADA E4 00 FC 04 02
|
||||
dstRules};
|
||||
}
|
||||
|
||||
static public byte[] worldCityRequest(int slot) {
|
||||
return new byte[] {
|
||||
Casio2C2DSupport.FEATURE_WORLD_CITY,
|
||||
(byte) slot};
|
||||
}
|
||||
|
||||
public byte[] worldCityBytes(int slot) {
|
||||
byte[] bytes = {
|
||||
Casio2C2DSupport.FEATURE_WORLD_CITY,
|
||||
@ -181,7 +174,7 @@ PONTA DELGADA E4 00 FC 04 02
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static CasioGWB5600TimeZone fromWatchResponses(List<byte[]> responses, int slot) {
|
||||
static CasioGWB5600TimeZone fromWatchResponses(Map<Casio2C2DSupport.FeatureRequest, byte[]> responses, int slot) {
|
||||
byte[] name = "unknown".getBytes(StandardCharsets.US_ASCII);
|
||||
byte[] number = {0,0};
|
||||
byte offset = 0;
|
||||
@ -189,7 +182,7 @@ PONTA DELGADA E4 00 FC 04 02
|
||||
byte dstRules = 0;
|
||||
byte dstSetting = 0;
|
||||
|
||||
for (byte[] response: responses) {
|
||||
for (byte[] response: responses.values()) {
|
||||
if (response[0] == Casio2C2DSupport.FEATURE_DST_WATCH_STATE && response.length >= 9) {
|
||||
if (response[1] == slot) {
|
||||
dstSetting = response[3];
|
||||
|
@ -1,130 +0,0 @@
|
||||
/* Copyright (C) 2023-2024 Johannes Krude
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.TextStyle;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.casio.CasioConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.casio.CasioConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.Casio2C2DSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600.CasioGWB5600DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gwb5600.CasioGWB5600TimeZone;
|
||||
|
||||
public class InitOperation extends AbstractBTLEOperation<CasioGWB5600DeviceSupport> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InitOperation.class);
|
||||
|
||||
private final TransactionBuilder builder;
|
||||
private final CasioGWB5600DeviceSupport support;
|
||||
private List<byte[]> responses = new LinkedList<byte[]>();
|
||||
|
||||
public InitOperation(CasioGWB5600DeviceSupport support, TransactionBuilder builder) {
|
||||
super(support);
|
||||
this.support = support;
|
||||
this.builder = builder;
|
||||
builder.setCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionBuilder performInitialized(String taskName) throws IOException {
|
||||
throw new UnsupportedOperationException("This IS the initialization class, you cannot call this method");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPerform() {//throws IOException {
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
|
||||
builder.notify(getCharacteristic(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID), true);
|
||||
for (int i = 1; i < 6; i++) {
|
||||
if (i%2 == 1)
|
||||
support.writeAllFeaturesRequest(builder, CasioGWB5600TimeZone.dstWatchStateRequest(i-1));
|
||||
|
||||
support.writeAllFeaturesRequest(builder, CasioGWB5600TimeZone.dstSettingRequest(i));
|
||||
support.writeAllFeaturesRequest(builder, CasioGWB5600TimeZone.worldCityRequest(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
UUID characteristicUUID = characteristic.getUuid();
|
||||
byte[] data = characteristic.getValue();
|
||||
|
||||
if (characteristicUUID.equals(CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID) && data.length > 0 &&
|
||||
(data[0] == Casio2C2DSupport.FEATURE_DST_WATCH_STATE ||
|
||||
data[0] == Casio2C2DSupport.FEATURE_DST_SETTING ||
|
||||
data[0] == Casio2C2DSupport.FEATURE_WORLD_CITY)) {
|
||||
responses.add(data);
|
||||
if (responses.size() == 13) {
|
||||
TransactionBuilder builder = createTransactionBuilder("setClocks");
|
||||
setClocks(builder);
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
|
||||
builder.setCallback(null);
|
||||
builder.queue(support.getQueue());
|
||||
operationFinished();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
||||
return super.onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
}
|
||||
|
||||
private void setClocks(TransactionBuilder builder) {
|
||||
ZoneId tz = ZoneId.systemDefault();
|
||||
Instant now = Instant.now().plusSeconds(2);
|
||||
CasioGWB5600TimeZone[] timezones = {
|
||||
CasioGWB5600TimeZone.fromZoneId(tz, now, tz.getDisplayName(TextStyle.SHORT, Locale.getDefault())),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 1),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 2),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 3),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 4),
|
||||
CasioGWB5600TimeZone.fromWatchResponses(responses, 5),
|
||||
};
|
||||
for (int i = 5; i >= 0; i--) {
|
||||
if (i%2 == 0)
|
||||
support.writeAllFeatures(builder, CasioGWB5600TimeZone.dstWatchStateBytes(i, timezones[i], i+1, timezones[i+1]));
|
||||
support.writeAllFeatures(builder, timezones[i].dstSettingBytes(i));
|
||||
support.writeAllFeatures(builder, timezones[i].worldCityBytes(i));
|
||||
}
|
||||
support.writeCurrentTime(builder, ZonedDateTime.ofInstant(now, tz));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void operationFinished() {
|
||||
operationStatus = OperationStatus.FINISHED;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user