Merge remote-tracking branch 'mjb/altoslib_mjb'
[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;
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         AltosState              previous_state;
31         AltosConfigData         config_data;
32         AltosGPS                gps;
33
34         int AltosRSSI() throws TimeoutException, InterruptedException {
35                 link.printf("s\n");
36                 String line = link.get_reply_no_dialog(5000);
37                 if (line == null)
38                         throw new TimeoutException();
39                 String[] items = line.split("\\s+");
40                 if (items.length < 2)
41                         return 0;
42                 if (!items[0].equals("RSSI:"))
43                         return 0;
44                 int rssi = Integer.parseInt(items[1]);
45                 return rssi;
46         }
47
48         void update_state() throws InterruptedException, TimeoutException {
49                 AltosRecord     record = null;
50
51                 try {
52                         if (remote) {
53                                 link.set_radio_frequency(frequency);
54                                 link.start_remote();
55                         } else
56                                 link.flush_input();
57                         config_data = new AltosConfigData(link);
58                         if (config_data.product.startsWith("TeleMetrum")) {
59                                 record = new AltosSensorTM(link, config_data);
60                         } else if (config_data.product.startsWith("MegaMetrum")) {
61                                 AltosRecordMM record_mm = new AltosRecordMM();
62                                 AltosSensorMM sensor = new AltosSensorMM(link);
63                                 AltosMs5607 ms5607 = new AltosMs5607Query(link);
64                                 AltosIMU imu = new AltosIMUQuery(link);
65
66                                 record_mm.accel_plus_g = config_data.accel_cal_plus;
67                                 record_mm.accel_minus_g = config_data.accel_cal_minus;
68
69                                 record_mm.ground_accel = sensor.accel;
70                                 record_mm.accel = sensor.accel;
71                                 record_mm.ground_pres = ms5607.pa;
72                                 record_mm.pres = ms5607.pa;
73                                 record_mm.temp = ms5607.cc;
74
75                                 record_mm.v_batt = sensor.v_batt;
76                                 record_mm.v_pyro = sensor.v_pyro;
77                                 record_mm.sense = sensor.sense;
78
79                                 record_mm.imu = imu;
80
81                                 record = record_mm;
82                         } else
83                                 record = new AltosRecord();
84
85                         gps = new AltosGPSQuery(link, config_data);
86
87                         record.version = 0;
88                         record.callsign = config_data.callsign;
89                         record.serial = config_data.serial;
90                         record.flight = config_data.log_available() > 0 ? 255 : 0;
91                         record.status = 0;
92                         record.state = AltosLib.ao_flight_idle;
93                         record.gps = gps;
94                         record.new_gps = true;
95                         state = new AltosState (record, state);
96                 } finally {
97                         if (remote) {
98                                 link.stop_remote();
99                                 if (record != null)
100                                         record.rssi = AltosRSSI();
101                         } else {
102                                 if (record != null)
103                                         record.rssi = 0;
104                         }
105                 }
106
107         }
108
109         public void set_frequency(double in_frequency) {
110                 frequency = in_frequency;
111         }
112
113         public void post_state() {
114                 listener.update(state);
115         }
116
117         public void run() {
118                 try {
119                         for (;;) {
120                                 try {
121                                         update_state();
122                                         post_state();
123                                 } catch (TimeoutException te) {
124                                 }
125                                 Thread.sleep(1000);
126                         }
127                 } catch (InterruptedException ie) {
128                         link.close();
129                 }
130         }
131
132         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
133                 throws FileNotFoundException, InterruptedException, TimeoutException {
134                 listener = in_listener;
135                 link = in_link;
136                 remote = in_remote;
137                 state = null;
138         }
139 }