2023-12-26 04:17:57 -08:00
|
|
|
import { Protobuf, Types } from "@meshtastic/js";
|
2023-09-09 05:16:14 -07:00
|
|
|
import React, { useEffect } from "react";
|
2023-05-12 04:40:11 -07:00
|
|
|
|
|
|
|
interface Region {
|
2023-09-09 05:16:14 -07:00
|
|
|
freq_start: number;
|
|
|
|
freq_end: number;
|
|
|
|
duty_cycle: number;
|
|
|
|
spacing: number;
|
|
|
|
power_limit: number;
|
2023-05-12 04:40:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
interface Modem {
|
2023-09-09 05:16:14 -07:00
|
|
|
bw: number;
|
|
|
|
cr: number;
|
|
|
|
sf: number;
|
2023-05-12 04:40:11 -07:00
|
|
|
}
|
|
|
|
|
2024-01-05 17:02:32 -08:00
|
|
|
const RegionData = new Map<
|
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode,
|
|
|
|
Region
|
|
|
|
>([
|
2023-09-09 05:16:14 -07:00
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.US,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 902.0,
|
|
|
|
freq_end: 928.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 30,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.EU_433,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 433.0,
|
|
|
|
freq_end: 434.0,
|
|
|
|
duty_cycle: 10,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 12,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.EU_868,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 869.4,
|
|
|
|
freq_end: 869.65,
|
|
|
|
duty_cycle: 10,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 27,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.CN,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 470.0,
|
|
|
|
freq_end: 510.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 19,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.JP,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 920.8,
|
|
|
|
freq_end: 927.8,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 16,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.ANZ,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 915.0,
|
|
|
|
freq_end: 928.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 30,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.RU,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 868.7,
|
|
|
|
freq_end: 869.2,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 20,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.KR,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 920.0,
|
|
|
|
freq_end: 923.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 0,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.TW,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 920.0,
|
|
|
|
freq_end: 925.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 0,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.IN,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 865.0,
|
|
|
|
freq_end: 867.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 30,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.NZ_865,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 864.0,
|
|
|
|
freq_end: 868.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 36,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.TH,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 920.0,
|
|
|
|
freq_end: 925.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 16,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.UA_433,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 433.0,
|
|
|
|
freq_end: 434.7,
|
|
|
|
duty_cycle: 10,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 10,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.UA_868,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 868.0,
|
|
|
|
freq_end: 868.6,
|
|
|
|
duty_cycle: 1,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 14,
|
|
|
|
},
|
|
|
|
],
|
2024-01-15 22:36:17 -08:00
|
|
|
[
|
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.MY_433,
|
|
|
|
{
|
|
|
|
freq_start: 433.0,
|
|
|
|
freq_end: 435.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 20,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.MY_919,
|
|
|
|
{
|
|
|
|
freq_start: 919.0,
|
|
|
|
freq_end: 924.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 27,
|
|
|
|
},
|
|
|
|
],
|
2023-09-09 05:16:14 -07:00
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.LORA_24,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 2400.0,
|
|
|
|
freq_end: 2483.5,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 10,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.UNSET,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
freq_start: 902.0,
|
|
|
|
freq_end: 928.0,
|
|
|
|
duty_cycle: 100,
|
|
|
|
spacing: 0,
|
|
|
|
power_limit: 30,
|
|
|
|
},
|
|
|
|
],
|
2023-05-12 04:40:11 -07:00
|
|
|
]);
|
|
|
|
|
2024-01-05 17:02:32 -08:00
|
|
|
const modemPresets = new Map<
|
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset,
|
|
|
|
Modem
|
|
|
|
>([
|
2023-09-09 05:16:14 -07:00
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.SHORT_FAST,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 250,
|
|
|
|
cr: 8,
|
|
|
|
sf: 7,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.SHORT_SLOW,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 250,
|
|
|
|
cr: 8,
|
|
|
|
sf: 8,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.MEDIUM_FAST,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 250,
|
|
|
|
cr: 8,
|
|
|
|
sf: 9,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.MEDIUM_SLOW,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 250,
|
|
|
|
cr: 8,
|
|
|
|
sf: 10,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_FAST,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 250,
|
|
|
|
cr: 8,
|
|
|
|
sf: 11,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_MODERATE,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 125,
|
|
|
|
cr: 8,
|
|
|
|
sf: 11,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_SLOW,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 125,
|
|
|
|
cr: 8,
|
|
|
|
sf: 12,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[
|
2024-01-05 17:02:32 -08:00
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.VERY_LONG_SLOW,
|
2023-09-09 05:16:14 -07:00
|
|
|
{
|
|
|
|
bw: 62.5,
|
|
|
|
cr: 8,
|
|
|
|
sf: 12,
|
|
|
|
},
|
|
|
|
],
|
2023-05-12 04:40:11 -07:00
|
|
|
]);
|
|
|
|
|
|
|
|
export const FrequencyCalculator = (): JSX.Element => {
|
2023-09-09 05:16:14 -07:00
|
|
|
const [modemPreset, setModemPreset] =
|
2024-01-05 17:02:32 -08:00
|
|
|
React.useState<Protobuf.Config.Config_LoRaConfig_ModemPreset>(
|
|
|
|
Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_FAST,
|
2023-09-09 05:16:14 -07:00
|
|
|
);
|
|
|
|
const [region, setRegion] =
|
2024-01-05 17:02:32 -08:00
|
|
|
React.useState<Protobuf.Config.Config_LoRaConfig_RegionCode>(
|
|
|
|
Protobuf.Config.Config_LoRaConfig_RegionCode.US,
|
2023-09-09 05:16:14 -07:00
|
|
|
);
|
|
|
|
const [channel, setChannel] = React.useState<Types.ChannelNumber>(
|
|
|
|
Types.ChannelNumber.PRIMARY,
|
|
|
|
);
|
|
|
|
const [numChannels, setNumChannels] = React.useState<number>(0);
|
|
|
|
const [channelFrequency, setChannelFrequency] = React.useState<number>(0);
|
2023-05-12 04:40:11 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
useEffect(() => {
|
|
|
|
const selectedRegion = RegionData.get(region);
|
|
|
|
const selectedModemPreset = modemPresets.get(modemPreset);
|
|
|
|
const calculatedNumChannels = Math.floor(
|
|
|
|
(selectedRegion.freq_end - selectedRegion.freq_start) /
|
|
|
|
(selectedRegion.spacing + selectedModemPreset.bw / 1000),
|
|
|
|
);
|
2023-05-20 19:37:14 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
setNumChannels(calculatedNumChannels);
|
2023-06-04 12:32:30 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
let updatedChannel = channel;
|
|
|
|
if (updatedChannel >= calculatedNumChannels) {
|
|
|
|
updatedChannel = 0;
|
|
|
|
}
|
2023-05-20 19:37:14 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
setChannel(updatedChannel);
|
2023-06-04 12:32:30 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
setChannelFrequency(
|
|
|
|
selectedRegion.freq_start +
|
|
|
|
selectedModemPreset.bw / 2000 +
|
|
|
|
updatedChannel * (selectedModemPreset.bw / 1000),
|
|
|
|
);
|
|
|
|
}, [modemPreset, region, channel]);
|
2023-05-12 04:40:11 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
return (
|
|
|
|
<div className="flex flex-col border-l-[5px] shadow-md my-4 border-accent rounded-lg p-4 bg-secondary gap-2">
|
|
|
|
<div className="flex gap-2">
|
|
|
|
<label>Modem Preset:</label>
|
|
|
|
<select
|
|
|
|
value={modemPreset}
|
|
|
|
onChange={(e) =>
|
|
|
|
setModemPreset(
|
|
|
|
parseInt(
|
|
|
|
e.target.value,
|
2024-01-05 17:02:32 -08:00
|
|
|
) as Protobuf.Config.Config_LoRaConfig_ModemPreset,
|
2023-09-09 05:16:14 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{Array.from(modemPresets.keys()).map((key) => (
|
|
|
|
<option key={key} value={key}>
|
2024-01-05 17:02:32 -08:00
|
|
|
{Protobuf.Config.Config_LoRaConfig_ModemPreset[key]}
|
2023-09-09 05:16:14 -07:00
|
|
|
</option>
|
|
|
|
))}
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div className="flex gap-2">
|
|
|
|
<label>Region:</label>
|
|
|
|
<select
|
|
|
|
value={region}
|
|
|
|
onChange={(e) => setRegion(parseInt(e.target.value))}
|
|
|
|
>
|
|
|
|
{Array.from(RegionData.keys()).map((key) => (
|
|
|
|
<option key={key} value={key}>
|
2024-01-05 17:02:32 -08:00
|
|
|
{Protobuf.Config.Config_LoRaConfig_RegionCode[key]}
|
2023-09-09 05:16:14 -07:00
|
|
|
</option>
|
|
|
|
))}
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div className="flex gap-2">
|
|
|
|
<label>Channel:</label>
|
|
|
|
<select
|
|
|
|
value={channel}
|
|
|
|
onChange={(e) => setChannel(parseInt(e.target.value))}
|
|
|
|
>
|
|
|
|
{Array.from(Array(numChannels).keys()).map((key) => (
|
|
|
|
<option key={key} value={key}>
|
|
|
|
{key + 1}
|
|
|
|
</option>
|
|
|
|
))}
|
|
|
|
</select>
|
|
|
|
</div>
|
2023-05-20 19:37:14 -07:00
|
|
|
|
2023-09-09 05:16:14 -07:00
|
|
|
<div className="flex gap-2">
|
|
|
|
<label className="font-semibold">Number of channels:</label>
|
2024-01-05 17:04:40 -08:00
|
|
|
<input type="number" disabled={true} value={numChannels} />
|
2023-09-09 05:16:14 -07:00
|
|
|
</div>
|
|
|
|
<div className="flex gap-2">
|
|
|
|
<label className="font-semibold">Channel Frequency:</label>
|
2024-01-05 17:04:40 -08:00
|
|
|
<input type="number" disabled={true} value={channelFrequency} />
|
2023-09-09 05:16:14 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2023-05-12 04:40:11 -07:00
|
|
|
};
|