altoslib/altosui: Carry receiver status around in AltosListenerState
[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 = link.rssi();
121                                         record.monitor_battery = link.monitor_battery();
122                                 }
123                         } else {
124                                 if (record != null)
125                                         record.rssi = 0;
126                         }
127                 }
128
129         }
130
131         public void set_frequency(double in_frequency) {
132                 frequency = in_frequency;
133                 link.abort_reply();
134         }
135
136         public void set_callsign(String in_callsign) {
137                 callsign = in_callsign;
138                 link.abort_reply();
139         }
140
141         public void post_state() {
142                 listener.update(state);
143         }
144
145         public void abort() {
146                 if (isAlive()) {
147                         interrupt();
148                         link.abort_reply();
149                         try {
150                                 join();
151                         } catch (InterruptedException ie) {
152                         }
153                 }
154         }
155
156         public void run() {
157                 try {
158                         for (;;) {
159                                 try {
160                                         update_state();
161                                         post_state();
162                                 } catch (TimeoutException te) {
163                                 }
164                                 Thread.sleep(1000);
165                         }
166                 } catch (InterruptedException ie) {
167                         link.close();
168                 }
169         }
170
171         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
172                 throws FileNotFoundException, InterruptedException, TimeoutException {
173                 listener = in_listener;
174                 link = in_link;
175                 remote = in_remote;
176                 state = null;
177         }
178 }