mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 19:12:23 +00:00
Use stock-compatible radio test exit
This commit is contained in:
1 parent
d61b287ddc
commit
2cd9a9dbae
4 files changed
+132
-7
No files matched your search
@@ -9,6 +9,10 @@
|
||||
bw: "500",
|
||||
sf: "8",
|
||||
cr: "7",
|
||||
normalfreq: "910.525",
|
||||
normalbw: "62.5",
|
||||
normalsf: "7",
|
||||
normalcr: "5",
|
||||
tx: "22",
|
||||
});
|
||||
const VALID_BANDWIDTHS = Object.freeze([
|
||||
@@ -108,6 +112,10 @@
|
||||
const bw = strictNumber(raw.bw, "bw");
|
||||
const sf = strictInteger(raw.sf, "sf");
|
||||
const cr = strictInteger(raw.cr, "cr");
|
||||
const normalFreq = strictNumber(raw.normalfreq, "normalfreq");
|
||||
const normalBw = strictNumber(raw.normalbw, "normalbw");
|
||||
const normalSf = strictInteger(raw.normalsf, "normalsf");
|
||||
const normalCr = strictInteger(raw.normalcr, "normalcr");
|
||||
const tx = strictSignedNumber(raw.tx, "tx");
|
||||
|
||||
if (endMs <= startMs) {
|
||||
@@ -129,6 +137,22 @@
|
||||
if (cr < 5 || cr > 8) {
|
||||
throw new PresetTestError("cr must be between 5 and 8");
|
||||
}
|
||||
if (normalFreq < 150 || normalFreq > 2500) {
|
||||
throw new PresetTestError("normalfreq must be between 150 and 2500 MHz");
|
||||
}
|
||||
if (!VALID_BANDWIDTHS.some(function (allowed) {
|
||||
return Math.abs(allowed - normalBw) < 0.01;
|
||||
})) {
|
||||
throw new PresetTestError(
|
||||
"normalbw must be one of " + VALID_BANDWIDTHS.join(", ") + " kHz"
|
||||
);
|
||||
}
|
||||
if (normalSf < 5 || normalSf > 12) {
|
||||
throw new PresetTestError("normalsf must be between 5 and 12");
|
||||
}
|
||||
if (normalCr < 5 || normalCr > 8) {
|
||||
throw new PresetTestError("normalcr must be between 5 and 8");
|
||||
}
|
||||
if (tx < -30 || tx > 60) {
|
||||
throw new PresetTestError("tx must be between -30 and 60 dBm");
|
||||
}
|
||||
@@ -143,9 +167,15 @@
|
||||
bw: bw,
|
||||
sf: sf,
|
||||
cr: cr,
|
||||
normalFreq: normalFreq,
|
||||
normalBw: normalBw,
|
||||
normalSf: normalSf,
|
||||
normalCr: normalCr,
|
||||
tx: tx,
|
||||
freqText: numberText(freq),
|
||||
bwText: numberText(bw),
|
||||
normalFreqText: numberText(normalFreq),
|
||||
normalBwText: numberText(normalBw),
|
||||
txText: numberText(tx),
|
||||
});
|
||||
}
|
||||
@@ -179,6 +209,9 @@
|
||||
|
||||
function commandsFor(config, nowMs) {
|
||||
const tuple = [config.freqText, config.bwText, config.sf, config.cr].join(",");
|
||||
const normalTuple = [
|
||||
config.normalFreqText, config.normalBwText, config.normalSf, config.normalCr,
|
||||
].join(",");
|
||||
const minutes = remainingMinutes(config, nowMs);
|
||||
return Object.freeze({
|
||||
stockNow: "tempradio " + tuple + "," + minutes,
|
||||
@@ -191,7 +224,7 @@
|
||||
"set radio2.cross on\nset tempradioat2 " + tuple + ",rxtx," +
|
||||
config.startEpoch + "," + config.endEpoch + "\nget tempradioat2",
|
||||
stockCancelBefore: "get tempradioat\ndel tempradioat all",
|
||||
stockCancelDuring: "normalradio",
|
||||
stockCancelDuring: "tempradio " + normalTuple + ",1",
|
||||
stockLeaveIn30: "tempradio " + tuple + ",30",
|
||||
companionCancelBefore:
|
||||
"get tempradioat2\ndel tempradioat2 all\nset radio2.cross auto",
|
||||
@@ -369,6 +402,10 @@
|
||||
params.set("bw", values.bw);
|
||||
params.set("sf", values.sf);
|
||||
params.set("cr", values.cr);
|
||||
params.set("normalfreq", values.normalfreq);
|
||||
params.set("normalbw", values.normalbw);
|
||||
params.set("normalsf", values.normalsf);
|
||||
params.set("normalcr", values.normalcr);
|
||||
params.set("tx", values.tx);
|
||||
return configFromSearch("?" + params.toString());
|
||||
}
|
||||
@@ -397,6 +434,10 @@
|
||||
url.searchParams.set("bw", config.bwText);
|
||||
url.searchParams.set("sf", String(config.sf));
|
||||
url.searchParams.set("cr", String(config.cr));
|
||||
url.searchParams.set("normalfreq", config.normalFreqText);
|
||||
url.searchParams.set("normalbw", config.normalBwText);
|
||||
url.searchParams.set("normalsf", String(config.normalSf));
|
||||
url.searchParams.set("normalcr", String(config.normalCr));
|
||||
url.searchParams.set("tx", config.txText);
|
||||
return url.toString();
|
||||
}
|
||||
@@ -472,6 +513,11 @@
|
||||
setText(root, '[data-field="bw-display"]', config.bwText);
|
||||
setText(root, '[data-field="sf"]', String(config.sf));
|
||||
setText(root, '[data-field="cr"]', String(config.cr));
|
||||
setText(
|
||||
root,
|
||||
'[data-field="normal-profile"]',
|
||||
[config.normalFreqText, config.normalBwText, config.normalSf, config.normalCr].join(",")
|
||||
);
|
||||
setText(root, '[data-role="start-zoned"]', formatZoned(config.startMs, config.tz));
|
||||
setText(root, '[data-role="end-zoned"]', formatZoned(config.endMs, config.tz));
|
||||
setText(root, '[data-role="display-zone"]', config.tz);
|
||||
@@ -507,6 +553,10 @@
|
||||
generator.elements.bw.value = config.bwText;
|
||||
generator.elements.sf.value = String(config.sf);
|
||||
generator.elements.cr.value = String(config.cr);
|
||||
generator.elements.normalfreq.value = config.normalFreqText;
|
||||
generator.elements.normalbw.value = config.normalBwText;
|
||||
generator.elements.normalsf.value = String(config.normalSf);
|
||||
generator.elements.normalcr.value = String(config.normalCr);
|
||||
generator.elements.tx.value = config.txText;
|
||||
|
||||
const zoneList = root.querySelector("#preset-test-time-zones");
|
||||
@@ -531,6 +581,10 @@
|
||||
bw: generator.elements.bw.value,
|
||||
sf: generator.elements.sf.value,
|
||||
cr: generator.elements.cr.value,
|
||||
normalfreq: generator.elements.normalfreq.value,
|
||||
normalbw: generator.elements.normalbw.value,
|
||||
normalsf: generator.elements.normalsf.value,
|
||||
normalcr: generator.elements.normalcr.value,
|
||||
tx: generator.elements.tx.value,
|
||||
});
|
||||
const url = configuredUrl(
|
||||
|
||||
@@ -278,6 +278,17 @@
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.preset-test-generator-subheading {
|
||||
grid-column: 1 / -1;
|
||||
border-bottom: 1px solid var(--preset-border);
|
||||
padding: 0.3rem 0 0.35rem;
|
||||
color: var(--preset-cyan);
|
||||
font-size: 0.74rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.preset-test-generator input,
|
||||
.preset-test-generator select {
|
||||
box-sizing: border-box;
|
||||
|
||||
+38
-6
@@ -47,7 +47,8 @@ tuple; no source edit is required.
|
||||
<p>
|
||||
The test will include bridges. If the Puget Sound area experiences a
|
||||
widespread power outage or loss of cellular service, we will end the
|
||||
test early and revert to the normal 910.525 MHz channel.
|
||||
test early and revert to the normal
|
||||
<code data-field="normal-profile">910.525,62.5,7,5</code> profile.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -212,12 +213,14 @@ clock</code></pre>
|
||||
|
||||
<article class="preset-test-card">
|
||||
<h3>Stock · while it is running</h3>
|
||||
<h4>Leave now</h4>
|
||||
<h4>Leave now · stock compatible</h4>
|
||||
<pre><code data-command="stock-cancel-during"></code></pre>
|
||||
<button type="button" data-copy-command="stock-cancel-during">Copy restore command</button>
|
||||
<button type="button" data-copy-command="stock-cancel-during">Copy stock leave command</button>
|
||||
<p class="preset-test-note">
|
||||
<code>normalradio</code> cancels pending and active primary TempRadio
|
||||
windows and restores the saved primary tuple after its reply drains.
|
||||
Stock MeshCore has no <code>normalradio</code> command. This starts a
|
||||
one-minute temporary session on the normal return profile without
|
||||
saving over the node's configuration. When that minute ends, the
|
||||
node restores its saved radio settings.
|
||||
</p>
|
||||
<h4>Leave in 30 minutes</h4>
|
||||
<pre><code data-command="stock-leave-30"></code></pre>
|
||||
@@ -283,6 +286,7 @@ clock</code></pre>
|
||||
autocomplete="off" spellcheck="false">
|
||||
<small>Use an IANA name such as America/Los_Angeles or UTC.</small>
|
||||
</label>
|
||||
<div class="preset-test-generator-subheading">Test radio profile</div>
|
||||
<label>
|
||||
<span>Frequency (MHz)</span>
|
||||
<input type="number" name="freq" min="150" max="2500" step="0.001" required>
|
||||
@@ -313,6 +317,32 @@ clock</code></pre>
|
||||
<input type="number" name="tx" min="-30" max="60" step="0.1" required>
|
||||
<small>This estimate-only value does not change the TempRadio commands.</small>
|
||||
</label>
|
||||
<div class="preset-test-generator-subheading">Normal return profile</div>
|
||||
<label>
|
||||
<span>Normal frequency (MHz)</span>
|
||||
<input type="number" name="normalfreq" min="150" max="2500" step="0.001" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Normal bandwidth (kHz)</span>
|
||||
<select name="normalbw" required>
|
||||
<option>7.8</option><option>10.4</option><option>15.6</option>
|
||||
<option>20.8</option><option>31.25</option><option>41.7</option>
|
||||
<option>62.5</option><option>125</option><option>250</option><option>500</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Normal spreading factor</span>
|
||||
<select name="normalsf" required>
|
||||
<option>5</option><option>6</option><option>7</option><option>8</option>
|
||||
<option>9</option><option>10</option><option>11</option><option>12</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Normal coding-rate denominator</span>
|
||||
<select name="normalcr" required>
|
||||
<option>5</option><option>6</option><option>7</option><option>8</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit">Generate test URL</button>
|
||||
</form>
|
||||
@@ -361,7 +391,9 @@ clock</code></pre>
|
||||
Advanced use: <code>start</code> and <code>end</code> also accept ISO-8601
|
||||
timestamps with explicit UTC offsets or Unix epoch seconds. The other URL
|
||||
parameters are <code>tz</code>, <code>freq</code>, <code>bw</code>,
|
||||
<code>sf</code>, <code>cr</code>, and estimate-only <code>tx</code>.
|
||||
<code>sf</code>, <code>cr</code>, <code>normalfreq</code>,
|
||||
<code>normalbw</code>, <code>normalsf</code>, <code>normalcr</code>, and
|
||||
estimate-only <code>tx</code>.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -18,6 +18,10 @@ assert.strictEqual(config.sf, 8);
|
||||
assert.strictEqual(config.cr, 7);
|
||||
assert.strictEqual(config.tz, "America/Los_Angeles");
|
||||
assert.strictEqual(config.tx, 22);
|
||||
assert.strictEqual(config.normalFreq, 910.525);
|
||||
assert.strictEqual(config.normalBw, 62.5);
|
||||
assert.strictEqual(config.normalSf, 7);
|
||||
assert.strictEqual(config.normalCr, 5);
|
||||
assert.strictEqual(defaults.startEpoch, config.startEpoch);
|
||||
assert.strictEqual(defaults.endEpoch, config.endEpoch);
|
||||
assert.strictEqual(defaults.freq, config.freq);
|
||||
@@ -58,6 +62,10 @@ assert.strictEqual(
|
||||
"get tempradioat2"
|
||||
);
|
||||
assert.strictEqual(commands.stockLeaveIn30, "tempradio 910.1,500,8,7,30");
|
||||
assert.strictEqual(
|
||||
commands.stockCancelDuring,
|
||||
"tempradio 910.525,62.5,7,5,1"
|
||||
);
|
||||
assert.strictEqual(
|
||||
commands.companionLeaveIn30,
|
||||
"set radio2.cross on\n" +
|
||||
@@ -101,6 +109,10 @@ const generated = tool.configFromGenerator({
|
||||
bw: "500",
|
||||
sf: "8",
|
||||
cr: "7",
|
||||
normalfreq: "910.525",
|
||||
normalbw: "62.5",
|
||||
normalsf: "7",
|
||||
normalcr: "5",
|
||||
tx: "22",
|
||||
});
|
||||
assert.strictEqual(generated.startEpoch, config.startEpoch);
|
||||
@@ -136,6 +148,18 @@ assert.throws(
|
||||
() => tool.configFromSearch("?tx=61"),
|
||||
/tx must be between/
|
||||
);
|
||||
assert.throws(
|
||||
() => tool.configFromSearch("?normalbw=100"),
|
||||
/normalbw must be one of/
|
||||
);
|
||||
|
||||
const alternateReturn = tool.configFromSearch(
|
||||
"?normalfreq=915.5&normalbw=125&normalsf=9&normalcr=6"
|
||||
);
|
||||
assert.strictEqual(
|
||||
tool.commandsFor(alternateReturn, alternateReturn.startMs).stockCancelDuring,
|
||||
"tempradio 915.5,125,9,6,1"
|
||||
);
|
||||
|
||||
const changed = tool.configFromSearch(
|
||||
"?start=1790035200&end=1790208000&freq=915.25&bw=125&sf=10&cr=5"
|
||||
@@ -154,6 +178,10 @@ assert.strictEqual(shared.searchParams.get("end"), "2026-09-24T00:00:00.000Z");
|
||||
assert.strictEqual(shared.searchParams.get("freq"), "915.25");
|
||||
assert.strictEqual(shared.searchParams.get("tz"), "America/Los_Angeles");
|
||||
assert.strictEqual(shared.searchParams.get("tx"), "22");
|
||||
assert.strictEqual(shared.searchParams.get("normalfreq"), "910.525");
|
||||
assert.strictEqual(shared.searchParams.get("normalbw"), "62.5");
|
||||
assert.strictEqual(shared.searchParams.get("normalsf"), "7");
|
||||
assert.strictEqual(shared.searchParams.get("normalcr"), "5");
|
||||
assert.strictEqual(shared.searchParams.has("stale"), false);
|
||||
assert.strictEqual(shared.hash, "#commands");
|
||||
|
||||
|
||||
Reference in new issue
Block a user