Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sensorhub-android-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies {
implementation project(path: ':sensorhub-datastore-h2')
implementation project(path: ':sensorhub-service-sweapi')
implementation project(':sensorhub-android-ste')
implementation project(':sensorhub-android-obd2')
}

android {
Expand Down
14 changes: 14 additions & 0 deletions sensorhub-android-app/res/xml/pref_sensors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,20 @@
android:entryValues="@array/sos_option_values"
android:defaultValue="@array/sos_option_defaults" />

<SwitchPreference
android:key="obd2_enabled"
android:defaultValue="false"
android:summary="Enable streaming of OBD2 sensor data (sensor must be connected via Bluetooth LE on startup)"
android:title="OBD2 Data" />

<MultiSelectListPreference
android:key="obd2_options"
android:title="OBD2 Output Options"
android:summary="Options for pushing sensor data"
android:entries="@array/sos_option_list"
android:entryValues="@array/sos_option_values"
android:defaultValue="@array/sos_option_defaults" />

</PreferenceCategory>


Expand Down
16 changes: 16 additions & 0 deletions sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.sensorhub.impl.service.sweapi.SWEApiServiceConfig;
import org.sensorhub.impl.sensor.trupulse.SimulatedDataStream;
import org.sensorhub.impl.sensor.ste.STERadPagerConfig;
import org.sensorhub.impl.sensor.obd2.Obd2Config;

import java.io.File;
import java.net.MalformedURLException;
Expand Down Expand Up @@ -153,6 +154,7 @@ enum Sensors {
ProxySensor,
BLELocation,
STERadPager,
Obd2Sensor,
}


Expand Down Expand Up @@ -424,6 +426,18 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorhubConfig.add(steRadPagerConfig);
}

// OBD2 sensor
enabled = prefs.getBoolean("obd2_enabled", false);
if(enabled){
Obd2Config obd2Config = new Obd2Config();
obd2Config.id = "OBD2_SENSOR";
obd2Config.name = "OBD2 [" + deviceName + "]";
obd2Config.autoStart = true;
obd2Config.lastUpdated = ANDROID_SENSORS_LAST_UPDATED;

sensorhubConfig.add(obd2Config);
}

// AngelSensor
/*enabled = prefs.getBoolean("angel_enabled", false);
if (enabled)
Expand Down Expand Up @@ -971,6 +985,8 @@ private boolean isPushingSensor(Sensors sensor) {
return prefs.getBoolean("ble_enable", false) && prefs.getStringSet("ble_options", Collections.emptySet()).contains("PUSH_REMOTE");
} else if(Sensors.STERadPager.equals(sensor)){
return prefs.getBoolean("ste_radpager_enabled", false) && prefs.getStringSet("radpager_options", Collections.emptySet()).contains("PUSH_REMOTE");
} else if(Sensors.Obd2Sensor.equals(sensor)){
return prefs.getBoolean("obd2_enabled", false) && prefs.getStringSet("obd2_options", Collections.emptySet()).contains("PUSH_REMOTE");
}

return false;
Expand Down
17 changes: 17 additions & 0 deletions sensorhub-android-obd2/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apply plugin: 'com.android.library'

description = 'OBD2 Sensor'
ext.details = 'Driver for OBD2 sensors'

dependencies {
api project(':sensorhub-core')
implementation "com.android.support:appcompat-v7:28.0.0"
implementation 'com.github.pires:obd-java-api:1.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
implementation project(':sensorhub-android-service')
implementation project(':sensorhub-driver-android')
}

android {
compileSdk = 28
}
9 changes: 9 additions & 0 deletions sensorhub-android-obd2/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.sensorhub.impl.sensor.obd2">

<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="33" />

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sensorhub.impl.sensor.obd2;

import android.content.Context;
import android.provider.Settings;

import org.sensorhub.android.SensorHubService;
import org.sensorhub.api.sensor.SensorConfig;

public class Obd2Config extends SensorConfig {
public Obd2Config() {
this.moduleClass = Obd2Sensor.class.getCanonicalName();
}

public static String getUid() {
Context context = SensorHubService.getContext();
return "urn:android:obd2:" + Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.sensorhub.impl.sensor.obd2;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

import org.sensorhub.api.sensor.SensorException;

import java.util.UUID;
import java.io.IOException;
import java.util.Set;

public class Obd2Connect extends Thread {
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothSocket btSocket;
private final BluetoothAdapter btAdapter;
volatile boolean active = true;

public Obd2Connect(BluetoothAdapter adapter, BluetoothDevice btDevice) throws SensorException {
btAdapter = adapter;
BluetoothSocket tmpSocket = null;

try {
tmpSocket = btDevice.createRfcommSocketToServiceRecord(SPP_UUID);
} catch (IOException e) {
// TODO Is this what I want to happen if creating the socket fails?
throw new SensorException("Could not create client socket", e);
}

btSocket = tmpSocket;
}

public BluetoothSocket getBtSocket() {
return btSocket;
}

public void run() {
btAdapter.cancelDiscovery();

try {
btSocket.connect();
} catch (IOException connectException) {
try {
btSocket.close();
} catch (IOException closeException) {
// TODO
}
}


// while (active) {
// btAdapter.cancelDiscovery();
//
// // connect to the bluetooth device
// try {
// btSocket.connect();
// } catch (IOException connectException) {
// System.out.println("*** CONNECTION ERROR: " + connectException);
// try {
// btSocket.close();
// } catch (IOException e) {
// // TODO What should I do if I can't close the socket?
// }
// }
// }
}

public void cancel() {
try {
btSocket.close();
} catch (IOException e) {
// TODO What should I do if I can't close the socket?
}
}

public boolean isConnected() {
return btSocket.isConnected();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.sensorhub.impl.sensor.obd2;

import net.opengis.swe.v20.CategoryOrRange;
import net.opengis.swe.v20.DataBlock;
import net.opengis.swe.v20.DataChoice;
import net.opengis.swe.v20.DataRecord;
import net.opengis.swe.v20.DataComponent;

import org.checkerframework.checker.units.qual.A;
import org.sensorhub.impl.sensor.AbstractSensorControl;
import org.sensorhub.impl.sensor.obd2.commands.Obd2Command;
import org.sensorhub.api.command.CommandException;
import org.sensorhub.impl.sensor.obd2.commands.Obd2CommandTask;
import org.sensorhub.impl.sensor.obd2.commands.Obd2Commands;
import org.vast.swe.SWEHelper;
import com.github.pires.obd.commands.control.DistanceMILOnCommand;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Obd2Control extends AbstractSensorControl<Obd2Sensor> {
DataChoice commandData;
DataRecord commandStruct;
Obd2Commands commands;

public Obd2Control(Obd2Sensor parentSensor) {
super("control", parentSensor);
}

@Override
public DataComponent getCommandDescription() {
return commandStruct;
}

@Override
protected boolean execCommand(DataBlock commandBlock) throws CommandException {
try {
DataRecord commandData = commandStruct.copy();
commandData.setData(commandBlock);
// DataComponent component = commandData.getField("Command");
// String commandName = component.getData().getStringValue();
// Obd2Command command = commands.get(commandName);
// TODO Is this ok?
InputStream in = parentSensor.getBtSocket().getInputStream();
OutputStream out = parentSensor.getBtSocket().getOutputStream();

// TODO check boolean value of the trigger control

try {
ArrayList<HashMap<Integer, String>> results = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(commands.getCommands().size());

for (Obd2Command command: commands.getCommands().values()) {
Obd2Command obd2Command = commands.get(command.getCommandName());
Callable<HashMap<Integer, String>> task = new Obd2CommandTask(obd2Command, in, out);
Future<HashMap<Integer, String>> future = executor.submit(task);

HashMap<Integer, String> result = null;
try {
result = future.get();
} catch (InterruptedException | ExecutionException e) {
// TODO
}

results.add(result);
}
executor.shutdown();
parentSensor.getOutput().setData(results);
} catch (Exception e) {
// TODO Handle errors
}
} catch (Exception e) {
throw new RuntimeException(e);
}

return true;
}

public void init() {
commands = Obd2Commands.getInstance();
SWEHelper swe = new SWEHelper();

commandStruct = swe.createRecord()
.name("xxx")
.updatable(true)
.definition(SWEHelper.getPropertyUri("xxx"))
.label("xxx")
.description("Sends read commands to the OBD-II device")
.addField("Trigger",
swe.createBoolean()
.name("Trigger reading")
.label("Triggers reading")
.definition(SWEHelper.getPropertyUri("TriggerControl"))
.description("Triggers the OBD-II sensor to read all available data"))
.build();
}

public void stop() {
// TODO Auto-generated method stub
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.sensorhub.impl.sensor.obd2;

import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleProvider;
import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.impl.module.JarModuleProvider;

public class Obd2Descriptor implements IModuleProvider {
@Override
public String getModuleName() {
return "OBD2 Driver";
}

@Override
public String getModuleDescription() {
return "Driver for OBD2 sensors conected via BLE";
}

@Override
public String getModuleVersion() {
return "0.1";
}

@Override
public String getProviderName() {
return "Botts Innovative Research, Inc.";
}

@Override
public Class<? extends IModule<?>> getModuleClass() {
return Obd2Sensor.class;
}

@Override
public Class<? extends ModuleConfig> getModuleConfigClass() {
return Obd2Config.class;
}
}
Loading