kopia lustrzana https://gitlab.com/gridtracker.org/gridtracker
Merge branch 'sd-rotator-support' into 'master'
Rotator support See merge request gridtracker.org/gridtracker!244 If this is changing anything in the UI or operational behavior, please prepare to update the wiki!merge-requests/241/merge
commit
4deeacbbc3
|
@ -60,6 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<script src="./lib/shadow.js" type="text/javascript"></script>
|
||||
<script src="./lib/gtws.js" type="text/javascript"></script>
|
||||
<script src="./lib/pota.js" type="text/javascript"></script>
|
||||
<script src="./lib/services/pstrotator.js" type="text/javascript"></script>
|
||||
<script src="./lib/gt.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
|
@ -2073,9 +2074,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
</div>
|
||||
</div>
|
||||
<div id="logSettingsDiv" class="settingsTabcontent">
|
||||
<div id="LoadAdifOnStartupDiv"
|
||||
style="left: 0; padding: 1px; overflow: auto; overflow-x: hidden; display: inline-block; height: 602px"
|
||||
class="roundBorder">
|
||||
<table class="darkTable" align="center">
|
||||
<tr>
|
||||
<th data-i18n="settings.logging.tableheader.source">Source/Sync</th>
|
||||
|
@ -2438,7 +2436,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 data-i18n="settings.logging.other.title">Other Services</h2>
|
||||
<table class="darkTable" align="center">
|
||||
<tr>
|
||||
<th data-i18n="settings.logging.otherheader.service">Service</th>
|
||||
<th data-i18n="settings.logging.otherheader.active">Active?</th>
|
||||
<th data-i18n="settings.logging.otherheader.details">Details</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td data-i18n="settings.logging.pstrotator.label">CatRotator / PstRotator</td>
|
||||
<td>
|
||||
<input type="checkbox" checked="false" class="inputTextValue" id="pstrotatorCheckBox"
|
||||
onclick=" ValidateIPaddress(pstrotatorIpInput, this); ValidatePort(pstrotatorPortInput, this, null ); pstrotatorServiceChanged(); " />
|
||||
</td>
|
||||
<td>
|
||||
<label data-i18n="settings.logging.pstrotator.details.IP" for="pstrotastorIpInput">IP</label>
|
||||
<input id="pstrotatorIpInput" type="text" class="inputTextValue" maxlength="15" size="15"
|
||||
onkeypress='return validIpKeys(event.charCode);'
|
||||
oninput="ValidateIPaddress(this, pstrotatorCheckBox); pstrotatorServiceChanged(); " />
|
||||
<label data-i18n="settings.logging.pstrotator.details.Port" for="pstrotatorPortInput">UDP Port</label>
|
||||
<input id="pstrotatorPortInput" type="text" class="inputTextValue" maxlength="5" size="5" onkeypress='return
|
||||
validNumberKeys(event.charCode);' oninput="ValidatePort(this, pstrotatorCheckBox, null );
|
||||
pstrotatorServiceChanged(); " />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div id="callRosterDiv" class="settingsTabcontent">
|
||||
<div class="mapItem">
|
||||
|
@ -3154,4 +3178,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<div id="selectNodeDiv" style="-webkit-user-select: text; user-select: text; display: block; z-index: -10000"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -433,4 +433,4 @@
|
|||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -344,6 +344,13 @@
|
|||
"settings.logging.HRDLogbook.source": "HRD Logbook",
|
||||
"settings.logging.HRDLogbook.details.IP": "IP地址",
|
||||
"settings.logging.HRDLogbook.details.Port": "埠號",
|
||||
"settings.logging.other.title": "Other Services",
|
||||
"settings.logging.otherheader.service": "Service",
|
||||
"settings.logging.otherheader.active": "Active?",
|
||||
"settings.logging.otherheader.details": "Details",
|
||||
"settings.logging.pstrotator.label": "CatRotator / PstRotator",
|
||||
"settings.logging.pstrotator.details.IP": "IP",
|
||||
"settings.logging.pstrotator.details.Port": "UDP Port",
|
||||
"settings.callroster.AlwaysOnTop.label": "視窗始終在最上層",
|
||||
"settings.callroster.AlwaysOnTop.hover": "將呼叫清單置於其他視窗之上",
|
||||
"settings.callroster.MaxAge.label": "呼叫清單最大時效",
|
||||
|
@ -995,6 +1002,7 @@
|
|||
"roster.menu.RosterMode": "Roster Mode",
|
||||
"roster.menu.Lookup": "Lookup",
|
||||
"roster.menu.GenMesg": "Gen Msgs",
|
||||
"roster.menu.AimRotator": "Aim Rotator",
|
||||
"roster.menu.IgnoreCall": "Ignore Call",
|
||||
"roster.menu.Realtime": "Realtime",
|
||||
"roster.menu.MoveLeft": "Move Column Left",
|
||||
|
@ -1057,4 +1065,4 @@
|
|||
"COMMENT_sendAlerts.js": "",
|
||||
"sendAlerts.scriptEnabled": "Script Enabled",
|
||||
"sendAlerts.scriptDisabled": "Script Disabled"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,6 +344,13 @@
|
|||
"settings.logging.HRDLogbook.source": "HRD Logbook",
|
||||
"settings.logging.HRDLogbook.details.IP": "IP地址",
|
||||
"settings.logging.HRDLogbook.details.Port": "端口",
|
||||
"settings.logging.other.title": "Other Services",
|
||||
"settings.logging.otherheader.service": "Service",
|
||||
"settings.logging.otherheader.active": "Active?",
|
||||
"settings.logging.otherheader.details": "Details",
|
||||
"settings.logging.pstrotator.label": "CatRotator / PstRotator",
|
||||
"settings.logging.pstrotator.details.IP": "IP",
|
||||
"settings.logging.pstrotator.details.Port": "UDP Port",
|
||||
"settings.callroster.AlwaysOnTop.label": "窗口始终在最上层",
|
||||
"settings.callroster.AlwaysOnTop.hover": "将呼叫列表置于其他窗口之上",
|
||||
"settings.callroster.MaxAge.label": "呼叫列表最大时效",
|
||||
|
@ -995,6 +1002,7 @@
|
|||
"roster.menu.RosterMode": "Roster Mode",
|
||||
"roster.menu.Lookup": "Lookup",
|
||||
"roster.menu.GenMesg": "Gen Msgs",
|
||||
"roster.menu.AimRotator": "Aim Rotator",
|
||||
"roster.menu.IgnoreCall": "Ignore Call",
|
||||
"roster.menu.Realtime": "Realtime",
|
||||
"roster.menu.MoveLeft": "Move Column Left",
|
||||
|
@ -1057,4 +1065,4 @@
|
|||
"COMMENT_sendAlerts.js": "",
|
||||
"sendAlerts.scriptEnabled": "Script Enabled",
|
||||
"sendAlerts.scriptDisabled": "Script Disabled"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,6 +343,13 @@
|
|||
"settings.logging.HRDLogbook.source": "HRD Logbook",
|
||||
"settings.logging.HRDLogbook.details.IP": "IP",
|
||||
"settings.logging.HRDLogbook.details.Port": "Port",
|
||||
"settings.logging.other.title": "Other Services",
|
||||
"settings.logging.otherheader.service": "Service",
|
||||
"settings.logging.otherheader.active": "Active?",
|
||||
"settings.logging.otherheader.details": "Details",
|
||||
"settings.logging.pstrotator.label": "CatRotator / PstRotator",
|
||||
"settings.logging.pstrotator.details.IP": "IP",
|
||||
"settings.logging.pstrotator.details.Port": "UDP Port",
|
||||
"settings.callroster.AlwaysOnTop.label": "Window Always On Top",
|
||||
"settings.callroster.AlwaysOnTop.hover": "Keep Call Roster Above Other Windows",
|
||||
"settings.callroster.MaxAge.label": "Call Roster Max Age",
|
||||
|
@ -497,7 +504,7 @@
|
|||
"roster.controls.hunting.label": "Hunting",
|
||||
"roster.controls.hunting.callsign": "Callsign",
|
||||
"roster.controls.hunting.grid": "Grid",
|
||||
"roster.controls.hunting.dxcc": "DXCC",
|
||||
"roster.controls.hunting.dxcc": "DXCC",
|
||||
"roster.controls.hunting.dxccSingle": "DXCC (Single)",
|
||||
"roster.controls.hunting.cqZone": "CQ Zone",
|
||||
"roster.controls.hunting.ituZone": "ITU Zone",
|
||||
|
@ -544,7 +551,7 @@
|
|||
"roster.secondary.exceptions.usesOQRS": "Uses OQRS",
|
||||
"roster.secondary.exceptions.wantRRCQ": "RR73 as CQ",
|
||||
"roster.secondary.exceptions.allOnlyNew": "Only New Calls",
|
||||
"roster.secondary.exceptions.noMsg.label": "No",
|
||||
"roster.secondary.exceptions.noMsg.label": "No",
|
||||
"roster.secondary.exceptions.noMsg.hover": "No Decodes Containing...",
|
||||
"roster.secondary.exceptions.onlyMsg.label": "Only",
|
||||
"roster.secondary.exceptions.onlyMsg.hover": "Only Decodes Containing...",
|
||||
|
@ -995,6 +1002,7 @@
|
|||
"roster.menu.RosterMode": "Roster Mode",
|
||||
"roster.menu.Lookup": "Lookup",
|
||||
"roster.menu.GenMesg": "Gen Msgs",
|
||||
"roster.menu.AimRotator": "Aim Rotator",
|
||||
"roster.menu.IgnoreCall": "Ignore Call",
|
||||
"roster.menu.Realtime": "Realtime",
|
||||
"roster.menu.MoveLeft": "Move Column Left",
|
||||
|
@ -1058,4 +1066,4 @@
|
|||
"COMMENT_sendAlerts.js": "",
|
||||
"sendAlerts.scriptEnabled": "Script Enabled",
|
||||
"sendAlerts.scriptDisabled": "Script Disabled"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ var validSettings = [
|
|||
"startupLogs",
|
||||
"trustedQslSettings",
|
||||
"screenSettings",
|
||||
"legendColors"
|
||||
"legendColors",
|
||||
"pstrotatorSettings"
|
||||
];
|
||||
|
||||
var def_appSettings = {
|
||||
|
@ -234,7 +235,6 @@ var def_HRDLogbookLogSettings = {
|
|||
port: 7826,
|
||||
ip: "127.0.0.1"
|
||||
};
|
||||
|
||||
var def_acLogSettings = {
|
||||
enable: false,
|
||||
port: 1100,
|
||||
|
@ -277,3 +277,9 @@ var def_legendColors = {
|
|||
QRZ: "#FFFF00",
|
||||
QTH: "#FFA600"
|
||||
};
|
||||
|
||||
var def_pstrotatorSettings = {
|
||||
enable: false,
|
||||
port: 12000,
|
||||
ip: "127.0.0.1"
|
||||
};
|
||||
|
|
|
@ -144,6 +144,10 @@ function loadAllSettings()
|
|||
"HRDLogbookLogSettings",
|
||||
def_HRDLogbookLogSettings
|
||||
);
|
||||
g_pstrotatorSettings = loadDefaultsAndMerge(
|
||||
"pstrotatorSettings",
|
||||
def_pstrotatorSettings
|
||||
);
|
||||
g_acLogSettings = loadDefaultsAndMerge("acLogSettings", def_acLogSettings);
|
||||
g_trustedQslSettings = loadDefaultsAndMerge(
|
||||
"trustedQslSettings",
|
||||
|
@ -262,6 +266,7 @@ function saveLogSettings()
|
|||
localStorage.log4OMSettings = JSON.stringify(g_log4OMSettings);
|
||||
localStorage.dxkLogSettings = JSON.stringify(g_dxkLogSettings);
|
||||
localStorage.HRDLogbookLogSettings = JSON.stringify(g_HRDLogbookLogSettings);
|
||||
localStorage.pstrotatorSettings = JSON.stringify(g_pstrotatorSettings);
|
||||
localStorage.acLogSettings = JSON.stringify(g_acLogSettings);
|
||||
localStorage.trustedQslSettings = JSON.stringify(g_trustedQslSettings);
|
||||
}
|
||||
|
@ -1077,7 +1082,7 @@ function addDeDx(
|
|||
var qsoDate = new Date(1970, 0, 1); qsoDate.setSeconds(finalTime);
|
||||
var isCurrentYear = (qsoDate.getFullYear() == currentYear);
|
||||
var dayAsString = String(parseInt(finalTime / 86400));
|
||||
|
||||
|
||||
var callsign = null;
|
||||
var rect = null;
|
||||
var worked = false;
|
||||
|
@ -1349,7 +1354,7 @@ function addDeDx(
|
|||
g_tracker.worked.pota[dayAsString + finalDXcall + finalPOTA + band + "ph"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
worked = true;
|
||||
locked = true;
|
||||
details.worked = worked;
|
||||
|
@ -5531,7 +5536,7 @@ function initMap()
|
|||
{
|
||||
var saveSettings = false;
|
||||
g_maps = Object.keys(g_maps).sort().reduce((obj, key) => { obj[key] = g_maps[key]; return obj; }, {});
|
||||
|
||||
|
||||
if (!(g_mapSettings.mapIndex in g_maps))
|
||||
{
|
||||
g_mapSettings.mapIndex = def_mapSettings.mapIndex;
|
||||
|
@ -5745,7 +5750,7 @@ function initMap()
|
|||
noFeature = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (features[index].size == 6)
|
||||
{
|
||||
noFeature = false;
|
||||
|
@ -10627,7 +10632,7 @@ function redrawGrids()
|
|||
~~g_cqZones[cqz].confirmed_modes[mode] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ituz && ituz.length > 0)
|
||||
{
|
||||
if (g_ituZones[ituz].worked == false)
|
||||
|
@ -10653,7 +10658,7 @@ function redrawGrids()
|
|||
~~g_ituZones[ituz].confirmed_modes[mode] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (finalGrid.length > 0)
|
||||
{
|
||||
var gridCheck = finalGrid.substr(0, 4);
|
||||
|
@ -12289,7 +12294,7 @@ function toggleTimezones()
|
|||
g_timezoneLayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
timezoneImg.style.filter = g_timezonesEnable == 1 ? "" : "grayscale(1)";
|
||||
}
|
||||
|
||||
|
@ -12735,7 +12740,7 @@ function loadMapSettings()
|
|||
rosterDelayOnFocus.checked = g_appSettings.rosterDelayOnFocus;
|
||||
rosterDelayTime.value = g_appSettings.rosterDelayTime;
|
||||
rosterDelayTimeTd.innerHTML = rosterDelayTime.value + "ms";
|
||||
|
||||
|
||||
setStrikesButton();
|
||||
|
||||
trafficDecode.checked = g_mapSettings.trafficDecode;
|
||||
|
@ -13200,6 +13205,12 @@ function loadViewSettings()
|
|||
ValidatePort(hrdLogbookPortInput, buttonHrdLogbookCheckBox, null);
|
||||
ValidateIPaddress(hrdLogbookIpInput, buttonHrdLogbookCheckBox, null);
|
||||
|
||||
pstrotatorIpInput.value = g_pstrotatorSettings.ip;
|
||||
pstrotatorPortInput.value = g_pstrotatorSettings.port;
|
||||
pstrotatorCheckBox.checked = g_pstrotatorSettings.enable;
|
||||
ValidatePort(pstrotatorPortInput, pstrotatorCheckBox, null);
|
||||
ValidateIPaddress(pstrotatorIpInput, pstrotatorCheckBox, null);
|
||||
|
||||
spotHistoryTimeValue.value = parseInt(
|
||||
g_receptionSettings.viewHistoryTimeSec / 60
|
||||
);
|
||||
|
@ -13506,7 +13517,7 @@ function postInit()
|
|||
openCallRosterWindow(false);
|
||||
openConditionsWindow(false);
|
||||
showMessaging(false);
|
||||
|
||||
|
||||
if (g_developerMode)
|
||||
{
|
||||
devPanel.style.display = "inline-block";
|
||||
|
@ -15719,7 +15730,7 @@ function mediaCheck()
|
|||
g_tracker.worked.px = {};
|
||||
g_tracker.confirmed.px = {};
|
||||
}
|
||||
|
||||
|
||||
if (typeof g_tracker.worked.pota == "undefined")
|
||||
{
|
||||
g_tracker.worked.pota = {};
|
||||
|
@ -15741,12 +15752,12 @@ function mediaCheck()
|
|||
g_QSOhash[i].px = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (typeof g_QSOhash[i].pota == "undefined" || g_QSOhash[i].pota == null)
|
||||
{
|
||||
g_QSOhash[i].pota = [];
|
||||
}
|
||||
|
||||
|
||||
g_QSOcount++;
|
||||
if (g_QSOhash[i].confirmed) g_QSLcount++;
|
||||
}
|
||||
|
|
|
@ -1725,13 +1725,28 @@ function addControls()
|
|||
callGenMessage(g_targetHash, "");
|
||||
}
|
||||
});
|
||||
|
||||
g_callMenu.append(item);
|
||||
|
||||
item = new nw.MenuItem({ type: "separator" });
|
||||
|
||||
g_callMenu.append(item);
|
||||
|
||||
if (window.opener.g_pstrotatorSettings.enable)
|
||||
{
|
||||
item = new nw.MenuItem({
|
||||
type: "normal",
|
||||
label: $.i18n("roster.menu.AimRotator"),
|
||||
click: function ()
|
||||
{
|
||||
let target = callRoster[g_targetHash]
|
||||
window.opener.aimRotator(target, "");
|
||||
}
|
||||
});
|
||||
g_callMenu.append(item);
|
||||
|
||||
item = new nw.MenuItem({ type: "separator" });
|
||||
g_callMenu.append(item);
|
||||
}
|
||||
|
||||
item = new nw.MenuItem({
|
||||
type: "normal",
|
||||
label: $.i18n("roster.menu.IgnoreCall"),
|
||||
|
@ -1747,7 +1762,6 @@ function addControls()
|
|||
g_callMenu.append(item);
|
||||
|
||||
g_callingMenu = new nw.Menu();
|
||||
|
||||
item = new nw.MenuItem({
|
||||
type: "normal",
|
||||
label: $.i18n("roster.menu.Lookup"),
|
||||
|
@ -1773,6 +1787,23 @@ function addControls()
|
|||
item = new nw.MenuItem({ type: "separator" });
|
||||
g_menu.append(item);
|
||||
|
||||
if (window.opener.g_pstrotatorSettings.enable)
|
||||
{
|
||||
item = new nw.MenuItem({
|
||||
type: "normal",
|
||||
label: $.i18n("roster.menu.AimRotator"),
|
||||
click: function ()
|
||||
{
|
||||
let target = callRoster[g_targetHash]
|
||||
window.opener.aimRotator(target, "");
|
||||
}
|
||||
});
|
||||
g_callingMenu.append(item);
|
||||
|
||||
item = new nw.MenuItem({ type: "separator" });
|
||||
g_callingMenu.append(item);
|
||||
}
|
||||
|
||||
item = new nw.MenuItem({
|
||||
type: "checkbox",
|
||||
label: $.i18n("roster.menu.Realtime"),
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* PSTRotator is a third party application (windows-only) that interfaces with dozens of antenna rotators.
|
||||
* It offers a way for other apps to request rotation to a specific azimuth, or a grid square.
|
||||
*
|
||||
* Other rotator control apps, like [CatRotator](https://www.pianetaradio.it/blog/catrotator/) also support this API.
|
||||
*
|
||||
* The most comprehensive API details are in this Groups.io post:
|
||||
* https://groups.io/g/PstRotator/message/5825
|
||||
*
|
||||
*/
|
||||
var g_pstrotatorSettings = {};
|
||||
|
||||
function pstrotatorServiceChanged()
|
||||
{
|
||||
if (g_pstrotatorSettings.enabled != pstrotatorCheckBox.checked)
|
||||
{
|
||||
// This setting toggles the presence of a contextual menu item in the roster,
|
||||
// which is constructed only during roster initialization.
|
||||
//
|
||||
// So when this setting is changed, we need to reload the entire roster window.
|
||||
//
|
||||
g_pstrotatorSettings.enable = pstrotatorCheckBox.checked;
|
||||
if (g_rosterInitialized)
|
||||
{
|
||||
try
|
||||
{
|
||||
g_callRosterWindowHandle.window.location.reload();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_pstrotatorSettings.ip = pstrotatorIpInput.value;
|
||||
g_pstrotatorSettings.port = pstrotatorPortInput.value;
|
||||
|
||||
saveLogSettings();
|
||||
}
|
||||
|
||||
function aimRotator(info)
|
||||
{
|
||||
const { callObj } = info
|
||||
|
||||
if (
|
||||
g_pstrotatorSettings.enable == true &&
|
||||
g_pstrotatorSettings.port > 0 &&
|
||||
g_pstrotatorSettings.ip.length > 4 &&
|
||||
(callObj.distance > 0 || callObj.grid)
|
||||
)
|
||||
{
|
||||
let payload = "<PST>"
|
||||
|
||||
if (callObj.distance > 0)
|
||||
{
|
||||
payload += `<AZIMUTH>${Math.round(callObj.heading)}</AZIMUTH>`
|
||||
}
|
||||
|
||||
if (callObj.grid)
|
||||
{
|
||||
payload += `<QRA>${callObj.grid}</QRA>`
|
||||
}
|
||||
|
||||
payload += "</PST>"
|
||||
|
||||
try
|
||||
{
|
||||
sendUdpMessage(
|
||||
payload,
|
||||
payload.length,
|
||||
parseInt(g_pstrotatorSettings.port),
|
||||
g_pstrotatorSettings.ip
|
||||
);
|
||||
addLastTraffic(`<font style='color:white'>Aiming rotator towards ${data.DEcall}</font>`);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
addLastTraffic("<font style='color:red'>UDP aimRotator failed</font>");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -619,7 +619,8 @@ a {
|
|||
margin: 0;
|
||||
display: none;
|
||||
background-color: black;
|
||||
padding: 2px;
|
||||
padding: 6px;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
border: 1px solid blue;
|
||||
|
@ -627,7 +628,8 @@ a {
|
|||
vertical-align: top;
|
||||
-webkit-border-radius: 6px;
|
||||
white-space: normal;
|
||||
|
||||
max-height: 600px;
|
||||
overflow: auto;
|
||||
/* animation: fadeEffect .3s; Fading effect takes 1 second */
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue