Compare commits
37 Commits
feature/up
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| af040a4096 | |||
| 38af7a1e27 | |||
| 94a0410957 | |||
| afa73644d4 | |||
| 7d8e4cd5cc | |||
| b4ce029dd6 | |||
| 55a84a03ea | |||
| 4a25f00f1b | |||
| ba49ce7cf0 | |||
|
be76e4919e
|
|||
| 032edad7ac | |||
| 0be6bb21ea | |||
| 335c7e7334 | |||
| 91664bfb81 | |||
| 04a1af17cd | |||
| b23bff5d67 | |||
| 8b500c4aea | |||
| ff5f94d9fd | |||
| 183fad5ca4 | |||
| 9f910b2c1e | |||
| d5c5e0e9fa | |||
| a7fdf8fea5 | |||
| 0fe6f5f757 | |||
| 627c970374 | |||
| 027b481290 | |||
| a386b37258 | |||
| 0a48f589e0 | |||
| a6c3b70282 | |||
| 89cdaf0791 | |||
| 81ea6a8005 | |||
| a7dabace24 | |||
| adf5e83991 | |||
| e4527ce9b1 | |||
| 6cc2f95fd4 | |||
| dad112a5f8 | |||
| bc23226733 | |||
| 6acb31e2a9 |
@ -12,9 +12,16 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: mkdir /tmp/deploy
|
- run: mkdir /tmp/deploy
|
||||||
- run: rsync -ua --exclude=".*" . /tmp/deploy
|
- run: rsync -ua --exclude=".*" . /tmp/deploy
|
||||||
|
- name: Set deploy branch
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.ref_name }}" = "master" ]; then
|
||||||
|
echo "DEPLOY_BRANCH=main" >> "$GITHUB_ENV"
|
||||||
|
else
|
||||||
|
echo "DEPLOY_BRANCH=${{ github.ref_name }}" >> "$GITHUB_ENV"
|
||||||
|
fi
|
||||||
- name: Build & Deploy Worker
|
- name: Build & Deploy Worker
|
||||||
uses: cloudflare/wrangler-action@v3
|
uses: cloudflare/wrangler-action@v3
|
||||||
with:
|
with:
|
||||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||||
command: pages deploy /tmp/deploy --project-name=ctmesh-org
|
command: pages deploy /tmp/deploy --project-name=ctmesh-org --branch=${{ env.DEPLOY_BRANCH }}
|
||||||
|
|||||||
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
||||||
3
_redirects
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/discord https://discord.gg/m4F328as3K 302
|
||||||
|
/merch https://ctmesh.redbubble.com 302
|
||||||
|
/store https://ctmesh.redbubble.com 302
|
||||||
BIN
favicon.png
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 34 KiB |
BIN
favicon_sq.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
346
index.html
@ -6,60 +6,75 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||||
|
|
||||||
<!-- Site Description & Keywords -->
|
<!-- Site Description & Keywords -->
|
||||||
<meta name="description" content="A Connecticut Meshtastic User Group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
<meta name="description" content="A Connecticut mesh technologies user group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
||||||
<meta name="keywords" content="CT Mesh, Meshtastic, Connecticut, CT, community, user group, Discord, map">
|
<meta name="keywords" content="CT Mesh, Mesh, MeshCore, Meshtastic, Connecticut, CT, community, networking, user group, Discord, map, radio">
|
||||||
<meta name="author" content="CT Mesh">
|
<meta name="author" content="CT Mesh">
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.png?3">
|
<link rel="shortcut icon" type="image/x-icon" href="favicon.png?2026-1">
|
||||||
|
|
||||||
<!-- Open Graph / Facebook -->
|
<!-- Open Graph / Facebook -->
|
||||||
<meta property="og:title" content="CT Mesh">
|
<meta property="og:title" content="CT Mesh">
|
||||||
<meta property="og:description" content="A Connecticut Meshtastic User Group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
<meta property="og:description" content="A Connecticut mesh technologies user group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
||||||
<meta property="og:image" content="favicon.png?3">
|
<meta property="og:image" content="favicon.png?2026-1">
|
||||||
<meta property="og:url" content="https://ctmesh.org">
|
<meta property="og:url" content="https://ctmesh.org">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
|
|
||||||
<!-- Twitter -->
|
<!-- Twitter -->
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:title" content="CT Mesh">
|
<meta name="twitter:title" content="CT Mesh">
|
||||||
<meta name="twitter:description" content="A Connecticut Meshtastic User Group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
<meta name="twitter:description" content="A Connecticut mesh technologies user group. Join the local community to connect, share, and explore with fellow enthusiasts.">
|
||||||
<meta name="twitter:image" content="favicon.png?3">
|
<meta name="twitter:image" content="favicon.png?2026-1">
|
||||||
|
|
||||||
<!-- Fonts and Icons -->
|
<!-- Fonts and Icons -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="favicon.png?3">
|
<link rel="icon" type="image/png" href="favicon.png?2026-14">
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="57x57" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="72x72" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="114x114" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="120x120" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="144x144" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="152x152" href="favicon.png?2026-1">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="favicon.png?3">
|
<link rel="apple-touch-icon" sizes="180x180" href="favicon.png?2026-1">
|
||||||
<meta name="msapplication-TileColor" content="#67EA94">
|
<meta name="msapplication-TileColor" content="#6EBEE1">
|
||||||
<meta name="msapplication-TileImage" content="favicon.png?3">
|
<meta name="msapplication-TileImage" content="favicon.png?2026-1">
|
||||||
<meta name="theme-color" content="#67EA94">
|
<meta name="theme-color" content="#6EBEE1">
|
||||||
|
|
||||||
<title>CT Mesh</title>
|
<title>CT Mesh</title>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
min-height: 100%;
|
||||||
|
background-color: #272727;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
background: url('background.svg') no-repeat center center fixed;
|
background-color: transparent;
|
||||||
background-size: cover;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('background.svg') no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
filter: invert(1) brightness(0.85);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
a,
|
a,
|
||||||
a:visited {
|
a:visited {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -70,16 +85,17 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(87, 87, 87, 0.4);
|
background: rgba(80, 80, 80, 0.35);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
.splash-box {
|
.splash-box {
|
||||||
background-color: #EBEBEB;
|
background-color: #EBEBEB;
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
padding: 3em 3em 2em 3em;
|
padding: 3em 3em 2em 3em;
|
||||||
margin: 1em;
|
margin: 2.5em;
|
||||||
width: min(100%, 900px);
|
width: 90%;
|
||||||
max-width: 900px;
|
max-width: 700px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
color: #000000;
|
color: #000000;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -90,23 +106,42 @@
|
|||||||
}
|
}
|
||||||
.top-section {
|
.top-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 1em;
|
gap: 0.5em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 15px;
|
background-color: #272727;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
margin: -3em -3em 0 -3em;
|
||||||
|
padding: 2.5em 3em 50px 3em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.top-section a img {
|
.email-link img {
|
||||||
width: 35px;
|
width: 35px;
|
||||||
filter: invert(15%) sepia(17%) saturate(767%) hue-rotate(198deg) brightness(94%) contrast(91%);
|
filter: brightness(0) invert(0.7);
|
||||||
|
}
|
||||||
|
.wave-divider {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.wave-divider svg {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
.logo {
|
.logo {
|
||||||
width: 200px;
|
width: 540px;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding-right: 30px;
|
|
||||||
}
|
}
|
||||||
.text-content {
|
.text-content {
|
||||||
text-align: left;
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
.text-content h1 {
|
.text-content h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -117,12 +152,14 @@
|
|||||||
}
|
}
|
||||||
.sub-header {
|
.sub-header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 4px;
|
||||||
|
margin: 0;
|
||||||
|
color: #e0e0e0;
|
||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
background-color: #67EA94;
|
background-color: #67EA94;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
border: none;
|
border: none;
|
||||||
@ -151,9 +188,56 @@
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
filter: brightness(0);
|
filter: brightness(0);
|
||||||
}
|
}
|
||||||
.btn-discord {
|
.btn-discord,
|
||||||
background-color: #7289da;
|
.btn-discord:visited {
|
||||||
|
background-color: #5865F2;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.btn-discord img {
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
|
}
|
||||||
|
.btn-meshcore,
|
||||||
|
.btn-meshcore:visited {
|
||||||
|
background-color: #2B3A4E;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.btn-learn,
|
||||||
|
.btn-learn:visited {
|
||||||
|
background-color: #6EBEE1;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.btn-learn img {
|
||||||
|
filter: brightness(1);
|
||||||
|
}
|
||||||
|
.btn-meshcore img {
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
|
}
|
||||||
|
a.btn[target="_blank"]::after {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: auto;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5L8.5 3.5M5 3.5h3.5V7'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
a.btn:not([target="_blank"])::after {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: auto;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 2.5L8.5 6L4 9.5'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.btn-discord::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.btn-meshcore::after {
|
||||||
|
filter: invert(1) !important;
|
||||||
}
|
}
|
||||||
.btn-group {
|
.btn-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -165,11 +249,11 @@
|
|||||||
.btn-groups {
|
.btn-groups {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1em;
|
gap: 1.5em;
|
||||||
}
|
}
|
||||||
.section-title {
|
.section-title {
|
||||||
margin: 0.5em 0 0;
|
margin: 0.5em 0 0;
|
||||||
padding-top: 0.75em;
|
padding-top: 1em;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
@ -213,54 +297,47 @@
|
|||||||
padding-top: calc(env(safe-area-inset-top, 1em));
|
padding-top: calc(env(safe-area-inset-top, 1em));
|
||||||
}
|
}
|
||||||
.splash-box {
|
.splash-box {
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
min-width: 350px;
|
margin: 1em 0;
|
||||||
|
width: calc(100% - 5em);
|
||||||
}
|
}
|
||||||
.top-section {
|
.top-section {
|
||||||
flex-direction: column;
|
margin: -2em -2em 0 -2em;
|
||||||
padding-bottom: 20px;
|
padding: 2em 2em 50px 2em;
|
||||||
}
|
}
|
||||||
.logo {
|
.logo {
|
||||||
width: 150px;
|
width: 335px;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.text-content {
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
.btn-group {
|
.btn-group {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.section-title {
|
.section-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
width: 100%;
|
width: 340px;
|
||||||
justify-content: center;
|
max-width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
padding: 0.8em 1em;
|
padding: 0.8em 1em;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-align: center;
|
text-align: left;
|
||||||
max-width: 100%;
|
|
||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
.btn-text {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Further adjustments for devices with a viewport width of 480px or less */
|
/* Further adjustments for devices with a viewport width of 480px or less */
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.splash-box {
|
.splash-box {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
margin: 1em;
|
}
|
||||||
width: 90%;
|
.top-section {
|
||||||
min-width: 250px;
|
margin: -1.5em -1.5em 0 -1.5em;
|
||||||
|
padding: 1.5em 1.5em 50px 1.5em;
|
||||||
}
|
}
|
||||||
.logo {
|
.logo {
|
||||||
width: 120px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
.text-content h1 {
|
.text-content h1 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@ -279,108 +356,89 @@
|
|||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<div class="splash-box">
|
<div class="splash-box">
|
||||||
<div class="top-section">
|
<div class="top-section">
|
||||||
<img src="logo_sm.png" alt="CT Mesh Logo" class="logo" />
|
<img src="logo_sm.png?2026" alt="CT Mesh Logo" class="logo" />
|
||||||
<div class="text-content">
|
<div class="text-content">
|
||||||
<h1>CT Mesh</h1>
|
<p class="sub-header">A Connecticut Mesh Technologies User Group</p>
|
||||||
<p class="sub-header">Connecticut Meshtastic User Group</p>
|
<a href="mailto:noah@ctmesh.org" class="email-link" rel="nofollow noindex"><img src="email.svg" alt="Email" /></a>
|
||||||
<a href="mailto:noah@ctmesh.org" rel="nofollow noindex"><img src="email.svg" alt="Email" /></a>
|
</div>
|
||||||
|
<div class="btn-group" style="margin-bottom: 1em;">
|
||||||
|
<a href="https://ctmesh.org/discord" target="_blank" class="btn btn-discord">
|
||||||
|
<img src="discord.svg" alt="Discord" />
|
||||||
|
<div class="btn-text">
|
||||||
|
Join our Discord
|
||||||
|
<small>Chat with the community</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="why-run-a-node.html" class="btn btn-learn">
|
||||||
|
<img src="info.svg" alt="Learn about mesh networking" />
|
||||||
|
<div class="btn-text">
|
||||||
|
Why Mesh?
|
||||||
|
<small>Learn about the mesh!</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="wave-divider">
|
||||||
|
<svg viewBox="0 0 1440 60" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0,30 C240,60 480,0 720,30 C960,60 1200,0 1440,30 L1440,60 L0,60 Z" fill="#EBEBEB"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-groups">
|
<div class="btn-groups">
|
||||||
<div class="section">
|
|
||||||
<div class="btn-group">
|
|
||||||
<a href="https://discord.gg/m4F328as3K" target="_blank" class="btn btn-discord">
|
|
||||||
<img src="discord.svg" alt="Discord Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Join our Discord
|
|
||||||
<small>Join the community</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<p class="section-title">Meshtastic</p>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a href="https://meshtastic.org/" target="_blank" class="btn">
|
|
||||||
<img src="meshtastic.svg" alt="Meshtastic Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Meshtastic
|
|
||||||
<small>Learn more!</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="https://malla.ctmesh.org/" target="_blank" class="btn">
|
|
||||||
<img src="info.svg" alt="Info Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Web Dashboard
|
|
||||||
<small>Network metrics & analytics</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="https://map.ctmesh.org/?lat=41.734429390721&lng=287.3501586914063&zoom=10" target="_blank" class="btn">
|
|
||||||
<img src="map.svg" alt="Map Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
CT Map
|
|
||||||
<small>Nodes seen by CT Mesh</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="https://meshtastic.liamcottle.net/?lat=26.58852714730864&lng=285.11718750000006&zoom=2" target="_blank" class="btn">
|
|
||||||
<img src="globe.svg" alt="Globe Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Global Map
|
|
||||||
<small>Nodes around the world</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="resources.html" class="btn">
|
|
||||||
<img src="info.svg" alt="Info Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Meshtastic Resources
|
|
||||||
<small>Channels, MQTT, tools</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<p class="section-title">MeshCore</p>
|
<p class="section-title">MeshCore</p>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a href="https://meshcore.co.uk/" target="_blank" class="btn">
|
<a href="https://meshcore.co.uk/" target="_blank" class="btn btn-meshcore">
|
||||||
<img src="meshcore.svg" alt="MeshCore Logo" />
|
<img src="meshcore.svg" alt="MeshCore" />
|
||||||
<div class="btn-text">
|
<div class="btn-text">
|
||||||
Official MeshCore Website
|
MeshCore
|
||||||
<small>Project website</small>
|
<small>About the project</small>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://meshcore-map.ctmesh.org/" target="_blank" class="btn">
|
<a href="https://meshcore-map.ctmesh.org/" target="_blank" class="btn btn-meshcore">
|
||||||
<img src="map.svg" alt="Map Icon" />
|
<img src="map.svg" alt="Map" />
|
||||||
<div class="btn-text">
|
<div class="btn-text">
|
||||||
MeshCore Map
|
Node Map
|
||||||
<small>Live node map</small>
|
<small>Live MeshCore nodes</small>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://meshcore-wardrive.ctmesh.org/" target="_blank" class="btn">
|
<a href="meshcore-resources.html" class="btn btn-meshcore">
|
||||||
<img src="map.svg" alt="Map Icon" />
|
<img src="info.svg" alt="Guides & Tools" />
|
||||||
<div class="btn-text">
|
<div class="btn-text">
|
||||||
MeshCore Wardrive
|
Guides & Tools
|
||||||
<small>Coverage maps</small>
|
<small>Wardrive, MQTT, setup</small>
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="https://meshcore-wardrive.ctmesh.org/wardrive" target="_blank" class="btn">
|
|
||||||
<img src="wheel.svg" alt="Wheel Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
Wardrive Contribution
|
|
||||||
<small>Upload wardrive data</small>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="meshcore-resources.html" class="btn">
|
|
||||||
<img src="info.svg" alt="Info Icon" />
|
|
||||||
<div class="btn-text">
|
|
||||||
MeshCore Resources
|
|
||||||
<small>Tools and maps</small>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<p class="section-title">Meshtastic</p>
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="https://meshtastic.org/" target="_blank" class="btn">
|
||||||
|
<img src="meshtastic.svg" alt="Meshtastic" />
|
||||||
|
<div class="btn-text">
|
||||||
|
Meshtastic
|
||||||
|
<small>About the project</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="https://map.ctmesh.org/?lat=41.734429390721&lng=287.3501586914063&zoom=10" target="_blank" class="btn">
|
||||||
|
<img src="map.svg" alt="Map" />
|
||||||
|
<div class="btn-text">
|
||||||
|
Node Map
|
||||||
|
<small>CT Mesh nodes</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="meshtastic-resources.html" class="btn">
|
||||||
|
<img src="info.svg" alt="Guides & Tools" />
|
||||||
|
<div class="btn-text">
|
||||||
|
Guides & Tools
|
||||||
|
<small>Channels, MQTT, setup</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<p><a href="https://ctmesh.org/">CT Mesh</a> is a volunteer-run user group for <a href="https://meshtastic.org" target="_blank">Meshtastic</a> enthusiasts in Connecticut.</p>
|
<p><a href="https://ctmesh.org/">CT Mesh</a> is a volunteer-run user group for mesh technology enthusiasts in Connecticut.</p>
|
||||||
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Content licensed CC BY-SA 4.0</a></p>
|
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Content licensed CC BY-SA 4.0</a></p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
logo.png
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 458 KiB |
BIN
logo_sm.png
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 77 KiB |
@ -10,23 +10,38 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
background-color: #272727;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
background: url('background.svg') no-repeat center center fixed;
|
background-color: transparent;
|
||||||
background-size: cover;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
color: #2C2D3C;
|
color: #2C2D3C;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 2em 0;
|
padding: 2em 0;
|
||||||
}
|
}
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('background.svg') no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
filter: invert(1) brightness(0.85);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
a,
|
a,
|
||||||
a:visited {
|
a:visited {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -37,14 +52,15 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(87, 87, 87, 0.4);
|
background: rgba(80, 80, 80, 0.35);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
.content-box {
|
.content-box {
|
||||||
background-color: #EBEBEB;
|
background-color: #EBEBEB;
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
padding: 2.5em 3em;
|
padding: 2.5em 3em;
|
||||||
margin: 1em;
|
margin: 2.5em;
|
||||||
max-width: 820px;
|
max-width: 820px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
@ -74,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
.note {
|
.note {
|
||||||
background: #F5F5F5;
|
background: #F5F5F5;
|
||||||
border-left: 4px solid #67EA94;
|
border-left: 4px solid #2B3A4E;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 0.75em 1em;
|
padding: 0.75em 1em;
|
||||||
margin: 0.75em 0 0.5em;
|
margin: 0.75em 0 0.5em;
|
||||||
@ -98,8 +114,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.75em;
|
top: 0.75em;
|
||||||
right: 0.75em;
|
right: 0.75em;
|
||||||
background-color: #67EA94;
|
background-color: #2B3A4E;
|
||||||
color: #000000;
|
color: #ffffff;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 0.4em 0.75em;
|
padding: 0.4em 0.75em;
|
||||||
@ -112,18 +128,86 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
background-color: #67EA94;
|
background-color: #2B3A4E;
|
||||||
color: #000000;
|
color: #ffffff;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.75em 1.5em;
|
padding: 0.75em 1.5em;
|
||||||
border-radius: 15px;
|
border-radius: 999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.back-link {
|
.page-header-bg {
|
||||||
|
background-color: #272727;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
margin: -2.5em -3em 1.5em -3em;
|
||||||
|
padding: 2em 3em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.page-header img {
|
||||||
|
width: 300px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.page-header span {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 19px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
.back-link,
|
||||||
|
.back-link:visited {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
|
color: #ffffff;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.back-link::before {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2.5L3.5 6L8 9.5'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
a[target="_blank"]::after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
vertical-align: middle;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5L8.5 3.5M5 3.5h3.5V7'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
opacity: 0.4;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.btn[target="_blank"]::after,
|
||||||
|
.copy-btn::after,
|
||||||
|
.site-footer a::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.site-footer {
|
||||||
|
margin-top: 2em;
|
||||||
|
padding-top: 2em;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #2C2D3C;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.site-footer a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.site-footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
body {
|
body {
|
||||||
@ -132,11 +216,19 @@
|
|||||||
.content-box {
|
.content-box {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -2em -2em 1.5em -2em;
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.content-box {
|
.content-box {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
}
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -1.5em -1.5em 1.5em -1.5em;
|
||||||
|
padding: 1.5em;
|
||||||
|
}
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
@ -149,38 +241,56 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<div class="content-box">
|
<div class="content-box">
|
||||||
|
<div class="page-header-bg">
|
||||||
|
<a href="index.html" class="page-header">
|
||||||
|
<img src="logo_sm.png" alt="CT Mesh" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<h1>MeshCore Resources</h1>
|
<h1>MeshCore Resources</h1>
|
||||||
|
|
||||||
<h2>Community-run Web Tools</h2>
|
<h2>Web Tools</h2>
|
||||||
<div class="community-tools">
|
<div class="community-tools">
|
||||||
<p><em>These tools use data reported to our MQTT server by nodes across the state.</em></p>
|
<p><em>These tools use data reported to MQTT using <a href="https://analyzer.letsmesh.net/observer/onboard" target="_blank">Observer Firmware</a> by nodes across the state.</em></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://meshcore-map.ctmesh.org/" target="_blank">MeshCore Map</a> <strong>NEW!</strong> - live map showing MeshCore nodes</li>
|
<li><a href="https://meshcore-map.ctmesh.org/" target="_blank">MeshCore Map</a> <strong>NEW!</strong> – live map showing MeshCore nodes</li>
|
||||||
<li><a href="https://meshcore-wardrive.ctmesh.org/" target="_blank">MeshCore Wardriving Map</a> <strong>NEW!</strong> - coverage maps for MeshCore (you can also contribute!). <em>Note: a new app is in testing and may supersede this.</em></li>
|
<li><a href="https://bdl.meshmapper.net/" target="_blank">MeshMapper</a> <strong>NEW!</strong> – coverage maps for MeshCore. Contribute via <a href="https://apps.apple.com/us/app/meshmapper/id6758073991" target="_blank">iOS</a> and <a href="https://play.google.com/store/apps/details?id=net.meshmapper.app" target="_blank">Android</a> mobile apps</li>
|
||||||
|
<li><a href="https://analyzer.letsmesh.net/packets?region=BDL" target="_blank">MeshCore Analyzer</a> – real-time MeshCore network analytics, node tracking, and packet analysis</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Official Links</h2>
|
<h2>Official Links</h2>
|
||||||
<p><a href="https://meshcore.co.uk/" target="_blank">meshcore.co.uk</a></p>
|
<p><a href="https://meshcore.co.uk/" target="_blank">meshcore.co.uk</a></p>
|
||||||
<p><a href="https://flasher.meshcore.co.uk/" target="_blank">flasher.meshcore.co.uk</a></p>
|
<p><a href="https://flasher.meshcore.co.uk/" target="_blank">flasher.meshcore.co.uk</a></p>
|
||||||
<div class="note"><strong>Note:</strong> the flasher requires WebSerial or Web Bluetooth support in your browser.</div>
|
<div class="note"><strong>Note:</strong> the flasher requires WebSerial or Web Bluetooth support in your browser</div>
|
||||||
|
|
||||||
<h2>MQTT</h2>
|
<h2>MQTT</h2>
|
||||||
<p>Our MQTT broker is <em>uplink-only</em> and designed for fixed nodes across the state to serve as gateway nodes. Its purpose is not to bridge gaps or extend mesh coverage, but to report local traffic to our own web-based tools for analytical data and metrics to assess the mesh's performance. <strong>This role is best suited for stable, well-placed nodes with reliable coverage.</strong></p>
|
<p>Our MQTT broker is <em>uplink-only</em> and designed for fixed nodes across the state to serve as gateway nodes. Its purpose is not to bridge gaps or extend mesh coverage, but to report local traffic to our own web-based tools for analytical data and metrics to assess the mesh's performance. <strong>This role is best suited for stable, well-placed nodes with reliable coverage.</strong></p>
|
||||||
<p>MeshCore MQTT uplink uses <a href="https://github.com/Cisien/meshcoretomqtt" target="_blank">meshcoretomqtt</a> on a Raspberry Pi or similar Linux computer with the service installed. This configuration stanza goes in your <code>.env.local</code> file after the first two MQTT servers that upload to analyzer.letsmesh.net. <strong>This also requires a custom firmware.</strong> See <a href="https://analyzer.letsmesh.net/observer/onboard" target="_blank">custom repeater firmware setup</a>.</p>
|
<p>MeshCore MQTT uplink uses <a href="https://github.com/Cisien/meshcoretomqtt" target="_blank">meshcoretomqtt</a> on a Raspberry Pi or similar Linux computer with the service installed. Configure it with a <a href="https://github.com/Cisien/meshcoretomqtt" target="_blank">Toml file</a> at <code>/etc/mctomqtt/config.d/00-user.toml</code>, with region set in your existing <code>[general]</code> section as <code>iata = "BDL"</code>, and a custom broker named <code>ctmesh</code>. The block below should be added at the end of the config file. Fill in your own broker credentials. <strong>This also requires custom firmware.</strong> See <a href="https://analyzer.letsmesh.net/observer/onboard" target="_blank">custom repeater firmware setup</a>.</p>
|
||||||
|
|
||||||
<div class="code-block">
|
<div class="code-block">
|
||||||
<button class="copy-btn" type="button" data-copy-target="meshcore-mqtt">Copy all</button>
|
<button class="copy-btn" type="button" data-copy-target="meshcore-mqtt">Copy all</button>
|
||||||
<pre id="meshcore-mqtt"># MQTT Broker 3 - CT Mesh
|
<pre id="meshcore-mqtt">[[broker]]
|
||||||
MCTOMQTT_MQTT3_ENABLED=true
|
name = "ctmesh"
|
||||||
MCTOMQTT_MQTT3_SERVER=mqtt.ctmesh.org
|
enabled = true
|
||||||
MCTOMQTT_MQTT3_PORT=1883
|
server = "mqtt.ctmesh.org"
|
||||||
MCTOMQTT_MQTT3_USE_TLS=false
|
port = 1883
|
||||||
MCTOMQTT_MQTT3_USERNAME=meshdev
|
transport = "tcp"
|
||||||
MCTOMQTT_MQTT3_PASSWORD=large4cats</pre>
|
keepalive = 60
|
||||||
|
qos = 0
|
||||||
|
retain = true
|
||||||
|
|
||||||
|
[broker.auth]
|
||||||
|
method = "password"
|
||||||
|
username = "meshdev"
|
||||||
|
password = "large4cats"</pre>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="note"><strong>Note:</strong> The <code>meshdev</code>/<code>large4cats</code> credentials are intentionally shared secrets for this broker. We recognize the security implications. Specific credentials to this broker can be requested.</p>
|
||||||
|
|
||||||
<a class="btn back-link" href="index.html">Back to CT Mesh</a>
|
<a class="btn back-link" href="index.html">Back to CT Mesh</a>
|
||||||
|
<footer class="site-footer">
|
||||||
|
<p><a href="https://ctmesh.org/">CT Mesh</a> is a volunteer-run user group for mesh technology enthusiasts in Connecticut.</p>
|
||||||
|
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Content licensed CC BY-SA 4.0</a></p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const copyButtons = document.querySelectorAll("[data-copy-target]");
|
const copyButtons = document.querySelectorAll("[data-copy-target]");
|
||||||
|
|||||||
@ -10,23 +10,38 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
background-color: #272727;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
background: url('background.svg') no-repeat center center fixed;
|
background-color: transparent;
|
||||||
background-size: cover;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
color: #2C2D3C;
|
color: #2C2D3C;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 2em 0;
|
padding: 2em 0;
|
||||||
}
|
}
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('background.svg') no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
filter: invert(1) brightness(0.85);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
a,
|
a,
|
||||||
a:visited {
|
a:visited {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -37,14 +52,15 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(87, 87, 87, 0.4);
|
background: rgba(80, 80, 80, 0.35);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
}
|
}
|
||||||
.content-box {
|
.content-box {
|
||||||
background-color: #EBEBEB;
|
background-color: #EBEBEB;
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
padding: 2.5em 3em;
|
padding: 2.5em 3em;
|
||||||
margin: 1em;
|
margin: 2.5em;
|
||||||
max-width: 820px;
|
max-width: 820px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
@ -74,14 +90,17 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
.settings {
|
.code-block {
|
||||||
background: #F5F5F5;
|
background: #F5F5F5;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border: 1px solid #D0D0D0;
|
border: 1px solid #D0D0D0;
|
||||||
margin: 0.75em 0;
|
margin: 0.75em 0;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.settings code {
|
.code-block pre {
|
||||||
|
margin: 0;
|
||||||
|
white-space: pre-wrap;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
}
|
}
|
||||||
@ -97,6 +116,13 @@
|
|||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
.code-block .copy-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.75em;
|
||||||
|
right: 0.75em;
|
||||||
|
padding: 0.4em 0.75em;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -106,7 +132,7 @@
|
|||||||
color: #000000;
|
color: #000000;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.75em 1.5em;
|
padding: 0.75em 1.5em;
|
||||||
border-radius: 15px;
|
border-radius: 999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -122,8 +148,81 @@
|
|||||||
.community-tools li {
|
.community-tools li {
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
.note {
|
||||||
|
background: #F5F5F5;
|
||||||
|
border-left: 4px solid #67EA94;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.75em 1em;
|
||||||
|
margin: 0.75em 0 0.5em;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
background-color: #272727;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
margin: -2.5em -3em 1.5em -3em;
|
||||||
|
padding: 2em 3em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.page-header img {
|
||||||
|
width: 300px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.page-header span {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 19px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
.back-link {
|
.back-link {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.back-link::before {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2.5L3.5 6L8 9.5'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
a[target="_blank"]::after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
vertical-align: middle;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5L8.5 3.5M5 3.5h3.5V7'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
opacity: 0.4;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.btn[target="_blank"]::after,
|
||||||
|
.copy-btn::after,
|
||||||
|
.site-footer a::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.site-footer {
|
||||||
|
margin-top: 2em;
|
||||||
|
padding-top: 2em;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #2C2D3C;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.site-footer a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.site-footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
body {
|
body {
|
||||||
@ -132,11 +231,19 @@
|
|||||||
.content-box {
|
.content-box {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -2em -2em 1.5em -2em;
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.content-box {
|
.content-box {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
}
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -1.5em -1.5em 1.5em -1.5em;
|
||||||
|
padding: 1.5em;
|
||||||
|
}
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
@ -149,8 +256,25 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="overlay"></div>
|
<div class="overlay"></div>
|
||||||
<div class="content-box">
|
<div class="content-box">
|
||||||
|
<div class="page-header-bg">
|
||||||
|
<a href="index.html" class="page-header">
|
||||||
|
<img src="logo_sm.png" alt="CT Mesh" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<h1>Meshtastic Resources</h1>
|
<h1>Meshtastic Resources</h1>
|
||||||
|
|
||||||
|
<h2>Community-run Web Tools</h2>
|
||||||
|
<div class="community-tools">
|
||||||
|
<p><em>These tools use data reported to our MQTT server by nodes across the state.</em></p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://map.ctmesh.org/?lat=41.6558113360196&lng=287.3377990722657&zoom=10" target="_blank">Meshtastic Map</a> - live map of Meshtastic nodes CT Mesh has heard</li>
|
||||||
|
<li><a href="https://meshtastic.liamcottle.net/?lat=26.58852714730864&lng=285.11718750000006&zoom=2" target="_blank">Global Map</a> - Meshtastic nodes around the world</li>
|
||||||
|
<li><a href="https://malla.ctmesh.org/" target="_blank">Malla</a> - deeper packet-level metrics and mesh performance insights fed from MQTT</li>
|
||||||
|
<li><a href="https://potato.ctmesh.org/" target="_blank">PotatoMesh</a> <strong>NEW!</strong> - packet, chat, node list, and map fed from RF on Box Mountain</li>
|
||||||
|
<li><a href="https://meshinfo.ctmesh.org/" target="_blank">MeshInfo</a> <em>legacy, partially broken</em> - MQTT gateway setup info, secondary map, graphs, message history, etc.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Mesh Channels</h2>
|
<h2>Mesh Channels</h2>
|
||||||
<h3>Default (Primary) Channel</h3>
|
<h3>Default (Primary) Channel</h3>
|
||||||
<p><em>Most CT chatter occurs on the default LongFast channel.</em></p>
|
<p><em>Most CT chatter occurs on the default LongFast channel.</em></p>
|
||||||
@ -167,40 +291,32 @@
|
|||||||
<p>Our MQTT broker is <em>uplink-only</em> and designed for fixed nodes across the state to serve as gateway nodes. Its purpose is not to bridge gaps or extend mesh coverage, but to report local traffic to our own <a href="https://map.ctmesh.org" target="_blank">map</a> and other web-based tools for analytical data and metrics to assess the mesh's performance. <strong>This role is best suited for stable, well-placed nodes with reliable coverage.</strong> If that describes your setup, follow the steps at on <a href="https://meshinfo.ctmesh.org/" target="_blank">this page</a> to get set up.</p>
|
<p>Our MQTT broker is <em>uplink-only</em> and designed for fixed nodes across the state to serve as gateway nodes. Its purpose is not to bridge gaps or extend mesh coverage, but to report local traffic to our own <a href="https://map.ctmesh.org" target="_blank">map</a> and other web-based tools for analytical data and metrics to assess the mesh's performance. <strong>This role is best suited for stable, well-placed nodes with reliable coverage.</strong> If that describes your setup, follow the steps at on <a href="https://meshinfo.ctmesh.org/" target="_blank">this page</a> to get set up.</p>
|
||||||
|
|
||||||
<h3>Key Settings</h3>
|
<h3>Key Settings</h3>
|
||||||
<div class="settings">
|
<div class="code-block">
|
||||||
<p>MQTT > Enabled > ON</p>
|
<pre id="meshtastic-mqtt">MQTT > Enabled > ON
|
||||||
<p>MQTT > Encryption Enabled > ON</p>
|
MQTT > Encryption Enabled > ON
|
||||||
<p>MQTT > Map Report > OFF</p>
|
MQTT > Map Report > OFF
|
||||||
<p>MQTT > Root Topic > <code>msh/US/CT</code></p>
|
MQTT > Root Topic > msh/US/CT
|
||||||
<p>MQTT > Address > <code>mqtt.ctmesh.org</code></p>
|
MQTT > Address > mqtt.ctmesh.org
|
||||||
<p>MQTT > Username > <code>meshdev</code></p>
|
MQTT > Username > meshdev
|
||||||
<p>MQTT > Password > <code>large4cats</code></p>
|
MQTT > Password > large4cats
|
||||||
<p>MQTT > TLS Enabled > OFF</p>
|
MQTT > TLS Enabled > OFF
|
||||||
<p>Channels > Primary Channel > Positions Enabled > ON</p>
|
Channels > Primary Channel > Positions Enabled > ON
|
||||||
<p>Channels > Primary Channel > Approximate Location > (set as desired)</p>
|
Channels > Primary Channel > Approximate Location > (set as desired)
|
||||||
<p>Channels > Primary Channel > MQTT Uplink > ON</p>
|
Channels > Primary Channel > MQTT Uplink > ON
|
||||||
<p>Channels > Primary Channel > MQTT Downlink > OFF</p>
|
Channels > Primary Channel > MQTT Downlink > OFF
|
||||||
<p>Settings > Modules > Neighbor Info > ON</p>
|
Settings > Modules > Neighbor Info > ON
|
||||||
<p>LoRa > Ok to MQTT > ON</p>
|
LoRa > Ok to MQTT > ON</pre>
|
||||||
</div>
|
|
||||||
|
|
||||||
<p><strong>Note:</strong> CT Mesh's MQTT server is bridged and uplinks to the MQTT servers for both <a href="https://meshtastic.liamcottle.net" target="_blank">meshtastic.liamcottle.net</a> and <a href="https://meshmap.net" target="_blank">meshmap.net</a>.</p>
|
|
||||||
|
|
||||||
<h2>Community-run Web Tools</h2>
|
|
||||||
<div class="community-tools">
|
|
||||||
<p><em>These tools use data reported to our MQTT server by nodes across the state.</em></p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://map.ctmesh.org/?lat=41.6558113360196&lng=287.3377990722657&zoom=10" target="_blank">Meshtastic Map</a> - live map of Meshtastic nodes CT Mesh has heard</li>
|
|
||||||
<li><a href="https://malla.ctmesh.org/" target="_blank">Malla</a> - deeper packet-level metrics and mesh performance insights fed from MQTT</li>
|
|
||||||
<li><a href="https://potato.ctmesh.org/" target="_blank">PotatoMesh</a> <strong>NEW!</strong> - packet, chat, node list, and map fed from RF on Box Mountain</li>
|
|
||||||
<li><a href="https://meshinfo.ctmesh.org/" target="_blank">MeshInfo</a> <em>legacy, partially broken</em> - MQTT gateway setup info, secondary map, graphs, message history, etc.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="note"><strong>Note:</strong> CT Mesh's MQTT server is bridged and uplinks to the MQTT servers for both <a href="https://meshtastic.liamcottle.net" target="_blank">meshtastic.liamcottle.net</a> and <a href="https://meshmap.net" target="_blank">meshmap.net</a></div>
|
||||||
|
|
||||||
<h2>Infrastructure Nodes</h2>
|
<h2>Infrastructure Nodes</h2>
|
||||||
<p><strong>Important:</strong> Infrastructure roles like <code>ROUTER</code>, <code>REPEATER</code>, <code>ROUTER_CLIENT</code>, or <code>ROUTER_LATE</code> are rarely appropriate. Unless your node is sitting on top of one of the tallest buildings in Hartford with clear line-of-sight across the region, using these roles will hurt more than help. For almost everyone, the correct choice is <code>CLIENT</code>. If you think you've got a node that truly warrants an infrastructure role, reach out first - we'd rather make sure it benefits the mesh than inadvertently weakens it.</p>
|
<p><strong>Important:</strong> Infrastructure roles like <code>ROUTER</code>, <code>REPEATER</code>, <code>ROUTER_CLIENT</code>, or <code>ROUTER_LATE</code> are rarely appropriate. Unless your node is sitting on top of one of the tallest buildings in Hartford with clear line-of-sight across the region, using these roles will hurt more than help. For almost everyone, the correct choice is <code>CLIENT</code>. If you think you've got a node that truly warrants an infrastructure role, reach out first - we'd rather make sure it benefits the mesh than inadvertently weakens it.</p>
|
||||||
|
|
||||||
<a class="btn back-link" href="index.html">Back to CT Mesh</a>
|
<a class="btn back-link" href="index.html">Back to CT Mesh</a>
|
||||||
|
<footer class="site-footer">
|
||||||
|
<p><a href="https://ctmesh.org/">CT Mesh</a> is a volunteer-run user group for mesh technology enthusiasts in Connecticut.</p>
|
||||||
|
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Content licensed CC BY-SA 4.0</a></p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const copyButtons = document.querySelectorAll("[data-copy-target]");
|
const copyButtons = document.querySelectorAll("[data-copy-target]");
|
||||||
339
why-run-a-node.html
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||||
|
<title>Why Run a Mesh Node? | CT Mesh</title>
|
||||||
|
<meta name="description" content="Learn how running a local MeshCore node helps your community with off-grid communication, emergency resilience, and private encrypted messaging.">
|
||||||
|
<link rel="shortcut icon" type="image/x-icon" href="favicon.png?3">
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png?3">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
background-color: #272727;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #2C2D3C;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2em 0;
|
||||||
|
}
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('background.svg') no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
filter: invert(1) brightness(0.85);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
a,
|
||||||
|
a:visited {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
.overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(80, 80, 80, 0.35);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
.content-box {
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
border-radius: 30px;
|
||||||
|
padding: 2.5em 3em;
|
||||||
|
margin: 2.5em;
|
||||||
|
max-width: 820px;
|
||||||
|
width: 90%;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
.page-title {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin-top: 1.25em;
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.subtitle {
|
||||||
|
margin-top: -0.25em;
|
||||||
|
font-size: 1.05em;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1F2230;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
margin: 0.5em 0 0.5em 1.25em;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.note {
|
||||||
|
background: #F5F5F5;
|
||||||
|
border-left: 4px solid #67EA94;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.75em 1em;
|
||||||
|
margin: 0.75em 0 0.5em;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
background-color: #67EA94;
|
||||||
|
color: #000000;
|
||||||
|
border: none;
|
||||||
|
padding: 0.75em 1.5em;
|
||||||
|
border-radius: 999px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
.btn-secondary,
|
||||||
|
.btn-secondary:visited {
|
||||||
|
background-color: #2B3A4E;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.btn-discord,
|
||||||
|
.btn-discord:visited {
|
||||||
|
background-color: #5865F2;
|
||||||
|
color: #ffffff;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.btn-discord img {
|
||||||
|
filter: brightness(0) invert(1);
|
||||||
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
background-color: #272727;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
margin: -2.5em -3em 1.5em -3em;
|
||||||
|
padding: 2em 3em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.page-header img {
|
||||||
|
width: 300px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.page-header span {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 19px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
.button-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.75em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.back-link {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.back-link::before {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2.5L3.5 6L8 9.5'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
a[target="_blank"]::after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
vertical-align: middle;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5L8.5 3.5M5 3.5h3.5V7'/%3E%3C/svg%3E") no-repeat center;
|
||||||
|
background-size: contain;
|
||||||
|
opacity: 0.4;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.btn[target="_blank"]::after,
|
||||||
|
.site-footer a::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.site-footer {
|
||||||
|
margin-top: 2em;
|
||||||
|
padding-top: 2em;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #2C2D3C;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.site-footer a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.site-footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
body {
|
||||||
|
padding-top: calc(env(safe-area-inset-top, 1em));
|
||||||
|
}
|
||||||
|
.content-box {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -2em -2em 1.5em -2em;
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.content-box {
|
||||||
|
padding: 1.5em;
|
||||||
|
}
|
||||||
|
.page-header-bg {
|
||||||
|
margin: -1.5em -1.5em 1.5em -1.5em;
|
||||||
|
padding: 1.5em;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="overlay"></div>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="page-header-bg">
|
||||||
|
<a href="index.html" class="page-header">
|
||||||
|
<img src="logo_sm.png" alt="CT Mesh" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 class="page-title">Why Run a Mesh Node?</h1>
|
||||||
|
<p class="subtitle">Learn about the mesh!</p>
|
||||||
|
<p>A local node is more than a gadget. It strengthens community communication by adding coverage, redundancy, and local routing for everyone nearby.</p>
|
||||||
|
|
||||||
|
<h2>How the Public Benefits</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Resilient network without internet or cellular dependency:</strong> Nodes route locally by radio and create alternate paths, so communication can continue even when phone or ISP backbones are unavailable.</li>
|
||||||
|
<li><strong>Emergency communication:</strong> During outages or disasters, local radio links can keep basic coordination available.</li>
|
||||||
|
<li><strong>Flexible encrypted communications:</strong> Mesh platforms support public channels for open community traffic, private encrypted channels for groups, and private encrypted direct messages between individuals.</li>
|
||||||
|
<li><strong>Accessible mobile apps:</strong> Both iPhone and Android users can manage nodes and messaging from their phones, using Bluetooth to communicate with the radios.</li>
|
||||||
|
<li><strong>Affordable hardware:</strong> Many compatible devices are commonly available for under $100.</li>
|
||||||
|
<li><strong>No operator license required (USA):</strong> On 915 MHz ISM, operation under 1W does not require an amateur radio license, and this is typically plenty of power for local mesh use.</li>
|
||||||
|
<li><strong>Easy onboarding:</strong> Pairing a node, loading channels, and joining local community resources is straightforward for new users.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Solar and Off-Grid Operation</h2>
|
||||||
|
<p>Many fixed mesh repeater nodes can run from small solar systems and batteries, with no grid connection required. That means:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Improved resilience</strong> because communication infrastructure can remain active during grid disruptions</li>
|
||||||
|
<li><strong>Install options beyond existing infrastructure</strong>, including remote locations with clear line-of-sight and reliable sun exposure</li>
|
||||||
|
<li><strong>No additional household electric cost</strong> for grid power at the node site</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Why Ham Radio Operators Often Love Mesh</h2>
|
||||||
|
<ul>
|
||||||
|
<li>It combines RF experimentation, antenna work, and practical local service.</li>
|
||||||
|
<li>It rewards good station design: Elevation, feedline quality, power planning, and interference control.</li>
|
||||||
|
<li>It offers an always-on local network that can complement other emergency and community communication practices.</li>
|
||||||
|
<li>These communities represent some of the largest mesh networks in the world: Over 21,000 MeshCore nodes globally (including about 14,000 repeaters) and over 32,000 Meshtastic nodes worldwide, with adoption levels comparable to APRS and major amateur IP mesh networks in Europe.</li>
|
||||||
|
</ul>
|
||||||
|
<h1>Getting Involved</h1>
|
||||||
|
<p>Most users only need a companion/client device. If you want to expand mesh coverage in your area, build a repeater/router node. In MeshCore, a <strong>repeater</strong> is a fixed station that stays in place to relay traffic for the mesh, while a <strong>companion</strong> is a personal device that travels with you for day-to-day messaging. Meshtastic follows a similar pattern with <strong>routers</strong> (fixed relay-focused nodes) and <strong>clients</strong> (user-focused mobile/personal nodes). Contact us on Discord if you want help building or operating a repeater.</p>
|
||||||
|
|
||||||
|
<h2>Recommended Hardware</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Heltec LoRa 32 V4</strong> - popular low-cost option and a common first node. Typical price: <strong>$25-$35</strong>.</li>
|
||||||
|
<li><strong>LILYGO T-Echo</strong> - portable handheld form factor with an integrated display and battery support. Typical price: <strong>$40-$80</strong> depending on configuration.</li>
|
||||||
|
<li><strong>RAK4631 Development Board</strong> - a common choice for reliable fixed installations with low-power operation and flexible deployment options. Typical combined core + base price: <strong>$30-$45</strong>.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Typical Installation Locations</h2>
|
||||||
|
<p>Fixed nodes in strong locations often improve neighborhood coverage for many nearby users, not just the node owner, and even modest elevation can make a big difference. For example, an upstairs attic-window repeater can significantly improve in-home and neighborhood reception, and a few extra feet of height can meaningfully improve overall mesh performance.</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Indoor locations:</strong> Attic or top-floor window positions with clear line-of-sight.</li>
|
||||||
|
<li><strong>Outdoor home locations:</strong> Rooftop mast or chimney mount, balcony rail, garage or shed roof, fences, trees, and old over-the-air TV antenna roof mounts.</li>
|
||||||
|
<li><strong>Hosted or remote sites:</strong> Hilltop, tower, or shared hosted locations with sun exposure for solar operation, including off-grid sites with no utility infrastructure.</li>
|
||||||
|
<li><strong>Mobile deployments:</strong> Vehicle-based nodes for mapping and temporary event coverage.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="note"><strong>Safety Note:</strong> Use a spotter when working on a ladder or on a roof.</div>
|
||||||
|
|
||||||
|
<h2>Meshtastic vs MeshCore in CT Mesh</h2>
|
||||||
|
<p>Both platforms are still useful, and many members experiment with both. In the CT Mesh fixed-node community, Meshtastic has gradually been replaced in many deployments by MeshCore as operators have seen stronger day-to-day reliability and broader platform functionality from current MeshCore firmware.</p>
|
||||||
|
<p>If you are starting fresh and your goal is reliable fixed-node service, MeshCore is often the first recommendation from local operators.</p>
|
||||||
|
|
||||||
|
<h1>Learn More</h1>
|
||||||
|
<p>Start with our local guides, then review official project docs and community channels to choose the right platform for your goals.</p>
|
||||||
|
<div class="button-row">
|
||||||
|
<a class="btn btn-secondary" href="meshcore-resources.html">MeshCore Guides & Tools</a>
|
||||||
|
<a class="btn btn-secondary" href="https://meshcore.co.uk/" target="_blank">Official MeshCore Site</a>
|
||||||
|
</div>
|
||||||
|
<div class="button-row">
|
||||||
|
<a class="btn" href="meshtastic-resources.html">Meshtastic Guides & Tools</a>
|
||||||
|
<a class="btn" href="https://meshtastic.org/" target="_blank">Official Meshtastic Site</a>
|
||||||
|
</div>
|
||||||
|
<div class="button-row">
|
||||||
|
<a class="btn btn-discord" href="https://ctmesh.org/discord" target="_blank">Join CT Mesh Discord</a>
|
||||||
|
</div>
|
||||||
|
<div class="button-row">
|
||||||
|
<a class="btn btn-secondary back-link" href="index.html">Back to CT Mesh</a>
|
||||||
|
</div>
|
||||||
|
<footer class="site-footer">
|
||||||
|
<p><a href="https://ctmesh.org/">CT Mesh</a> is a volunteer-run user group for mesh technology enthusiasts in Connecticut.</p>
|
||||||
|
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">Content licensed CC BY-SA 4.0</a></p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||