c379547f22e8efc480c6b14342ac41de9f87e264
[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         AltosListenerState      listener_state;
33         AltosConfigData         config_data;
34         AltosGPS                gps;
35
36         int AltosRSSI() throws TimeoutException, InterruptedException {
37                 link.printf("s\n");
38                 String line = link.get_reply_no_dialog(5000);
39                 if (line == null)
40                         throw new TimeoutException();
41                 String[] items = line.split("\\s+");
42                 if (items.length < 2)
43                         return 0;
44                 if (!items[0].equals("RSSI:"))
45                         return 0;
46                 int rssi = Integer.parseInt(items[1]);
47                 return rssi;
48         }
49
50         boolean has_sensor_tm(AltosConfigData config_data) {
51                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMini");
52         }
53
54         boolean has_sensor_mm(AltosConfigData config_data) {
55                 return config_data.product.startsWith("MegaMetrum");
56         }
57
58         boolean has_gps(AltosConfigData config_data) {
59                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("MegaMetrum");
60         }
61
62         AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException {
63                 AltosRecordMM record_mm = new AltosRecordMM();
64                 AltosSensorMM sensor = new AltosSensorMM(link);
65                 AltosMs5607 ms5607 = new AltosMs5607Query(link);
66                 AltosIMU imu = new AltosIMUQuery(link);
67
68                 record_mm.accel_plus_g = config_data.accel_cal_plus;
69                 record_mm.accel_minus_g = config_data.accel_cal_minus;
70
71                 record_mm.ground_accel = sensor.accel;
72                 record_mm.accel = sensor.accel;
73                 record_mm.ground_pres = ms5607.pa;
74                 record_mm.pres = ms5607.pa;
75                 record_mm.temp = ms5607.cc;
76
77                 record_mm.v_batt = sensor.v_batt;
78                 record_mm.v_pyro = sensor.v_pyro;
79                 record_mm.sense = sensor.sense;
80
81                 record_mm.imu = imu;
82
83                 return record_mm;
84         }
85
86         void update_state() throws InterruptedException, TimeoutException {
87                 AltosRecord     record = null;
88
89                 try {
90                         if (remote) {
91                                 link.set_radio_frequency(frequency);
92                                 link.set_callsign(callsign);
93                                 link.start_remote();
94                         } else
95                                 link.flush_input();
96                         config_data = new AltosConfigData(link);
97
98                         if (has_sensor_tm(config_data))
99                                 record = new AltosSensorTM(link, config_data);
100                         else if (has_sensor_mm(config_data))
101                                 record = sensor_mm(config_data);
102                         else
103                                 record = new AltosRecordNone();
104
105                         if (has_gps(config_data))
106                                 gps = new AltosGPSQuery(link, config_data);
107
108                         record.version = 0;
109                         record.callsign = config_data.callsign;
110                         record.serial = config_data.serial;
111                         record.flight = config_data.log_available() > 0 ? 255 : 0;
112                         record.status = 0;
113                         record.state = AltosLib.ao_flight_idle;
114                         record.gps = gps;
115                         record.new_gps = true;
116                         state = new AltosState (record, state);
117                 } finally {
118                         if (remote) {
119                                 link.stop_remote();
120                                 if (record != null) {
121                                         record.rssi = link.rssi();
122                                         listener_state.battery = link.monitor_battery();
123                                 }
124                         } else {
125                                 if (record != null)
126                                         record.rssi = 0;
127                         }
128                 }
129
130         }
131
132         public void set_frequency(double in_frequency) {
133                 frequency = in_frequency;
134                 link.abort_reply();
135         }
136
137         public void set_callsign(String in_callsign) {
138                 callsign = in_callsign;
139                 link.abort_reply();
140         }
141
142         public void post_state() {
143                 listener.update(state, listener_state);
144         }
145
146         public void abort() {
147                 if (isAlive()) {
148                         interrupt();
149                         link.abort_reply();
150                         try {
151                                 join();
152                         } catch (InterruptedException ie) {
153                         }
154                 }
155         }
156
157         public void run() {
158                 try {
159                         for (;;) {
160                                 try {
161                                         update_state();
162                                         post_state();
163                                 } catch (TimeoutException te) {
164                                 }
165                                 Thread.sleep(1000);
166                         }
167                 } catch (InterruptedException ie) {
168                         link.close();
169                 }
170         }
171
172         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
173                 throws FileNotFoundException, InterruptedException, TimeoutException {
174                 listener = in_listener;
175                 link = in_link;
176                 remote = in_remote;
177                 state = null;
178                 listener_state = new AltosListenerState();
179         }
180 }