private AltosJson config;
ArrayList<Byte> data;
private AltosConfigData config_data;
+ int errors = 0;
/*
* Public accessor APIs
AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data);
- monitor.set_filename(f.toString());
+ log.set_file(f);
- FileWriter w = new FileWriter(f);
+ boolean do_write = true;
- eeprom.write(w);
- w.close();
+ if (f.exists())
+ do_write = monitor.check_overwrite(f);
+
+ if (do_write) {
+ FileWriter w = new FileWriter(f);
+
+ eeprom.write(w);
+ w.close();
+ }
+
+ if (eeprom.errors != 0)
+ throw new ParseException(String.format("%d CRC Errors", eeprom.errors), 0);
+ }
+
+ static String label(int flight) {
+ if (flight < 0)
+ return "Corrupt";
+ else
+ return "Flight";
+ }
+
+ static int flight(int flight) {
+ if (flight < 0)
+ return -flight;
+ return flight;
}
public void run () {
boolean success = false;
try {
- boolean failed = false;
if (remote)
link.start_remote();
for (AltosEepromLog log : flights) {
parse_errors = null;
- if (log.selected) {
+ if (log.download_selected) {
monitor.reset();
try {
CaptureLog(log);
LogError(e.getMessage());
}
}
+ success = true;
if (parse_errors != null) {
- failed = true;
- monitor.show_message(String.format("Flight %d download error. Valid log data saved\n%s",
- log.flight,
+ monitor.show_message(String.format("%s %d download error. Valid log data saved\n%s",
+ label(log.flight),
+ flight(log.flight),
parse_errors),
link.name,
AltosEepromMonitor.WARNING_MESSAGE);
}
}
- success = !failed;
} catch (IOException ee) {
monitor.show_message(ee.getLocalizedMessage(),
link.name,
start = AltosParse.parse_hex(tokens[3]);
if (tokens[4].equals("end"))
end = AltosParse.parse_hex(tokens[5]);
- if (flight > 0 && start >= 0 && end > 0)
+ if (flight != 0 && start >= 0 && end > 0)
flights.add(new AltosEepromFlight(flight, start, end));
} catch (ParseException pe) { System.out.printf("Parse error %s\n", pe.toString()); }
}
link.flush_output();
}
}
-}
\ No newline at end of file
+}
package org.altusmetrum.altoslib_12;
+import java.io.*;
import java.text.*;
import java.util.concurrent.*;
public int start_block;
public int end_block;
- public boolean selected;
+ public boolean download_selected;
+ public boolean delete_selected;
+ public boolean graph_selected;
+
+ public File file;
+
+ public void set_file(File file) {
+ this.file = file;
+ }
public AltosEepromLog(AltosConfigData config_data,
AltosLink link,
serial = config_data.serial;
/*
- * Select all flights for download
+ * Select all flights for download and graph, but not
+ * for delete
*/
- selected = true;
+ download_selected = true;
+ delete_selected = false;
+ graph_selected = true;
}
}
package org.altusmetrum.altoslib_12;
+import java.io.*;
+
public interface AltosEepromMonitor {
public void set_block(int in_block);
public void set_flight(int in_flight);
- public void set_filename(String in_file);
-
public void set_thread(Thread eeprom_thread);
final static int INFO_MESSAGE = 0;
public void show_message(String message, String title, int message_type);
+ public Boolean check_overwrite(File file);
+
public void start();
public void done(boolean success);
return data8(i) | (data8(i+1) << 8) | (data8(i+2) << 16) | (data8(i+3) << 24);
}
+ public boolean empty(int s) {
+ for (int i = 0; i < length; i++)
+ if (eeprom.data8(s + i) != 0xff)
+ return false;
+ return true;
+ }
+
public boolean valid(int s) {
- return AltosConvert.checksum(eeprom.data, s, length) == 0;
+ int ck = AltosConvert.checksum(eeprom.data, s, length);
+
+ if (ck != 0) {
+ ++eeprom.errors;
+ System.out.printf("invalid checksum 0x%x at 0x%x\n", ck, s);
+ return false;
+ }
+ return true;
}
public boolean valid() {
int s = start + length;
while (s + length <= eeprom.data.size()) {
- if (valid(s))
+ if (!empty(s) && valid(s))
return s;
s += length;
}
return -1;
}
- public boolean hasNext() {
- return next_start() >= 0;
- }
-
public abstract AltosEepromRecord next();
public AltosEepromRecord(AltosEeprom eeprom, int start, int length) {
this.eeprom = eeprom;
this.start = start;
this.length = length;
-
- while (start + length < eeprom.data.size() && !valid())
- start += length;
}
}
int tick = 0;
boolean first = true;
- for (;;) {
+ do {
int t = record.tick();
if (first) {
}
record.wide_tick = tick;
ordered.add(record);
- if (!record.hasNext())
- break;
record = record.next();
- }
+ } while (record != null);
}
public AltosEepromRecordSet(InputStream input) throws IOException {
return String.format("-via-%04d", receiver);
}
+ static private String label(int flight) {
+ if (flight < 0)
+ return "corrupt";
+ else
+ return "flight";
+ }
+
+ static private int flight(int flight) {
+ if (flight < 0)
+ return -flight;
+ return flight;
+ }
+
public AltosFile(int year, int month, int day, int serial, int flight, int receiver, String extension) {
super (AltosPreferences.logdir(),
- String.format("%04d-%02d-%02d-serial-%s-flight-%s%s.%s",
- year, month, day, number(serial), number(flight), receiver(receiver), extension));
+ String.format("%04d-%02d-%02d-serial-%s-%s-%s%s.%s",
+ year, month, day, number(serial), label(flight), number(flight(flight)), receiver(receiver), extension));
}
public AltosFile(int year, int month, int day, int serial, int flight, String extension) {
import org.altusmetrum.altoslib_12.*;
import org.altusmetrum.altosuilib_12.*;
-public class AltosUI extends AltosUIFrame {
+public class AltosUI extends AltosUIFrame implements AltosEepromGrapher {
public AltosVoice voice = new AltosVoice();
public static boolean load_library(Frame frame) {
/* Connect to TeleMetrum, either directly or through
* a TeleDongle over the packet link
*/
+
+ public void graph_flights(AltosEepromList flights) {
+ for (AltosEepromLog flight : flights) {
+ if (flight.graph_selected && flight.file != null) {
+ process_graph(flight.file);
+ }
+ }
+ }
+
private void SaveFlightData() {
- new AltosEepromManage(AltosUI.this, AltosLib.product_any);
+ new AltosEepromManage(this, this, AltosLib.product_any);
}
private static AltosFlightSeries make_series(AltosRecordSet set) {
serial_line.start_remote();
for (AltosEepromLog log : flights) {
- if (log.selected) {
+ if (log.delete_selected) {
DeleteLog(log);
}
}
AltosEepromList flights;
AltosEepromDownload download;
AltosEepromDelete delete;
+ AltosEepromGrapher grapher;
public void finish() {
if (serial_line != null) {
private int countDeletedFlights() {
int count = 0;
for (AltosEepromLog flight : flights) {
- if (flight.selected)
+ if (flight.delete_selected)
count++;
}
return count;
String result = "";
for (AltosEepromLog flight : flights) {
- if (flight.selected) {
+ if (flight.delete_selected) {
if (result.equals(""))
result = String.format("%d", flight.flight);
else
return result;
}
- public boolean download_done() {
- AltosEepromSelect select = new AltosEepromSelect(frame, flights, "Delete");
-
- if (select.run()) {
- boolean any_selected = false;
- for (AltosEepromLog flight : flights)
- any_selected = any_selected || flight.selected;
- if (any_selected) {
- delete = new AltosEepromDelete(frame,
- serial_line,
- remote,
- flights);
- delete.addActionListener(this);
- /*
- * Start flight log delete
- */
-
- delete.start();
- return true;
- }
+ public boolean delete_start() {
+
+ boolean any_selected = false;
+ for (AltosEepromLog flight : flights)
+ any_selected = any_selected || flight.delete_selected;
+ if (any_selected) {
+ delete = new AltosEepromDelete(frame,
+ serial_line,
+ remote,
+ flights);
+ delete.addActionListener(this);
+ /*
+ * Start flight log delete
+ */
+
+ delete.start();
+ return true;
}
return false;
}
+ public void graph_start() {
+ boolean any_selected = false;
+ for (AltosEepromLog flight : flights) {
+ if (!flight.download_selected)
+ flight.graph_selected = false;
+ any_selected = any_selected || flight.graph_selected;
+ }
+ if (any_selected && grapher != null)
+ grapher.graph_flights(flights);
+ }
+
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
boolean success = e.getID() != 0;
boolean running = false;
if (cmd.equals("download")) {
- if (success)
- running = download_done();
+ if (success) {
+ running = delete_start();
+ if (!running)
+ graph_start();
+ }
} else if (cmd.equals("delete")) {
if (success) {
JOptionPane.showMessageDialog(frame,
showDeletedFlights()),
serial_line.device.toShortString(),
JOptionPane.INFORMATION_MESSAGE);
+ graph_start();
}
}
if (!running)
serial_line.device.toShortString(),
JOptionPane.INFORMATION_MESSAGE);
} else {
- AltosEepromSelect select = new AltosEepromSelect(frame, flights, "Download");
+ AltosEepromSelect select = new AltosEepromSelect(frame, flights, grapher != null);
if (select.run()) {
boolean any_selected = false;
for (AltosEepromLog flight : flights)
- any_selected = any_selected || flight.selected;
+ any_selected = any_selected || flight.download_selected;
if (any_selected) {
AltosEepromMonitorUI monitor = new AltosEepromMonitorUI(frame);
monitor.addActionListener(this);
download.start();
running = true;
} else {
- running = download_done();
+ running = delete_start();
+ if (!running)
+ graph_start();
}
}
}
}
}
- public AltosEepromManage(JFrame given_frame, int product) {
+ public AltosEepromManage(JFrame given_frame, AltosEepromGrapher grapher, int product) {
//boolean running = false;
frame = given_frame;
+ this.grapher = grapher;
device = AltosDeviceUIDialog.show(frame, product);
remote = false;
package org.altusmetrum.altosuilib_12;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import org.altusmetrum.altoslib_12.*;
+ class result_holder {
+ static int result;
+ }
+
public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor {
JFrame owner;
Container pane;
JLabel file_label;
JLabel serial_value;
JLabel flight_value;
- JLabel file_value;
JButton cancel;
JProgressBar pbar;
ActionListener listener;
public AltosEepromMonitorUI(JFrame owner) {
super (owner, "Download Flight Data", false);
+ setMinimumSize(new Dimension(600, 100));
+
this.owner = owner;
GridBagConstraints c;
flight_value = new JLabel("");
pane.add(flight_value, c);
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.NONE;
- c.gridx = 0; c.gridy = 2;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = il;
- file_label = new JLabel("File:");
- pane.add(file_label, c);
-
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.gridx = 1; c.gridy = 2;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = ir;
- file_value = new JLabel("");
- pane.add(file_value, c);
-
pbar = new JProgressBar();
pbar.setMinimum(0);
pbar.setMaximum(progress_max);
- pbar.setValue(0);
- pbar.setString("startup");
pbar.setStringPainted(true);
- pbar.setPreferredSize(new Dimension(600, 20));
+ set_block_internal(0);
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.CENTER;
c.insets = ib;
pane.add(pbar, c);
-
cancel = new JButton("Cancel");
c = new GridBagConstraints();
c.fill = GridBagConstraints.NONE;
final Thread eeprom_thread = in_eeprom_thread;
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- if (eeprom_thread != null)
+ if (eeprom_thread != null) {
eeprom_thread.interrupt();
+ }
}
});
}
s = String.format("block %d of %d", block, max_block);
pbar.setString(s);
+ pbar.setStringPainted(true);
pbar.setValue((int) (pos * progress_max));
}
SwingUtilities.invokeLater(r);
}
- private void set_filename_internal(String filename) {
- file_value.setText(String.format("%s", filename));
- }
-
- public void set_filename(String in_filename) {
- final String filename = in_filename;
- Runnable r = new Runnable() {
- public void run() {
- try {
- set_filename_internal(filename);
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
private void done_internal(boolean success) {
listener.actionPerformed(new ActionEvent(this,
success ? 1 : 0,
set_max(1);
set_block_internal(0);
set_flight_internal(0);
- set_filename_internal("");
}
public void reset() {
joption_message_type);
}
+ public Boolean check_overwrite(File in_file) {
+ final Semaphore check_overwrite_done = new Semaphore(0);
+ final File file = in_file;
+ final result_holder result = new result_holder();
+
+ Runnable r = new Runnable() {
+ public void run() {
+ result_holder.result = JOptionPane.showConfirmDialog(owner,
+ String.format("\"%s\" already exists, overwrite?",
+ file.toString()),
+ "Overwrite Existing File?",
+ JOptionPane.YES_NO_OPTION);
+ check_overwrite_done.release();
+ }
+ };
+
+ SwingUtilities.invokeLater(r);
+ try {
+ check_overwrite_done.acquire();
+ } catch (Exception e) {}
+ return result_holder.result == JOptionPane.YES_OPTION;
+ }
+
public void show_message(String in_message, String in_title, int in_message_type) {
final String message = in_message;
final String title = in_title;
class AltosEepromItem implements ActionListener {
AltosEepromLog log;
JLabel label;
- JCheckBox action;
+ JCheckBox download;
JCheckBox delete;
+ JCheckBox graph;
public void actionPerformed(ActionEvent e) {
- log.selected = action.isSelected();
+ log.download_selected = download.isSelected();
+ log.delete_selected = delete.isSelected();
+ log.graph_selected = graph.isSelected();
}
public AltosEepromItem(AltosEepromLog in_log) {
log = in_log;
String text;
- text = String.format("Flight #%02d", log.flight);
+ if (log.flight >= 0)
+ text = String.format("Flight #%02d", log.flight);
+ else
+ text = String.format("Corrupt #%02d", -log.flight);
label = new JLabel(text);
- action = new JCheckBox("", log.selected);
- action.addActionListener(this);
+ download = new JCheckBox("", log.download_selected);
+ download.addActionListener(this);
+
+ delete = new JCheckBox("", log.delete_selected);
+ delete.addActionListener(this);
+
+ graph = new JCheckBox("", log.graph_selected);
+ graph.addActionListener(this);
}
}
public AltosEepromSelect (JFrame in_frame,
AltosEepromList flights,
- String action) {
+ boolean has_graph) {
super(in_frame, String.format("Flight list for serial %d", flights.config_data.serial), true);
frame = in_frame;
Container contentPane = getContentPane();
/* First, we create a pane containing the dialog's header/title */
- JLabel selectLabel = new JLabel(String.format ("Select flights to %s", action), SwingConstants.CENTER);
+ JLabel selectLabel = new JLabel(String.format ("Select flights"), SwingConstants.CENTER);
JPanel labelPane = new JPanel();
labelPane.setLayout(new BoxLayout(labelPane, BoxLayout.X_AXIS));
c.weightx = 0.5;
c.anchor = GridBagConstraints.CENTER;
c.insets = i;
- JLabel downloadHeaderLabel = new JLabel(action);
+ JLabel downloadHeaderLabel = new JLabel("Download");
flightPane.add(downloadHeaderLabel, c);
+ /* Delete Header */
+ c = new GridBagConstraints();
+ c.gridx = 2; c.gridy = 0;
+ c.fill = GridBagConstraints.NONE;
+ c.weightx = 0.5;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ JLabel deleteHeaderLabel = new JLabel("Delete");
+ flightPane.add(deleteHeaderLabel, c);
+
+ if (has_graph) {
+ /* Graph Header */
+ c = new GridBagConstraints();
+ c.gridx = 3; c.gridy = 0;
+ c.fill = GridBagConstraints.NONE;
+ c.weightx = 0.5;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ JLabel graphHeaderLabel = new JLabel("Graph");
+ flightPane.add(graphHeaderLabel, c);
+ }
+
/* Add the flights to the GridBag */
AltosEepromItem item;
int itemNumber = 1;
c.insets = i;
flightPane.add(item.label, c);
- /* Add action checkbox for the flight */
+ /* Add download checkbox for the flight */
c = new GridBagConstraints();
c.gridx = 1; c.gridy = itemNumber;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.5;
c.anchor = GridBagConstraints.CENTER;
c.insets = i;
- flightPane.add(item.action, c);
+ flightPane.add(item.download, c);
+
+ /* Add delete checkbox for the flight */
+ c = new GridBagConstraints();
+ c.gridx = 2; c.gridy = itemNumber;
+ c.fill = GridBagConstraints.NONE;
+ c.weightx = 0.5;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ flightPane.add(item.delete, c);
+
+ if (has_graph) {
+ /* Add graph checkbox for the flight */
+ c = new GridBagConstraints();
+ c.gridx = 3; c.gridy = itemNumber;
+ c.fill = GridBagConstraints.NONE;
+ c.weightx = 0.5;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ flightPane.add(item.graph, c);
+ }
itemNumber++;
}
public class TeleGPS
extends AltosUIFrame
- implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener
+ implements AltosFlightDisplay, AltosFontListener, AltosUnitsListener, ActionListener, AltosEepromGrapher
{
static String[] telegps_icon_names = {
}
void download(){
- new AltosEepromManage(this, AltosLib.product_telegps);
+ new AltosEepromManage(this, this, AltosLib.product_telegps);
}
void configure() {
}
}
+ public void graph_flights(AltosEepromList list) {
+ for (AltosEepromLog log : list) {
+ if (log.file != null) {
+ AltosRecordSet set = record_set(log.file);
+ if (set != null) {
+ try {
+ new TeleGPSGraphUI(set, log.file);
+ } catch (InterruptedException ie) {
+ } catch (IOException ie) {
+ }
+ }
+ }
+ }
+ }
+
void flash() {
AltosFlashUI.show(this);
}