f2f75bbb60f80dc21cf388a70459e7c239c76b37
[fw/altos] / altoslib / AltosIdleMonitor.java
1 /*
2  * Copyright © 2010 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.altoslib_1;
19
20 import java.io.*;
21 import java.util.concurrent.*;
22
23
24 public class AltosIdleMonitor extends Thread {
25         AltosLink               link;
26         AltosIdleMonitorListener        listener;
27         AltosState              state;
28         boolean                 remote;
29         double                  frequency;
30         String                  callsign;
31         AltosState              previous_state;
32         AltosConfigData         config_data;
33         AltosGPS                gps;
34
35         int AltosRSSI() throws TimeoutException, InterruptedException {
36                 link.printf("s\n");
37                 String line = link.get_reply_no_dialog(5000);
38                 if (line == null)
39                         throw new TimeoutException();
40                 String[] items = line.split("\\s+");
41                 if (items.length < 2)
42                         return 0;
43                 if (!items[0].equals("RSSI:"))
44                         return 0;
45                 int rssi = Integer.parseInt(items[1]);
46                 return rssi;
47         }
48
49         boolean has_sensor_tm(AltosConfigData config_data) {
50                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMini");
51         }
52
53         boolean has_sensor_mm(AltosConfigData config_data) {
54                 return config_data.product.startsWith("MegaMetrum");
55         }
56
57         boolean has_gps(AltosConfigData config_data) {
58                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("MegaMetrum");
59         }
60
61         AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException {
62                 AltosRecordMM record_mm = new AltosRecordMM();
63                 AltosSensorMM sensor = new AltosSensorMM(link);
64                 AltosMs5607 ms5607 = new AltosMs5607Query(link);
65                 AltosIMU imu = new AltosIMUQuery(link);
66
67                 record_mm.accel_plus_g = config_data.accel_cal_plus;
68                 record_mm.accel_minus_g = config_data.accel_cal_minus;
69
70                 record_mm.ground_accel = sensor.accel;
71                 record_mm.accel = sensor.accel;
72                 record_mm.ground_pres = ms5607.pa;
73                 record_mm.pres = ms5607.pa;
74                 record_mm.temp = ms5607.cc;
75
76                 record_mm.v_batt = sensor.v_batt;
77                 record_mm.v_pyro = sensor.v_pyro;
78                 record_mm.sense = sensor.sense;
79
80                 record_mm.imu = imu;
81
82                 return record_mm;
83         }
84
85         void update_state() throws InterruptedException, TimeoutException {
86                 AltosRecord     record = null;
87
88                 try {
89                         if (remote) {
90                                 link.set_radio_frequency(frequency);
91                                 link.set_callsign(callsign);
92                                 link.start_remote();
93                         } else
94                                 link.flush_input();
95                         config_data = new AltosConfigData(link);
96
97                         if (has_sensor_tm(config_data))
98                                 record = new AltosSensorTM(link, config_data);
99                         else if (has_sensor_mm(config_data))
100                                 record = sensor_mm(config_data);
101                         else
102                                 record = new AltosRecordNone();
103
104                         if (has_gps(config_data))
105                                 gps = new AltosGPSQuery(link, config_data);
106
107                         record.version = 0;
108                         record.callsign = config_data.callsign;
109                         record.serial = config_data.serial;
110                         record.flight = config_data.log_available() > 0 ? 255 : 0;
111                         record.status = 0;
112                         record.state = AltosLib.ao_flight_idle;
113                         record.gps = gps;
114                         record.new_gps = true;
115                         state = new AltosState (record, state);
116                 } finally {
117                         if (remote) {
118                                 link.stop_remote();
119                                 if (record != null)
120                                         record.rssi = AltosRSSI();
121                         } else {
122                                 if (record != null)
123                                         record.rssi = 0;
124                         }
125                 }
126
127         }
128
129         public void set_frequency(double in_frequency) {
130                 frequency = in_frequency;
131                 link.abort_reply();
132         }
133
134         public void set_callsign(String in_callsign) {
135                 callsign = in_callsign;
136                 link.abort_reply();
137         }
138
139         public void post_state() {
140                 listener.update(state);
141         }
142
143         public void abort() {
144                 if (isAlive()) {
145                         interrupt();
146                         link.abort_reply();
147                         try {
148                                 join();
149                         } catch (InterruptedException ie) {
150                         }
151                 }
152         }
153
154         public void run() {
155                 try {
156                         for (;;) {
157                                 try {
158                                         update_state();
159                                         post_state();
160                                 } catch (TimeoutException te) {
161                                 }
162                                 Thread.sleep(1000);
163                         }
164                 } catch (InterruptedException ie) {
165                         link.close();
166                 }
167         }
168
169         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
170                 throws FileNotFoundException, InterruptedException, TimeoutException {
171                 listener = in_listener;
172                 link = in_link;
173                 remote = in_remote;
174                 state = null;
175         }
176 }