Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void onReceive(Context context, Intent intent) {
private ParcelFileDescriptor mUsbDescriptor = null;
private FileInputStream mUsbInputStream = null;
private FileOutputStream mUsbOutputStream = null;

/**
* Listen for disconnection events for accessory and close connection if we were using it.
*/
Expand Down
122 changes: 121 additions & 1 deletion app/src/main/java/com/platypus/android/server/LauncherFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import android.app.ActivityManager;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
Expand All @@ -24,6 +27,9 @@

import com.platypus.android.server.gui.SwipeOnlySwitch;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
Expand All @@ -42,12 +48,33 @@ public class LauncherFragment extends Fragment

private static final String TAG = LauncherFragment.class.getSimpleName();

// bind the VehicleService so we can send sensor type JSON commands
// https://developer.android.com/guide/components/bound-services.html
VehicleService mService;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "LauncherFragment: onServiceConnected() called...");
VehicleService.LocalBinder binder = (VehicleService.LocalBinder) service;
mService = binder.getService();
mBound = true;
sendSensorsJSON();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.d(TAG, "LauncherFragment: onServiceDisconnected() called...");
mBound= false;
}
};

final Handler mHandler = new Handler();

protected TextView mHomeText;
protected TextView mIpAddressText;
protected Switch mLaunchSwitch;
protected Button mSetHomeButton;
protected Button mSetSensorsButton;
protected ImageView mVehicleImage;
protected LocationManager mLocationManager;
/**
Expand All @@ -60,10 +87,14 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
mLaunchSwitch.setEnabled(false);
if (!isVehicleServiceRunning()) {
// If the service is not running, start it.
getActivity().startService(new Intent(getActivity(), VehicleService.class));
Log.d(TAG, "LauncherFragment: slider listener called...");
Intent intent = new Intent(getActivity(), VehicleService.class);
getActivity().startService(intent);
getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG, "Vehicle service started.");
} else {
// If the service is running, stop it.
getActivity().unbindService(mConnection);
getActivity().stopService(new Intent(getActivity(), VehicleService.class));
Log.i(TAG, "Vehicle service stopped.");
}
Expand Down Expand Up @@ -97,6 +128,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
mIpAddressText = (TextView) view.findViewById(R.id.ip_address_text);
mLaunchSwitch = (SwipeOnlySwitch) view.findViewById(R.id.launcher_launch_switch);
mSetHomeButton = (Button) view.findViewById(R.id.launcher_home_button);
mSetSensorsButton = (Button) view.findViewById(R.id.launcher_sensors_button);
mVehicleImage = (ImageView) view.findViewById(R.id.launcher_vehicle_image);

// Add listener for starting/stopping vehicle service.
Expand All @@ -105,6 +137,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Add listener for home button click.
mSetHomeButton.setOnLongClickListener(new SetHomeListener());

// Add listener for sensors update button click
mSetSensorsButton.setOnLongClickListener(new UpdateSensorsListener());

return view;
}

Expand Down Expand Up @@ -244,6 +279,91 @@ public void updateServerAddress() {
String port = sharedPreferences.getString("pref_server_port", "11411");
mIpAddressText.setText(getLocalIpAddress() + ":" + port);
}

/**
* Listens for long-click events on "Update Sensors" button and updates sensor types
*/
class UpdateSensorsListener implements View.OnLongClickListener {
@Override
public boolean onLongClick(View v) {
sendSensorsJSON();
return true;
}
}
void sendSensorsJSON()
{
Log.d(TAG, "LauncherFragment: sendSensorsJSON() called...");

if (mBound)
{
JSONObject sensors_JSON = generateSensorsJSON();
Log.d(TAG, " sensor JSON: ");
Log.d(TAG, sensors_JSON.toString());
mService.send(sensors_JSON);
mService.getServer().reset_expected_sensors(); // reset sensor type checks
}
else
{
Log.w(TAG, " mBound = false, sending nothing");
}
}
JSONObject generateSensorsJSON()
{
JSONObject sensors_JSON = new JSONObject();
for (int i = 1; i < 4; i++)
{
insertSensorJSON(i, sensors_JSON);
}
return sensors_JSON;
}
void insertSensorJSON(int sensorID, JSONObject sensors_JSON)
{
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(getActivity());
String sensor_array_name = "pref_sensor_" + Integer.toString(sensorID) + "_type";
try
{
switch (sharedPreferences.getString(sensor_array_name, "NONE"))
{
case "NONE":
sensors_JSON.put(String.format("i%d", sensorID), "None");
break;
case "ATLAS_DO":
sensors_JSON.put(String.format("i%d", sensorID), "AtlasDO");
break;
case "ATLAS_PH":
sensors_JSON.put(String.format("i%d", sensorID), "AtlasPH");
break;
case "ES2":
sensors_JSON.put(String.format("i%d", sensorID), "ES2");
break;
case "HDS":
sensors_JSON.put(String.format("i%d", sensorID), "HDS");
break;
case "ADAFRUIT_GPS":
sensors_JSON.put(String.format("i%d", sensorID), "AdaGPS");
break;
case "AHRS_PLUS":
sensors_JSON.put(String.format("i%d", sensorID), "AHRSp");
break;
case "BLUEBOX":
sensors_JSON.put(String.format("i%d", sensorID), "BlueBox");
break;
case "WINCH":
sensors_JSON.put(String.format("i%d", sensorID), "Winch");
break;
case "SAMPLER":
sensors_JSON.put(String.format("i%d", sensorID), "Sampler");
break;
default:
break;
}
}
catch (JSONException e)
{
Log.w(TAG, "Failed to serialize sensor type.", e);
}
}

/**
* Listens for long-click events on "Set Home" button and updates home location.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.platypus.android.server;

import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.platypus.crw.AbstractVehicleServer;
Expand Down Expand Up @@ -105,6 +109,53 @@ public class VehicleServerImpl extends AbstractVehicleServer {
// Last known temperature and EC values for sensor compensation
private double _lastTemp = 20.0; // Deg C
private double _lastEC = 0.0; // uS/cm

//Define Notification Manager
NotificationManager notificationManager;
//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

boolean[] received_expected_sensor_type = {false, false, false};
public void reset_expected_sensors()
{
for (int i = 0; i < 3; i++)
{
received_expected_sensor_type[i] = false;
}
}

private final Timer _sensorTypeTimer = new Timer();
private TimerTask expect_sensor_type_task = new TimerTask() {
@Override
public void run() {
for (int i = 0; i < 3; i++)
{
try {
Thread.sleep(1000); // sleep for all sensor slots, even if empty
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (!received_expected_sensor_type[i])
{
String sensor_array_name = "pref_sensor_" + Integer.toString(i+1) + "_type";
String expected_type = mPrefs.getString(sensor_array_name, "NONE");
if (expected_type.equals("NONE"))
{
continue;
}
String message = "s" + (i+1) + " expects " + expected_type + " not received yet";
Log.w(TAG, message);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(_context)
.setSmallIcon(R.drawable.camera_icon) //just some random icon placeholder
.setContentTitle("Sensor Warning")
.setContentText(message)
.setSound(soundUri); //This sets the sound to play
notificationManager.notify(0, mBuilder.build());
}
}
}
};

/**
* Internal update function called at regular intervals to process command
* and control events.
Expand Down Expand Up @@ -224,6 +275,9 @@ protected VehicleServerImpl(Context context, VehicleLogger logger, Controller co
// Connect to the Shared Preferences for this process.
mPrefs = PreferenceManager.getDefaultSharedPreferences(_context);

notificationManager = (NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);
_sensorTypeTimer.scheduleAtFixedRate(expect_sensor_type_task, 0, 100);

// Load PID values from SharedPreferences.
// Use hard-coded defaults if not specified.
r_PID[0] = mPrefs.getFloat("gain_rP", 1.0f);
Expand Down Expand Up @@ -404,9 +458,40 @@ protected void onCommand(JSONObject cmd) {
} else if (name.startsWith("s")) {
int sensor = name.charAt(1) - 48;

// check sensor type expected in the preferences
String sensor_array_name = "pref_sensor_" + Integer.toString(sensor) + "_type";
String expected_type = mPrefs.getString(sensor_array_name, "NONE");

// Hacks to send sensor information
if (value.has("type")) {
String type = value.getString("type");

// check if received type matches expected type
if (!type.equalsIgnoreCase("battery")) {
if (type.equalsIgnoreCase(expected_type)) {
received_expected_sensor_type[sensor - 1] = true;
/*
String message = "s" + sensor + ": expected = " + expected_type + " received = " + type;
Log.w(TAG, message);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(_context)
.setSmallIcon(R.drawable.camera_icon) //just some random icon placeholder
.setContentTitle("Sensor Success")
.setContentText(message)
.setSound(soundUri); //This sets the sound to play
notificationManager.notify(0, mBuilder.build());
*/
} else {
String message = "s" + sensor + ": expected = " + expected_type + " received = " + type;
Log.w(TAG, message);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(_context)
.setSmallIcon(R.drawable.camera_icon) //just some random icon placeholder
.setContentTitle("Sensor Warning")
.setContentText(message)
.setSound(soundUri); //This sets the sound to play
notificationManager.notify(0, mBuilder.build());
}
}

SensorData reading = new SensorData();

if (type.equalsIgnoreCase("es2")) {
Expand Down
43 changes: 41 additions & 2 deletions app/src/main/java/com/platypus/android/server/VehicleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
Expand All @@ -41,7 +42,9 @@
import org.jscience.geography.coordinates.LatLong;
import org.jscience.geography.coordinates.UTM;
import org.jscience.geography.coordinates.crs.ReferenceEllipsoid;
import org.json.JSONObject;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.measure.unit.NonSI;
Expand Down Expand Up @@ -75,6 +78,43 @@ public class VehicleService extends Service {

// Reference to vehicle controller;
private Controller mController;
public void send(JSONObject jsonObject)
{
Log.d(TAG, "VehicleService.send() called...");
if (mController != null)
{
try
{
if (mController.isConnected())
{
Log.d(TAG, " sending this JSON: ");
Log.d(TAG, jsonObject.toString());
mController.send(jsonObject);
}
else
{
Log.w(TAG, " mController is NOT connected");
}
}
catch (IOException e)
{
Log.w(TAG, "Failed to send command.", e);
}
}
else
{
Log.w(TAG, " mController is null");
}
}


public class LocalBinder extends Binder {
VehicleService getService() {
Log.d(TAG, "VehicleService: binding in process...");
return VehicleService.this;
}
}
private final IBinder mBinder = new LocalBinder();

// Objects implementing actual functionality
private VehicleServerImpl _vehicleServerImpl;
Expand Down Expand Up @@ -507,10 +547,9 @@ public void onFailure(@NonNull Exception e) {
super.onDestroy();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
return mBinder;
}

public void sendNotification(CharSequence text) {
Expand Down
Loading