This commit is contained in:
2023-07-24 23:46:18 +03:00
commit 6051ed0b82
121 changed files with 14058 additions and 0 deletions

View 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
View 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>
);
};

View 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>;
};

View 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
View 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"
>
&#8203;
</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>
);
};

View 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;
}

View 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>
);
};

View 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>
);
};