altosdroid: Class of offline map view widget changed
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / TelemetryService.java
index eae360db3913e7678aa1e1cd19e3658737bf49d5..58bf8804513dbf787b0f3514fa3746099b7fa880 100644 (file)
 package org.altusmetrum.AltosDroid;
 
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
 import java.util.concurrent.TimeoutException;
-import java.util.Timer;
-import java.util.TimerTask;
+import java.util.*;
 
 import android.app.Notification;
 //import android.app.NotificationManager;
@@ -47,7 +45,6 @@ import android.location.Criteria;
 
 import org.altusmetrum.altoslib_7.*;
 
-
 public class TelemetryService extends Service implements LocationListener {
 
        static final int MSG_REGISTER_CLIENT   = 1;
@@ -62,6 +59,7 @@ public class TelemetryService extends Service implements LocationListener {
        static final int MSG_CRC_ERROR         = 10;
        static final int MSG_SETBAUD           = 11;
        static final int MSG_DISCONNECT        = 12;
+       static final int MSG_DELETE_SERIAL     = 13;
 
        // Unique Identification Number for the Notification.
        // We use it on Notification start, and to cancel it.
@@ -120,6 +118,10 @@ public class TelemetryService extends Service implements LocationListener {
                                s.address = null;
                                s.disconnect(true);
                                break;
+                       case MSG_DELETE_SERIAL:
+                               AltosDebug.debug("Delete Serial command received");
+                               s.delete_serial((Integer) msg.obj);
+                               break;
                        case MSG_SETFREQUENCY:
                                AltosDebug.debug("MSG_SETFREQUENCY");
                                s.telemetry_state.frequency = (Double) msg.obj;
@@ -197,13 +199,8 @@ public class TelemetryService extends Service implements LocationListener {
                                 * Messages from TelemetryReader
                                 */
                        case MSG_TELEMETRY:
-                               s.telemetry_state.state = (AltosState) msg.obj;
-                               if (s.telemetry_state.state != null) {
-                                       AltosDebug.debug("Save state");
-                                       AltosPreferences.set_state(0, s.telemetry_state.state, null);
-                               }
                                AltosDebug.debug("MSG_TELEMETRY");
-                               s.send_to_clients();
+                               s.telemetry((AltosTelemetry) msg.obj);
                                break;
                        case MSG_CRC_ERROR:
                                // forward crc error messages
@@ -217,13 +214,31 @@ public class TelemetryService extends Service implements LocationListener {
                }
        }
 
+       /* Handle telemetry packet
+        */
+       private void telemetry(AltosTelemetry telem) {
+               AltosState      state;
+
+               if (telemetry_state.states.containsKey(telem.serial))
+                       state = telemetry_state.states.get(telem.serial).clone();
+               else
+                       state = new AltosState();
+               telem.update_state(state);
+               telemetry_state.states.put(telem.serial, state);
+               if (state != null) {
+                       AltosDebug.debug("Save state %d", telem.serial);
+                       AltosPreferences.set_state(telem.serial, state, null);
+               }
+               send_to_clients();
+       }
+
        /* Construct the message to deliver to clients
         */
        private Message message() {
                if (telemetry_state == null)
                        AltosDebug.debug("telemetry_state null!");
-               if (telemetry_state.state == null)
-                       AltosDebug.debug("telemetry_state.state null!");
+               if (telemetry_state.states == null)
+                       AltosDebug.debug("telemetry_state.states null!");
                return Message.obtain(null, AltosDroid.MSG_STATE, telemetry_state);
        }
 
@@ -289,6 +304,8 @@ public class TelemetryService extends Service implements LocationListener {
                if (altos_link != null)
                        altos_link.closing();
 
+               stop_receiver_voltage_timer();
+
                if (telemetry_reader != null) {
                        AltosDebug.debug("disconnect(): stopping TelemetryReader");
                        telemetry_reader.interrupt();
@@ -332,6 +349,12 @@ public class TelemetryService extends Service implements LocationListener {
                }
        }
 
+       private void delete_serial(int serial) {
+               telemetry_state.states.remove((Integer) serial);
+               AltosPreferences.remove_state(serial);
+               send_to_clients();
+       }
+
        private void start_altos_bluetooth(DeviceAddress address, boolean pause) {
                // Get the BLuetoothDevice object
                BluetoothDevice device = bluetooth_adapter.getRemoteDevice(address.address);
@@ -345,6 +368,35 @@ public class TelemetryService extends Service implements LocationListener {
                send_to_clients();
        }
 
+       // Timer for receiver battery voltage monitoring
+       Timer receiver_voltage_timer;
+
+       private void update_receiver_voltage() {
+               if (altos_link != null) {
+                       try {
+                               double  voltage = altos_link.monitor_battery();
+                               AltosDebug.debug("update receiver voltage %g\n", voltage);
+                               telemetry_state.receiver_battery = voltage;
+                       } catch (InterruptedException ie) {
+                       }
+               }
+       }
+
+       private void stop_receiver_voltage_timer() {
+               if (receiver_voltage_timer != null) {
+                       receiver_voltage_timer.cancel();
+                       receiver_voltage_timer.purge();
+                       receiver_voltage_timer = null;
+               }
+       }
+
+       private void start_receiver_voltage_timer() {
+               if (receiver_voltage_timer == null && altos_link.has_monitor_battery()) {
+                       receiver_voltage_timer = new Timer();
+                       receiver_voltage_timer.scheduleAtFixedRate(new TimerTask() { public void run() {update_receiver_voltage();}}, 1000L, 10000L);
+               }
+       }
+
        private void connected() throws InterruptedException {
                AltosDebug.debug("connected top");
                AltosDebug.check_ui("connected\n");
@@ -372,13 +424,15 @@ public class TelemetryService extends Service implements LocationListener {
                telemetry_state.connect = TelemetryState.CONNECT_CONNECTED;
                telemetry_state.address = address;
 
-               telemetry_reader = new TelemetryReader(altos_link, handler, telemetry_state.state);
+               telemetry_reader = new TelemetryReader(altos_link, handler);
                telemetry_reader.start();
 
                AltosDebug.debug("connected TelemetryReader started");
 
                telemetry_logger = new TelemetryLogger(this, altos_link);
 
+               start_receiver_voltage_timer();
+
                AltosDebug.debug("Notify UI of connection");
 
                send_to_clients();
@@ -387,6 +441,12 @@ public class TelemetryService extends Service implements LocationListener {
 
        @Override
        public void onCreate() {
+
+               AltosDebug.init(this);
+
+               // Initialise preferences
+               AltosDroidPreferences.init(this);
+
                // Get local Bluetooth adapter
                bluetooth_adapter = BluetoothAdapter.getDefaultAdapter();
 
@@ -395,9 +455,6 @@ public class TelemetryService extends Service implements LocationListener {
                        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
                }
 
-               // Initialise preferences
-               AltosDroidPreferences.init(this);
-
                telemetry_state = new TelemetryState();
 
                // Create a reference to the NotificationManager so that we can update our notifcation text later
@@ -406,11 +463,32 @@ public class TelemetryService extends Service implements LocationListener {
                telemetry_state.connect = TelemetryState.CONNECT_DISCONNECTED;
                telemetry_state.address = null;
 
-               AltosSavedState saved_state = AltosPreferences.state(0);
+               /* Pull the saved state information out of the preferences database
+                */
+               ArrayList<Integer> serials = AltosPreferences.list_states();
+
+               telemetry_state.latest_serial = AltosPreferences.latest_state();
 
-               if (saved_state != null) {
-                       AltosDebug.debug("recovered old state flight %d\n", saved_state.state.flight);
-                       telemetry_state.state = saved_state.state;
+               for (int serial : serials) {
+                       AltosSavedState saved_state = AltosPreferences.state(serial);
+                       if (saved_state != null) {
+                               if (serial == 0) {
+                                       serial = saved_state.state.serial;
+                                       AltosPreferences.set_state(serial, saved_state.state, saved_state.listener_state);
+                                       AltosPreferences.remove_state(0);
+                               }
+                               if (telemetry_state.latest_serial == 0)
+                                       telemetry_state.latest_serial = serial;
+
+                               AltosDebug.debug("recovered old state serial %d flight %d\n",
+                                                serial,
+                                                saved_state.state.flight);
+                               if (saved_state.state.gps != null)
+                                       AltosDebug.debug("\tposition %f,%f\n",
+                                                        saved_state.state.gps.lat,
+                                                        saved_state.state.gps.lon);
+                               telemetry_state.states.put(serial, saved_state.state);
+                       }
                }
 
                // Listen for GPS and Network position updates