package com.blakequ.bluetooth_manager_lib.device.ibeacon;
|
|
|
import com.blakequ.bluetooth_manager_lib.util.ByteUtils;
|
|
final class IBeaconUtils {
|
private static final double DISTANCE_THRESHOLD_WTF = 0.0;
|
private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
|
private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
|
|
private IBeaconUtils(){
|
// TO AVOID INSTANTIATION
|
}
|
|
/**
|
* Calculates the accuracy of an RSSI reading.
|
* <p/>
|
* The code was taken from <a href="http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing" /a>
|
*
|
* @param txPower the calibrated TX power of an iBeacon
|
* @param rssi the RSSI value of the iBeacon
|
* @return the calculated Accuracy
|
*/
|
public static double calculateAccuracy(final int txPower, final double rssi) {
|
if (rssi == 0) {
|
return -1.0; // if we cannot determine accuracy, return -1.
|
}
|
|
final double ratio = rssi * 1.0 / txPower;
|
if (ratio < 1.0) {
|
return Math.pow(ratio, 10);
|
} else {
|
return (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
|
}
|
}
|
|
public static String calculateUuidString(final byte[] uuid) {
|
final StringBuilder sb = new StringBuilder();
|
|
for (int i = 0; i < uuid.length; i++) {
|
if (i == 4) {
|
sb.append('-');
|
}
|
if (i == 6) {
|
sb.append('-');
|
}
|
if (i == 8) {
|
sb.append('-');
|
}
|
if (i == 10) {
|
sb.append('-');
|
}
|
|
final int intFromByte = ByteUtils.getIntFromByte(uuid[i]);
|
if(intFromByte <= 0xF){
|
sb.append('0');
|
}
|
sb.append(Integer.toHexString(intFromByte));
|
}
|
|
|
return sb.toString();
|
}
|
|
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy) {
|
if (accuracy < DISTANCE_THRESHOLD_WTF) {
|
return IBeaconDistanceDescriptor.UNKNOWN;
|
}
|
|
if (accuracy < DISTANCE_THRESHOLD_IMMEDIATE) {
|
return IBeaconDistanceDescriptor.IMMEDIATE;
|
}
|
|
if (accuracy < DISTANCE_THRESHOLD_NEAR) {
|
return IBeaconDistanceDescriptor.NEAR;
|
}
|
|
return IBeaconDistanceDescriptor.FAR;
|
}
|
}
|