From 138b49247a72890df66af9a01e1179dab72a4b71 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 20 Jan 2015 00:19:22 +0100 Subject: o Adding a way to append promises to promises. o Reading each sensors name when probing a device. o Enabling probing on long presses on already probed devices. Is probably useful to update the local information when other handsets has updated the device's values. --- .../soilmoisture/DefaultSoilMoistureService.java | 90 +++++++++++++++++----- 1 file changed, 71 insertions(+), 19 deletions(-) (limited to 'app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java') 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 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 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; } } -- cgit v1.2.3