diff options
author | Keith Packard <keithp@keithp.com> | 2016-04-25 23:12:34 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-04-25 23:12:34 -0400 |
commit | 204ae5142702044eb8ad2697a55028e904067958 (patch) | |
tree | eadc8893251e4ebbfd036ccc57ac95aa1aba199d /altosdroid/src | |
parent | 565404599fe9edf9ba16aec348eeb19ea31af743 (diff) |
altosdroid: Add idle mode monitoring, reboot. Start igniters
This adds three idle mode operations -- monitor idle, reboot flight
computer and test igniters. The igniter test isn't quite wired up.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altosdroid/src')
5 files changed, 673 insertions, 21 deletions
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 4f1dcb1a..e5f56a5a 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -64,12 +64,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, public static final int MSG_STATE = 1; public static final int MSG_UPDATE_AGE = 2; + public static final int MSG_IDLE_MODE = 3; + public static final int MSG_IGNITER_STATUS = 4; // Intent request codes public static final int REQUEST_CONNECT_DEVICE = 1; public static final int REQUEST_ENABLE_BT = 2; public static final int REQUEST_PRELOAD_MAPS = 3; public static final int REQUEST_MAP_TYPE = 4; + public static final int REQUEST_IDLE_MODE = 5; + public static final int REQUEST_IGNITERS = 6; + + public static final String EXTRA_IDLE_MODE = "idle_mode"; + public static final String EXTRA_IDLE_RESULT = "idle_result"; + public static final String EXTRA_TELEMETRY_SERVICE = "telemetry_service"; public int map_type = AltosMap.maptype_hybrid; @@ -100,6 +108,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, private double frequency; private int telemetry_rate; + private boolean idle_mode = false; + public Location location = null; // Tabs @@ -146,6 +156,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, case MSG_UPDATE_AGE: ad.update_age(); break; + case MSG_IDLE_MODE: + ad.idle_mode = (Boolean) msg.obj; + ad.update_state(null); + break; } } }; @@ -216,8 +230,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, switch (telemetry_state.connect) { case TelemetryState.CONNECT_CONNECTED: if (telemetry_state.config != null) { - String str = String.format("S/N %d %6.3f MHz", telemetry_state.config.serial, - telemetry_state.frequency); + String str = String.format("S/N %d %6.3f MHz%s", telemetry_state.config.serial, + telemetry_state.frequency, idle_mode ? " (idle)" : ""); if (telemetry_state.telemetry_rate != AltosLib.ao_telemetry_rate_38400) str = str.concat(String.format(" %d bps", AltosLib.ao_telemetry_rate_values[telemetry_state.telemetry_rate])); @@ -444,7 +458,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, mCallsignView.setText(state.callsign); } if (saved_state == null || state.serial != saved_state.serial) { - mSerialView.setText(String.format("%d", state.serial)); + if (state.serial == AltosLib.MISSING) + mSerialView.setText(""); + else + mSerialView.setText(String.format("%d", state.serial)); } if (saved_state == null || state.flight != saved_state.flight) { if (state.flight == AltosLib.MISSING) @@ -461,7 +478,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } } if (saved_state == null || state.rssi != saved_state.rssi) { - mRSSIView.setText(String.format("%d", state.rssi)); + if (state.rssi == AltosLib.MISSING) + mRSSIView.setText(""); + else + mRSSIView.setText(String.format("%d", state.rssi)); } } @@ -681,9 +701,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); - AltosDebug.debug("Resume, location is %f,%f\n", - location.getLatitude(), - location.getLongitude()); + if (location != null) + AltosDebug.debug("Resume, location is %f,%f\n", + location.getLatitude(), + location.getLongitude()); update_ui(telemetry_state, saved_state); } @@ -740,6 +761,12 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (resultCode == Activity.RESULT_OK) set_map_type(data); break; + case REQUEST_IDLE_MODE: + if (resultCode == Activity.RESULT_OK) + idle_mode(data); + break; + case REQUEST_IGNITERS: + break; } } @@ -798,6 +825,40 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } } + private void idle_mode(Intent data) { + int type = data.getIntExtra(IdleModeActivity.EXTRA_IDLE_RESULT, -1); + Message msg; + + AltosDebug.debug("intent idle_mode %d", type); + switch (type) { + case IdleModeActivity.IDLE_MODE_CONNECT: + msg = Message.obtain(null, TelemetryService.MSG_MONITOR_IDLE_START); + try { + mService.send(msg); + } catch (RemoteException re) { + } + break; + case IdleModeActivity.IDLE_MODE_DISCONNECT: + msg = Message.obtain(null, TelemetryService.MSG_MONITOR_IDLE_STOP); + try { + mService.send(msg); + } catch (RemoteException re) { + } + break; + case IdleModeActivity.IDLE_MODE_REBOOT: + msg = Message.obtain(null, TelemetryService.MSG_REBOOT); + try { + mService.send(msg); + } catch (RemoteException re) { + } + break; + case IdleModeActivity.IDLE_MODE_IGNITERS: + Intent serverIntent = new Intent(this, IgniterActivity.class); + startActivityForResult(serverIntent, REQUEST_IGNITERS); + break; + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -1025,6 +1086,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } return true; + case R.id.idle_mode: + serverIntent = new Intent(this, IdleModeActivity.class); + serverIntent.putExtra(EXTRA_IDLE_MODE, idle_mode); + startActivityForResult(serverIntent, REQUEST_IDLE_MODE); + return true; } return false; } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java index 6bc52d7e..2b10b11f 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java @@ -207,10 +207,9 @@ public abstract class AltosDroidLink extends AltosLink { public void print(String data) { byte[] bytes = data.getBytes(); - AltosDebug.debug("print(): begin"); + AltosDebug.debug(data.replace('\n', '\\')); for (byte b : bytes) putchar(b); - AltosDebug.debug("print(): Wrote bytes: '" + data.replace('\n', '\\') + "'"); } public AltosDroidLink(Handler handler) { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/IdleModeActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/IdleModeActivity.java new file mode 100644 index 00000000..ec12c192 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/IdleModeActivity.java @@ -0,0 +1,130 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +import java.util.*; +import org.altusmetrum.AltosDroid.R; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.View.OnClickListener; +import android.widget.*; +import android.widget.AdapterView.*; + +import org.altusmetrum.altoslib_10.*; + +public class IdleModeActivity extends Activity { + private EditText callsign; + private Button connect; + private Button disconnect; + private Button reboot; + private Button igniters; + + public static final String EXTRA_IDLE_MODE = "idle_mode"; + public static final String EXTRA_IDLE_RESULT = "idle_result"; + + public static final int IDLE_MODE_CONNECT = 1; + public static final int IDLE_MODE_REBOOT = 2; + public static final int IDLE_MODE_IGNITERS = 3; + public static final int IDLE_MODE_DISCONNECT = 4; + + private void done(int type) { + AltosPreferences.set_callsign(callsign()); + Intent intent = new Intent(); + intent.putExtra(EXTRA_IDLE_RESULT, type); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + private String callsign() { + return callsign.getEditableText().toString(); + } + + public void connect_idle() { + done(IDLE_MODE_CONNECT); + } + + public void disconnect_idle() { + AltosDebug.debug("Disconnect idle button pressed"); + done(IDLE_MODE_DISCONNECT); + } + + public void reboot_idle() { + done(IDLE_MODE_REBOOT); + } + + public void igniters_idle() { + done(IDLE_MODE_IGNITERS); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Setup the window + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + setContentView(R.layout.idle_mode); + + callsign = (EditText) findViewById(R.id.set_callsign); + callsign.setText(new StringBuffer(AltosPreferences.callsign())); + + connect = (Button) findViewById(R.id.connect_idle); + connect.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + connect_idle(); + } + }); + disconnect = (Button) findViewById(R.id.disconnect_idle); + disconnect.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + disconnect_idle(); + } + }); + + boolean idle_mode = getIntent().getBooleanExtra(AltosDroid.EXTRA_IDLE_MODE, false); + + if (idle_mode) + connect.setVisibility(View.GONE); + else + disconnect.setVisibility(View.GONE); + + reboot = (Button) findViewById(R.id.reboot_idle); + reboot.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + reboot_idle(); + } + }); + igniters = (Button) findViewById(R.id.igniters_idle); + igniters.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + igniters_idle(); + } + }); + + // Set result CANCELED incase the user backs out + setResult(Activity.RESULT_CANCELED); + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java new file mode 100644 index 00000000..a608bba0 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java @@ -0,0 +1,303 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +import java.lang.ref.WeakReference; +import java.util.*; +import org.altusmetrum.AltosDroid.R; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.*; +import android.graphics.*; +import android.os.*; +import android.view.*; +import android.view.View.*; +import android.widget.*; +import android.widget.AdapterView.*; + +import org.altusmetrum.altoslib_10.*; + +class IgniterItem { + public String name; + public String status; + public LinearLayout igniter_view = null; + public TextView name_view = null; + public TextView status_view = null; + + private void update() { + AltosDebug.debug("update item %s %s", name, status); + if (name_view != null) + name_view.setText(name); + if (status_view != null) + status_view.setText(status); + } + + public void set(String name, String status) { + if (!name.equals(this.name) || !status.equals(this.status)) { + this.name = name; + this.status = status; + update(); + } + } + + public void realize(LinearLayout igniter_view, + TextView name_view, + TextView status_view) { + if (igniter_view != this.igniter_view || + name_view != this.name_view || + status_view != this.status_view) + { + this.igniter_view = igniter_view; + this.name_view = name_view; + this.status_view = status_view; + update(); + } + } + + public IgniterItem() { + AltosDebug.debug("New igniter item"); + } +} + +class IgniterAdapter extends ArrayAdapter<IgniterItem> { + int resource; + int selected_item = -1; + + public IgniterAdapter(Context context, int in_resource) { + super(context, in_resource); + resource = in_resource; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + IgniterItem item = getItem(position); + if (item.igniter_view == null) { + LinearLayout igniter_view = new LinearLayout(getContext()); + String inflater = Context.LAYOUT_INFLATER_SERVICE; + LayoutInflater li = (LayoutInflater) getContext().getSystemService(inflater); + li.inflate(resource, igniter_view, true); + + item.realize(igniter_view, + (TextView) igniter_view.findViewById(R.id.igniter_name), + (TextView) igniter_view.findViewById(R.id.igniter_status)); + AltosDebug.debug("Realize new igniter view"); + } else + AltosDebug.debug("Reuse existing igniter view"); + if (position == selected_item) + item.igniter_view.setBackgroundColor(Color.RED); + else + item.igniter_view.setBackgroundColor(Color.BLACK); + return item.igniter_view; + } +} + +public class IgniterActivity extends Activity { + private ListView igniters_view; + private ToggleButton arm; + private Button fire; + + private HashMap<String,IgniterItem> igniters = new HashMap<String,IgniterItem>();; + + private IgniterAdapter igniters_adapter; + + private boolean is_bound; + private boolean timer_running; + private Messenger service = null; + private final Messenger messenger = new Messenger(new IncomingHandler(this)); + + private Timer timer; + + public static final int IGNITER_QUERY = 1; + public static final int IGNITER_FIRE = 2; + + // The Handler that gets information back from the Telemetry Service + static class IncomingHandler extends Handler { + private final WeakReference<IgniterActivity> igniter_activity; + IncomingHandler(IgniterActivity ia) { igniter_activity = new WeakReference<IgniterActivity>(ia); } + + @Override + public void handleMessage(Message msg) { + IgniterActivity ia = igniter_activity.get(); + + switch (msg.what) { + case AltosDroid.MSG_IGNITER_STATUS: + ia.igniter_status((HashMap <String,Integer>) msg.obj); + break; + } + } + }; + + + private ServiceConnection connection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder binder) { + service = new Messenger(binder); + } + + public void onServiceDisconnected(ComponentName className) { + // This is called when the connection with the service has been unexpectedly disconnected - process crashed. + service = null; + } + }; + + void doBindService() { + bindService(new Intent(this, TelemetryService.class), connection, Context.BIND_AUTO_CREATE); + is_bound = true; + } + + void doUnbindService() { + if (is_bound) { + // If we have received the service, and hence registered with it, then now is the time to unregister. + unbindService(connection); + is_bound = false; + } + } + + private void done() { + Intent intent = new Intent(); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + private void fire_igniter() { + } + + private void arm_igniter(boolean is_checked) { + } + + private synchronized void timer_tick() { + if (timer_running) + return; + timer_running = true; + try { + Message msg = Message.obtain(null, TelemetryService.MSG_IGNITER_QUERY); + msg.replyTo = messenger; + service.send(msg); + } catch (RemoteException re) { + } + } + + private boolean set_igniter(HashMap <String,Integer> status, String name, String pretty) { + if (!status.containsKey(name)) + return false; + + IgniterItem item; + if (!igniters.containsKey(name)) { + item = new IgniterItem(); + igniters.put(name, item); + igniters_adapter.add(item); + } else + item = igniters.get(name); + + item.set(pretty, AltosIgnite.status_string(status.get(name))); + return true; + } + + private synchronized void igniter_status(HashMap <String,Integer> status) { + timer_running = false; + if (status == null) { + AltosDebug.debug("no igniter status"); + return; + } + set_igniter(status, "drogue", "Apogee"); + set_igniter(status, "main", "Main"); + for (int extra = 0;; extra++) { + String name = String.format("%d", extra); + String pretty = String.format("%c", 'A' + extra); + if (!set_igniter(status, name, pretty)) + break; + } +// if (igniters_adapter.selected_item >= 0) +// igniters_view.setSelection(selected_item); + } + + private class IgniterItemClickListener implements ListView.OnItemClickListener { + @Override + public void onItemClick(AdapterView<?> av, View v, int position, long id) { + if (igniters_adapter.selected_item >= 0) + igniters_view.setItemChecked(igniters_adapter.selected_item, false); + igniters_view.setItemChecked(position, true); + igniters_adapter.selected_item = position; + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Setup the window + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + setContentView(R.layout.igniters); + + igniters_view = (ListView) findViewById(R.id.igniters); + igniters_view.setClickable(true); + + igniters_adapter = new IgniterAdapter(this, R.layout.igniter_status); + + igniters_view.setAdapter(igniters_adapter); + igniters_view.setOnItemClickListener(new IgniterItemClickListener()); + + fire = (Button) findViewById(R.id.igniter_fire); + fire.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + fire_igniter(); + } + }); + + arm = (ToggleButton) findViewById(R.id.igniter_arm); + arm.setOnCheckedChangeListener(new ToggleButton.OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton v, boolean is_checked) { + arm_igniter(is_checked); + } + }); + + // Set result CANCELED incase the user backs out + setResult(Activity.RESULT_CANCELED); + } + + @Override + protected void onStart() { + super.onStart(); + doBindService(); + } + + @Override + protected void onResume() { + super.onResume(); + timer = new Timer(true); + timer.scheduleAtFixedRate(new TimerTask() { + public void run() { + timer_tick(); + }}, + 1000L, 1000L); + } + + @Override + protected void onPause() { + super.onPause(); + timer.cancel(); + timer = null; + } + + @Override + protected void onStop() { + super.onStop(); + doUnbindService(); + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 926109e2..4b26d263 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -42,7 +42,7 @@ import android.location.Criteria; import org.altusmetrum.altoslib_10.*; -public class TelemetryService extends Service { +public class TelemetryService extends Service implements AltosIdleMonitorListener { static final int MSG_REGISTER_CLIENT = 1; static final int MSG_UNREGISTER_CLIENT = 2; @@ -58,6 +58,11 @@ public class TelemetryService extends Service { static final int MSG_DISCONNECT = 12; static final int MSG_DELETE_SERIAL = 13; static final int MSG_BLUETOOTH_ENABLED = 14; + static final int MSG_MONITOR_IDLE_START= 15; + static final int MSG_MONITOR_IDLE_STOP = 16; + static final int MSG_REBOOT = 17; + static final int MSG_IGNITER_QUERY = 18; + static final int MSG_IGNITER_FIRE = 19; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. @@ -80,6 +85,13 @@ public class TelemetryService extends Service { // Last data seen; send to UI when it starts private TelemetryState telemetry_state; + // Idle monitor if active + AltosIdleMonitor idle_monitor = null; + + // Igniter bits + AltosIgnite ignite = null; + boolean ignite_running; + // Handler of incoming messages from clients. static class IncomingHandler extends Handler { private final WeakReference<TelemetryService> service; @@ -93,6 +105,7 @@ public class TelemetryService extends Service { AltosDroidLink bt = null; if (s == null) return; + switch (msg.what) { /* Messages from application */ @@ -212,6 +225,26 @@ public class TelemetryService extends Service { if (address != null && !address.address.startsWith("USB")) s.start_altos_bluetooth(address, false); break; + case MSG_MONITOR_IDLE_START: + AltosDebug.debug("start monitor idle"); + s.start_idle_monitor(); + break; + case MSG_MONITOR_IDLE_STOP: + AltosDebug.debug("stop monitor idle"); + s.stop_idle_monitor(); + break; + case MSG_REBOOT: + AltosDebug.debug("reboot"); + s.reboot_remote(); + break; + case MSG_IGNITER_QUERY: + AltosDebug.debug("igniter query"); + s.igniter_query(msg.replyTo); + break; + case MSG_IGNITER_FIRE: + AltosDebug.debug("igniter fire"); + s.igniter_fire((String) msg.obj); + break; default: super.handleMessage(msg); } @@ -255,6 +288,7 @@ public class TelemetryService extends Service { /* On connect, send the current state to the new client */ send_to_client(client); + send_idle_mode_to_client(client); /* If we've got an address from a previous session, then * go ahead and try to reconnect to the device @@ -296,17 +330,29 @@ public class TelemetryService extends Service { send_to_client(client); } - private void disconnect(boolean notify) { - AltosDebug.debug("disconnect(): begin"); - - telemetry_state.connect = TelemetryState.CONNECT_DISCONNECTED; - telemetry_state.address = null; + private void send_idle_mode_to_client(Messenger client) { + Message m = Message.obtain(null, AltosDroid.MSG_IDLE_MODE, idle_monitor != null); + try { + client.send(m); + } catch (RemoteException e) { + AltosDebug.error("Client %s disappeared", client.toString()); + remove_client(client); + } + } - if (altos_link != null) - altos_link.closing(); + private void send_idle_mode_to_clients() { + for (Messenger client : clients) + send_idle_mode_to_client(client); + } - stop_receiver_voltage_timer(); + private void telemetry_start() { + if (telemetry_reader == null && idle_monitor == null && !ignite_running) { + telemetry_reader = new TelemetryReader(altos_link, handler); + telemetry_reader.start(); + } + } + private void telemetry_stop() { if (telemetry_reader != null) { AltosDebug.debug("disconnect(): stopping TelemetryReader"); telemetry_reader.interrupt(); @@ -316,6 +362,23 @@ public class TelemetryService extends Service { } telemetry_reader = null; } + } + + private void disconnect(boolean notify) { + AltosDebug.debug("disconnect(): begin"); + + telemetry_state.connect = TelemetryState.CONNECT_DISCONNECTED; + telemetry_state.address = null; + + if (idle_monitor != null) + stop_idle_monitor(); + + if (altos_link != null) + altos_link.closing(); + + stop_receiver_voltage_timer(); + + telemetry_stop(); if (telemetry_logger != null) { AltosDebug.debug("disconnect(): stopping TelemetryLogger"); telemetry_logger.stop(); @@ -325,6 +388,7 @@ public class TelemetryService extends Service { AltosDebug.debug("disconnect(): stopping AltosDroidLink"); altos_link.close(); altos_link = null; + ignite = null; } telemetry_state.config = null; if (notify) { @@ -373,14 +437,95 @@ public class TelemetryService extends Service { send_to_clients(); } + private void start_idle_monitor() { + if (altos_link != null && idle_monitor == null) { + telemetry_stop(); + idle_monitor = new AltosIdleMonitor(this, altos_link, true, false); + idle_monitor.set_callsign(AltosPreferences.callsign()); + idle_monitor.start(); + send_idle_mode_to_clients(); + } + } + + private void stop_idle_monitor() { + if (idle_monitor != null) { + try { + idle_monitor.abort(); + } catch (InterruptedException ie) { + } + idle_monitor = null; + telemetry_start(); + send_idle_mode_to_clients(); + } + } + + private void reboot_remote() { + if (altos_link != null) { + stop_idle_monitor(); + try { + altos_link.start_remote(); + altos_link.printf("r eboot\n"); + altos_link.flush_output(); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } finally { + try { + altos_link.stop_remote(); + } catch (InterruptedException ie) { + } + } + } + } + + private void ensure_ignite() { + if (ignite == null) + ignite = new AltosIgnite(altos_link, true, false); + } + + private synchronized void igniter_query(Messenger client) { + ensure_ignite(); + HashMap<String,Integer> status_map = null; + ignite_running = true; + try { + stop_idle_monitor(); + try { + status_map = ignite.status(); + } catch (InterruptedException ie) { + AltosDebug.debug("ignite.status interrupted"); + } catch (TimeoutException te) { + AltosDebug.debug("ignite.status timeout"); + } + } finally { + ignite_running = false; + } + Message m = Message.obtain(null, AltosDroid.MSG_IGNITER_STATUS, status_map); + try { + client.send(m); + } catch (RemoteException e) { + } + } + + private synchronized void igniter_fire(String igniter) { + ensure_ignite(); + ignite_running = true; + stop_idle_monitor(); + try { + ignite.fire(igniter); + } catch (InterruptedException ie) { + } finally { + ignite_running = false; + } + } + // Timer for receiver battery voltage monitoring Timer receiver_voltage_timer; private void update_receiver_voltage() { - if (altos_link != null) { + if (altos_link != null && idle_monitor == null && !ignite_running) { try { double voltage = altos_link.monitor_battery(); telemetry_state.receiver_battery = voltage; + send_to_clients(); } catch (InterruptedException ie) { } } @@ -428,8 +573,7 @@ public class TelemetryService extends Service { telemetry_state.connect = TelemetryState.CONNECT_CONNECTED; telemetry_state.address = address; - telemetry_reader = new TelemetryReader(altos_link, handler); - telemetry_reader.start(); + telemetry_start(); AltosDebug.debug("connected TelemetryReader started"); @@ -549,4 +693,14 @@ public class TelemetryService extends Service { public IBinder onBind(Intent intent) { return messenger.getBinder(); } + + /* AltosIdleMonitorListener */ + public void update(AltosState state, AltosListenerState listener_state) { + telemetry_state.states.put(state.serial, state); + telemetry_state.receiver_battery = listener_state.battery; + send_to_clients(); + } + + public void failed() { + } } |