From 17a1f7227c8c3872fce7bbcc2f5cd46540f9ac52 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 11 Jan 2015 12:28:55 +0100 Subject: o Reading values from the soil sensor. o Rewrote the database schema to match the new device+sensors model. o Storing samples in the database. o To be able to reuse BT callbacks, added a way to always to directly to the next step instead of waiting for an event. --- .../soilmoisture/DefaultSoilMoistureService.java | 231 ++++++++++++++++----- .../java/io/trygvis/soilmoisture/MainActivity.java | 116 ++++++++--- .../java/io/trygvis/soilmoisture/SmDevice.java | 36 +++- .../java/io/trygvis/soilmoisture/SmSensor.java | 35 +++- .../trygvis/soilmoisture/SoilMoistureService.java | 5 +- .../main/java/io/trygvis/soilmoisture/Tables.java | 24 +++ 6 files changed, 343 insertions(+), 104 deletions(-) create mode 100644 app/src/main/java/io/trygvis/soilmoisture/Tables.java (limited to 'app/src/main/java/io/trygvis/soilmoisture') diff --git a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java index a2723d5..3ff6e66 100644 --- a/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java +++ b/app/src/main/java/io/trygvis/soilmoisture/DefaultSoilMoistureService.java @@ -9,12 +9,17 @@ import android.content.ComponentName; import android.content.ContentValues; import android.content.Intent; import android.content.ServiceConnection; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; import android.os.IBinder; import android.util.Log; import java.util.ArrayList; import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -25,15 +30,24 @@ import io.trygvis.android.bt.BtService; import io.trygvis.android.bt.DefaultBtService; import io.trygvis.bluetooth.TrygvisIoUuids; -import static io.trygvis.android.bt.BtPromise.continueDownChain; -import static io.trygvis.android.bt.BtPromise.doneWithChain; +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.GetValueRes; import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.GET_SENSOR_COUNT; +import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.GET_VALUE; +import static io.trygvis.soilmoisture.SmDevice.createGetSensorCountReq; +import static io.trygvis.soilmoisture.SmDevice.createGetValueReq; +import static io.trygvis.soilmoisture.SmDevice.parseResponse; +import static java.lang.String.valueOf; +import static java.lang.System.currentTimeMillis; public class DefaultSoilMoistureService extends Service implements SoilMoistureService { private final static String TAG = DefaultSoilMoistureService.class.getSimpleName(); - private final static int DEFAULT_WARNING_LEVEL = 750; private final IBinder binder = new LocalBinder<>(this); @@ -58,7 +72,7 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS @Override public void onServiceConnected(ComponentName componentName, IBinder service) { btService = ((LocalBinder>) service).getService(); - boolean ok = btService.initialize(DefaultSoilMoistureService.this::onNewDevice); + boolean ok = btService.initialize(DefaultSoilMoistureService.this::createTag); sendBroadcast(createReady(ok)); } @@ -98,28 +112,16 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS BtDevice btDevice = btService.getDevice(address); SmDevice smDevice = btDevice.getTag(); + sendBroadcast(createNewDevice(address)); + if (!smDevice.isProbed()) { Log.i(TAG, "Probing " + address + ", name=" + btDevice.getName()); BtPromise executor = new BtPromise(). - onConnectionStateChange((gatt, newState) -> { - //noinspection SimplifiableIfStatement - if (newState == BluetoothGatt.STATE_CONNECTED) { - Log.i(TAG, "Connected to " + address + ", getting services"); - return gatt.discoverServices() ? continueDownChain : doneWithChain; - } else { - Log.i(TAG, "Disconnected from " + address + ", trying again"); - - return new BtPromise().onConnectionStateChange((gatt2, newState2) -> { - if (newState2 == BluetoothGatt.STATE_CONNECTED) { - Log.i(TAG, "Connected to " + address + ", getting services"); - return continueDownChain; - } - - Log.i(TAG, "Could still not connect to " + address + ", failing."); - - return doneWithChain; - }).toDetour(); - } + ignoreFailureForNext(). + onConnectionStateChange(DefaultSoilMoistureService::defaultConnectCallback). + onDirect(v -> { + BluetoothGatt gatt = (BluetoothGatt) v; + return gatt.discoverServices() ? waitForNextEvent() : stop(); }). onServicesDiscovered(gatt -> { Log.i(TAG, "Services discovered"); @@ -127,38 +129,37 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS BluetoothGattService service = gatt.getService(TrygvisIoUuids.Services.SOIL_MOISTURE_SERVICE); if (service == null) { - return doneWithChain; + return stop(); } BluetoothGattCharacteristic soilMoisture = service.getCharacteristic(TrygvisIoUuids.Characteristics.SOIL_MOISTURE); if (soilMoisture == null) { - return doneWithChain; + return stop(); } BluetoothGattDescriptor ccg = soilMoisture.getDescriptor(TrygvisIoUuids.CLIENT_CHARACTERISTIC_CONFIG); ccg.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.setCharacteristicNotification(soilMoisture, true); - return gatt.writeDescriptor(ccg) ? continueDownChain : doneWithChain; + return gatt.writeDescriptor(ccg) ? waitForNextEvent() : stop(); }). onDescriptorWrite((gatt, descriptor) -> { Log.i(TAG, "Notifications enabled, getting sensor count"); BluetoothGattCharacteristic c = descriptor.getCharacteristic(); - c.setValue(SmDevice.createGetSensorCountReq()); - return gatt.writeCharacteristic(c) ? continueDownChain : doneWithChain; + c.setValue(createGetSensorCountReq()); + return gatt.writeCharacteristic(c) ? waitForNextEvent() : stop(); }). - onCharacteristicWrite((gatt, characteristic) -> continueDownChain). + onCharacteristicWrite((gatt, characteristic) -> waitForNextEvent()). onCharacteristicChanged((gatt, characteristic) -> { - GetSensorCountRes getSensorCountRes = SmDevice.parseResponse(characteristic.getValue(), + GetSensorCountRes getSensorCountRes = parseResponse(characteristic.getValue(), GET_SENSOR_COUNT, GetSensorCountRes.class); Log.i(TAG, "The device has " + getSensorCountRes.count + " sensors."); - smDevice.setIsUseful(true); - smDevice.setSensorCount(getSensorCountRes.count); + markDeviceAsUseful(smDevice, getSensorCountRes.count); - return doneWithChain; + return stop(); }). onFinally(() -> { btDevice.disconnect(); @@ -167,28 +168,69 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS smDevice.setIsUseful(false); } - btService.runTx(db -> { - if (!btDevice.isSeenBefore() && smDevice.isUseful()) { - for (SmSensor soilMonitor : smDevice.getSensors()) { - ContentValues values = new ContentValues(); - values.put("bt_device", btDevice.getId()); - values.put("warning_level", DEFAULT_WARNING_LEVEL); - db.insert("soil_monitor", null, values); - } - } - - return null; - }); - sendBroadcast(createNewDevice(address)); }); btDevice.connect(executor); - } else { - sendBroadcast(createNewDevice(address)); } } }; + private void markDeviceAsUseful(SmDevice device, int sensorCount) { + btService.runTx(db -> { + device.setIsUseful(true); + + // Find all already registered sensors and register the rest + Map indexes = new HashMap<>(); + Cursor cursor = db.query(Tables.T_SM_SENSOR, new String[]{Tables.C_ID, Tables.C_INDEX}, + Tables.C_SM_DEVICE + "=?", new String[]{valueOf(device.id)}, null, null, null); + while (cursor.moveToNext()) { + indexes.put(cursor.getInt(1), cursor.getLong(0)); + } + + ContentValues values = new ContentValues(); + values.put(Tables.C_USEFUL, true); + db.update(Tables.T_SM_DEVICE, values, "id=?", new String[]{valueOf(device.id)}); + + for (int i = 0; i < sensorCount; i++) { + Long id = indexes.get(i); + + if (id == null) { + values = new ContentValues(); + 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)); + } + + return null; + }); + } + + public static BtPromise.PromiseResult defaultConnectCallback(BluetoothGatt gatt, int status, Integer newState) { + Log.i(TAG, "defaultConnectCallback: status=" + status + ", newState=" + newState); + String address = gatt.getDevice().getAddress(); + //noinspection SimplifiableIfStatement + if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { + Log.i(TAG, "Connected to " + address); + return continueDirectly(gatt); + } else { + Log.i(TAG, "Disconnected from " + address + ", trying again"); + + return detour(new BtPromise().onConnectionStateChange((gatt2, status2, newState2) -> { + if (newState2 == BluetoothGatt.STATE_CONNECTED) { + Log.i(TAG, "Connected to " + address); + return continueDirectly(gatt); + } + + Log.i(TAG, "Could still not connect to " + address + ", failing."); + + return stop(); + })); + } + } + // ----------------------------------------------------------------------- // SmDevicesManager Implementation // ----------------------------------------------------------------------- @@ -223,13 +265,82 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS } // ----------------------------------------------------------------------- - // Event creation and dispatching + // // ----------------------------------------------------------------------- - private SmDevice onNewDevice(BtDevice btDevice) { - return new SmDevice(btDevice); + private SmDevice createTag(SQLiteDatabase db, BtDevice btDevice) { + Cursor cursor = db.query(Tables.T_SM_DEVICE, new String[]{Tables.C_ID}, Tables.C_BT_DEVICE + "=?", + new String[]{valueOf(btDevice.getId())}, null, null, null); + + long id; + if (cursor.moveToNext()) { + id = cursor.getLong(0); + } else { + ContentValues values = new ContentValues(); + values.put(Tables.C_BT_DEVICE, btDevice.getId()); + id = db.insert(Tables.T_SM_DEVICE, null, values); + } + + return new SmDevice(this, btDevice, id); + } + + void handleNewSensorValueReady(SmSensor sensor, int value) { + long timestamp = currentTimeMillis(); + btService.runTx(db -> { + ContentValues values = new ContentValues(); + values.put(Tables.C_SM_SENSOR, sensor.getId()); + values.put(Tables.C_TIMESTAMP, timestamp); + values.put(Tables.C_VALUE, value); + return db.insert(Tables.T_SOIL_SAMPLE, null, values); + }); + + sensor.updateLastValue(new Date(timestamp), value); + sendBroadcast(createNewSample(sensor)); + } + + void readCurrentValue(SmSensor sensor) { + BtPromise promise = new BtPromise(). + onConnectionStateChange(DefaultSoilMoistureService::defaultConnectCallback). + onDirect(v -> { + BluetoothGatt gatt = (BluetoothGatt) v; + return gatt.discoverServices() ? waitForNextEvent() : stop(); + }). + onServicesDiscovered(gatt -> { + BluetoothGattService service = gatt.getService(TrygvisIoUuids.Services.SOIL_MOISTURE_SERVICE); + BluetoothGattCharacteristic soilMoisture = service.getCharacteristic(TrygvisIoUuids.Characteristics.SOIL_MOISTURE); + + BluetoothGattDescriptor ccg = soilMoisture.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG); + ccg.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + gatt.setCharacteristicNotification(soilMoisture, true); + + return gatt.writeDescriptor(ccg) ? waitForNextEvent() : stop(); + }). + onDescriptorWrite((gatt, descriptor) -> { + BluetoothGattCharacteristic c = descriptor.getCharacteristic(); + c.setValue(createGetValueReq((byte) sensor.getIndex())); + return gatt.writeCharacteristic(c) ? waitForNextEvent() : stop(); + }). + onCharacteristicWrite((gatt, characteristic) -> waitForNextEvent()). + onCharacteristicChanged((gatt, characteristic) -> { + GetValueRes getSensorCountRes = parseResponse(characteristic.getValue(), + GET_VALUE, GetValueRes.class); + + handleNewSensorValueReady(sensor, getSensorCountRes.value); + + gatt.disconnect(); + + return stop(); + }). + onFinally(() -> { + }); + + sensor.getDevice().getBtDevice().connect(promise); } + // ----------------------------------------------------------------------- + // Event creation and dispatching + // ----------------------------------------------------------------------- + private Intent createReady(boolean success) { return new Intent(SoilMoistureListener.INTENT_NAME). putExtra("event", "ready"). @@ -252,15 +363,24 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS putExtra("address", address); } + private Intent createNewSample(SmSensor sensor) { + return new Intent(SoilMoistureListener.INTENT_NAME). + putExtra("event", "newSample"). + putExtra("address", sensor.getDevice().getBtDevice().getAddress()). + putExtra("index", sensor.getIndex()); + } + public static void dispatchEvent(Intent intent, SoilMoistureListener listener) { String event = intent.getStringExtra("event"); Log.i(TAG, "Dispatching event " + intent.getAction() + "/" + event); switch (event) { case "ready": - listener.onReady(intent.getBooleanExtra("success", false)); + listener.onReady( + intent.getBooleanExtra("success", false)); break; case "newDevice": - listener.onNewDevice(intent.getStringExtra("address")); + listener.onNewDevice( + intent.getStringExtra("address")); break; case "scanStarted": listener.onScanStarted(); @@ -268,6 +388,11 @@ public class DefaultSoilMoistureService extends Service implements SoilMoistureS case "scanStopped": listener.onScanStopped(); break; + case "newSample": + listener.onNewSample( + intent.getStringExtra("address"), + intent.getIntExtra("index", -1)); + break; default: break; } diff --git a/app/src/main/java/io/trygvis/soilmoisture/MainActivity.java b/app/src/main/java/io/trygvis/soilmoisture/MainActivity.java index 7aa3534..3a88f6c 100644 --- a/app/src/main/java/io/trygvis/soilmoisture/MainActivity.java +++ b/app/src/main/java/io/trygvis/soilmoisture/MainActivity.java @@ -16,9 +16,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import android.widget.ListAdapter; -import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -209,9 +207,18 @@ public class MainActivity extends ListActivity { } } - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - stopScan(); + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + private void onDeviceClick(SmDevice device) { + Log.i(TAG, "onDeviceClick, device=" + device.getBtDevice().getId()); + } + + private void onSensorClick(SmSensor sensor) { + Log.i(TAG, "onSensorClick, device=" + sensor.getDevice().getBtDevice().getId() + "/" + sensor.getIndex()); + + sensor.readCurrentValue(); } // ----------------------------------------------------------------------- @@ -223,16 +230,25 @@ public class MainActivity extends ListActivity { final TextView deviceAddress; final TextView rssi; final TextView info; - final ProgressBar spinner; - final Button connect; DeviceItem(View view) { this.deviceName = (TextView) view.findViewById(R.id.device_name); this.deviceAddress = (TextView) view.findViewById(R.id.device_address); this.rssi = (TextView) view.findViewById(R.id.device_rssi); this.info = (TextView) view.findViewById(R.id.device_info); - this.spinner = (ProgressBar) view.findViewById(R.id.device_spinner); - this.connect = (Button) view.findViewById(R.id.button_connect); + } + } + + static class SensorItem { + final SmSensor sensor; + final TextView description; + final ProgressBar sensorProgress; + + SensorItem(SmSensor sensor, View view) { + this.sensor = sensor; + this.description = (TextView) view.findViewById(R.id.description); + this.sensorProgress = (ProgressBar) view.findViewById(R.id.sensor_progress); + sensorProgress.setMax(1024); } } @@ -254,18 +270,24 @@ public class MainActivity extends ListActivity { for (SmDevice d : devices) { (d.isUseful() ? usefulDevices : unusefulDevices).add(d); } - List monitors = new ArrayList<>(); + List sensors = new ArrayList<>(); for (SmDevice d : devices) { - monitors.addAll(d.getSensors()); + if (d.isUseful()) { + sensors.addAll(d.getSensors()); + } } if (groupByDevice) { - current.addAll(usefulDevices); +// current.addAll(usefulDevices); + for (SmDevice device : usefulDevices) { + current.add(device); + current.addAll(device.getSensors()); + } if (showAll) { current.addAll(unusefulDevices); } } else { - current.addAll(monitors); + current.addAll(sensors); } dataSetObservable.notifyChanged(); } @@ -374,50 +396,77 @@ public class MainActivity extends ListActivity { if (o instanceof SmDevice) { return getSmDeviceView((SmDevice) o, view); } else if (o instanceof SmSensor) { - return getSoilMonitorView((SmSensor) o, view); + return getSoilSensorView((SmSensor) o, view); } throw new RuntimeException("Not implemented"); } private View getSmDeviceView(SmDevice smDevice, View view) { - - DeviceItem item; if (view == null) { - view = inflater.inflate(R.layout.listitem_device, null); - item = new DeviceItem(view); - view.setTag(item); - view.setClickable(false); - } else { - item = (DeviceItem) view.getTag(); + view = inflater.inflate(R.layout.fragment_device, null); + view.setTag(new DeviceItem(view)); + view.setClickable(true); + view.setOnClickListener(v -> onDeviceClick(smDevice)); } + DeviceItem item = (DeviceItem) view.getTag(); + if (smDevice.getName() != null) { item.deviceName.setText(smDevice.getName()); } else { item.deviceName.setText(R.string.unknown_device); } - item.deviceAddress.setText(smDevice.getBtDevice().getAddress()); + String address = smDevice.getBtDevice().getAddress(); + + if (!smDevice.isProbed()) { + address += " not probed"; + } else if (smDevice.isUseful()) { + address += " useful"; + } else { + address += " not useful"; + } + + item.deviceAddress.setText(address); item.rssi.setText(getText(R.string.rssi) + ": " + (smDevice.getBtDevice().getRssi() != 0 ? valueOf(smDevice.getBtDevice().getRssi()) : getText(R.string.unknown))); - if (smDevice.isUseful()) { - item.info.setText("number of sensors: " + smDevice.getSensors().size()); + boolean useful = smDevice.isUseful(); + + if (useful) { + item.info.setText("Number of sensors: " + smDevice.getSensors().size()); } else { item.info.setText(""); } - boolean useful = smDevice.isUseful(); - item.spinner.setVisibility(useful ? View.GONE : View.VISIBLE); - item.connect.setVisibility(useful ? View.VISIBLE : View.GONE); - view.setClickable(useful); +// view.setClickable(useful); return view; } - private View getSoilMonitorView(SmSensor smSensor, View view) { - throw new RuntimeException("Not implemented"); + private View getSoilSensorView(SmSensor smSensor, View view) { + if (view == null) { + view = inflater.inflate(R.layout.fragment_sensor, null); + view.setTag(new SensorItem(smSensor, view)); + view.setClickable(true); + view.setOnClickListener(v -> onSensorClick(smSensor)); + } + + SensorItem item = (SensorItem) view.getTag(); + + Integer value = smSensor.getLastValue(); + String text = "Connected: " + smSensor.getDevice().getBtDevice().connected(); + text += ", value: " + (value == null ? "Unknown" : value); + item.description.setText(text); + + if (value != null) { + item.sensorProgress.setProgress(value); + } else { + item.sensorProgress.setIndeterminate(true); + } + + return view; } } @@ -459,5 +508,10 @@ public class MainActivity extends ListActivity { deviceList.devices.add(device); deviceList.sort(); } + + @Override + public void onNewSample(String address, int sensor) { + deviceList.notifyDataSetChanged(); + } } } diff --git a/app/src/main/java/io/trygvis/soilmoisture/SmDevice.java b/app/src/main/java/io/trygvis/soilmoisture/SmDevice.java index b51b3fa..4cb25f3 100644 --- a/app/src/main/java/io/trygvis/soilmoisture/SmDevice.java +++ b/app/src/main/java/io/trygvis/soilmoisture/SmDevice.java @@ -18,16 +18,22 @@ import static io.trygvis.soilmoisture.SmDevice.SmCmdCode.SET_WARNING_VALUE; class SmDevice implements BtDevice.BtDeviceWrapper { private final static String TAG = SmDevice.class.getSimpleName(); + final DefaultSoilMoistureService smService; + private final BtDevice btDevice; + final long id; + private String name; private Boolean isUseful; private List sensors = new ArrayList<>(); - public SmDevice(BtDevice btDevice) { + public SmDevice(DefaultSoilMoistureService smService, BtDevice btDevice, long id) { + this.smService = smService; this.btDevice = btDevice; + this.id = id; Log.i(TAG, "new device"); name = btDevice.getName(); @@ -63,14 +69,21 @@ class SmDevice implements BtDevice.BtDeviceWrapper { } public List getSensors() { + if (!isUseful()) { + throw new IllegalStateException("Not a useful device"); + } return sensors; } + void addSensor(SmSensor sensor) { + sensors.add(sensor); + } + // ----------------------------------------------------------------------- - // + // Message parsing and handling. // ----------------------------------------------------------------------- - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "StatementWithEmptyBody"}) public static T parseResponse(byte[] bytes, SmCmdCode code, Class klass) { byte c = bytes[0]; @@ -78,10 +91,10 @@ class SmDevice implements BtDevice.BtDeviceWrapper { throw new RuntimeException("Expected response of type " + code + ", got " + c); } - Object value = null; if (c == GET_SENSOR_COUNT.code) { return (T) new GetSensorCountRes(bytes[1]); } else if (c == GET_VALUE.code) { + return (T) new GetValueRes((bytes[2] & 0xff) << 8 | (bytes[1] & 0xff)); } else if (c == SET_WARNING_VALUE.code) { } else if (c == GET_WARNING_VALUE.code) { } else if (c == SET_SENSOR_NAME.code) { @@ -91,13 +104,6 @@ class SmDevice implements BtDevice.BtDeviceWrapper { throw new RuntimeException("Unknown code: " + c); } - public void setSensorCount(int count) { - sensors = new ArrayList<>(); - for (int index = 0; index < count; index++) { - sensors.add(new SmSensor(this, index)); - } - } - public static class GetSensorCountRes { public final int count; @@ -106,6 +112,14 @@ class SmDevice implements BtDevice.BtDeviceWrapper { } } + public static class GetValueRes { + public final int value; + + public GetValueRes(int value) { + this.value = value; + } + } + public static byte[] createGetSensorCountReq() { return new byte[]{ GET_SENSOR_COUNT.code diff --git a/app/src/main/java/io/trygvis/soilmoisture/SmSensor.java b/app/src/main/java/io/trygvis/soilmoisture/SmSensor.java index ec4b423..2a0d9cd 100644 --- a/app/src/main/java/io/trygvis/soilmoisture/SmSensor.java +++ b/app/src/main/java/io/trygvis/soilmoisture/SmSensor.java @@ -5,38 +5,57 @@ import java.util.Date; class SmSensor { private final SmDevice device; - private final int index; + public final long id; + + public final int index; + + private String name; private Date timestamp; - private int lastValue; + private Integer lastValue; - SmSensor(SmDevice device, int index) { + SmSensor(SmDevice device, long id, int index) { this.device = device; + this.id = id; this.index = index; + this.name = "Sensor #" + index; } public SmDevice getDevice() { return device; } + public long getId() { + return id; + } + public int getIndex() { return index; } - public int getLastValue() { - return lastValue; + public String getName() { + return name; } - public void setLastValue(int lastValue) { - this.lastValue = lastValue; + public Integer getLastValue() { + return lastValue; } public Date getTimestamp() { return timestamp; } - public void setTimestamp(Date timestamp) { + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + public void readCurrentValue() { + device.smService.readCurrentValue(this); + } + + void updateLastValue(Date timestamp, int lastValue) { this.timestamp = timestamp; + this.lastValue = lastValue; } } diff --git a/app/src/main/java/io/trygvis/soilmoisture/SoilMoistureService.java b/app/src/main/java/io/trygvis/soilmoisture/SoilMoistureService.java index 8100649..643fa08 100644 --- a/app/src/main/java/io/trygvis/soilmoisture/SoilMoistureService.java +++ b/app/src/main/java/io/trygvis/soilmoisture/SoilMoistureService.java @@ -25,7 +25,7 @@ public interface SoilMoistureService { public static final IntentFilter INTENT_FILTER = new IntentFilter(INTENT_NAME); - public void onReceive(Context context, Intent intent) { + public final void onReceive(Context context, Intent intent) { if (!intent.getAction().equals(INTENT_NAME)) { return; } @@ -44,5 +44,8 @@ public interface SoilMoistureService { public void onScanStopped() { } + + public void onNewSample(String address, int sensor) { + } } } diff --git a/app/src/main/java/io/trygvis/soilmoisture/Tables.java b/app/src/main/java/io/trygvis/soilmoisture/Tables.java new file mode 100644 index 0000000..56e5041 --- /dev/null +++ b/app/src/main/java/io/trygvis/soilmoisture/Tables.java @@ -0,0 +1,24 @@ +package io.trygvis.soilmoisture; + +public class Tables { + public static String T_SM_DEVICE = "sm_device"; + public static String T_SM_SENSOR = "sm_sensor"; + public static String T_SOIL_SAMPLE = "soil_sample"; + + // sm_device + public static String C_ID = "id"; + public static String C_BT_DEVICE = "bt_device"; + public static String C_USEFUL = "useful"; +// public static String C_NAME = "name"; + + // sm_sensor + public static String C_SM_DEVICE = "sm_device"; + // name + public static String C_WARNING_VALUE = "warning_value"; + + // soil_sample + public static String C_SM_SENSOR = "sm_sensor"; + public static String C_INDEX = "idx"; + public static String C_TIMESTAMP = "timestamp"; + public static String C_VALUE = "value"; +} -- cgit v1.2.3