Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/m3h-landing-browser-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: ARStack Latest Stable Landing Browser and Mobile Acceptance
on:
push:
branches: [main]
paths: ['index.html', 'assets/screenshots/arstack-studio-windows.png', 'assets/studio_icon/**', 'scripts/check_site_visual_assets.py', '.github/workflows/m3h-landing-browser-acceptance.yml']
paths: ['index.html', 'assets/screenshots/arstack-studio-windows.png', 'assets/photos/arstack-esp32-p4-lab-demo.webp', 'assets/studio_icon/**', 'scripts/check_site_visual_assets.py', '.github/workflows/m3h-landing-browser-acceptance.yml']
pull_request:
paths: ['index.html', 'assets/screenshots/arstack-studio-windows.png', 'assets/studio_icon/**', 'scripts/check_site_visual_assets.py', '.github/workflows/m3h-landing-browser-acceptance.yml']
paths: ['index.html', 'assets/screenshots/arstack-studio-windows.png', 'assets/photos/arstack-esp32-p4-lab-demo.webp', 'assets/studio_icon/**', 'scripts/check_site_visual_assets.py', '.github/workflows/m3h-landing-browser-acceptance.yml']
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -43,6 +43,8 @@ jobs:
const response=await page.goto('http://127.0.0.1:4173/',{waitUntil:'domcontentloaded',timeout:30000});
if(response.status()!==200)throw new Error('LIVE_HTTP_'+response.status());
await Promise.all([page.locator('.brand img').evaluate(el=>el.decode()),page.locator('.hero-visual img').evaluate(el=>el.decode())]);
await page.locator('.lab-photo img').scrollIntoViewIfNeeded();
await page.locator('.lab-photo img').evaluate(el=>el.decode());
const data=await page.evaluate(()=>{
const buttons=[...document.querySelectorAll('a[data-asset="windows"],a[data-asset="portable"],a[data-asset="firmware"]')];
const releaseLink=/^https:\/\/github\.com\/masarray\/arstack61850\/releases\/(latest|tag\/[^/]+|download\/[^/]+\/[^/]+)$/;
Expand All @@ -53,6 +55,8 @@ jobs:
heroDownloads:[...document.querySelectorAll('.hero-downloads a')].map(el=>({label:el.textContent.trim(),href:el.href,visible:el.getBoundingClientRect().width>0&&el.getBoundingClientRect().height>0})),
officialBrand:(()=>{const el=document.querySelector('.brand img');return el?.naturalWidth===192&&el.getAttribute('src')==='assets/studio_icon/android-chrome-192x192.png'})(),
nativeScreenshot:(()=>{const el=document.querySelector('.hero-visual img');return el?.naturalWidth===960&&el?.naturalHeight===680&&el.getAttribute('src')==='assets/screenshots/arstack-studio-windows.png'})(),
realBenchPhoto:(()=>{const el=document.querySelector('.lab-photo img');return el?.naturalWidth===960&&el?.naturalHeight===713&&el.getAttribute('src')==='assets/photos/arstack-esp32-p4-lab-demo.webp'})(),
officialBoardLink:!!document.querySelector('a[href="https://www.waveshare.com/product/iot-communication/wired-comm-converter/esp32-p4-eth.htm"]'),
studioFavicons:[...document.querySelectorAll('link[rel="icon"],link[rel="apple-touch-icon"],link[rel="manifest"]')].every(el=>el.getAttribute('href').startsWith('assets/studio_icon/')),
studioSocialImage:document.querySelector('meta[property="og:image"]')?.content?.endsWith('/assets/studio_icon/android-chrome-512x512.png')===true,
noPaintedMock:!document.querySelector('.monitor,.wave'),
Expand All @@ -62,7 +66,7 @@ jobs:
await page.screenshot({path:'evidence/m3h-'+width+'.png',fullPage:true});
if(!data.latest||!data.benchmark||!data.og||data.buttons!==4||!data.anyVisible||!data.linksValid||!data.linuxReady)throw new Error('MISSING_LATEST_RELEASE_LINKS_'+width);
if(data.heroDownloads.length!==2||!data.heroDownloads.every(x=>x.visible)||data.heroDownloads[0].label!=='Download for Windows'||data.heroDownloads[1].label!=='Download for Linux'||!/ARStack-Studio-win-x64-setup\.zip$/.test(data.heroDownloads[0].href)||!/ARStack-Studio-linux-x86_64\.AppImage$/.test(data.heroDownloads[1].href))throw new Error('HERO_DIRECT_PLATFORM_DOWNLOADS_'+width);
if(!data.officialBrand||!data.nativeScreenshot||!data.noPaintedMock||!data.studioFavicons||!data.studioSocialImage)throw new Error('NONCANONICAL_STUDIO_ICON_OR_MOCK_SCREEN_'+width);
if(!data.officialBrand||!data.nativeScreenshot||!data.realBenchPhoto||!data.officialBoardLink||!data.noPaintedMock||!data.studioFavicons||!data.studioSocialImage)throw new Error('NONCANONICAL_STUDIO_ICON_OR_MOCK_SCREEN_'+width);
if(data.scroll>data.width+2)throw new Error('HORIZONTAL_OVERFLOW_'+width+':'+data.scroll+'>'+data.width);
await page.close();
}
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/m3h-project-pages-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
paths:
- 'index.html'
- 'assets/screenshots/arstack-studio-windows.png'
- 'assets/photos/arstack-esp32-p4-lab-demo.webp'
- 'assets/studio_icon/**'
- 'scripts/check_site_visual_assets.py'
- '.github/workflows/m3h-project-pages-publish.yml'
Expand Down Expand Up @@ -41,6 +42,8 @@ jobs:
grep -Fq 'class="actionrow hero-downloads"' index.html
grep -Fq 'Download for Windows' index.html
grep -Fq 'Download for Linux' index.html
grep -Fq 'assets/photos/arstack-esp32-p4-lab-demo.webp' index.html
grep -Fq 'https://docs.waveshare.com/ESP32-P4-ETH' index.html
grep -Fq 'ARStack-Studio-linux-x86_64.AppImage' index.html
grep -Fq 'data-asset="firmware"' index.html
grep -Fq 'M3.H' index.html
Expand All @@ -53,13 +56,15 @@ jobs:
python3 scripts/check_site_visual_assets.py
mkdir -p _site
cp index.html _site/index.html
mkdir -p _site/assets/screenshots _site/assets/studio_icon
mkdir -p _site/assets/screenshots _site/assets/studio_icon _site/assets/photos
for asset in android-chrome-192x192.png android-chrome-512x512.png favicon.ico favicon-16x16.png favicon-32x32.png apple-touch-icon.png site.webmanifest; do
test -s "assets/studio_icon/$asset"
cp "assets/studio_icon/$asset" "_site/assets/studio_icon/$asset"
done
test -s assets/screenshots/arstack-studio-windows.png
cp assets/screenshots/arstack-studio-windows.png _site/assets/screenshots/arstack-studio-windows.png
test -s assets/photos/arstack-esp32-p4-lab-demo.webp
cp assets/photos/arstack-esp32-p4-lab-demo.webp _site/assets/photos/arstack-esp32-p4-lab-demo.webp
touch _site/.nojekyll
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v4
Expand All @@ -83,9 +88,10 @@ jobs:
grep -Fq 'Download for Windows' /tmp/arstack-live.html &&
grep -Fq 'Download for Linux' /tmp/arstack-live.html &&
grep -Fq 'assets/studio_icon/android-chrome-192x192.png' /tmp/arstack-live.html &&
grep -Fq 'assets/photos/arstack-esp32-p4-lab-demo.webp' /tmp/arstack-live.html &&
grep -Fq '4,705,090' /tmp/arstack-live.html &&
grep -Fq 'processbus-sim-dual-stable-20261105' /tmp/arstack-live.html; then
for asset in assets/studio_icon/android-chrome-192x192.png assets/studio_icon/android-chrome-512x512.png assets/studio_icon/favicon.ico assets/studio_icon/favicon-16x16.png assets/studio_icon/favicon-32x32.png assets/studio_icon/apple-touch-icon.png assets/studio_icon/site.webmanifest assets/screenshots/arstack-studio-windows.png; do
for asset in assets/studio_icon/android-chrome-192x192.png assets/studio_icon/android-chrome-512x512.png assets/studio_icon/favicon.ico assets/studio_icon/favicon-16x16.png assets/studio_icon/favicon-32x32.png assets/studio_icon/apple-touch-icon.png assets/studio_icon/site.webmanifest assets/screenshots/arstack-studio-windows.png assets/photos/arstack-esp32-p4-lab-demo.webp; do
published="/tmp/arstack-live-$(basename "$asset")"
curl --fail --location --silent --show-error "https://masarray.github.io/arstack61850/$asset?build=$GITHUB_SHA" -o "$published"
cmp --silent "$asset" "$published" || { echo "FAIL: published image differs from repository $asset" >&2; exit 1; }
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ Use **ARStack Studio** and one affordable **ESP32-P4 Ethernet board** to generat

*Screenshot captured directly from the Windows Qt application by the native GUI test.*

## Real ESP32-P4 Ethernet lab setup

![Real Waveshare ESP32-P4-ETH series board connected to USB-C and an RJ45 Ethernet cable, held in front of an engineering waveform workspace](assets/photos/arstack-esp32-p4-lab-demo.webp)

*Real hardware setup photo contributed to the project: an ESP32-P4-ETH-series development board connected over USB and Ethernet with a waveform workspace in the background. This illustrates the bench setup; standards compliance and SV/PTP timing claims are supported by the separate [packet-capture benchmark](docs/releases/PROCESSBUS_AUTONOMOUS_M3H3_OFFICIAL_20261025.md), not by the photograph.*

**Want to see or buy a board?** [Waveshare official ESP32-P4-ETH product page (including the ESP32-P4-ETH-M option)](https://www.waveshare.com/product/iot-communication/wired-comm-converter/esp32-p4-eth.htm) · [Waveshare board documentation and revision guidance](https://docs.waveshare.com/ESP32-P4-ETH) · [Getting started](docs/GETTING_STARTED.md).

The ESP32-P4-ETH-M is the version with pre-soldered pin headers. Confirm your actual chip revision in Studio before flashing the **matched firmware**: pre-v3 is supported by historical lab evidence, while v3.x physical compatibility remains an **engineering preview**. Run SV/PTP only on isolated test Ethernet.

## Get started in minutes

1. **Download Studio** for [Windows (Setup ZIP)](https://github.com/masarray/arstack61850/releases/download/processbus-sim-dual-stable-20261105/ARStack-Studio-win-x64-setup.zip) or [Linux x86_64 (AppImage)](https://github.com/masarray/arstack61850/releases/download/processbus-sim-dual-stable-20261105/ARStack-Studio-linux-x86_64.AppImage). Extract the Windows ZIP and run the installer inside, or mark the Linux AppImage executable and launch it. Windows Portable ZIP and direct EXE are also available.
Expand Down
Binary file added assets/photos/arstack-esp32-p4-lab-demo.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 26 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,17 @@
.evidence{border-top:1px solid #284050;border-bottom:1px solid #284050;background:#0b1b26a8}.metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));padding:23px 0;gap:0}.metric{padding:0 20px;border-right:1px solid #2a4655}.metric:first-child{padding-left:0}.metric:last-child{border:0}.metric strong{display:block;color:#d6f1f9;font-size:clamp(18px,2.1vw,26px);letter-spacing:-.55px;font-weight:600;line-height:1.35;font-variant-numeric:tabular-nums}.metric span{display:block;margin-top:4px;color:#94acbc;font-size:11px;line-height:1.5}.metrics-note{color:#829dab;font-size:10px;padding-bottom:16px}
.section{padding:71px 0 0}.sectionhead{display:flex;justify-content:space-between;gap:20px;align-items:end;margin-bottom:25px}.kicker{color:#73c7df;text-transform:uppercase;letter-spacing:1.65px;font-size:10px;margin-bottom:9px}h2{font-size:clamp(24px,2.6vw,32px);letter-spacing:-.65px;line-height:1.26;font-weight:600;margin:0 0 12px}.intro{max-width:730px;color:var(--muted);font-size:13px;line-height:1.8;margin:0}.sectionlink{font-size:12px;white-space:nowrap;color:#9cdeee;text-underline-offset:4px}
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.card{padding:23px 21px;background:linear-gradient(150deg,#132635,#0e1c28);border:1px solid #2b4555;border-radius:10px}.card-num{font-size:11px;color:#6cbdd5;letter-spacing:1px}.card h3{font-size:15px;font-weight:600;letter-spacing:-.1px;margin:14px 0 7px}.card p{font-size:12px;color:#9eb4c1;line-height:1.8;margin:0}.two-col{display:grid;grid-template-columns:1fr 1fr;gap:14px}.panel{background:#10212f;border:1px solid #2d4556;border-radius:10px;padding:23px}.panel h3{font-size:15px;font-weight:600;margin:0 0 11px}.panel p{font-size:12px;line-height:1.8;color:#a5bdc8;margin:0 0 14px}.panel .link{color:#83d6e7;font-size:12px;text-decoration:none}.panel .link:hover{text-decoration:underline}.tagline{margin:0 0 12px;font-size:11px;color:#78d5c4}.panel-list{list-style:none;margin:0;padding:0;display:grid;gap:9px}.panel-list li{font-size:12px;color:#b3c7d1}.panel-list li:before{content:"✓";display:inline-block;margin-right:10px;color:#69dbc0}
.lab-grid{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);gap:28px;align-items:center}
.lab-photo{margin:0;padding:7px;background:#10212e;border:1px solid #2b4757;border-radius:11px}
.lab-photo img{display:block;width:100%;height:auto;aspect-ratio:960/713;object-fit:cover;border-radius:6px}
.lab-photo figcaption{padding:9px 5px 3px;font-size:10.5px;color:#8da7b6;line-height:1.6}
.lab-copy{min-width:0}.lab-copy h3{font-size:20px;font-weight:600;letter-spacing:-.4px;line-height:1.3;margin:0 0 11px}
.lab-copy p{font-size:12.5px;color:#a6bdc9;line-height:1.85;margin:0 0 12px}
.lab-links{display:flex;flex-direction:column;align-items:flex-start;gap:9px;margin-top:17px}
.lab-links a{font-size:12px;color:#9ce1f0;text-underline-offset:4px}
.setup{counter-reset:step;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:25px 0 14px}.step{padding:20px;background:#102330;border:1px solid #2d4858;border-radius:9px;color:#98acba;font-size:12px;line-height:1.7}.step:before{counter-increment:step;content:"0" counter(step);display:block;font-size:18px;color:#70d1e9;font-weight:650;margin-bottom:10px}.step b{display:block;font-size:13px;color:#eaf5fa;font-weight:600;margin-bottom:6px}.notice{border-left:2px solid #5ba4bc;color:#afc6d1;padding:9px 16px;margin-top:19px;font-size:12px;background:#12263370}
.downloads{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:24px}.download{background:linear-gradient(150deg,#132635,#0d1b28);border:1px solid #315061;border-radius:10px;padding:22px;display:flex;flex-direction:column;gap:16px}.download .detail{font-size:11px;color:#9bb3c0;margin:3px 0 0}.download h3{font-size:15px;font-weight:600;margin:0}.download a{font-size:12px;color:#91e1f0;font-weight:600;text-decoration:none;align-self:start}.download a:hover{text-decoration:underline}.small{font-size:11px;color:#89a3b2;line-height:1.8;margin-top:14px}.small a{color:#a8ddec}.footer{margin-top:70px;border-top:1px solid #273d4c;padding:27px 0 31px;color:#88a1ae;font-size:11px}.footer-inner{display:flex;flex-wrap:wrap;justify-content:space-between;gap:13px}.footer-links{display:flex;flex-wrap:wrap;gap:17px}.footer-links a{text-decoration:none}.footer-links a:hover{color:var(--aqua)}
@media(max-width:950px){.hero-grid{grid-template-columns:minmax(0,1fr);gap:28px}.hero-copy{max-width:720px}.hero-visual{max-width:770px;width:100%}.navlinks{gap:15px}}
@media(max-width:950px){.lab-grid{grid-template-columns:1fr;gap:22px}.lab-photo{max-width:730px}.hero-grid{grid-template-columns:minmax(0,1fr);gap:28px}.hero-copy{max-width:720px}.hero-visual{max-width:770px;width:100%}.navlinks{gap:15px}}
@media(max-width:700px){.wrap{width:calc(100% - 32px)}.hero{padding:44px 0 38px}.section{padding-top:52px}.metrics{grid-template-columns:repeat(2,1fr);row-gap:16px}.metric:nth-child(2){border:0}.metric:nth-child(3){padding-left:0}.cards{grid-template-columns:1fr}.two-col{grid-template-columns:1fr}.setup{grid-template-columns:repeat(2,1fr)}.sectionhead{display:block}.sectionlink{display:inline-block;margin-top:16px}.navlinks a:not(.nav-github){display:none}}
@media(max-width:440px){.hero{padding-top:38px}.brand{font-size:14px}.nav-github{padding:6px 9px}.hero h1{font-size:34px;letter-spacing:-1.2px}.actionrow{flex-direction:column;align-items:stretch}.btn{width:100%}.preview-link{padding:5px}.metrics{padding:20px 0}.metric{padding:0 10px}.metric strong{font-size:17px}.setup,.downloads{grid-template-columns:1fr}.footer-inner{display:block}.footer-links{margin-top:12px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}.btn,.navlinks a{transition:none}}
Expand Down Expand Up @@ -102,6 +110,23 @@ <h1>A process bus lab.<br><em>Without the test rack.</em></h1>
<article class="card"><div class="card-num">03 / ENGINEERING WORKFLOW</div><h3>SCL identities and Studio control</h3><p>Import supported SCD, SCL, CID or IID files, deploy supported SV profiles, tune waveforms, START/STOP, capture and reconnect without resetting the powered board.</p></article>
</div>
</section>

<section class="wrap section" id="hardware-lab">
<div class="sectionhead"><div><div class="kicker">A real hardware bench</div><h2>See the ESP32-P4 lab setup.</h2><p class="intro">A real photo of a compact ESP32-P4 development board connected to USB-C and Ethernet, with the engineering waveform workspace in the background.</p></div></div>
<div class="lab-grid">
<figure class="lab-photo">
<img src="assets/photos/arstack-esp32-p4-lab-demo.webp" width="960" height="713" loading="lazy" decoding="async" alt="Real ESP32-P4-ETH-series development board connected to a green Ethernet RJ45 cable and white USB-C cable in front of a three-phase waveform workspace">
<figcaption>Project hardware demo photo · real board and cables. On-wire SV/PTP benchmark evidence is documented separately.</figcaption>
</figure>
<div class="lab-copy">
<div class="tagline">AFFORDABLE PROCESS BUS EXPERIMENTS</div>
<h3>Explore with Waveshare ESP32-P4-ETH.</h3>
<p>The ESP32-P4-ETH family includes the <strong>ESP32-P4-ETH-M</strong> with pre-soldered headers. For the ARStack lab, use a compatible Ethernet board and release-matched firmware; use a dedicated, isolated test network.</p>
<p>Board revisions matter. ARStack Studio distributes distinct pre-v3 and v3.x firmware images. The newer v3.x firmware is still in engineering-preview hardware qualification.</p>
<div class="lab-links"><a href="https://www.waveshare.com/product/iot-communication/wired-comm-converter/esp32-p4-eth.htm">View or buy the board · Waveshare official store ↗</a><a href="https://docs.waveshare.com/ESP32-P4-ETH">Hardware documentation and revision information ↗</a><a href="https://github.com/masarray/arstack61850/blob/main/docs/releases/PROCESSBUS_AUTONOMOUS_M3H3_OFFICIAL_20261025.md">Read the separate SV/PTP capture evidence ↗</a></div>
</div>
</div>
</section>
<section class="wrap section" id="roadmap">
<div class="sectionhead"><div><div class="kicker">Latest software progress</div><h2>Three virtual Merging Units. One ESP32-P4.</h2><p class="intro">M4 software includes SCL-driven three-virtual-MU configuration and group START/STOP with shared sample/PTP timing. The publicly shipped dual-firmware stable package carries these integrated controls, while sustained 3 × 4,000 fps on-wire load acceptance and v3.x hardware qualification are still being collected.</p></div><a class="sectionlink" href="https://github.com/masarray/arstack61850/blob/main/docs/PROCESS_BUS_MULTI_SV_SCL_NEXT_PHASE.md">Implementation details ↗</a></div>
<div class="two-col">
Expand Down
Loading
Loading