aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java')
-rw-r--r--app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java90
1 files changed, 71 insertions, 19 deletions
diff --git a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
index 86a1917..85a6afb 100644
--- a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
+++ b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import io.trygvis.android.Function;
import io.trygvis.android.LocalBinder;
import io.trygvis.android.bt.BtDevice;
import io.trygvis.android.bt.BtPromise;
@@ -30,15 +31,20 @@ import io.trygvis.android.bt.BtService;
import io.trygvis.android.bt.DefaultBtService;
import io.trygvis.bluetooth.TrygvisIoUuids;
+import static io.trygvis.android.bt.BtPromise.PromiseResult.continueDirectly;
+import static io.trygvis.android.bt.BtPromise.PromiseResult.detour;
import static io.trygvis.android.bt.BtPromise.PromiseResult.stop;
import static io.trygvis.android.bt.BtPromise.PromiseResult.waitForNextEvent;
import static io.trygvis.android.bt.BtService.BtServiceListenerBroadcastReceiver;
import static io.trygvis.bluetooth.TrygvisIoUuids.CLIENT_CHARACTERISTIC_CONFIG;
import static io.trygvis.soilmoisture.SmDevice.GetSensorCountRes;
+import static io.trygvis.soilmoisture.SmDevice.GetSensorNameRes;
import static io.trygvis.soilmoisture.SmDevice.GetValueRes;
import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.GET_SENSOR_COUNT;
+import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.GET_SENSOR_NAME;
import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.GET_VALUE;
import static io.trygvis.soilmoisture.SmDevice.createGetSensorCountReq;
+import static io.trygvis.soilmoisture.SmDevice.createGetSensorNameReq;
import static io.trygvis.soilmoisture.SmDevice.createGetValueReq;
import static io.trygvis.soilmoisture.SmDevice.parseResponse;
import static java.lang.String.valueOf;
@@ -127,12 +133,47 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
}
};
+ private BtPromise readAttribute(String value, byte[] req, Function<byte[], BtPromise.PromiseResult> handler) {
+ return new BtPromise().
+ onDirect(gatt -> {
+ Log.i(TAG, "Getting attribute: " + value);
+
+ BluetoothGattService service = gatt.getService(TrygvisIoUuids.Services.SOIL_MOISTURE_SERVICE);
+ BluetoothGattCharacteristic soilMoisture = service.getCharacteristic(TrygvisIoUuids.Characteristics.SOIL_MOISTURE);
+
+ soilMoisture.setValue(req);
+ return gatt.writeCharacteristic(soilMoisture) ? waitForNextEvent() : stop();
+ }).
+ onCharacteristicWrite((gatt, characteristic) -> waitForNextEvent()).
+ onCharacteristicChanged((gatt, characteristic) -> {
+ byte[] bytes = characteristic.getValue();
+
+ return handler.apply(bytes);
+ });
+ }
+
+ private BtPromise readSensorName(SmDevice device, int index) {
+ byte[] req = createGetSensorNameReq((byte) index);
+
+ return readAttribute("sensor name, index#" + index, req, bytes -> {
+ GetSensorNameRes res = parseResponse(bytes, GET_SENSOR_NAME, GetSensorNameRes.class);
+ String name = res.name;
+
+ device.getSensorByIndex(index).ifPresent(sensor -> {
+ sensor.setName(name);
+ sendBroadcast(createDevicePropertyUpdated(device));
+ });
+
+ return index == device.getSensors().size() - 1 ? stop() : detour(readSensorName(device, index + 1));
+ });
+ }
+
public void probe(String address) {
BtDevice<SmDevice> btDevice = btService.getDevice(address);
SmDevice smDevice = btDevice.getTag();
Log.i(TAG, "Probing " + address + ", name=" + btDevice.getName());
- BtPromise executor = new BtPromise().
+ BtPromise promise = new BtPromise().
onDirect(gatt -> {
BluetoothGattService service = gatt.getService(TrygvisIoUuids.Services.SOIL_MOISTURE_SERVICE);
@@ -153,21 +194,8 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
return gatt.writeDescriptor(ccg) ? waitForNextEvent() : stop();
}).
onDescriptorWrite((gatt, descriptor) -> {
- Log.i(TAG, "Notifications enabled, getting sensor count");
- BluetoothGattCharacteristic c = descriptor.getCharacteristic();
- c.setValue(createGetSensorCountReq());
- return gatt.writeCharacteristic(c) ? waitForNextEvent() : stop();
- }).
- onCharacteristicWrite((gatt, characteristic) -> waitForNextEvent()).
- onCharacteristicChanged((gatt, characteristic) -> {
- GetSensorCountRes getSensorCountRes = parseResponse(characteristic.getValue(),
- GET_SENSOR_COUNT, GetSensorCountRes.class);
-
- Log.i(TAG, "The device has " + getSensorCountRes.count + " sensors.");
-
- markDeviceAsUseful(smDevice, getSensorCountRes.count);
-
- return stop();
+ Log.i(TAG, "Notifications enabled");
+ return continueDirectly();
}).
onFinally(success -> {
if (smDevice.getIsUseful() == null) {
@@ -175,7 +203,20 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
}
});
- btDevice.withConnection(executor);
+ BtPromise btPromise = readAttribute("sensor count", createGetSensorCountReq(), bytes -> {
+ GetSensorCountRes getSensorCountRes = parseResponse(bytes, GET_SENSOR_COUNT, GetSensorCountRes.class);
+
+ int count = getSensorCountRes.count;
+
+ Log.i(TAG, "The device has " + count + " sensors.");
+
+ markDeviceAsUseful(smDevice, count);
+
+ return detour(readSensorName(smDevice, 0));
+ });
+ promise.andThen(btPromise);
+
+ btDevice.withConnection(promise);
}
private void markDeviceAsNotUseful(SmDevice device) {
@@ -214,9 +255,9 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
values.put(Tables.C_SM_DEVICE, device.id);
values.put(Tables.C_INDEX, i);
id = db.insert(Tables.T_SM_SENSOR, null, values);
- }
- device.addSensor(new SmSensor(device, id, (byte) i));
+ device.addSensor(new SmSensor(device, id, (byte) i));
+ }
}
return null;
@@ -393,6 +434,12 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
putExtra("index", sensor.getIndex());
}
+ private Intent createDevicePropertyUpdated(SmDevice device) {
+ return new Intent(SoilMoistureListener.INTENT_NAME).
+ putExtra("event", "devicePropertyUpdated").
+ putExtra("address", device.getBtDevice().getAddress());
+ }
+
public static void dispatchEvent(Intent intent, SoilMoistureListener listener) {
String event = intent.getStringExtra("event");
Log.i(TAG, "Dispatching event " + intent.getAction() + "/" + event);
@@ -421,7 +468,12 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS
intent.getStringExtra("address"),
intent.getIntExtra("index", -1));
break;
+ case "devicePropertyUpdated":
+ listener.onDevicePropertyUpdated(
+ intent.getStringExtra("address"));
+ break;
default:
+ Log.w(TAG, "Unknown event: " + event);
break;
}
}