Remove distinction between DV modes and LSB/USB

This commit is contained in:
Ian Renton
2026-08-31 11:17:05 +01:00
parent 8345238d76
commit 12e9b6a4ca
15 changed files with 41 additions and 49 deletions
+8 -10
View File
@@ -182,16 +182,9 @@ CW_MODES = ["CW"]
PHONE_MODES = [ PHONE_MODES = [
"PHONE", "PHONE",
"SSB", "SSB",
"USB",
"LSB",
"AM", "AM",
"FM", "FM",
"DV", "DV"
"DMR",
"DSTAR",
"C4FM",
"FUSION",
"M17",
] ]
DATA_MODES = [ DATA_MODES = [
"DATA", "DATA",
@@ -209,14 +202,19 @@ DATA_MODES = [
] ]
ALL_MODES = CW_MODES + PHONE_MODES + DATA_MODES ALL_MODES = CW_MODES + PHONE_MODES + DATA_MODES
MODE_TYPES = ["CW", "PHONE", "DATA"] MODE_TYPES = ["CW", "PHONE", "DATA"]
SSB_SUB_MODES = ["USB", "LSB"]
DV_SUB_MODES = ["DMR", "DSTAR", "C4FM", "FUSION", "M17"]
# Mode aliases. Sometimes we get spots with a mode described in a different way that is effectively the same as a mode # Mode aliases. Sometimes we get spots with a mode described in a different way that is effectively the same as a mode
# we already know, or we want to normalise things for consistency. The lookup table for this is here. Incoming spots # we already know, or we want to normalise things for consistency. The lookup table for this is here. Incoming spots
# that match a key in this table will be converted to the corresponding value, so only the modes above will actually be # that match a key in this table will be converted to the corresponding value, so only the modes above will actually be
# present in the spots. # present in the spots.
MODE_ALIASES = { MODE_ALIASES = {
"USB": "SSB",
"LSB": "SSB",
"DMR": "DV",
"DSTAR": "DV",
"C4FM": "DV",
"FUSION": "DV",
"M17": "DV",
"RTT": "RTTY", "RTT": "RTTY",
"BPSK": "PSK", "BPSK": "PSK",
"PSK31": "PSK", "PSK31": "PSK",
+1 -1
View File
@@ -70,7 +70,7 @@ def infer_mode_from_frequency(freq):
mode = freq_to_band(khz)["mode"] mode = freq_to_band(khz)["mode"]
# Some additional common digimode ranges in addition to what the 3rd-party freq_to_band function returns. # Some additional common digimode ranges in addition to what the 3rd-party freq_to_band function returns.
# This is mostly here just because freq_to_band is very specific about things like FT8 frequencies, and e.g. # This is mostly here just because freq_to_band is very specific about things like FT8 frequencies, and e.g.
# a spot at 7074.5 kHz will be indicated as LSB, even though it's clearly in the FT8 range. Future updates # a spot at 7074.5 kHz will be indicated as SSB, even though it's clearly in the FT8 range. Future updates
# might include other common digimode centres of activity here, but this achieves the main goal of keeping # might include other common digimode centres of activity here, but this achieves the main goal of keeping
# large numbers of clearly-FT* spots off the list of people filtering out digimodes. # large numbers of clearly-FT* spots off the list of people filtering out digimodes.
if ( if (
+2 -7
View File
@@ -4,7 +4,7 @@ from datetime import datetime
import requests import requests
from requests.exceptions import ConnectionError, ConnectTimeout, ReadTimeout from requests.exceptions import ConnectionError, ConnectTimeout, ReadTimeout
from core.constants import DV_SUB_MODES, HTTP_HEADERS, SSB_SUB_MODES from core.constants import HTTP_HEADERS
from data.sig_ref import SIGRef from data.sig_ref import SIGRef
from data.spot import Spot from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider from providers.spot.http_spot_provider import HTTPSpotProvider
@@ -98,12 +98,7 @@ class SOTA(HTTPSpotProvider):
# https://github.com/ham2k/app-polo/blob/main/src/extensions/activities/sota/SOTAPostSelfSpot.js # https://github.com/ham2k/app-polo/blob/main/src/extensions/activities/sota/SOTAPostSelfSpot.js
mode = spot.mode mode = spot.mode
if mode and mode not in self.VALID_MODES: if mode and mode not in self.VALID_MODES:
if mode in SSB_SUB_MODES: mode = "Data"
mode = "SSB"
elif mode in DV_SUB_MODES:
mode = "DV"
else:
mode = "Data"
body = { body = {
"activatorCallsign": spot.dx_call, "activatorCallsign": spot.dx_call,
+2 -4
View File
@@ -3,7 +3,7 @@ from datetime import datetime
import requests import requests
from core.constants import HTTP_HEADERS, SSB_SUB_MODES from core.constants import HTTP_HEADERS
from data.sig_ref import SIGRef from data.sig_ref import SIGRef
from data.spot import Spot from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider from providers.spot.http_spot_provider import HTTPSpotProvider
@@ -92,9 +92,7 @@ class Tiles(HTTPSpotProvider):
if spot.mode: if spot.mode:
mode = spot.mode mode = spot.mode
if mode not in self.VALID_MODES: if mode not in self.VALID_MODES:
if mode in SSB_SUB_MODES: if mode == "OLIVIA":
mode = "SSB"
elif mode == "OLIVIA":
mode = "Olivia" mode = "Olivia"
elif mode == "JS8": elif mode == "JS8":
mode = "JS8Call" mode = "JS8Call"
+7 -7
View File
@@ -15,6 +15,11 @@ info:
## Changelog ## Changelog
### 2.1
* Added DTMBA, FEA and BIWOTA SIGs
* Removed the distinction between LSB & USB (both will now show as SSB) and between the various digital voice modes, which will now show as DV.
### 2.0 ### 2.0
* **Breaking change:** The "add spot" API has changed to enable future support for upstream submission to the spotting services associated with various SIGs. Instead of just posting the spot object itself as the JSON content of the POST, this has moved into a `spot` object within the structure. A new `handling` object alongside it contains the `submit_upstream`, `upstream_provider`, `upstream_credentials`, and `captcha_token` fields which control the server handling of the spot. * **Breaking change:** The "add spot" API has changed to enable future support for upstream submission to the spotting services associated with various SIGs. Instead of just posting the spot object itself as the JSON content of the POST, this has moved into a `spot` object within the structure. A new `handling` object alongside it contains the `submit_upstream`, `upstream_provider`, `upstream_credentials`, and `captcha_token` fields which control the server handling of the spot.
@@ -854,6 +859,7 @@ components:
- DME - DME
- FEA - FEA
- DTMBA - DTMBA
- BIWOTA
- Toilets - Toilets
example: POTA example: POTA
@@ -913,15 +919,9 @@ components:
- CW - CW
- PHONE - PHONE
- SSB - SSB
- USB
- LSB
- AM - AM
- FM - FM
- DV - DV
- DMR
- DSTAR
- C4FM
- M17
- DATA - DATA
- FT8 - FT8
- FT4 - FT4
@@ -2032,7 +2032,7 @@ components:
description: An array of all the supported modes. description: An array of all the supported modes.
items: items:
type: string type: string
example: "LSB" example: "SSB"
mode_types: mode_types:
type: array type: array
description: An array of all the supported mode types. description: An array of all the supported mode types.
+1 -1
View File
@@ -64,7 +64,7 @@ function generateModesMultiToggleFilterCard(mode_options) {
// Set the mode toggles that relate to Analog Voice. // Set the mode toggles that relate to Analog Voice.
function setVoiceModeToggles() { function setVoiceModeToggles() {
const modes = ["PHONE", "SSB", "LSB", "USB", "AM", "FM", "DV", "DMR", "DSTAR", "C4FM", "M17"]; const modes = ["PHONE", "SSB", "AM", "FM", "DV"];
$(".filter-button-mode").each(function () { $(".filter-button-mode").each(function () {
$(this).prop('checked', modes.includes($(this).val().replace("filter-button-mode-", ""))); $(this).prop('checked', modes.includes($(this).val().replace("filter-button-mode-", "")));
}); });
+5 -4
View File
@@ -103,10 +103,11 @@
Parks Award (KRMNPA), South Australia National Parks and Conservation Parks Award (SANPCPA), Wainwrights on the Parks Award (KRMNPA), South Australia National Parks and Conservation Parks Award (SANPCPA), Wainwrights on the
Air (WOTA), Beaches on the Air (BOTA), Lagos y Lagunas On the Air (LLOTA), Towers on the Air, Tiles on Air (WOTA), Beaches on the Air (BOTA), Lagos y Lagunas On the Air (LLOTA), Towers on the Air, Tiles on
the Air, Worked All Britain (WAB), Worked All Ireland (WAI), el Diploma Municipios de España (DME), el Diploma the Air, Worked All Britain (WAB), Worked All Ireland (WAI), el Diploma Municipios de España (DME), el Diploma
Faros de España (FEA), il Diploma Teatri Musei e Belle Arti (DTMBA) and Toilets on the Air.</p> Faros de España (FEA), il Diploma Teatri Musei e Belle Arti (DTMBA), British Inland Waterways on the Air
<p>As of the time of writing in June 2026, I think Spothole captures essentially all outdoor radio programmes (BIWOTA) and Toilets on the Air.</p>
that have a defined reference list, and almost certainly those that have a spotting/alerting API. If you know of <p>As of the time of writing in August 2026, I think Spothole captures most outdoor radio programmes that have a
one I've missed, please let me know!</p> defined, downloadable reference list, and almost certainly those that have a spotting/alerting API. If you know
of one I've missed, please let me know!</p>
<h4 class="mt-4">Why can I filter spots by both SIG and Source? Isn't that basically the same thing?</h4> <h4 class="mt-4">Why can I filter spots by both SIG and Source? Isn't that basically the same thing?</h4>
<p>Mostly, but not quite. While POTA spots generally come from the POTA source and so on, there are a few <p>Mostly, but not quite. While POTA spots generally come from the POTA source and so on, there are a few
exceptions:</p> exceptions:</p>
+1 -1
View File
@@ -76,7 +76,7 @@
</div> </div>
<script src="/static/js/add-spot.js?v=1788170754"></script> <script src="/static/js/add-spot.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-add-spot").addClass("active"); $("#nav-link-add-spot").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+1 -1
View File
@@ -84,7 +84,7 @@
</div> </div>
<script src="/static/js/alerts.js?v=1788170753"></script> <script src="/static/js/alerts.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-alerts").addClass("active"); $("#nav-link-alerts").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -76,8 +76,8 @@
</div> </div>
<script src="/static/js/spotsbandsandmap.js?v=1788170754"></script> <script src="/static/js/spotsbandsandmap.js?v=1788171425"></script>
<script src="/static/js/bands.js?v=1788170754"></script> <script src="/static/js/bands.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-bands").addClass("active"); $("#nav-link-bands").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+5 -5
View File
@@ -1,6 +1,6 @@
{% extends "skeleton.html" %} {% extends "skeleton.html" %}
{% block head_extra %} {% block head_extra %}
<link rel="stylesheet" href="/static/css/style.css?v=1788170753" type="text/css"> <link rel="stylesheet" href="/static/css/style.css?v=1788171425" type="text/css">
<link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet"> <link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
<link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet"> <link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
<link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet"> <link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
@@ -15,10 +15,10 @@
window.fetchEventSource = fetchEventSource; window.fetchEventSource = fetchEventSource;
</script> </script>
<script src="/static/js/utils.js?v=1788170753"></script> <script src="/static/js/utils.js?v=1788171425"></script>
<script src="/static/js/ui-ham.js?v=1788170753"></script> <script src="/static/js/ui-ham.js?v=1788171425"></script>
<script src="/static/js/geo.js?v=1788170753"></script> <script src="/static/js/geo.js?v=1788171425"></script>
<script src="/static/js/common.js?v=1788170753"></script> <script src="/static/js/common.js?v=1788171425"></script>
{% end %} {% end %}
{% block body %} {% block body %}
<div class="container"> <div class="container">
+1 -1
View File
@@ -284,7 +284,7 @@
</div> </div>
<script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script> <script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script>
<script src="/static/js/conditions.js?v=1788170753"></script> <script src="/static/js/conditions.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-conditions").addClass("active"); $("#nav-link-conditions").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -113,8 +113,8 @@
const CARTODB_API_KEY = "{{ web_ui_options.get('cartodb_api_key', '') }}"; const CARTODB_API_KEY = "{{ web_ui_options.get('cartodb_api_key', '') }}";
</script> </script>
<script src="/static/js/spotsbandsandmap.js?v=1788170753"></script> <script src="/static/js/spotsbandsandmap.js?v=1788171425"></script>
<script src="/static/js/map.js?v=1788170753"></script> <script src="/static/js/map.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-map").addClass("active"); $("#nav-link-map").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -113,8 +113,8 @@
</div> </div>
<script src="/static/js/spotsbandsandmap.js?v=1788170753"></script> <script src="/static/js/spotsbandsandmap.js?v=1788171425"></script>
<script src="/static/js/spots.js?v=1788170753"></script> <script src="/static/js/spots.js?v=1788171425"></script>
<script>$(document).ready(function () { <script>$(document).ready(function () {
$("#nav-link-spots").addClass("active"); $("#nav-link-spots").addClass("active");
}); <!-- highlight active page in nav --></script> }); <!-- highlight active page in nav --></script>
+1 -1
View File
@@ -86,7 +86,7 @@
</div> </div>
</div> </div>
<script src="/static/js/status.js?v=1788170754"></script> <script src="/static/js/status.js?v=1788171425"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$("#nav-link-status").addClass("active"); $("#nav-link-status").addClass("active");