/* This file is part of Wattzap Community Edition. * * Wattzap Community Edtion is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Wattzap Community Edition is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Wattzap. If not, see <http://www.gnu.org/licenses/>. */ package com.wattzap.view.prefs; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.HashMap; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import net.miginfocom.swing.MigLayout; import com.wattzap.controller.MessageBus; import com.wattzap.controller.MessageCallback; import com.wattzap.controller.Messages; import com.wattzap.model.UserPreferences; import com.wattzap.model.ant.AdvancedSpeedCadenceListener; import com.wattzap.model.ant.Ant; import com.wattzap.model.ant.AntListener; import com.wattzap.model.ant.CadenceListener; import com.wattzap.model.ant.HeartRateListener; import com.wattzap.model.ant.PowerListener; import com.wattzap.model.ant.SpeedListener; import com.wattzap.model.dto.Telemetry; /** * Searches for and pairs ANT devices * * @author David George * @date 25th August 2013 * * (c) 2013-2015 David George / Wattzap.com */ public class AntPanel extends JPanel implements ActionListener, ItemListener, MessageCallback { private static final long serialVersionUID = 1L; private Ant antDevice; // device id display private JLabel sandcField; private JLabel cadenceField; private JLabel speedField; private JLabel hrmIdField; private JLabel powIdField; // Device values private JLabel sandcLabel; private JLabel speedLabel; private JLabel hrm; private JLabel cadenceLabel; private JLabel powLabel; private JLabel status; private int scID; private int hrmID; private int speedID; private int cadenceID; private int powerID; private JSlider powerSmooth; // Checkboxen JCheckBox scCheckBox; JCheckBox cadCheckBox; JCheckBox speedCheckBox; JCheckBox powCheckBox; JCheckBox hrmCheckBox; JButton pairButton; // Interface Text private final JLabel sCIDlabel; private final JLabel cadIdLabel; private final JLabel speedIdLabel; private final JLabel hrmIdLabel; private final JLabel powIdLabel; private UserPreferences userPrefs = UserPreferences.INSTANCE; private HashMap<String, AntListener> antListeners; public AntPanel() { super(); MigLayout layout = new MigLayout(); setLayout(layout); // speed and cadence sensor sCIDlabel = new JLabel(); sandcField = new JLabel(); scID = userPrefs.getSCId(); sandcField.setText(": " + scID); sandcLabel = new JLabel(); sandcLabel.setText("0 km/h"); scCheckBox = new JCheckBox(); add(sCIDlabel); add(sandcField); add(sandcLabel, "w 80!"); add(scCheckBox, "gapleft 30, wrap"); if (userPrefs.getSCId() > 0) { scCheckBox.setVisible(true); scCheckBox.setSelected(true); } else { scCheckBox.setVisible(false); } scCheckBox.addItemListener(this); // Cadence Sensor cadIdLabel = new JLabel(); cadenceField = new JLabel(); cadenceID = userPrefs.getCadenceId(); cadenceField.setText(": " + cadenceID); // cadence ID cadenceLabel = new JLabel(); cadenceLabel.setText("0 rpm"); cadCheckBox = new JCheckBox(); if (userPrefs.getCadenceId() > 0) { cadCheckBox.setVisible(true); cadCheckBox.setSelected(true); } else { cadCheckBox.setVisible(false); } add(cadIdLabel); add(cadenceField); add(cadenceLabel, "w 80!"); add(cadCheckBox, "gapleft 30, wrap"); cadCheckBox.addItemListener(this); // Speed Sensor speedIdLabel = new JLabel(); speedField = new JLabel(); speedID = userPrefs.getSpeedId(); speedField.setText(": " + speedID); // speed Sensor speedLabel = new JLabel(); speedLabel.setText("0 km/h"); speedCheckBox = new JCheckBox(); add(speedIdLabel); add(speedField); add(speedLabel, "w 80!"); add(speedCheckBox, "gapleft 30, wrap"); if (userPrefs.getSpeedId() > 0) { speedCheckBox.setVisible(true); speedCheckBox.setSelected(true); } else { speedCheckBox.setVisible(false); } speedCheckBox.addItemListener(this); // Power Meter powIdLabel = new JLabel(); powIdField = new JLabel(); powerID = userPrefs.getPowerId(); powIdField.setText(": " + powerID); // cadence ID powLabel = new JLabel(); powLabel.setText("0 watts"); powCheckBox = new JCheckBox(); add(powIdLabel); add(powIdField); add(powLabel, "w 80!"); add(powCheckBox, "gapleft 30, wrap"); if (userPrefs.getPowerId() > 0) { powCheckBox.setVisible(true); powCheckBox.setSelected(true); } else { powCheckBox.setVisible(false); } powCheckBox.addItemListener(this); // Heart Rate Strap hrmIdLabel = new JLabel(); hrmIdField = new JLabel(); hrmID = userPrefs.getHRMId(); hrmIdField.setText(": " + hrmID); hrmCheckBox = new JCheckBox(); hrm = new JLabel(); hrm.setText("0 bpm"); add(hrmIdLabel); add(hrmIdField); add(hrm); add(hrmCheckBox, "gapleft 30, wrap 15px"); if (userPrefs.getHRMId() > 0) { hrmCheckBox.setVisible(true); hrmCheckBox.setSelected(true); } else { hrmCheckBox.setVisible(false); } hrmCheckBox.addItemListener(this); JLabel pwrSliderLabel = new JLabel("Power Smoothing"); powerSmooth = new JSlider(JSlider.HORIZONTAL, 0, 30, 1); powerSmooth.setMajorTickSpacing(5); powerSmooth.setMinorTickSpacing(1); powerSmooth.setPaintTicks(true); powerSmooth.setVisible(true); add(pwrSliderLabel, "wrap"); add(powerSmooth, "wrap 15px"); pairButton = new JButton("Pair"); pairButton.setPreferredSize(new Dimension(60, 30)); pairButton.setActionCommand("pair"); pairButton.addActionListener(this); JButton stopButton = new JButton(userPrefs.getString("stop")); stopButton.setPreferredSize(new Dimension(60, 30)); stopButton.setActionCommand("stop"); stopButton.addActionListener(this); add(pairButton); add(stopButton, "wrap"); status = new JLabel(); status.setText(""); add(status, "span"); MessageBus.INSTANCE.register(Messages.LOCALE, this); setText(); } @Override public void callback(Messages message, Object o) { switch (message) { case HEARTRATE: int heartRate = (Integer) o; int hr = heartRate; if (hr != -1) { hrm.setText(Integer.toString(hr) + " bpm"); } break; case SPEED: Telemetry t = (Telemetry) o; if (userPrefs.isMetric()) { speedLabel.setText(String.format("%.1f", t.getSpeedKMH()) + " km/h"); sandcLabel.setText(String.format("%.1f", t.getSpeedKMH()) + " km/h"); } else { speedLabel.setText(String.format("%.1f", t.getSpeedMPH()) + " mph"); sandcLabel.setText(String.format("%.1f", t.getSpeedMPH()) + " mph"); } if (t.getPower() != -1) { powLabel.setText(t.getPower() + " watts"); } break; case CADENCE: int cadence = (Integer) o; cadenceLabel.setText(Integer.toString(cadence) + " rpm"); break; } } @Override public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); if (source == scCheckBox) { if (scCheckBox.isSelected()) { cadCheckBox.setSelected(false); speedCheckBox.setSelected(false); } } else if (source == cadCheckBox) { if (cadCheckBox.isSelected()) { scCheckBox.setSelected(false); } } else if (source == speedCheckBox) { if (speedCheckBox.isSelected()) { scCheckBox.setSelected(false); } } else if (source == powCheckBox) { // power checkbox selected, don't use speed if (speedCheckBox.isSelected()) { scCheckBox.setSelected(false); } } } @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if ("pair".equals(command)) { antListeners = new HashMap<String, AntListener>(); AntListener listener = new AdvancedSpeedCadenceListener(); antListeners.put(listener.getName(), listener); listener = new CadenceListener(); antListeners.put(listener.getName(), listener); listener = new SpeedListener(); antListeners.put(listener.getName(), listener); listener = new HeartRateListener(); antListeners.put(listener.getName(), listener); listener = new PowerListener(); antListeners.put(listener.getName(), listener); antDevice = new Ant(antListeners); // FIXME will need to set all ids to zero first scCheckBox.setVisible(false); scCheckBox.setSelected(false); hrmCheckBox.setVisible(false); hrmCheckBox.setSelected(false); sandcField.setText(": 0"); hrmIdField.setText(": 0"); MessageBus.INSTANCE.register(Messages.SPEED, this); MessageBus.INSTANCE.register(Messages.CADENCE, this); MessageBus.INSTANCE.register(Messages.HEARTRATE, this); antDevice.open(); status.setText("Attempting pairing..."); } else { status.setText("Pairing complete..."); MessageBus.INSTANCE.unregister(Messages.SPEED, this); MessageBus.INSTANCE.unregister(Messages.CADENCE, this); MessageBus.INSTANCE.unregister(Messages.HEARTRATE, this); hrmID = antDevice.getChannelId(HeartRateListener.name); if (hrmID > 0) { hrmCheckBox.setVisible(true); } hrmIdField.setText(": " + hrmID); scID = antDevice.getChannelId(AdvancedSpeedCadenceListener.name); if (scID > 0) { scCheckBox.setVisible(true); } sandcField.setText(": " + scID); cadenceID = antDevice.getChannelId(CadenceListener.name); if (cadenceID > 0) { cadCheckBox.setVisible(true); } cadenceField.setText(": " + cadenceID); speedID = antDevice.getChannelId(SpeedListener.name); if (speedID > 0) { speedCheckBox.setVisible(true); } speedField.setText(": " + speedID); powerID = antDevice.getChannelId(PowerListener.name); if (powerID > 0) { powCheckBox.setVisible(true); } powIdField.setText(": " + powerID); antDevice.close(); antListeners = null; } } private void setText() { sCIDlabel.setText("Speed and Cadence ID"); cadIdLabel.setText("Cadence ID"); speedIdLabel.setText("Speed ID"); powIdLabel.setText("Power ID"); hrmIdLabel.setText("HRM Id"); } public void close() { status.setText(""); speedLabel.setText(""); hrm.setText(""); } public int getSCId() { if (scCheckBox.isSelected()) { return scID; } return 0; } public int getHRMId() { if (hrmCheckBox.isSelected()) { return hrmID; } return 0; } public int getSpeedId() { if (speedCheckBox.isSelected()) { return speedID; } return 0; } public int getCadenceId() { if (cadCheckBox.isSelected()) { return cadenceID; } return 0; } public int getPwrId() { if (powCheckBox.isSelected()) { return powerID; } return 0; } public int getSmoothing() { return powerSmooth.getValue(); } }