mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-15 05:04:22 +02:00
@@ -168,9 +168,8 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
|
switch (stepNr) {
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
case 0:
|
||||||
// Setup notification
|
// Setup notification
|
||||||
setNotificationOn(CUSTOM_CHARACTERISTIC_WEIGHT);
|
setNotificationOn(CUSTOM_CHARACTERISTIC_WEIGHT);
|
||||||
@@ -212,26 +211,10 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
if (currentRemoteUser != null) {
|
if (currentRemoteUser != null) {
|
||||||
Timber.d("Request saved measurements for %s", currentRemoteUser.name);
|
Timber.d("Request saved measurements for %s", currentRemoteUser.name);
|
||||||
sendCommand(CMD_GET_SAVED_MEASUREMENTS, encodeUserId(currentRemoteUser));
|
sendCommand(CMD_GET_SAVED_MEASUREMENTS, encodeUserId(currentRemoteUser));
|
||||||
|
|
||||||
// Wait for all measurements to be received
|
|
||||||
stopMachineState();
|
stopMachineState();
|
||||||
} else {
|
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (currentRemoteUser != null) {
|
|
||||||
Timber.d("Deleting saved measurements for %s", currentRemoteUser.name);
|
|
||||||
sendCommand(CMD_DELETE_SAVED_MEASUREMENTS, encodeUserId(currentRemoteUser));
|
|
||||||
|
|
||||||
// Return to the previous state until all users have been processed
|
|
||||||
repeatMachineStateSteps(2);
|
|
||||||
stopMachineState();
|
|
||||||
} else {
|
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// Create a remote user for selected openScale user if needed
|
// Create a remote user for selected openScale user if needed
|
||||||
currentRemoteUser = null;
|
currentRemoteUser = null;
|
||||||
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
||||||
@@ -244,14 +227,20 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
if (currentRemoteUser == null) {
|
if (currentRemoteUser == null) {
|
||||||
createRemoteUser(selectedUser);
|
createRemoteUser(selectedUser);
|
||||||
stopMachineState();
|
stopMachineState();
|
||||||
} else {
|
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 7:
|
||||||
sendCommand(CMD_USER_DETAILS, encodeUserId(currentRemoteUser));
|
sendCommand(CMD_USER_DETAILS, encodeUserId(currentRemoteUser));
|
||||||
stopMachineState();
|
stopMachineState();
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
if (!currentRemoteUser.isNew) {
|
||||||
|
sendCommand(CMD_DO_MEASUREMENT, encodeUserId(currentRemoteUser));
|
||||||
|
stopMachineState();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Finish init if everything is done
|
// Finish init if everything is done
|
||||||
return false;
|
return false;
|
||||||
@@ -260,40 +249,6 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
if (!currentRemoteUser.isNew) {
|
|
||||||
sendCommand(CMD_DO_MEASUREMENT, encodeUserId(currentRemoteUser));
|
|
||||||
stopMachineState();
|
|
||||||
} else {
|
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// Force disconnect
|
|
||||||
sendAlternativeStartCode(ID_START_NIBBLE_DISCONNECT, (byte) 0x02);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
byte[] data = value;
|
byte[] data = value;
|
||||||
@@ -303,7 +258,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
|
|
||||||
if (data[0] == getAlternativeStartByte(ID_START_NIBBLE_INIT)) {
|
if (data[0] == getAlternativeStartByte(ID_START_NIBBLE_INIT)) {
|
||||||
Timber.d("Got init ack from scale; scale is ready");
|
Timber.d("Got init ack from scale; scale is ready");
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +332,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All users received
|
// All users received
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processMeasurementData(byte[] data, int offset, boolean firstPart) {
|
private void processMeasurementData(byte[] data, int offset, boolean firstPart) {
|
||||||
@@ -401,11 +356,18 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
int current = data[3] & 0xFF;
|
int current = data[3] & 0xFF;
|
||||||
|
|
||||||
processMeasurementData(data, 4, current % 2 == 1);
|
processMeasurementData(data, 4, current % 2 == 1);
|
||||||
if (current == count) {
|
|
||||||
// Resume but don't do next step until ACK has been sent
|
|
||||||
resumeMachineState(false);
|
|
||||||
}
|
|
||||||
sendAck(data);
|
sendAck(data);
|
||||||
|
|
||||||
|
if (current == count) {
|
||||||
|
Timber.d("Deleting saved measurements for %s", currentRemoteUser.name);
|
||||||
|
sendCommand(CMD_DELETE_SAVED_MEASUREMENTS, encodeUserId(currentRemoteUser));
|
||||||
|
|
||||||
|
if (currentRemoteUser.remoteUserId != remoteUsers.get(remoteUsers.size() - 1).remoteUserId) {
|
||||||
|
jumpNextToStepNr(5);
|
||||||
|
resumeMachineState();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processWeightMeasurement(byte[] data) {
|
private void processWeightMeasurement(byte[] data) {
|
||||||
@@ -483,7 +445,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
Timber.d("Set scale unit to %s (%d)", user.getScaleUnit(), requestedUnit);
|
Timber.d("Set scale unit to %s (%d)", user.getScaleUnit(), requestedUnit);
|
||||||
sendCommand(CMD_SET_UNIT, requestedUnit);
|
sendCommand(CMD_SET_UNIT, requestedUnit);
|
||||||
} else {
|
} else {
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -491,7 +453,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
if (data[3] == 0) {
|
if (data[3] == 0) {
|
||||||
Timber.d("Scale unit successfully set");
|
Timber.d("Scale unit successfully set");
|
||||||
}
|
}
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_USER_LIST:
|
case CMD_USER_LIST:
|
||||||
@@ -499,7 +461,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
int maxUserCount = data[5] & 0xFF;
|
int maxUserCount = data[5] & 0xFF;
|
||||||
Timber.d("Have %d users (max is %d)", userCount, maxUserCount);
|
Timber.d("Have %d users (max is %d)", userCount, maxUserCount);
|
||||||
if (userCount == 0) {
|
if (userCount == 0) {
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
// Otherwise wait for CMD_USER_INFO notifications
|
// Otherwise wait for CMD_USER_INFO notifications
|
||||||
break;
|
break;
|
||||||
@@ -508,8 +470,9 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
int measurementCount = data[3] & 0xFF;
|
int measurementCount = data[3] & 0xFF;
|
||||||
if (measurementCount == 0) {
|
if (measurementCount == 0) {
|
||||||
// Skip delete all measurements step (since there are no measurements to delete)
|
// Skip delete all measurements step (since there are no measurements to delete)
|
||||||
repeatMachineStateSteps(1);
|
Timber.d("No saved measurements found for user " + currentRemoteUser.name);
|
||||||
resumeMachineState(true);
|
jumpNextToStepNr(5);
|
||||||
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
// Otherwise wait for CMD_SAVED_MEASUREMENT notifications which will,
|
// Otherwise wait for CMD_SAVED_MEASUREMENT notifications which will,
|
||||||
// once all measurements have been received, resume the state machine.
|
// once all measurements have been received, resume the state machine.
|
||||||
@@ -517,9 +480,9 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
|
|
||||||
case CMD_DELETE_SAVED_MEASUREMENTS:
|
case CMD_DELETE_SAVED_MEASUREMENTS:
|
||||||
if (data[3] == 0) {
|
if (data[3] == 0) {
|
||||||
Timber.d("Saved measurements successfully deleted");
|
Timber.d("Saved measurements successfully deleted for user " + currentRemoteUser.name);
|
||||||
}
|
}
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_USER_ADD:
|
case CMD_USER_ADD:
|
||||||
@@ -533,7 +496,10 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
|
|
||||||
Timber.d("Cannot create additional scale user (error 0x%02x)", data[3]);
|
Timber.d("Cannot create additional scale user (error 0x%02x)", data[3]);
|
||||||
sendMessage(R.string.error_max_scale_users, 0);
|
sendMessage(R.string.error_max_scale_users, 0);
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
// Force disconnect
|
||||||
|
Timber.d("Send disconnect command to scale");
|
||||||
|
jumpNextToStepNr(8);
|
||||||
|
resumeMachineState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DO_MEASUREMENT:
|
case CMD_DO_MEASUREMENT:
|
||||||
@@ -556,7 +522,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
Timber.d("Name: %s, Birthday: %d-%02d-%02d, Height: %d, Sex: %s, activity: %d",
|
Timber.d("Name: %s, Birthday: %d-%02d-%02d, Height: %d, Sex: %s, activity: %d",
|
||||||
name, year, month, day, height, male ? "male" : "female", activity);
|
name, year, month, day, height, male ? "male" : "female", activity);
|
||||||
}
|
}
|
||||||
resumeMachineState(true);
|
resumeMachineState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -596,7 +562,7 @@ public class BluetoothBeurerSanitas extends BluetoothCommunication {
|
|||||||
receivedMeasurement.setMuscle(muscle);
|
receivedMeasurement.setMuscle(muscle);
|
||||||
receivedMeasurement.setBone(bone);
|
receivedMeasurement.setBone(bone);
|
||||||
|
|
||||||
addScaleData(receivedMeasurement);
|
addScaleMeasurement(receivedMeasurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBytes(byte[] data) {
|
private void writeBytes(byte[] data) {
|
||||||
|
@@ -38,40 +38,38 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.Single;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.exceptions.UndeliverableException;
|
import io.reactivex.exceptions.UndeliverableException;
|
||||||
import io.reactivex.plugins.RxJavaPlugins;
|
import io.reactivex.plugins.RxJavaPlugins;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.PublishSubject;
|
import io.reactivex.subjects.PublishSubject;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static android.content.Context.LOCATION_SERVICE;
|
import static android.content.Context.LOCATION_SERVICE;
|
||||||
|
|
||||||
public abstract class BluetoothCommunication {
|
public abstract class BluetoothCommunication {
|
||||||
public enum BT_STATUS_CODE {
|
public enum BT_STATUS {
|
||||||
BT_RETRIEVE_SCALE_DATA,
|
RETRIEVE_SCALE_DATA,
|
||||||
BT_INIT_PROCESS,
|
INIT_PROCESS,
|
||||||
BT_CONNECTION_RETRYING,
|
CONNECTION_RETRYING,
|
||||||
BT_CONNECTION_ESTABLISHED,
|
CONNECTION_ESTABLISHED,
|
||||||
BT_CONNECTION_DISCONNECT,
|
CONNECTION_DISCONNECT,
|
||||||
BT_CONNECTION_LOST,
|
CONNECTION_LOST,
|
||||||
BT_NO_DEVICE_FOUND,
|
NO_DEVICE_FOUND,
|
||||||
BT_UNEXPECTED_ERROR,
|
UNEXPECTED_ERROR,
|
||||||
BT_SCALE_MESSAGE
|
SCALE_MESSAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BT_MACHINE_STATE {
|
private int stepNr;
|
||||||
BT_INIT_STATE,
|
private boolean stopped;
|
||||||
BT_CMD_STATE,
|
|
||||||
BT_CLEANUP_STATE,
|
|
||||||
BT_STOPPED_STATE
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int BT_RETRY_TIMES_ON_ERROR = 3;
|
|
||||||
|
|
||||||
protected Context context;
|
protected Context context;
|
||||||
|
|
||||||
|
private final int BT_RETRY_TIMES_ON_ERROR = 3;
|
||||||
|
|
||||||
private RxBleClient bleClient;
|
private RxBleClient bleClient;
|
||||||
private RxBleDevice bleDevice;
|
private RxBleDevice bleDevice;
|
||||||
private Observable<RxBleConnection> connectionObservable;
|
private Observable<RxBleConnection> connectionObservable;
|
||||||
@@ -80,13 +78,6 @@ public abstract class BluetoothCommunication {
|
|||||||
private PublishSubject<Boolean> disconnectTriggerSubject = PublishSubject.create();
|
private PublishSubject<Boolean> disconnectTriggerSubject = PublishSubject.create();
|
||||||
|
|
||||||
private Handler callbackBtHandler;
|
private Handler callbackBtHandler;
|
||||||
|
|
||||||
private int cmdStepNr;
|
|
||||||
private int initStepNr;
|
|
||||||
private int cleanupStepNr;
|
|
||||||
private BT_MACHINE_STATE btMachineState;
|
|
||||||
private BT_MACHINE_STATE btStopppedMachineState;
|
|
||||||
|
|
||||||
private Handler disconnectHandler;
|
private Handler disconnectHandler;
|
||||||
|
|
||||||
public BluetoothCommunication(Context context)
|
public BluetoothCommunication(Context context)
|
||||||
@@ -95,6 +86,8 @@ public abstract class BluetoothCommunication {
|
|||||||
this.bleClient = OpenScale.getInstance().getBleClient();
|
this.bleClient = OpenScale.getInstance().getBleClient();
|
||||||
this.scanSubscription = null;
|
this.scanSubscription = null;
|
||||||
this.disconnectHandler = new Handler();
|
this.disconnectHandler = new Handler();
|
||||||
|
this.stepNr = 0;
|
||||||
|
this.stopped = false;
|
||||||
|
|
||||||
RxJavaPlugins.setErrorHandler(e -> {
|
RxJavaPlugins.setErrorHandler(e -> {
|
||||||
if (e instanceof UndeliverableException && e.getCause() instanceof BleException) {
|
if (e instanceof UndeliverableException && e.getCause() instanceof BleException) {
|
||||||
@@ -126,7 +119,7 @@ public abstract class BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a callback Bluetooth handler that notify any BT_STATUS_CODE changes for GUI/CORE.
|
* Register a callback Bluetooth handler that notify any BT_STATUS changes for GUI/CORE.
|
||||||
*
|
*
|
||||||
* @param cbBtHandler a handler that is registered
|
* @param cbBtHandler a handler that is registered
|
||||||
*/
|
*/
|
||||||
@@ -137,10 +130,10 @@ public abstract class BluetoothCommunication {
|
|||||||
/**
|
/**
|
||||||
* Set for the openScale GUI/CORE the Bluetooth status code.
|
* Set for the openScale GUI/CORE the Bluetooth status code.
|
||||||
*
|
*
|
||||||
* @param statusCode the status code that should be set
|
* @param status the status code that should be set
|
||||||
*/
|
*/
|
||||||
protected void setBtStatus(BT_STATUS_CODE statusCode) {
|
protected void setBluetoothStatus(BT_STATUS status) {
|
||||||
setBtStatus(statusCode, "");
|
setBluetoothStatus(status, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,7 +142,7 @@ public abstract class BluetoothCommunication {
|
|||||||
* @param statusCode the status code that should be set
|
* @param statusCode the status code that should be set
|
||||||
* @param infoText the information text that is displayed to the status code.
|
* @param infoText the information text that is displayed to the status code.
|
||||||
*/
|
*/
|
||||||
protected void setBtStatus(BT_STATUS_CODE statusCode, String infoText) {
|
protected void setBluetoothStatus(BT_STATUS statusCode, String infoText) {
|
||||||
if (callbackBtHandler != null) {
|
if (callbackBtHandler != null) {
|
||||||
callbackBtHandler.obtainMessage(
|
callbackBtHandler.obtainMessage(
|
||||||
statusCode.ordinal(), infoText).sendToTarget();
|
statusCode.ordinal(), infoText).sendToTarget();
|
||||||
@@ -161,10 +154,10 @@ public abstract class BluetoothCommunication {
|
|||||||
*
|
*
|
||||||
* @param scaleMeasurement the scale data that should be added to openScale
|
* @param scaleMeasurement the scale data that should be added to openScale
|
||||||
*/
|
*/
|
||||||
protected void addScaleData(ScaleMeasurement scaleMeasurement) {
|
protected void addScaleMeasurement(ScaleMeasurement scaleMeasurement) {
|
||||||
if (callbackBtHandler != null) {
|
if (callbackBtHandler != null) {
|
||||||
callbackBtHandler.obtainMessage(
|
callbackBtHandler.obtainMessage(
|
||||||
BT_STATUS_CODE.BT_RETRIEVE_SCALE_DATA.ordinal(), scaleMeasurement).sendToTarget();
|
BT_STATUS.RETRIEVE_SCALE_DATA.ordinal(), scaleMeasurement).sendToTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +170,7 @@ public abstract class BluetoothCommunication {
|
|||||||
protected void sendMessage(int msg, Object value) {
|
protected void sendMessage(int msg, Object value) {
|
||||||
if (callbackBtHandler != null) {
|
if (callbackBtHandler != null) {
|
||||||
callbackBtHandler.obtainMessage(
|
callbackBtHandler.obtainMessage(
|
||||||
BT_STATUS_CODE.BT_SCALE_MESSAGE.ordinal(), msg, 0, value).sendToTarget();
|
BT_STATUS.SCALE_MESSAGE.ordinal(), msg, 0, value).sendToTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,70 +184,10 @@ public abstract class BluetoothCommunication {
|
|||||||
/**
|
/**
|
||||||
* State machine for the initialization process of the Bluetooth device.
|
* State machine for the initialization process of the Bluetooth device.
|
||||||
*
|
*
|
||||||
* @param stateNr the current step number
|
* @param stepNr the current step number
|
||||||
* @return false if no next step is available otherwise true
|
* @return false if no next step is available otherwise true
|
||||||
*/
|
*/
|
||||||
abstract protected boolean nextInitCmd(int stateNr);
|
abstract protected boolean onNextStep(int stepNr);
|
||||||
|
|
||||||
/**
|
|
||||||
* State machine for the normal/command process of the Bluetooth device.
|
|
||||||
*
|
|
||||||
* This state machine is automatically triggered if initialization process is finished.
|
|
||||||
*
|
|
||||||
* @param stateNr the current step number
|
|
||||||
* @return false if no next step is available otherwise true
|
|
||||||
*/
|
|
||||||
abstract protected boolean nextBluetoothCmd(int stateNr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Step the current machine state backwards. Needs to be called before a command.
|
|
||||||
*
|
|
||||||
* @param steps Number of steps to back the machine.
|
|
||||||
*/
|
|
||||||
protected void repeatMachineStateSteps(int steps) {
|
|
||||||
switch (btMachineState) {
|
|
||||||
case BT_INIT_STATE:
|
|
||||||
initStepNr = initStepNr - steps;
|
|
||||||
break;
|
|
||||||
case BT_CMD_STATE:
|
|
||||||
cmdStepNr = cmdStepNr - steps;
|
|
||||||
break;
|
|
||||||
case BT_CLEANUP_STATE:
|
|
||||||
cleanupStepNr = cleanupStepNr - steps;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stopped the current machine state
|
|
||||||
*/
|
|
||||||
protected void stopMachineState() {
|
|
||||||
Timber.d("Machine state stopped");
|
|
||||||
btStopppedMachineState = btMachineState;
|
|
||||||
btMachineState = BT_MACHINE_STATE.BT_STOPPED_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resumed the current machine state
|
|
||||||
*/
|
|
||||||
protected void resumeMachineState(boolean doNextStep) {
|
|
||||||
Timber.d("Machine state resumed");
|
|
||||||
btMachineState = btStopppedMachineState;
|
|
||||||
|
|
||||||
if (doNextStep) {
|
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* State machine for the clean up process for the Bluetooth device.
|
|
||||||
*
|
|
||||||
* This state machine is *not* automatically triggered. You have to setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE) to trigger this process if necessary.
|
|
||||||
*
|
|
||||||
* @param stateNr the current step number
|
|
||||||
* @return false if no next step is available otherwise true
|
|
||||||
*/
|
|
||||||
abstract protected boolean nextCleanUpCmd(int stateNr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method is triggered if a Bluetooth data is read from a device.
|
* Method is triggered if a Bluetooth data is read from a device.
|
||||||
@@ -279,17 +212,20 @@ public abstract class BluetoothCommunication {
|
|||||||
*/
|
*/
|
||||||
protected void onBluetoothDiscovery(RxBleDeviceServices rxBleDeviceServices) { }
|
protected void onBluetoothDiscovery(RxBleDeviceServices rxBleDeviceServices) { }
|
||||||
|
|
||||||
/**
|
protected synchronized void stopMachineState() {
|
||||||
* Set the Bluetooth machine state to a specific state.
|
Timber.d("Stop machine state");
|
||||||
*
|
stopped = true;
|
||||||
* @note after setting a new state the next step is automatically triggered.
|
}
|
||||||
*
|
|
||||||
* @param btMachineState the machine state that should be set.
|
|
||||||
*/
|
|
||||||
protected void setBtMachineState(BT_MACHINE_STATE btMachineState) {
|
|
||||||
this.btMachineState = btMachineState;
|
|
||||||
|
|
||||||
nextMachineStateStep();
|
protected synchronized void resumeMachineState() {
|
||||||
|
Timber.d("Resume machine state");
|
||||||
|
stopped = false;
|
||||||
|
nextMachineStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized void jumpNextToStepNr(int nr) {
|
||||||
|
Timber.d("Jump next to step nr " + nr);
|
||||||
|
stepNr = nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -297,22 +233,25 @@ public abstract class BluetoothCommunication {
|
|||||||
* @param characteristic the Bluetooth UUID characteristic
|
* @param characteristic the Bluetooth UUID characteristic
|
||||||
* @param bytes the bytes that should be write
|
* @param bytes the bytes that should be write
|
||||||
*/
|
*/
|
||||||
protected void writeBytes(UUID characteristic, byte[] bytes) {
|
protected Observable<byte[]> writeBytes(UUID characteristic, byte[] bytes) {
|
||||||
final Disposable disposable = connectionObservable
|
Timber.d("Invoke write bytes [" + byteInHex(bytes) + "] on " + BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
|
Observable<byte[]> observable = connectionObservable
|
||||||
.flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristic, bytes))
|
.flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristic, bytes))
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.retry(BT_RETRY_TIMES_ON_ERROR);
|
||||||
.subscribe(
|
|
||||||
|
compositeDisposable.add(observable.subscribe(
|
||||||
value -> {
|
value -> {
|
||||||
Timber.d("Write characteristic %s: %s",
|
Timber.d("Write characteristic %s: %s",
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
byteInHex(value));
|
byteInHex(value));
|
||||||
nextMachineStateStep();
|
|
||||||
},
|
},
|
||||||
throwable -> onError(throwable)
|
throwable -> onError(throwable)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,20 +260,25 @@ public abstract class BluetoothCommunication {
|
|||||||
* @note onBluetoothRead() will be triggered if read command was successful. nextMachineStep() needs to manually called!
|
* @note onBluetoothRead() will be triggered if read command was successful. nextMachineStep() needs to manually called!
|
||||||
*@param characteristic the Bluetooth UUID characteristic
|
*@param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void readBytes(UUID characteristic) {
|
protected Single<byte[]> readBytes(UUID characteristic) {
|
||||||
final Disposable disposable = connectionObservable
|
Timber.d("Invoke read bytes on " + BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
|
Single<byte[]> observable = connectionObservable
|
||||||
.firstOrError()
|
.firstOrError()
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristic))
|
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristic))
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.retry(BT_RETRY_TIMES_ON_ERROR);
|
||||||
|
|
||||||
|
compositeDisposable.add(observable
|
||||||
.subscribe(bytes -> {
|
.subscribe(bytes -> {
|
||||||
Timber.d("Read characteristic %s", BluetoothGattUuid.prettyPrint(characteristic));
|
Timber.d("Read characteristic %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
onBluetoothRead(characteristic, bytes);
|
onBluetoothRead(characteristic, bytes);
|
||||||
},
|
},
|
||||||
throwable -> onError(throwable)
|
throwable -> onError(throwable)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,29 +286,32 @@ public abstract class BluetoothCommunication {
|
|||||||
*
|
*
|
||||||
* @param characteristic the Bluetooth UUID characteristic
|
* @param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void setIndicationOn(UUID characteristic) {
|
protected Observable<byte[]> setIndicationOn(UUID characteristic) {
|
||||||
final Disposable disposable = connectionObservable
|
Timber.d("Invoke set indication on " + BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
|
Observable<byte[]> observable = connectionObservable
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.setupIndication(characteristic))
|
.flatMap(rxBleConnection -> rxBleConnection.setupIndication(characteristic))
|
||||||
.doOnNext(notificationObservable -> {
|
.doOnNext(notificationObservable -> {
|
||||||
Timber.d("Successful set indication on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
Timber.d("Successful set indication on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
nextMachineStateStep();
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.flatMap(indicationObservable -> indicationObservable)
|
.flatMap(indicationObservable -> indicationObservable)
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.retry(BT_RETRY_TIMES_ON_ERROR);
|
||||||
.subscribe(
|
|
||||||
|
compositeDisposable.add(observable.subscribe(
|
||||||
bytes -> {
|
bytes -> {
|
||||||
onBluetoothNotify(characteristic, bytes);
|
|
||||||
Timber.d("onCharacteristicChanged %s: %s",
|
Timber.d("onCharacteristicChanged %s: %s",
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
byteInHex(bytes));
|
byteInHex(bytes));
|
||||||
|
onBluetoothNotify(characteristic, bytes);
|
||||||
resetDisconnectTimer();
|
resetDisconnectTimer();
|
||||||
},
|
},
|
||||||
throwable -> onError(throwable)
|
throwable -> onError(throwable)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,46 +319,69 @@ public abstract class BluetoothCommunication {
|
|||||||
*
|
*
|
||||||
* @param characteristic the Bluetooth UUID characteristic
|
* @param characteristic the Bluetooth UUID characteristic
|
||||||
*/
|
*/
|
||||||
protected void setNotificationOn(UUID characteristic) {
|
protected Observable<byte[]> setNotificationOn(UUID characteristic) {
|
||||||
final Disposable disposable = connectionObservable
|
Timber.d("Invoke set notification on " + BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
|
stopped = true;
|
||||||
|
Observable<byte[]> observable = connectionObservable
|
||||||
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristic))
|
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristic))
|
||||||
.doOnNext(notificationObservable -> {
|
.doOnNext(notificationObservable -> {
|
||||||
Timber.d("Successful set notification on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
Timber.d("Successful set notification on for %s", BluetoothGattUuid.prettyPrint(characteristic));
|
||||||
nextMachineStateStep();
|
stopped = false;
|
||||||
|
nextMachineStep();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.flatMap(notificationObservable -> notificationObservable)
|
.flatMap(notificationObservable -> notificationObservable)
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.retry(BT_RETRY_TIMES_ON_ERROR);
|
||||||
.subscribe(
|
|
||||||
|
compositeDisposable.add(observable.subscribe(
|
||||||
bytes -> {
|
bytes -> {
|
||||||
onBluetoothNotify(characteristic, bytes);
|
|
||||||
Timber.d("onCharacteristicChanged %s: %s",
|
Timber.d("onCharacteristicChanged %s: %s",
|
||||||
BluetoothGattUuid.prettyPrint(characteristic),
|
BluetoothGattUuid.prettyPrint(characteristic),
|
||||||
byteInHex(bytes));
|
byteInHex(bytes));
|
||||||
|
onBluetoothNotify(characteristic, bytes);
|
||||||
resetDisconnectTimer();
|
resetDisconnectTimer();
|
||||||
},
|
},
|
||||||
throwable -> onError(throwable)
|
throwable -> onError(throwable)
|
||||||
);
|
));
|
||||||
|
|
||||||
compositeDisposable.add(disposable);
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doBluetoothDiscoverServices() {
|
protected Observable<RxBleDeviceServices> discoverBluetoothServices() {
|
||||||
final Disposable connectionDisposable = connectionObservable
|
Timber.d("Invoke discover Bluetooth services");
|
||||||
|
final Observable<RxBleDeviceServices> observable = connectionObservable
|
||||||
.flatMapSingle(RxBleConnection::discoverServices)
|
.flatMapSingle(RxBleConnection::discoverServices)
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.retry(BT_RETRY_TIMES_ON_ERROR)
|
.retry(BT_RETRY_TIMES_ON_ERROR);
|
||||||
.subscribe(
|
|
||||||
|
compositeDisposable.add(observable.subscribe(
|
||||||
deviceServices -> {
|
deviceServices -> {
|
||||||
Timber.d("Successful Bluetooth services discovered");
|
Timber.d("Successful Bluetooth services discovered");
|
||||||
onBluetoothDiscovery(deviceServices);
|
onBluetoothDiscovery(deviceServices);
|
||||||
nextMachineStateStep();
|
|
||||||
},
|
},
|
||||||
throwable -> onError(throwable)
|
throwable -> onError(throwable)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
compositeDisposable.add(connectionDisposable);
|
return observable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect from a Bluetooth device
|
||||||
|
*/
|
||||||
|
public void disconnect() {
|
||||||
|
Timber.d("Bluetooth disconnect");
|
||||||
|
setBluetoothStatus(BT_STATUS.CONNECTION_DISCONNECT);
|
||||||
|
if (scanSubscription != null) {
|
||||||
|
scanSubscription.dispose();
|
||||||
|
}
|
||||||
|
callbackBtHandler = null;
|
||||||
|
disconnectHandler.removeCallbacksAndMessages(null);
|
||||||
|
disconnectTriggerSubject.onNext(true);
|
||||||
|
compositeDisposable.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -496,11 +466,12 @@ public abstract class BluetoothCommunication {
|
|||||||
//.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
|
//.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(bleScanResult -> {
|
.subscribe(bleScanResult -> {
|
||||||
if (bleScanResult.getBleDevice().getMacAddress().equals(macAddress)) {
|
if (bleScanResult.getBleDevice().getMacAddress().equals(macAddress)) {
|
||||||
connectToDevice(macAddress);
|
connectToDevice(macAddress);
|
||||||
}}, throwable -> setBtStatus(BT_STATUS_CODE.BT_NO_DEVICE_FOUND));
|
}}, throwable -> setBluetoothStatus(BT_STATUS.NO_DEVICE_FOUND));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Timber.d("No coarse location permission, connecting without LE scan");
|
Timber.d("No coarse location permission, connecting without LE scan");
|
||||||
@@ -515,7 +486,6 @@ public abstract class BluetoothCommunication {
|
|||||||
Timber.d("Stop Le san");
|
Timber.d("Stop Le san");
|
||||||
scanSubscription.dispose();
|
scanSubscription.dispose();
|
||||||
scanSubscription = null;
|
scanSubscription = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
@@ -527,19 +497,18 @@ public abstract class BluetoothCommunication {
|
|||||||
connectionObservable = bleDevice
|
connectionObservable = bleDevice
|
||||||
.establishConnection(false)
|
.establishConnection(false)
|
||||||
.takeUntil(disconnectTriggerSubject)
|
.takeUntil(disconnectTriggerSubject)
|
||||||
.doOnError(throwable -> setBtStatus(BT_STATUS_CODE.BT_CONNECTION_RETRYING))
|
.doOnError(throwable -> setBluetoothStatus(BT_STATUS.CONNECTION_RETRYING))
|
||||||
|
.subscribeOn(Schedulers.trampoline())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.compose(ReplayingShare.instance());
|
.compose(ReplayingShare.instance());
|
||||||
|
|
||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
disconnect();
|
disconnect();
|
||||||
} else {
|
} else {
|
||||||
initStepNr = -1;
|
stepNr = 0;
|
||||||
cmdStepNr = -1;
|
|
||||||
cleanupStepNr = -1;
|
|
||||||
|
|
||||||
setBtMonitoringOn();
|
setBtMonitoringOn();
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_INIT_STATE);
|
nextMachineStep();
|
||||||
resetDisconnectTimer();
|
resetDisconnectTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,7 +521,7 @@ public abstract class BluetoothCommunication {
|
|||||||
connectionState -> {
|
connectionState -> {
|
||||||
switch (connectionState) {
|
switch (connectionState) {
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_ESTABLISHED);
|
setBluetoothStatus(BT_STATUS.CONNECTION_ESTABLISHED);
|
||||||
break;
|
break;
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
// empty
|
// empty
|
||||||
@@ -561,7 +530,7 @@ public abstract class BluetoothCommunication {
|
|||||||
// empty
|
// empty
|
||||||
break;
|
break;
|
||||||
case DISCONNECTED:
|
case DISCONNECTED:
|
||||||
// setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
// setBluetoothStatus(BT_STATUS.CONNECTION_LOST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -571,20 +540,20 @@ public abstract class BluetoothCommunication {
|
|||||||
compositeDisposable.add(disposableConnectionState);
|
compositeDisposable.add(disposableConnectionState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onError(Throwable throwable) {
|
protected void onError(Throwable throwable) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, throwable.getMessage());
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, throwable.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConnected() {
|
private boolean isConnected() {
|
||||||
return bleDevice.getConnectionState() == RxBleConnection.RxBleConnectionState.CONNECTED;
|
return bleDevice.getConnectionState() == RxBleConnection.RxBleConnectionState.CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetDisconnectTimer() {
|
private void resetDisconnectTimer() {
|
||||||
disconnectHandler.removeCallbacksAndMessages(null);
|
disconnectHandler.removeCallbacksAndMessages(null);
|
||||||
disconnectWithDelay();
|
disconnectWithDelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnectWithDelay() {
|
private void disconnectWithDelay() {
|
||||||
disconnectHandler.postDelayed(new Runnable() {
|
disconnectHandler.postDelayed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -594,48 +563,16 @@ public abstract class BluetoothCommunication {
|
|||||||
}, 60000); // 60s timeout
|
}, 60000); // 60s timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private synchronized void nextMachineStep() {
|
||||||
* Disconnect from a Bluetooth device
|
if (!stopped) {
|
||||||
*/
|
Timber.d("Step Nr " + stepNr);
|
||||||
public void disconnect() {
|
if (onNextStep(stepNr)) {
|
||||||
Timber.d("Bluetooth disconnect");
|
stepNr++;
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_DISCONNECT);
|
nextMachineStep();
|
||||||
if (scanSubscription != null) {
|
} else {
|
||||||
scanSubscription.dispose();
|
Timber.d("Invoke delayed disconnect in 60s");
|
||||||
}
|
|
||||||
callbackBtHandler = null;
|
|
||||||
disconnectHandler.removeCallbacksAndMessages(null);
|
|
||||||
disconnectTriggerSubject.onNext(true);
|
|
||||||
compositeDisposable.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke next step for internal Bluetooth state machine.
|
|
||||||
*/
|
|
||||||
protected void nextMachineStateStep() {
|
|
||||||
switch (btMachineState) {
|
|
||||||
case BT_INIT_STATE:
|
|
||||||
initStepNr++;
|
|
||||||
Timber.d("INIT STATE: %d", initStepNr);
|
|
||||||
if (!nextInitCmd(initStepNr)) {
|
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CMD_STATE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BT_CMD_STATE:
|
|
||||||
cmdStepNr++;
|
|
||||||
Timber.d("CMD STATE: %d", cmdStepNr);
|
|
||||||
if (!nextBluetoothCmd(cmdStepNr)) {
|
|
||||||
disconnectWithDelay();
|
disconnectWithDelay();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case BT_CLEANUP_STATE:
|
|
||||||
cleanupStepNr++;
|
|
||||||
Timber.d("CLEANUP STATE: %d", cleanupStepNr);
|
|
||||||
if (!nextCleanUpCmd(cleanupStepNr)) {
|
|
||||||
Timber.d("Cleanup Bluetooth disconnect");
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ package com.health.openscale.core.bluetooth;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
||||||
import com.polidea.rxandroidble2.RxBleClient;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -44,8 +43,8 @@ public class BluetoothCustomOpenScale extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC
|
||||||
);
|
);
|
||||||
@@ -70,16 +69,6 @@ public class BluetoothCustomOpenScale extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearEEPROM()
|
public void clearEEPROM()
|
||||||
{
|
{
|
||||||
byte[] cmd = {(byte)'9'};
|
byte[] cmd = {(byte)'9'};
|
||||||
@@ -106,7 +95,7 @@ public class BluetoothCustomOpenScale extends BluetoothCommunication {
|
|||||||
btString = btString.substring(0, btString.length() - 1); // delete newline '\n' of the string
|
btString = btString.substring(0, btString.length() - 1); // delete newline '\n' of the string
|
||||||
|
|
||||||
if (btString.charAt(0) != '$' && btString.charAt(2) != '$') {
|
if (btString.charAt(0) != '$' && btString.charAt(2) != '$') {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Parse error of bluetooth string. String has not a valid format: " + btString);
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Parse error of bluetooth string. String has not a valid format: " + btString);
|
||||||
}
|
}
|
||||||
|
|
||||||
String btMsg = btString.substring(3, btString.length()); // message string
|
String btMsg = btString.substring(3, btString.length()); // message string
|
||||||
@@ -156,18 +145,18 @@ public class BluetoothCustomOpenScale extends BluetoothCommunication {
|
|||||||
scaleBtData.setWater(Float.parseFloat(csvField[8]));
|
scaleBtData.setWater(Float.parseFloat(csvField[8]));
|
||||||
scaleBtData.setMuscle(Float.parseFloat(csvField[9]));
|
scaleBtData.setMuscle(Float.parseFloat(csvField[9]));
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
} else {
|
} else {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Error calculated checksum (" + checksum + ") and received checksum (" + btChecksum + ") is different");
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Error calculated checksum (" + checksum + ") and received checksum (" + btChecksum + ") is different");
|
||||||
}
|
}
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Error while decoding a number of bluetooth string (" + e.getMessage() + ")");
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Error while decoding a number of bluetooth string (" + e.getMessage() + ")");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Error unknown MCU command : " + btString);
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Error unknown MCU command : " + btString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -164,14 +164,14 @@ public class BluetoothDebug extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr)
|
switch (stepNr)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
doBluetoothDiscoverServices();
|
discoverBluetoothServices();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
int offset = stateNr;
|
int offset = stepNr;
|
||||||
|
|
||||||
for (BluetoothGattService service : rxBleDeviceServices.getBluetoothGattServices()) {
|
for (BluetoothGattService service : rxBleDeviceServices.getBluetoothGattServices()) {
|
||||||
offset = readServiceCharacteristics(service, offset);
|
offset = readServiceCharacteristics(service, offset);
|
||||||
@@ -181,7 +181,7 @@ public class BluetoothDebug extends BluetoothCommunication {
|
|||||||
logService(service, false);
|
logService(service, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
setBluetoothStatus(BT_STATUS.CONNECTION_LOST);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
disconnect();
|
disconnect();
|
||||||
@@ -192,14 +192,4 @@ public class BluetoothDebug extends BluetoothCommunication {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -56,8 +56,8 @@ public class BluetoothDigooDGSO38H extends BluetoothCommunication {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
//Tell device to send us weight measurements
|
//Tell device to send us weight measurements
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
@@ -65,19 +65,11 @@ public class BluetoothDigooDGSO38H extends BluetoothCommunication {
|
|||||||
case 1:
|
case 1:
|
||||||
sendMessage(R.string.info_step_on_scale, 0);
|
sendMessage(R.string.info_step_on_scale, 0);
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return true;
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseBytes(byte[] weightBytes) {
|
private void parseBytes(byte[] weightBytes) {
|
||||||
@@ -135,7 +127,7 @@ public class BluetoothDigooDGSO38H extends BluetoothCommunication {
|
|||||||
scaleBtData.setVisceralFat(visceralFat);
|
scaleBtData.setVisceralFat(visceralFat);
|
||||||
}
|
}
|
||||||
scaleBtData.setWeight(weight);
|
scaleBtData.setWeight(weight);
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -44,13 +44,8 @@ public class BluetoothExcelvanCF36xBLE extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
return false;
|
switch (stepNr) {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
case 0:
|
||||||
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
||||||
|
|
||||||
@@ -103,12 +98,7 @@ public class BluetoothExcelvanCF36xBLE extends BluetoothCommunication {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -150,6 +140,6 @@ public class BluetoothExcelvanCF36xBLE extends BluetoothCommunication {
|
|||||||
scaleBtData.setBone(bone);
|
scaleBtData.setBone(bone);
|
||||||
scaleBtData.setVisceralFat(visceralFat);
|
scaleBtData.setVisceralFat(visceralFat);
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,11 +42,10 @@ public class BluetoothExingtechY1 extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
||||||
@@ -71,16 +70,6 @@ public class BluetoothExingtechY1 extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -118,6 +107,6 @@ public class BluetoothExingtechY1 extends BluetoothCommunication {
|
|||||||
scaleBtData.setVisceralFat(visc_fat);
|
scaleBtData.setVisceralFat(visc_fat);
|
||||||
scaleBtData.setDateTime(new Date());
|
scaleBtData.setDateTime(new Date());
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,8 +39,8 @@ public class BluetoothHesley extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
break;
|
break;
|
||||||
@@ -58,16 +58,6 @@ public class BluetoothHesley extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -101,6 +91,6 @@ public class BluetoothHesley extends BluetoothCommunication {
|
|||||||
scaleBtData.setBone(bone);
|
scaleBtData.setBone(bone);
|
||||||
scaleBtData.setDateTime(new Date());
|
scaleBtData.setDateTime(new Date());
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -23,14 +23,13 @@ import android.bluetooth.BluetoothSocket;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
||||||
import com.polidea.rxandroidble2.RxBleClient;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -57,20 +56,8 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
Timber.w("ihealthHS3 - nextInitCmd - returning false");
|
Timber.w("ihealthHS3 - onNextStep - returning false");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
Timber.w("ihealthHS3 - nextBluetoothCmd - returning false");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
Timber.w("ihealthHS3 - nextCleanUpCmd - returning false");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +66,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
|
||||||
if (btAdapter == null) {
|
if (btAdapter == null) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_NO_DEVICE_FOUND);
|
setBluetoothStatus(BT_STATUS.NO_DEVICE_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +75,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
// Get a BluetoothSocket to connect with the given BluetoothDevice
|
// Get a BluetoothSocket to connect with the given BluetoothDevice
|
||||||
btSocket = btDevice.createRfcommSocketToServiceRecord(uuid);
|
btSocket = btDevice.createRfcommSocketToServiceRecord(uuid);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Can't get a bluetooth socket");
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Can't get a bluetooth socket");
|
||||||
btDevice = null;
|
btDevice = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -103,7 +90,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
btSocket.connect();
|
btSocket.connect();
|
||||||
|
|
||||||
// Bluetooth connection was successful
|
// Bluetooth connection was successful
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_ESTABLISHED);
|
setBluetoothStatus(BT_STATUS.CONNECTION_ESTABLISHED);
|
||||||
|
|
||||||
btConnectThread = new BluetoothConnectedThread();
|
btConnectThread = new BluetoothConnectedThread();
|
||||||
btConnectThread.start();
|
btConnectThread.start();
|
||||||
@@ -111,7 +98,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
} catch (IOException connectException) {
|
} catch (IOException connectException) {
|
||||||
// Unable to connect; close the socket and get out
|
// Unable to connect; close the socket and get out
|
||||||
disconnect();
|
disconnect();
|
||||||
setBtStatus(BT_STATUS_CODE.BT_NO_DEVICE_FOUND);
|
setBluetoothStatus(BT_STATUS.NO_DEVICE_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -129,7 +116,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
btSocket.close();
|
btSocket.close();
|
||||||
btSocket = null;
|
btSocket = null;
|
||||||
} catch (IOException closeException) {
|
} catch (IOException closeException) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Can't close bluetooth socket");
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Can't close bluetooth socket");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +158,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
btInStream = btSocket.getInputStream();
|
btInStream = btSocket.getInputStream();
|
||||||
btOutStream = btSocket.getOutputStream();
|
btOutStream = btSocket.getOutputStream();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Can't get bluetooth input or output stream " + e.getMessage());
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Can't get bluetooth input or output stream " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +196,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
ScaleMeasurement scaleMeasurement = parseWeightArray(weightBytes);
|
ScaleMeasurement scaleMeasurement = parseWeightArray(weightBytes);
|
||||||
|
|
||||||
if (scaleMeasurement != null) {
|
if (scaleMeasurement != null) {
|
||||||
addScaleData(scaleMeasurement);
|
addScaleMeasurement(scaleMeasurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -227,7 +214,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
cancel();
|
cancel();
|
||||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
setBluetoothStatus(BT_STATUS.CONNECTION_LOST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +253,7 @@ public class BluetoothIhealthHS3 extends BluetoothCommunication {
|
|||||||
try {
|
try {
|
||||||
btOutStream.write(bytes);
|
btOutStream.write(bytes);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "Error while writing to bluetooth socket " + e.getMessage());
|
setBluetoothStatus(BT_STATUS.UNEXPECTED_ERROR, "Error while writing to bluetooth socket " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -73,8 +73,8 @@ public class BluetoothInlife extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
break;
|
break;
|
||||||
@@ -98,16 +98,6 @@ public class BluetoothInlife extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -229,7 +219,7 @@ public class BluetoothInlife extends BluetoothCommunication {
|
|||||||
measurement.setLbm(lbm);
|
measurement.setLbm(lbm);
|
||||||
measurement.setVisceralFat(clamp(visceral, 1, 50));
|
measurement.setVisceralFat(clamp(visceral, 1, 50));
|
||||||
|
|
||||||
addScaleData(measurement);
|
addScaleMeasurement(measurement);
|
||||||
|
|
||||||
sendCommand(0xd4);
|
sendCommand(0xd4);
|
||||||
}
|
}
|
||||||
|
@@ -82,8 +82,8 @@ public class BluetoothMGB extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(uuid_char_ctrl
|
setNotificationOn(uuid_char_ctrl
|
||||||
);
|
);
|
||||||
@@ -126,19 +126,6 @@ public class BluetoothMGB extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
packet_buf = value;
|
packet_buf = value;
|
||||||
@@ -202,7 +189,7 @@ public class BluetoothMGB extends BluetoothCommunication {
|
|||||||
popInt(); // unknown =02
|
popInt(); // unknown =02
|
||||||
popInt(); // unknown =47;48;4e;4b;42
|
popInt(); // unknown =47;48;4e;4b;42
|
||||||
|
|
||||||
addScaleData(measurement);
|
addScaleMeasurement(measurement);
|
||||||
|
|
||||||
// Visceral fat?
|
// Visceral fat?
|
||||||
// Standard weight?
|
// Standard weight?
|
||||||
|
@@ -51,13 +51,8 @@ public class BluetoothMedisanaBS44x extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
return false;
|
switch (stepNr) {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
case 0:
|
||||||
// set indication on for feature characteristic
|
// set indication on for feature characteristic
|
||||||
setIndicationOn(FEATURE_MEASUREMENT_CHARACTERISTIC);
|
setIndicationOn(FEATURE_MEASUREMENT_CHARACTERISTIC);
|
||||||
@@ -92,12 +87,6 @@ public class BluetoothMedisanaBS44x extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -109,7 +98,7 @@ public class BluetoothMedisanaBS44x extends BluetoothCommunication {
|
|||||||
if (characteristic.equals(FEATURE_MEASUREMENT_CHARACTERISTIC)) {
|
if (characteristic.equals(FEATURE_MEASUREMENT_CHARACTERISTIC)) {
|
||||||
parseFeatureData(data);
|
parseFeatureData(data);
|
||||||
|
|
||||||
addScaleData(btScaleMeasurement);
|
addScaleMeasurement(btScaleMeasurement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_STATUS_CODE.BT_UNEXPECTED_ERROR;
|
import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_STATUS.UNEXPECTED_ERROR;
|
||||||
|
|
||||||
public class BluetoothMiScale extends BluetoothCommunication {
|
public class BluetoothMiScale extends BluetoothCommunication {
|
||||||
private final UUID WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC = UUID.fromString("00002a2f-0000-3512-2118-0009af100700");
|
private final UUID WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC = UUID.fromString("00002a2f-0000-3512-2118-0009af100700");
|
||||||
@@ -60,11 +60,21 @@ public class BluetoothMiScale extends BluetoothCommunication {
|
|||||||
int scaleMonth = (int) data[2];
|
int scaleMonth = (int) data[2];
|
||||||
int scaleDay = (int) data[3];
|
int scaleDay = (int) data[3];
|
||||||
|
|
||||||
if (currentYear == scaleYear && currentMonth == scaleMonth && currentDay == scaleDay) {
|
if (!(currentYear == scaleYear && currentMonth == scaleMonth && currentDay == scaleDay)) {
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CMD_STATE);
|
|
||||||
} else {
|
|
||||||
Timber.d("Current year and scale year is different");
|
Timber.d("Current year and scale year is different");
|
||||||
nextMachineStateStep();
|
|
||||||
|
// set current time
|
||||||
|
Calendar currentDateTime = Calendar.getInstance();
|
||||||
|
int year = currentDateTime.get(Calendar.YEAR);
|
||||||
|
byte month = (byte)(currentDateTime.get(Calendar.MONTH)+1);
|
||||||
|
byte day = (byte)currentDateTime.get(Calendar.DAY_OF_MONTH);
|
||||||
|
byte hour = (byte)currentDateTime.get(Calendar.HOUR_OF_DAY);
|
||||||
|
byte min = (byte)currentDateTime.get(Calendar.MINUTE);
|
||||||
|
byte sec = (byte)currentDateTime.get(Calendar.SECOND);
|
||||||
|
|
||||||
|
byte[] dateTimeByte = {(byte)(year), (byte)(year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00};
|
||||||
|
|
||||||
|
writeBytes(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, dateTimeByte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +86,15 @@ public class BluetoothMiScale extends BluetoothCommunication {
|
|||||||
|
|
||||||
// Stop command from mi scale received
|
// Stop command from mi scale received
|
||||||
if (data[0] == 0x03) {
|
if (data[0] == 0x03) {
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
// send stop command to mi scale
|
||||||
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x03});
|
||||||
|
// acknowledge that you received the last history data
|
||||||
|
int uniqueNumber = getUniqueNumber();
|
||||||
|
|
||||||
|
byte[] userIdentifier = new byte[]{(byte)0x04, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||||
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||||
|
|
||||||
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length == 20) {
|
if (data.length == 20) {
|
||||||
@@ -95,82 +113,37 @@ public class BluetoothMiScale extends BluetoothCommunication {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
// read device time
|
// read device time
|
||||||
readBytes(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME);
|
readBytes(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// set current time
|
|
||||||
Calendar currentDateTime = Calendar.getInstance();
|
|
||||||
int year = currentDateTime.get(Calendar.YEAR);
|
|
||||||
byte month = (byte)(currentDateTime.get(Calendar.MONTH)+1);
|
|
||||||
byte day = (byte)currentDateTime.get(Calendar.DAY_OF_MONTH);
|
|
||||||
byte hour = (byte)currentDateTime.get(Calendar.HOUR_OF_DAY);
|
|
||||||
byte min = (byte)currentDateTime.get(Calendar.MINUTE);
|
|
||||||
byte sec = (byte)currentDateTime.get(Calendar.SECOND);
|
|
||||||
|
|
||||||
byte[] dateTimeByte = {(byte)(year), (byte)(year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00};
|
|
||||||
|
|
||||||
writeBytes(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, dateTimeByte);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Set on history weight measurement
|
// Set on history weight measurement
|
||||||
byte[] magicBytes = new byte[]{(byte)0x01, (byte)0x96, (byte)0x8a, (byte)0xbd, (byte)0x62};
|
byte[] magicBytes = new byte[]{(byte)0x01, (byte)0x96, (byte)0x8a, (byte)0xbd, (byte)0x62};
|
||||||
|
|
||||||
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, magicBytes);
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, magicBytes);
|
||||||
break;
|
break;
|
||||||
default:
|
case 2:
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// set notification on for weight measurement history
|
// set notification on for weight measurement history
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC);
|
setNotificationOn(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 3:
|
||||||
// set notification on for weight measurement
|
// set notification on for weight measurement
|
||||||
setNotificationOn(BluetoothGattUuid.CHARACTERISTIC_WEIGHT_MEASUREMENT);
|
setNotificationOn(BluetoothGattUuid.CHARACTERISTIC_WEIGHT_MEASUREMENT);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 4:
|
||||||
// configure scale to get only last measurements
|
// configure scale to get only last measurements
|
||||||
int uniqueNumber = getUniqueNumber();
|
int uniqueNumber = getUniqueNumber();
|
||||||
|
|
||||||
byte[] userIdentifier = new byte[]{(byte)0x01, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
byte[] userIdentifier = new byte[]{(byte)0x01, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||||
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 5:
|
||||||
// invoke receiving history data
|
// invoke receiving history data
|
||||||
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
||||||
break;
|
stopMachineState();
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// send stop command to mi scale
|
|
||||||
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x03});
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// acknowledge that you received the last history data
|
|
||||||
int uniqueNumber = getUniqueNumber();
|
|
||||||
|
|
||||||
byte[] userIdentifier = new byte[]{(byte)0x04, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
|
||||||
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -225,13 +198,13 @@ public class BluetoothMiScale extends BluetoothCommunication {
|
|||||||
scaleBtData.setWeight(Converters.toKilogram(weight, selectedUser.getScaleUnit()));
|
scaleBtData.setWeight(Converters.toKilogram(weight, selectedUser.getScaleUnit()));
|
||||||
scaleBtData.setDateTime(date_time);
|
scaleBtData.setDateTime(date_time);
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
} else {
|
} else {
|
||||||
Timber.e("Invalid Mi scale weight year %d", year);
|
Timber.e("Invalid Mi scale weight year %d", year);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
setBtStatus(BT_UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
setBluetoothStatus(UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@ import com.health.openscale.gui.views.FatMeasurementView;
|
|||||||
import com.health.openscale.gui.views.LBMMeasurementView;
|
import com.health.openscale.gui.views.LBMMeasurementView;
|
||||||
import com.health.openscale.gui.views.MeasurementViewSettings;
|
import com.health.openscale.gui.views.MeasurementViewSettings;
|
||||||
import com.health.openscale.gui.views.WaterMeasurementView;
|
import com.health.openscale.gui.views.WaterMeasurementView;
|
||||||
import com.polidea.rxandroidble2.RxBleClient;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -43,7 +42,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_STATUS_CODE.BT_UNEXPECTED_ERROR;
|
import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_STATUS.UNEXPECTED_ERROR;
|
||||||
|
|
||||||
public class BluetoothMiScale2 extends BluetoothCommunication {
|
public class BluetoothMiScale2 extends BluetoothCommunication {
|
||||||
private final UUID WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC = UUID.fromString("00002a2f-0000-3512-2118-0009af100700");
|
private final UUID WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC = UUID.fromString("00002a2f-0000-3512-2118-0009af100700");
|
||||||
@@ -69,7 +68,18 @@ public class BluetoothMiScale2 extends BluetoothCommunication {
|
|||||||
|
|
||||||
// Stop command from mi scale received
|
// Stop command from mi scale received
|
||||||
if (data[0] == 0x03) {
|
if (data[0] == 0x03) {
|
||||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
Timber.d("Scale stop byte received");
|
||||||
|
// send stop command to mi scale
|
||||||
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x03});
|
||||||
|
// acknowledge that you received the last history data
|
||||||
|
int uniqueNumber = getUniqueNumber();
|
||||||
|
|
||||||
|
byte[] userIdentifier = new byte[]{(byte)0x04, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||||
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||||
|
|
||||||
|
disconnect();
|
||||||
|
|
||||||
|
resumeMachineState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length == 26) {
|
if (data.length == 26) {
|
||||||
@@ -88,8 +98,8 @@ public class BluetoothMiScale2 extends BluetoothCommunication {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
// set scale units
|
// set scale units
|
||||||
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
|
||||||
@@ -108,73 +118,23 @@ public class BluetoothMiScale2 extends BluetoothCommunication {
|
|||||||
|
|
||||||
byte[] dateTimeByte = {(byte)(year), (byte)(year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00};
|
byte[] dateTimeByte = {(byte)(year), (byte)(year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00};
|
||||||
|
|
||||||
writeBytes(
|
writeBytes(BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, dateTimeByte);
|
||||||
BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, dateTimeByte);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// set notification on for weight measurement history
|
// set notification on for weight measurement history
|
||||||
setNotificationOn(
|
setNotificationOn(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC);
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
default:
|
case 3:
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// configure scale to get only last measurements
|
// configure scale to get only last measurements
|
||||||
int uniqueNumber = getUniqueNumber();
|
int uniqueNumber = getUniqueNumber();
|
||||||
|
|
||||||
byte[] userIdentifier = new byte[]{(byte)0x01, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
byte[] userIdentifier = new byte[]{(byte)0x01, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
||||||
writeBytes(
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 4:
|
||||||
// set notification on for weight measurement history
|
|
||||||
setNotificationOn(
|
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// invoke receiving history data
|
// invoke receiving history data
|
||||||
writeBytes(
|
writeBytes(WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x02});
|
stopMachineState();
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// send stop command to mi scale
|
|
||||||
writeBytes(
|
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[]{0x03});
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// acknowledge that you received the last history data
|
|
||||||
int uniqueNumber = getUniqueNumber();
|
|
||||||
|
|
||||||
byte[] userIdentifier = new byte[]{(byte)0x04, (byte)0xFF, (byte)0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0)};
|
|
||||||
writeBytes(
|
|
||||||
WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// set notification on for body composition measurement
|
|
||||||
setNotificationOn(
|
|
||||||
BluetoothGattUuid.CHARACTERISTIC_BODY_COMPOSITION_MEASUREMENT
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -239,13 +199,13 @@ public class BluetoothMiScale2 extends BluetoothCommunication {
|
|||||||
EstimatedLBMMetric.FORMULA.valueOf(settings.getEstimationFormula()));
|
EstimatedLBMMetric.FORMULA.valueOf(settings.getEstimationFormula()));
|
||||||
scaleBtData.setLbm(lbmMetric.getLBM(selectedUser, scaleBtData));
|
scaleBtData.setLbm(lbmMetric.getLBM(selectedUser, scaleBtData));
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
} else {
|
} else {
|
||||||
Timber.e("Invalid Mi scale weight year %d", year);
|
Timber.e("Invalid Mi scale weight year %d", year);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
setBtStatus(BT_UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
setBluetoothStatus(UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,12 +47,10 @@ public class BluetoothOneByone extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC_BODY_COMPOSITION);
|
||||||
WEIGHT_MEASUREMENT_CHARACTERISTIC_BODY_COMPOSITION
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ScaleUser currentUser = OpenScale.getInstance().getSelectedScaleUser();
|
ScaleUser currentUser = OpenScale.getInstance().getSelectedScaleUser();
|
||||||
@@ -83,16 +81,6 @@ public class BluetoothOneByone extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -155,6 +143,6 @@ public class BluetoothOneByone extends BluetoothCommunication {
|
|||||||
|
|
||||||
Timber.d("scale measurement [%s]", scaleBtData);
|
Timber.d("scale measurement [%s]", scaleBtData);
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -84,13 +84,8 @@ public class BluetoothQNScale extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
return false;
|
switch (stepNr) {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
case 0:
|
||||||
// set notification on for custom characteristic 1 (weight, time, and others)
|
// set notification on for custom characteristic 1 (weight, time, and others)
|
||||||
setNotificationOn(CUSTOM1_MEASUREMENT_CHARACTERISTIC);
|
setNotificationOn(CUSTOM1_MEASUREMENT_CHARACTERISTIC);
|
||||||
@@ -116,28 +111,17 @@ public class BluetoothQNScale extends BluetoothCommunication {
|
|||||||
case 4:
|
case 4:
|
||||||
sendMessage(R.string.info_step_on_scale, 0);
|
sendMessage(R.string.info_step_on_scale, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
/*case 5:
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
// send stop command to scale (0x1f05151049)
|
// send stop command to scale (0x1f05151049)
|
||||||
writeBytes(CUSTOM3_MEASUREMENT_CHARACTERISTIC, new byte[]{(byte)0x1f, (byte)0x05, (byte)0x15, (byte)0x10, (byte)0x49});
|
writeBytes(CUSTOM3_MEASUREMENT_CHARACTERISTIC, new byte[]{(byte)0x1f, (byte)0x05, (byte)0x15, (byte)0x10, (byte)0x49});
|
||||||
break;
|
break;*/
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -198,7 +182,7 @@ public class BluetoothQNScale extends BluetoothCommunication {
|
|||||||
btScaleMeasurement.setMuscle(qnscalelib.getMuscle(weightKg, impedance));
|
btScaleMeasurement.setMuscle(qnscalelib.getMuscle(weightKg, impedance));
|
||||||
btScaleMeasurement.setBone(qnscalelib.getBone(weightKg, impedance));
|
btScaleMeasurement.setBone(qnscalelib.getBone(weightKg, impedance));
|
||||||
btScaleMeasurement.setWeight(weightKg);
|
btScaleMeasurement.setWeight(weightKg);
|
||||||
addScaleData(btScaleMeasurement);
|
addScaleMeasurement(btScaleMeasurement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,8 +68,8 @@ public class BluetoothSenssun extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
break;
|
break;
|
||||||
@@ -85,16 +85,6 @@ public class BluetoothSenssun extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -107,7 +97,7 @@ public class BluetoothSenssun extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isBitSet(WeightFatMus,2) ) {
|
if (isBitSet(WeightFatMus,2) ) {
|
||||||
addScaleData(measurement);
|
addScaleMeasurement(measurement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,7 +92,7 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
|||||||
* set-broadcast-id command, and should disconnect after the write succeeds.
|
* set-broadcast-id command, and should disconnect after the write succeeds.
|
||||||
*
|
*
|
||||||
* @see #onPasswordReceived
|
* @see #onPasswordReceived
|
||||||
* @see #nextBluetoothCmd
|
* @see #onNextStep
|
||||||
*/
|
*/
|
||||||
private boolean pairing = false;
|
private boolean pairing = false;
|
||||||
|
|
||||||
@@ -119,13 +119,13 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
Timber.i("nextInitCmd(%d)", stateNr);
|
Timber.i("onNextStep(%d)", stepNr);
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
// Register for notifications of the measurement characteristic.
|
// Register for notifications of the measurement characteristic.
|
||||||
setIndicationOn(MEASUREMENT_CHARACTERISTIC_UUID);
|
setIndicationOn(MEASUREMENT_CHARACTERISTIC_UUID);
|
||||||
return true; // more commands follow
|
break; // more commands follow
|
||||||
case 1:
|
case 1:
|
||||||
// Register for notifications of the command upload characteristic.
|
// Register for notifications of the command upload characteristic.
|
||||||
//
|
//
|
||||||
@@ -133,40 +133,22 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
|||||||
// immediately after. This is important because we should be in the main state
|
// immediately after. This is important because we should be in the main state
|
||||||
// to handle pairing correctly.
|
// to handle pairing correctly.
|
||||||
setIndicationOn(UPLOAD_COMMAND_CHARACTERISTIC_UUID);
|
setIndicationOn(UPLOAD_COMMAND_CHARACTERISTIC_UUID);
|
||||||
// falls through
|
break;
|
||||||
default:
|
case 2:
|
||||||
return false; // no more commands
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
Timber.i("nextBluetoothCmd(%d)", stateNr);
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return false; // no more commands
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// This state is triggered by the write in onPasswordReceived()
|
// This state is triggered by the write in onPasswordReceived()
|
||||||
if (pairing) {
|
if (pairing) {
|
||||||
pairing = false;
|
pairing = false;
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
return false; // no more commands;
|
break;
|
||||||
}
|
case 3:
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
Timber.i("nextCleanUpCmd(%d)", stateNr);
|
|
||||||
switch (stateNr) {
|
|
||||||
case 0:
|
|
||||||
writeCommand(DOWNLOAD_INFORMATION_ENABLE_DISCONNECT_COMMAND);
|
writeCommand(DOWNLOAD_INFORMATION_ENABLE_DISCONNECT_COMMAND);
|
||||||
// falls through
|
break;
|
||||||
default:
|
default:
|
||||||
return false; // no more commands
|
return false; // no more commands
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -247,7 +229,7 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addScaleData(measurement);
|
addScaleMeasurement(measurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScaleMeasurement parseScaleMeasurementData(byte[] data, ScaleUser user) {
|
public ScaleMeasurement parseScaleMeasurementData(byte[] data, ScaleUser user) {
|
||||||
|
@@ -52,8 +52,8 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean nextInitCmd(int stateNr) {
|
protected boolean onNextStep(int stepNr) {
|
||||||
switch (stateNr) {
|
switch (stepNr) {
|
||||||
case 0:
|
case 0:
|
||||||
byte[] userId = Converters.toInt16Be(getUniqueNumber());
|
byte[] userId = Converters.toInt16Be(getUniqueNumber());
|
||||||
|
|
||||||
@@ -82,8 +82,7 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication {
|
|||||||
writeBytes(WEIGHT_CMD_CHARACTERISTIC, set_time);
|
writeBytes(WEIGHT_CMD_CHARACTERISTIC, set_time);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC
|
setNotificationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
byte[] magic_bytes = new byte[]{(byte)0x0d, (byte)0x05, (byte)0x13, (byte)0x00, (byte)0x16};
|
byte[] magic_bytes = new byte[]{(byte)0x0d, (byte)0x05, (byte)0x13, (byte)0x00, (byte)0x16};
|
||||||
@@ -97,16 +96,6 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextBluetoothCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean nextCleanUpCmd(int stateNr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
public void onBluetoothNotify(UUID characteristic, byte[] value) {
|
||||||
final byte[] data = value;
|
final byte[] data = value;
|
||||||
@@ -154,7 +143,7 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication {
|
|||||||
Timber.d("scale measurement [%s]", scaleBtData);
|
Timber.d("scale measurement [%s]", scaleBtData);
|
||||||
}
|
}
|
||||||
|
|
||||||
addScaleData(scaleBtData);
|
addScaleMeasurement(scaleBtData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getUniqueNumber() {
|
private int getUniqueNumber() {
|
||||||
|
@@ -154,8 +154,8 @@ public class MainActivity extends BaseAppCompatActivity
|
|||||||
if(prefs.edit().putInt("launchCount", ++launchCount).commit()){
|
if(prefs.edit().putInt("launchCount", ++launchCount).commit()){
|
||||||
valueOfCountModified = true;
|
valueOfCountModified = true;
|
||||||
|
|
||||||
// ask the user once for feedback on the 30th app launch
|
// ask the user once for feedback on the 15th app launch
|
||||||
if(launchCount == 30){
|
if(launchCount == 15){
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
|
||||||
builder.setMessage(R.string.label_feedback_message_enjoying)
|
builder.setMessage(R.string.label_feedback_message_enjoying)
|
||||||
@@ -476,10 +476,10 @@ public class MainActivity extends BaseAppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
|
||||||
BluetoothCommunication.BT_STATUS_CODE btStatusCode = BluetoothCommunication.BT_STATUS_CODE.values()[msg.what];
|
BluetoothCommunication.BT_STATUS btStatus = BluetoothCommunication.BT_STATUS.values()[msg.what];
|
||||||
|
|
||||||
switch (btStatusCode) {
|
switch (btStatus) {
|
||||||
case BT_RETRIEVE_SCALE_DATA:
|
case RETRIEVE_SCALE_DATA:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
||||||
ScaleMeasurement scaleBtData = (ScaleMeasurement) msg.obj;
|
ScaleMeasurement scaleBtData = (ScaleMeasurement) msg.obj;
|
||||||
|
|
||||||
@@ -496,42 +496,42 @@ public class MainActivity extends BaseAppCompatActivity
|
|||||||
|
|
||||||
openScale.addScaleData(scaleBtData, true);
|
openScale.addScaleData(scaleBtData, true);
|
||||||
break;
|
break;
|
||||||
case BT_INIT_PROCESS:
|
case INIT_PROCESS:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_init), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_init), Toast.LENGTH_SHORT).show();
|
||||||
Timber.d("Bluetooth initializing");
|
Timber.d("Bluetooth initializing");
|
||||||
break;
|
break;
|
||||||
case BT_CONNECTION_LOST:
|
case CONNECTION_LOST:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_lost), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_lost), Toast.LENGTH_SHORT).show();
|
||||||
Timber.d("Bluetooth connection lost");
|
Timber.d("Bluetooth connection lost");
|
||||||
break;
|
break;
|
||||||
case BT_NO_DEVICE_FOUND:
|
case NO_DEVICE_FOUND:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_no_device), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_no_device), Toast.LENGTH_SHORT).show();
|
||||||
Timber.e("No Bluetooth device found");
|
Timber.e("No Bluetooth device found");
|
||||||
break;
|
break;
|
||||||
case BT_CONNECTION_RETRYING:
|
case CONNECTION_RETRYING:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_searching);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_searching);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_no_device_retrying), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_no_device_retrying), Toast.LENGTH_SHORT).show();
|
||||||
Timber.e("No Bluetooth device found retrying");
|
Timber.e("No Bluetooth device found retrying");
|
||||||
break;
|
break;
|
||||||
case BT_CONNECTION_ESTABLISHED:
|
case CONNECTION_ESTABLISHED:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_success);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_successful), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_successful), Toast.LENGTH_SHORT).show();
|
||||||
Timber.d("Bluetooth connection successful established");
|
Timber.d("Bluetooth connection successful established");
|
||||||
break;
|
break;
|
||||||
case BT_CONNECTION_DISCONNECT:
|
case CONNECTION_DISCONNECT:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_disconnected), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_disconnected), Toast.LENGTH_SHORT).show();
|
||||||
Timber.d("Bluetooth connection successful disconnected");
|
Timber.d("Bluetooth connection successful disconnected");
|
||||||
break;
|
break;
|
||||||
case BT_UNEXPECTED_ERROR:
|
case UNEXPECTED_ERROR:
|
||||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||||
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_error) + ": " + msg.obj, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplicationContext(), getResources().getString(R.string.info_bluetooth_connection_error) + ": " + msg.obj, Toast.LENGTH_SHORT).show();
|
||||||
Timber.e("Bluetooth unexpected error: %s", msg.obj);
|
Timber.e("Bluetooth unexpected error: %s", msg.obj);
|
||||||
break;
|
break;
|
||||||
case BT_SCALE_MESSAGE:
|
case SCALE_MESSAGE:
|
||||||
String toastMessage = String.format(getResources().getString(msg.arg1), msg.obj);
|
String toastMessage = String.format(getResources().getString(msg.arg1), msg.obj);
|
||||||
Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_LONG).show();
|
Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_LONG).show();
|
||||||
break;
|
break;
|
||||||
|
@@ -31,7 +31,6 @@ import android.preference.Preference;
|
|||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.widget.BaseAdapter;
|
import android.widget.BaseAdapter;
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.health.openscale.R;
|
import com.health.openscale.R;
|
||||||
@@ -289,8 +288,8 @@ public class BluetoothPreferences extends PreferenceFragment {
|
|||||||
Handler btHandler = new Handler() {
|
Handler btHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (BluetoothCommunication.BT_STATUS_CODE.values()[msg.what]) {
|
switch (BluetoothCommunication.BT_STATUS.values()[msg.what]) {
|
||||||
case BT_CONNECTION_LOST:
|
case CONNECTION_LOST:
|
||||||
OpenScale.getInstance().disconnectFromBluetoothDevice();
|
OpenScale.getInstance().disconnectFromBluetoothDevice();
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
break;
|
break;
|
||||||
|
@@ -230,8 +230,9 @@ public class ChartMeasurementView extends LineChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setMeasurementList(List<ScaleMeasurement> measurementList) {
|
private void setMeasurementList(List<ScaleMeasurement> measurementList) {
|
||||||
if (!measurementList.isEmpty()) {
|
|
||||||
scaleMeasurementList = measurementList;
|
scaleMeasurementList = measurementList;
|
||||||
|
|
||||||
|
if (!measurementList.isEmpty()) {
|
||||||
lastMeasurement = measurementList.get(0);
|
lastMeasurement = measurementList.get(0);
|
||||||
Collections.reverse(measurementList);
|
Collections.reverse(measurementList);
|
||||||
firstMeasurement = measurementList.get(0);
|
firstMeasurement = measurementList.get(0);
|
||||||
@@ -409,12 +410,12 @@ public class ChartMeasurementView extends LineChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
|
clear();
|
||||||
|
|
||||||
if (scaleMeasurementList.isEmpty()) {
|
if (scaleMeasurementList.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
List<ILineDataSet> lineDataSets = new ArrayList<>();
|
List<ILineDataSet> lineDataSets = new ArrayList<>();
|
||||||
|
|
||||||
ScaleMeasurement[] avgMeasurementList = averageScaleMeasurementList(scaleMeasurementList);
|
ScaleMeasurement[] avgMeasurementList = averageScaleMeasurementList(scaleMeasurementList);
|
||||||
|
Reference in New Issue
Block a user