import { Protobuf, Types } from "@meshtastic/js"; import React, { useEffect } from "react"; interface Region { freq_start: number; freq_end: number; duty_cycle: number; spacing: number; power_limit: number; } interface Modem { bw: number; cr: number; sf: number; } const RegionData = new Map< Protobuf.Config.Config_LoRaConfig_RegionCode, Region >([ [ Protobuf.Config.Config_LoRaConfig_RegionCode.US, { freq_start: 902.0, freq_end: 928.0, duty_cycle: 100, spacing: 0, power_limit: 30, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.EU_433, { freq_start: 433.0, freq_end: 434.0, duty_cycle: 10, spacing: 0, power_limit: 12, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.EU_868, { freq_start: 869.4, freq_end: 869.65, duty_cycle: 10, spacing: 0, power_limit: 27, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.CN, { freq_start: 470.0, freq_end: 510.0, duty_cycle: 100, spacing: 0, power_limit: 19, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.JP, { freq_start: 920.8, freq_end: 927.8, duty_cycle: 100, spacing: 0, power_limit: 16, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.ANZ, { freq_start: 915.0, freq_end: 928.0, duty_cycle: 100, spacing: 0, power_limit: 30, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.RU, { freq_start: 868.7, freq_end: 869.2, duty_cycle: 100, spacing: 0, power_limit: 20, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.KR, { freq_start: 920.0, freq_end: 923.0, duty_cycle: 100, spacing: 0, power_limit: 0, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.TW, { freq_start: 920.0, freq_end: 925.0, duty_cycle: 100, spacing: 0, power_limit: 0, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.IN, { freq_start: 865.0, freq_end: 867.0, duty_cycle: 100, spacing: 0, power_limit: 30, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.NZ_865, { freq_start: 864.0, freq_end: 868.0, duty_cycle: 100, spacing: 0, power_limit: 36, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.TH, { freq_start: 920.0, freq_end: 925.0, duty_cycle: 100, spacing: 0, power_limit: 16, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.UA_433, { freq_start: 433.0, freq_end: 434.7, duty_cycle: 10, spacing: 0, power_limit: 10, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.UA_868, { freq_start: 868.0, freq_end: 868.6, duty_cycle: 1, spacing: 0, power_limit: 14, }, ], [ 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, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.LORA_24, { freq_start: 2400.0, freq_end: 2483.5, duty_cycle: 100, spacing: 0, power_limit: 10, }, ], [ Protobuf.Config.Config_LoRaConfig_RegionCode.UNSET, { freq_start: 902.0, freq_end: 928.0, duty_cycle: 100, spacing: 0, power_limit: 30, }, ], ]); const modemPresets = new Map< Protobuf.Config.Config_LoRaConfig_ModemPreset, Modem >([ [ Protobuf.Config.Config_LoRaConfig_ModemPreset.SHORT_FAST, { bw: 250, cr: 8, sf: 7, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.SHORT_SLOW, { bw: 250, cr: 8, sf: 8, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.MEDIUM_FAST, { bw: 250, cr: 8, sf: 9, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.MEDIUM_SLOW, { bw: 250, cr: 8, sf: 10, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_FAST, { bw: 250, cr: 8, sf: 11, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_MODERATE, { bw: 125, cr: 8, sf: 11, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_SLOW, { bw: 125, cr: 8, sf: 12, }, ], [ Protobuf.Config.Config_LoRaConfig_ModemPreset.VERY_LONG_SLOW, { bw: 62.5, cr: 8, sf: 12, }, ], ]); export const FrequencyCalculator = (): JSX.Element => { const [modemPreset, setModemPreset] = React.useState( Protobuf.Config.Config_LoRaConfig_ModemPreset.LONG_FAST, ); const [region, setRegion] = React.useState( Protobuf.Config.Config_LoRaConfig_RegionCode.US, ); const [channel, setChannel] = React.useState( Types.ChannelNumber.PRIMARY, ); const [numChannels, setNumChannels] = React.useState(0); const [channelFrequency, setChannelFrequency] = React.useState(0); 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), ); setNumChannels(calculatedNumChannels); let updatedChannel = channel; if (updatedChannel >= calculatedNumChannels) { updatedChannel = 0; } setChannel(updatedChannel); setChannelFrequency( selectedRegion.freq_start + selectedModemPreset.bw / 2000 + updatedChannel * (selectedModemPreset.bw / 1000), ); }, [modemPreset, region, channel]); return (
); };