Initial
This commit is contained in:
27
src/components/BatteryCalculator.tsx
Normal file
27
src/components/BatteryCalculator.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from "react";
|
||||
|
||||
export const BatteryCalculator = (): JSX.Element => {
|
||||
return (
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3>Battery Calculator</h3>
|
||||
</div>
|
||||
<div className="card__body" style={{ display: "flex", gap: "2rem" }}>
|
||||
<div>
|
||||
<input placeholder="Search" />
|
||||
<input placeholder="Search" />
|
||||
<input placeholder="Search" />
|
||||
<input placeholder="Search" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<button
|
||||
type="button"
|
||||
className="button button--secondary button--block"
|
||||
>
|
||||
See All
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
16
src/components/Button.tsx
Normal file
16
src/components/Button.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
|
||||
import { HTMLMotionProps, motion } from "framer-motion";
|
||||
|
||||
export const Button = ({ children, ...props }: HTMLMotionProps<"div">) => {
|
||||
return (
|
||||
<motion.div
|
||||
{...props}
|
||||
whileHover={{ scale: 1.1, backgroundColor: "var(--tertiary)" }}
|
||||
whileTap={{ scale: 1.0 }}
|
||||
className="m-auto flex cursor-pointer rounded-full bg-secondary p-3 shadow-md"
|
||||
>
|
||||
<div className="m-auto">{children}</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
13
src/components/ColorMode.tsx
Normal file
13
src/components/ColorMode.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from "react";
|
||||
|
||||
export interface ColorModeProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Dark = ({ children }: ColorModeProps): JSX.Element => {
|
||||
return <div className="hideLight">{children}</div>;
|
||||
};
|
||||
|
||||
export const Light = ({ children }: ColorModeProps): JSX.Element => {
|
||||
return <div className="hideDark">{children}</div>;
|
||||
};
|
274
src/components/HardwareComponents.tsx
Normal file
274
src/components/HardwareComponents.tsx
Normal file
@@ -0,0 +1,274 @@
|
||||
// import React from 'react';
|
||||
// import data from '/docs/hardware/supported/devices.json'
|
||||
|
||||
// function checkVersionOverrides(selectedDevice, version, value) {
|
||||
|
||||
// var versionOverride = selectedDevice.versionOverrides[version]
|
||||
// var device = selectedDevice
|
||||
// var objectSegment = value.split('.')
|
||||
|
||||
// while (objectSegment.length > 1) {
|
||||
// console.log(objectSegment)
|
||||
// let test = objectSegment.shift()
|
||||
// console.log('test', test, 'og objectSegment', objectSegment)
|
||||
// versionOverride = versionOverride[test]
|
||||
// device = device[test]
|
||||
// }
|
||||
// if (versionOverride) {
|
||||
// return versionOverride
|
||||
// } else return device
|
||||
|
||||
// // if (selectedDevice.versionOverrides[version][value]) {
|
||||
// // return selectedDevice.versionOverrides[version][value]
|
||||
// // } else {
|
||||
// // console.log("no", selectedDevice, value, selectedDevice[value])
|
||||
// // return selectedDevice[value]
|
||||
// // }
|
||||
// }
|
||||
|
||||
// export const MeshtasticFeatures = ({device, version}): JSX.Element => {
|
||||
|
||||
// const selectedDevice = data[device]
|
||||
|
||||
// return (
|
||||
// <table>
|
||||
// <thead>
|
||||
// <th style={{align: "center"}}>
|
||||
// Meshtastic Feature
|
||||
// </th>
|
||||
// <th style={{align: "center"}}>
|
||||
// Device Support
|
||||
// </th>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Support Status
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// {checkVersionOverrides(selectedDevice, version, 'supportStatus')}
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Bluetooth
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// {checkVersionOverrides(selectedDevice, version, "features.bluetoothCapable")}
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - Canned Message
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - External Notification
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - Range Test
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - Rotary Encoder
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - Store and Forward
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Module - Telemetry (aka Environmental Measurement)
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Router - Always Powered
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Router - Solar Powered
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// WiFi
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export const HardwareSpecifications = ({device, version}): JSX.Element => {
|
||||
|
||||
// const selectedDevice = data[device]
|
||||
|
||||
// return (
|
||||
// <table>
|
||||
// <thead>
|
||||
// <th style={{align: "center"}}>
|
||||
// Specification
|
||||
// </th>
|
||||
// <th style={{align: "center"}}>
|
||||
// Value
|
||||
// </th>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Bluetooth
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Bluetooth Antenna
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Chipset
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Driver
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// GPS
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Flash
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Frequency - 433MHz
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Frequency - 868MHz
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Frequency - 915MHz
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// Frequency - 923MHz
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// LoRa Transceiver
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// PSRAM
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// RAM
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// WiFi
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td style={{align: "center"}}>
|
||||
// WiFi Antenna
|
||||
// </td>
|
||||
// <td style={{align: "center"}}>
|
||||
// VALUE
|
||||
// </td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
// );
|
||||
// };
|
49
src/components/Modal.tsx
Normal file
49
src/components/Modal.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
|
||||
import { Dialog } from "@headlessui/react";
|
||||
|
||||
export interface ModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Modal = ({ open, onClose, children }: ModalProps): JSX.Element => {
|
||||
return (
|
||||
<AnimatePresence initial={false} exitBeforeEnter={true}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="fixed inset-0 z-10 overflow-y-auto"
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
>
|
||||
<div className="min-h-screen px-0.5 text-center md:px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
>
|
||||
<Dialog.Overlay className="fixed inset-0 backdrop-blur-md" />
|
||||
</motion.div>
|
||||
|
||||
<span
|
||||
className="inline-block h-screen align-middle"
|
||||
aria-hidden="true"
|
||||
>
|
||||
​
|
||||
</span>
|
||||
<div className="inline-block w-full transform text-left align-middle transition-all 2xl:max-w-7xl">
|
||||
<div className="group relative">
|
||||
<div className="animate-tilt absolute -inset-0.5 rotate-2 rounded-lg bg-accent shadow-md transition duration-1000 group-hover:opacity-100 group-hover:duration-200" />
|
||||
<div className="relative flex flex-col overflow-hidden rounded-2xl bg-base shadow-md md:aspect-[2/1] md:flex-row md:bg-primary">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
25
src/components/PageLayout.tsx
Normal file
25
src/components/PageLayout.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react";
|
||||
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
export interface PageLayoutProps {
|
||||
title: string;
|
||||
description: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const PageLayout = ({
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
}: PageLayoutProps): JSX.Element => {
|
||||
return (
|
||||
<Layout title={title} description={description}>
|
||||
{children}
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export interface ColorModeProps {
|
||||
children: React.ReactNode;
|
||||
}
|
31
src/components/homepage/SocialCard.tsx
Normal file
31
src/components/homepage/SocialCard.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from "react";
|
||||
|
||||
import { FiExternalLink } from "react-icons/fi";
|
||||
|
||||
export interface SocialCardProps {
|
||||
children: React.ReactNode;
|
||||
color: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export const SocialCard = ({
|
||||
children,
|
||||
color,
|
||||
link,
|
||||
}: SocialCardProps): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className={`group relative flex h-24 w-36 min-w-max flex-shrink-0 rounded-xl shadow-xl ${color} m-2`}
|
||||
>
|
||||
{children}
|
||||
<a
|
||||
className="absolute top-0 left-0 right-0 bottom-0 hidden rounded-xl border border-accent bg-secondary bg-opacity-95 text-2xl shadow-xl group-hover:flex"
|
||||
href={link}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<FiExternalLink className="m-auto" />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
345
src/components/tools/FrequencyCalculator.tsx
Normal file
345
src/components/tools/FrequencyCalculator.tsx
Normal file
@@ -0,0 +1,345 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Protobuf, Types } from "@meshtastic/meshtasticjs";
|
||||
|
||||
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_LoRaConfig_RegionCode, Region>([
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.US,
|
||||
{
|
||||
freq_start: 902.0,
|
||||
freq_end: 928.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 30,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.EU_433,
|
||||
{
|
||||
freq_start: 433.0,
|
||||
freq_end: 434.0,
|
||||
duty_cycle: 10,
|
||||
spacing: 0,
|
||||
power_limit: 12,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.EU_868,
|
||||
{
|
||||
freq_start: 869.4,
|
||||
freq_end: 869.65,
|
||||
duty_cycle: 10,
|
||||
spacing: 0,
|
||||
power_limit: 27,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.CN,
|
||||
{
|
||||
freq_start: 470.0,
|
||||
freq_end: 510.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 19,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.JP,
|
||||
{
|
||||
freq_start: 920.8,
|
||||
freq_end: 927.8,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 16,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.ANZ,
|
||||
{
|
||||
freq_start: 915.0,
|
||||
freq_end: 928.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 30,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.RU,
|
||||
{
|
||||
freq_start: 868.7,
|
||||
freq_end: 869.2,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 20,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.KR,
|
||||
{
|
||||
freq_start: 920.0,
|
||||
freq_end: 923.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 0,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.TW,
|
||||
{
|
||||
freq_start: 920.0,
|
||||
freq_end: 925.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 0,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.IN,
|
||||
{
|
||||
freq_start: 865.0,
|
||||
freq_end: 867.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 30,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.NZ_865,
|
||||
{
|
||||
freq_start: 864.0,
|
||||
freq_end: 868.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 36,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.TH,
|
||||
{
|
||||
freq_start: 920.0,
|
||||
freq_end: 925.0,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 16,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.UA_433,
|
||||
{
|
||||
freq_start: 433.0,
|
||||
freq_end: 434.7,
|
||||
duty_cycle: 10,
|
||||
spacing: 0,
|
||||
power_limit: 10,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.UA_868,
|
||||
{
|
||||
freq_start: 868.0,
|
||||
freq_end: 868.6,
|
||||
duty_cycle: 1,
|
||||
spacing: 0,
|
||||
power_limit: 14,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_RegionCode.LORA_24,
|
||||
{
|
||||
freq_start: 2400.0,
|
||||
freq_end: 2483.5,
|
||||
duty_cycle: 100,
|
||||
spacing: 0,
|
||||
power_limit: 10,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.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_LoRaConfig_ModemPreset, Modem>([
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.SHORT_FAST,
|
||||
{
|
||||
bw: 250,
|
||||
cr: 8,
|
||||
sf: 7,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.SHORT_SLOW,
|
||||
{
|
||||
bw: 250,
|
||||
cr: 8,
|
||||
sf: 8,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.MEDIUM_FAST,
|
||||
{
|
||||
bw: 250,
|
||||
cr: 8,
|
||||
sf: 9,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.MEDIUM_SLOW,
|
||||
{
|
||||
bw: 250,
|
||||
cr: 8,
|
||||
sf: 10,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.LONG_FAST,
|
||||
{
|
||||
bw: 250,
|
||||
cr: 8,
|
||||
sf: 11,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.LONG_MODERATE,
|
||||
{
|
||||
bw: 125,
|
||||
cr: 8,
|
||||
sf: 11,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.LONG_SLOW,
|
||||
{
|
||||
bw: 125,
|
||||
cr: 8,
|
||||
sf: 12,
|
||||
},
|
||||
],
|
||||
[
|
||||
Protobuf.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_LoRaConfig_ModemPreset>(
|
||||
Protobuf.Config_LoRaConfig_ModemPreset.LONG_FAST,
|
||||
);
|
||||
const [region, setRegion] =
|
||||
React.useState<Protobuf.Config_LoRaConfig_RegionCode>(
|
||||
Protobuf.Config_LoRaConfig_RegionCode.US,
|
||||
);
|
||||
const [channel, setChannel] = React.useState<Types.ChannelNumber>(
|
||||
Types.ChannelNumber.PRIMARY,
|
||||
);
|
||||
const [numChannels, setNumChannels] = React.useState<number>(0);
|
||||
const [channelFrequency, setChannelFrequency] = React.useState<number>(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 (
|
||||
<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,
|
||||
) as Protobuf.Config_LoRaConfig_ModemPreset,
|
||||
)
|
||||
}
|
||||
>
|
||||
{Array.from(modemPresets.keys()).map((key) => (
|
||||
<option key={key} value={key}>
|
||||
{Protobuf.Config_LoRaConfig_ModemPreset[key]}
|
||||
</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}>
|
||||
{Protobuf.Config_LoRaConfig_RegionCode[key]}
|
||||
</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>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<label className="font-semibold">Number of channels:</label>
|
||||
<input type="number" disabled value={numChannels} />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<label className="font-semibold">Channel Frequency:</label>
|
||||
<input type="number" disabled value={channelFrequency} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user