Index: Configuration.cpp
===================================================================
--- Configuration.cpp	(revision 6352)
+++ Configuration.cpp	(working copy)
@@ -525,6 +525,7 @@
   bool id_after_73_;
   bool tx_QSY_allowed_;
   bool spot_to_psk_reporter_;
+  bool spot_to_snus_reporter_;
   bool monitor_off_at_startup_;
   bool monitor_last_used_;
   bool log_as_RTTY_;
@@ -606,6 +607,7 @@
 bool Configuration::id_after_73 () const {return m_->id_after_73_;}
 bool Configuration::tx_QSY_allowed () const {return m_->tx_QSY_allowed_;}
 bool Configuration::spot_to_psk_reporter () const {return m_->spot_to_psk_reporter_;}
+bool Configuration::spot_to_snus_reporter () const {return m_->spot_to_snus_reporter_;}
 bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
 bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
 bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
@@ -1054,6 +1056,7 @@
   ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
   ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
   ui_->psk_reporter_check_box->setChecked (spot_to_psk_reporter_);
+  ui_->snus_reporter_check_box->setChecked (spot_to_snus_reporter_);
   ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
   ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
   ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
@@ -1241,6 +1244,7 @@
   monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
   monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
   spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
+  spot_to_snus_reporter_ = settings_->value ("SNUSReporter", false).toBool ();
   id_after_73_ = settings_->value ("After73", false).toBool ();
   tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
 
@@ -1359,6 +1363,7 @@
   settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
   settings_->setValue ("MonitorLastUsed", monitor_last_used_);
   settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
+  settings_->setValue ("SNUSReporter", spot_to_snus_reporter_);
   settings_->setValue ("After73", id_after_73_);
   settings_->setValue ("TxQSYAllowed", tx_QSY_allowed_);
   settings_->setValue ("Macros", macros_.stringList ());
@@ -1756,6 +1761,7 @@
   my_callsign_ = ui_->callsign_line_edit->text ();
   my_grid_ = ui_->grid_line_edit->text ();
   spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
+  spot_to_snus_reporter_ = ui_->snus_reporter_check_box->isChecked ();
   id_interval_ = ui_->CW_id_interval_spin_box->value ();
   ntrials_ = ui_->sbNtrials->value ();
   aggressive_ = ui_->sbAggressive->value ();
Index: Configuration.hpp
===================================================================
--- Configuration.hpp	(revision 6352)
+++ Configuration.hpp	(working copy)
@@ -97,6 +97,7 @@
   bool id_after_73 () const;
   bool tx_QSY_allowed () const;
   bool spot_to_psk_reporter () const;
+  bool spot_to_snus_reporter () const;
   bool monitor_off_at_startup () const;
   bool monitor_last_used () const;
   bool log_as_RTTY () const;
Index: Configuration.ui
===================================================================
--- Configuration.ui	(revision 6352)
+++ Configuration.ui	(working copy)
@@ -1577,11 +1577,14 @@
        </item>
        <item>
         <widget class="QGroupBox" name="network_group_box">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
          <property name="title">
           <string>Network Services</string>
          </property>
-         <layout class="QGridLayout" name="gridLayout_17">
-          <item row="0" column="0">
+         <layout class="QVBoxLayout" name="verticalLayout_13">
+          <item>
            <widget class="QCheckBox" name="psk_reporter_check_box">
             <property name="toolTip">
              <string>The program can send your station details and all
@@ -1594,7 +1597,20 @@
             </property>
            </widget>
           </item>
+          <item>
+           <widget class="QCheckBox" name="snus_reporter_check_box">
+            <property name="toolTip">
+             <string>Report balloon data to http://picospace.net</string>
+            </property>
+            <property name="text">
+             <string>Enable &amp;SNUS Reporter Spotting</string>
+            </property>
+           </widget>
+          </item>
          </layout>
+         <zorder>psk_reporter_check_box</zorder>
+         <zorder>snus_reporter_check_box</zorder>
+         <zorder>groupBox_4</zorder>
         </widget>
        </item>
        <item>
@@ -1693,22 +1709,22 @@
             </item>
            </layout>
           </item>
+          <item row="1" column="0" colspan="2">
+           <spacer name="verticalSpacer_4">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
          </layout>
         </widget>
        </item>
-       <item>
-        <spacer name="verticalSpacer_4">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="frequencies_tab">
@@ -2491,12 +2507,12 @@
   </connection>
  </connections>
  <buttongroups>
+  <buttongroup name="TX_audio_source_button_group"/>
   <buttongroup name="split_mode_button_group"/>
-  <buttongroup name="TX_mode_button_group"/>
+  <buttongroup name="CAT_stop_bits_button_group"/>
   <buttongroup name="PTT_method_button_group"/>
-  <buttongroup name="TX_audio_source_button_group"/>
-  <buttongroup name="CAT_stop_bits_button_group"/>
   <buttongroup name="CAT_handshake_button_group"/>
   <buttongroup name="CAT_data_bits_button_group"/>
+  <buttongroup name="TX_mode_button_group"/>
  </buttongroups>
 </ui>
Index: mainwindow.cpp
===================================================================
--- mainwindow.cpp	(revision 6352)
+++ mainwindow.cpp	(working copy)
@@ -18,6 +18,8 @@
 #include <QVector>
 #include <QCursor>
 #include <QToolTip>
+#include <QtNetwork>
+#include <QHash>
 
 #include "revision_utils.hpp"
 #include "qt_helpers.hpp"
@@ -682,6 +684,10 @@
   m_dialFreqRxWSPR=0;
   wsprNet = new WSPRNet(network_manager, this);
   connect( wsprNet, SIGNAL(uploadStatus(QString)), this, SLOT(uploadResponse(QString)));
+  networkManager = new QNetworkAccessManager(this);
+  balloonData = new QHash<QString,QString>();
+  connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestCompleted(QNetworkReply *)));
+  
   if(m_bFastMode) {
     int ntr[]={5,10,15,30};
     m_TRperiod=ntr[m_TRindex-11];
@@ -1900,6 +1906,24 @@
           psk_Reporter->addRemoteStation(deCall,grid,QString::number(frequency),msgmode,
                   QString::number(snr),QString::number(QDateTime::currentDateTime().toTime_t()));
       }
+      // send telemetry to HAB server if required
+      // will send the RX station callsign, grid, frequency and JT9/65 string
+      QString deCall;
+      QString grid;
+      decodedtext.deCallAndGrid(/*out*/deCall,grid);
+      if (m_config.spot_to_snus_reporter () and gridChanged(deCall,grid) and stdMsg and !m_diskData){
+        QUrl serviceUrl = QUrl("http://vps.comms.net.au/snus.php");
+        QByteArray postData;
+        Frequency frequency = m_dialFreq + decodedtext.frequencyOffset();
+        QUrlQuery q;
+        q.addQueryItem("callsign",  m_config.my_callsign());
+        q.addQueryItem("grid",  m_config.my_grid());
+        q.addQueryItem("frequency", QString::number(frequency));
+        q.addQueryItem("data", QString(decodedtext.string()).replace(QString("+"), QString("%2B")));
+        q.addQueryItem("version", version());
+        postData = q.query(QUrl::FullyEncoded).toUtf8();
+        networkManager->post(QNetworkRequest(serviceUrl), postData);
+      }
     }
 
   }
@@ -1908,6 +1932,21 @@
   ui->DecodeButton->setChecked (false);
 }
 
+bool MainWindow::gridChanged(QString deCall, QString grid)
+{
+	if (!gridOK(grid)) return false;
+	if (balloonData->contains(deCall)) {
+		// Any change from first grid report will report all subsequent decodes
+		if (balloonData->value(deCall) != grid) {
+			return true;
+		}
+	}
+	else {
+		balloonData->insert(deCall,grid);
+	}
+	return false;
+}
+
 void MainWindow::jt9_error (QProcess::ProcessError e)
 {
   if(!m_killAll) {
Index: mainwindow.h
===================================================================
--- mainwindow.h	(revision 6352)
+++ mainwindow.h	(working copy)
@@ -523,6 +523,8 @@
   MessageClient * m_messageClient;
   PSK_Reporter *psk_Reporter;
   DisplayManual m_manual;
+  QNetworkAccessManager *networkManager;
+  QHash<QString, QString> *balloonData;
 
   //---------------------------------------------------- private functions
   void readSettings();
@@ -559,6 +561,7 @@
   QString WSPR_hhmm(int n);
   void fast_config(bool b);
   void CQRxFreq();
+  bool gridChanged(QString deCall, QString grid);
 };
 
 extern void getfile(QString fname, int ntrperiod);
