SCL identities and Studio control
Import supported SCD, SCL, CID or IID files, deploy supported SV profiles, tune waveforms, START/STOP, capture and reconnect without resetting the powered board.
diff --git a/.github/workflows/m3h-landing-browser-acceptance.yml b/.github/workflows/m3h-landing-browser-acceptance.yml index 230d35aca..360aca4b1 100644 --- a/.github/workflows/m3h-landing-browser-acceptance.yml +++ b/.github/workflows/m3h-landing-browser-acceptance.yml @@ -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: @@ -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\/[^/]+\/[^/]+)$/; @@ -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'), @@ -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(); } diff --git a/.github/workflows/m3h-project-pages-publish.yml b/.github/workflows/m3h-project-pages-publish.yml index ca9a97bbd..a72b3b6c1 100644 --- a/.github/workflows/m3h-project-pages-publish.yml +++ b/.github/workflows/m3h-project-pages-publish.yml @@ -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' @@ -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 @@ -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 @@ -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; } diff --git a/README.md b/README.md index da058af36..41a10dd8e 100644 --- a/README.md +++ b/README.md @@ -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 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. diff --git a/assets/photos/arstack-esp32-p4-lab-demo.webp b/assets/photos/arstack-esp32-p4-lab-demo.webp new file mode 100644 index 000000000..3b717f692 Binary files /dev/null and b/assets/photos/arstack-esp32-p4-lab-demo.webp differ diff --git a/index.html b/index.html index 79879853a..167d282fd 100644 --- a/index.html +++ b/index.html @@ -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}} @@ -102,6 +110,23 @@
Import supported SCD, SCL, CID or IID files, deploy supported SV profiles, tune waveforms, START/STOP, capture and reconnect without resetting the powered board.
A real photo of a compact ESP32-P4 development board connected to USB-C and Ethernet, with the engineering waveform workspace in the background.
+ The ESP32-P4-ETH family includes the ESP32-P4-ETH-M with pre-soldered headers. For the ARStack lab, use a compatible Ethernet board and release-matched firmware; use a dedicated, isolated test network.
+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.
+ +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.
]*href="{ICON_ROOT}/favicon.ico"',
rf']*href="{ICON_ROOT}/favicon-16x16.png"',
@@ -69,6 +81,12 @@
if HTML.count('