package scheduler; import gnu.io.*; import java.io.*; import java.util.LinkedList; import java.util.Calendar; import java.util.Scanner; import scheduler.model.*; import scheduler.ProgressListener; public class PatientSerial { private static final char TERM = '~'; // it may be necessary to change this due to its low integer value private static boolean inputReady = false; private static String input = ""; private static String port = "COM5"; private static OutputStream out; private static LinkedList meds; private static boolean verification = false; private static void synchClock() throws Exception { byte hour = (byte)Calendar.getInstance().get(Calendar.HOUR_OF_DAY); byte min = (byte)Calendar.getInstance().get(Calendar.MINUTE); System.out.println("Synchronizing clock..."); putString("SYN"); checkConfirm(getString()); out.write(hour); out.write(min); putString(""); checkConfirm(getString()); System.out.println("Clock synchronized"); } public static boolean uploadPatient(Patient patient, final ProgressListener pl) { boolean rv = false; SerialPort sp = null; try { pl.progressUpdate("Initializing serial port...",0); sp = initPort(); verification = false; pl.progressUpdate("Populating meds list...", 10); meds = new LinkedList(); // fill in meds populateMedsList(patient.getSchedule()); System.out.println("Initialization complete."); pl.progressUpdate("Contacting device...", 20); // Reset Device putString("XX"); try { Thread.sleep(500); } catch (Exception e) {} pl.progressUpdate("Synchronizing clock...", 30); // Synch Clock synchClock(); pl.progressUpdate("Uploading schedule...", 40); System.out.println("Starting Schedule..."); // Begin schedule putString("US"); checkConfirm(getString()); System.out.println("Starting bins..."); // Bin transmission for (int i = 1; i <= 4; i++) { uploadBin(patient.getSchedule().getBin(i)); pl.progressUpdate("Uploading schedule...", 40 + i*10); } System.out.println("Starting meds..."); // Med header putString("MH"); checkConfirm(getString()); byte numMeds = (byte)meds.size(); out.write(numMeds); putString(""); checkConfirm(getString()); // Med transmissions int i = 0; for (Medication m : meds) { uploadMedication(m, i++); } if (meds.size() > 0) { System.out.println("Starting strings..."); // Strings header putString("S"); checkConfirm(getString()); for (Medication m : meds) { uploadName(m.getName()); } out.write(0); out.write(4); putString(""); checkConfirm(getString()); } pl.progressUpdate("Upload complete.", 90); verification = true; // Download complete System.out.println("Upload done."); pl.progressUpdate("Verifying...", 0); javax.swing.Timer timer = new javax.swing.Timer(20, new java.awt.event.ActionListener() { private int progress = 0; public void actionPerformed(java.awt.event.ActionEvent e) { pl.progressUpdate("Verifying...", progress++); } }); timer.start(); System.out.println("Verifying..."); try { Thread.sleep(4000); } catch (Exception e) {} // Verify the schedule rv = verifySchedule(patient.getSchedule()); timer.stop(); pl.progressUpdate("Verification Complete.", 100); System.out.println("Download complete."); verification = false; System.out.println("Returning control to GUI"); } catch (Exception e) { e.printStackTrace(); } finally { sp.close(); } return rv; } public static boolean verifyPatient(Patient p, final ProgressListener pl) { verification = true; SerialPort sp = null; boolean rv = false; try { pl.progressUpdate("Initializing serial port...", 0); putString("XX"); try { Thread.sleep(500); } catch (Exception e) {} sp = initPort(); input = ""; putString("VER"); pl.progressUpdate("Verifying...", 0); javax.swing.Timer timer = new javax.swing.Timer(30, new java.awt.event.ActionListener() { private int progress = 0; public void actionPerformed(java.awt.event.ActionEvent e) { pl.progressUpdate("Verifying...", progress++); } }); timer.start(); try { Thread.sleep(4000); } catch (Exception e) {} populateMedsList(p.getSchedule()); rv = verifySchedule(p.getSchedule()); timer.stop(); } catch (Exception e) { e.printStackTrace(); rv = false; } finally { sp.close(); } return rv; } private static void uploadBin(Bin b) throws Exception { // Begin bin putString("B"); checkConfirm(getString()); out.write((byte)b.getHour()); System.out.println("hour: " + (byte)b.getHour()); out.write((byte)b.getMinute()); out.write((byte)b.listDoses().length); putString(""); checkConfirm(getString()); for (Dose d : b.listDoses()) { if (d.getMedication() != null) { uploadDose(d); } } } private static void uploadDose(Dose d) throws Exception { // Begin dose System.out.println("Sending a dose..."); putString("D"); checkConfirm(getString()); out.write((byte)(d.getAmount()*10)); System.out.println("Amount: " + (byte)(d.getAmount()*10)); out.write((byte)(meds.indexOf(d.getMedication()))); System.out.println("Med#: " + (byte)(meds.indexOf(d.getMedication()))); putString(""); checkConfirm(getString()); System.out.println("..dose sent"); } private static void uploadMedication(Medication m, int name_num) throws Exception { // Begin med putString("M"); checkConfirm(getString()); out.write((byte)(name_num)); out.write((byte)(m.getShape().getNum())); out.write((byte)(m.getColor().getNum())); out.write((byte)(m.getSpecial1().getNum())); out.write((byte)(m.getSpecial2().getNum())); putString(""); checkConfirm(getString()); } private static void uploadName(String name) throws Exception { putString(name + "\0"); checkConfirm(getString()); } private static void populateMedsList(Schedule sched) throws Exception { meds.clear(); for (int i = 1; i <= 4; i++) { Bin b = sched.getBin(i); for (Dose d : b.listDoses()) { if (!meds.contains(d.getMedication())) { meds.add(d.getMedication()); } } } } private static boolean verifySchedule(Schedule sched) throws Exception { String s = getString(); System.out.println(s); Scanner scan = new Scanner(s); scan.useDelimiter(" "); System.out.println("Start verification"); if (!scan.next().equals("VER")) { return false; } System.out.println("Bin verification"); for (int i = 1; i <= 4; i++) { Bin currBin = sched.getBin(i); if(!scan.next().equals("B")) { System.out.println("Missing B"); return false; } char[] params = scan.next().toCharArray(); System.out.println("Received: " + ((int)params[0]) + " " + ((int)params[1]) + " " + ((int)params[2])); if (params[0] != currBin.getHour() || params[1] != currBin.getMinute() || params[2] != currBin.listDoses().length) { System.out.println("Wrong B params"); System.out.println("Expected: " + currBin.getHour() + " " + currBin.getMinute() + " " + currBin.listDoses().length); return false; } for (Dose d : currBin.listDoses()) { if (!scan.next().equals("D")) { System.out.println("Missing D"); return false; } params = scan.next().toCharArray(); System.out.println("Received: " + ((int)params[0]) + " " + ((int)params[1])); if (params[0] != (int)(d.getAmount()*10) || params[1] != meds.indexOf(d.getMedication())) { System.out.println("Wrong D Params"); System.out.println("Expected: " + ((int)(d.getAmount()*10)) + " " + meds.indexOf(d.getMedication())); return false; } } } System.out.println("Med Verification"); for (Medication med : meds) { if (!scan.next().equals("M")) { System.out.println("Missing M"); return false; } char[] params = scan.next().toCharArray(); if (params[0] != meds.indexOf(med) || params[1] != med.getShape().getNum() || params[2] != med.getColor().getNum() || params[3] != med.getSpecial1().getNum() || params[4] != med.getSpecial2().getNum()) { System.out.println("Wrong M Params"); return false; } } for (Medication med : meds) { if (!scan.next().equals(med.getName())) { System.out.println("Missing String"); return false; } } if (!scan.next().equals("FIN")) { System.out.println("Missing FIN"); return false; } return true; } private static SerialPort initPort() throws Exception { java.util.Enumeration idents = CommPortIdentifier.getPortIdentifiers(); SerialPort sp = null; while (idents.hasMoreElements()) { CommPortIdentifier portId = (CommPortIdentifier)idents.nextElement(); if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (port.equals(portId.getName())) { sp = (SerialPort)portId.open("Pill Scheduler", 2000); break; } } } if (sp == null) { System.err.println("Serial port not found or in use."); throw new Exception("Serial port not found or in use."); } sp.notifyOnDataAvailable(true); // 9600 baud, no parity, 1 stop-bit, no flow control sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); sp.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); out = sp.getOutputStream(); final InputStream in = sp.getInputStream(); final char[] inputArray = new char[128]; inputReady = false; sp.addEventListener(new SerialPortEventListener() { public void serialEvent(SerialPortEvent e) { if (e.getEventType() == SerialPortEvent.DATA_AVAILABLE) { try { char c = (char)in.read(); System.out.println("in: " + c); if (c == TERM) { inputReady = true; if (verification) { input += " "; } } else { input += (c + ""); } } catch (Exception f) { f.printStackTrace(); } } } }); return sp; } private static String getString() throws Exception { while(!inputReady); inputReady = false; String rv = input; input = ""; //System.out.println(rv); return rv; } private static void putString(String output) throws Exception { for (char c : output.toCharArray()) { out.write((byte)c); } out.write((byte)(TERM)); } private static void checkConfirm(String message) throws Exception { if (!message.endsWith("K")) { System.out.println("Expected OK, received: " + message); throw new Exception("Transmission denied"); } } }