[DOCS] Migrate documentation from VuePress 1.x to VitePress (#2299)

- Replace VuePress 1.9.10 with VitePress 1.6.4
- Convert config from CommonJS to ESM TypeScript (config.mts)
- Convert shared Theengs nav config to ESM (commonConfig.mts)
- Rewrite BoardEnvironmentTable in Vue 3 Composition API
- Rewrite FlashEnvironmentSelector in Vue 3 Composition API
- Enable built-in local search and dark mode
- Add medium-zoom for image zoom
- Use VitePress CSS variables for dark mode compatibility
- Update CI script paths from .vuepress to .vitepress
- Update .gitignore for VitePress build artifacts
- Rename README.md files to index.md (VitePress convention)
- Fix markdown compatibility (angle-bracket escaping, image paths)
- Drop PWA plugin (not needed)

Co-authored-by: Florian <1technophile@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-03-30 07:00:20 -05:00
1 parent 600d48dc48
commit 8273617c17
33 files changed
+4212 -28476

No files matched your search

+8 -6
View File
@@ -24,11 +24,11 @@ managed_components
.github/*instructions.md .github/*instructions.md
.github/workflows/_docs .github/workflows/_docs
# CI/CD Generated outputs # CI/CD Generated outputs
docs/.vuepress/dist/ docs/.vitepress/dist/
docs/.vuepress/public/boards-info.json docs/.vitepress/cache/
docs/.vuepress/public/commonConfig.js docs/.vitepress/public/boards-info.json
docs/.vuepress/public/firmware_build docs/.vitepress/public/commonConfig.js
docs/.vitepress/public/firmware_build
# Generated site/firmware/reports files # Generated site/firmware/reports files
generated/ generated/
@@ -41,8 +41,10 @@ scripts/latest_version.json
scripts/latest_version_dev.json scripts/latest_version_dev.json
# Generated configuration files # Generated configuration files
docs/.vuepress/meta.json docs/.vitepress/meta.json
# Generated full documentation pages # Generated full documentation pages
docs/prerequisites/board-full.md docs/prerequisites/board-full.md
docs/upload/web-install-full.md docs/upload/web-install-full.md
.superpowers/
docs/superpowers/
+41
View File
@@ -0,0 +1,41 @@
// docs/.vitepress/commonConfig.mts
// Adapter that loads the shared Theengs commonConfig.js (CommonJS) downloaded
// by CI from https://www.theengs.io/commonConfig.js, and re-exports the nav
// and head arrays in a format VitePress can consume.
//
// This keeps theengs.io as the single source of truth for nav/head until all
// Theengs docs sites are migrated to VitePress.
import { createRequire } from 'module'
import { existsSync } from 'fs'
import { resolve, dirname } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const require = createRequire(import.meta.url)
const commonConfigPath = resolve(__dirname, 'public/commonConfig.js')
let sharedConfig: any = null
if (existsSync(commonConfigPath)) {
sharedConfig = require(commonConfigPath)
} else {
console.warn(
'commonConfig.js not found in .vitepress/public/. ' +
'Using fallback nav/head. Run CI or download from https://www.theengs.io/commonConfig.js'
)
}
// Re-export nav from shared config, or use a minimal fallback
export const commonNav = sharedConfig?.themeConfig?.nav ?? [
{ text: 'Home', link: 'https://www.theengs.io' },
{ text: 'Community', link: 'https://community.openmqttgateway.com' },
{ text: 'Shop', link: 'https://shop.theengs.io/' }
]
// Re-export head from shared config, or use a minimal fallback
export const commonHead = sharedConfig?.head ?? [
['meta', { name: 'viewport', content: 'width=device-width, initial-scale=1' }],
['meta', { name: 'theme-color', content: '#3eaf7c' }]
]
@@ -77,9 +77,9 @@
:key="board.environment" :key="board.environment"
class="board-card" class="board-card"
@click="openSelector(board.environment)"> @click="openSelector(board.environment)">
<div class="board-card__image"> <div class="board-card__image">
<span v-if="popularEnvironments.indexOf(board.environment) !== -1" class="popular-badge">Popular</span> <span v-if="popularEnvironments.includes(board.environment)" class="popular-badge">Popular</span>
<img <img
:src="getBoardImageUrl(board)" :src="getBoardImageUrl(board)"
:alt="board.environment" :alt="board.environment"
@@ -112,18 +112,18 @@
<svg :class="{rotated: expandedModules[board.environment]}" width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg> <svg :class="{rotated: expandedModules[board.environment]}" width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg>
</span> </span>
</div> </div>
<transition name="expand-fade"> <Transition name="expand-fade">
<div class="libraries-badges" <div class="libraries-badges"
:style="expandedModules[board.environment] ? '' : 'max-height: 2.2em; overflow: hidden;'"> :style="expandedModules[board.environment] ? '' : 'max-height: 2.2em; overflow: hidden;'">
<span <span
v-for="(mod, index) in board.modules" v-for="(mod, index) in board.modules"
:key="index" :key="index"
class="lib-badge"> class="lib-badge">
{{ mod }} {{ mod }}
</span> </span>
</div> </div>
</transition> </Transition>
</div> </div>
<!-- Libraries Section with expand/collapse --> <!-- Libraries Section with expand/collapse -->
@@ -137,20 +137,20 @@
:title="expandedLibraries[board.environment] ? 'Hide' : 'Show all'"> :title="expandedLibraries[board.environment] ? 'Hide' : 'Show all'">
<svg :class="{rotated: expandedLibraries[board.environment]}" width="19" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg> <svg :class="{rotated: expandedLibraries[board.environment]}" width="19" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg>
</span> </span>
</div> </div>
<transition name="expand-fade"> <Transition name="expand-fade">
<div class="libraries-badges" <div class="libraries-badges"
:style="expandedLibraries[board.environment] ? '' : 'max-height: 2.2em; overflow: hidden;'"> :style="expandedLibraries[board.environment] ? '' : 'max-height: 2.2em; overflow: hidden;'">
<span <span
v-for="(lib, index) in board.libraries" v-for="(lib, index) in board.libraries"
:key="index" :key="index"
class="lib-badge"> class="lib-badge">
{{ lib }} {{ lib }}
</span> </span>
</div> </div>
</transition> </Transition>
</div> </div>
<div class="board-card__action"> <div class="board-card__action">
@@ -163,190 +163,202 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
export default { import { ref, reactive, computed, onMounted } from 'vue'
name: 'BoardEnvironmentTable',
props: { interface Board {
boardsUrl: { environment: string
type: String, description?: string
default: '/boards-info.json' microcontroller?: string
}, modules?: string[]
selectorPath: { libraries?: string[]
type: String, customImg?: string
default: '/upload/board-selector.html' CustomImg?: string
} }
},
data() { interface GatewayFilter {
return { key: string
boards: [], label: string
loading: false, }
error: null,
expandedModules: {}, const props = withDefaults(defineProps<{
expandedLibraries: {}, boardsUrl?: string
searchQuery: '', selectorPath?: string
activeMcuFilter: null, }>(), {
activeGatewayFilter: null, boardsUrl: '/boards-info.json',
popularEnvironments: [ selectorPath: '/upload/board-selector.html'
'esp32dev-ble', })
'theengs-bridge-v11',
'lilygo-rtl_433', const boards = ref<Board[]>([])
'lilygo-rtl_433-fsk', const loading = ref(false)
'esp32dev-ir' const error = ref<string | null>(null)
] const expandedModules = reactive<Record<string, boolean>>({})
}; const expandedLibraries = reactive<Record<string, boolean>>({})
}, const searchQuery = ref('')
computed: { const activeMcuFilter = ref<string | null>(null)
resolvedBoardsUrl() { const activeGatewayFilter = ref<string | null>(null)
return this.buildUrl(this.boardsUrl);
}, const popularEnvironments = [
resolvedSelectorUrl() { 'esp32dev-ble',
return this.buildUrl(this.selectorPath); 'theengs-bridge-v11',
}, 'lilygo-rtl_433',
mcuFilters() { 'lilygo-rtl_433-fsk',
var families = {}; 'esp32dev-ir'
this.boards.forEach(function(b) { ]
var family = this.getMcuFamily(b.microcontroller);
if (family) families[family] = true; function buildUrl(path: string): string {
}.bind(this)); const base = import.meta.env.BASE_URL || '/'
return Object.keys(families).sort(); const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base
}, const cleanPath = path.startsWith('/') ? path : `/${path}`
gatewayFilters() { return `${cleanBase}${cleanPath}`
var gateways = { }
BT: 'BLE',
RF: 'RF', const resolvedBoardsUrl = computed(() => buildUrl(props.boardsUrl))
IR: 'IR', const resolvedSelectorUrl = computed(() => buildUrl(props.selectorPath))
LORA: 'LoRa',
RTL_433: 'RTL_433', function getMcuFamily(mcu: string | undefined): string | null {
Pilight: 'Pilight' if (!mcu) return null
}; const m = mcu.toLowerCase()
var result = []; if (m.includes('esp32-s3') || m.includes('esp32s3') || m.includes('atoms3') || m.includes('lilygo-t3-s3')) return 'ESP32-S3'
var self = this; if (m.includes('esp32-c3') || m.includes('esp32c3') || m.includes('lolin_c3') || m.includes('airm2m')) return 'ESP32-C3'
Object.keys(gateways).forEach(function(key) { if (m.includes('esp32') || m.includes('m5st') || m.includes('heltec') || m.includes('ttgo') || m.includes('lolin32') || m.includes('pico32') || m.includes('tinypico') || m.includes('feather')) return 'ESP32'
var hasBoards = self.boards.some(function(b) { if (m.includes('esp8') || m.includes('nodemcu')) return 'ESP8266'
return Array.isArray(b.modules) && b.modules.some(function(m) { return 'Other'
return m.toLowerCase().indexOf(key.toLowerCase()) !== -1; }
});
}); const mcuFilters = computed<string[]>(() => {
if (hasBoards) { const families: Record<string, boolean> = {}
result.push({ key: key, label: gateways[key] }); boards.value.forEach(b => {
} const family = getMcuFamily(b.microcontroller)
}); if (family) families[family] = true
return result; })
}, return Object.keys(families).sort()
hasActiveFilters() { })
return this.searchQuery || this.activeMcuFilter || this.activeGatewayFilter;
}, const gatewayFilters = computed<GatewayFilter[]>(() => {
filteredBoards() { const gateways: Record<string, string> = {
var self = this; BT: 'BLE',
return this.boards.filter(function(board) { RF: 'RF',
if (self.searchQuery) { IR: 'IR',
var q = self.searchQuery.toLowerCase(); LORA: 'LoRa',
var haystack = [ RTL_433: 'RTL_433',
board.environment, Pilight: 'Pilight'
board.description || '',
board.microcontroller || '',
(board.modules || []).join(' ')
].join(' ').toLowerCase();
if (haystack.indexOf(q) === -1) return false;
}
if (self.activeMcuFilter) {
var family = self.getMcuFamily(board.microcontroller);
if (family !== self.activeMcuFilter) return false;
}
if (self.activeGatewayFilter) {
var key = self.activeGatewayFilter.toLowerCase();
if (!Array.isArray(board.modules) || !board.modules.some(function(m) {
return m.toLowerCase().indexOf(key) !== -1;
})) return false;
}
return true;
});
}
},
methods: {
getMcuFamily(mcu) {
if (!mcu) return null;
var m = mcu.toLowerCase();
if (m.indexOf('esp32-s3') !== -1 || m.indexOf('esp32s3') !== -1 || m.indexOf('atoms3') !== -1 || m.indexOf('lilygo-t3-s3') !== -1) return 'ESP32-S3';
if (m.indexOf('esp32-c3') !== -1 || m.indexOf('esp32c3') !== -1 || m.indexOf('lolin_c3') !== -1 || m.indexOf('airm2m') !== -1) return 'ESP32-C3';
if (m.indexOf('esp32') !== -1 || m.indexOf('m5st') !== -1 || m.indexOf('heltec') !== -1 || m.indexOf('ttgo') !== -1 || m.indexOf('lolin32') !== -1 || m.indexOf('pico32') !== -1 || m.indexOf('tinypico') !== -1 || m.indexOf('feather') !== -1) return 'ESP32';
if (m.indexOf('esp8') !== -1 || m.indexOf('nodemcu') !== -1) return 'ESP8266';
return 'Other';
},
toggleMcuFilter(mcu) {
this.activeMcuFilter = this.activeMcuFilter === mcu ? null : mcu;
},
toggleGatewayFilter(gw) {
this.activeGatewayFilter = this.activeGatewayFilter === gw ? null : gw;
},
clearFilters() {
this.searchQuery = '';
this.activeMcuFilter = null;
this.activeGatewayFilter = null;
},
buildUrl(path) {
const base = this.$site?.base || '/';
const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;
const cleanPath = path.startsWith('/') ? path : `/${path}`;
return `${cleanBase}${cleanPath}`;
},
async loadBoards() {
this.loading = true;
this.error = null;
try {
const response = await fetch(this.resolvedBoardsUrl);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (!Array.isArray(data)) {
throw new Error('boards-info.json must be an array');
}
var self = this;
this.boards = data
.filter(board => board && typeof board.environment === 'string')
.sort(function(a, b) {
var aPopular = self.popularEnvironments.indexOf(a.environment) !== -1;
var bPopular = self.popularEnvironments.indexOf(b.environment) !== -1;
if (aPopular && !bPopular) return -1;
if (!aPopular && bPopular) return 1;
return a.environment.localeCompare(b.environment);
});
} catch (err) {
console.error('Failed to load boards-info:', err);
this.error = err.message || 'Unable to load board information';
} finally {
this.loading = false;
}
},
toggleModules(env) {
this.$set(this.expandedModules, env, !this.expandedModules[env]);
},
toggleLibraries(env) {
this.$set(this.expandedLibraries, env, !this.expandedLibraries[env]);
},
openSelector(environment) {
if (!environment) return;
const url = `${this.resolvedSelectorUrl}?env=${encodeURIComponent(environment)}`;
window.location.href = url;
},
getBoardImageUrl(board) {
const customImg = board.customImg || board.CustomImg;
if (customImg) {
// If it's an absolute URL, use it as-is
if (customImg.startsWith('http')) {
return customImg;
}
// Otherwise, build the URL with site base
return this.buildUrl(customImg);
}
return this.buildUrl('/img/microcontroller.gif');
}
},
mounted() {
this.loadBoards();
} }
}; const result: GatewayFilter[] = []
Object.keys(gateways).forEach(key => {
const hasBoards = boards.value.some(b =>
Array.isArray(b.modules) && b.modules.some(m =>
m.toLowerCase().includes(key.toLowerCase())
)
)
if (hasBoards) {
result.push({ key, label: gateways[key] })
}
})
return result
})
const hasActiveFilters = computed(() =>
searchQuery.value || activeMcuFilter.value || activeGatewayFilter.value
)
const filteredBoards = computed<Board[]>(() =>
boards.value.filter(board => {
if (searchQuery.value) {
const q = searchQuery.value.toLowerCase()
const haystack = [
board.environment,
board.description || '',
board.microcontroller || '',
(board.modules || []).join(' ')
].join(' ').toLowerCase()
if (!haystack.includes(q)) return false
}
if (activeMcuFilter.value) {
const family = getMcuFamily(board.microcontroller)
if (family !== activeMcuFilter.value) return false
}
if (activeGatewayFilter.value) {
const key = activeGatewayFilter.value.toLowerCase()
if (!Array.isArray(board.modules) || !board.modules.some(m =>
m.toLowerCase().includes(key)
)) return false
}
return true
})
)
function toggleMcuFilter(mcu: string) {
activeMcuFilter.value = activeMcuFilter.value === mcu ? null : mcu
}
function toggleGatewayFilter(gw: string) {
activeGatewayFilter.value = activeGatewayFilter.value === gw ? null : gw
}
function clearFilters() {
searchQuery.value = ''
activeMcuFilter.value = null
activeGatewayFilter.value = null
}
async function loadBoards() {
loading.value = true
error.value = null
try {
const response = await fetch(resolvedBoardsUrl.value)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
const data = await response.json()
if (!Array.isArray(data)) {
throw new Error('boards-info.json must be an array')
}
boards.value = data
.filter((board: Board) => board && typeof board.environment === 'string')
.sort((a: Board, b: Board) => {
const aPopular = popularEnvironments.includes(a.environment)
const bPopular = popularEnvironments.includes(b.environment)
if (aPopular && !bPopular) return -1
if (!aPopular && bPopular) return 1
return a.environment.localeCompare(b.environment)
})
} catch (err: unknown) {
console.error('Failed to load boards-info:', err)
error.value = err instanceof Error ? err.message : 'Unable to load board information'
} finally {
loading.value = false
}
}
function toggleModules(env: string) {
expandedModules[env] = !expandedModules[env]
}
function toggleLibraries(env: string) {
expandedLibraries[env] = !expandedLibraries[env]
}
function openSelector(environment: string) {
if (!environment) return
const url = `${resolvedSelectorUrl.value}?env=${encodeURIComponent(environment)}`
window.location.href = url
}
function getBoardImageUrl(board: Board): string {
const customImg = board.customImg || board.CustomImg
if (customImg) {
if (customImg.startsWith('http')) {
return customImg
}
return buildUrl(customImg)
}
return buildUrl('/img/microcontroller.gif')
}
onMounted(() => {
loadBoards()
})
</script> </script>
<style scoped> <style scoped>
@@ -371,29 +383,29 @@ export default {
.search-icon { .search-icon {
position: absolute; position: absolute;
left: 12px; left: 12px;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
pointer-events: none; pointer-events: none;
} }
.search-input { .search-input {
width: 100%; width: 100%;
padding: 0.6rem 2.2rem 0.6rem 2.4rem; padding: 0.6rem 2.2rem 0.6rem 2.4rem;
border: 1px solid var(--border-color, #eaecef); border: 1px solid var(--vp-c-divider);
border-radius: 8px; border-radius: 8px;
font-size: 0.9rem; font-size: 0.9rem;
background: #ffffff; background: var(--vp-c-bg);
color: var(--text-color, #2c3e50); color: var(--vp-c-text-1);
transition: border-color 0.2s; transition: border-color 0.2s;
} }
.search-input:focus { .search-input:focus {
outline: none; outline: none;
border-color: var(--accent-color, #3eaf7c); border-color: var(--vp-c-brand-1);
box-shadow: 0 0 0 3px rgba(62, 175, 124, 0.15); box-shadow: 0 0 0 3px rgba(62, 175, 124, 0.15);
} }
.search-input::placeholder { .search-input::placeholder {
color: var(--text-color-secondary, #999); color: var(--vp-c-text-3);
} }
.search-clear { .search-clear {
@@ -403,14 +415,14 @@ export default {
border: none; border: none;
cursor: pointer; cursor: pointer;
padding: 4px; padding: 4px;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.search-clear:hover { .search-clear:hover {
background: rgba(0, 0, 0, 0.05); background: var(--vp-c-bg-soft);
} }
.filter-groups { .filter-groups {
@@ -428,7 +440,7 @@ export default {
.filter-group__label { .filter-group__label {
font-size: 0.8rem; font-size: 0.8rem;
font-weight: 600; font-weight: 600;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
white-space: nowrap; white-space: nowrap;
} }
@@ -439,9 +451,9 @@ export default {
} }
.filter-chip { .filter-chip {
background: var(--code-bg-color, #f6f8fa); background: var(--vp-c-bg-soft);
color: var(--text-color, #2c3e50); color: var(--vp-c-text-1);
border: 1px solid var(--border-color, #eaecef); border: 1px solid var(--vp-c-divider);
padding: 0.25rem 0.7rem; padding: 0.25rem 0.7rem;
border-radius: 16px; border-radius: 16px;
font-size: 0.78rem; font-size: 0.78rem;
@@ -451,14 +463,14 @@ export default {
} }
.filter-chip:hover { .filter-chip:hover {
border-color: var(--accent-color, #3eaf7c); border-color: var(--vp-c-brand-1);
color: var(--accent-color, #3eaf7c); color: var(--vp-c-brand-1);
} }
.filter-chip--active { .filter-chip--active {
background: var(--accent-color, #3eaf7c); background: var(--vp-c-brand-1);
color: #ffffff; color: #ffffff;
border-color: var(--accent-color, #3eaf7c); border-color: var(--vp-c-brand-1);
} }
.filter-chip--active:hover { .filter-chip--active:hover {
@@ -471,13 +483,13 @@ export default {
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
font-size: 0.85rem; font-size: 0.85rem;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
} }
.filter-clear { .filter-clear {
background: none; background: none;
border: none; border: none;
color: var(--accent-color, #3eaf7c); color: var(--vp-c-brand-1);
cursor: pointer; cursor: pointer;
font-size: 0.85rem; font-size: 0.85rem;
font-weight: 500; font-weight: 500;
@@ -491,7 +503,7 @@ export default {
.no-results { .no-results {
text-align: center; text-align: center;
padding: 3rem 1rem; padding: 3rem 1rem;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
} }
.no-results p { .no-results p {
@@ -501,15 +513,15 @@ export default {
/* Grid Layout */ /* Grid Layout */
.boards-grid { .boards-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); grid-template-columns: repeat(3, 1fr);
gap: 1.5rem; gap: 1rem;
margin-top: 1.5rem; margin-top: 1.5rem;
} }
/* Card Design */ /* Card Design */
.board-card { .board-card {
background: #ffffff; background: var(--vp-c-bg);
border: 1px solid var(--border-color, #eaecef); border: 1px solid var(--vp-c-divider);
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
@@ -522,18 +534,18 @@ export default {
.board-card:hover { .board-card:hover {
transform: translateY(-4px); transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
border-color: var(--accent-color, #3eaf7c); border-color: var(--vp-c-brand-1);
} }
/* Image Section */ /* Image Section */
.board-card__image { .board-card__image {
background: var(--code-bg-color, #f6f8fa); background: var(--vp-c-bg-soft);
padding: 1.5rem; padding: 1.5rem;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 120px; min-height: 120px;
border-bottom: 1px solid var(--border-color, #eaecef); border-bottom: 1px solid var(--vp-c-divider);
position: relative; position: relative;
} }
@@ -585,22 +597,22 @@ export default {
.board-card__title code { .board-card__title code {
background: transparent; background: transparent;
color: var(--accent-color, #3eaf7c); color: var(--vp-c-brand-1);
font-size: 0.9em; font-size: 0.9em;
padding: 0; padding: 0;
font-weight: 600; font-weight: 600;
} }
.board-card__chip { .board-card__chip {
background: var(--code-bg-color, #f6f8fa); background: var(--vp-c-bg-soft);
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
padding: 0.3rem 0.8rem; padding: 0.3rem 0.8rem;
border-radius: 4px; border-radius: 4px;
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 600; font-weight: 600;
white-space: nowrap; white-space: nowrap;
flex-shrink: 0; flex-shrink: 0;
border: 1px solid var(--border-color, #eaecef); border: 1px solid var(--vp-c-divider);
} }
/* Description */ /* Description */
@@ -608,7 +620,7 @@ export default {
margin: 0; margin: 0;
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1.5; line-height: 1.5;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
} }
@@ -616,7 +628,7 @@ export default {
.board-card__libraries { .board-card__libraries {
margin-top: 0.5rem; margin-top: 0.5rem;
padding-top: 0.25rem; padding-top: 0.25rem;
border-top: 1px solid var(--border-color, #eaecef); border-top: 1px solid var(--vp-c-divider);
} }
.modules-label-row { .modules-label-row {
@@ -628,7 +640,7 @@ export default {
.libraries-label { .libraries-label {
font-size: 0.8rem; font-size: 0.8rem;
font-weight: 600; font-weight: 600;
color: var(--text-color-secondary, #666); color: var(--vp-c-text-2);
display: inline-block; display: inline-block;
} }
@@ -640,24 +652,24 @@ export default {
.lib-badge { .lib-badge {
display: inline-block; display: inline-block;
background: var(--code-bg-color, #f6f8fa); background: var(--vp-c-bg-soft);
color: var(--text-color, #2c3e50); color: var(--vp-c-text-1);
padding: 0.2rem 0.6rem; padding: 0.2rem 0.6rem;
border-radius: 4px; border-radius: 4px;
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 500; font-weight: 500;
border: 1px solid var(--border-color, #eaecef); border: 1px solid var(--vp-c-divider);
} }
/* Action Footer */ /* Action Footer */
.board-card__action { .board-card__action {
padding-top: 0.75rem; padding-top: 0.75rem;
margin-top: 0.5rem; margin-top: 0.5rem;
border-top: 1px solid var(--border-color, #eaecef); border-top: 1px solid var(--vp-c-divider);
} }
.action-text { .action-text {
color: var(--accent-color, #3eaf7c); color: var(--vp-c-brand-1);
font-size: 0.85rem; font-size: 0.85rem;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
@@ -676,7 +688,7 @@ export default {
height: 16px; height: 16px;
min-width: 16px; min-width: 16px;
border: 2px solid #cfd8dc; border: 2px solid #cfd8dc;
border-top-color: var(--accent-color, #3eaf7c); border-top-color: var(--vp-c-brand-1);
border-radius: 50%; border-radius: 50%;
animation: spin 0.8s linear infinite; animation: spin 0.8s linear infinite;
vertical-align: middle; vertical-align: middle;
@@ -702,7 +714,6 @@ export default {
.boards-grid { .boards-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 1rem;
} }
.board-card__image { .board-card__image {
@@ -730,11 +741,11 @@ export default {
.expand-fade-enter-active, .expand-fade-leave-active { .expand-fade-enter-active, .expand-fade-leave-active {
transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s; transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s;
} }
.expand-fade-enter, .expand-fade-leave-to { .expand-fade-enter-from, .expand-fade-leave-to {
opacity: 0; opacity: 0;
max-height: 0; max-height: 0;
} }
.expand-fade-enter-to, .expand-fade-leave { .expand-fade-enter-to, .expand-fade-leave-from {
opacity: 1; opacity: 1;
max-height: 500px; max-height: 500px;
} }
@@ -745,7 +756,7 @@ export default {
justify-content: center; justify-content: center;
background: none; background: none;
border: none; border: none;
color: var(--accent-color, #3eaf7c); color: var(--vp-c-brand-1);
cursor: pointer; cursor: pointer;
margin-top: 0.3em; margin-top: 0.3em;
margin-left: 0.2em; margin-left: 0.2em;
+138
View File
@@ -0,0 +1,138 @@
// docs/.vitepress/config.mts
import { defineConfig } from 'vitepress'
import { resolve, dirname } from 'path'
import { fileURLToPath } from 'url'
import { commonNav, commonHead } from './commonConfig.mts'
const __dirname = dirname(fileURLToPath(import.meta.url))
// Load metadata with override support
import defaults from './defaults.json'
let meta = { ...defaults }
try {
const overrides = await import('./meta.json')
meta = { ...meta, ...overrides.default }
} catch {
console.warn('meta.json not found or not valid. Using default configuration.')
}
export default defineConfig({
title: `${meta.title} - ${meta.version}`,
description: 'One gateway, many technologies: MQTT gateway for ESP8266 or ESP32 with bidirectional 433mhz/315mhz/868mhz, Infrared communications, BLE, LoRa, beacons detection, mi flora / mi jia / LYWSD02/ Mi Scale compatibility, SMS & LORA.',
base: meta.url_prefix as '/' | `/${string}/`,
outDir: resolve(__dirname, '../../', meta.dest),
head: commonHead,
ignoreDeadLinks: [
/localhost/,
/LoraTemperature/
],
lastUpdated: true,
markdown: {
lineNumbers: true
},
themeConfig: {
siteTitle: 'OpenMQTTGateway',
nav: commonNav,
socialLinks: [
{ icon: 'github', link: `https://github.com/${meta.theme_config_repo}` }
],
editLink: {
pattern: `https://github.com/${meta.theme_config_repo}/edit/development/docs/:path`
},
sidebar: [
{ text: '0 - What is it for', link: '/' },
{
text: '1 - Prerequisites',
collapsed: true,
items: [
{ text: 'Devices', link: '/prerequisites/devices' },
{ text: 'Board', link: '/prerequisites/board' },
{ text: 'Parts', link: '/prerequisites/parts' },
{ text: 'Broker', link: '/prerequisites/broker' },
{ text: 'Controller', link: '/prerequisites/controller' }
]
},
{
text: '2 - Set it up',
collapsed: true,
items: [
{ text: 'RF', link: '/setitup/rf' },
{ text: 'BLE', link: '/setitup/ble' },
{ text: 'IR', link: '/setitup/ir' },
{ text: 'LoRa', link: '/setitup/lora' },
{ text: 'GSM', link: '/setitup/gsm' },
{ text: 'Serial', link: '/setitup/serial' },
{ text: 'Sensors', link: '/setitup/sensors' },
{ text: 'Actuators', link: '/setitup/actuators' }
]
},
{
text: '3 - Upload',
collapsed: true,
link: '/upload/',
items: [
{ text: '(Option 1) Upload from the web', link: '/upload/web-install' },
{ text: 'Binaries', link: '/upload/binaries' },
{ text: 'Builds', link: '/upload/builds' },
{ text: 'Gitpod', link: '/upload/gitpod' },
{ text: 'Portal', link: '/upload/portal' },
{ text: 'Advanced Configuration', link: '/upload/advanced-configuration' },
{ text: 'Troubleshoot', link: '/upload/troubleshoot' }
]
},
{
text: '4 - Use',
collapsed: true,
items: [
{ text: 'RF', link: '/use/rf' },
{ text: 'BLE', link: '/use/ble' },
{ text: 'IR', link: '/use/ir' },
{ text: 'LoRa', link: '/use/lora' },
{ text: 'GSM', link: '/use/gsm' },
{ text: 'Serial', link: '/use/serial' },
{ text: 'RFM69', link: '/use/rfm69' },
{ text: 'Sensors', link: '/use/sensors' },
{ text: 'Actuators', link: '/use/actuators' },
{ text: 'Boards', link: '/use/boards' },
{ text: 'Displays', link: '/use/displays' },
{ text: 'Gateway', link: '/use/gateway' },
{ text: 'WebUI', link: '/use/webui' }
]
},
{
text: '5 - Integrate',
collapsed: true,
items: [
{ text: 'OpenHAB 2', link: '/integrate/openhab2' },
{ text: 'OpenHAB 3', link: '/integrate/openhab3' },
{ text: 'Home Assistant', link: '/integrate/home_assistant' },
{ text: 'Node-RED', link: '/integrate/node_red' },
{ text: 'AWS IoT', link: '/integrate/aws_iot' },
{ text: 'Jeedom', link: '/integrate/jeedom' }
]
},
{
text: '6 - Participate',
collapsed: true,
link: '/participate/',
items: [
{ text: 'Quick Start', link: '/participate/quick_start' },
{ text: 'Support', link: '/participate/support' },
{ text: 'Development', link: '/participate/development' },
{ text: 'Adding Protocols', link: '/participate/adding-protocols' },
{ text: 'Community', link: '/participate/community' },
{ text: 'License', link: meta.url_license_file }
]
}
],
search: {
provider: 'local'
}
},
sitemap: {
hostname: meta.hostname
},
vite: {
publicDir: '.vitepress/public'
}
})
File renamed without changes.
File renamed without changes.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 603 B

File renamed without changes.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 324 KiB

File renamed without changes.
+32
View File
@@ -0,0 +1,32 @@
/* docs/.vitepress/theme/custom.css */
/* Prevent long site title from overlapping sidebar/nav */
.VPNavBarTitle .title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Widen the entire content column on pages without aside (board/flash pages) */
.VPDoc:not(.has-aside) .content-container,
.VPDoc:not(.has-aside) .container {
max-width: 100% !important;
}
.VPDoc:not(.has-aside) .vp-doc {
max-width: 100% !important;
}
/* Gray backdrop when ESP Web Tools install dialog is open */
ewt-install-dialog {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
+34
View File
@@ -0,0 +1,34 @@
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import mediumZoom from 'medium-zoom'
import { onMounted, watch, nextTick } from 'vue'
import { useRoute } from 'vitepress'
import './custom.css'
import BoardEnvironmentTable from '../components/BoardEnvironmentTable.vue'
import FlashEnvironmentSelector from '../components/FlashEnvironmentSelector.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('BoardEnvironmentTable', BoardEnvironmentTable)
app.component('FlashEnvironmentSelector', FlashEnvironmentSelector)
},
setup() {
const route = useRoute()
const initZoom = () => {
mediumZoom('.vp-doc img:not(.no-zoom)', {
background: 'var(--vp-c-bg)'
})
}
onMounted(() => {
initZoom()
})
watch(
() => route.path,
() => nextTick(() => initZoom())
)
}
}
-135
View File
@@ -1,135 +0,0 @@
let meta = require('./defaults.json');
try {
meta_overload = require('./meta.json');
meta = { ...meta, ...meta_overload };
} catch (e) {
console.warn('meta.json not found or not valid. Using default configuration.');
}
const fs = require('fs');
const path = require('path');
const commonConfigPath = path.resolve(__dirname, 'public/commonConfig.js');
if (!fs.existsSync(commonConfigPath)) {
throw new Error(`commonConfig.js not found in ${commonConfigPath}.\nPlease download from https://www.theengs.io/commonConfig.js or create this file before you build the documentation.`);
}
const commonConfig = require('./public/commonConfig');
module.exports = {
...commonConfig,
title: `${meta.title} - ${meta.version}`,
base: meta.url_prefix,
dest: meta.dest, // default is generated/site
description: 'One gateway, many technologies: MQTT gateway for ESP8266 or ESP32 with bidirectional 433mhz/315mhz/868mhz, Infrared communications, BLE, LoRa, beacons detection, mi flora / mi jia / LYWSD02/ Mi Scale compatibility, SMS & LORA.',
head: [...commonConfig.head],
themeConfig: {
...commonConfig.themeConfig,
repo: meta.theme_config_repo,
docsDir: 'docs',
mode: meta.mode,
sidebar: [
['/', '0 - What is it for 🏠'],
{
title: '1 - Prerequisites🧭', // required
//collapsable: true, // optional, defaults to true
sidebarDepth: 1, // optional, defaults to 1
children: [
'prerequisites/devices',
'prerequisites/board',
'prerequisites/parts',
'prerequisites/broker',
'prerequisites/controller']
},
{
title: '2 - Set it up 🔨', // required
sidebarDepth: 1, // optional, defaults to 1
children: [
'setitup/rf',
'setitup/ble',
'setitup/ir',
'setitup/lora',
'setitup/gsm',
'setitup/serial',
'setitup/sensors',
'setitup/actuators'
]
},
{
title: '3 - Upload ➡️', // required
path: '/upload/',
sidebarDepth: 1, // optional, defaults to 1
children: [
['upload/web-install', "(Option 1) Upload from the web"],
'upload/binaries',
'upload/builds',
'upload/gitpod',
'upload/portal',
'upload/advanced-configuration',
'upload/troubleshoot'
]
},
{
title: '4 - Use ✈️', // required
sidebarDepth: 1, // optional, defaults to 1
children: [
'use/rf',
'use/ble',
'use/ir',
'use/lora',
'use/gsm',
'use/serial',
'use/rfm69',
'use/sensors',
'use/actuators',
'use/boards',
'use/displays',
'use/gateway',
'use/webui'
]
},
{
title: '5 - Integrate 🎉', // required
sidebarDepth: 1, // optional, defaults to 1
children: [
'integrate/openhab2',
'integrate/openhab3',
'integrate/home_assistant',
'integrate/node_red',
'integrate/aws_iot',
'integrate/jeedom'
]
},
{
title: '6 - Participate 💻', // required
path: '/participate/',
sidebarDepth: 1, // optional, defaults to 1
children: [
'participate/quick_start',
'participate/support',
'participate/development',
'participate/adding-protocols',
'participate/community',
[meta.url_license_file, 'License']
]
}
]
},
plugins: {
'sitemap': {
hostname: meta.hostname,
urls: [
'https://decoder.theengs.io/devices/devices.html',
meta.url_community_forum,
'https://shop.theengs.io/',
'https://shop.theengs.io/products/theengs-plug-smart-plug-ble-gateway-and-energy-consumption',
'https://shop.theengs.io/products/theengs-bridge-esp32-ble-mqtt-gateway-with-ethernet-and-external-antenna',
'https://app.theengs.io/',
'https://gateway.theengs.io/',
'https://decoder.theengs.io/',
'https://parser.theengs.io/',
'https://www.theengs.io/'
],
},
}
}
-13
View File
@@ -1,13 +0,0 @@
div.table-generated-page
main
div.content__default,
footer.page-edit,
div.page-nav
// Display full with the API pages
max-width: 65%
.sidebar
z-index 6
.navbar
z-index 6
File renamed without changes.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

+12 -11
View File
@@ -1,17 +1,18 @@
<ClientOnly> <script setup>
<span v-if="$site.themeConfig.mode === 'dev'"> import { useData } from 'vitepress'
const { site } = useData()
::: warning Development Version const isDev = site.value.title?.includes('edge') || site.value.title?.includes('dev')
This is the edge version of the documentation. It is under active development and may contain bugs, incomplete features, or breaking changes. Use it at your own risk. </script>
:::
</span> <div v-if="isDev" class="warning custom-block">
</ClientOnly> <p class="custom-block-title">Development Version</p>
<p>This is the edge version of the documentation. It is under active development and may contain bugs, incomplete features, or breaking changes. Use it at your own risk.</p>
</div>
OpenMQTTGateway aims to unify various technologies and protocols into a single firmware. This reduces the need for multiple physical bridges and streamlines diverse technologies under the widely-used [MQTT](http://mqtt.org/) protocol. OpenMQTTGateway aims to unify various technologies and protocols into a single firmware. This reduces the need for multiple physical bridges and streamlines diverse technologies under the widely-used [MQTT](http://mqtt.org/) protocol.
<div style="text-align: center;"> <div style="text-align: center;">
<img src="img/OpenMQTTGateway.png" alt="Overview of the protocols and compatible controllers" style="max-width: 100%; height: auto;"> <img src="./img/OpenMQTTGateway.png" alt="Overview of the protocols and compatible controllers" style="max-width: 100%; height: auto;">
</div> </div>
# What is an MQTT gateway or bridge ? # What is an MQTT gateway or bridge ?
@@ -83,7 +84,7 @@ Support open-source development through sponsorship and gain exclusive access to
<div style="text-align: center;"> <div style="text-align: center;">
<a href="https://shop.theengs.io/products/theengs-bridge-esp32-ble-mqtt-gateway-with-ethernet-and-external-antenna" target="_blank" rel="noopener noreferrer"> <a href="https://shop.theengs.io/products/theengs-bridge-esp32-ble-mqtt-gateway-with-ethernet-and-external-antenna" target="_blank" rel="noopener noreferrer">
<img src="img/Theengs-Bridge-ble-gateway.png" alt="Theengs bridge view" style="max-width: 100%; height: auto;"> <img src="./img/Theengs-Bridge-ble-gateway.png" alt="Theengs bridge view" style="max-width: 100%; height: auto;">
</a> </a>
</div> </div>
@@ -99,7 +100,7 @@ Support open-source development through sponsorship and gain exclusive access to
<div style="text-align: center;"> <div style="text-align: center;">
<a href="https://shop.theengs.io/products/theengs-plug-smart-plug-ble-gateway-and-energy-consumption" target="_blank" rel="noopener noreferrer"> <a href="https://shop.theengs.io/products/theengs-plug-smart-plug-ble-gateway-and-energy-consumption" target="_blank" rel="noopener noreferrer">
<img src="img/Theengs-Plug-OpenMQTTGateway.png" alt="Theengs plug view" style="max-width: 100%; height: auto;"> <img src="./img/Theengs-Plug-OpenMQTTGateway.png" alt="Theengs plug view" style="max-width: 100%; height: auto;">
</a> </a>
</div> </div>
+1 -1
View File
@@ -37,7 +37,7 @@ OMG will use the auto discovery functionality of home assistant to create gatewa
The Bluetooth and the RTL_433 gateway will automatically create devices and entities, the RF gateway will create DeviceTrigger. The Bluetooth and the RTL_433 gateway will automatically create devices and entities, the RF gateway will create DeviceTrigger.
The OpenMQTTGateway will also be available as a device to monitor its parameters and control it. The sensors (DHT for example) and actuators (relays) are attached to the gateway. The OpenMQTTGateway will also be available as a device to monitor its parameters and control it. The sensors (DHT for example) and actuators (relays) are attached to the gateway.
On first and subsequent startups, auto discovery will start. If you want to prevent this from happening, be sure to manually turn off auto discovery, either by using the UI in Home Assistant, or by publishing to the home/<gatewayname>/commands/MQTTtoSYS/config topic. On first and subsequent startups, auto discovery will start. If you want to prevent this from happening, be sure to manually turn off auto discovery, either by using the UI in Home Assistant, or by publishing to the `home/<gatewayname>/commands/MQTTtoSYS/config` topic.
30 minutes after its activation the auto discovery will be automatically deactivated, you can reactivate it from the gateway controls. 30 minutes after its activation the auto discovery will be automatically deactivated, you can reactivate it from the gateway controls.
Some devices may require a button push or motion/contact event to trigger a message and generate the auto discovery. Some devices may require a button push or motion/contact event to trigger a message and generate the auto discovery.
::: :::
File renamed without changes.
+27 -27
View File
@@ -76,11 +76,11 @@ Install these tools first. They are useful for **all** types of work:
On Windows you can download: On Windows you can download:
- Git from the official site: <https://git-scm.com/downloads> - Git from the official site: https://git-scm.com/downloads
- Visual Studio Code from <https://code.visualstudio.com/> - Visual Studio Code from https://code.visualstudio.com/
- Git Bash comes with "Git for Windows". - Git Bash comes with "Git for Windows".
On Linux you can install these with your package manager (for example apt on Ubuntu). For more help you can read the Git book: <https://git-scm.com/book/en/v2/Getting-Started-Installing-Git>. On Linux you can install these with your package manager (for example apt on Ubuntu). For more help you can read the Git book: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git.
**Check (common tools):** open a terminal (Git Bash, WSL, or Linux shell) and run: **Check (common tools):** open a terminal (Git Bash, WSL, or Linux shell) and run:
@@ -117,9 +117,9 @@ Install these extra tools:
- Python 3.10 or newer - Python 3.10 or newer
- PlatformIO CLI (pip package) - PlatformIO CLI (pip package)
PlatformIO is the main build system for this project. We will use it from VS Code and from the terminal. If you want to read more, the official docs are here: <https://docs.platformio.org/>. PlatformIO is the main build system for this project. We will use it from VS Code and from the terminal. If you want to read more, the official docs are here: https://docs.platformio.org/.
On Windows you can download Python from: <https://www.python.org/downloads/> On Windows you can download Python from: https://www.python.org/downloads/
On Linux you can install Python with your package manager. On Linux you can install Python with your package manager.
@@ -150,9 +150,9 @@ Install:
- Node.js 18 or newer - Node.js 18 or newer
- npm (usually comes with Node.js) - npm (usually comes with Node.js)
On Windows you can get Node.js from: <https://nodejs.org/en/download> On Windows you can get Node.js from: https://nodejs.org/en/download
On Linux you can install Node.js with your package manager or by following the docs: <https://nodejs.org/en/download/package-manager>. On Linux you can install Node.js with your package manager or by following the docs: https://nodejs.org/en/download/package-manager.
**Check (docs tools):** **Check (docs tools):**
@@ -164,7 +164,7 @@ npm --version
If one of these commands fails, reinstall Node.js, close the terminal, and try again. If one of these commands fails, reinstall Node.js, close the terminal, and try again.
### 2.4 PlatformIO extension in Visual Studio Code ### 2.4 PlatformIO extension in Visual Studio Code
Now add PlatformIO inside VS Code. You can also see pictures of these steps in many ESP32 + PlatformIO tutorials, for example on the PlatformIO site: <https://platformio.org/install/ide?install=vscode>. Now add PlatformIO inside VS Code. You can also see pictures of these steps in many ESP32 + PlatformIO tutorials, for example on the PlatformIO site: https://platformio.org/install/ide?install=vscode.
Steps (based on common PlatformIO + VS Code ESP32 guides, adapted for this project): Steps (based on common PlatformIO + VS Code ESP32 guides, adapted for this project):
@@ -216,7 +216,7 @@ cd OpenMQTTGateway
you should see main, lib, scripts, docs and other files. you should see main, lib, scripts, docs and other files.
If the clone fails, check your internet connection or a possible proxy. Then try again. If you are new to Git, the GitHub "Hello World" guide can also help: <https://docs.github.com/en/get-started/start-your-journey/hello-world>. If the clone fails, check your internet connection or a possible proxy. Then try again. If you are new to Git, the GitHub "Hello World" guide can also help: https://docs.github.com/en/get-started/start-your-journey/hello-world.
@@ -224,7 +224,7 @@ If the clone fails, check your internet connection or a possible proxy. Then try
This section explains how to build and flash the firmware using Visual Studio Code with the PlatformIO extension. This section explains how to build and flash the firmware using Visual Studio Code with the PlatformIO extension.
If you know the classic Arduino IDE, you can think of PlatformIO as a more powerful alternative. It manages many boards, libraries, and environments for you. The official introduction is here: <https://docs.platformio.org/en/latest/what-is-platformio.html>. If you know the classic Arduino IDE, you can think of PlatformIO as a more powerful alternative. It manages many boards, libraries, and environments for you. The official introduction is here: https://docs.platformio.org/en/latest/what-is-platformio.html.
You do **not** create a new PlatformIO project. This repository is already a PlatformIO project. You just open it. You do **not** create a new PlatformIO project. This repository is already a PlatformIO project. You just open it.
@@ -268,7 +268,7 @@ In OpenMQTTGateway the structure is a bit different, because it is a large proje
**Check:** open platformio.ini in VS Code and scroll. You should see several [env:...] sections. This means PlatformIO understands the project. **Check:** open platformio.ini in VS Code and scroll. You should see several [env:...] sections. This means PlatformIO understands the project.
If you want to know more about this file, see the PlatformIO docs about configuration: <https://docs.platformio.org/en/latest/projectconf/index.html>. If you want to know more about this file, see the PlatformIO docs about configuration: https://docs.platformio.org/en/latest/projectconf/index.html.
### 4.3 Choose a PlatformIO environment ### 4.3 Choose a PlatformIO environment
@@ -350,7 +350,7 @@ The Serial Monitor lets you see log messages from the firmware.
If the text is unreadable, check that the baud rate matches the value in platformio.ini (monitor_speed). In this project the default is usually 115200. If the text is unreadable, check that the baud rate matches the value in platformio.ini (monitor_speed). In this project the default is usually 115200.
If you want to learn more about Serial Monitor problems, the PlatformIO docs have a short page: <https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html>. If you want to learn more about Serial Monitor problems, the PlatformIO docs have a short page: https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html.
### 4.7 Run PlatformIO tests (optional) ### 4.7 Run PlatformIO tests (optional)
@@ -387,7 +387,7 @@ This script calls other scripts:
The scripts are written for bash. On Windows always use **Git Bash** or **WSL** for them, not plain PowerShell or cmd. The scripts are written for bash. On Windows always use **Git Bash** or **WSL** for them, not plain PowerShell or cmd.
If you are new to bash, a gentle introduction is here: <https://ubuntu.com/tutorials/command-line-for-beginners>. If you are new to bash, a gentle introduction is here: https://ubuntu.com/tutorials/command-line-for-beginners.
### 5.1 Check that you are in the right place ### 5.1 Check that you are in the right place
@@ -493,14 +493,14 @@ Example direct call to ci_prepare_artifacts.sh:
This script: This script:
- Copies firmware.bin, partitions.bin, bootloader.bin and other files from .pio/build/<env> into the output folder. - Copies firmware.bin, partitions.bin, bootloader.bin and other files from `.pio/build/<env>` into the output folder.
- Renames them with the environment name, for example esp32dev-all-test-firmware.bin. - Renames them with the environment name, for example esp32dev-all-test-firmware.bin.
- Creates archives for the libraries used by that environment. - Creates archives for the libraries used by that environment.
**Check:** **Check:**
- The folder generated/toDeploy (or your custom output) exists. - The folder generated/toDeploy (or your custom output) exists.
- It contains files like <env>-firmware.bin and one or more *-libraries.tgz archives. - It contains files like `<env>-firmware.bin` and one or more `*-libraries.tgz` archives.
If the script says the build directory is missing, run a firmware build first (section 5.3 or 5.4). If the script says the build directory is missing, run a firmware build first (section 5.3 or 5.4).
@@ -790,18 +790,18 @@ If any word in this guide is not clear, you can search it on the web or ask in t
Here is a list of useful links related to tools used in this project: Here is a list of useful links related to tools used in this project:
- **OpenMQTTGateway project**: <https://github.com/1technophile/OpenMQTTGateway> - **OpenMQTTGateway project**: https://github.com/1technophile/OpenMQTTGateway
- **PlatformIO main site**: <https://platformio.org/> - **PlatformIO main site**: https://platformio.org/
- **PlatformIO installation for VS Code**: <https://platformio.org/install/ide?install=vscode> - **PlatformIO installation for VS Code**: https://platformio.org/install/ide?install=vscode
- **PlatformIO documentation**: <https://docs.platformio.org/> - **PlatformIO documentation**: https://docs.platformio.org/
- **Visual Studio Code documentation**: <https://code.visualstudio.com/docs> - **Visual Studio Code documentation**: https://code.visualstudio.com/docs
- **Git official site**: <https://git-scm.com/> - **Git official site**: https://git-scm.com/
- **Pro Git book (free)**: <https://git-scm.com/book/en/v2> - **Pro Git book (free)**: https://git-scm.com/book/en/v2
- **GitHub getting started**: <https://docs.github.com/en/get-started> - **GitHub getting started**: https://docs.github.com/en/get-started
- **Node.js documentation**: <https://nodejs.org/en/docs> - **Node.js documentation**: https://nodejs.org/en/docs
- **npm documentation**: <https://docs.npmjs.com/> - **npm documentation**: https://docs.npmjs.com/
- **VuePress documentation** (v1, similar to what this project uses): <https://v1.vuepress.vuejs.org/> - **VuePress documentation** (v1, similar to what this project uses): https://v1.vuepress.vuejs.org/
- **MQTT introduction (HiveMQ)**: <https://www.hivemq.com/mqtt-essentials/> - **MQTT introduction (HiveMQ)**: https://www.hivemq.com/mqtt-essentials/
You do **not** need to read all of them now. Keep this list as a bookmark and come back when you are curious or stuck. You do **not** need to read all of them now. Keep this list as a bookmark and come back when you are curious or stuck.
+2 -2
View File
@@ -1,5 +1,5 @@
--- ---
pageClass: table-generated-page aside: false
--- ---
# Boards # Boards
+1 -5
View File
@@ -8,9 +8,7 @@ Added to that is an overview of devices supported by OpenMQTTGateway:
OpenMQTTGateway can support a wide range of 433mhz/315mhz devices, all the ones with SC5262 / SC5272, HX2262 / HX2272, PT2262 / PT2272, EV1527, RT1527, FP1527, HS1527 chipsets are supported by the RF gateway. Added to that RF2 support Kaku and Pilight an [huge list](https://wiki.pilight.org/devices). OpenMQTTGateway can support a wide range of 433mhz/315mhz devices, all the ones with SC5262 / SC5272, HX2262 / HX2272, PT2262 / PT2272, EV1527, RT1527, FP1527, HS1527 chipsets are supported by the RF gateway. Added to that RF2 support Kaku and Pilight an [huge list](https://wiki.pilight.org/devices).
Note that for the moment RF, RF2 and Pilight can not be activated on the same boards together. Note that for the moment RF, RF2 and Pilight can not be activated on the same boards together.
![boards](../img/OpenMQTTGateway_devices_rf1.png ':size=250%')
![boards](../img/OpenMQTTGateway_devices_rf2.png ':size=250%')
![boards](../img/OpenMQTTGateway_devices_rf3.png ':size=250%')
## For BLE devices ## For BLE devices
OpenMQTTGateway is able to scan all the BLE devices that advertise their data so as to do presence detection. OpenMQTTGateway is able to scan all the BLE devices that advertise their data so as to do presence detection.
@@ -23,8 +21,6 @@ OpenMQTTGateway currently supports the decoding of [more than 100 Bluetooth devi
- (3) See https://github.com/pvvx/ATC_MiThermometer - (3) See https://github.com/pvvx/ATC_MiThermometer
::: :::
![devices](../img/OpenMQTTGateway_devices_ble.png ':size=250%')
## For infrared IR devices ## For infrared IR devices
The list of supported devices for ESP is [here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md), and [here](https://github.com/1technophile/OpenMQTTGateway/blob/6f73160d1421bebf2c1bbc9b8017978ff5b16520/main/config_IR.h#L123) for Arduino boards, as there is also the possibility of using raw and global cache (ESP) sending possibilities of this gateway is huge! The list of supported devices for ESP is [here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md), and [here](https://github.com/1technophile/OpenMQTTGateway/blob/6f73160d1421bebf2c1bbc9b8017978ff5b16520/main/config_IR.h#L123) for Arduino boards, as there is also the possibility of using raw and global cache (ESP) sending possibilities of this gateway is huge!
+1 -8
View File
@@ -1,10 +1,3 @@
--- <FlashEnvironmentSelector
pageClass: table-generated-page
---
<FlashEnvironmentSelector
boardsUrl="/boards-info.json" boardsUrl="/boards-info.json"
firmwareBaseUrl="firmware_build/" /> firmwareBaseUrl="firmware_build/" />
File renamed without changes.
+2 -3
View File
@@ -1,5 +1,5 @@
--- ---
pageClass: table-generated-page aside: false
--- ---
## Select your firmware ## Select your firmware
@@ -32,4 +32,3 @@ Support open-source development through sponsorship and gain exclusive access to
<iframe src="https://github.com/sponsors/theengs/button" title="Sponsor Theengs" height="32" width="228" style="border: 0; border-radius: 6px;"></iframe> <iframe src="https://github.com/sponsors/theengs/button" title="Sponsor Theengs" height="32" width="228" style="border: 0; border-radius: 6px;"></iframe>
</div> </div>
+5 -5
View File
@@ -23,9 +23,9 @@ const {
// Base directories // Base directories
const ROOT_DIR = path.join(__dirname, '..'); const ROOT_DIR = path.join(__dirname, '..');
const DOCS_DIR = path.join(ROOT_DIR, 'docs'); const DOCS_DIR = path.join(ROOT_DIR, 'docs');
const VUEPRESS_DIR = path.join(DOCS_DIR, '.vuepress'); const VITEPRESS_DIR = path.join(DOCS_DIR, '.vitepress');
const PUBLIC_DIR = path.join(VUEPRESS_DIR, 'public'); const PUBLIC_DIR = path.join(VITEPRESS_DIR, 'public');
const COMPONENTS_DIR = path.join(VUEPRESS_DIR, 'components'); const COMPONENTS_DIR = path.join(VITEPRESS_DIR, 'components');
const ARTIFACTS_DIR = path.join(ROOT_DIR, 'generated', 'artifacts'); const ARTIFACTS_DIR = path.join(ROOT_DIR, 'generated', 'artifacts');
// Feature-specific directories // Feature-specific directories
@@ -34,8 +34,8 @@ const FIRMWARE_BUILD_DIR = path.join(PUBLIC_DIR, 'firmware_build');
const BOARDS_INFO_FILE = path.join(PUBLIC_DIR, 'boards-info.json'); const BOARDS_INFO_FILE = path.join(PUBLIC_DIR, 'boards-info.json');
// Configuration files // Configuration files
const DEFAULTS_CONFIG_PATH = path.join(VUEPRESS_DIR, 'defaults.json'); const DEFAULTS_CONFIG_PATH = path.join(VITEPRESS_DIR, 'defaults.json');
const META_CONFIG_PATH = path.join(VUEPRESS_DIR, 'meta.json'); const META_CONFIG_PATH = path.join(VITEPRESS_DIR, 'meta.json');
+2959 -27318
View File
File diff suppressed because it is too large. Load diff
+12 -11
View File
@@ -2,19 +2,20 @@
"scripts": { "scripts": {
"gen:ssl": "node scripts/ensure_ssl_certs.js", "gen:ssl": "node scripts/ensure_ssl_certs.js",
"gen:metadata": "node docsgen/gen_wu.js", "gen:metadata": "node docsgen/gen_wu.js",
"gen:site:only": "vuepress build docs", "gen:commonconfig": "curl -sSf -o docs/.vitepress/public/commonConfig.js https://www.theengs.io/commonConfig.js",
"docs:dev": "npm run gen:metadata && vuepress dev docs", "docs:dev": "npm run gen:commonconfig && npm run gen:metadata && vitepress dev docs",
"docs:build": "npm run gen:metadata && npm run gen:site:only", "docs:build": "npm run gen:commonconfig && npm run gen:metadata && vitepress build docs",
"site:preview": " npm run gen:ssl && node scripts/preview_site.js", "docs:preview": "vitepress preview docs",
"site:preview:full": "npm run docs:build && npm run gen:ssl && node scripts/preview_site.js" "site:preview": " npm run gen:ssl && node scripts/preview_site.js"
},
"devDependencies": {
"vuepress": "^1.9.10"
}, },
"dependencies": { "dependencies": {
"ini": "^4.1.1", "ini": "^4.1.1",
"markdown-table": "^3.0.3", "markdown-table": "^3.0.3",
"mime-types": "^2.1.35", "mime-types": "^2.1.35"
"vuepress-plugin-sitemap": "^2.3.1" },
"devDependencies": {
"medium-zoom": "^1.1.0",
"vitepress": "^1.6.4",
"vue": "^3.5.31"
} }
} }
+4 -4
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# CI/CD Site/Documentation Builder # CI/CD Site/Documentation Builder
# This script builds and deploys VuePress documentation with version management. # This script builds and deploys VitePress documentation with version management.
# Usage: ./scripts/ci_site.sh [OPTIONS] - Specify options for the script execution. # Usage: ./scripts/ci_site.sh [OPTIONS] - Specify options for the script execution.
set -euo pipefail set -euo pipefail
@@ -91,7 +91,7 @@ download_common_config() {
log_info "Downloading common configuration..." log_info "Downloading common configuration..."
local config_url="https://www.theengs.io/commonConfig.js" local config_url="https://www.theengs.io/commonConfig.js"
local config_dest="${DOCS_DIR}/.vuepress/public/commonConfig.js" local config_dest="${DOCS_DIR}/.vitepress/public/commonConfig.js"
local curl_opts="-sSf" local curl_opts="-sSf"
# Optionally disable TLS verification if explicitly requested # Optionally disable TLS verification if explicitly requested
@@ -121,7 +121,7 @@ create_configuration_files() {
## Create a meta.json file on config folder ## Create a meta.json file on config folder
local meta_file="${DOCS_DIR}/.vuepress/meta.json" local meta_file="${DOCS_DIR}/.vitepress/meta.json"
cat > "$meta_file" <<EOF cat > "$meta_file" <<EOF
{ {
"title": "Theengs OpenMQTTGateway", "title": "Theengs OpenMQTTGateway",
@@ -184,7 +184,7 @@ usage() {
cat << EOF cat << EOF
Usage: $0 [OPTIONS] Usage: $0 [OPTIONS]
Build and deploy OpenMQTTGateway documentation with VuePress. Build and deploy OpenMQTTGateway documentation with VitePress.
Generates site structure and meta.json file. Generates site structure and meta.json file.
OPTIONS: OPTIONS: